summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--.gitattributes42
-rw-r--r--.gitignore24
-rw-r--r--CHANGELOG.md170
-rw-r--r--LICENSE20
-rw-r--r--MANIFEST.in0
-rw-r--r--README.md40
-rw-r--r--actionsosx/README.txt19
-rw-r--r--actionsosx/UFO Normalize.workflow/Contents/Info.plist27
-rw-r--r--actionsosx/UFO Normalize.workflow/Contents/QuickLook/Thumbnail.pngbin0 -> 34886 bytes
-rw-r--r--actionsosx/UFO Normalize.workflow/Contents/document.wflow204
-rw-r--r--docs/composite.md106
-rw-r--r--docs/docs.md204
-rw-r--r--docs/examples.md236
-rw-r--r--docs/fea2_proposal.md150
-rw-r--r--docs/feaextensions.md518
-rw-r--r--docs/feax_future.md283
-rw-r--r--docs/parameters.md179
-rw-r--r--docs/scripts.md1544
-rw-r--r--docs/technical.md342
-rw-r--r--docs/ufo.md159
-rwxr-xr-xexamples/FFmapGdlNames.py99
-rwxr-xr-xexamples/FFmapGdlNames2.py72
-rwxr-xr-xexamples/FLWriteXml.py118
-rw-r--r--examples/FTMLnorm.py24
-rw-r--r--examples/FTaddEmptyOT.py49
-rw-r--r--examples/accesslibplist.py34
-rw-r--r--examples/chaindemo.py43
-rw-r--r--examples/fbonecheck.py17
-rw-r--r--examples/fbttfchecks.py65
-rwxr-xr-xexamples/ffchangeglyphnames.py65
-rw-r--r--examples/ffcopyglyphs.py161
-rwxr-xr-xexamples/ffremovealloverlaps.py31
-rwxr-xr-xexamples/fontforge-old/FFaddPUA.py31
-rwxr-xr-xexamples/fontforge-old/FFcheckDupUSV.py62
-rwxr-xr-xexamples/fontforge-old/FFcolourGlyphs.py51
-rwxr-xr-xexamples/fontforge-old/FFcompareFonts.py44
-rwxr-xr-xexamples/fontforge-old/FFdblEncode.py48
-rwxr-xr-xexamples/fontforge-old/FFfromAP.py74
-rwxr-xr-xexamples/fontforge-old/FFlistAPNum.py38
-rwxr-xr-xexamples/fontforge-old/FFlistGlyphNames.py22
-rwxr-xr-xexamples/fontforge-old/FFlistGlyphinfo.py61
-rwxr-xr-xexamples/fontforge-old/FFlistRefNum.py33
-rwxr-xr-xexamples/fontforge-old/FFnameSearchNReplace.py38
-rwxr-xr-xexamples/fontforge-old/FFundblEncode.py50
-rwxr-xr-xexamples/fontforge-old/demoAddToMenu.py38
-rwxr-xr-xexamples/fontforge-old/demoExecuteScript.py29
-rwxr-xr-xexamples/fontforge-old/demoFunctions.py90
-rw-r--r--examples/gdl/__init__.py20
-rw-r--r--examples/gdl/font.py394
-rw-r--r--examples/gdl/glyph.py174
-rwxr-xr-xexamples/gdl/makeGdl.py31
-rw-r--r--examples/gdl/ot.py448
-rw-r--r--examples/gdl/psnames.py4506
-rwxr-xr-xexamples/preflight9
-rwxr-xr-xexamples/psfaddGlyphDemo.py53
-rwxr-xr-xexamples/psfexpandstroke.py641
-rw-r--r--examples/psfexportnamesunicodesfp.py30
-rw-r--r--examples/psfgenftml.py189
-rwxr-xr-xexamples/psftidyfontlabufo.py102
-rw-r--r--examples/psftoneletters.py327
-rwxr-xr-xexamples/xmlDemo.py54
-rwxr-xr-xez_setup.py391
-rw-r--r--lib/silfont/__init__.py5
-rw-r--r--lib/silfont/comp.py358
-rwxr-xr-xlib/silfont/core.py748
-rw-r--r--lib/silfont/data/required_chars.csv308
-rw-r--r--lib/silfont/data/required_chars.md32
-rw-r--r--lib/silfont/etutil.py270
-rwxr-xr-xlib/silfont/fbtests/__init__.py0
-rw-r--r--lib/silfont/fbtests/silnotcjk.py230
-rw-r--r--lib/silfont/fbtests/silttfchecks.py250
-rw-r--r--lib/silfont/fbtests/ttfchecks.py305
-rw-r--r--lib/silfont/feax_ast.py445
-rw-r--r--lib/silfont/feax_lexer.py105
-rw-r--r--lib/silfont/feax_parser.py727
-rw-r--r--lib/silfont/ftml.py433
-rw-r--r--lib/silfont/ftml_builder.py750
-rwxr-xr-xlib/silfont/harfbuzz.py71
-rw-r--r--lib/silfont/ipython.py135
-rwxr-xr-xlib/silfont/scripts/__init__.py0
-rwxr-xr-xlib/silfont/scripts/psfaddanchors.py73
-rwxr-xr-xlib/silfont/scripts/psfbuildcomp.py309
-rw-r--r--lib/silfont/scripts/psfbuildcompgc.py45
-rwxr-xr-xlib/silfont/scripts/psfbuildfea.py89
-rwxr-xr-xlib/silfont/scripts/psfchangegdlnames.py160
-rw-r--r--lib/silfont/scripts/psfchangettfglyphnames.py35
-rw-r--r--lib/silfont/scripts/psfcheckbasicchars.py68
-rw-r--r--lib/silfont/scripts/psfcheckclassorders.py142
-rw-r--r--lib/silfont/scripts/psfcheckftml.py65
-rw-r--r--lib/silfont/scripts/psfcheckglyphinventory.py125
-rw-r--r--lib/silfont/scripts/psfcheckinterpolatable.py75
-rwxr-xr-xlib/silfont/scripts/psfcompdef2xml.py65
-rwxr-xr-xlib/silfont/scripts/psfcompressgr.py100
-rw-r--r--lib/silfont/scripts/psfcopyglyphs.py243
-rwxr-xr-xlib/silfont/scripts/psfcopymeta.py148
-rw-r--r--lib/silfont/scripts/psfcreateinstances.py228
-rw-r--r--lib/silfont/scripts/psfcsv2comp.py129
-rwxr-xr-xlib/silfont/scripts/psfdeflang.py47
-rw-r--r--lib/silfont/scripts/psfdeleteglyphs.py144
-rw-r--r--lib/silfont/scripts/psfdupglyphs.py48
-rwxr-xr-xlib/silfont/scripts/psfexportanchors.py101
-rwxr-xr-xlib/silfont/scripts/psfexportmarkcolors.py55
-rwxr-xr-xlib/silfont/scripts/psfexportpsnames.py47
-rwxr-xr-xlib/silfont/scripts/psfexportunicodes.py43
-rwxr-xr-xlib/silfont/scripts/psffixffglifs.py48
-rwxr-xr-xlib/silfont/scripts/psffixfontlab.py169
-rwxr-xr-xlib/silfont/scripts/psfftml2TThtml.py389
-rwxr-xr-xlib/silfont/scripts/psfftml2odt.py453
-rwxr-xr-xlib/silfont/scripts/psfgetglyphnames.py87
-rw-r--r--lib/silfont/scripts/psfglyphs2ufo.py275
-rw-r--r--lib/silfont/scripts/psfmakedeprecated.py74
-rwxr-xr-xlib/silfont/scripts/psfmakefea.py369
-rw-r--r--lib/silfont/scripts/psfmakescaledshifted.py117
-rwxr-xr-xlib/silfont/scripts/psfmakewoffmetadata.py225
-rwxr-xr-xlib/silfont/scripts/psfnormalize.py31
-rw-r--r--lib/silfont/scripts/psfremovegliflibkeys.py71
-rw-r--r--lib/silfont/scripts/psfrenameglyphs.py587
-rwxr-xr-xlib/silfont/scripts/psfrunfbchecks.py249
-rwxr-xr-xlib/silfont/scripts/psfsetassocfeat.py54
-rwxr-xr-xlib/silfont/scripts/psfsetassocuids.py51
-rw-r--r--lib/silfont/scripts/psfsetdummydsig.py36
-rw-r--r--lib/silfont/scripts/psfsetglyphdata.py143
-rwxr-xr-xlib/silfont/scripts/psfsetglyphorder.py91
-rwxr-xr-xlib/silfont/scripts/psfsetkeys.py100
-rwxr-xr-xlib/silfont/scripts/psfsetmarkcolors.py106
-rwxr-xr-xlib/silfont/scripts/psfsetpsnames.py86
-rwxr-xr-xlib/silfont/scripts/psfsetunicodes.py79
-rwxr-xr-xlib/silfont/scripts/psfsetversion.py85
-rwxr-xr-xlib/silfont/scripts/psfshownames.py235
-rw-r--r--lib/silfont/scripts/psfsubset.py112
-rw-r--r--lib/silfont/scripts/psfsyncmasters.py293
-rwxr-xr-xlib/silfont/scripts/psfsyncmeta.py303
-rw-r--r--lib/silfont/scripts/psftuneraliases.py121
-rw-r--r--lib/silfont/scripts/psfufo2glyphs.py69
-rw-r--r--lib/silfont/scripts/psfufo2ttf.py108
-rwxr-xr-xlib/silfont/scripts/psfversion.py64
-rw-r--r--lib/silfont/scripts/psfwoffit.py99
-rwxr-xr-xlib/silfont/scripts/psfxml2compdef.py33
-rwxr-xr-xlib/silfont/ufo.py1386
-rwxr-xr-xlib/silfont/util.py374
-rwxr-xr-xpreflight/update-preflight-libs.sh28
-rw-r--r--pytest.ini3
-rwxr-xr-xsetup.py69
-rw-r--r--tests/fontparts/test_10_psfbuildcompgc.py37
-rw-r--r--tests/input/PsfTest-R.ttfbin0 -> 22564 bytes
-rw-r--r--tests/input/font-psf-test/FONTLOG.txt174
-rw-r--r--tests/input/font-psf-test/OFL-FAQ.txt427
-rw-r--r--tests/input/font-psf-test/OFL.txt94
-rw-r--r--tests/input/font-psf-test/README.md9
-rw-r--r--tests/input/font-psf-test/README.txt87
-rwxr-xr-xtests/input/font-psf-test/preflight19
-rwxr-xr-xtests/input/font-psf-test/preflightg7
-rw-r--r--tests/input/font-psf-test/source/PsfTest-Bold.ufo/fontinfo.plist245
-rw-r--r--tests/input/font-psf-test/source/PsfTest-Bold.ufo/glyphs/A_mpersand.glif61
-rw-r--r--tests/input/font-psf-test/source/PsfTest-Bold.ufo/glyphs/A_pos.glif17
-rw-r--r--tests/input/font-psf-test/source/PsfTest-Bold.ufo/glyphs/A_sterisk.glif51
-rw-r--r--tests/input/font-psf-test/source/PsfTest-Bold.ufo/glyphs/A_tS_gn.glif80
-rw-r--r--tests/input/font-psf-test/source/PsfTest-Bold.ufo/glyphs/C_ircumA_ccent.glif17
-rw-r--r--tests/input/font-psf-test/source/PsfTest-Bold.ufo/glyphs/C_olon.glif35
-rw-r--r--tests/input/font-psf-test/source/PsfTest-Bold.ufo/glyphs/C_ombA_cute.glif14
-rw-r--r--tests/input/font-psf-test/source/PsfTest-Bold.ufo/glyphs/C_ombC_ircum.glif17
-rw-r--r--tests/input/font-psf-test/source/PsfTest-Bold.ufo/glyphs/C_ombD_iaer.glif36
-rw-r--r--tests/input/font-psf-test/source/PsfTest-Bold.ufo/glyphs/C_ombG_rave.glif14
-rw-r--r--tests/input/font-psf-test/source/PsfTest-Bold.ufo/glyphs/C_ombR_ingA_bv.glif36
-rw-r--r--tests/input/font-psf-test/source/PsfTest-Bold.ufo/glyphs/C_ombT_ilde.glif36
-rw-r--r--tests/input/font-psf-test/source/PsfTest-Bold.ufo/glyphs/C_omma.glif24
-rw-r--r--tests/input/font-psf-test/source/PsfTest-Bold.ufo/glyphs/D_igitE_ight.glif63
-rw-r--r--tests/input/font-psf-test/source/PsfTest-Bold.ufo/glyphs/D_igitF_ive.glif44
-rw-r--r--tests/input/font-psf-test/source/PsfTest-Bold.ufo/glyphs/D_igitF_our.glif27
-rw-r--r--tests/input/font-psf-test/source/PsfTest-Bold.ufo/glyphs/D_igitN_ine.glif49
-rw-r--r--tests/input/font-psf-test/source/PsfTest-Bold.ufo/glyphs/D_igitO_ne.glif22
-rw-r--r--tests/input/font-psf-test/source/PsfTest-Bold.ufo/glyphs/D_igitS_even.glif25
-rw-r--r--tests/input/font-psf-test/source/PsfTest-Bold.ufo/glyphs/D_igitS_ix.glif49
-rw-r--r--tests/input/font-psf-test/source/PsfTest-Bold.ufo/glyphs/D_igitT_hree.glif52
-rw-r--r--tests/input/font-psf-test/source/PsfTest-Bold.ufo/glyphs/D_igitT_wo.glif37
-rw-r--r--tests/input/font-psf-test/source/PsfTest-Bold.ufo/glyphs/D_igitZ_ero.glif37
-rw-r--r--tests/input/font-psf-test/source/PsfTest-Bold.ufo/glyphs/D_ollarS_gn.glif57
-rw-r--r--tests/input/font-psf-test/source/PsfTest-Bold.ufo/glyphs/D_ottedC_irc.glif235
-rw-r--r--tests/input/font-psf-test/source/PsfTest-Bold.ufo/glyphs/E_qS_gn.glif19
-rw-r--r--tests/input/font-psf-test/source/PsfTest-Bold.ufo/glyphs/E_xclamationM_rk.glif31
-rw-r--r--tests/input/font-psf-test/source/PsfTest-Bold.ufo/glyphs/F_ullS_top.glif21
-rw-r--r--tests/input/font-psf-test/source/PsfTest-Bold.ufo/glyphs/G_T_S_gn.glif16
-rw-r--r--tests/input/font-psf-test/source/PsfTest-Bold.ufo/glyphs/G_raveA_ccent.glif14
-rw-r--r--tests/input/font-psf-test/source/PsfTest-Bold.ufo/glyphs/H_yphen.glif14
-rw-r--r--tests/input/font-psf-test/source/PsfTest-Bold.ufo/glyphs/H_yphenM_inus.glif14
-rw-r--r--tests/input/font-psf-test/source/PsfTest-Bold.ufo/glyphs/H_yphen_S_oft.glif9
-rw-r--r--tests/input/font-psf-test/source/PsfTest-Bold.ufo/glyphs/L_T_S_gn.glif16
-rw-r--r--tests/input/font-psf-test/source/PsfTest-Bold.ufo/glyphs/L_ftC_urlyB_rac.glif47
-rw-r--r--tests/input/font-psf-test/source/PsfTest-Bold.ufo/glyphs/L_ftP_aren.glif23
-rw-r--r--tests/input/font-psf-test/source/PsfTest-Bold.ufo/glyphs/L_ftS_qrB_rac.glif17
-rw-r--r--tests/input/font-psf-test/source/PsfTest-Bold.ufo/glyphs/L_owL_ine.glif13
-rw-r--r--tests/input/font-psf-test/source/PsfTest-Bold.ufo/glyphs/L_tnC_apA_.alt.glif31
-rw-r--r--tests/input/font-psf-test/source/PsfTest-Bold.ufo/glyphs/L_tnC_apA_.glif32
-rw-r--r--tests/input/font-psf-test/source/PsfTest-Bold.ufo/glyphs/L_tnC_apA_D_iaer.glif13
-rw-r--r--tests/input/font-psf-test/source/PsfTest-Bold.ufo/glyphs/L_tnC_apB_.glif62
-rw-r--r--tests/input/font-psf-test/source/PsfTest-Bold.ufo/glyphs/L_tnC_apC_.glif38
-rw-r--r--tests/input/font-psf-test/source/PsfTest-Bold.ufo/glyphs/L_tnC_apD_.glif45
-rw-r--r--tests/input/font-psf-test/source/PsfTest-Bold.ufo/glyphs/L_tnC_apE_.glif35
-rw-r--r--tests/input/font-psf-test/source/PsfTest-Bold.ufo/glyphs/L_tnC_apF_.glif30
-rw-r--r--tests/input/font-psf-test/source/PsfTest-Bold.ufo/glyphs/L_tnC_apG_.glif42
-rw-r--r--tests/input/font-psf-test/source/PsfTest-Bold.ufo/glyphs/L_tnC_apH_.glif40
-rw-r--r--tests/input/font-psf-test/source/PsfTest-Bold.ufo/glyphs/L_tnC_apI_.glif26
-rw-r--r--tests/input/font-psf-test/source/PsfTest-Bold.ufo/glyphs/L_tnC_apJ_.glif32
-rw-r--r--tests/input/font-psf-test/source/PsfTest-Bold.ufo/glyphs/L_tnC_apK_.glif34
-rw-r--r--tests/input/font-psf-test/source/PsfTest-Bold.ufo/glyphs/L_tnC_apL_.glif28
-rw-r--r--tests/input/font-psf-test/source/PsfTest-Bold.ufo/glyphs/L_tnC_apM_.glif38
-rw-r--r--tests/input/font-psf-test/source/PsfTest-Bold.ufo/glyphs/L_tnC_apN_.glif37
-rw-r--r--tests/input/font-psf-test/source/PsfTest-Bold.ufo/glyphs/L_tnC_apO_.glif40
-rw-r--r--tests/input/font-psf-test/source/PsfTest-Bold.ufo/glyphs/L_tnC_apP_.glif50
-rw-r--r--tests/input/font-psf-test/source/PsfTest-Bold.ufo/glyphs/L_tnC_apQ_.glif49
-rw-r--r--tests/input/font-psf-test/source/PsfTest-Bold.ufo/glyphs/L_tnC_apR_.glif55
-rw-r--r--tests/input/font-psf-test/source/PsfTest-Bold.ufo/glyphs/L_tnC_apS_.glif50
-rw-r--r--tests/input/font-psf-test/source/PsfTest-Bold.ufo/glyphs/L_tnC_apT_.glif32
-rw-r--r--tests/input/font-psf-test/source/PsfTest-Bold.ufo/glyphs/L_tnC_apU_.glif38
-rw-r--r--tests/input/font-psf-test/source/PsfTest-Bold.ufo/glyphs/L_tnC_apV_.glif26
-rw-r--r--tests/input/font-psf-test/source/PsfTest-Bold.ufo/glyphs/L_tnC_apW_.glif45
-rw-r--r--tests/input/font-psf-test/source/PsfTest-Bold.ufo/glyphs/L_tnC_apX_.glif39
-rw-r--r--tests/input/font-psf-test/source/PsfTest-Bold.ufo/glyphs/L_tnC_apY_.glif39
-rw-r--r--tests/input/font-psf-test/source/PsfTest-Bold.ufo/glyphs/L_tnS_mA_.glif76
-rw-r--r--tests/input/font-psf-test/source/PsfTest-Bold.ufo/glyphs/L_tnS_mA_A_cute.glif14
-rw-r--r--tests/input/font-psf-test/source/PsfTest-Bold.ufo/glyphs/L_tnS_mA_C_ircum.glif14
-rw-r--r--tests/input/font-psf-test/source/PsfTest-Bold.ufo/glyphs/L_tnS_mA_D_iaer.glif14
-rw-r--r--tests/input/font-psf-test/source/PsfTest-Bold.ufo/glyphs/L_tnS_mA_G_rave.glif14
-rw-r--r--tests/input/font-psf-test/source/PsfTest-Bold.ufo/glyphs/L_tnS_mA_R_ingA_bv.glif14
-rw-r--r--tests/input/font-psf-test/source/PsfTest-Bold.ufo/glyphs/L_tnS_mA_T_ilde.glif14
-rw-r--r--tests/input/font-psf-test/source/PsfTest-Bold.ufo/glyphs/L_tnS_mB_.glif50
-rw-r--r--tests/input/font-psf-test/source/PsfTest-Bold.ufo/glyphs/L_tnS_mC_.glif39
-rw-r--r--tests/input/font-psf-test/source/PsfTest-Bold.ufo/glyphs/L_tnS_mD_.glif53
-rw-r--r--tests/input/font-psf-test/source/PsfTest-Bold.ufo/glyphs/L_tnS_mE_.glif45
-rw-r--r--tests/input/font-psf-test/source/PsfTest-Bold.ufo/glyphs/L_tnS_mF_.glif39
-rw-r--r--tests/input/font-psf-test/source/PsfTest-Bold.ufo/glyphs/L_tnS_mG_.glif91
-rw-r--r--tests/input/font-psf-test/source/PsfTest-Bold.ufo/glyphs/L_tnS_mH_.glif43
-rw-r--r--tests/input/font-psf-test/source/PsfTest-Bold.ufo/glyphs/L_tnS_mI_.glif42
-rw-r--r--tests/input/font-psf-test/source/PsfTest-Bold.ufo/glyphs/L_tnS_mJ_.glif44
-rw-r--r--tests/input/font-psf-test/source/PsfTest-Bold.ufo/glyphs/L_tnS_mK_.glif34
-rw-r--r--tests/input/font-psf-test/source/PsfTest-Bold.ufo/glyphs/L_tnS_mL_.glif23
-rw-r--r--tests/input/font-psf-test/source/PsfTest-Bold.ufo/glyphs/L_tnS_mM_.glif52
-rw-r--r--tests/input/font-psf-test/source/PsfTest-Bold.ufo/glyphs/L_tnS_mN_.glif43
-rw-r--r--tests/input/font-psf-test/source/PsfTest-Bold.ufo/glyphs/L_tnS_mO_.glif40
-rw-r--r--tests/input/font-psf-test/source/PsfTest-Bold.ufo/glyphs/L_tnS_mP_.glif59
-rw-r--r--tests/input/font-psf-test/source/PsfTest-Bold.ufo/glyphs/L_tnS_mQ_.glif47
-rw-r--r--tests/input/font-psf-test/source/PsfTest-Bold.ufo/glyphs/L_tnS_mR_.glif35
-rw-r--r--tests/input/font-psf-test/source/PsfTest-Bold.ufo/glyphs/L_tnS_mS_.glif50
-rw-r--r--tests/input/font-psf-test/source/PsfTest-Bold.ufo/glyphs/L_tnS_mT_.glif35
-rw-r--r--tests/input/font-psf-test/source/PsfTest-Bold.ufo/glyphs/L_tnS_mU_.glif51
-rw-r--r--tests/input/font-psf-test/source/PsfTest-Bold.ufo/glyphs/L_tnS_mV_.glif30
-rw-r--r--tests/input/font-psf-test/source/PsfTest-Bold.ufo/glyphs/L_tnS_mW_.glif30
-rw-r--r--tests/input/font-psf-test/source/PsfTest-Bold.ufo/glyphs/L_tnS_mX_.glif40
-rw-r--r--tests/input/font-psf-test/source/PsfTest-Bold.ufo/glyphs/L_tnS_mY_.glif39
-rw-r--r--tests/input/font-psf-test/source/PsfTest-Bold.ufo/glyphs/N_onB_reakingH_yphen.glif9
-rw-r--r--tests/input/font-psf-test/source/PsfTest-Bold.ufo/glyphs/N_umS_gn.glif31
-rw-r--r--tests/input/font-psf-test/source/PsfTest-Bold.ufo/glyphs/P_ercentS_gn.glif69
-rw-r--r--tests/input/font-psf-test/source/PsfTest-Bold.ufo/glyphs/P_lusS_gn.glif19
-rw-r--r--tests/input/font-psf-test/source/PsfTest-Bold.ufo/glyphs/Q_stnM_rk.glif49
-rw-r--r--tests/input/font-psf-test/source/PsfTest-Bold.ufo/glyphs/Q_uotM_rk.glif27
-rw-r--r--tests/input/font-psf-test/source/PsfTest-Bold.ufo/glyphs/R_everseS_olidus.glif13
-rw-r--r--tests/input/font-psf-test/source/PsfTest-Bold.ufo/glyphs/R_tC_urlyB_rac.glif47
-rw-r--r--tests/input/font-psf-test/source/PsfTest-Bold.ufo/glyphs/R_tP_aren.glif23
-rw-r--r--tests/input/font-psf-test/source/PsfTest-Bold.ufo/glyphs/R_tS_qrB_rac.glif17
-rw-r--r--tests/input/font-psf-test/source/PsfTest-Bold.ufo/glyphs/S_emicolon.glif38
-rw-r--r--tests/input/font-psf-test/source/PsfTest-Bold.ufo/glyphs/S_olidus.glif13
-rw-r--r--tests/input/font-psf-test/source/PsfTest-Bold.ufo/glyphs/S_pace.glif6
-rw-r--r--tests/input/font-psf-test/source/PsfTest-Bold.ufo/glyphs/T_ilde.glif29
-rw-r--r--tests/input/font-psf-test/source/PsfTest-Bold.ufo/glyphs/V_ertL_ine.glif13
-rw-r--r--tests/input/font-psf-test/source/PsfTest-Bold.ufo/glyphs/_notdef.glif18
-rw-r--r--tests/input/font-psf-test/source/PsfTest-Bold.ufo/glyphs/_null.glif4
-rw-r--r--tests/input/font-psf-test/source/PsfTest-Bold.ufo/glyphs/contents.plist234
-rw-r--r--tests/input/font-psf-test/source/PsfTest-Bold.ufo/glyphs/nonmarkingreturn.glif5
-rw-r--r--tests/input/font-psf-test/source/PsfTest-Bold.ufo/layercontents.plist10
-rw-r--r--tests/input/font-psf-test/source/PsfTest-Bold.ufo/lib.plist535
-rw-r--r--tests/input/font-psf-test/source/PsfTest-Bold.ufo/metainfo.plist10
-rw-r--r--tests/input/font-psf-test/source/PsfTest-BoldItalic.ufo/fontinfo.plist245
-rw-r--r--tests/input/font-psf-test/source/PsfTest-BoldItalic.ufo/glyphs/A_mpersand.glif61
-rw-r--r--tests/input/font-psf-test/source/PsfTest-BoldItalic.ufo/glyphs/A_pos.glif17
-rw-r--r--tests/input/font-psf-test/source/PsfTest-BoldItalic.ufo/glyphs/A_sterisk.glif51
-rw-r--r--tests/input/font-psf-test/source/PsfTest-BoldItalic.ufo/glyphs/A_tS_gn.glif104
-rw-r--r--tests/input/font-psf-test/source/PsfTest-BoldItalic.ufo/glyphs/C_ircumA_ccent.glif17
-rw-r--r--tests/input/font-psf-test/source/PsfTest-BoldItalic.ufo/glyphs/C_olon.glif35
-rw-r--r--tests/input/font-psf-test/source/PsfTest-BoldItalic.ufo/glyphs/C_ombA_cute.glif14
-rw-r--r--tests/input/font-psf-test/source/PsfTest-BoldItalic.ufo/glyphs/C_ombC_ircum.glif17
-rw-r--r--tests/input/font-psf-test/source/PsfTest-BoldItalic.ufo/glyphs/C_ombD_iaer.glif36
-rw-r--r--tests/input/font-psf-test/source/PsfTest-BoldItalic.ufo/glyphs/C_ombG_rave.glif14
-rw-r--r--tests/input/font-psf-test/source/PsfTest-BoldItalic.ufo/glyphs/C_ombR_ingA_bv.glif36
-rw-r--r--tests/input/font-psf-test/source/PsfTest-BoldItalic.ufo/glyphs/C_ombT_ilde.glif36
-rw-r--r--tests/input/font-psf-test/source/PsfTest-BoldItalic.ufo/glyphs/C_omma.glif24
-rw-r--r--tests/input/font-psf-test/source/PsfTest-BoldItalic.ufo/glyphs/D_igitE_ight.glif63
-rw-r--r--tests/input/font-psf-test/source/PsfTest-BoldItalic.ufo/glyphs/D_igitF_ive.glif44
-rw-r--r--tests/input/font-psf-test/source/PsfTest-BoldItalic.ufo/glyphs/D_igitF_our.glif27
-rw-r--r--tests/input/font-psf-test/source/PsfTest-BoldItalic.ufo/glyphs/D_igitN_ine.glif49
-rw-r--r--tests/input/font-psf-test/source/PsfTest-BoldItalic.ufo/glyphs/D_igitO_ne.glif22
-rw-r--r--tests/input/font-psf-test/source/PsfTest-BoldItalic.ufo/glyphs/D_igitS_even.glif25
-rw-r--r--tests/input/font-psf-test/source/PsfTest-BoldItalic.ufo/glyphs/D_igitS_ix.glif49
-rw-r--r--tests/input/font-psf-test/source/PsfTest-BoldItalic.ufo/glyphs/D_igitT_hree.glif52
-rw-r--r--tests/input/font-psf-test/source/PsfTest-BoldItalic.ufo/glyphs/D_igitT_wo.glif37
-rw-r--r--tests/input/font-psf-test/source/PsfTest-BoldItalic.ufo/glyphs/D_igitZ_ero.glif49
-rw-r--r--tests/input/font-psf-test/source/PsfTest-BoldItalic.ufo/glyphs/D_ollarS_gn.glif57
-rw-r--r--tests/input/font-psf-test/source/PsfTest-BoldItalic.ufo/glyphs/D_ottedC_irc.glif235
-rw-r--r--tests/input/font-psf-test/source/PsfTest-BoldItalic.ufo/glyphs/E_qS_gn.glif19
-rw-r--r--tests/input/font-psf-test/source/PsfTest-BoldItalic.ufo/glyphs/E_xclamationM_rk.glif31
-rw-r--r--tests/input/font-psf-test/source/PsfTest-BoldItalic.ufo/glyphs/F_ullS_top.glif21
-rw-r--r--tests/input/font-psf-test/source/PsfTest-BoldItalic.ufo/glyphs/G_T_S_gn.glif16
-rw-r--r--tests/input/font-psf-test/source/PsfTest-BoldItalic.ufo/glyphs/G_raveA_ccent.glif14
-rw-r--r--tests/input/font-psf-test/source/PsfTest-BoldItalic.ufo/glyphs/H_yphen.glif14
-rw-r--r--tests/input/font-psf-test/source/PsfTest-BoldItalic.ufo/glyphs/H_yphenM_inus.glif14
-rw-r--r--tests/input/font-psf-test/source/PsfTest-BoldItalic.ufo/glyphs/H_yphen_S_oft.glif9
-rw-r--r--tests/input/font-psf-test/source/PsfTest-BoldItalic.ufo/glyphs/L_T_S_gn.glif16
-rw-r--r--tests/input/font-psf-test/source/PsfTest-BoldItalic.ufo/glyphs/L_ftC_urlyB_rac.glif50
-rw-r--r--tests/input/font-psf-test/source/PsfTest-BoldItalic.ufo/glyphs/L_ftP_aren.glif29
-rw-r--r--tests/input/font-psf-test/source/PsfTest-BoldItalic.ufo/glyphs/L_ftS_qrB_rac.glif17
-rw-r--r--tests/input/font-psf-test/source/PsfTest-BoldItalic.ufo/glyphs/L_owL_ine.glif13
-rw-r--r--tests/input/font-psf-test/source/PsfTest-BoldItalic.ufo/glyphs/L_tnC_apA_.glif32
-rw-r--r--tests/input/font-psf-test/source/PsfTest-BoldItalic.ufo/glyphs/L_tnC_apA_D_iaer.glif13
-rw-r--r--tests/input/font-psf-test/source/PsfTest-BoldItalic.ufo/glyphs/L_tnC_apB_.glif62
-rw-r--r--tests/input/font-psf-test/source/PsfTest-BoldItalic.ufo/glyphs/L_tnC_apC_.glif38
-rw-r--r--tests/input/font-psf-test/source/PsfTest-BoldItalic.ufo/glyphs/L_tnC_apD_.glif51
-rw-r--r--tests/input/font-psf-test/source/PsfTest-BoldItalic.ufo/glyphs/L_tnC_apE_.glif35
-rw-r--r--tests/input/font-psf-test/source/PsfTest-BoldItalic.ufo/glyphs/L_tnC_apF_.glif30
-rw-r--r--tests/input/font-psf-test/source/PsfTest-BoldItalic.ufo/glyphs/L_tnC_apG_.glif48
-rw-r--r--tests/input/font-psf-test/source/PsfTest-BoldItalic.ufo/glyphs/L_tnC_apH_.glif40
-rw-r--r--tests/input/font-psf-test/source/PsfTest-BoldItalic.ufo/glyphs/L_tnC_apI_.glif26
-rw-r--r--tests/input/font-psf-test/source/PsfTest-BoldItalic.ufo/glyphs/L_tnC_apJ_.glif32
-rw-r--r--tests/input/font-psf-test/source/PsfTest-BoldItalic.ufo/glyphs/L_tnC_apK_.glif35
-rw-r--r--tests/input/font-psf-test/source/PsfTest-BoldItalic.ufo/glyphs/L_tnC_apL_.glif28
-rw-r--r--tests/input/font-psf-test/source/PsfTest-BoldItalic.ufo/glyphs/L_tnC_apM_.glif38
-rw-r--r--tests/input/font-psf-test/source/PsfTest-BoldItalic.ufo/glyphs/L_tnC_apN_.glif37
-rw-r--r--tests/input/font-psf-test/source/PsfTest-BoldItalic.ufo/glyphs/L_tnC_apO_.glif40
-rw-r--r--tests/input/font-psf-test/source/PsfTest-BoldItalic.ufo/glyphs/L_tnC_apP_.glif50
-rw-r--r--tests/input/font-psf-test/source/PsfTest-BoldItalic.ufo/glyphs/L_tnC_apQ_.glif52
-rw-r--r--tests/input/font-psf-test/source/PsfTest-BoldItalic.ufo/glyphs/L_tnC_apR_.glif55
-rw-r--r--tests/input/font-psf-test/source/PsfTest-BoldItalic.ufo/glyphs/L_tnC_apS_.glif50
-rw-r--r--tests/input/font-psf-test/source/PsfTest-BoldItalic.ufo/glyphs/L_tnC_apT_.glif32
-rw-r--r--tests/input/font-psf-test/source/PsfTest-BoldItalic.ufo/glyphs/L_tnC_apU_.glif44
-rw-r--r--tests/input/font-psf-test/source/PsfTest-BoldItalic.ufo/glyphs/L_tnC_apV_.glif26
-rw-r--r--tests/input/font-psf-test/source/PsfTest-BoldItalic.ufo/glyphs/L_tnC_apW_.glif45
-rw-r--r--tests/input/font-psf-test/source/PsfTest-BoldItalic.ufo/glyphs/L_tnC_apX_.glif39
-rw-r--r--tests/input/font-psf-test/source/PsfTest-BoldItalic.ufo/glyphs/L_tnC_apY_.glif39
-rw-r--r--tests/input/font-psf-test/source/PsfTest-BoldItalic.ufo/glyphs/L_tnS_mA_.glif79
-rw-r--r--tests/input/font-psf-test/source/PsfTest-BoldItalic.ufo/glyphs/L_tnS_mA_A_cute.glif14
-rw-r--r--tests/input/font-psf-test/source/PsfTest-BoldItalic.ufo/glyphs/L_tnS_mA_C_ircum.glif14
-rw-r--r--tests/input/font-psf-test/source/PsfTest-BoldItalic.ufo/glyphs/L_tnS_mA_D_iaer.glif14
-rw-r--r--tests/input/font-psf-test/source/PsfTest-BoldItalic.ufo/glyphs/L_tnS_mA_G_rave.glif14
-rw-r--r--tests/input/font-psf-test/source/PsfTest-BoldItalic.ufo/glyphs/L_tnS_mA_R_ingA_bv.glif14
-rw-r--r--tests/input/font-psf-test/source/PsfTest-BoldItalic.ufo/glyphs/L_tnS_mA_T_ilde.glif14
-rw-r--r--tests/input/font-psf-test/source/PsfTest-BoldItalic.ufo/glyphs/L_tnS_mB_.glif55
-rw-r--r--tests/input/font-psf-test/source/PsfTest-BoldItalic.ufo/glyphs/L_tnS_mC_.glif39
-rw-r--r--tests/input/font-psf-test/source/PsfTest-BoldItalic.ufo/glyphs/L_tnS_mD_.glif65
-rw-r--r--tests/input/font-psf-test/source/PsfTest-BoldItalic.ufo/glyphs/L_tnS_mE_.glif52
-rw-r--r--tests/input/font-psf-test/source/PsfTest-BoldItalic.ufo/glyphs/L_tnS_mF_.glif44
-rw-r--r--tests/input/font-psf-test/source/PsfTest-BoldItalic.ufo/glyphs/L_tnS_mG_.glif91
-rw-r--r--tests/input/font-psf-test/source/PsfTest-BoldItalic.ufo/glyphs/L_tnS_mH_.glif54
-rw-r--r--tests/input/font-psf-test/source/PsfTest-BoldItalic.ufo/glyphs/L_tnS_mI_.glif50
-rw-r--r--tests/input/font-psf-test/source/PsfTest-BoldItalic.ufo/glyphs/L_tnS_mJ_.glif45
-rw-r--r--tests/input/font-psf-test/source/PsfTest-BoldItalic.ufo/glyphs/L_tnS_mK_.glif45
-rw-r--r--tests/input/font-psf-test/source/PsfTest-BoldItalic.ufo/glyphs/L_tnS_mL_.glif35
-rw-r--r--tests/input/font-psf-test/source/PsfTest-BoldItalic.ufo/glyphs/L_tnS_mM_.glif80
-rw-r--r--tests/input/font-psf-test/source/PsfTest-BoldItalic.ufo/glyphs/L_tnS_mN_.glif57
-rw-r--r--tests/input/font-psf-test/source/PsfTest-BoldItalic.ufo/glyphs/L_tnS_mO_.glif40
-rw-r--r--tests/input/font-psf-test/source/PsfTest-BoldItalic.ufo/glyphs/L_tnS_mP_.glif66
-rw-r--r--tests/input/font-psf-test/source/PsfTest-BoldItalic.ufo/glyphs/L_tnS_mQ_.glif54
-rw-r--r--tests/input/font-psf-test/source/PsfTest-BoldItalic.ufo/glyphs/L_tnS_mR_.glif42
-rw-r--r--tests/input/font-psf-test/source/PsfTest-BoldItalic.ufo/glyphs/L_tnS_mS_.glif50
-rw-r--r--tests/input/font-psf-test/source/PsfTest-BoldItalic.ufo/glyphs/L_tnS_mT_.glif45
-rw-r--r--tests/input/font-psf-test/source/PsfTest-BoldItalic.ufo/glyphs/L_tnS_mU_.glif57
-rw-r--r--tests/input/font-psf-test/source/PsfTest-BoldItalic.ufo/glyphs/L_tnS_mV_.glif34
-rw-r--r--tests/input/font-psf-test/source/PsfTest-BoldItalic.ufo/glyphs/L_tnS_mW_.glif50
-rw-r--r--tests/input/font-psf-test/source/PsfTest-BoldItalic.ufo/glyphs/L_tnS_mX_.glif40
-rw-r--r--tests/input/font-psf-test/source/PsfTest-BoldItalic.ufo/glyphs/L_tnS_mY_.glif45
-rw-r--r--tests/input/font-psf-test/source/PsfTest-BoldItalic.ufo/glyphs/N_onB_reakingH_yphen.glif9
-rw-r--r--tests/input/font-psf-test/source/PsfTest-BoldItalic.ufo/glyphs/N_umS_gn.glif31
-rw-r--r--tests/input/font-psf-test/source/PsfTest-BoldItalic.ufo/glyphs/P_ercentS_gn.glif93
-rw-r--r--tests/input/font-psf-test/source/PsfTest-BoldItalic.ufo/glyphs/P_lusS_gn.glif19
-rw-r--r--tests/input/font-psf-test/source/PsfTest-BoldItalic.ufo/glyphs/Q_stnM_rk.glif49
-rw-r--r--tests/input/font-psf-test/source/PsfTest-BoldItalic.ufo/glyphs/Q_uotM_rk.glif27
-rw-r--r--tests/input/font-psf-test/source/PsfTest-BoldItalic.ufo/glyphs/R_everseS_olidus.glif13
-rw-r--r--tests/input/font-psf-test/source/PsfTest-BoldItalic.ufo/glyphs/R_tC_urlyB_rac.glif47
-rw-r--r--tests/input/font-psf-test/source/PsfTest-BoldItalic.ufo/glyphs/R_tP_aren.glif29
-rw-r--r--tests/input/font-psf-test/source/PsfTest-BoldItalic.ufo/glyphs/R_tS_qrB_rac.glif17
-rw-r--r--tests/input/font-psf-test/source/PsfTest-BoldItalic.ufo/glyphs/S_emicolon.glif38
-rw-r--r--tests/input/font-psf-test/source/PsfTest-BoldItalic.ufo/glyphs/S_olidus.glif13
-rw-r--r--tests/input/font-psf-test/source/PsfTest-BoldItalic.ufo/glyphs/S_pace.glif6
-rw-r--r--tests/input/font-psf-test/source/PsfTest-BoldItalic.ufo/glyphs/T_ilde.glif29
-rw-r--r--tests/input/font-psf-test/source/PsfTest-BoldItalic.ufo/glyphs/V_ertL_ine.glif13
-rw-r--r--tests/input/font-psf-test/source/PsfTest-BoldItalic.ufo/glyphs/_notdef.glif18
-rw-r--r--tests/input/font-psf-test/source/PsfTest-BoldItalic.ufo/glyphs/_null.glif4
-rw-r--r--tests/input/font-psf-test/source/PsfTest-BoldItalic.ufo/glyphs/contents.plist232
-rw-r--r--tests/input/font-psf-test/source/PsfTest-BoldItalic.ufo/glyphs/nonmarkingreturn.glif5
-rw-r--r--tests/input/font-psf-test/source/PsfTest-BoldItalic.ufo/layercontents.plist10
-rw-r--r--tests/input/font-psf-test/source/PsfTest-BoldItalic.ufo/lib.plist538
-rw-r--r--tests/input/font-psf-test/source/PsfTest-BoldItalic.ufo/metainfo.plist10
-rw-r--r--tests/input/font-psf-test/source/PsfTest-Italic.ufo/fontinfo.plist243
-rw-r--r--tests/input/font-psf-test/source/PsfTest-Italic.ufo/glyphs/A_mpersand.glif61
-rw-r--r--tests/input/font-psf-test/source/PsfTest-Italic.ufo/glyphs/A_pos.glif17
-rw-r--r--tests/input/font-psf-test/source/PsfTest-Italic.ufo/glyphs/A_sterisk.glif51
-rw-r--r--tests/input/font-psf-test/source/PsfTest-Italic.ufo/glyphs/A_tS_gn.glif104
-rw-r--r--tests/input/font-psf-test/source/PsfTest-Italic.ufo/glyphs/C_ircumA_ccent.glif17
-rw-r--r--tests/input/font-psf-test/source/PsfTest-Italic.ufo/glyphs/C_olon.glif35
-rw-r--r--tests/input/font-psf-test/source/PsfTest-Italic.ufo/glyphs/C_ombA_cute.glif14
-rw-r--r--tests/input/font-psf-test/source/PsfTest-Italic.ufo/glyphs/C_ombC_ircum.glif17
-rw-r--r--tests/input/font-psf-test/source/PsfTest-Italic.ufo/glyphs/C_ombD_iaer.glif36
-rw-r--r--tests/input/font-psf-test/source/PsfTest-Italic.ufo/glyphs/C_ombG_rave.glif14
-rw-r--r--tests/input/font-psf-test/source/PsfTest-Italic.ufo/glyphs/C_ombR_ingA_bv.glif36
-rw-r--r--tests/input/font-psf-test/source/PsfTest-Italic.ufo/glyphs/C_ombT_ilde.glif36
-rw-r--r--tests/input/font-psf-test/source/PsfTest-Italic.ufo/glyphs/C_omma.glif24
-rw-r--r--tests/input/font-psf-test/source/PsfTest-Italic.ufo/glyphs/D_igitE_ight.glif63
-rw-r--r--tests/input/font-psf-test/source/PsfTest-Italic.ufo/glyphs/D_igitF_ive.glif44
-rw-r--r--tests/input/font-psf-test/source/PsfTest-Italic.ufo/glyphs/D_igitF_our.glif27
-rw-r--r--tests/input/font-psf-test/source/PsfTest-Italic.ufo/glyphs/D_igitN_ine.glif49
-rw-r--r--tests/input/font-psf-test/source/PsfTest-Italic.ufo/glyphs/D_igitO_ne.glif22
-rw-r--r--tests/input/font-psf-test/source/PsfTest-Italic.ufo/glyphs/D_igitS_even.glif25
-rw-r--r--tests/input/font-psf-test/source/PsfTest-Italic.ufo/glyphs/D_igitS_ix.glif49
-rw-r--r--tests/input/font-psf-test/source/PsfTest-Italic.ufo/glyphs/D_igitT_hree.glif52
-rw-r--r--tests/input/font-psf-test/source/PsfTest-Italic.ufo/glyphs/D_igitT_wo.glif37
-rw-r--r--tests/input/font-psf-test/source/PsfTest-Italic.ufo/glyphs/D_igitZ_ero.glif49
-rw-r--r--tests/input/font-psf-test/source/PsfTest-Italic.ufo/glyphs/D_ollarS_gn.glif53
-rw-r--r--tests/input/font-psf-test/source/PsfTest-Italic.ufo/glyphs/D_ottedC_irc.glif235
-rw-r--r--tests/input/font-psf-test/source/PsfTest-Italic.ufo/glyphs/E_qS_gn.glif19
-rw-r--r--tests/input/font-psf-test/source/PsfTest-Italic.ufo/glyphs/E_xclamationM_rk.glif31
-rw-r--r--tests/input/font-psf-test/source/PsfTest-Italic.ufo/glyphs/F_ullS_top.glif21
-rw-r--r--tests/input/font-psf-test/source/PsfTest-Italic.ufo/glyphs/G_T_S_gn.glif16
-rw-r--r--tests/input/font-psf-test/source/PsfTest-Italic.ufo/glyphs/G_raveA_ccent.glif14
-rw-r--r--tests/input/font-psf-test/source/PsfTest-Italic.ufo/glyphs/H_yphen.glif14
-rw-r--r--tests/input/font-psf-test/source/PsfTest-Italic.ufo/glyphs/H_yphenM_inus.glif14
-rw-r--r--tests/input/font-psf-test/source/PsfTest-Italic.ufo/glyphs/H_yphen_S_oft.glif9
-rw-r--r--tests/input/font-psf-test/source/PsfTest-Italic.ufo/glyphs/L_T_S_gn.glif16
-rw-r--r--tests/input/font-psf-test/source/PsfTest-Italic.ufo/glyphs/L_ftC_urlyB_rac.glif50
-rw-r--r--tests/input/font-psf-test/source/PsfTest-Italic.ufo/glyphs/L_ftP_aren.glif29
-rw-r--r--tests/input/font-psf-test/source/PsfTest-Italic.ufo/glyphs/L_ftS_qrB_rac.glif17
-rw-r--r--tests/input/font-psf-test/source/PsfTest-Italic.ufo/glyphs/L_owL_ine.glif13
-rw-r--r--tests/input/font-psf-test/source/PsfTest-Italic.ufo/glyphs/L_tnC_apA_.glif32
-rw-r--r--tests/input/font-psf-test/source/PsfTest-Italic.ufo/glyphs/L_tnC_apA_D_iaer.glif13
-rw-r--r--tests/input/font-psf-test/source/PsfTest-Italic.ufo/glyphs/L_tnC_apB_.glif62
-rw-r--r--tests/input/font-psf-test/source/PsfTest-Italic.ufo/glyphs/L_tnC_apC_.glif38
-rw-r--r--tests/input/font-psf-test/source/PsfTest-Italic.ufo/glyphs/L_tnC_apD_.glif51
-rw-r--r--tests/input/font-psf-test/source/PsfTest-Italic.ufo/glyphs/L_tnC_apE_.glif35
-rw-r--r--tests/input/font-psf-test/source/PsfTest-Italic.ufo/glyphs/L_tnC_apF_.glif30
-rw-r--r--tests/input/font-psf-test/source/PsfTest-Italic.ufo/glyphs/L_tnC_apG_.glif48
-rw-r--r--tests/input/font-psf-test/source/PsfTest-Italic.ufo/glyphs/L_tnC_apH_.glif36
-rw-r--r--tests/input/font-psf-test/source/PsfTest-Italic.ufo/glyphs/L_tnC_apI_.glif26
-rw-r--r--tests/input/font-psf-test/source/PsfTest-Italic.ufo/glyphs/L_tnC_apJ_.glif30
-rw-r--r--tests/input/font-psf-test/source/PsfTest-Italic.ufo/glyphs/L_tnC_apK_.glif35
-rw-r--r--tests/input/font-psf-test/source/PsfTest-Italic.ufo/glyphs/L_tnC_apL_.glif28
-rw-r--r--tests/input/font-psf-test/source/PsfTest-Italic.ufo/glyphs/L_tnC_apM_.glif36
-rw-r--r--tests/input/font-psf-test/source/PsfTest-Italic.ufo/glyphs/L_tnC_apN_.glif37
-rw-r--r--tests/input/font-psf-test/source/PsfTest-Italic.ufo/glyphs/L_tnC_apO_.glif40
-rw-r--r--tests/input/font-psf-test/source/PsfTest-Italic.ufo/glyphs/L_tnC_apP_.glif50
-rw-r--r--tests/input/font-psf-test/source/PsfTest-Italic.ufo/glyphs/L_tnC_apQ_.glif52
-rw-r--r--tests/input/font-psf-test/source/PsfTest-Italic.ufo/glyphs/L_tnC_apR_.glif55
-rw-r--r--tests/input/font-psf-test/source/PsfTest-Italic.ufo/glyphs/L_tnC_apS_.glif50
-rw-r--r--tests/input/font-psf-test/source/PsfTest-Italic.ufo/glyphs/L_tnC_apT_.glif32
-rw-r--r--tests/input/font-psf-test/source/PsfTest-Italic.ufo/glyphs/L_tnC_apU_.glif44
-rw-r--r--tests/input/font-psf-test/source/PsfTest-Italic.ufo/glyphs/L_tnC_apV_.glif26
-rw-r--r--tests/input/font-psf-test/source/PsfTest-Italic.ufo/glyphs/L_tnC_apW_.glif44
-rw-r--r--tests/input/font-psf-test/source/PsfTest-Italic.ufo/glyphs/L_tnC_apX_.glif39
-rw-r--r--tests/input/font-psf-test/source/PsfTest-Italic.ufo/glyphs/L_tnC_apY_.glif39
-rw-r--r--tests/input/font-psf-test/source/PsfTest-Italic.ufo/glyphs/L_tnS_mA_.glif77
-rw-r--r--tests/input/font-psf-test/source/PsfTest-Italic.ufo/glyphs/L_tnS_mA_A_cute.glif14
-rw-r--r--tests/input/font-psf-test/source/PsfTest-Italic.ufo/glyphs/L_tnS_mA_C_ircum.glif14
-rw-r--r--tests/input/font-psf-test/source/PsfTest-Italic.ufo/glyphs/L_tnS_mA_D_iaer.glif14
-rw-r--r--tests/input/font-psf-test/source/PsfTest-Italic.ufo/glyphs/L_tnS_mA_G_rave.glif14
-rw-r--r--tests/input/font-psf-test/source/PsfTest-Italic.ufo/glyphs/L_tnS_mA_R_ingA_bv.glif14
-rw-r--r--tests/input/font-psf-test/source/PsfTest-Italic.ufo/glyphs/L_tnS_mA_T_ilde.glif14
-rw-r--r--tests/input/font-psf-test/source/PsfTest-Italic.ufo/glyphs/L_tnS_mB_.glif55
-rw-r--r--tests/input/font-psf-test/source/PsfTest-Italic.ufo/glyphs/L_tnS_mC_.glif39
-rw-r--r--tests/input/font-psf-test/source/PsfTest-Italic.ufo/glyphs/L_tnS_mD_.glif65
-rw-r--r--tests/input/font-psf-test/source/PsfTest-Italic.ufo/glyphs/L_tnS_mE_.glif52
-rw-r--r--tests/input/font-psf-test/source/PsfTest-Italic.ufo/glyphs/L_tnS_mF_.glif44
-rw-r--r--tests/input/font-psf-test/source/PsfTest-Italic.ufo/glyphs/L_tnS_mG_.glif100
-rw-r--r--tests/input/font-psf-test/source/PsfTest-Italic.ufo/glyphs/L_tnS_mH_.glif54
-rw-r--r--tests/input/font-psf-test/source/PsfTest-Italic.ufo/glyphs/L_tnS_mI_.glif50
-rw-r--r--tests/input/font-psf-test/source/PsfTest-Italic.ufo/glyphs/L_tnS_mJ_.glif45
-rw-r--r--tests/input/font-psf-test/source/PsfTest-Italic.ufo/glyphs/L_tnS_mK_.glif50
-rw-r--r--tests/input/font-psf-test/source/PsfTest-Italic.ufo/glyphs/L_tnS_mL_.glif35
-rw-r--r--tests/input/font-psf-test/source/PsfTest-Italic.ufo/glyphs/L_tnS_mM_.glif80
-rw-r--r--tests/input/font-psf-test/source/PsfTest-Italic.ufo/glyphs/L_tnS_mN_.glif57
-rw-r--r--tests/input/font-psf-test/source/PsfTest-Italic.ufo/glyphs/L_tnS_mO_.glif40
-rw-r--r--tests/input/font-psf-test/source/PsfTest-Italic.ufo/glyphs/L_tnS_mP_.glif66
-rw-r--r--tests/input/font-psf-test/source/PsfTest-Italic.ufo/glyphs/L_tnS_mQ_.glif54
-rw-r--r--tests/input/font-psf-test/source/PsfTest-Italic.ufo/glyphs/L_tnS_mR_.glif42
-rw-r--r--tests/input/font-psf-test/source/PsfTest-Italic.ufo/glyphs/L_tnS_mS_.glif50
-rw-r--r--tests/input/font-psf-test/source/PsfTest-Italic.ufo/glyphs/L_tnS_mT_.glif45
-rw-r--r--tests/input/font-psf-test/source/PsfTest-Italic.ufo/glyphs/L_tnS_mU_.glif57
-rw-r--r--tests/input/font-psf-test/source/PsfTest-Italic.ufo/glyphs/L_tnS_mV_.glif34
-rw-r--r--tests/input/font-psf-test/source/PsfTest-Italic.ufo/glyphs/L_tnS_mW_.glif50
-rw-r--r--tests/input/font-psf-test/source/PsfTest-Italic.ufo/glyphs/L_tnS_mX_.glif40
-rw-r--r--tests/input/font-psf-test/source/PsfTest-Italic.ufo/glyphs/L_tnS_mY_.glif45
-rw-r--r--tests/input/font-psf-test/source/PsfTest-Italic.ufo/glyphs/N_onB_reakingH_yphen.glif9
-rw-r--r--tests/input/font-psf-test/source/PsfTest-Italic.ufo/glyphs/N_umS_gn.glif31
-rw-r--r--tests/input/font-psf-test/source/PsfTest-Italic.ufo/glyphs/P_ercentS_gn.glif93
-rw-r--r--tests/input/font-psf-test/source/PsfTest-Italic.ufo/glyphs/P_lusS_gn.glif19
-rw-r--r--tests/input/font-psf-test/source/PsfTest-Italic.ufo/glyphs/Q_stnM_rk.glif49
-rw-r--r--tests/input/font-psf-test/source/PsfTest-Italic.ufo/glyphs/Q_uotM_rk.glif27
-rw-r--r--tests/input/font-psf-test/source/PsfTest-Italic.ufo/glyphs/R_everseS_olidus.glif13
-rw-r--r--tests/input/font-psf-test/source/PsfTest-Italic.ufo/glyphs/R_tC_urlyB_rac.glif50
-rw-r--r--tests/input/font-psf-test/source/PsfTest-Italic.ufo/glyphs/R_tP_aren.glif29
-rw-r--r--tests/input/font-psf-test/source/PsfTest-Italic.ufo/glyphs/R_tS_qrB_rac.glif17
-rw-r--r--tests/input/font-psf-test/source/PsfTest-Italic.ufo/glyphs/S_emicolon.glif38
-rw-r--r--tests/input/font-psf-test/source/PsfTest-Italic.ufo/glyphs/S_olidus.glif13
-rw-r--r--tests/input/font-psf-test/source/PsfTest-Italic.ufo/glyphs/S_pace.glif6
-rw-r--r--tests/input/font-psf-test/source/PsfTest-Italic.ufo/glyphs/T_ilde.glif29
-rw-r--r--tests/input/font-psf-test/source/PsfTest-Italic.ufo/glyphs/V_ertL_ine.glif13
-rw-r--r--tests/input/font-psf-test/source/PsfTest-Italic.ufo/glyphs/_notdef.glif18
-rw-r--r--tests/input/font-psf-test/source/PsfTest-Italic.ufo/glyphs/_null.glif4
-rw-r--r--tests/input/font-psf-test/source/PsfTest-Italic.ufo/glyphs/contents.plist232
-rw-r--r--tests/input/font-psf-test/source/PsfTest-Italic.ufo/glyphs/nonmarkingreturn.glif5
-rw-r--r--tests/input/font-psf-test/source/PsfTest-Italic.ufo/layercontents.plist10
-rw-r--r--tests/input/font-psf-test/source/PsfTest-Italic.ufo/lib.plist538
-rw-r--r--tests/input/font-psf-test/source/PsfTest-Italic.ufo/metainfo.plist10
-rw-r--r--tests/input/font-psf-test/source/PsfTest-Regular.ufo/fontinfo.plist260
-rw-r--r--tests/input/font-psf-test/source/PsfTest-Regular.ufo/glyphs/A_mpersand.glif61
-rw-r--r--tests/input/font-psf-test/source/PsfTest-Regular.ufo/glyphs/A_pos.glif17
-rw-r--r--tests/input/font-psf-test/source/PsfTest-Regular.ufo/glyphs/A_sterisk.glif51
-rw-r--r--tests/input/font-psf-test/source/PsfTest-Regular.ufo/glyphs/A_tS_gn.glif80
-rw-r--r--tests/input/font-psf-test/source/PsfTest-Regular.ufo/glyphs/C_ircumA_ccent.glif8
-rw-r--r--tests/input/font-psf-test/source/PsfTest-Regular.ufo/glyphs/C_olon.glif35
-rw-r--r--tests/input/font-psf-test/source/PsfTest-Regular.ufo/glyphs/C_ombA_cute.glif14
-rw-r--r--tests/input/font-psf-test/source/PsfTest-Regular.ufo/glyphs/C_ombC_ircum.glif17
-rw-r--r--tests/input/font-psf-test/source/PsfTest-Regular.ufo/glyphs/C_ombD_iaer.glif36
-rw-r--r--tests/input/font-psf-test/source/PsfTest-Regular.ufo/glyphs/C_ombG_rave.glif14
-rw-r--r--tests/input/font-psf-test/source/PsfTest-Regular.ufo/glyphs/C_ombR_ingA_bv.glif36
-rw-r--r--tests/input/font-psf-test/source/PsfTest-Regular.ufo/glyphs/C_ombT_ilde.glif36
-rw-r--r--tests/input/font-psf-test/source/PsfTest-Regular.ufo/glyphs/C_omma.glif24
-rw-r--r--tests/input/font-psf-test/source/PsfTest-Regular.ufo/glyphs/D_igitE_ight.glif63
-rw-r--r--tests/input/font-psf-test/source/PsfTest-Regular.ufo/glyphs/D_igitF_ive.glif44
-rw-r--r--tests/input/font-psf-test/source/PsfTest-Regular.ufo/glyphs/D_igitF_our.glif27
-rw-r--r--tests/input/font-psf-test/source/PsfTest-Regular.ufo/glyphs/D_igitN_ine.glif49
-rw-r--r--tests/input/font-psf-test/source/PsfTest-Regular.ufo/glyphs/D_igitO_ne.glif22
-rw-r--r--tests/input/font-psf-test/source/PsfTest-Regular.ufo/glyphs/D_igitS_even.glif25
-rw-r--r--tests/input/font-psf-test/source/PsfTest-Regular.ufo/glyphs/D_igitS_ix.glif49
-rw-r--r--tests/input/font-psf-test/source/PsfTest-Regular.ufo/glyphs/D_igitT_hree.glif52
-rw-r--r--tests/input/font-psf-test/source/PsfTest-Regular.ufo/glyphs/D_igitT_wo.glif37
-rw-r--r--tests/input/font-psf-test/source/PsfTest-Regular.ufo/glyphs/D_igitZ_ero.glif37
-rw-r--r--tests/input/font-psf-test/source/PsfTest-Regular.ufo/glyphs/D_ollarS_gn.glif53
-rw-r--r--tests/input/font-psf-test/source/PsfTest-Regular.ufo/glyphs/D_ottedC_irc.glif235
-rw-r--r--tests/input/font-psf-test/source/PsfTest-Regular.ufo/glyphs/E_qS_gn.glif19
-rw-r--r--tests/input/font-psf-test/source/PsfTest-Regular.ufo/glyphs/E_xclamationM_rk.glif31
-rw-r--r--tests/input/font-psf-test/source/PsfTest-Regular.ufo/glyphs/F_ullS_top.glif21
-rw-r--r--tests/input/font-psf-test/source/PsfTest-Regular.ufo/glyphs/G_T_S_gn.glif16
-rw-r--r--tests/input/font-psf-test/source/PsfTest-Regular.ufo/glyphs/G_raveA_ccent.glif8
-rw-r--r--tests/input/font-psf-test/source/PsfTest-Regular.ufo/glyphs/H_yphen.glif14
-rw-r--r--tests/input/font-psf-test/source/PsfTest-Regular.ufo/glyphs/H_yphenM_inus.glif14
-rw-r--r--tests/input/font-psf-test/source/PsfTest-Regular.ufo/glyphs/H_yphen_S_oft.glif9
-rw-r--r--tests/input/font-psf-test/source/PsfTest-Regular.ufo/glyphs/L_T_S_gn.glif16
-rw-r--r--tests/input/font-psf-test/source/PsfTest-Regular.ufo/glyphs/L_ftC_urlyB_rac.glif47
-rw-r--r--tests/input/font-psf-test/source/PsfTest-Regular.ufo/glyphs/L_ftP_aren.glif23
-rw-r--r--tests/input/font-psf-test/source/PsfTest-Regular.ufo/glyphs/L_ftS_qrB_rac.glif17
-rw-r--r--tests/input/font-psf-test/source/PsfTest-Regular.ufo/glyphs/L_owL_ine.glif13
-rw-r--r--tests/input/font-psf-test/source/PsfTest-Regular.ufo/glyphs/L_tnC_apA_.alt.glif31
-rw-r--r--tests/input/font-psf-test/source/PsfTest-Regular.ufo/glyphs/L_tnC_apA_.glif32
-rw-r--r--tests/input/font-psf-test/source/PsfTest-Regular.ufo/glyphs/L_tnC_apA_D_iaer.glif13
-rw-r--r--tests/input/font-psf-test/source/PsfTest-Regular.ufo/glyphs/L_tnC_apB_.glif62
-rw-r--r--tests/input/font-psf-test/source/PsfTest-Regular.ufo/glyphs/L_tnC_apC_.glif38
-rw-r--r--tests/input/font-psf-test/source/PsfTest-Regular.ufo/glyphs/L_tnC_apD_.glif45
-rw-r--r--tests/input/font-psf-test/source/PsfTest-Regular.ufo/glyphs/L_tnC_apE_.glif35
-rw-r--r--tests/input/font-psf-test/source/PsfTest-Regular.ufo/glyphs/L_tnC_apF_.glif30
-rw-r--r--tests/input/font-psf-test/source/PsfTest-Regular.ufo/glyphs/L_tnC_apG_.glif42
-rw-r--r--tests/input/font-psf-test/source/PsfTest-Regular.ufo/glyphs/L_tnC_apH_.glif36
-rw-r--r--tests/input/font-psf-test/source/PsfTest-Regular.ufo/glyphs/L_tnC_apI_.glif26
-rw-r--r--tests/input/font-psf-test/source/PsfTest-Regular.ufo/glyphs/L_tnC_apJ_.glif30
-rw-r--r--tests/input/font-psf-test/source/PsfTest-Regular.ufo/glyphs/L_tnC_apK_.glif35
-rw-r--r--tests/input/font-psf-test/source/PsfTest-Regular.ufo/glyphs/L_tnC_apL_.glif28
-rw-r--r--tests/input/font-psf-test/source/PsfTest-Regular.ufo/glyphs/L_tnC_apM_.glif37
-rw-r--r--tests/input/font-psf-test/source/PsfTest-Regular.ufo/glyphs/L_tnC_apN_.glif37
-rw-r--r--tests/input/font-psf-test/source/PsfTest-Regular.ufo/glyphs/L_tnC_apO_.glif40
-rw-r--r--tests/input/font-psf-test/source/PsfTest-Regular.ufo/glyphs/L_tnC_apP_.glif50
-rw-r--r--tests/input/font-psf-test/source/PsfTest-Regular.ufo/glyphs/L_tnC_apQ_.glif49
-rw-r--r--tests/input/font-psf-test/source/PsfTest-Regular.ufo/glyphs/L_tnC_apR_.glif55
-rw-r--r--tests/input/font-psf-test/source/PsfTest-Regular.ufo/glyphs/L_tnC_apS_.glif50
-rw-r--r--tests/input/font-psf-test/source/PsfTest-Regular.ufo/glyphs/L_tnC_apT_.glif32
-rw-r--r--tests/input/font-psf-test/source/PsfTest-Regular.ufo/glyphs/L_tnC_apU_.glif38
-rw-r--r--tests/input/font-psf-test/source/PsfTest-Regular.ufo/glyphs/L_tnC_apV_.glif26
-rw-r--r--tests/input/font-psf-test/source/PsfTest-Regular.ufo/glyphs/L_tnC_apW_.glif45
-rw-r--r--tests/input/font-psf-test/source/PsfTest-Regular.ufo/glyphs/L_tnC_apX_.glif35
-rw-r--r--tests/input/font-psf-test/source/PsfTest-Regular.ufo/glyphs/L_tnC_apY_.glif32
-rw-r--r--tests/input/font-psf-test/source/PsfTest-Regular.ufo/glyphs/L_tnS_mA_.glif76
-rw-r--r--tests/input/font-psf-test/source/PsfTest-Regular.ufo/glyphs/L_tnS_mA_A_cute.glif14
-rw-r--r--tests/input/font-psf-test/source/PsfTest-Regular.ufo/glyphs/L_tnS_mA_C_ircum.glif14
-rw-r--r--tests/input/font-psf-test/source/PsfTest-Regular.ufo/glyphs/L_tnS_mA_D_iaer.glif14
-rw-r--r--tests/input/font-psf-test/source/PsfTest-Regular.ufo/glyphs/L_tnS_mA_G_rave.glif14
-rw-r--r--tests/input/font-psf-test/source/PsfTest-Regular.ufo/glyphs/L_tnS_mA_R_ingA_bv.glif41
-rw-r--r--tests/input/font-psf-test/source/PsfTest-Regular.ufo/glyphs/L_tnS_mA_T_ilde.glif41
-rw-r--r--tests/input/font-psf-test/source/PsfTest-Regular.ufo/glyphs/L_tnS_mB_.glif50
-rw-r--r--tests/input/font-psf-test/source/PsfTest-Regular.ufo/glyphs/L_tnS_mC_.glif39
-rw-r--r--tests/input/font-psf-test/source/PsfTest-Regular.ufo/glyphs/L_tnS_mD_.glif53
-rw-r--r--tests/input/font-psf-test/source/PsfTest-Regular.ufo/glyphs/L_tnS_mE_.glif45
-rw-r--r--tests/input/font-psf-test/source/PsfTest-Regular.ufo/glyphs/L_tnS_mF_.glif39
-rw-r--r--tests/input/font-psf-test/source/PsfTest-Regular.ufo/glyphs/L_tnS_mG_.glif91
-rw-r--r--tests/input/font-psf-test/source/PsfTest-Regular.ufo/glyphs/L_tnS_mH_.glif43
-rw-r--r--tests/input/font-psf-test/source/PsfTest-Regular.ufo/glyphs/L_tnS_mI_.glif40
-rw-r--r--tests/input/font-psf-test/source/PsfTest-Regular.ufo/glyphs/L_tnS_mJ_.glif44
-rw-r--r--tests/input/font-psf-test/source/PsfTest-Regular.ufo/glyphs/L_tnS_mK_.glif35
-rw-r--r--tests/input/font-psf-test/source/PsfTest-Regular.ufo/glyphs/L_tnS_mL_.glif24
-rw-r--r--tests/input/font-psf-test/source/PsfTest-Regular.ufo/glyphs/L_tnS_mM_.glif52
-rw-r--r--tests/input/font-psf-test/source/PsfTest-Regular.ufo/glyphs/L_tnS_mN_.glif43
-rw-r--r--tests/input/font-psf-test/source/PsfTest-Regular.ufo/glyphs/L_tnS_mO_.glif40
-rw-r--r--tests/input/font-psf-test/source/PsfTest-Regular.ufo/glyphs/L_tnS_mP_.glif56
-rw-r--r--tests/input/font-psf-test/source/PsfTest-Regular.ufo/glyphs/L_tnS_mQ_.glif47
-rw-r--r--tests/input/font-psf-test/source/PsfTest-Regular.ufo/glyphs/L_tnS_mR_.glif36
-rw-r--r--tests/input/font-psf-test/source/PsfTest-Regular.ufo/glyphs/L_tnS_mS_.glif50
-rw-r--r--tests/input/font-psf-test/source/PsfTest-Regular.ufo/glyphs/L_tnS_mT_.glif39
-rw-r--r--tests/input/font-psf-test/source/PsfTest-Regular.ufo/glyphs/L_tnS_mU_.glif51
-rw-r--r--tests/input/font-psf-test/source/PsfTest-Regular.ufo/glyphs/L_tnS_mV_.glif30
-rw-r--r--tests/input/font-psf-test/source/PsfTest-Regular.ufo/glyphs/L_tnS_mW_.glif30
-rw-r--r--tests/input/font-psf-test/source/PsfTest-Regular.ufo/glyphs/L_tnS_mX_.glif40
-rw-r--r--tests/input/font-psf-test/source/PsfTest-Regular.ufo/glyphs/L_tnS_mY_.glif42
-rw-r--r--tests/input/font-psf-test/source/PsfTest-Regular.ufo/glyphs/N_onB_reakingH_yphen.glif9
-rw-r--r--tests/input/font-psf-test/source/PsfTest-Regular.ufo/glyphs/N_umS_gn.glif31
-rw-r--r--tests/input/font-psf-test/source/PsfTest-Regular.ufo/glyphs/P_ercentS_gn.glif69
-rw-r--r--tests/input/font-psf-test/source/PsfTest-Regular.ufo/glyphs/P_lusS_gn.glif19
-rw-r--r--tests/input/font-psf-test/source/PsfTest-Regular.ufo/glyphs/Q_stnM_rk.glif49
-rw-r--r--tests/input/font-psf-test/source/PsfTest-Regular.ufo/glyphs/Q_uotM_rk.glif27
-rw-r--r--tests/input/font-psf-test/source/PsfTest-Regular.ufo/glyphs/R_everseS_olidus.glif13
-rw-r--r--tests/input/font-psf-test/source/PsfTest-Regular.ufo/glyphs/R_tC_urlyB_rac.glif47
-rw-r--r--tests/input/font-psf-test/source/PsfTest-Regular.ufo/glyphs/R_tP_aren.glif23
-rw-r--r--tests/input/font-psf-test/source/PsfTest-Regular.ufo/glyphs/R_tS_qrB_rac.glif17
-rw-r--r--tests/input/font-psf-test/source/PsfTest-Regular.ufo/glyphs/S_emicolon.glif38
-rw-r--r--tests/input/font-psf-test/source/PsfTest-Regular.ufo/glyphs/S_olidus.glif13
-rw-r--r--tests/input/font-psf-test/source/PsfTest-Regular.ufo/glyphs/S_pace.glif6
-rw-r--r--tests/input/font-psf-test/source/PsfTest-Regular.ufo/glyphs/T_ilde.glif29
-rw-r--r--tests/input/font-psf-test/source/PsfTest-Regular.ufo/glyphs/V_ertL_ine.glif13
-rw-r--r--tests/input/font-psf-test/source/PsfTest-Regular.ufo/glyphs/_notdef.glif18
-rw-r--r--tests/input/font-psf-test/source/PsfTest-Regular.ufo/glyphs/_null.glif4
-rw-r--r--tests/input/font-psf-test/source/PsfTest-Regular.ufo/glyphs/contents.plist234
-rw-r--r--tests/input/font-psf-test/source/PsfTest-Regular.ufo/glyphs/nonmarkingreturn.glif5
-rw-r--r--tests/input/font-psf-test/source/PsfTest-Regular.ufo/layercontents.plist10
-rw-r--r--tests/input/font-psf-test/source/PsfTest-Regular.ufo/lib.plist536
-rw-r--r--tests/input/font-psf-test/source/PsfTest-Regular.ufo/metainfo.plist10
-rw-r--r--tests/input/font-psf-test/source/PsfTestItalic.designspace58
-rw-r--r--tests/input/font-psf-test/source/PsfTestItalic.glyphs12469
-rw-r--r--tests/input/font-psf-test/source/PsfTestRoman.designspace58
-rw-r--r--tests/input/font-psf-test/source/PsfTestRoman.glyphs12025
-rw-r--r--tests/input/font-psf-test/source/glyph_data.csv115
-rw-r--r--tests/input/font-psf-test/source/logs/readme.txt1
-rw-r--r--tests/input/font-psf-test/wscript27
-rw-r--r--tests/input/glyph_data.csv28
-rw-r--r--tests/input/issue65.feax4
-rw-r--r--tests/input/ligatures.feax12
-rw-r--r--tests/input/psfbuildcomp.txt30
-rw-r--r--tests/input/psfcopyglyphs.csv7
-rw-r--r--tests/input/psfdeleteglyphs.txt3
-rw-r--r--tests/input/psfgenftml.csv116
-rw-r--r--tests/input/psfmakefea.feax8
-rw-r--r--tests/input/psfmakefea_2.feax11
-rw-r--r--tests/input/psfmakefea_3.feax20
-rw-r--r--tests/input/psfmakewoffmetadata.txt40
-rw-r--r--tests/input/psfrenameglyphs.csv3
-rw-r--r--tests/input/psfsetassocfeat.csv2
-rw-r--r--tests/input/psfsetassocuids.csv3
-rw-r--r--tests/input/psfsetunicodes.csv4
-rw-r--r--tests/input/psfsubset.csv73
-rw-r--r--tests/localufos.csv.sample6
-rw-r--r--tests/reference/fontparts/psfbuildcompgc.lg2
-rw-r--r--tests/reference/fontparts/psfbuildcompgc.ufo/fontinfo.plist266
-rw-r--r--tests/reference/fontparts/psfbuildcompgc.ufo/glyphs/A_mpersand.glif61
-rw-r--r--tests/reference/fontparts/psfbuildcompgc.ufo/glyphs/A_pos.glif17
-rw-r--r--tests/reference/fontparts/psfbuildcompgc.ufo/glyphs/A_sterisk.glif51
-rw-r--r--tests/reference/fontparts/psfbuildcompgc.ufo/glyphs/A_tS_gn.glif80
-rw-r--r--tests/reference/fontparts/psfbuildcompgc.ufo/glyphs/C_ircumA_ccent.glif8
-rw-r--r--tests/reference/fontparts/psfbuildcompgc.ufo/glyphs/C_olon.glif35
-rw-r--r--tests/reference/fontparts/psfbuildcompgc.ufo/glyphs/C_ombA_cute.glif14
-rw-r--r--tests/reference/fontparts/psfbuildcompgc.ufo/glyphs/C_ombC_ircum.glif17
-rw-r--r--tests/reference/fontparts/psfbuildcompgc.ufo/glyphs/C_ombD_iaer.glif36
-rw-r--r--tests/reference/fontparts/psfbuildcompgc.ufo/glyphs/C_ombG_rave.glif14
-rw-r--r--tests/reference/fontparts/psfbuildcompgc.ufo/glyphs/C_ombR_ingA_bv.glif36
-rw-r--r--tests/reference/fontparts/psfbuildcompgc.ufo/glyphs/C_ombT_ilde.glif36
-rw-r--r--tests/reference/fontparts/psfbuildcompgc.ufo/glyphs/C_omma.glif24
-rw-r--r--tests/reference/fontparts/psfbuildcompgc.ufo/glyphs/D_igitE_ight.glif63
-rw-r--r--tests/reference/fontparts/psfbuildcompgc.ufo/glyphs/D_igitF_ive.glif44
-rw-r--r--tests/reference/fontparts/psfbuildcompgc.ufo/glyphs/D_igitF_our.glif27
-rw-r--r--tests/reference/fontparts/psfbuildcompgc.ufo/glyphs/D_igitN_ine.glif49
-rw-r--r--tests/reference/fontparts/psfbuildcompgc.ufo/glyphs/D_igitO_ne.glif22
-rw-r--r--tests/reference/fontparts/psfbuildcompgc.ufo/glyphs/D_igitS_even.glif25
-rw-r--r--tests/reference/fontparts/psfbuildcompgc.ufo/glyphs/D_igitS_ix.glif49
-rw-r--r--tests/reference/fontparts/psfbuildcompgc.ufo/glyphs/D_igitT_hree.glif52
-rw-r--r--tests/reference/fontparts/psfbuildcompgc.ufo/glyphs/D_igitT_wo.glif37
-rw-r--r--tests/reference/fontparts/psfbuildcompgc.ufo/glyphs/D_igitZ_ero.glif37
-rw-r--r--tests/reference/fontparts/psfbuildcompgc.ufo/glyphs/D_ollarS_gn.glif53
-rw-r--r--tests/reference/fontparts/psfbuildcompgc.ufo/glyphs/D_ottedC_irc.glif235
-rw-r--r--tests/reference/fontparts/psfbuildcompgc.ufo/glyphs/E_qS_gn.glif19
-rw-r--r--tests/reference/fontparts/psfbuildcompgc.ufo/glyphs/E_xclamationM_rk.glif31
-rw-r--r--tests/reference/fontparts/psfbuildcompgc.ufo/glyphs/F_ullS_top.glif21
-rw-r--r--tests/reference/fontparts/psfbuildcompgc.ufo/glyphs/G_T_S_gn.glif16
-rw-r--r--tests/reference/fontparts/psfbuildcompgc.ufo/glyphs/G_raveA_ccent.glif8
-rw-r--r--tests/reference/fontparts/psfbuildcompgc.ufo/glyphs/H_yphen.glif14
-rw-r--r--tests/reference/fontparts/psfbuildcompgc.ufo/glyphs/H_yphenM_inus.glif14
-rw-r--r--tests/reference/fontparts/psfbuildcompgc.ufo/glyphs/H_yphen_S_oft.glif9
-rw-r--r--tests/reference/fontparts/psfbuildcompgc.ufo/glyphs/L_T_S_gn.glif16
-rw-r--r--tests/reference/fontparts/psfbuildcompgc.ufo/glyphs/L_ftC_urlyB_rac.glif47
-rw-r--r--tests/reference/fontparts/psfbuildcompgc.ufo/glyphs/L_ftP_aren.glif23
-rw-r--r--tests/reference/fontparts/psfbuildcompgc.ufo/glyphs/L_ftS_qrB_rac.glif17
-rw-r--r--tests/reference/fontparts/psfbuildcompgc.ufo/glyphs/L_owL_ine.glif13
-rw-r--r--tests/reference/fontparts/psfbuildcompgc.ufo/glyphs/L_tnC_apA_.alt.glif31
-rw-r--r--tests/reference/fontparts/psfbuildcompgc.ufo/glyphs/L_tnC_apA_.glif32
-rw-r--r--tests/reference/fontparts/psfbuildcompgc.ufo/glyphs/L_tnC_apA_D_iaer.glif13
-rw-r--r--tests/reference/fontparts/psfbuildcompgc.ufo/glyphs/L_tnC_apB_.glif62
-rw-r--r--tests/reference/fontparts/psfbuildcompgc.ufo/glyphs/L_tnC_apC_.glif38
-rw-r--r--tests/reference/fontparts/psfbuildcompgc.ufo/glyphs/L_tnC_apC_A_cute.glif9
-rw-r--r--tests/reference/fontparts/psfbuildcompgc.ufo/glyphs/L_tnC_apC_A_cuteC_edilla.glif10
-rw-r--r--tests/reference/fontparts/psfbuildcompgc.ufo/glyphs/L_tnC_apC_C_ircum.glif9
-rw-r--r--tests/reference/fontparts/psfbuildcompgc.ufo/glyphs/L_tnC_apD_.glif45
-rw-r--r--tests/reference/fontparts/psfbuildcompgc.ufo/glyphs/L_tnC_apE_.glif35
-rw-r--r--tests/reference/fontparts/psfbuildcompgc.ufo/glyphs/L_tnC_apF_.glif30
-rw-r--r--tests/reference/fontparts/psfbuildcompgc.ufo/glyphs/L_tnC_apG_.glif42
-rw-r--r--tests/reference/fontparts/psfbuildcompgc.ufo/glyphs/L_tnC_apH_.glif36
-rw-r--r--tests/reference/fontparts/psfbuildcompgc.ufo/glyphs/L_tnC_apI_.glif26
-rw-r--r--tests/reference/fontparts/psfbuildcompgc.ufo/glyphs/L_tnC_apI_J_.glif9
-rw-r--r--tests/reference/fontparts/psfbuildcompgc.ufo/glyphs/L_tnC_apJ_.glif30
-rw-r--r--tests/reference/fontparts/psfbuildcompgc.ufo/glyphs/L_tnC_apK_.glif35
-rw-r--r--tests/reference/fontparts/psfbuildcompgc.ufo/glyphs/L_tnC_apL_.glif28
-rw-r--r--tests/reference/fontparts/psfbuildcompgc.ufo/glyphs/L_tnC_apM_.glif37
-rw-r--r--tests/reference/fontparts/psfbuildcompgc.ufo/glyphs/L_tnC_apN_.glif37
-rw-r--r--tests/reference/fontparts/psfbuildcompgc.ufo/glyphs/L_tnC_apO_.glif40
-rw-r--r--tests/reference/fontparts/psfbuildcompgc.ufo/glyphs/L_tnC_apP_.glif50
-rw-r--r--tests/reference/fontparts/psfbuildcompgc.ufo/glyphs/L_tnC_apQ_.glif49
-rw-r--r--tests/reference/fontparts/psfbuildcompgc.ufo/glyphs/L_tnC_apR_.glif55
-rw-r--r--tests/reference/fontparts/psfbuildcompgc.ufo/glyphs/L_tnC_apS_.glif50
-rw-r--r--tests/reference/fontparts/psfbuildcompgc.ufo/glyphs/L_tnC_apT_.glif32
-rw-r--r--tests/reference/fontparts/psfbuildcompgc.ufo/glyphs/L_tnC_apU_.glif38
-rw-r--r--tests/reference/fontparts/psfbuildcompgc.ufo/glyphs/L_tnC_apV_.glif26
-rw-r--r--tests/reference/fontparts/psfbuildcompgc.ufo/glyphs/L_tnC_apW_.glif45
-rw-r--r--tests/reference/fontparts/psfbuildcompgc.ufo/glyphs/L_tnC_apX_.glif35
-rw-r--r--tests/reference/fontparts/psfbuildcompgc.ufo/glyphs/L_tnC_apY_.glif32
-rw-r--r--tests/reference/fontparts/psfbuildcompgc.ufo/glyphs/L_tnS_mA_.glif68
-rw-r--r--tests/reference/fontparts/psfbuildcompgc.ufo/glyphs/L_tnS_mA_A_cute.glif14
-rw-r--r--tests/reference/fontparts/psfbuildcompgc.ufo/glyphs/L_tnS_mA_C_ircum.glif14
-rw-r--r--tests/reference/fontparts/psfbuildcompgc.ufo/glyphs/L_tnS_mA_D_iaer.glif14
-rw-r--r--tests/reference/fontparts/psfbuildcompgc.ufo/glyphs/L_tnS_mA_G_rave.glif14
-rw-r--r--tests/reference/fontparts/psfbuildcompgc.ufo/glyphs/L_tnS_mA_R_ingA_bv.glif41
-rw-r--r--tests/reference/fontparts/psfbuildcompgc.ufo/glyphs/L_tnS_mA_T_ilde.glif41
-rw-r--r--tests/reference/fontparts/psfbuildcompgc.ufo/glyphs/L_tnS_mB_.glif50
-rw-r--r--tests/reference/fontparts/psfbuildcompgc.ufo/glyphs/L_tnS_mC_.glif39
-rw-r--r--tests/reference/fontparts/psfbuildcompgc.ufo/glyphs/L_tnS_mC_A_cute.glif9
-rw-r--r--tests/reference/fontparts/psfbuildcompgc.ufo/glyphs/L_tnS_mC_A_cuteC_edilla.glif10
-rw-r--r--tests/reference/fontparts/psfbuildcompgc.ufo/glyphs/L_tnS_mC_C_ircum.glif9
-rw-r--r--tests/reference/fontparts/psfbuildcompgc.ufo/glyphs/L_tnS_mD_.glif53
-rw-r--r--tests/reference/fontparts/psfbuildcompgc.ufo/glyphs/L_tnS_mE_.glif45
-rw-r--r--tests/reference/fontparts/psfbuildcompgc.ufo/glyphs/L_tnS_mF_.glif39
-rw-r--r--tests/reference/fontparts/psfbuildcompgc.ufo/glyphs/L_tnS_mG_.glif91
-rw-r--r--tests/reference/fontparts/psfbuildcompgc.ufo/glyphs/L_tnS_mH_.glif43
-rw-r--r--tests/reference/fontparts/psfbuildcompgc.ufo/glyphs/L_tnS_mI_.glif40
-rw-r--r--tests/reference/fontparts/psfbuildcompgc.ufo/glyphs/L_tnS_mI_J_.glif9
-rw-r--r--tests/reference/fontparts/psfbuildcompgc.ufo/glyphs/L_tnS_mI_T_ilde.glif9
-rw-r--r--tests/reference/fontparts/psfbuildcompgc.ufo/glyphs/L_tnS_mI_T_ildeG_rave.glif9
-rw-r--r--tests/reference/fontparts/psfbuildcompgc.ufo/glyphs/L_tnS_mI_T_ildeG_raveC_edilla.glif14
-rw-r--r--tests/reference/fontparts/psfbuildcompgc.ufo/glyphs/L_tnS_mJ_.glif44
-rw-r--r--tests/reference/fontparts/psfbuildcompgc.ufo/glyphs/L_tnS_mK_.glif35
-rw-r--r--tests/reference/fontparts/psfbuildcompgc.ufo/glyphs/L_tnS_mL_.glif24
-rw-r--r--tests/reference/fontparts/psfbuildcompgc.ufo/glyphs/L_tnS_mM_.glif52
-rw-r--r--tests/reference/fontparts/psfbuildcompgc.ufo/glyphs/L_tnS_mN_.glif43
-rw-r--r--tests/reference/fontparts/psfbuildcompgc.ufo/glyphs/L_tnS_mO_.glif40
-rw-r--r--tests/reference/fontparts/psfbuildcompgc.ufo/glyphs/L_tnS_mP_.glif56
-rw-r--r--tests/reference/fontparts/psfbuildcompgc.ufo/glyphs/L_tnS_mQ_.glif47
-rw-r--r--tests/reference/fontparts/psfbuildcompgc.ufo/glyphs/L_tnS_mR_.glif36
-rw-r--r--tests/reference/fontparts/psfbuildcompgc.ufo/glyphs/L_tnS_mS_.glif50
-rw-r--r--tests/reference/fontparts/psfbuildcompgc.ufo/glyphs/L_tnS_mT_.glif39
-rw-r--r--tests/reference/fontparts/psfbuildcompgc.ufo/glyphs/L_tnS_mU_.glif51
-rw-r--r--tests/reference/fontparts/psfbuildcompgc.ufo/glyphs/L_tnS_mV_.glif30
-rw-r--r--tests/reference/fontparts/psfbuildcompgc.ufo/glyphs/L_tnS_mW_.glif30
-rw-r--r--tests/reference/fontparts/psfbuildcompgc.ufo/glyphs/L_tnS_mX_.glif40
-rw-r--r--tests/reference/fontparts/psfbuildcompgc.ufo/glyphs/L_tnS_mY_.glif42
-rw-r--r--tests/reference/fontparts/psfbuildcompgc.ufo/glyphs/N_onB_reakingH_yphen.glif9
-rw-r--r--tests/reference/fontparts/psfbuildcompgc.ufo/glyphs/N_umS_gn.glif31
-rw-r--r--tests/reference/fontparts/psfbuildcompgc.ufo/glyphs/P_ercentS_gn.glif69
-rw-r--r--tests/reference/fontparts/psfbuildcompgc.ufo/glyphs/P_lusS_gn.glif19
-rw-r--r--tests/reference/fontparts/psfbuildcompgc.ufo/glyphs/Q_stnM_rk.glif49
-rw-r--r--tests/reference/fontparts/psfbuildcompgc.ufo/glyphs/Q_uotM_rk.glif27
-rw-r--r--tests/reference/fontparts/psfbuildcompgc.ufo/glyphs/R_everseS_olidus.glif13
-rw-r--r--tests/reference/fontparts/psfbuildcompgc.ufo/glyphs/R_tC_urlyB_rac.glif47
-rw-r--r--tests/reference/fontparts/psfbuildcompgc.ufo/glyphs/R_tP_aren.glif23
-rw-r--r--tests/reference/fontparts/psfbuildcompgc.ufo/glyphs/R_tS_qrB_rac.glif17
-rw-r--r--tests/reference/fontparts/psfbuildcompgc.ufo/glyphs/S_emicolon.glif38
-rw-r--r--tests/reference/fontparts/psfbuildcompgc.ufo/glyphs/S_olidus.glif13
-rw-r--r--tests/reference/fontparts/psfbuildcompgc.ufo/glyphs/S_pace.glif7
-rw-r--r--tests/reference/fontparts/psfbuildcompgc.ufo/glyphs/T_ilde.glif29
-rw-r--r--tests/reference/fontparts/psfbuildcompgc.ufo/glyphs/V_ertL_ine.glif13
-rw-r--r--tests/reference/fontparts/psfbuildcompgc.ufo/glyphs/_notdef.glif18
-rw-r--r--tests/reference/fontparts/psfbuildcompgc.ufo/glyphs/_null.glif5
-rw-r--r--tests/reference/fontparts/psfbuildcompgc.ufo/glyphs/contents.plist256
-rw-r--r--tests/reference/fontparts/psfbuildcompgc.ufo/glyphs/nonmarkingreturn.glif6
-rw-r--r--tests/reference/fontparts/psfbuildcompgc.ufo/layercontents.plist10
-rw-r--r--tests/reference/fontparts/psfbuildcompgc.ufo/lib.plist547
-rw-r--r--tests/reference/fontparts/psfbuildcompgc.ufo/metainfo.plist10
-rw-r--r--tests/reference/psfmakefea/issue65.fea7
-rw-r--r--tests/reference/psfmakefea/issue65.log0
-rw-r--r--tests/reference/psfmakefea/ligatures.fea15
-rw-r--r--tests/reference/psfmakefea/ligatures.log0
-rw-r--r--tests/reference/psfmakefea/psfmakefea.fea11
-rw-r--r--tests/reference/psfmakefea/psfmakefea.log0
-rw-r--r--tests/reference/psfmakefea/psfmakefea_2.fea11
-rw-r--r--tests/reference/psfmakefea/psfmakefea_2.log0
-rw-r--r--tests/reference/ufo/psfbuildcomp.lg52
-rw-r--r--tests/reference/ufo/psfbuildcomp.ufo/fontinfo.plist260
-rw-r--r--tests/reference/ufo/psfbuildcomp.ufo/glyphs/A_mpersand.glif61
-rw-r--r--tests/reference/ufo/psfbuildcomp.ufo/glyphs/A_pos.glif17
-rw-r--r--tests/reference/ufo/psfbuildcomp.ufo/glyphs/A_sterisk.glif51
-rw-r--r--tests/reference/ufo/psfbuildcomp.ufo/glyphs/A_tS_gn.glif80
-rw-r--r--tests/reference/ufo/psfbuildcomp.ufo/glyphs/C_ircumA_ccent.glif8
-rw-r--r--tests/reference/ufo/psfbuildcomp.ufo/glyphs/C_olon.glif35
-rw-r--r--tests/reference/ufo/psfbuildcomp.ufo/glyphs/C_ombA_cute.glif14
-rw-r--r--tests/reference/ufo/psfbuildcomp.ufo/glyphs/C_ombC_ircum.glif17
-rw-r--r--tests/reference/ufo/psfbuildcomp.ufo/glyphs/C_ombD_iaer.glif36
-rw-r--r--tests/reference/ufo/psfbuildcomp.ufo/glyphs/C_ombG_rave.glif14
-rw-r--r--tests/reference/ufo/psfbuildcomp.ufo/glyphs/C_ombR_ingA_bv.glif36
-rw-r--r--tests/reference/ufo/psfbuildcomp.ufo/glyphs/C_ombT_ilde.glif36
-rw-r--r--tests/reference/ufo/psfbuildcomp.ufo/glyphs/C_omma.glif24
-rw-r--r--tests/reference/ufo/psfbuildcomp.ufo/glyphs/D_igitE_ight.glif63
-rw-r--r--tests/reference/ufo/psfbuildcomp.ufo/glyphs/D_igitF_ive.glif44
-rw-r--r--tests/reference/ufo/psfbuildcomp.ufo/glyphs/D_igitF_our.glif27
-rw-r--r--tests/reference/ufo/psfbuildcomp.ufo/glyphs/D_igitN_ine.glif49
-rw-r--r--tests/reference/ufo/psfbuildcomp.ufo/glyphs/D_igitO_ne.glif22
-rw-r--r--tests/reference/ufo/psfbuildcomp.ufo/glyphs/D_igitS_even.glif25
-rw-r--r--tests/reference/ufo/psfbuildcomp.ufo/glyphs/D_igitS_ix.glif49
-rw-r--r--tests/reference/ufo/psfbuildcomp.ufo/glyphs/D_igitT_hree.glif52
-rw-r--r--tests/reference/ufo/psfbuildcomp.ufo/glyphs/D_igitT_wo.glif37
-rw-r--r--tests/reference/ufo/psfbuildcomp.ufo/glyphs/D_igitZ_ero.glif37
-rw-r--r--tests/reference/ufo/psfbuildcomp.ufo/glyphs/D_ollarS_gn.glif53
-rw-r--r--tests/reference/ufo/psfbuildcomp.ufo/glyphs/D_ottedC_irc.glif235
-rw-r--r--tests/reference/ufo/psfbuildcomp.ufo/glyphs/E_qS_gn.glif19
-rw-r--r--tests/reference/ufo/psfbuildcomp.ufo/glyphs/E_xclamationM_rk.glif31
-rw-r--r--tests/reference/ufo/psfbuildcomp.ufo/glyphs/F_ullS_top.glif21
-rw-r--r--tests/reference/ufo/psfbuildcomp.ufo/glyphs/G_T_S_gn.glif16
-rw-r--r--tests/reference/ufo/psfbuildcomp.ufo/glyphs/G_raveA_ccent.glif8
-rw-r--r--tests/reference/ufo/psfbuildcomp.ufo/glyphs/H_yphen.glif14
-rw-r--r--tests/reference/ufo/psfbuildcomp.ufo/glyphs/H_yphenM_inus.glif14
-rw-r--r--tests/reference/ufo/psfbuildcomp.ufo/glyphs/H_yphen_S_oft.glif9
-rw-r--r--tests/reference/ufo/psfbuildcomp.ufo/glyphs/L_T_S_gn.glif16
-rw-r--r--tests/reference/ufo/psfbuildcomp.ufo/glyphs/L_ftC_urlyB_rac.glif47
-rw-r--r--tests/reference/ufo/psfbuildcomp.ufo/glyphs/L_ftP_aren.glif23
-rw-r--r--tests/reference/ufo/psfbuildcomp.ufo/glyphs/L_ftS_qrB_rac.glif17
-rw-r--r--tests/reference/ufo/psfbuildcomp.ufo/glyphs/L_owL_ine.glif13
-rw-r--r--tests/reference/ufo/psfbuildcomp.ufo/glyphs/L_tnC_apA_.alt.glif31
-rw-r--r--tests/reference/ufo/psfbuildcomp.ufo/glyphs/L_tnC_apA_.glif32
-rw-r--r--tests/reference/ufo/psfbuildcomp.ufo/glyphs/L_tnC_apA_D_iaer.glif13
-rw-r--r--tests/reference/ufo/psfbuildcomp.ufo/glyphs/L_tnC_apB_.glif62
-rw-r--r--tests/reference/ufo/psfbuildcomp.ufo/glyphs/L_tnC_apC_.glif38
-rw-r--r--tests/reference/ufo/psfbuildcomp.ufo/glyphs/L_tnC_apC_A_cute.glif13
-rw-r--r--tests/reference/ufo/psfbuildcomp.ufo/glyphs/L_tnC_apC_A_cuteC_edilla.glif12
-rw-r--r--tests/reference/ufo/psfbuildcomp.ufo/glyphs/L_tnC_apC_C_ircum.glif12
-rw-r--r--tests/reference/ufo/psfbuildcomp.ufo/glyphs/L_tnC_apD_.glif45
-rw-r--r--tests/reference/ufo/psfbuildcomp.ufo/glyphs/L_tnC_apE_.glif35
-rw-r--r--tests/reference/ufo/psfbuildcomp.ufo/glyphs/L_tnC_apF_.glif30
-rw-r--r--tests/reference/ufo/psfbuildcomp.ufo/glyphs/L_tnC_apG_.glif42
-rw-r--r--tests/reference/ufo/psfbuildcomp.ufo/glyphs/L_tnC_apH_.glif36
-rw-r--r--tests/reference/ufo/psfbuildcomp.ufo/glyphs/L_tnC_apI_.glif26
-rw-r--r--tests/reference/ufo/psfbuildcomp.ufo/glyphs/L_tnC_apI_J_.glif14
-rw-r--r--tests/reference/ufo/psfbuildcomp.ufo/glyphs/L_tnC_apJ_.glif30
-rw-r--r--tests/reference/ufo/psfbuildcomp.ufo/glyphs/L_tnC_apK_.glif35
-rw-r--r--tests/reference/ufo/psfbuildcomp.ufo/glyphs/L_tnC_apL_.glif28
-rw-r--r--tests/reference/ufo/psfbuildcomp.ufo/glyphs/L_tnC_apM_.glif37
-rw-r--r--tests/reference/ufo/psfbuildcomp.ufo/glyphs/L_tnC_apN_.glif37
-rw-r--r--tests/reference/ufo/psfbuildcomp.ufo/glyphs/L_tnC_apO_.glif40
-rw-r--r--tests/reference/ufo/psfbuildcomp.ufo/glyphs/L_tnC_apP_.glif50
-rw-r--r--tests/reference/ufo/psfbuildcomp.ufo/glyphs/L_tnC_apQ_.glif49
-rw-r--r--tests/reference/ufo/psfbuildcomp.ufo/glyphs/L_tnC_apR_.glif55
-rw-r--r--tests/reference/ufo/psfbuildcomp.ufo/glyphs/L_tnC_apS_.glif50
-rw-r--r--tests/reference/ufo/psfbuildcomp.ufo/glyphs/L_tnC_apT_.glif32
-rw-r--r--tests/reference/ufo/psfbuildcomp.ufo/glyphs/L_tnC_apU_.glif38
-rw-r--r--tests/reference/ufo/psfbuildcomp.ufo/glyphs/L_tnC_apV_.glif26
-rw-r--r--tests/reference/ufo/psfbuildcomp.ufo/glyphs/L_tnC_apW_.glif45
-rw-r--r--tests/reference/ufo/psfbuildcomp.ufo/glyphs/L_tnC_apX_.glif35
-rw-r--r--tests/reference/ufo/psfbuildcomp.ufo/glyphs/L_tnC_apY_.glif32
-rw-r--r--tests/reference/ufo/psfbuildcomp.ufo/glyphs/L_tnS_mA_.glif76
-rw-r--r--tests/reference/ufo/psfbuildcomp.ufo/glyphs/L_tnS_mA_A_cute.glif14
-rw-r--r--tests/reference/ufo/psfbuildcomp.ufo/glyphs/L_tnS_mA_C_ircum.glif14
-rw-r--r--tests/reference/ufo/psfbuildcomp.ufo/glyphs/L_tnS_mA_D_iaer.glif14
-rw-r--r--tests/reference/ufo/psfbuildcomp.ufo/glyphs/L_tnS_mA_G_rave.glif14
-rw-r--r--tests/reference/ufo/psfbuildcomp.ufo/glyphs/L_tnS_mA_R_ingA_bv.glif41
-rw-r--r--tests/reference/ufo/psfbuildcomp.ufo/glyphs/L_tnS_mA_T_ilde.glif41
-rw-r--r--tests/reference/ufo/psfbuildcomp.ufo/glyphs/L_tnS_mB_.glif50
-rw-r--r--tests/reference/ufo/psfbuildcomp.ufo/glyphs/L_tnS_mC_.glif39
-rw-r--r--tests/reference/ufo/psfbuildcomp.ufo/glyphs/L_tnS_mC_A_cute.glif12
-rw-r--r--tests/reference/ufo/psfbuildcomp.ufo/glyphs/L_tnS_mC_A_cuteC_edilla.glif13
-rw-r--r--tests/reference/ufo/psfbuildcomp.ufo/glyphs/L_tnS_mC_C_ircum.glif13
-rw-r--r--tests/reference/ufo/psfbuildcomp.ufo/glyphs/L_tnS_mD_.glif53
-rw-r--r--tests/reference/ufo/psfbuildcomp.ufo/glyphs/L_tnS_mE_.glif45
-rw-r--r--tests/reference/ufo/psfbuildcomp.ufo/glyphs/L_tnS_mF_.glif39
-rw-r--r--tests/reference/ufo/psfbuildcomp.ufo/glyphs/L_tnS_mG_.glif91
-rw-r--r--tests/reference/ufo/psfbuildcomp.ufo/glyphs/L_tnS_mH_.glif43
-rw-r--r--tests/reference/ufo/psfbuildcomp.ufo/glyphs/L_tnS_mI_.glif40
-rw-r--r--tests/reference/ufo/psfbuildcomp.ufo/glyphs/L_tnS_mI_J_.glif14
-rw-r--r--tests/reference/ufo/psfbuildcomp.ufo/glyphs/L_tnS_mI_T_ilde.glif9
-rw-r--r--tests/reference/ufo/psfbuildcomp.ufo/glyphs/L_tnS_mI_T_ildeG_rave.glif9
-rw-r--r--tests/reference/ufo/psfbuildcomp.ufo/glyphs/L_tnS_mI_T_ildeG_raveC_edilla.glif10
-rw-r--r--tests/reference/ufo/psfbuildcomp.ufo/glyphs/L_tnS_mJ_.glif44
-rw-r--r--tests/reference/ufo/psfbuildcomp.ufo/glyphs/L_tnS_mK_.glif35
-rw-r--r--tests/reference/ufo/psfbuildcomp.ufo/glyphs/L_tnS_mL_.glif24
-rw-r--r--tests/reference/ufo/psfbuildcomp.ufo/glyphs/L_tnS_mM_.glif52
-rw-r--r--tests/reference/ufo/psfbuildcomp.ufo/glyphs/L_tnS_mN_.glif43
-rw-r--r--tests/reference/ufo/psfbuildcomp.ufo/glyphs/L_tnS_mO_.glif40
-rw-r--r--tests/reference/ufo/psfbuildcomp.ufo/glyphs/L_tnS_mP_.glif56
-rw-r--r--tests/reference/ufo/psfbuildcomp.ufo/glyphs/L_tnS_mQ_.glif47
-rw-r--r--tests/reference/ufo/psfbuildcomp.ufo/glyphs/L_tnS_mR_.glif36
-rw-r--r--tests/reference/ufo/psfbuildcomp.ufo/glyphs/L_tnS_mS_.glif50
-rw-r--r--tests/reference/ufo/psfbuildcomp.ufo/glyphs/L_tnS_mT_.glif39
-rw-r--r--tests/reference/ufo/psfbuildcomp.ufo/glyphs/L_tnS_mU_.glif51
-rw-r--r--tests/reference/ufo/psfbuildcomp.ufo/glyphs/L_tnS_mV_.glif30
-rw-r--r--tests/reference/ufo/psfbuildcomp.ufo/glyphs/L_tnS_mW_.glif30
-rw-r--r--tests/reference/ufo/psfbuildcomp.ufo/glyphs/L_tnS_mX_.glif40
-rw-r--r--tests/reference/ufo/psfbuildcomp.ufo/glyphs/L_tnS_mY_.glif42
-rw-r--r--tests/reference/ufo/psfbuildcomp.ufo/glyphs/N_onB_reakingH_yphen.glif9
-rw-r--r--tests/reference/ufo/psfbuildcomp.ufo/glyphs/N_umS_gn.glif31
-rw-r--r--tests/reference/ufo/psfbuildcomp.ufo/glyphs/P_ercentS_gn.glif69
-rw-r--r--tests/reference/ufo/psfbuildcomp.ufo/glyphs/P_lusS_gn.glif19
-rw-r--r--tests/reference/ufo/psfbuildcomp.ufo/glyphs/Q_stnM_rk.glif49
-rw-r--r--tests/reference/ufo/psfbuildcomp.ufo/glyphs/Q_uotM_rk.glif27
-rw-r--r--tests/reference/ufo/psfbuildcomp.ufo/glyphs/R_everseS_olidus.glif13
-rw-r--r--tests/reference/ufo/psfbuildcomp.ufo/glyphs/R_tC_urlyB_rac.glif47
-rw-r--r--tests/reference/ufo/psfbuildcomp.ufo/glyphs/R_tP_aren.glif23
-rw-r--r--tests/reference/ufo/psfbuildcomp.ufo/glyphs/R_tS_qrB_rac.glif17
-rw-r--r--tests/reference/ufo/psfbuildcomp.ufo/glyphs/S_emicolon.glif38
-rw-r--r--tests/reference/ufo/psfbuildcomp.ufo/glyphs/S_olidus.glif13
-rw-r--r--tests/reference/ufo/psfbuildcomp.ufo/glyphs/S_pace.glif6
-rw-r--r--tests/reference/ufo/psfbuildcomp.ufo/glyphs/T_ilde.glif29
-rw-r--r--tests/reference/ufo/psfbuildcomp.ufo/glyphs/V_ertL_ine.glif13
-rw-r--r--tests/reference/ufo/psfbuildcomp.ufo/glyphs/_notdef.glif18
-rw-r--r--tests/reference/ufo/psfbuildcomp.ufo/glyphs/_null.glif4
-rw-r--r--tests/reference/ufo/psfbuildcomp.ufo/glyphs/contents.plist256
-rw-r--r--tests/reference/ufo/psfbuildcomp.ufo/glyphs/nonmarkingreturn.glif5
-rw-r--r--tests/reference/ufo/psfbuildcomp.ufo/layercontents.plist10
-rw-r--r--tests/reference/ufo/psfbuildcomp.ufo/lib.plist536
-rw-r--r--tests/reference/ufo/psfbuildcomp.ufo/metainfo.plist10
-rw-r--r--tests/reference/ufo/psfbuildcompgc.lg3
-rw-r--r--tests/reference/ufo/psfchangettfglyphnames.lg4
-rw-r--r--tests/reference/ufo/psfchangettfglyphnames.ttfbin0 -> 21668 bytes
-rw-r--r--tests/reference/ufo/psfcheckbasicchars.lg199
-rw-r--r--tests/reference/ufo/psfcopyglyphs.lg30
-rw-r--r--tests/reference/ufo/psfcopyglyphs.ufo/fontinfo.plist243
-rw-r--r--tests/reference/ufo/psfcopyglyphs.ufo/glyphs/A_mpergravel.glif61
-rw-r--r--tests/reference/ufo/psfcopyglyphs.ufo/glyphs/A_mpersand.glif61
-rw-r--r--tests/reference/ufo/psfcopyglyphs.ufo/glyphs/A_pos.glif17
-rw-r--r--tests/reference/ufo/psfcopyglyphs.ufo/glyphs/A_sterisk.glif51
-rw-r--r--tests/reference/ufo/psfcopyglyphs.ufo/glyphs/A_tS_gn.glif104
-rw-r--r--tests/reference/ufo/psfcopyglyphs.ufo/glyphs/C_ircumA_ccent.glif17
-rw-r--r--tests/reference/ufo/psfcopyglyphs.ufo/glyphs/C_olon.glif35
-rw-r--r--tests/reference/ufo/psfcopyglyphs.ufo/glyphs/C_ombA_cute.glif14
-rw-r--r--tests/reference/ufo/psfcopyglyphs.ufo/glyphs/C_ombC_ircum.glif17
-rw-r--r--tests/reference/ufo/psfcopyglyphs.ufo/glyphs/C_ombD_iaer.glif36
-rw-r--r--tests/reference/ufo/psfcopyglyphs.ufo/glyphs/C_ombG_rave.glif14
-rw-r--r--tests/reference/ufo/psfcopyglyphs.ufo/glyphs/C_ombR_ingA_bv.glif36
-rw-r--r--tests/reference/ufo/psfcopyglyphs.ufo/glyphs/C_ombT_ilde.glif36
-rw-r--r--tests/reference/ufo/psfcopyglyphs.ufo/glyphs/C_omma.glif24
-rw-r--r--tests/reference/ufo/psfcopyglyphs.ufo/glyphs/D_igitE_ight.glif63
-rw-r--r--tests/reference/ufo/psfcopyglyphs.ufo/glyphs/D_igitF_ive.glif44
-rw-r--r--tests/reference/ufo/psfcopyglyphs.ufo/glyphs/D_igitF_our.glif27
-rw-r--r--tests/reference/ufo/psfcopyglyphs.ufo/glyphs/D_igitN_ine.glif49
-rw-r--r--tests/reference/ufo/psfcopyglyphs.ufo/glyphs/D_igitO_ne.glif22
-rw-r--r--tests/reference/ufo/psfcopyglyphs.ufo/glyphs/D_igitS_even.glif25
-rw-r--r--tests/reference/ufo/psfcopyglyphs.ufo/glyphs/D_igitS_ix.glif49
-rw-r--r--tests/reference/ufo/psfcopyglyphs.ufo/glyphs/D_igitT_hree.glif52
-rw-r--r--tests/reference/ufo/psfcopyglyphs.ufo/glyphs/D_igitT_wo.glif37
-rw-r--r--tests/reference/ufo/psfcopyglyphs.ufo/glyphs/D_igitZ_ero.glif49
-rw-r--r--tests/reference/ufo/psfcopyglyphs.ufo/glyphs/D_ollarS_gn.glif53
-rw-r--r--tests/reference/ufo/psfcopyglyphs.ufo/glyphs/D_ottedC_irc.glif235
-rw-r--r--tests/reference/ufo/psfcopyglyphs.ufo/glyphs/E_qS_gn.glif19
-rw-r--r--tests/reference/ufo/psfcopyglyphs.ufo/glyphs/E_xclamationM_rk.glif31
-rw-r--r--tests/reference/ufo/psfcopyglyphs.ufo/glyphs/F_ullS_top.glif21
-rw-r--r--tests/reference/ufo/psfcopyglyphs.ufo/glyphs/F_ullstart.glif20
-rw-r--r--tests/reference/ufo/psfcopyglyphs.ufo/glyphs/G_T_S_gn.glif16
-rw-r--r--tests/reference/ufo/psfcopyglyphs.ufo/glyphs/G_raveA_ccent.glif14
-rw-r--r--tests/reference/ufo/psfcopyglyphs.ufo/glyphs/H_yphen.glif14
-rw-r--r--tests/reference/ufo/psfcopyglyphs.ufo/glyphs/H_yphenM_inus.glif14
-rw-r--r--tests/reference/ufo/psfcopyglyphs.ufo/glyphs/H_yphen_S_oft.glif9
-rw-r--r--tests/reference/ufo/psfcopyglyphs.ufo/glyphs/L_T_S_gn.glif16
-rw-r--r--tests/reference/ufo/psfcopyglyphs.ufo/glyphs/L_ftC_urlyB_rac.glif50
-rw-r--r--tests/reference/ufo/psfcopyglyphs.ufo/glyphs/L_ftP_aren.glif29
-rw-r--r--tests/reference/ufo/psfcopyglyphs.ufo/glyphs/L_ftS_qrB_rac.glif17
-rw-r--r--tests/reference/ufo/psfcopyglyphs.ufo/glyphs/L_owL_ine.glif13
-rw-r--r--tests/reference/ufo/psfcopyglyphs.ufo/glyphs/L_tnC_apA_.alt.glif32
-rw-r--r--tests/reference/ufo/psfcopyglyphs.ufo/glyphs/L_tnC_apA_.glif32
-rw-r--r--tests/reference/ufo/psfcopyglyphs.ufo/glyphs/L_tnC_apA_D_iaer.glif13
-rw-r--r--tests/reference/ufo/psfcopyglyphs.ufo/glyphs/L_tnC_apB_.glif62
-rw-r--r--tests/reference/ufo/psfcopyglyphs.ufo/glyphs/L_tnC_apC_.glif38
-rw-r--r--tests/reference/ufo/psfcopyglyphs.ufo/glyphs/L_tnC_apD_.glif51
-rw-r--r--tests/reference/ufo/psfcopyglyphs.ufo/glyphs/L_tnC_apE_.glif35
-rw-r--r--tests/reference/ufo/psfcopyglyphs.ufo/glyphs/L_tnC_apF_.glif30
-rw-r--r--tests/reference/ufo/psfcopyglyphs.ufo/glyphs/L_tnC_apG_.glif48
-rw-r--r--tests/reference/ufo/psfcopyglyphs.ufo/glyphs/L_tnC_apH_.glif36
-rw-r--r--tests/reference/ufo/psfcopyglyphs.ufo/glyphs/L_tnC_apI_.glif26
-rw-r--r--tests/reference/ufo/psfcopyglyphs.ufo/glyphs/L_tnC_apJ_.glif30
-rw-r--r--tests/reference/ufo/psfcopyglyphs.ufo/glyphs/L_tnC_apK_.glif35
-rw-r--r--tests/reference/ufo/psfcopyglyphs.ufo/glyphs/L_tnC_apL_.glif28
-rw-r--r--tests/reference/ufo/psfcopyglyphs.ufo/glyphs/L_tnC_apM_.glif36
-rw-r--r--tests/reference/ufo/psfcopyglyphs.ufo/glyphs/L_tnC_apN_.glif37
-rw-r--r--tests/reference/ufo/psfcopyglyphs.ufo/glyphs/L_tnC_apO_.glif40
-rw-r--r--tests/reference/ufo/psfcopyglyphs.ufo/glyphs/L_tnC_apP_.glif50
-rw-r--r--tests/reference/ufo/psfcopyglyphs.ufo/glyphs/L_tnC_apQ_.glif52
-rw-r--r--tests/reference/ufo/psfcopyglyphs.ufo/glyphs/L_tnC_apR_.glif55
-rw-r--r--tests/reference/ufo/psfcopyglyphs.ufo/glyphs/L_tnC_apS_.glif50
-rw-r--r--tests/reference/ufo/psfcopyglyphs.ufo/glyphs/L_tnC_apT_.glif32
-rw-r--r--tests/reference/ufo/psfcopyglyphs.ufo/glyphs/L_tnC_apU_.glif44
-rw-r--r--tests/reference/ufo/psfcopyglyphs.ufo/glyphs/L_tnC_apV_.glif26
-rw-r--r--tests/reference/ufo/psfcopyglyphs.ufo/glyphs/L_tnC_apW_.glif44
-rw-r--r--tests/reference/ufo/psfcopyglyphs.ufo/glyphs/L_tnC_apX_.glif39
-rw-r--r--tests/reference/ufo/psfcopyglyphs.ufo/glyphs/L_tnC_apY_.glif39
-rw-r--r--tests/reference/ufo/psfcopyglyphs.ufo/glyphs/L_tnS_mA_.glif77
-rw-r--r--tests/reference/ufo/psfcopyglyphs.ufo/glyphs/L_tnS_mA_A_cute.glif14
-rw-r--r--tests/reference/ufo/psfcopyglyphs.ufo/glyphs/L_tnS_mA_C_ircum.glif14
-rw-r--r--tests/reference/ufo/psfcopyglyphs.ufo/glyphs/L_tnS_mA_D_iaer.glif14
-rw-r--r--tests/reference/ufo/psfcopyglyphs.ufo/glyphs/L_tnS_mA_G_rave.glif14
-rw-r--r--tests/reference/ufo/psfcopyglyphs.ufo/glyphs/L_tnS_mA_R_ingA_bv.glif14
-rw-r--r--tests/reference/ufo/psfcopyglyphs.ufo/glyphs/L_tnS_mA_T_ilde.glif14
-rw-r--r--tests/reference/ufo/psfcopyglyphs.ufo/glyphs/L_tnS_mB_.glif55
-rw-r--r--tests/reference/ufo/psfcopyglyphs.ufo/glyphs/L_tnS_mC_.glif39
-rw-r--r--tests/reference/ufo/psfcopyglyphs.ufo/glyphs/L_tnS_mD_.glif65
-rw-r--r--tests/reference/ufo/psfcopyglyphs.ufo/glyphs/L_tnS_mE_.glif52
-rw-r--r--tests/reference/ufo/psfcopyglyphs.ufo/glyphs/L_tnS_mF_.glif44
-rw-r--r--tests/reference/ufo/psfcopyglyphs.ufo/glyphs/L_tnS_mG_.glif100
-rw-r--r--tests/reference/ufo/psfcopyglyphs.ufo/glyphs/L_tnS_mH_.glif54
-rw-r--r--tests/reference/ufo/psfcopyglyphs.ufo/glyphs/L_tnS_mI_.glif50
-rw-r--r--tests/reference/ufo/psfcopyglyphs.ufo/glyphs/L_tnS_mJ_.glif45
-rw-r--r--tests/reference/ufo/psfcopyglyphs.ufo/glyphs/L_tnS_mK_.glif50
-rw-r--r--tests/reference/ufo/psfcopyglyphs.ufo/glyphs/L_tnS_mL_.glif35
-rw-r--r--tests/reference/ufo/psfcopyglyphs.ufo/glyphs/L_tnS_mM_.glif80
-rw-r--r--tests/reference/ufo/psfcopyglyphs.ufo/glyphs/L_tnS_mN_.glif57
-rw-r--r--tests/reference/ufo/psfcopyglyphs.ufo/glyphs/L_tnS_mO_.glif40
-rw-r--r--tests/reference/ufo/psfcopyglyphs.ufo/glyphs/L_tnS_mP_.glif66
-rw-r--r--tests/reference/ufo/psfcopyglyphs.ufo/glyphs/L_tnS_mQ_.glif54
-rw-r--r--tests/reference/ufo/psfcopyglyphs.ufo/glyphs/L_tnS_mR_.glif42
-rw-r--r--tests/reference/ufo/psfcopyglyphs.ufo/glyphs/L_tnS_mS_.glif50
-rw-r--r--tests/reference/ufo/psfcopyglyphs.ufo/glyphs/L_tnS_mT_.glif45
-rw-r--r--tests/reference/ufo/psfcopyglyphs.ufo/glyphs/L_tnS_mU_.glif57
-rw-r--r--tests/reference/ufo/psfcopyglyphs.ufo/glyphs/L_tnS_mV_.glif34
-rw-r--r--tests/reference/ufo/psfcopyglyphs.ufo/glyphs/L_tnS_mW_.glif50
-rw-r--r--tests/reference/ufo/psfcopyglyphs.ufo/glyphs/L_tnS_mX_.glif40
-rw-r--r--tests/reference/ufo/psfcopyglyphs.ufo/glyphs/L_tnS_mY_.glif45
-rw-r--r--tests/reference/ufo/psfcopyglyphs.ufo/glyphs/N_onB_reakingH_yphen.glif9
-rw-r--r--tests/reference/ufo/psfcopyglyphs.ufo/glyphs/N_umS_gn.glif31
-rw-r--r--tests/reference/ufo/psfcopyglyphs.ufo/glyphs/P_ercentS_gn.glif93
-rw-r--r--tests/reference/ufo/psfcopyglyphs.ufo/glyphs/P_lusS_gn.glif19
-rw-r--r--tests/reference/ufo/psfcopyglyphs.ufo/glyphs/Q_stnM_rk.glif49
-rw-r--r--tests/reference/ufo/psfcopyglyphs.ufo/glyphs/Q_uotM_rk.glif27
-rw-r--r--tests/reference/ufo/psfcopyglyphs.ufo/glyphs/R_everseS_olidus.glif13
-rw-r--r--tests/reference/ufo/psfcopyglyphs.ufo/glyphs/R_tC_urlyB_rac.glif50
-rw-r--r--tests/reference/ufo/psfcopyglyphs.ufo/glyphs/R_tP_aren.glif29
-rw-r--r--tests/reference/ufo/psfcopyglyphs.ufo/glyphs/R_tS_qrB_rac.glif17
-rw-r--r--tests/reference/ufo/psfcopyglyphs.ufo/glyphs/S_emicolon.glif38
-rw-r--r--tests/reference/ufo/psfcopyglyphs.ufo/glyphs/S_olidus.glif13
-rw-r--r--tests/reference/ufo/psfcopyglyphs.ufo/glyphs/S_pace.glif6
-rw-r--r--tests/reference/ufo/psfcopyglyphs.ufo/glyphs/S_tar.glif51
-rw-r--r--tests/reference/ufo/psfcopyglyphs.ufo/glyphs/T_ilde.glif29
-rw-r--r--tests/reference/ufo/psfcopyglyphs.ufo/glyphs/V_ertL_ine.glif13
-rw-r--r--tests/reference/ufo/psfcopyglyphs.ufo/glyphs/_notdef.glif18
-rw-r--r--tests/reference/ufo/psfcopyglyphs.ufo/glyphs/_null.glif4
-rw-r--r--tests/reference/ufo/psfcopyglyphs.ufo/glyphs/contents.plist240
-rw-r--r--tests/reference/ufo/psfcopyglyphs.ufo/glyphs/nonmarkingreturn.glif5
-rw-r--r--tests/reference/ufo/psfcopyglyphs.ufo/layercontents.plist10
-rw-r--r--tests/reference/ufo/psfcopyglyphs.ufo/lib.plist538
-rw-r--r--tests/reference/ufo/psfcopyglyphs.ufo/metainfo.plist10
-rw-r--r--tests/reference/ufo/psfdeleteglyphs.lg27
-rw-r--r--tests/reference/ufo/psfdeleteglyphs.ufo/fontinfo.plist260
-rw-r--r--tests/reference/ufo/psfdeleteglyphs.ufo/glyphs/A_mpersand.glif61
-rw-r--r--tests/reference/ufo/psfdeleteglyphs.ufo/glyphs/A_sterisk.glif51
-rw-r--r--tests/reference/ufo/psfdeleteglyphs.ufo/glyphs/A_tS_gn.glif80
-rw-r--r--tests/reference/ufo/psfdeleteglyphs.ufo/glyphs/C_ircumA_ccent.glif8
-rw-r--r--tests/reference/ufo/psfdeleteglyphs.ufo/glyphs/C_olon.glif35
-rw-r--r--tests/reference/ufo/psfdeleteglyphs.ufo/glyphs/C_ombA_cute.glif14
-rw-r--r--tests/reference/ufo/psfdeleteglyphs.ufo/glyphs/C_ombC_ircum.glif17
-rw-r--r--tests/reference/ufo/psfdeleteglyphs.ufo/glyphs/C_ombD_iaer.glif36
-rw-r--r--tests/reference/ufo/psfdeleteglyphs.ufo/glyphs/C_ombG_rave.glif14
-rw-r--r--tests/reference/ufo/psfdeleteglyphs.ufo/glyphs/C_ombR_ingA_bv.glif36
-rw-r--r--tests/reference/ufo/psfdeleteglyphs.ufo/glyphs/C_ombT_ilde.glif36
-rw-r--r--tests/reference/ufo/psfdeleteglyphs.ufo/glyphs/D_igitE_ight.glif63
-rw-r--r--tests/reference/ufo/psfdeleteglyphs.ufo/glyphs/D_igitF_ive.glif44
-rw-r--r--tests/reference/ufo/psfdeleteglyphs.ufo/glyphs/D_igitF_our.glif27
-rw-r--r--tests/reference/ufo/psfdeleteglyphs.ufo/glyphs/D_igitN_ine.glif49
-rw-r--r--tests/reference/ufo/psfdeleteglyphs.ufo/glyphs/D_igitO_ne.glif22
-rw-r--r--tests/reference/ufo/psfdeleteglyphs.ufo/glyphs/D_igitS_even.glif25
-rw-r--r--tests/reference/ufo/psfdeleteglyphs.ufo/glyphs/D_igitS_ix.glif49
-rw-r--r--tests/reference/ufo/psfdeleteglyphs.ufo/glyphs/D_igitT_hree.glif52
-rw-r--r--tests/reference/ufo/psfdeleteglyphs.ufo/glyphs/D_igitT_wo.glif37
-rw-r--r--tests/reference/ufo/psfdeleteglyphs.ufo/glyphs/D_igitZ_ero.glif37
-rw-r--r--tests/reference/ufo/psfdeleteglyphs.ufo/glyphs/D_ollarS_gn.glif53
-rw-r--r--tests/reference/ufo/psfdeleteglyphs.ufo/glyphs/D_ottedC_irc.glif235
-rw-r--r--tests/reference/ufo/psfdeleteglyphs.ufo/glyphs/E_qS_gn.glif19
-rw-r--r--tests/reference/ufo/psfdeleteglyphs.ufo/glyphs/E_xclamationM_rk.glif31
-rw-r--r--tests/reference/ufo/psfdeleteglyphs.ufo/glyphs/F_ullS_top.glif21
-rw-r--r--tests/reference/ufo/psfdeleteglyphs.ufo/glyphs/G_T_S_gn.glif16
-rw-r--r--tests/reference/ufo/psfdeleteglyphs.ufo/glyphs/G_raveA_ccent.glif8
-rw-r--r--tests/reference/ufo/psfdeleteglyphs.ufo/glyphs/H_yphen.glif14
-rw-r--r--tests/reference/ufo/psfdeleteglyphs.ufo/glyphs/H_yphenM_inus.glif14
-rw-r--r--tests/reference/ufo/psfdeleteglyphs.ufo/glyphs/H_yphen_S_oft.glif9
-rw-r--r--tests/reference/ufo/psfdeleteglyphs.ufo/glyphs/L_T_S_gn.glif16
-rw-r--r--tests/reference/ufo/psfdeleteglyphs.ufo/glyphs/L_ftC_urlyB_rac.glif47
-rw-r--r--tests/reference/ufo/psfdeleteglyphs.ufo/glyphs/L_ftP_aren.glif23
-rw-r--r--tests/reference/ufo/psfdeleteglyphs.ufo/glyphs/L_ftS_qrB_rac.glif17
-rw-r--r--tests/reference/ufo/psfdeleteglyphs.ufo/glyphs/L_owL_ine.glif13
-rw-r--r--tests/reference/ufo/psfdeleteglyphs.ufo/glyphs/L_tnC_apA_.alt.glif31
-rw-r--r--tests/reference/ufo/psfdeleteglyphs.ufo/glyphs/L_tnC_apA_.glif32
-rw-r--r--tests/reference/ufo/psfdeleteglyphs.ufo/glyphs/L_tnC_apA_D_iaer.glif13
-rw-r--r--tests/reference/ufo/psfdeleteglyphs.ufo/glyphs/L_tnC_apB_.glif62
-rw-r--r--tests/reference/ufo/psfdeleteglyphs.ufo/glyphs/L_tnC_apC_.glif38
-rw-r--r--tests/reference/ufo/psfdeleteglyphs.ufo/glyphs/L_tnC_apD_.glif45
-rw-r--r--tests/reference/ufo/psfdeleteglyphs.ufo/glyphs/L_tnC_apE_.glif35
-rw-r--r--tests/reference/ufo/psfdeleteglyphs.ufo/glyphs/L_tnC_apF_.glif30
-rw-r--r--tests/reference/ufo/psfdeleteglyphs.ufo/glyphs/L_tnC_apG_.glif42
-rw-r--r--tests/reference/ufo/psfdeleteglyphs.ufo/glyphs/L_tnC_apH_.glif36
-rw-r--r--tests/reference/ufo/psfdeleteglyphs.ufo/glyphs/L_tnC_apI_.glif26
-rw-r--r--tests/reference/ufo/psfdeleteglyphs.ufo/glyphs/L_tnC_apJ_.glif30
-rw-r--r--tests/reference/ufo/psfdeleteglyphs.ufo/glyphs/L_tnC_apK_.glif35
-rw-r--r--tests/reference/ufo/psfdeleteglyphs.ufo/glyphs/L_tnC_apL_.glif28
-rw-r--r--tests/reference/ufo/psfdeleteglyphs.ufo/glyphs/L_tnC_apM_.glif37
-rw-r--r--tests/reference/ufo/psfdeleteglyphs.ufo/glyphs/L_tnC_apN_.glif37
-rw-r--r--tests/reference/ufo/psfdeleteglyphs.ufo/glyphs/L_tnC_apO_.glif40
-rw-r--r--tests/reference/ufo/psfdeleteglyphs.ufo/glyphs/L_tnC_apP_.glif50
-rw-r--r--tests/reference/ufo/psfdeleteglyphs.ufo/glyphs/L_tnC_apQ_.glif49
-rw-r--r--tests/reference/ufo/psfdeleteglyphs.ufo/glyphs/L_tnC_apR_.glif55
-rw-r--r--tests/reference/ufo/psfdeleteglyphs.ufo/glyphs/L_tnC_apS_.glif50
-rw-r--r--tests/reference/ufo/psfdeleteglyphs.ufo/glyphs/L_tnC_apT_.glif32
-rw-r--r--tests/reference/ufo/psfdeleteglyphs.ufo/glyphs/L_tnC_apU_.glif38
-rw-r--r--tests/reference/ufo/psfdeleteglyphs.ufo/glyphs/L_tnC_apV_.glif26
-rw-r--r--tests/reference/ufo/psfdeleteglyphs.ufo/glyphs/L_tnC_apW_.glif45
-rw-r--r--tests/reference/ufo/psfdeleteglyphs.ufo/glyphs/L_tnC_apX_.glif35
-rw-r--r--tests/reference/ufo/psfdeleteglyphs.ufo/glyphs/L_tnC_apY_.glif32
-rw-r--r--tests/reference/ufo/psfdeleteglyphs.ufo/glyphs/L_tnS_mA_.glif76
-rw-r--r--tests/reference/ufo/psfdeleteglyphs.ufo/glyphs/L_tnS_mA_A_cute.glif14
-rw-r--r--tests/reference/ufo/psfdeleteglyphs.ufo/glyphs/L_tnS_mA_C_ircum.glif14
-rw-r--r--tests/reference/ufo/psfdeleteglyphs.ufo/glyphs/L_tnS_mA_D_iaer.glif14
-rw-r--r--tests/reference/ufo/psfdeleteglyphs.ufo/glyphs/L_tnS_mA_G_rave.glif14
-rw-r--r--tests/reference/ufo/psfdeleteglyphs.ufo/glyphs/L_tnS_mA_R_ingA_bv.glif41
-rw-r--r--tests/reference/ufo/psfdeleteglyphs.ufo/glyphs/L_tnS_mA_T_ilde.glif41
-rw-r--r--tests/reference/ufo/psfdeleteglyphs.ufo/glyphs/L_tnS_mB_.glif50
-rw-r--r--tests/reference/ufo/psfdeleteglyphs.ufo/glyphs/L_tnS_mC_.glif39
-rw-r--r--tests/reference/ufo/psfdeleteglyphs.ufo/glyphs/L_tnS_mD_.glif53
-rw-r--r--tests/reference/ufo/psfdeleteglyphs.ufo/glyphs/L_tnS_mE_.glif45
-rw-r--r--tests/reference/ufo/psfdeleteglyphs.ufo/glyphs/L_tnS_mF_.glif39
-rw-r--r--tests/reference/ufo/psfdeleteglyphs.ufo/glyphs/L_tnS_mG_.glif91
-rw-r--r--tests/reference/ufo/psfdeleteglyphs.ufo/glyphs/L_tnS_mH_.glif43
-rw-r--r--tests/reference/ufo/psfdeleteglyphs.ufo/glyphs/L_tnS_mI_.glif40
-rw-r--r--tests/reference/ufo/psfdeleteglyphs.ufo/glyphs/L_tnS_mJ_.glif44
-rw-r--r--tests/reference/ufo/psfdeleteglyphs.ufo/glyphs/L_tnS_mK_.glif35
-rw-r--r--tests/reference/ufo/psfdeleteglyphs.ufo/glyphs/L_tnS_mL_.glif24
-rw-r--r--tests/reference/ufo/psfdeleteglyphs.ufo/glyphs/L_tnS_mM_.glif52
-rw-r--r--tests/reference/ufo/psfdeleteglyphs.ufo/glyphs/L_tnS_mN_.glif43
-rw-r--r--tests/reference/ufo/psfdeleteglyphs.ufo/glyphs/L_tnS_mO_.glif40
-rw-r--r--tests/reference/ufo/psfdeleteglyphs.ufo/glyphs/L_tnS_mP_.glif56
-rw-r--r--tests/reference/ufo/psfdeleteglyphs.ufo/glyphs/L_tnS_mQ_.glif47
-rw-r--r--tests/reference/ufo/psfdeleteglyphs.ufo/glyphs/L_tnS_mR_.glif36
-rw-r--r--tests/reference/ufo/psfdeleteglyphs.ufo/glyphs/L_tnS_mS_.glif50
-rw-r--r--tests/reference/ufo/psfdeleteglyphs.ufo/glyphs/L_tnS_mT_.glif39
-rw-r--r--tests/reference/ufo/psfdeleteglyphs.ufo/glyphs/L_tnS_mU_.glif51
-rw-r--r--tests/reference/ufo/psfdeleteglyphs.ufo/glyphs/L_tnS_mV_.glif30
-rw-r--r--tests/reference/ufo/psfdeleteglyphs.ufo/glyphs/L_tnS_mW_.glif30
-rw-r--r--tests/reference/ufo/psfdeleteglyphs.ufo/glyphs/L_tnS_mX_.glif40
-rw-r--r--tests/reference/ufo/psfdeleteglyphs.ufo/glyphs/L_tnS_mY_.glif42
-rw-r--r--tests/reference/ufo/psfdeleteglyphs.ufo/glyphs/N_onB_reakingH_yphen.glif9
-rw-r--r--tests/reference/ufo/psfdeleteglyphs.ufo/glyphs/N_umS_gn.glif31
-rw-r--r--tests/reference/ufo/psfdeleteglyphs.ufo/glyphs/P_ercentS_gn.glif69
-rw-r--r--tests/reference/ufo/psfdeleteglyphs.ufo/glyphs/P_lusS_gn.glif19
-rw-r--r--tests/reference/ufo/psfdeleteglyphs.ufo/glyphs/Q_stnM_rk.glif49
-rw-r--r--tests/reference/ufo/psfdeleteglyphs.ufo/glyphs/Q_uotM_rk.glif27
-rw-r--r--tests/reference/ufo/psfdeleteglyphs.ufo/glyphs/R_everseS_olidus.glif13
-rw-r--r--tests/reference/ufo/psfdeleteglyphs.ufo/glyphs/R_tC_urlyB_rac.glif47
-rw-r--r--tests/reference/ufo/psfdeleteglyphs.ufo/glyphs/R_tP_aren.glif23
-rw-r--r--tests/reference/ufo/psfdeleteglyphs.ufo/glyphs/R_tS_qrB_rac.glif17
-rw-r--r--tests/reference/ufo/psfdeleteglyphs.ufo/glyphs/S_emicolon.glif38
-rw-r--r--tests/reference/ufo/psfdeleteglyphs.ufo/glyphs/S_olidus.glif13
-rw-r--r--tests/reference/ufo/psfdeleteglyphs.ufo/glyphs/S_pace.glif6
-rw-r--r--tests/reference/ufo/psfdeleteglyphs.ufo/glyphs/T_ilde.glif29
-rw-r--r--tests/reference/ufo/psfdeleteglyphs.ufo/glyphs/V_ertL_ine.glif13
-rw-r--r--tests/reference/ufo/psfdeleteglyphs.ufo/glyphs/_notdef.glif18
-rw-r--r--tests/reference/ufo/psfdeleteglyphs.ufo/glyphs/_null.glif4
-rw-r--r--tests/reference/ufo/psfdeleteglyphs.ufo/glyphs/contents.plist230
-rw-r--r--tests/reference/ufo/psfdeleteglyphs.ufo/glyphs/nonmarkingreturn.glif5
-rw-r--r--tests/reference/ufo/psfdeleteglyphs.ufo/layercontents.plist10
-rw-r--r--tests/reference/ufo/psfdeleteglyphs.ufo/lib.plist536
-rw-r--r--tests/reference/ufo/psfdeleteglyphs.ufo/metainfo.plist10
-rw-r--r--tests/reference/ufo/psfexportanchors.lg17
-rw-r--r--tests/reference/ufo/psfexportanchors.xml928
-rw-r--r--tests/reference/ufo/psfexportunicodes.csv113
-rw-r--r--tests/reference/ufo/psfexportunicodes.lg14
-rw-r--r--tests/reference/ufo/psfgenftml.ftml66
-rw-r--r--tests/reference/ufo/psfgenftml.lg19
-rw-r--r--tests/reference/ufo/psfglyphs2ufo.lg13
-rw-r--r--tests/reference/ufo/psfglyphs2ufo/PsfTest-Bold.ufo/fontinfo.plist245
-rw-r--r--tests/reference/ufo/psfglyphs2ufo/PsfTest-Bold.ufo/glyphs/A_mpersand.glif61
-rw-r--r--tests/reference/ufo/psfglyphs2ufo/PsfTest-Bold.ufo/glyphs/A_pos.glif17
-rw-r--r--tests/reference/ufo/psfglyphs2ufo/PsfTest-Bold.ufo/glyphs/A_sterisk.glif51
-rw-r--r--tests/reference/ufo/psfglyphs2ufo/PsfTest-Bold.ufo/glyphs/A_tS_gn.glif80
-rw-r--r--tests/reference/ufo/psfglyphs2ufo/PsfTest-Bold.ufo/glyphs/C_ircumA_ccent.glif17
-rw-r--r--tests/reference/ufo/psfglyphs2ufo/PsfTest-Bold.ufo/glyphs/C_olon.glif35
-rw-r--r--tests/reference/ufo/psfglyphs2ufo/PsfTest-Bold.ufo/glyphs/C_ombA_cute.glif14
-rw-r--r--tests/reference/ufo/psfglyphs2ufo/PsfTest-Bold.ufo/glyphs/C_ombC_ircum.glif17
-rw-r--r--tests/reference/ufo/psfglyphs2ufo/PsfTest-Bold.ufo/glyphs/C_ombD_iaer.glif36
-rw-r--r--tests/reference/ufo/psfglyphs2ufo/PsfTest-Bold.ufo/glyphs/C_ombG_rave.glif14
-rw-r--r--tests/reference/ufo/psfglyphs2ufo/PsfTest-Bold.ufo/glyphs/C_ombR_ingA_bv.glif36
-rw-r--r--tests/reference/ufo/psfglyphs2ufo/PsfTest-Bold.ufo/glyphs/C_ombT_ilde.glif36
-rw-r--r--tests/reference/ufo/psfglyphs2ufo/PsfTest-Bold.ufo/glyphs/C_omma.glif24
-rw-r--r--tests/reference/ufo/psfglyphs2ufo/PsfTest-Bold.ufo/glyphs/D_igitE_ight.glif63
-rw-r--r--tests/reference/ufo/psfglyphs2ufo/PsfTest-Bold.ufo/glyphs/D_igitF_ive.glif44
-rw-r--r--tests/reference/ufo/psfglyphs2ufo/PsfTest-Bold.ufo/glyphs/D_igitF_our.glif27
-rw-r--r--tests/reference/ufo/psfglyphs2ufo/PsfTest-Bold.ufo/glyphs/D_igitN_ine.glif49
-rw-r--r--tests/reference/ufo/psfglyphs2ufo/PsfTest-Bold.ufo/glyphs/D_igitO_ne.glif22
-rw-r--r--tests/reference/ufo/psfglyphs2ufo/PsfTest-Bold.ufo/glyphs/D_igitS_even.glif25
-rw-r--r--tests/reference/ufo/psfglyphs2ufo/PsfTest-Bold.ufo/glyphs/D_igitS_ix.glif49
-rw-r--r--tests/reference/ufo/psfglyphs2ufo/PsfTest-Bold.ufo/glyphs/D_igitT_hree.glif52
-rw-r--r--tests/reference/ufo/psfglyphs2ufo/PsfTest-Bold.ufo/glyphs/D_igitT_wo.glif37
-rw-r--r--tests/reference/ufo/psfglyphs2ufo/PsfTest-Bold.ufo/glyphs/D_igitZ_ero.glif37
-rw-r--r--tests/reference/ufo/psfglyphs2ufo/PsfTest-Bold.ufo/glyphs/D_ollarS_gn.glif57
-rw-r--r--tests/reference/ufo/psfglyphs2ufo/PsfTest-Bold.ufo/glyphs/D_ottedC_irc.glif235
-rw-r--r--tests/reference/ufo/psfglyphs2ufo/PsfTest-Bold.ufo/glyphs/E_qS_gn.glif19
-rw-r--r--tests/reference/ufo/psfglyphs2ufo/PsfTest-Bold.ufo/glyphs/E_xclamationM_rk.glif31
-rw-r--r--tests/reference/ufo/psfglyphs2ufo/PsfTest-Bold.ufo/glyphs/F_ullS_top.glif21
-rw-r--r--tests/reference/ufo/psfglyphs2ufo/PsfTest-Bold.ufo/glyphs/G_T_S_gn.glif16
-rw-r--r--tests/reference/ufo/psfglyphs2ufo/PsfTest-Bold.ufo/glyphs/G_raveA_ccent.glif14
-rw-r--r--tests/reference/ufo/psfglyphs2ufo/PsfTest-Bold.ufo/glyphs/H_yphen.glif14
-rw-r--r--tests/reference/ufo/psfglyphs2ufo/PsfTest-Bold.ufo/glyphs/H_yphenM_inus.glif14
-rw-r--r--tests/reference/ufo/psfglyphs2ufo/PsfTest-Bold.ufo/glyphs/H_yphen_S_oft.glif9
-rw-r--r--tests/reference/ufo/psfglyphs2ufo/PsfTest-Bold.ufo/glyphs/L_T_S_gn.glif16
-rw-r--r--tests/reference/ufo/psfglyphs2ufo/PsfTest-Bold.ufo/glyphs/L_ftC_urlyB_rac.glif47
-rw-r--r--tests/reference/ufo/psfglyphs2ufo/PsfTest-Bold.ufo/glyphs/L_ftP_aren.glif23
-rw-r--r--tests/reference/ufo/psfglyphs2ufo/PsfTest-Bold.ufo/glyphs/L_ftS_qrB_rac.glif17
-rw-r--r--tests/reference/ufo/psfglyphs2ufo/PsfTest-Bold.ufo/glyphs/L_owL_ine.glif13
-rw-r--r--tests/reference/ufo/psfglyphs2ufo/PsfTest-Bold.ufo/glyphs/L_tnC_apA_.alt.glif31
-rw-r--r--tests/reference/ufo/psfglyphs2ufo/PsfTest-Bold.ufo/glyphs/L_tnC_apA_.glif32
-rw-r--r--tests/reference/ufo/psfglyphs2ufo/PsfTest-Bold.ufo/glyphs/L_tnC_apA_D_iaer.glif13
-rw-r--r--tests/reference/ufo/psfglyphs2ufo/PsfTest-Bold.ufo/glyphs/L_tnC_apB_.glif62
-rw-r--r--tests/reference/ufo/psfglyphs2ufo/PsfTest-Bold.ufo/glyphs/L_tnC_apC_.glif38
-rw-r--r--tests/reference/ufo/psfglyphs2ufo/PsfTest-Bold.ufo/glyphs/L_tnC_apD_.glif45
-rw-r--r--tests/reference/ufo/psfglyphs2ufo/PsfTest-Bold.ufo/glyphs/L_tnC_apE_.glif35
-rw-r--r--tests/reference/ufo/psfglyphs2ufo/PsfTest-Bold.ufo/glyphs/L_tnC_apF_.glif30
-rw-r--r--tests/reference/ufo/psfglyphs2ufo/PsfTest-Bold.ufo/glyphs/L_tnC_apG_.glif42
-rw-r--r--tests/reference/ufo/psfglyphs2ufo/PsfTest-Bold.ufo/glyphs/L_tnC_apH_.glif40
-rw-r--r--tests/reference/ufo/psfglyphs2ufo/PsfTest-Bold.ufo/glyphs/L_tnC_apI_.glif26
-rw-r--r--tests/reference/ufo/psfglyphs2ufo/PsfTest-Bold.ufo/glyphs/L_tnC_apJ_.glif32
-rw-r--r--tests/reference/ufo/psfglyphs2ufo/PsfTest-Bold.ufo/glyphs/L_tnC_apK_.glif34
-rw-r--r--tests/reference/ufo/psfglyphs2ufo/PsfTest-Bold.ufo/glyphs/L_tnC_apL_.glif28
-rw-r--r--tests/reference/ufo/psfglyphs2ufo/PsfTest-Bold.ufo/glyphs/L_tnC_apM_.glif38
-rw-r--r--tests/reference/ufo/psfglyphs2ufo/PsfTest-Bold.ufo/glyphs/L_tnC_apN_.glif37
-rw-r--r--tests/reference/ufo/psfglyphs2ufo/PsfTest-Bold.ufo/glyphs/L_tnC_apO_.glif40
-rw-r--r--tests/reference/ufo/psfglyphs2ufo/PsfTest-Bold.ufo/glyphs/L_tnC_apP_.glif50
-rw-r--r--tests/reference/ufo/psfglyphs2ufo/PsfTest-Bold.ufo/glyphs/L_tnC_apQ_.glif49
-rw-r--r--tests/reference/ufo/psfglyphs2ufo/PsfTest-Bold.ufo/glyphs/L_tnC_apR_.glif55
-rw-r--r--tests/reference/ufo/psfglyphs2ufo/PsfTest-Bold.ufo/glyphs/L_tnC_apS_.glif50
-rw-r--r--tests/reference/ufo/psfglyphs2ufo/PsfTest-Bold.ufo/glyphs/L_tnC_apT_.glif32
-rw-r--r--tests/reference/ufo/psfglyphs2ufo/PsfTest-Bold.ufo/glyphs/L_tnC_apU_.glif38
-rw-r--r--tests/reference/ufo/psfglyphs2ufo/PsfTest-Bold.ufo/glyphs/L_tnC_apV_.glif26
-rw-r--r--tests/reference/ufo/psfglyphs2ufo/PsfTest-Bold.ufo/glyphs/L_tnC_apW_.glif45
-rw-r--r--tests/reference/ufo/psfglyphs2ufo/PsfTest-Bold.ufo/glyphs/L_tnC_apX_.glif39
-rw-r--r--tests/reference/ufo/psfglyphs2ufo/PsfTest-Bold.ufo/glyphs/L_tnC_apY_.glif39
-rw-r--r--tests/reference/ufo/psfglyphs2ufo/PsfTest-Bold.ufo/glyphs/L_tnS_mA_.glif68
-rw-r--r--tests/reference/ufo/psfglyphs2ufo/PsfTest-Bold.ufo/glyphs/L_tnS_mA_A_cute.glif14
-rw-r--r--tests/reference/ufo/psfglyphs2ufo/PsfTest-Bold.ufo/glyphs/L_tnS_mA_C_ircum.glif14
-rw-r--r--tests/reference/ufo/psfglyphs2ufo/PsfTest-Bold.ufo/glyphs/L_tnS_mA_D_iaer.glif14
-rw-r--r--tests/reference/ufo/psfglyphs2ufo/PsfTest-Bold.ufo/glyphs/L_tnS_mA_G_rave.glif14
-rw-r--r--tests/reference/ufo/psfglyphs2ufo/PsfTest-Bold.ufo/glyphs/L_tnS_mA_R_ingA_bv.glif14
-rw-r--r--tests/reference/ufo/psfglyphs2ufo/PsfTest-Bold.ufo/glyphs/L_tnS_mA_T_ilde.glif14
-rw-r--r--tests/reference/ufo/psfglyphs2ufo/PsfTest-Bold.ufo/glyphs/L_tnS_mB_.glif50
-rw-r--r--tests/reference/ufo/psfglyphs2ufo/PsfTest-Bold.ufo/glyphs/L_tnS_mC_.glif39
-rw-r--r--tests/reference/ufo/psfglyphs2ufo/PsfTest-Bold.ufo/glyphs/L_tnS_mD_.glif53
-rw-r--r--tests/reference/ufo/psfglyphs2ufo/PsfTest-Bold.ufo/glyphs/L_tnS_mE_.glif45
-rw-r--r--tests/reference/ufo/psfglyphs2ufo/PsfTest-Bold.ufo/glyphs/L_tnS_mF_.glif39
-rw-r--r--tests/reference/ufo/psfglyphs2ufo/PsfTest-Bold.ufo/glyphs/L_tnS_mG_.glif91
-rw-r--r--tests/reference/ufo/psfglyphs2ufo/PsfTest-Bold.ufo/glyphs/L_tnS_mH_.glif43
-rw-r--r--tests/reference/ufo/psfglyphs2ufo/PsfTest-Bold.ufo/glyphs/L_tnS_mI_.glif42
-rw-r--r--tests/reference/ufo/psfglyphs2ufo/PsfTest-Bold.ufo/glyphs/L_tnS_mJ_.glif44
-rw-r--r--tests/reference/ufo/psfglyphs2ufo/PsfTest-Bold.ufo/glyphs/L_tnS_mK_.glif34
-rw-r--r--tests/reference/ufo/psfglyphs2ufo/PsfTest-Bold.ufo/glyphs/L_tnS_mL_.glif23
-rw-r--r--tests/reference/ufo/psfglyphs2ufo/PsfTest-Bold.ufo/glyphs/L_tnS_mM_.glif52
-rw-r--r--tests/reference/ufo/psfglyphs2ufo/PsfTest-Bold.ufo/glyphs/L_tnS_mN_.glif43
-rw-r--r--tests/reference/ufo/psfglyphs2ufo/PsfTest-Bold.ufo/glyphs/L_tnS_mO_.glif40
-rw-r--r--tests/reference/ufo/psfglyphs2ufo/PsfTest-Bold.ufo/glyphs/L_tnS_mP_.glif59
-rw-r--r--tests/reference/ufo/psfglyphs2ufo/PsfTest-Bold.ufo/glyphs/L_tnS_mQ_.glif47
-rw-r--r--tests/reference/ufo/psfglyphs2ufo/PsfTest-Bold.ufo/glyphs/L_tnS_mR_.glif35
-rw-r--r--tests/reference/ufo/psfglyphs2ufo/PsfTest-Bold.ufo/glyphs/L_tnS_mS_.glif50
-rw-r--r--tests/reference/ufo/psfglyphs2ufo/PsfTest-Bold.ufo/glyphs/L_tnS_mT_.glif35
-rw-r--r--tests/reference/ufo/psfglyphs2ufo/PsfTest-Bold.ufo/glyphs/L_tnS_mU_.glif51
-rw-r--r--tests/reference/ufo/psfglyphs2ufo/PsfTest-Bold.ufo/glyphs/L_tnS_mV_.glif30
-rw-r--r--tests/reference/ufo/psfglyphs2ufo/PsfTest-Bold.ufo/glyphs/L_tnS_mW_.glif30
-rw-r--r--tests/reference/ufo/psfglyphs2ufo/PsfTest-Bold.ufo/glyphs/L_tnS_mX_.glif40
-rw-r--r--tests/reference/ufo/psfglyphs2ufo/PsfTest-Bold.ufo/glyphs/L_tnS_mY_.glif39
-rw-r--r--tests/reference/ufo/psfglyphs2ufo/PsfTest-Bold.ufo/glyphs/N_onB_reakingH_yphen.glif9
-rw-r--r--tests/reference/ufo/psfglyphs2ufo/PsfTest-Bold.ufo/glyphs/N_umS_gn.glif31
-rw-r--r--tests/reference/ufo/psfglyphs2ufo/PsfTest-Bold.ufo/glyphs/P_ercentS_gn.glif69
-rw-r--r--tests/reference/ufo/psfglyphs2ufo/PsfTest-Bold.ufo/glyphs/P_lusS_gn.glif19
-rw-r--r--tests/reference/ufo/psfglyphs2ufo/PsfTest-Bold.ufo/glyphs/Q_stnM_rk.glif49
-rw-r--r--tests/reference/ufo/psfglyphs2ufo/PsfTest-Bold.ufo/glyphs/Q_uotM_rk.glif27
-rw-r--r--tests/reference/ufo/psfglyphs2ufo/PsfTest-Bold.ufo/glyphs/R_everseS_olidus.glif13
-rw-r--r--tests/reference/ufo/psfglyphs2ufo/PsfTest-Bold.ufo/glyphs/R_tC_urlyB_rac.glif47
-rw-r--r--tests/reference/ufo/psfglyphs2ufo/PsfTest-Bold.ufo/glyphs/R_tP_aren.glif23
-rw-r--r--tests/reference/ufo/psfglyphs2ufo/PsfTest-Bold.ufo/glyphs/R_tS_qrB_rac.glif17
-rw-r--r--tests/reference/ufo/psfglyphs2ufo/PsfTest-Bold.ufo/glyphs/S_emicolon.glif38
-rw-r--r--tests/reference/ufo/psfglyphs2ufo/PsfTest-Bold.ufo/glyphs/S_olidus.glif13
-rw-r--r--tests/reference/ufo/psfglyphs2ufo/PsfTest-Bold.ufo/glyphs/S_pace.glif6
-rw-r--r--tests/reference/ufo/psfglyphs2ufo/PsfTest-Bold.ufo/glyphs/T_ilde.glif29
-rw-r--r--tests/reference/ufo/psfglyphs2ufo/PsfTest-Bold.ufo/glyphs/V_ertL_ine.glif13
-rw-r--r--tests/reference/ufo/psfglyphs2ufo/PsfTest-Bold.ufo/glyphs/_notdef.glif18
-rw-r--r--tests/reference/ufo/psfglyphs2ufo/PsfTest-Bold.ufo/glyphs/_null.glif4
-rw-r--r--tests/reference/ufo/psfglyphs2ufo/PsfTest-Bold.ufo/glyphs/contents.plist234
-rw-r--r--tests/reference/ufo/psfglyphs2ufo/PsfTest-Bold.ufo/glyphs/nonmarkingreturn.glif5
-rw-r--r--tests/reference/ufo/psfglyphs2ufo/PsfTest-Bold.ufo/layercontents.plist10
-rw-r--r--tests/reference/ufo/psfglyphs2ufo/PsfTest-Bold.ufo/lib.plist417
-rw-r--r--tests/reference/ufo/psfglyphs2ufo/PsfTest-Bold.ufo/metainfo.plist10
-rw-r--r--tests/reference/ufo/psfglyphs2ufo/PsfTest-Regular.ufo/fontinfo.plist260
-rw-r--r--tests/reference/ufo/psfglyphs2ufo/PsfTest-Regular.ufo/glyphs/A_mpersand.glif61
-rw-r--r--tests/reference/ufo/psfglyphs2ufo/PsfTest-Regular.ufo/glyphs/A_pos.glif17
-rw-r--r--tests/reference/ufo/psfglyphs2ufo/PsfTest-Regular.ufo/glyphs/A_sterisk.glif51
-rw-r--r--tests/reference/ufo/psfglyphs2ufo/PsfTest-Regular.ufo/glyphs/A_tS_gn.glif80
-rw-r--r--tests/reference/ufo/psfglyphs2ufo/PsfTest-Regular.ufo/glyphs/C_ircumA_ccent.glif8
-rw-r--r--tests/reference/ufo/psfglyphs2ufo/PsfTest-Regular.ufo/glyphs/C_olon.glif35
-rw-r--r--tests/reference/ufo/psfglyphs2ufo/PsfTest-Regular.ufo/glyphs/C_ombA_cute.glif14
-rw-r--r--tests/reference/ufo/psfglyphs2ufo/PsfTest-Regular.ufo/glyphs/C_ombC_ircum.glif17
-rw-r--r--tests/reference/ufo/psfglyphs2ufo/PsfTest-Regular.ufo/glyphs/C_ombD_iaer.glif36
-rw-r--r--tests/reference/ufo/psfglyphs2ufo/PsfTest-Regular.ufo/glyphs/C_ombG_rave.glif14
-rw-r--r--tests/reference/ufo/psfglyphs2ufo/PsfTest-Regular.ufo/glyphs/C_ombR_ingA_bv.glif36
-rw-r--r--tests/reference/ufo/psfglyphs2ufo/PsfTest-Regular.ufo/glyphs/C_ombT_ilde.glif36
-rw-r--r--tests/reference/ufo/psfglyphs2ufo/PsfTest-Regular.ufo/glyphs/C_omma.glif24
-rw-r--r--tests/reference/ufo/psfglyphs2ufo/PsfTest-Regular.ufo/glyphs/D_igitE_ight.glif63
-rw-r--r--tests/reference/ufo/psfglyphs2ufo/PsfTest-Regular.ufo/glyphs/D_igitF_ive.glif44
-rw-r--r--tests/reference/ufo/psfglyphs2ufo/PsfTest-Regular.ufo/glyphs/D_igitF_our.glif27
-rw-r--r--tests/reference/ufo/psfglyphs2ufo/PsfTest-Regular.ufo/glyphs/D_igitN_ine.glif49
-rw-r--r--tests/reference/ufo/psfglyphs2ufo/PsfTest-Regular.ufo/glyphs/D_igitO_ne.glif22
-rw-r--r--tests/reference/ufo/psfglyphs2ufo/PsfTest-Regular.ufo/glyphs/D_igitS_even.glif25
-rw-r--r--tests/reference/ufo/psfglyphs2ufo/PsfTest-Regular.ufo/glyphs/D_igitS_ix.glif49
-rw-r--r--tests/reference/ufo/psfglyphs2ufo/PsfTest-Regular.ufo/glyphs/D_igitT_hree.glif52
-rw-r--r--tests/reference/ufo/psfglyphs2ufo/PsfTest-Regular.ufo/glyphs/D_igitT_wo.glif37
-rw-r--r--tests/reference/ufo/psfglyphs2ufo/PsfTest-Regular.ufo/glyphs/D_igitZ_ero.glif37
-rw-r--r--tests/reference/ufo/psfglyphs2ufo/PsfTest-Regular.ufo/glyphs/D_ollarS_gn.glif53
-rw-r--r--tests/reference/ufo/psfglyphs2ufo/PsfTest-Regular.ufo/glyphs/D_ottedC_irc.glif235
-rw-r--r--tests/reference/ufo/psfglyphs2ufo/PsfTest-Regular.ufo/glyphs/E_qS_gn.glif19
-rw-r--r--tests/reference/ufo/psfglyphs2ufo/PsfTest-Regular.ufo/glyphs/E_xclamationM_rk.glif31
-rw-r--r--tests/reference/ufo/psfglyphs2ufo/PsfTest-Regular.ufo/glyphs/F_ullS_top.glif21
-rw-r--r--tests/reference/ufo/psfglyphs2ufo/PsfTest-Regular.ufo/glyphs/G_T_S_gn.glif16
-rw-r--r--tests/reference/ufo/psfglyphs2ufo/PsfTest-Regular.ufo/glyphs/G_raveA_ccent.glif8
-rw-r--r--tests/reference/ufo/psfglyphs2ufo/PsfTest-Regular.ufo/glyphs/H_yphen.glif14
-rw-r--r--tests/reference/ufo/psfglyphs2ufo/PsfTest-Regular.ufo/glyphs/H_yphenM_inus.glif14
-rw-r--r--tests/reference/ufo/psfglyphs2ufo/PsfTest-Regular.ufo/glyphs/H_yphen_S_oft.glif9
-rw-r--r--tests/reference/ufo/psfglyphs2ufo/PsfTest-Regular.ufo/glyphs/L_T_S_gn.glif16
-rw-r--r--tests/reference/ufo/psfglyphs2ufo/PsfTest-Regular.ufo/glyphs/L_ftC_urlyB_rac.glif47
-rw-r--r--tests/reference/ufo/psfglyphs2ufo/PsfTest-Regular.ufo/glyphs/L_ftP_aren.glif23
-rw-r--r--tests/reference/ufo/psfglyphs2ufo/PsfTest-Regular.ufo/glyphs/L_ftS_qrB_rac.glif17
-rw-r--r--tests/reference/ufo/psfglyphs2ufo/PsfTest-Regular.ufo/glyphs/L_owL_ine.glif13
-rw-r--r--tests/reference/ufo/psfglyphs2ufo/PsfTest-Regular.ufo/glyphs/L_tnC_apA_.alt.glif31
-rw-r--r--tests/reference/ufo/psfglyphs2ufo/PsfTest-Regular.ufo/glyphs/L_tnC_apA_.glif32
-rw-r--r--tests/reference/ufo/psfglyphs2ufo/PsfTest-Regular.ufo/glyphs/L_tnC_apA_D_iaer.glif13
-rw-r--r--tests/reference/ufo/psfglyphs2ufo/PsfTest-Regular.ufo/glyphs/L_tnC_apB_.glif62
-rw-r--r--tests/reference/ufo/psfglyphs2ufo/PsfTest-Regular.ufo/glyphs/L_tnC_apC_.glif38
-rw-r--r--tests/reference/ufo/psfglyphs2ufo/PsfTest-Regular.ufo/glyphs/L_tnC_apD_.glif45
-rw-r--r--tests/reference/ufo/psfglyphs2ufo/PsfTest-Regular.ufo/glyphs/L_tnC_apE_.glif35
-rw-r--r--tests/reference/ufo/psfglyphs2ufo/PsfTest-Regular.ufo/glyphs/L_tnC_apF_.glif30
-rw-r--r--tests/reference/ufo/psfglyphs2ufo/PsfTest-Regular.ufo/glyphs/L_tnC_apG_.glif42
-rw-r--r--tests/reference/ufo/psfglyphs2ufo/PsfTest-Regular.ufo/glyphs/L_tnC_apH_.glif36
-rw-r--r--tests/reference/ufo/psfglyphs2ufo/PsfTest-Regular.ufo/glyphs/L_tnC_apI_.glif26
-rw-r--r--tests/reference/ufo/psfglyphs2ufo/PsfTest-Regular.ufo/glyphs/L_tnC_apJ_.glif30
-rw-r--r--tests/reference/ufo/psfglyphs2ufo/PsfTest-Regular.ufo/glyphs/L_tnC_apK_.glif35
-rw-r--r--tests/reference/ufo/psfglyphs2ufo/PsfTest-Regular.ufo/glyphs/L_tnC_apL_.glif28
-rw-r--r--tests/reference/ufo/psfglyphs2ufo/PsfTest-Regular.ufo/glyphs/L_tnC_apM_.glif37
-rw-r--r--tests/reference/ufo/psfglyphs2ufo/PsfTest-Regular.ufo/glyphs/L_tnC_apN_.glif37
-rw-r--r--tests/reference/ufo/psfglyphs2ufo/PsfTest-Regular.ufo/glyphs/L_tnC_apO_.glif40
-rw-r--r--tests/reference/ufo/psfglyphs2ufo/PsfTest-Regular.ufo/glyphs/L_tnC_apP_.glif50
-rw-r--r--tests/reference/ufo/psfglyphs2ufo/PsfTest-Regular.ufo/glyphs/L_tnC_apQ_.glif49
-rw-r--r--tests/reference/ufo/psfglyphs2ufo/PsfTest-Regular.ufo/glyphs/L_tnC_apR_.glif55
-rw-r--r--tests/reference/ufo/psfglyphs2ufo/PsfTest-Regular.ufo/glyphs/L_tnC_apS_.glif50
-rw-r--r--tests/reference/ufo/psfglyphs2ufo/PsfTest-Regular.ufo/glyphs/L_tnC_apT_.glif32
-rw-r--r--tests/reference/ufo/psfglyphs2ufo/PsfTest-Regular.ufo/glyphs/L_tnC_apU_.glif38
-rw-r--r--tests/reference/ufo/psfglyphs2ufo/PsfTest-Regular.ufo/glyphs/L_tnC_apV_.glif26
-rw-r--r--tests/reference/ufo/psfglyphs2ufo/PsfTest-Regular.ufo/glyphs/L_tnC_apW_.glif45
-rw-r--r--tests/reference/ufo/psfglyphs2ufo/PsfTest-Regular.ufo/glyphs/L_tnC_apX_.glif35
-rw-r--r--tests/reference/ufo/psfglyphs2ufo/PsfTest-Regular.ufo/glyphs/L_tnC_apY_.glif32
-rw-r--r--tests/reference/ufo/psfglyphs2ufo/PsfTest-Regular.ufo/glyphs/L_tnS_mA_.glif68
-rw-r--r--tests/reference/ufo/psfglyphs2ufo/PsfTest-Regular.ufo/glyphs/L_tnS_mA_A_cute.glif14
-rw-r--r--tests/reference/ufo/psfglyphs2ufo/PsfTest-Regular.ufo/glyphs/L_tnS_mA_C_ircum.glif14
-rw-r--r--tests/reference/ufo/psfglyphs2ufo/PsfTest-Regular.ufo/glyphs/L_tnS_mA_D_iaer.glif14
-rw-r--r--tests/reference/ufo/psfglyphs2ufo/PsfTest-Regular.ufo/glyphs/L_tnS_mA_G_rave.glif14
-rw-r--r--tests/reference/ufo/psfglyphs2ufo/PsfTest-Regular.ufo/glyphs/L_tnS_mA_R_ingA_bv.glif41
-rw-r--r--tests/reference/ufo/psfglyphs2ufo/PsfTest-Regular.ufo/glyphs/L_tnS_mA_T_ilde.glif41
-rw-r--r--tests/reference/ufo/psfglyphs2ufo/PsfTest-Regular.ufo/glyphs/L_tnS_mB_.glif50
-rw-r--r--tests/reference/ufo/psfglyphs2ufo/PsfTest-Regular.ufo/glyphs/L_tnS_mC_.glif39
-rw-r--r--tests/reference/ufo/psfglyphs2ufo/PsfTest-Regular.ufo/glyphs/L_tnS_mD_.glif53
-rw-r--r--tests/reference/ufo/psfglyphs2ufo/PsfTest-Regular.ufo/glyphs/L_tnS_mE_.glif45
-rw-r--r--tests/reference/ufo/psfglyphs2ufo/PsfTest-Regular.ufo/glyphs/L_tnS_mF_.glif39
-rw-r--r--tests/reference/ufo/psfglyphs2ufo/PsfTest-Regular.ufo/glyphs/L_tnS_mG_.glif91
-rw-r--r--tests/reference/ufo/psfglyphs2ufo/PsfTest-Regular.ufo/glyphs/L_tnS_mH_.glif43
-rw-r--r--tests/reference/ufo/psfglyphs2ufo/PsfTest-Regular.ufo/glyphs/L_tnS_mI_.glif40
-rw-r--r--tests/reference/ufo/psfglyphs2ufo/PsfTest-Regular.ufo/glyphs/L_tnS_mJ_.glif44
-rw-r--r--tests/reference/ufo/psfglyphs2ufo/PsfTest-Regular.ufo/glyphs/L_tnS_mK_.glif35
-rw-r--r--tests/reference/ufo/psfglyphs2ufo/PsfTest-Regular.ufo/glyphs/L_tnS_mL_.glif24
-rw-r--r--tests/reference/ufo/psfglyphs2ufo/PsfTest-Regular.ufo/glyphs/L_tnS_mM_.glif52
-rw-r--r--tests/reference/ufo/psfglyphs2ufo/PsfTest-Regular.ufo/glyphs/L_tnS_mN_.glif43
-rw-r--r--tests/reference/ufo/psfglyphs2ufo/PsfTest-Regular.ufo/glyphs/L_tnS_mO_.glif40
-rw-r--r--tests/reference/ufo/psfglyphs2ufo/PsfTest-Regular.ufo/glyphs/L_tnS_mP_.glif56
-rw-r--r--tests/reference/ufo/psfglyphs2ufo/PsfTest-Regular.ufo/glyphs/L_tnS_mQ_.glif47
-rw-r--r--tests/reference/ufo/psfglyphs2ufo/PsfTest-Regular.ufo/glyphs/L_tnS_mR_.glif36
-rw-r--r--tests/reference/ufo/psfglyphs2ufo/PsfTest-Regular.ufo/glyphs/L_tnS_mS_.glif50
-rw-r--r--tests/reference/ufo/psfglyphs2ufo/PsfTest-Regular.ufo/glyphs/L_tnS_mT_.glif39
-rw-r--r--tests/reference/ufo/psfglyphs2ufo/PsfTest-Regular.ufo/glyphs/L_tnS_mU_.glif51
-rw-r--r--tests/reference/ufo/psfglyphs2ufo/PsfTest-Regular.ufo/glyphs/L_tnS_mV_.glif30
-rw-r--r--tests/reference/ufo/psfglyphs2ufo/PsfTest-Regular.ufo/glyphs/L_tnS_mW_.glif30
-rw-r--r--tests/reference/ufo/psfglyphs2ufo/PsfTest-Regular.ufo/glyphs/L_tnS_mX_.glif40
-rw-r--r--tests/reference/ufo/psfglyphs2ufo/PsfTest-Regular.ufo/glyphs/L_tnS_mY_.glif42
-rw-r--r--tests/reference/ufo/psfglyphs2ufo/PsfTest-Regular.ufo/glyphs/N_onB_reakingH_yphen.glif9
-rw-r--r--tests/reference/ufo/psfglyphs2ufo/PsfTest-Regular.ufo/glyphs/N_umS_gn.glif31
-rw-r--r--tests/reference/ufo/psfglyphs2ufo/PsfTest-Regular.ufo/glyphs/P_ercentS_gn.glif69
-rw-r--r--tests/reference/ufo/psfglyphs2ufo/PsfTest-Regular.ufo/glyphs/P_lusS_gn.glif19
-rw-r--r--tests/reference/ufo/psfglyphs2ufo/PsfTest-Regular.ufo/glyphs/Q_stnM_rk.glif49
-rw-r--r--tests/reference/ufo/psfglyphs2ufo/PsfTest-Regular.ufo/glyphs/Q_uotM_rk.glif27
-rw-r--r--tests/reference/ufo/psfglyphs2ufo/PsfTest-Regular.ufo/glyphs/R_everseS_olidus.glif13
-rw-r--r--tests/reference/ufo/psfglyphs2ufo/PsfTest-Regular.ufo/glyphs/R_tC_urlyB_rac.glif47
-rw-r--r--tests/reference/ufo/psfglyphs2ufo/PsfTest-Regular.ufo/glyphs/R_tP_aren.glif23
-rw-r--r--tests/reference/ufo/psfglyphs2ufo/PsfTest-Regular.ufo/glyphs/R_tS_qrB_rac.glif17
-rw-r--r--tests/reference/ufo/psfglyphs2ufo/PsfTest-Regular.ufo/glyphs/S_emicolon.glif38
-rw-r--r--tests/reference/ufo/psfglyphs2ufo/PsfTest-Regular.ufo/glyphs/S_olidus.glif13
-rw-r--r--tests/reference/ufo/psfglyphs2ufo/PsfTest-Regular.ufo/glyphs/S_pace.glif6
-rw-r--r--tests/reference/ufo/psfglyphs2ufo/PsfTest-Regular.ufo/glyphs/T_ilde.glif29
-rw-r--r--tests/reference/ufo/psfglyphs2ufo/PsfTest-Regular.ufo/glyphs/V_ertL_ine.glif13
-rw-r--r--tests/reference/ufo/psfglyphs2ufo/PsfTest-Regular.ufo/glyphs/_notdef.glif18
-rw-r--r--tests/reference/ufo/psfglyphs2ufo/PsfTest-Regular.ufo/glyphs/_null.glif4
-rw-r--r--tests/reference/ufo/psfglyphs2ufo/PsfTest-Regular.ufo/glyphs/contents.plist234
-rw-r--r--tests/reference/ufo/psfglyphs2ufo/PsfTest-Regular.ufo/glyphs/nonmarkingreturn.glif5
-rw-r--r--tests/reference/ufo/psfglyphs2ufo/PsfTest-Regular.ufo/layercontents.plist10
-rw-r--r--tests/reference/ufo/psfglyphs2ufo/PsfTest-Regular.ufo/lib.plist417
-rw-r--r--tests/reference/ufo/psfglyphs2ufo/PsfTest-Regular.ufo/metainfo.plist10
-rw-r--r--tests/reference/ufo/psfmakefea.fea214
-rw-r--r--tests/reference/ufo/psfmakefea.lg2
-rw-r--r--tests/reference/ufo/psfmakewoffmetadata.lg13
-rw-r--r--tests/reference/ufo/psfmakewoffmetadata.xml82
-rw-r--r--tests/reference/ufo/psfnormalize.lg18
-rw-r--r--tests/reference/ufo/psfnormalize.ufo/fontinfo.plist240
-rw-r--r--tests/reference/ufo/psfnormalize.ufo/glyphs/A_mpersand.glif61
-rw-r--r--tests/reference/ufo/psfnormalize.ufo/glyphs/A_pos.glif17
-rw-r--r--tests/reference/ufo/psfnormalize.ufo/glyphs/A_sterisk.glif51
-rw-r--r--tests/reference/ufo/psfnormalize.ufo/glyphs/A_tS_gn.glif104
-rw-r--r--tests/reference/ufo/psfnormalize.ufo/glyphs/C_ircumA_ccent.glif17
-rw-r--r--tests/reference/ufo/psfnormalize.ufo/glyphs/C_olon.glif35
-rw-r--r--tests/reference/ufo/psfnormalize.ufo/glyphs/C_ombA_cute.glif14
-rw-r--r--tests/reference/ufo/psfnormalize.ufo/glyphs/C_ombC_ircum.glif17
-rw-r--r--tests/reference/ufo/psfnormalize.ufo/glyphs/C_ombD_iaer.glif36
-rw-r--r--tests/reference/ufo/psfnormalize.ufo/glyphs/C_ombG_rave.glif14
-rw-r--r--tests/reference/ufo/psfnormalize.ufo/glyphs/C_ombR_ingA_bv.glif36
-rw-r--r--tests/reference/ufo/psfnormalize.ufo/glyphs/C_ombT_ilde.glif36
-rw-r--r--tests/reference/ufo/psfnormalize.ufo/glyphs/C_omma.glif24
-rw-r--r--tests/reference/ufo/psfnormalize.ufo/glyphs/D_igitE_ight.glif63
-rw-r--r--tests/reference/ufo/psfnormalize.ufo/glyphs/D_igitF_ive.glif44
-rw-r--r--tests/reference/ufo/psfnormalize.ufo/glyphs/D_igitF_our.glif27
-rw-r--r--tests/reference/ufo/psfnormalize.ufo/glyphs/D_igitN_ine.glif49
-rw-r--r--tests/reference/ufo/psfnormalize.ufo/glyphs/D_igitO_ne.glif22
-rw-r--r--tests/reference/ufo/psfnormalize.ufo/glyphs/D_igitS_even.glif25
-rw-r--r--tests/reference/ufo/psfnormalize.ufo/glyphs/D_igitS_ix.glif49
-rw-r--r--tests/reference/ufo/psfnormalize.ufo/glyphs/D_igitT_hree.glif52
-rw-r--r--tests/reference/ufo/psfnormalize.ufo/glyphs/D_igitT_wo.glif37
-rw-r--r--tests/reference/ufo/psfnormalize.ufo/glyphs/D_igitZ_ero.glif49
-rw-r--r--tests/reference/ufo/psfnormalize.ufo/glyphs/D_ollarS_gn.glif53
-rw-r--r--tests/reference/ufo/psfnormalize.ufo/glyphs/D_ottedC_irc.glif235
-rw-r--r--tests/reference/ufo/psfnormalize.ufo/glyphs/E_qS_gn.glif19
-rw-r--r--tests/reference/ufo/psfnormalize.ufo/glyphs/E_xclamationM_rk.glif31
-rw-r--r--tests/reference/ufo/psfnormalize.ufo/glyphs/F_ullS_top.glif21
-rw-r--r--tests/reference/ufo/psfnormalize.ufo/glyphs/G_T_S_gn.glif16
-rw-r--r--tests/reference/ufo/psfnormalize.ufo/glyphs/G_raveA_ccent.glif14
-rw-r--r--tests/reference/ufo/psfnormalize.ufo/glyphs/H_yphen.glif14
-rw-r--r--tests/reference/ufo/psfnormalize.ufo/glyphs/H_yphenM_inus.glif14
-rw-r--r--tests/reference/ufo/psfnormalize.ufo/glyphs/H_yphen_S_oft.glif9
-rw-r--r--tests/reference/ufo/psfnormalize.ufo/glyphs/L_T_S_gn.glif16
-rw-r--r--tests/reference/ufo/psfnormalize.ufo/glyphs/L_ftC_urlyB_rac.glif50
-rw-r--r--tests/reference/ufo/psfnormalize.ufo/glyphs/L_ftP_aren.glif29
-rw-r--r--tests/reference/ufo/psfnormalize.ufo/glyphs/L_ftS_qrB_rac.glif17
-rw-r--r--tests/reference/ufo/psfnormalize.ufo/glyphs/L_owL_ine.glif13
-rw-r--r--tests/reference/ufo/psfnormalize.ufo/glyphs/L_tnC_apA_.glif32
-rw-r--r--tests/reference/ufo/psfnormalize.ufo/glyphs/L_tnC_apA_D_iaer.glif13
-rw-r--r--tests/reference/ufo/psfnormalize.ufo/glyphs/L_tnC_apB_.glif62
-rw-r--r--tests/reference/ufo/psfnormalize.ufo/glyphs/L_tnC_apC_.glif38
-rw-r--r--tests/reference/ufo/psfnormalize.ufo/glyphs/L_tnC_apD_.glif51
-rw-r--r--tests/reference/ufo/psfnormalize.ufo/glyphs/L_tnC_apE_.glif35
-rw-r--r--tests/reference/ufo/psfnormalize.ufo/glyphs/L_tnC_apF_.glif30
-rw-r--r--tests/reference/ufo/psfnormalize.ufo/glyphs/L_tnC_apG_.glif48
-rw-r--r--tests/reference/ufo/psfnormalize.ufo/glyphs/L_tnC_apH_.glif36
-rw-r--r--tests/reference/ufo/psfnormalize.ufo/glyphs/L_tnC_apI_.glif26
-rw-r--r--tests/reference/ufo/psfnormalize.ufo/glyphs/L_tnC_apJ_.glif30
-rw-r--r--tests/reference/ufo/psfnormalize.ufo/glyphs/L_tnC_apK_.glif35
-rw-r--r--tests/reference/ufo/psfnormalize.ufo/glyphs/L_tnC_apL_.glif28
-rw-r--r--tests/reference/ufo/psfnormalize.ufo/glyphs/L_tnC_apM_.glif36
-rw-r--r--tests/reference/ufo/psfnormalize.ufo/glyphs/L_tnC_apN_.glif37
-rw-r--r--tests/reference/ufo/psfnormalize.ufo/glyphs/L_tnC_apO_.glif40
-rw-r--r--tests/reference/ufo/psfnormalize.ufo/glyphs/L_tnC_apP_.glif50
-rw-r--r--tests/reference/ufo/psfnormalize.ufo/glyphs/L_tnC_apQ_.glif52
-rw-r--r--tests/reference/ufo/psfnormalize.ufo/glyphs/L_tnC_apR_.glif55
-rw-r--r--tests/reference/ufo/psfnormalize.ufo/glyphs/L_tnC_apS_.glif50
-rw-r--r--tests/reference/ufo/psfnormalize.ufo/glyphs/L_tnC_apT_.glif32
-rw-r--r--tests/reference/ufo/psfnormalize.ufo/glyphs/L_tnC_apU_.glif44
-rw-r--r--tests/reference/ufo/psfnormalize.ufo/glyphs/L_tnC_apV_.glif26
-rw-r--r--tests/reference/ufo/psfnormalize.ufo/glyphs/L_tnC_apW_.glif44
-rw-r--r--tests/reference/ufo/psfnormalize.ufo/glyphs/L_tnC_apX_.glif39
-rw-r--r--tests/reference/ufo/psfnormalize.ufo/glyphs/L_tnC_apY_.glif39
-rw-r--r--tests/reference/ufo/psfnormalize.ufo/glyphs/L_tnS_mA_.glif77
-rw-r--r--tests/reference/ufo/psfnormalize.ufo/glyphs/L_tnS_mA_A_cute.glif14
-rw-r--r--tests/reference/ufo/psfnormalize.ufo/glyphs/L_tnS_mA_C_ircum.glif14
-rw-r--r--tests/reference/ufo/psfnormalize.ufo/glyphs/L_tnS_mA_D_iaer.glif14
-rw-r--r--tests/reference/ufo/psfnormalize.ufo/glyphs/L_tnS_mA_G_rave.glif14
-rw-r--r--tests/reference/ufo/psfnormalize.ufo/glyphs/L_tnS_mA_R_ingA_bv.glif14
-rw-r--r--tests/reference/ufo/psfnormalize.ufo/glyphs/L_tnS_mA_T_ilde.glif14
-rw-r--r--tests/reference/ufo/psfnormalize.ufo/glyphs/L_tnS_mB_.glif55
-rw-r--r--tests/reference/ufo/psfnormalize.ufo/glyphs/L_tnS_mC_.glif39
-rw-r--r--tests/reference/ufo/psfnormalize.ufo/glyphs/L_tnS_mD_.glif65
-rw-r--r--tests/reference/ufo/psfnormalize.ufo/glyphs/L_tnS_mE_.glif52
-rw-r--r--tests/reference/ufo/psfnormalize.ufo/glyphs/L_tnS_mF_.glif44
-rw-r--r--tests/reference/ufo/psfnormalize.ufo/glyphs/L_tnS_mG_.glif100
-rw-r--r--tests/reference/ufo/psfnormalize.ufo/glyphs/L_tnS_mH_.glif54
-rw-r--r--tests/reference/ufo/psfnormalize.ufo/glyphs/L_tnS_mI_.glif50
-rw-r--r--tests/reference/ufo/psfnormalize.ufo/glyphs/L_tnS_mJ_.glif45
-rw-r--r--tests/reference/ufo/psfnormalize.ufo/glyphs/L_tnS_mK_.glif50
-rw-r--r--tests/reference/ufo/psfnormalize.ufo/glyphs/L_tnS_mL_.glif35
-rw-r--r--tests/reference/ufo/psfnormalize.ufo/glyphs/L_tnS_mM_.glif80
-rw-r--r--tests/reference/ufo/psfnormalize.ufo/glyphs/L_tnS_mN_.glif57
-rw-r--r--tests/reference/ufo/psfnormalize.ufo/glyphs/L_tnS_mO_.glif40
-rw-r--r--tests/reference/ufo/psfnormalize.ufo/glyphs/L_tnS_mP_.glif66
-rw-r--r--tests/reference/ufo/psfnormalize.ufo/glyphs/L_tnS_mQ_.glif54
-rw-r--r--tests/reference/ufo/psfnormalize.ufo/glyphs/L_tnS_mR_.glif42
-rw-r--r--tests/reference/ufo/psfnormalize.ufo/glyphs/L_tnS_mS_.glif50
-rw-r--r--tests/reference/ufo/psfnormalize.ufo/glyphs/L_tnS_mT_.glif45
-rw-r--r--tests/reference/ufo/psfnormalize.ufo/glyphs/L_tnS_mU_.glif57
-rw-r--r--tests/reference/ufo/psfnormalize.ufo/glyphs/L_tnS_mV_.glif34
-rw-r--r--tests/reference/ufo/psfnormalize.ufo/glyphs/L_tnS_mW_.glif50
-rw-r--r--tests/reference/ufo/psfnormalize.ufo/glyphs/L_tnS_mX_.glif40
-rw-r--r--tests/reference/ufo/psfnormalize.ufo/glyphs/L_tnS_mY_.glif45
-rw-r--r--tests/reference/ufo/psfnormalize.ufo/glyphs/N_onB_reakingH_yphen.glif9
-rw-r--r--tests/reference/ufo/psfnormalize.ufo/glyphs/N_umS_gn.glif31
-rw-r--r--tests/reference/ufo/psfnormalize.ufo/glyphs/P_ercentS_gn.glif93
-rw-r--r--tests/reference/ufo/psfnormalize.ufo/glyphs/P_lusS_gn.glif19
-rw-r--r--tests/reference/ufo/psfnormalize.ufo/glyphs/Q_stnM_rk.glif49
-rw-r--r--tests/reference/ufo/psfnormalize.ufo/glyphs/Q_uotM_rk.glif27
-rw-r--r--tests/reference/ufo/psfnormalize.ufo/glyphs/R_everseS_olidus.glif13
-rw-r--r--tests/reference/ufo/psfnormalize.ufo/glyphs/R_tC_urlyB_rac.glif50
-rw-r--r--tests/reference/ufo/psfnormalize.ufo/glyphs/R_tP_aren.glif29
-rw-r--r--tests/reference/ufo/psfnormalize.ufo/glyphs/R_tS_qrB_rac.glif17
-rw-r--r--tests/reference/ufo/psfnormalize.ufo/glyphs/S_emicolon.glif38
-rw-r--r--tests/reference/ufo/psfnormalize.ufo/glyphs/S_olidus.glif13
-rw-r--r--tests/reference/ufo/psfnormalize.ufo/glyphs/S_pace.glif6
-rw-r--r--tests/reference/ufo/psfnormalize.ufo/glyphs/T_ilde.glif29
-rw-r--r--tests/reference/ufo/psfnormalize.ufo/glyphs/V_ertL_ine.glif13
-rw-r--r--tests/reference/ufo/psfnormalize.ufo/glyphs/_notdef.glif18
-rw-r--r--tests/reference/ufo/psfnormalize.ufo/glyphs/_null.glif4
-rw-r--r--tests/reference/ufo/psfnormalize.ufo/glyphs/contents.plist232
-rw-r--r--tests/reference/ufo/psfnormalize.ufo/glyphs/nonmarkingreturn.glif5
-rw-r--r--tests/reference/ufo/psfnormalize.ufo/layercontents.plist10
-rw-r--r--tests/reference/ufo/psfnormalize.ufo/lib.plist534
-rw-r--r--tests/reference/ufo/psfnormalize.ufo/metainfo.plist10
-rw-r--r--tests/reference/ufo/psfrenameglyphs.lg34
-rw-r--r--tests/reference/ufo/psfrenameglyphs.ufo/fontinfo.plist244
-rw-r--r--tests/reference/ufo/psfrenameglyphs.ufo/glyphs/A_mpersand.glif61
-rw-r--r--tests/reference/ufo/psfrenameglyphs.ufo/glyphs/A_tS_gn.glif80
-rw-r--r--tests/reference/ufo/psfrenameglyphs.ufo/glyphs/B_pos.glif17
-rw-r--r--tests/reference/ufo/psfrenameglyphs.ufo/glyphs/C_ircumA_ccent.glif17
-rw-r--r--tests/reference/ufo/psfrenameglyphs.ufo/glyphs/C_olon.glif35
-rw-r--r--tests/reference/ufo/psfrenameglyphs.ufo/glyphs/C_ombA_cute.glif14
-rw-r--r--tests/reference/ufo/psfrenameglyphs.ufo/glyphs/C_ombC_ircum.glif17
-rw-r--r--tests/reference/ufo/psfrenameglyphs.ufo/glyphs/C_ombD_iaer.glif36
-rw-r--r--tests/reference/ufo/psfrenameglyphs.ufo/glyphs/C_ombG_rave.glif14
-rw-r--r--tests/reference/ufo/psfrenameglyphs.ufo/glyphs/C_ombR_ingA_bv.glif36
-rw-r--r--tests/reference/ufo/psfrenameglyphs.ufo/glyphs/C_ombT_ilde.glif36
-rw-r--r--tests/reference/ufo/psfrenameglyphs.ufo/glyphs/C_omma.glif24
-rw-r--r--tests/reference/ufo/psfrenameglyphs.ufo/glyphs/D_igitE_ight.glif63
-rw-r--r--tests/reference/ufo/psfrenameglyphs.ufo/glyphs/D_igitF_ive.glif44
-rw-r--r--tests/reference/ufo/psfrenameglyphs.ufo/glyphs/D_igitF_our.glif27
-rw-r--r--tests/reference/ufo/psfrenameglyphs.ufo/glyphs/D_igitN_ine.glif49
-rw-r--r--tests/reference/ufo/psfrenameglyphs.ufo/glyphs/D_igitO_ne.glif22
-rw-r--r--tests/reference/ufo/psfrenameglyphs.ufo/glyphs/D_igitS_even.glif25
-rw-r--r--tests/reference/ufo/psfrenameglyphs.ufo/glyphs/D_igitS_ix.glif49
-rw-r--r--tests/reference/ufo/psfrenameglyphs.ufo/glyphs/D_igitT_hree.glif52
-rw-r--r--tests/reference/ufo/psfrenameglyphs.ufo/glyphs/D_igitT_wo.glif37
-rw-r--r--tests/reference/ufo/psfrenameglyphs.ufo/glyphs/D_igitZ_ero.glif37
-rw-r--r--tests/reference/ufo/psfrenameglyphs.ufo/glyphs/D_ollarS_gn.glif57
-rw-r--r--tests/reference/ufo/psfrenameglyphs.ufo/glyphs/D_ottedC_irc.glif235
-rw-r--r--tests/reference/ufo/psfrenameglyphs.ufo/glyphs/E_qS_gn.glif19
-rw-r--r--tests/reference/ufo/psfrenameglyphs.ufo/glyphs/E_xclamationM_rk.glif31
-rw-r--r--tests/reference/ufo/psfrenameglyphs.ufo/glyphs/F_ullS_top.glif21
-rw-r--r--tests/reference/ufo/psfrenameglyphs.ufo/glyphs/G_T_S_gn.glif16
-rw-r--r--tests/reference/ufo/psfrenameglyphs.ufo/glyphs/G_raveA_ccent.glif14
-rw-r--r--tests/reference/ufo/psfrenameglyphs.ufo/glyphs/H_yphen.glif14
-rw-r--r--tests/reference/ufo/psfrenameglyphs.ufo/glyphs/H_yphenM_inus.glif14
-rw-r--r--tests/reference/ufo/psfrenameglyphs.ufo/glyphs/H_yphen_S_oft.glif9
-rw-r--r--tests/reference/ufo/psfrenameglyphs.ufo/glyphs/L_T_S_gn.glif16
-rw-r--r--tests/reference/ufo/psfrenameglyphs.ufo/glyphs/L_ftC_urlyB_rac.glif47
-rw-r--r--tests/reference/ufo/psfrenameglyphs.ufo/glyphs/L_ftP_aren.glif23
-rw-r--r--tests/reference/ufo/psfrenameglyphs.ufo/glyphs/L_ftS_qrB_rac.glif17
-rw-r--r--tests/reference/ufo/psfrenameglyphs.ufo/glyphs/L_owL_ine.glif13
-rw-r--r--tests/reference/ufo/psfrenameglyphs.ufo/glyphs/L_tnC_apA_.alt.glif31
-rw-r--r--tests/reference/ufo/psfrenameglyphs.ufo/glyphs/L_tnC_apA_.glif32
-rw-r--r--tests/reference/ufo/psfrenameglyphs.ufo/glyphs/L_tnC_apA_D_iaer.glif13
-rw-r--r--tests/reference/ufo/psfrenameglyphs.ufo/glyphs/L_tnC_apB_.glif62
-rw-r--r--tests/reference/ufo/psfrenameglyphs.ufo/glyphs/L_tnC_apC_.glif38
-rw-r--r--tests/reference/ufo/psfrenameglyphs.ufo/glyphs/L_tnC_apD_.glif45
-rw-r--r--tests/reference/ufo/psfrenameglyphs.ufo/glyphs/L_tnC_apE_.glif35
-rw-r--r--tests/reference/ufo/psfrenameglyphs.ufo/glyphs/L_tnC_apF_.glif30
-rw-r--r--tests/reference/ufo/psfrenameglyphs.ufo/glyphs/L_tnC_apG_.glif42
-rw-r--r--tests/reference/ufo/psfrenameglyphs.ufo/glyphs/L_tnC_apH_.glif40
-rw-r--r--tests/reference/ufo/psfrenameglyphs.ufo/glyphs/L_tnC_apI_.glif26
-rw-r--r--tests/reference/ufo/psfrenameglyphs.ufo/glyphs/L_tnC_apJ_.glif32
-rw-r--r--tests/reference/ufo/psfrenameglyphs.ufo/glyphs/L_tnC_apK_.glif34
-rw-r--r--tests/reference/ufo/psfrenameglyphs.ufo/glyphs/L_tnC_apL_.glif28
-rw-r--r--tests/reference/ufo/psfrenameglyphs.ufo/glyphs/L_tnC_apM_.glif38
-rw-r--r--tests/reference/ufo/psfrenameglyphs.ufo/glyphs/L_tnC_apN_.glif37
-rw-r--r--tests/reference/ufo/psfrenameglyphs.ufo/glyphs/L_tnC_apO_.glif40
-rw-r--r--tests/reference/ufo/psfrenameglyphs.ufo/glyphs/L_tnC_apP_.glif50
-rw-r--r--tests/reference/ufo/psfrenameglyphs.ufo/glyphs/L_tnC_apQ_.glif49
-rw-r--r--tests/reference/ufo/psfrenameglyphs.ufo/glyphs/L_tnC_apR_.glif55
-rw-r--r--tests/reference/ufo/psfrenameglyphs.ufo/glyphs/L_tnC_apS_.glif50
-rw-r--r--tests/reference/ufo/psfrenameglyphs.ufo/glyphs/L_tnC_apT_.glif32
-rw-r--r--tests/reference/ufo/psfrenameglyphs.ufo/glyphs/L_tnC_apU_.glif38
-rw-r--r--tests/reference/ufo/psfrenameglyphs.ufo/glyphs/L_tnC_apV_.glif26
-rw-r--r--tests/reference/ufo/psfrenameglyphs.ufo/glyphs/L_tnC_apW_.glif45
-rw-r--r--tests/reference/ufo/psfrenameglyphs.ufo/glyphs/L_tnC_apX_.glif39
-rw-r--r--tests/reference/ufo/psfrenameglyphs.ufo/glyphs/L_tnC_apY_.glif39
-rw-r--r--tests/reference/ufo/psfrenameglyphs.ufo/glyphs/L_tnS_mA_.glif76
-rw-r--r--tests/reference/ufo/psfrenameglyphs.ufo/glyphs/L_tnS_mA_A_cute.glif14
-rw-r--r--tests/reference/ufo/psfrenameglyphs.ufo/glyphs/L_tnS_mA_C_ircum.glif14
-rw-r--r--tests/reference/ufo/psfrenameglyphs.ufo/glyphs/L_tnS_mA_D_iaer.glif14
-rw-r--r--tests/reference/ufo/psfrenameglyphs.ufo/glyphs/L_tnS_mA_G_rave.glif14
-rw-r--r--tests/reference/ufo/psfrenameglyphs.ufo/glyphs/L_tnS_mA_R_ingA_bv.glif14
-rw-r--r--tests/reference/ufo/psfrenameglyphs.ufo/glyphs/L_tnS_mA_T_ilde.glif14
-rw-r--r--tests/reference/ufo/psfrenameglyphs.ufo/glyphs/L_tnS_mB_.glif50
-rw-r--r--tests/reference/ufo/psfrenameglyphs.ufo/glyphs/L_tnS_mC_.glif39
-rw-r--r--tests/reference/ufo/psfrenameglyphs.ufo/glyphs/L_tnS_mD_.glif53
-rw-r--r--tests/reference/ufo/psfrenameglyphs.ufo/glyphs/L_tnS_mE_.glif45
-rw-r--r--tests/reference/ufo/psfrenameglyphs.ufo/glyphs/L_tnS_mF_.glif39
-rw-r--r--tests/reference/ufo/psfrenameglyphs.ufo/glyphs/L_tnS_mG_.glif91
-rw-r--r--tests/reference/ufo/psfrenameglyphs.ufo/glyphs/L_tnS_mH_.glif43
-rw-r--r--tests/reference/ufo/psfrenameglyphs.ufo/glyphs/L_tnS_mI_.glif42
-rw-r--r--tests/reference/ufo/psfrenameglyphs.ufo/glyphs/L_tnS_mJ_.glif44
-rw-r--r--tests/reference/ufo/psfrenameglyphs.ufo/glyphs/L_tnS_mK_.glif34
-rw-r--r--tests/reference/ufo/psfrenameglyphs.ufo/glyphs/L_tnS_mL_.glif23
-rw-r--r--tests/reference/ufo/psfrenameglyphs.ufo/glyphs/L_tnS_mM_.glif52
-rw-r--r--tests/reference/ufo/psfrenameglyphs.ufo/glyphs/L_tnS_mN_.glif43
-rw-r--r--tests/reference/ufo/psfrenameglyphs.ufo/glyphs/L_tnS_mO_.glif40
-rw-r--r--tests/reference/ufo/psfrenameglyphs.ufo/glyphs/L_tnS_mP_.glif59
-rw-r--r--tests/reference/ufo/psfrenameglyphs.ufo/glyphs/L_tnS_mQ_.glif47
-rw-r--r--tests/reference/ufo/psfrenameglyphs.ufo/glyphs/L_tnS_mR_.glif35
-rw-r--r--tests/reference/ufo/psfrenameglyphs.ufo/glyphs/L_tnS_mS_.glif50
-rw-r--r--tests/reference/ufo/psfrenameglyphs.ufo/glyphs/L_tnS_mT_.glif35
-rw-r--r--tests/reference/ufo/psfrenameglyphs.ufo/glyphs/L_tnS_mU_.glif51
-rw-r--r--tests/reference/ufo/psfrenameglyphs.ufo/glyphs/L_tnS_mV_.glif30
-rw-r--r--tests/reference/ufo/psfrenameglyphs.ufo/glyphs/L_tnS_mW_.glif30
-rw-r--r--tests/reference/ufo/psfrenameglyphs.ufo/glyphs/L_tnS_mX_.glif40
-rw-r--r--tests/reference/ufo/psfrenameglyphs.ufo/glyphs/L_tnS_mY_.glif39
-rw-r--r--tests/reference/ufo/psfrenameglyphs.ufo/glyphs/N_onB_reakingH_yphen.glif9
-rw-r--r--tests/reference/ufo/psfrenameglyphs.ufo/glyphs/N_umS_gn.glif31
-rw-r--r--tests/reference/ufo/psfrenameglyphs.ufo/glyphs/P_ercentS_gn.glif69
-rw-r--r--tests/reference/ufo/psfrenameglyphs.ufo/glyphs/P_lusS_gn.glif19
-rw-r--r--tests/reference/ufo/psfrenameglyphs.ufo/glyphs/Q_stnM_rk.glif49
-rw-r--r--tests/reference/ufo/psfrenameglyphs.ufo/glyphs/Q_uotM_rk.glif27
-rw-r--r--tests/reference/ufo/psfrenameglyphs.ufo/glyphs/R_everseS_olidus.glif13
-rw-r--r--tests/reference/ufo/psfrenameglyphs.ufo/glyphs/R_tC_urlyB_rac.glif47
-rw-r--r--tests/reference/ufo/psfrenameglyphs.ufo/glyphs/R_tP_aren.glif23
-rw-r--r--tests/reference/ufo/psfrenameglyphs.ufo/glyphs/R_tS_qrB_rac.glif17
-rw-r--r--tests/reference/ufo/psfrenameglyphs.ufo/glyphs/S_emicolon.glif38
-rw-r--r--tests/reference/ufo/psfrenameglyphs.ufo/glyphs/S_olidus.glif13
-rw-r--r--tests/reference/ufo/psfrenameglyphs.ufo/glyphs/S_pace.glif6
-rw-r--r--tests/reference/ufo/psfrenameglyphs.ufo/glyphs/S_tar.glif51
-rw-r--r--tests/reference/ufo/psfrenameglyphs.ufo/glyphs/T_ilde.glif29
-rw-r--r--tests/reference/ufo/psfrenameglyphs.ufo/glyphs/V_ertL_ine.glif13
-rw-r--r--tests/reference/ufo/psfrenameglyphs.ufo/glyphs/_notdef.glif18
-rw-r--r--tests/reference/ufo/psfrenameglyphs.ufo/glyphs/_null.glif4
-rw-r--r--tests/reference/ufo/psfrenameglyphs.ufo/glyphs/contents.plist234
-rw-r--r--tests/reference/ufo/psfrenameglyphs.ufo/glyphs/nonmarkingreturn.glif5
-rw-r--r--tests/reference/ufo/psfrenameglyphs.ufo/layercontents.plist10
-rw-r--r--tests/reference/ufo/psfrenameglyphs.ufo/lib.plist531
-rw-r--r--tests/reference/ufo/psfrenameglyphs.ufo/metainfo.plist10
-rw-r--r--tests/reference/ufo/psfsetassocfeat.lg30
-rw-r--r--tests/reference/ufo/psfsetassocfeat.ufo/fontinfo.plist243
-rw-r--r--tests/reference/ufo/psfsetassocfeat.ufo/glyphs/A_mpersand.glif61
-rw-r--r--tests/reference/ufo/psfsetassocfeat.ufo/glyphs/A_pos.glif17
-rw-r--r--tests/reference/ufo/psfsetassocfeat.ufo/glyphs/A_sterisk.glif51
-rw-r--r--tests/reference/ufo/psfsetassocfeat.ufo/glyphs/A_tS_gn.glif104
-rw-r--r--tests/reference/ufo/psfsetassocfeat.ufo/glyphs/C_ircumA_ccent.glif17
-rw-r--r--tests/reference/ufo/psfsetassocfeat.ufo/glyphs/C_olon.glif35
-rw-r--r--tests/reference/ufo/psfsetassocfeat.ufo/glyphs/C_ombA_cute.glif14
-rw-r--r--tests/reference/ufo/psfsetassocfeat.ufo/glyphs/C_ombC_ircum.glif17
-rw-r--r--tests/reference/ufo/psfsetassocfeat.ufo/glyphs/C_ombD_iaer.glif36
-rw-r--r--tests/reference/ufo/psfsetassocfeat.ufo/glyphs/C_ombG_rave.glif14
-rw-r--r--tests/reference/ufo/psfsetassocfeat.ufo/glyphs/C_ombR_ingA_bv.glif36
-rw-r--r--tests/reference/ufo/psfsetassocfeat.ufo/glyphs/C_ombT_ilde.glif36
-rw-r--r--tests/reference/ufo/psfsetassocfeat.ufo/glyphs/C_omma.glif24
-rw-r--r--tests/reference/ufo/psfsetassocfeat.ufo/glyphs/D_igitE_ight.glif63
-rw-r--r--tests/reference/ufo/psfsetassocfeat.ufo/glyphs/D_igitF_ive.glif44
-rw-r--r--tests/reference/ufo/psfsetassocfeat.ufo/glyphs/D_igitF_our.glif27
-rw-r--r--tests/reference/ufo/psfsetassocfeat.ufo/glyphs/D_igitN_ine.glif49
-rw-r--r--tests/reference/ufo/psfsetassocfeat.ufo/glyphs/D_igitO_ne.glif22
-rw-r--r--tests/reference/ufo/psfsetassocfeat.ufo/glyphs/D_igitS_even.glif25
-rw-r--r--tests/reference/ufo/psfsetassocfeat.ufo/glyphs/D_igitS_ix.glif49
-rw-r--r--tests/reference/ufo/psfsetassocfeat.ufo/glyphs/D_igitT_hree.glif52
-rw-r--r--tests/reference/ufo/psfsetassocfeat.ufo/glyphs/D_igitT_wo.glif37
-rw-r--r--tests/reference/ufo/psfsetassocfeat.ufo/glyphs/D_igitZ_ero.glif49
-rw-r--r--tests/reference/ufo/psfsetassocfeat.ufo/glyphs/D_ollarS_gn.glif53
-rw-r--r--tests/reference/ufo/psfsetassocfeat.ufo/glyphs/D_ottedC_irc.glif235
-rw-r--r--tests/reference/ufo/psfsetassocfeat.ufo/glyphs/E_qS_gn.glif19
-rw-r--r--tests/reference/ufo/psfsetassocfeat.ufo/glyphs/E_xclamationM_rk.glif31
-rw-r--r--tests/reference/ufo/psfsetassocfeat.ufo/glyphs/F_ullS_top.glif21
-rw-r--r--tests/reference/ufo/psfsetassocfeat.ufo/glyphs/G_T_S_gn.glif16
-rw-r--r--tests/reference/ufo/psfsetassocfeat.ufo/glyphs/G_raveA_ccent.glif14
-rw-r--r--tests/reference/ufo/psfsetassocfeat.ufo/glyphs/H_yphen.glif14
-rw-r--r--tests/reference/ufo/psfsetassocfeat.ufo/glyphs/H_yphenM_inus.glif14
-rw-r--r--tests/reference/ufo/psfsetassocfeat.ufo/glyphs/H_yphen_S_oft.glif9
-rw-r--r--tests/reference/ufo/psfsetassocfeat.ufo/glyphs/L_T_S_gn.glif16
-rw-r--r--tests/reference/ufo/psfsetassocfeat.ufo/glyphs/L_ftC_urlyB_rac.glif50
-rw-r--r--tests/reference/ufo/psfsetassocfeat.ufo/glyphs/L_ftP_aren.glif29
-rw-r--r--tests/reference/ufo/psfsetassocfeat.ufo/glyphs/L_ftS_qrB_rac.glif17
-rw-r--r--tests/reference/ufo/psfsetassocfeat.ufo/glyphs/L_owL_ine.glif13
-rw-r--r--tests/reference/ufo/psfsetassocfeat.ufo/glyphs/L_tnC_apA_.glif38
-rw-r--r--tests/reference/ufo/psfsetassocfeat.ufo/glyphs/L_tnC_apA_D_iaer.glif13
-rw-r--r--tests/reference/ufo/psfsetassocfeat.ufo/glyphs/L_tnC_apB_.glif62
-rw-r--r--tests/reference/ufo/psfsetassocfeat.ufo/glyphs/L_tnC_apC_.glif38
-rw-r--r--tests/reference/ufo/psfsetassocfeat.ufo/glyphs/L_tnC_apD_.glif51
-rw-r--r--tests/reference/ufo/psfsetassocfeat.ufo/glyphs/L_tnC_apE_.glif35
-rw-r--r--tests/reference/ufo/psfsetassocfeat.ufo/glyphs/L_tnC_apF_.glif30
-rw-r--r--tests/reference/ufo/psfsetassocfeat.ufo/glyphs/L_tnC_apG_.glif48
-rw-r--r--tests/reference/ufo/psfsetassocfeat.ufo/glyphs/L_tnC_apH_.glif36
-rw-r--r--tests/reference/ufo/psfsetassocfeat.ufo/glyphs/L_tnC_apI_.glif26
-rw-r--r--tests/reference/ufo/psfsetassocfeat.ufo/glyphs/L_tnC_apJ_.glif30
-rw-r--r--tests/reference/ufo/psfsetassocfeat.ufo/glyphs/L_tnC_apK_.glif35
-rw-r--r--tests/reference/ufo/psfsetassocfeat.ufo/glyphs/L_tnC_apL_.glif28
-rw-r--r--tests/reference/ufo/psfsetassocfeat.ufo/glyphs/L_tnC_apM_.glif36
-rw-r--r--tests/reference/ufo/psfsetassocfeat.ufo/glyphs/L_tnC_apN_.glif37
-rw-r--r--tests/reference/ufo/psfsetassocfeat.ufo/glyphs/L_tnC_apO_.glif40
-rw-r--r--tests/reference/ufo/psfsetassocfeat.ufo/glyphs/L_tnC_apP_.glif50
-rw-r--r--tests/reference/ufo/psfsetassocfeat.ufo/glyphs/L_tnC_apQ_.glif52
-rw-r--r--tests/reference/ufo/psfsetassocfeat.ufo/glyphs/L_tnC_apR_.glif55
-rw-r--r--tests/reference/ufo/psfsetassocfeat.ufo/glyphs/L_tnC_apS_.glif50
-rw-r--r--tests/reference/ufo/psfsetassocfeat.ufo/glyphs/L_tnC_apT_.glif32
-rw-r--r--tests/reference/ufo/psfsetassocfeat.ufo/glyphs/L_tnC_apU_.glif50
-rw-r--r--tests/reference/ufo/psfsetassocfeat.ufo/glyphs/L_tnC_apV_.glif26
-rw-r--r--tests/reference/ufo/psfsetassocfeat.ufo/glyphs/L_tnC_apW_.glif44
-rw-r--r--tests/reference/ufo/psfsetassocfeat.ufo/glyphs/L_tnC_apX_.glif39
-rw-r--r--tests/reference/ufo/psfsetassocfeat.ufo/glyphs/L_tnC_apY_.glif39
-rw-r--r--tests/reference/ufo/psfsetassocfeat.ufo/glyphs/L_tnS_mA_.glif77
-rw-r--r--tests/reference/ufo/psfsetassocfeat.ufo/glyphs/L_tnS_mA_A_cute.glif14
-rw-r--r--tests/reference/ufo/psfsetassocfeat.ufo/glyphs/L_tnS_mA_C_ircum.glif14
-rw-r--r--tests/reference/ufo/psfsetassocfeat.ufo/glyphs/L_tnS_mA_D_iaer.glif14
-rw-r--r--tests/reference/ufo/psfsetassocfeat.ufo/glyphs/L_tnS_mA_G_rave.glif14
-rw-r--r--tests/reference/ufo/psfsetassocfeat.ufo/glyphs/L_tnS_mA_R_ingA_bv.glif14
-rw-r--r--tests/reference/ufo/psfsetassocfeat.ufo/glyphs/L_tnS_mA_T_ilde.glif14
-rw-r--r--tests/reference/ufo/psfsetassocfeat.ufo/glyphs/L_tnS_mB_.glif55
-rw-r--r--tests/reference/ufo/psfsetassocfeat.ufo/glyphs/L_tnS_mC_.glif39
-rw-r--r--tests/reference/ufo/psfsetassocfeat.ufo/glyphs/L_tnS_mD_.glif65
-rw-r--r--tests/reference/ufo/psfsetassocfeat.ufo/glyphs/L_tnS_mE_.glif52
-rw-r--r--tests/reference/ufo/psfsetassocfeat.ufo/glyphs/L_tnS_mF_.glif44
-rw-r--r--tests/reference/ufo/psfsetassocfeat.ufo/glyphs/L_tnS_mG_.glif100
-rw-r--r--tests/reference/ufo/psfsetassocfeat.ufo/glyphs/L_tnS_mH_.glif54
-rw-r--r--tests/reference/ufo/psfsetassocfeat.ufo/glyphs/L_tnS_mI_.glif50
-rw-r--r--tests/reference/ufo/psfsetassocfeat.ufo/glyphs/L_tnS_mJ_.glif45
-rw-r--r--tests/reference/ufo/psfsetassocfeat.ufo/glyphs/L_tnS_mK_.glif50
-rw-r--r--tests/reference/ufo/psfsetassocfeat.ufo/glyphs/L_tnS_mL_.glif35
-rw-r--r--tests/reference/ufo/psfsetassocfeat.ufo/glyphs/L_tnS_mM_.glif80
-rw-r--r--tests/reference/ufo/psfsetassocfeat.ufo/glyphs/L_tnS_mN_.glif57
-rw-r--r--tests/reference/ufo/psfsetassocfeat.ufo/glyphs/L_tnS_mO_.glif40
-rw-r--r--tests/reference/ufo/psfsetassocfeat.ufo/glyphs/L_tnS_mP_.glif66
-rw-r--r--tests/reference/ufo/psfsetassocfeat.ufo/glyphs/L_tnS_mQ_.glif54
-rw-r--r--tests/reference/ufo/psfsetassocfeat.ufo/glyphs/L_tnS_mR_.glif42
-rw-r--r--tests/reference/ufo/psfsetassocfeat.ufo/glyphs/L_tnS_mS_.glif50
-rw-r--r--tests/reference/ufo/psfsetassocfeat.ufo/glyphs/L_tnS_mT_.glif45
-rw-r--r--tests/reference/ufo/psfsetassocfeat.ufo/glyphs/L_tnS_mU_.glif57
-rw-r--r--tests/reference/ufo/psfsetassocfeat.ufo/glyphs/L_tnS_mV_.glif34
-rw-r--r--tests/reference/ufo/psfsetassocfeat.ufo/glyphs/L_tnS_mW_.glif50
-rw-r--r--tests/reference/ufo/psfsetassocfeat.ufo/glyphs/L_tnS_mX_.glif40
-rw-r--r--tests/reference/ufo/psfsetassocfeat.ufo/glyphs/L_tnS_mY_.glif45
-rw-r--r--tests/reference/ufo/psfsetassocfeat.ufo/glyphs/N_onB_reakingH_yphen.glif9
-rw-r--r--tests/reference/ufo/psfsetassocfeat.ufo/glyphs/N_umS_gn.glif31
-rw-r--r--tests/reference/ufo/psfsetassocfeat.ufo/glyphs/P_ercentS_gn.glif93
-rw-r--r--tests/reference/ufo/psfsetassocfeat.ufo/glyphs/P_lusS_gn.glif19
-rw-r--r--tests/reference/ufo/psfsetassocfeat.ufo/glyphs/Q_stnM_rk.glif49
-rw-r--r--tests/reference/ufo/psfsetassocfeat.ufo/glyphs/Q_uotM_rk.glif27
-rw-r--r--tests/reference/ufo/psfsetassocfeat.ufo/glyphs/R_everseS_olidus.glif13
-rw-r--r--tests/reference/ufo/psfsetassocfeat.ufo/glyphs/R_tC_urlyB_rac.glif50
-rw-r--r--tests/reference/ufo/psfsetassocfeat.ufo/glyphs/R_tP_aren.glif29
-rw-r--r--tests/reference/ufo/psfsetassocfeat.ufo/glyphs/R_tS_qrB_rac.glif17
-rw-r--r--tests/reference/ufo/psfsetassocfeat.ufo/glyphs/S_emicolon.glif38
-rw-r--r--tests/reference/ufo/psfsetassocfeat.ufo/glyphs/S_olidus.glif13
-rw-r--r--tests/reference/ufo/psfsetassocfeat.ufo/glyphs/S_pace.glif6
-rw-r--r--tests/reference/ufo/psfsetassocfeat.ufo/glyphs/T_ilde.glif29
-rw-r--r--tests/reference/ufo/psfsetassocfeat.ufo/glyphs/V_ertL_ine.glif13
-rw-r--r--tests/reference/ufo/psfsetassocfeat.ufo/glyphs/_notdef.glif18
-rw-r--r--tests/reference/ufo/psfsetassocfeat.ufo/glyphs/_null.glif4
-rw-r--r--tests/reference/ufo/psfsetassocfeat.ufo/glyphs/contents.plist232
-rw-r--r--tests/reference/ufo/psfsetassocfeat.ufo/glyphs/nonmarkingreturn.glif5
-rw-r--r--tests/reference/ufo/psfsetassocfeat.ufo/layercontents.plist10
-rw-r--r--tests/reference/ufo/psfsetassocfeat.ufo/lib.plist538
-rw-r--r--tests/reference/ufo/psfsetassocfeat.ufo/metainfo.plist10
-rw-r--r--tests/reference/ufo/psfsetassocuids.lg22
-rw-r--r--tests/reference/ufo/psfsetassocuids.ufo/fontinfo.plist245
-rw-r--r--tests/reference/ufo/psfsetassocuids.ufo/glyphs/A_mpersand.glif61
-rw-r--r--tests/reference/ufo/psfsetassocuids.ufo/glyphs/A_pos.glif17
-rw-r--r--tests/reference/ufo/psfsetassocuids.ufo/glyphs/A_sterisk.glif51
-rw-r--r--tests/reference/ufo/psfsetassocuids.ufo/glyphs/A_tS_gn.glif80
-rw-r--r--tests/reference/ufo/psfsetassocuids.ufo/glyphs/C_ircumA_ccent.glif25
-rw-r--r--tests/reference/ufo/psfsetassocuids.ufo/glyphs/C_olon.glif35
-rw-r--r--tests/reference/ufo/psfsetassocuids.ufo/glyphs/C_ombA_cute.glif14
-rw-r--r--tests/reference/ufo/psfsetassocuids.ufo/glyphs/C_ombC_ircum.glif17
-rw-r--r--tests/reference/ufo/psfsetassocuids.ufo/glyphs/C_ombD_iaer.glif36
-rw-r--r--tests/reference/ufo/psfsetassocuids.ufo/glyphs/C_ombG_rave.glif14
-rw-r--r--tests/reference/ufo/psfsetassocuids.ufo/glyphs/C_ombR_ingA_bv.glif36
-rw-r--r--tests/reference/ufo/psfsetassocuids.ufo/glyphs/C_ombT_ilde.glif36
-rw-r--r--tests/reference/ufo/psfsetassocuids.ufo/glyphs/C_omma.glif24
-rw-r--r--tests/reference/ufo/psfsetassocuids.ufo/glyphs/D_igitE_ight.glif63
-rw-r--r--tests/reference/ufo/psfsetassocuids.ufo/glyphs/D_igitF_ive.glif44
-rw-r--r--tests/reference/ufo/psfsetassocuids.ufo/glyphs/D_igitF_our.glif27
-rw-r--r--tests/reference/ufo/psfsetassocuids.ufo/glyphs/D_igitN_ine.glif49
-rw-r--r--tests/reference/ufo/psfsetassocuids.ufo/glyphs/D_igitO_ne.glif22
-rw-r--r--tests/reference/ufo/psfsetassocuids.ufo/glyphs/D_igitS_even.glif25
-rw-r--r--tests/reference/ufo/psfsetassocuids.ufo/glyphs/D_igitS_ix.glif49
-rw-r--r--tests/reference/ufo/psfsetassocuids.ufo/glyphs/D_igitT_hree.glif52
-rw-r--r--tests/reference/ufo/psfsetassocuids.ufo/glyphs/D_igitT_wo.glif37
-rw-r--r--tests/reference/ufo/psfsetassocuids.ufo/glyphs/D_igitZ_ero.glif37
-rw-r--r--tests/reference/ufo/psfsetassocuids.ufo/glyphs/D_ollarS_gn.glif57
-rw-r--r--tests/reference/ufo/psfsetassocuids.ufo/glyphs/D_ottedC_irc.glif235
-rw-r--r--tests/reference/ufo/psfsetassocuids.ufo/glyphs/E_qS_gn.glif19
-rw-r--r--tests/reference/ufo/psfsetassocuids.ufo/glyphs/E_xclamationM_rk.glif31
-rw-r--r--tests/reference/ufo/psfsetassocuids.ufo/glyphs/F_ullS_top.glif21
-rw-r--r--tests/reference/ufo/psfsetassocuids.ufo/glyphs/G_T_S_gn.glif16
-rw-r--r--tests/reference/ufo/psfsetassocuids.ufo/glyphs/G_raveA_ccent.glif14
-rw-r--r--tests/reference/ufo/psfsetassocuids.ufo/glyphs/H_yphen.glif14
-rw-r--r--tests/reference/ufo/psfsetassocuids.ufo/glyphs/H_yphenM_inus.glif14
-rw-r--r--tests/reference/ufo/psfsetassocuids.ufo/glyphs/H_yphen_S_oft.glif9
-rw-r--r--tests/reference/ufo/psfsetassocuids.ufo/glyphs/L_T_S_gn.glif16
-rw-r--r--tests/reference/ufo/psfsetassocuids.ufo/glyphs/L_ftC_urlyB_rac.glif47
-rw-r--r--tests/reference/ufo/psfsetassocuids.ufo/glyphs/L_ftP_aren.glif23
-rw-r--r--tests/reference/ufo/psfsetassocuids.ufo/glyphs/L_ftS_qrB_rac.glif17
-rw-r--r--tests/reference/ufo/psfsetassocuids.ufo/glyphs/L_owL_ine.glif13
-rw-r--r--tests/reference/ufo/psfsetassocuids.ufo/glyphs/L_tnC_apA_.alt.glif31
-rw-r--r--tests/reference/ufo/psfsetassocuids.ufo/glyphs/L_tnC_apA_.glif32
-rw-r--r--tests/reference/ufo/psfsetassocuids.ufo/glyphs/L_tnC_apA_D_iaer.glif13
-rw-r--r--tests/reference/ufo/psfsetassocuids.ufo/glyphs/L_tnC_apB_.glif62
-rw-r--r--tests/reference/ufo/psfsetassocuids.ufo/glyphs/L_tnC_apC_.glif38
-rw-r--r--tests/reference/ufo/psfsetassocuids.ufo/glyphs/L_tnC_apD_.glif45
-rw-r--r--tests/reference/ufo/psfsetassocuids.ufo/glyphs/L_tnC_apE_.glif35
-rw-r--r--tests/reference/ufo/psfsetassocuids.ufo/glyphs/L_tnC_apF_.glif30
-rw-r--r--tests/reference/ufo/psfsetassocuids.ufo/glyphs/L_tnC_apG_.glif42
-rw-r--r--tests/reference/ufo/psfsetassocuids.ufo/glyphs/L_tnC_apH_.glif40
-rw-r--r--tests/reference/ufo/psfsetassocuids.ufo/glyphs/L_tnC_apI_.glif26
-rw-r--r--tests/reference/ufo/psfsetassocuids.ufo/glyphs/L_tnC_apJ_.glif32
-rw-r--r--tests/reference/ufo/psfsetassocuids.ufo/glyphs/L_tnC_apK_.glif34
-rw-r--r--tests/reference/ufo/psfsetassocuids.ufo/glyphs/L_tnC_apL_.glif28
-rw-r--r--tests/reference/ufo/psfsetassocuids.ufo/glyphs/L_tnC_apM_.glif38
-rw-r--r--tests/reference/ufo/psfsetassocuids.ufo/glyphs/L_tnC_apN_.glif37
-rw-r--r--tests/reference/ufo/psfsetassocuids.ufo/glyphs/L_tnC_apO_.glif40
-rw-r--r--tests/reference/ufo/psfsetassocuids.ufo/glyphs/L_tnC_apP_.glif50
-rw-r--r--tests/reference/ufo/psfsetassocuids.ufo/glyphs/L_tnC_apQ_.glif49
-rw-r--r--tests/reference/ufo/psfsetassocuids.ufo/glyphs/L_tnC_apR_.glif55
-rw-r--r--tests/reference/ufo/psfsetassocuids.ufo/glyphs/L_tnC_apS_.glif50
-rw-r--r--tests/reference/ufo/psfsetassocuids.ufo/glyphs/L_tnC_apT_.glif32
-rw-r--r--tests/reference/ufo/psfsetassocuids.ufo/glyphs/L_tnC_apU_.glif46
-rw-r--r--tests/reference/ufo/psfsetassocuids.ufo/glyphs/L_tnC_apV_.glif26
-rw-r--r--tests/reference/ufo/psfsetassocuids.ufo/glyphs/L_tnC_apW_.glif45
-rw-r--r--tests/reference/ufo/psfsetassocuids.ufo/glyphs/L_tnC_apX_.glif39
-rw-r--r--tests/reference/ufo/psfsetassocuids.ufo/glyphs/L_tnC_apY_.glif39
-rw-r--r--tests/reference/ufo/psfsetassocuids.ufo/glyphs/L_tnS_mA_.glif76
-rw-r--r--tests/reference/ufo/psfsetassocuids.ufo/glyphs/L_tnS_mA_A_cute.glif14
-rw-r--r--tests/reference/ufo/psfsetassocuids.ufo/glyphs/L_tnS_mA_C_ircum.glif14
-rw-r--r--tests/reference/ufo/psfsetassocuids.ufo/glyphs/L_tnS_mA_D_iaer.glif14
-rw-r--r--tests/reference/ufo/psfsetassocuids.ufo/glyphs/L_tnS_mA_G_rave.glif14
-rw-r--r--tests/reference/ufo/psfsetassocuids.ufo/glyphs/L_tnS_mA_R_ingA_bv.glif14
-rw-r--r--tests/reference/ufo/psfsetassocuids.ufo/glyphs/L_tnS_mA_T_ilde.glif14
-rw-r--r--tests/reference/ufo/psfsetassocuids.ufo/glyphs/L_tnS_mB_.glif50
-rw-r--r--tests/reference/ufo/psfsetassocuids.ufo/glyphs/L_tnS_mC_.glif39
-rw-r--r--tests/reference/ufo/psfsetassocuids.ufo/glyphs/L_tnS_mD_.glif53
-rw-r--r--tests/reference/ufo/psfsetassocuids.ufo/glyphs/L_tnS_mE_.glif45
-rw-r--r--tests/reference/ufo/psfsetassocuids.ufo/glyphs/L_tnS_mF_.glif39
-rw-r--r--tests/reference/ufo/psfsetassocuids.ufo/glyphs/L_tnS_mG_.glif91
-rw-r--r--tests/reference/ufo/psfsetassocuids.ufo/glyphs/L_tnS_mH_.glif43
-rw-r--r--tests/reference/ufo/psfsetassocuids.ufo/glyphs/L_tnS_mI_.glif42
-rw-r--r--tests/reference/ufo/psfsetassocuids.ufo/glyphs/L_tnS_mJ_.glif44
-rw-r--r--tests/reference/ufo/psfsetassocuids.ufo/glyphs/L_tnS_mK_.glif34
-rw-r--r--tests/reference/ufo/psfsetassocuids.ufo/glyphs/L_tnS_mL_.glif23
-rw-r--r--tests/reference/ufo/psfsetassocuids.ufo/glyphs/L_tnS_mM_.glif52
-rw-r--r--tests/reference/ufo/psfsetassocuids.ufo/glyphs/L_tnS_mN_.glif43
-rw-r--r--tests/reference/ufo/psfsetassocuids.ufo/glyphs/L_tnS_mO_.glif40
-rw-r--r--tests/reference/ufo/psfsetassocuids.ufo/glyphs/L_tnS_mP_.glif59
-rw-r--r--tests/reference/ufo/psfsetassocuids.ufo/glyphs/L_tnS_mQ_.glif47
-rw-r--r--tests/reference/ufo/psfsetassocuids.ufo/glyphs/L_tnS_mR_.glif35
-rw-r--r--tests/reference/ufo/psfsetassocuids.ufo/glyphs/L_tnS_mS_.glif50
-rw-r--r--tests/reference/ufo/psfsetassocuids.ufo/glyphs/L_tnS_mT_.glif35
-rw-r--r--tests/reference/ufo/psfsetassocuids.ufo/glyphs/L_tnS_mU_.glif51
-rw-r--r--tests/reference/ufo/psfsetassocuids.ufo/glyphs/L_tnS_mV_.glif30
-rw-r--r--tests/reference/ufo/psfsetassocuids.ufo/glyphs/L_tnS_mW_.glif30
-rw-r--r--tests/reference/ufo/psfsetassocuids.ufo/glyphs/L_tnS_mX_.glif40
-rw-r--r--tests/reference/ufo/psfsetassocuids.ufo/glyphs/L_tnS_mY_.glif39
-rw-r--r--tests/reference/ufo/psfsetassocuids.ufo/glyphs/N_onB_reakingH_yphen.glif9
-rw-r--r--tests/reference/ufo/psfsetassocuids.ufo/glyphs/N_umS_gn.glif31
-rw-r--r--tests/reference/ufo/psfsetassocuids.ufo/glyphs/P_ercentS_gn.glif69
-rw-r--r--tests/reference/ufo/psfsetassocuids.ufo/glyphs/P_lusS_gn.glif19
-rw-r--r--tests/reference/ufo/psfsetassocuids.ufo/glyphs/Q_stnM_rk.glif49
-rw-r--r--tests/reference/ufo/psfsetassocuids.ufo/glyphs/Q_uotM_rk.glif27
-rw-r--r--tests/reference/ufo/psfsetassocuids.ufo/glyphs/R_everseS_olidus.glif13
-rw-r--r--tests/reference/ufo/psfsetassocuids.ufo/glyphs/R_tC_urlyB_rac.glif47
-rw-r--r--tests/reference/ufo/psfsetassocuids.ufo/glyphs/R_tP_aren.glif23
-rw-r--r--tests/reference/ufo/psfsetassocuids.ufo/glyphs/R_tS_qrB_rac.glif17
-rw-r--r--tests/reference/ufo/psfsetassocuids.ufo/glyphs/S_emicolon.glif38
-rw-r--r--tests/reference/ufo/psfsetassocuids.ufo/glyphs/S_olidus.glif13
-rw-r--r--tests/reference/ufo/psfsetassocuids.ufo/glyphs/S_pace.glif6
-rw-r--r--tests/reference/ufo/psfsetassocuids.ufo/glyphs/T_ilde.glif29
-rw-r--r--tests/reference/ufo/psfsetassocuids.ufo/glyphs/V_ertL_ine.glif13
-rw-r--r--tests/reference/ufo/psfsetassocuids.ufo/glyphs/_notdef.glif18
-rw-r--r--tests/reference/ufo/psfsetassocuids.ufo/glyphs/_null.glif4
-rw-r--r--tests/reference/ufo/psfsetassocuids.ufo/glyphs/contents.plist234
-rw-r--r--tests/reference/ufo/psfsetassocuids.ufo/glyphs/nonmarkingreturn.glif5
-rw-r--r--tests/reference/ufo/psfsetassocuids.ufo/layercontents.plist10
-rw-r--r--tests/reference/ufo/psfsetassocuids.ufo/lib.plist535
-rw-r--r--tests/reference/ufo/psfsetassocuids.ufo/metainfo.plist10
-rw-r--r--tests/reference/ufo/psfsetglyphorder.lg158
-rw-r--r--tests/reference/ufo/psfsetglyphorder.ufo/fontinfo.plist243
-rw-r--r--tests/reference/ufo/psfsetglyphorder.ufo/glyphs/A_mpersand.glif61
-rw-r--r--tests/reference/ufo/psfsetglyphorder.ufo/glyphs/A_pos.glif17
-rw-r--r--tests/reference/ufo/psfsetglyphorder.ufo/glyphs/A_sterisk.glif51
-rw-r--r--tests/reference/ufo/psfsetglyphorder.ufo/glyphs/A_tS_gn.glif104
-rw-r--r--tests/reference/ufo/psfsetglyphorder.ufo/glyphs/C_ircumA_ccent.glif17
-rw-r--r--tests/reference/ufo/psfsetglyphorder.ufo/glyphs/C_olon.glif35
-rw-r--r--tests/reference/ufo/psfsetglyphorder.ufo/glyphs/C_ombA_cute.glif14
-rw-r--r--tests/reference/ufo/psfsetglyphorder.ufo/glyphs/C_ombC_ircum.glif17
-rw-r--r--tests/reference/ufo/psfsetglyphorder.ufo/glyphs/C_ombD_iaer.glif36
-rw-r--r--tests/reference/ufo/psfsetglyphorder.ufo/glyphs/C_ombG_rave.glif14
-rw-r--r--tests/reference/ufo/psfsetglyphorder.ufo/glyphs/C_ombR_ingA_bv.glif36
-rw-r--r--tests/reference/ufo/psfsetglyphorder.ufo/glyphs/C_ombT_ilde.glif36
-rw-r--r--tests/reference/ufo/psfsetglyphorder.ufo/glyphs/C_omma.glif24
-rw-r--r--tests/reference/ufo/psfsetglyphorder.ufo/glyphs/D_igitE_ight.glif63
-rw-r--r--tests/reference/ufo/psfsetglyphorder.ufo/glyphs/D_igitF_ive.glif44
-rw-r--r--tests/reference/ufo/psfsetglyphorder.ufo/glyphs/D_igitF_our.glif27
-rw-r--r--tests/reference/ufo/psfsetglyphorder.ufo/glyphs/D_igitN_ine.glif49
-rw-r--r--tests/reference/ufo/psfsetglyphorder.ufo/glyphs/D_igitO_ne.glif22
-rw-r--r--tests/reference/ufo/psfsetglyphorder.ufo/glyphs/D_igitS_even.glif25
-rw-r--r--tests/reference/ufo/psfsetglyphorder.ufo/glyphs/D_igitS_ix.glif49
-rw-r--r--tests/reference/ufo/psfsetglyphorder.ufo/glyphs/D_igitT_hree.glif52
-rw-r--r--tests/reference/ufo/psfsetglyphorder.ufo/glyphs/D_igitT_wo.glif37
-rw-r--r--tests/reference/ufo/psfsetglyphorder.ufo/glyphs/D_igitZ_ero.glif49
-rw-r--r--tests/reference/ufo/psfsetglyphorder.ufo/glyphs/D_ollarS_gn.glif53
-rw-r--r--tests/reference/ufo/psfsetglyphorder.ufo/glyphs/D_ottedC_irc.glif235
-rw-r--r--tests/reference/ufo/psfsetglyphorder.ufo/glyphs/E_qS_gn.glif19
-rw-r--r--tests/reference/ufo/psfsetglyphorder.ufo/glyphs/E_xclamationM_rk.glif31
-rw-r--r--tests/reference/ufo/psfsetglyphorder.ufo/glyphs/F_ullS_top.glif21
-rw-r--r--tests/reference/ufo/psfsetglyphorder.ufo/glyphs/G_T_S_gn.glif16
-rw-r--r--tests/reference/ufo/psfsetglyphorder.ufo/glyphs/G_raveA_ccent.glif14
-rw-r--r--tests/reference/ufo/psfsetglyphorder.ufo/glyphs/H_yphen.glif14
-rw-r--r--tests/reference/ufo/psfsetglyphorder.ufo/glyphs/H_yphenM_inus.glif14
-rw-r--r--tests/reference/ufo/psfsetglyphorder.ufo/glyphs/H_yphen_S_oft.glif9
-rw-r--r--tests/reference/ufo/psfsetglyphorder.ufo/glyphs/L_T_S_gn.glif16
-rw-r--r--tests/reference/ufo/psfsetglyphorder.ufo/glyphs/L_ftC_urlyB_rac.glif50
-rw-r--r--tests/reference/ufo/psfsetglyphorder.ufo/glyphs/L_ftP_aren.glif29
-rw-r--r--tests/reference/ufo/psfsetglyphorder.ufo/glyphs/L_ftS_qrB_rac.glif17
-rw-r--r--tests/reference/ufo/psfsetglyphorder.ufo/glyphs/L_owL_ine.glif13
-rw-r--r--tests/reference/ufo/psfsetglyphorder.ufo/glyphs/L_tnC_apA_.glif32
-rw-r--r--tests/reference/ufo/psfsetglyphorder.ufo/glyphs/L_tnC_apA_D_iaer.glif13
-rw-r--r--tests/reference/ufo/psfsetglyphorder.ufo/glyphs/L_tnC_apB_.glif62
-rw-r--r--tests/reference/ufo/psfsetglyphorder.ufo/glyphs/L_tnC_apC_.glif38
-rw-r--r--tests/reference/ufo/psfsetglyphorder.ufo/glyphs/L_tnC_apD_.glif51
-rw-r--r--tests/reference/ufo/psfsetglyphorder.ufo/glyphs/L_tnC_apE_.glif35
-rw-r--r--tests/reference/ufo/psfsetglyphorder.ufo/glyphs/L_tnC_apF_.glif30
-rw-r--r--tests/reference/ufo/psfsetglyphorder.ufo/glyphs/L_tnC_apG_.glif48
-rw-r--r--tests/reference/ufo/psfsetglyphorder.ufo/glyphs/L_tnC_apH_.glif36
-rw-r--r--tests/reference/ufo/psfsetglyphorder.ufo/glyphs/L_tnC_apI_.glif26
-rw-r--r--tests/reference/ufo/psfsetglyphorder.ufo/glyphs/L_tnC_apJ_.glif30
-rw-r--r--tests/reference/ufo/psfsetglyphorder.ufo/glyphs/L_tnC_apK_.glif35
-rw-r--r--tests/reference/ufo/psfsetglyphorder.ufo/glyphs/L_tnC_apL_.glif28
-rw-r--r--tests/reference/ufo/psfsetglyphorder.ufo/glyphs/L_tnC_apM_.glif36
-rw-r--r--tests/reference/ufo/psfsetglyphorder.ufo/glyphs/L_tnC_apN_.glif37
-rw-r--r--tests/reference/ufo/psfsetglyphorder.ufo/glyphs/L_tnC_apO_.glif40
-rw-r--r--tests/reference/ufo/psfsetglyphorder.ufo/glyphs/L_tnC_apP_.glif50
-rw-r--r--tests/reference/ufo/psfsetglyphorder.ufo/glyphs/L_tnC_apQ_.glif52
-rw-r--r--tests/reference/ufo/psfsetglyphorder.ufo/glyphs/L_tnC_apR_.glif55
-rw-r--r--tests/reference/ufo/psfsetglyphorder.ufo/glyphs/L_tnC_apS_.glif50
-rw-r--r--tests/reference/ufo/psfsetglyphorder.ufo/glyphs/L_tnC_apT_.glif32
-rw-r--r--tests/reference/ufo/psfsetglyphorder.ufo/glyphs/L_tnC_apU_.glif44
-rw-r--r--tests/reference/ufo/psfsetglyphorder.ufo/glyphs/L_tnC_apV_.glif26
-rw-r--r--tests/reference/ufo/psfsetglyphorder.ufo/glyphs/L_tnC_apW_.glif44
-rw-r--r--tests/reference/ufo/psfsetglyphorder.ufo/glyphs/L_tnC_apX_.glif39
-rw-r--r--tests/reference/ufo/psfsetglyphorder.ufo/glyphs/L_tnC_apY_.glif39
-rw-r--r--tests/reference/ufo/psfsetglyphorder.ufo/glyphs/L_tnS_mA_.glif77
-rw-r--r--tests/reference/ufo/psfsetglyphorder.ufo/glyphs/L_tnS_mA_A_cute.glif14
-rw-r--r--tests/reference/ufo/psfsetglyphorder.ufo/glyphs/L_tnS_mA_C_ircum.glif14
-rw-r--r--tests/reference/ufo/psfsetglyphorder.ufo/glyphs/L_tnS_mA_D_iaer.glif14
-rw-r--r--tests/reference/ufo/psfsetglyphorder.ufo/glyphs/L_tnS_mA_G_rave.glif14
-rw-r--r--tests/reference/ufo/psfsetglyphorder.ufo/glyphs/L_tnS_mA_R_ingA_bv.glif14
-rw-r--r--tests/reference/ufo/psfsetglyphorder.ufo/glyphs/L_tnS_mA_T_ilde.glif14
-rw-r--r--tests/reference/ufo/psfsetglyphorder.ufo/glyphs/L_tnS_mB_.glif55
-rw-r--r--tests/reference/ufo/psfsetglyphorder.ufo/glyphs/L_tnS_mC_.glif39
-rw-r--r--tests/reference/ufo/psfsetglyphorder.ufo/glyphs/L_tnS_mD_.glif65
-rw-r--r--tests/reference/ufo/psfsetglyphorder.ufo/glyphs/L_tnS_mE_.glif52
-rw-r--r--tests/reference/ufo/psfsetglyphorder.ufo/glyphs/L_tnS_mF_.glif44
-rw-r--r--tests/reference/ufo/psfsetglyphorder.ufo/glyphs/L_tnS_mG_.glif100
-rw-r--r--tests/reference/ufo/psfsetglyphorder.ufo/glyphs/L_tnS_mH_.glif54
-rw-r--r--tests/reference/ufo/psfsetglyphorder.ufo/glyphs/L_tnS_mI_.glif50
-rw-r--r--tests/reference/ufo/psfsetglyphorder.ufo/glyphs/L_tnS_mJ_.glif45
-rw-r--r--tests/reference/ufo/psfsetglyphorder.ufo/glyphs/L_tnS_mK_.glif50
-rw-r--r--tests/reference/ufo/psfsetglyphorder.ufo/glyphs/L_tnS_mL_.glif35
-rw-r--r--tests/reference/ufo/psfsetglyphorder.ufo/glyphs/L_tnS_mM_.glif80
-rw-r--r--tests/reference/ufo/psfsetglyphorder.ufo/glyphs/L_tnS_mN_.glif57
-rw-r--r--tests/reference/ufo/psfsetglyphorder.ufo/glyphs/L_tnS_mO_.glif40
-rw-r--r--tests/reference/ufo/psfsetglyphorder.ufo/glyphs/L_tnS_mP_.glif66
-rw-r--r--tests/reference/ufo/psfsetglyphorder.ufo/glyphs/L_tnS_mQ_.glif54
-rw-r--r--tests/reference/ufo/psfsetglyphorder.ufo/glyphs/L_tnS_mR_.glif42
-rw-r--r--tests/reference/ufo/psfsetglyphorder.ufo/glyphs/L_tnS_mS_.glif50
-rw-r--r--tests/reference/ufo/psfsetglyphorder.ufo/glyphs/L_tnS_mT_.glif45
-rw-r--r--tests/reference/ufo/psfsetglyphorder.ufo/glyphs/L_tnS_mU_.glif57
-rw-r--r--tests/reference/ufo/psfsetglyphorder.ufo/glyphs/L_tnS_mV_.glif34
-rw-r--r--tests/reference/ufo/psfsetglyphorder.ufo/glyphs/L_tnS_mW_.glif50
-rw-r--r--tests/reference/ufo/psfsetglyphorder.ufo/glyphs/L_tnS_mX_.glif40
-rw-r--r--tests/reference/ufo/psfsetglyphorder.ufo/glyphs/L_tnS_mY_.glif45
-rw-r--r--tests/reference/ufo/psfsetglyphorder.ufo/glyphs/N_onB_reakingH_yphen.glif9
-rw-r--r--tests/reference/ufo/psfsetglyphorder.ufo/glyphs/N_umS_gn.glif31
-rw-r--r--tests/reference/ufo/psfsetglyphorder.ufo/glyphs/P_ercentS_gn.glif93
-rw-r--r--tests/reference/ufo/psfsetglyphorder.ufo/glyphs/P_lusS_gn.glif19
-rw-r--r--tests/reference/ufo/psfsetglyphorder.ufo/glyphs/Q_stnM_rk.glif49
-rw-r--r--tests/reference/ufo/psfsetglyphorder.ufo/glyphs/Q_uotM_rk.glif27
-rw-r--r--tests/reference/ufo/psfsetglyphorder.ufo/glyphs/R_everseS_olidus.glif13
-rw-r--r--tests/reference/ufo/psfsetglyphorder.ufo/glyphs/R_tC_urlyB_rac.glif50
-rw-r--r--tests/reference/ufo/psfsetglyphorder.ufo/glyphs/R_tP_aren.glif29
-rw-r--r--tests/reference/ufo/psfsetglyphorder.ufo/glyphs/R_tS_qrB_rac.glif17
-rw-r--r--tests/reference/ufo/psfsetglyphorder.ufo/glyphs/S_emicolon.glif38
-rw-r--r--tests/reference/ufo/psfsetglyphorder.ufo/glyphs/S_olidus.glif13
-rw-r--r--tests/reference/ufo/psfsetglyphorder.ufo/glyphs/S_pace.glif6
-rw-r--r--tests/reference/ufo/psfsetglyphorder.ufo/glyphs/T_ilde.glif29
-rw-r--r--tests/reference/ufo/psfsetglyphorder.ufo/glyphs/V_ertL_ine.glif13
-rw-r--r--tests/reference/ufo/psfsetglyphorder.ufo/glyphs/_notdef.glif18
-rw-r--r--tests/reference/ufo/psfsetglyphorder.ufo/glyphs/_null.glif4
-rw-r--r--tests/reference/ufo/psfsetglyphorder.ufo/glyphs/contents.plist232
-rw-r--r--tests/reference/ufo/psfsetglyphorder.ufo/glyphs/nonmarkingreturn.glif5
-rw-r--r--tests/reference/ufo/psfsetglyphorder.ufo/layercontents.plist10
-rw-r--r--tests/reference/ufo/psfsetglyphorder.ufo/lib.plist451
-rw-r--r--tests/reference/ufo/psfsetglyphorder.ufo/metainfo.plist10
-rw-r--r--tests/reference/ufo/psfsetkeys.lg27
-rw-r--r--tests/reference/ufo/psfsetkeys.ufo/fontinfo.plist242
-rw-r--r--tests/reference/ufo/psfsetkeys.ufo/glyphs/A_mpersand.glif61
-rw-r--r--tests/reference/ufo/psfsetkeys.ufo/glyphs/A_pos.glif17
-rw-r--r--tests/reference/ufo/psfsetkeys.ufo/glyphs/A_sterisk.glif51
-rw-r--r--tests/reference/ufo/psfsetkeys.ufo/glyphs/A_tS_gn.glif104
-rw-r--r--tests/reference/ufo/psfsetkeys.ufo/glyphs/C_ircumA_ccent.glif17
-rw-r--r--tests/reference/ufo/psfsetkeys.ufo/glyphs/C_olon.glif35
-rw-r--r--tests/reference/ufo/psfsetkeys.ufo/glyphs/C_ombA_cute.glif14
-rw-r--r--tests/reference/ufo/psfsetkeys.ufo/glyphs/C_ombC_ircum.glif17
-rw-r--r--tests/reference/ufo/psfsetkeys.ufo/glyphs/C_ombD_iaer.glif36
-rw-r--r--tests/reference/ufo/psfsetkeys.ufo/glyphs/C_ombG_rave.glif14
-rw-r--r--tests/reference/ufo/psfsetkeys.ufo/glyphs/C_ombR_ingA_bv.glif36
-rw-r--r--tests/reference/ufo/psfsetkeys.ufo/glyphs/C_ombT_ilde.glif36
-rw-r--r--tests/reference/ufo/psfsetkeys.ufo/glyphs/C_omma.glif24
-rw-r--r--tests/reference/ufo/psfsetkeys.ufo/glyphs/D_igitE_ight.glif63
-rw-r--r--tests/reference/ufo/psfsetkeys.ufo/glyphs/D_igitF_ive.glif44
-rw-r--r--tests/reference/ufo/psfsetkeys.ufo/glyphs/D_igitF_our.glif27
-rw-r--r--tests/reference/ufo/psfsetkeys.ufo/glyphs/D_igitN_ine.glif49
-rw-r--r--tests/reference/ufo/psfsetkeys.ufo/glyphs/D_igitO_ne.glif22
-rw-r--r--tests/reference/ufo/psfsetkeys.ufo/glyphs/D_igitS_even.glif25
-rw-r--r--tests/reference/ufo/psfsetkeys.ufo/glyphs/D_igitS_ix.glif49
-rw-r--r--tests/reference/ufo/psfsetkeys.ufo/glyphs/D_igitT_hree.glif52
-rw-r--r--tests/reference/ufo/psfsetkeys.ufo/glyphs/D_igitT_wo.glif37
-rw-r--r--tests/reference/ufo/psfsetkeys.ufo/glyphs/D_igitZ_ero.glif49
-rw-r--r--tests/reference/ufo/psfsetkeys.ufo/glyphs/D_ollarS_gn.glif57
-rw-r--r--tests/reference/ufo/psfsetkeys.ufo/glyphs/D_ottedC_irc.glif235
-rw-r--r--tests/reference/ufo/psfsetkeys.ufo/glyphs/E_qS_gn.glif19
-rw-r--r--tests/reference/ufo/psfsetkeys.ufo/glyphs/E_xclamationM_rk.glif31
-rw-r--r--tests/reference/ufo/psfsetkeys.ufo/glyphs/F_ullS_top.glif21
-rw-r--r--tests/reference/ufo/psfsetkeys.ufo/glyphs/G_T_S_gn.glif16
-rw-r--r--tests/reference/ufo/psfsetkeys.ufo/glyphs/G_raveA_ccent.glif14
-rw-r--r--tests/reference/ufo/psfsetkeys.ufo/glyphs/H_yphen.glif14
-rw-r--r--tests/reference/ufo/psfsetkeys.ufo/glyphs/H_yphenM_inus.glif14
-rw-r--r--tests/reference/ufo/psfsetkeys.ufo/glyphs/H_yphen_S_oft.glif9
-rw-r--r--tests/reference/ufo/psfsetkeys.ufo/glyphs/L_T_S_gn.glif16
-rw-r--r--tests/reference/ufo/psfsetkeys.ufo/glyphs/L_ftC_urlyB_rac.glif50
-rw-r--r--tests/reference/ufo/psfsetkeys.ufo/glyphs/L_ftP_aren.glif29
-rw-r--r--tests/reference/ufo/psfsetkeys.ufo/glyphs/L_ftS_qrB_rac.glif17
-rw-r--r--tests/reference/ufo/psfsetkeys.ufo/glyphs/L_owL_ine.glif13
-rw-r--r--tests/reference/ufo/psfsetkeys.ufo/glyphs/L_tnC_apA_.glif32
-rw-r--r--tests/reference/ufo/psfsetkeys.ufo/glyphs/L_tnC_apA_D_iaer.glif13
-rw-r--r--tests/reference/ufo/psfsetkeys.ufo/glyphs/L_tnC_apB_.glif62
-rw-r--r--tests/reference/ufo/psfsetkeys.ufo/glyphs/L_tnC_apC_.glif38
-rw-r--r--tests/reference/ufo/psfsetkeys.ufo/glyphs/L_tnC_apD_.glif51
-rw-r--r--tests/reference/ufo/psfsetkeys.ufo/glyphs/L_tnC_apE_.glif35
-rw-r--r--tests/reference/ufo/psfsetkeys.ufo/glyphs/L_tnC_apF_.glif30
-rw-r--r--tests/reference/ufo/psfsetkeys.ufo/glyphs/L_tnC_apG_.glif48
-rw-r--r--tests/reference/ufo/psfsetkeys.ufo/glyphs/L_tnC_apH_.glif40
-rw-r--r--tests/reference/ufo/psfsetkeys.ufo/glyphs/L_tnC_apI_.glif26
-rw-r--r--tests/reference/ufo/psfsetkeys.ufo/glyphs/L_tnC_apJ_.glif32
-rw-r--r--tests/reference/ufo/psfsetkeys.ufo/glyphs/L_tnC_apK_.glif35
-rw-r--r--tests/reference/ufo/psfsetkeys.ufo/glyphs/L_tnC_apL_.glif28
-rw-r--r--tests/reference/ufo/psfsetkeys.ufo/glyphs/L_tnC_apM_.glif38
-rw-r--r--tests/reference/ufo/psfsetkeys.ufo/glyphs/L_tnC_apN_.glif37
-rw-r--r--tests/reference/ufo/psfsetkeys.ufo/glyphs/L_tnC_apO_.glif40
-rw-r--r--tests/reference/ufo/psfsetkeys.ufo/glyphs/L_tnC_apP_.glif50
-rw-r--r--tests/reference/ufo/psfsetkeys.ufo/glyphs/L_tnC_apQ_.glif52
-rw-r--r--tests/reference/ufo/psfsetkeys.ufo/glyphs/L_tnC_apR_.glif55
-rw-r--r--tests/reference/ufo/psfsetkeys.ufo/glyphs/L_tnC_apS_.glif50
-rw-r--r--tests/reference/ufo/psfsetkeys.ufo/glyphs/L_tnC_apT_.glif32
-rw-r--r--tests/reference/ufo/psfsetkeys.ufo/glyphs/L_tnC_apU_.glif44
-rw-r--r--tests/reference/ufo/psfsetkeys.ufo/glyphs/L_tnC_apV_.glif26
-rw-r--r--tests/reference/ufo/psfsetkeys.ufo/glyphs/L_tnC_apW_.glif45
-rw-r--r--tests/reference/ufo/psfsetkeys.ufo/glyphs/L_tnC_apX_.glif39
-rw-r--r--tests/reference/ufo/psfsetkeys.ufo/glyphs/L_tnC_apY_.glif39
-rw-r--r--tests/reference/ufo/psfsetkeys.ufo/glyphs/L_tnS_mA_.glif79
-rw-r--r--tests/reference/ufo/psfsetkeys.ufo/glyphs/L_tnS_mA_A_cute.glif14
-rw-r--r--tests/reference/ufo/psfsetkeys.ufo/glyphs/L_tnS_mA_C_ircum.glif14
-rw-r--r--tests/reference/ufo/psfsetkeys.ufo/glyphs/L_tnS_mA_D_iaer.glif14
-rw-r--r--tests/reference/ufo/psfsetkeys.ufo/glyphs/L_tnS_mA_G_rave.glif14
-rw-r--r--tests/reference/ufo/psfsetkeys.ufo/glyphs/L_tnS_mA_R_ingA_bv.glif14
-rw-r--r--tests/reference/ufo/psfsetkeys.ufo/glyphs/L_tnS_mA_T_ilde.glif14
-rw-r--r--tests/reference/ufo/psfsetkeys.ufo/glyphs/L_tnS_mB_.glif55
-rw-r--r--tests/reference/ufo/psfsetkeys.ufo/glyphs/L_tnS_mC_.glif39
-rw-r--r--tests/reference/ufo/psfsetkeys.ufo/glyphs/L_tnS_mD_.glif65
-rw-r--r--tests/reference/ufo/psfsetkeys.ufo/glyphs/L_tnS_mE_.glif52
-rw-r--r--tests/reference/ufo/psfsetkeys.ufo/glyphs/L_tnS_mF_.glif44
-rw-r--r--tests/reference/ufo/psfsetkeys.ufo/glyphs/L_tnS_mG_.glif91
-rw-r--r--tests/reference/ufo/psfsetkeys.ufo/glyphs/L_tnS_mH_.glif54
-rw-r--r--tests/reference/ufo/psfsetkeys.ufo/glyphs/L_tnS_mI_.glif50
-rw-r--r--tests/reference/ufo/psfsetkeys.ufo/glyphs/L_tnS_mJ_.glif45
-rw-r--r--tests/reference/ufo/psfsetkeys.ufo/glyphs/L_tnS_mK_.glif45
-rw-r--r--tests/reference/ufo/psfsetkeys.ufo/glyphs/L_tnS_mL_.glif35
-rw-r--r--tests/reference/ufo/psfsetkeys.ufo/glyphs/L_tnS_mM_.glif80
-rw-r--r--tests/reference/ufo/psfsetkeys.ufo/glyphs/L_tnS_mN_.glif57
-rw-r--r--tests/reference/ufo/psfsetkeys.ufo/glyphs/L_tnS_mO_.glif40
-rw-r--r--tests/reference/ufo/psfsetkeys.ufo/glyphs/L_tnS_mP_.glif66
-rw-r--r--tests/reference/ufo/psfsetkeys.ufo/glyphs/L_tnS_mQ_.glif54
-rw-r--r--tests/reference/ufo/psfsetkeys.ufo/glyphs/L_tnS_mR_.glif42
-rw-r--r--tests/reference/ufo/psfsetkeys.ufo/glyphs/L_tnS_mS_.glif50
-rw-r--r--tests/reference/ufo/psfsetkeys.ufo/glyphs/L_tnS_mT_.glif45
-rw-r--r--tests/reference/ufo/psfsetkeys.ufo/glyphs/L_tnS_mU_.glif57
-rw-r--r--tests/reference/ufo/psfsetkeys.ufo/glyphs/L_tnS_mV_.glif34
-rw-r--r--tests/reference/ufo/psfsetkeys.ufo/glyphs/L_tnS_mW_.glif50
-rw-r--r--tests/reference/ufo/psfsetkeys.ufo/glyphs/L_tnS_mX_.glif40
-rw-r--r--tests/reference/ufo/psfsetkeys.ufo/glyphs/L_tnS_mY_.glif45
-rw-r--r--tests/reference/ufo/psfsetkeys.ufo/glyphs/N_onB_reakingH_yphen.glif9
-rw-r--r--tests/reference/ufo/psfsetkeys.ufo/glyphs/N_umS_gn.glif31
-rw-r--r--tests/reference/ufo/psfsetkeys.ufo/glyphs/P_ercentS_gn.glif93
-rw-r--r--tests/reference/ufo/psfsetkeys.ufo/glyphs/P_lusS_gn.glif19
-rw-r--r--tests/reference/ufo/psfsetkeys.ufo/glyphs/Q_stnM_rk.glif49
-rw-r--r--tests/reference/ufo/psfsetkeys.ufo/glyphs/Q_uotM_rk.glif27
-rw-r--r--tests/reference/ufo/psfsetkeys.ufo/glyphs/R_everseS_olidus.glif13
-rw-r--r--tests/reference/ufo/psfsetkeys.ufo/glyphs/R_tC_urlyB_rac.glif47
-rw-r--r--tests/reference/ufo/psfsetkeys.ufo/glyphs/R_tP_aren.glif29
-rw-r--r--tests/reference/ufo/psfsetkeys.ufo/glyphs/R_tS_qrB_rac.glif17
-rw-r--r--tests/reference/ufo/psfsetkeys.ufo/glyphs/S_emicolon.glif38
-rw-r--r--tests/reference/ufo/psfsetkeys.ufo/glyphs/S_olidus.glif13
-rw-r--r--tests/reference/ufo/psfsetkeys.ufo/glyphs/S_pace.glif6
-rw-r--r--tests/reference/ufo/psfsetkeys.ufo/glyphs/T_ilde.glif29
-rw-r--r--tests/reference/ufo/psfsetkeys.ufo/glyphs/V_ertL_ine.glif13
-rw-r--r--tests/reference/ufo/psfsetkeys.ufo/glyphs/_notdef.glif18
-rw-r--r--tests/reference/ufo/psfsetkeys.ufo/glyphs/_null.glif4
-rw-r--r--tests/reference/ufo/psfsetkeys.ufo/glyphs/contents.plist232
-rw-r--r--tests/reference/ufo/psfsetkeys.ufo/glyphs/nonmarkingreturn.glif5
-rw-r--r--tests/reference/ufo/psfsetkeys.ufo/layercontents.plist10
-rw-r--r--tests/reference/ufo/psfsetkeys.ufo/lib.plist534
-rw-r--r--tests/reference/ufo/psfsetkeys.ufo/metainfo.plist10
-rw-r--r--tests/reference/ufo/psfsetpsnames.lg155
-rw-r--r--tests/reference/ufo/psfsetpsnames.ufo/fontinfo.plist245
-rw-r--r--tests/reference/ufo/psfsetpsnames.ufo/glyphs/A_mpersand.glif61
-rw-r--r--tests/reference/ufo/psfsetpsnames.ufo/glyphs/A_pos.glif17
-rw-r--r--tests/reference/ufo/psfsetpsnames.ufo/glyphs/A_sterisk.glif51
-rw-r--r--tests/reference/ufo/psfsetpsnames.ufo/glyphs/A_tS_gn.glif104
-rw-r--r--tests/reference/ufo/psfsetpsnames.ufo/glyphs/C_ircumA_ccent.glif17
-rw-r--r--tests/reference/ufo/psfsetpsnames.ufo/glyphs/C_olon.glif35
-rw-r--r--tests/reference/ufo/psfsetpsnames.ufo/glyphs/C_ombA_cute.glif14
-rw-r--r--tests/reference/ufo/psfsetpsnames.ufo/glyphs/C_ombC_ircum.glif17
-rw-r--r--tests/reference/ufo/psfsetpsnames.ufo/glyphs/C_ombD_iaer.glif36
-rw-r--r--tests/reference/ufo/psfsetpsnames.ufo/glyphs/C_ombG_rave.glif14
-rw-r--r--tests/reference/ufo/psfsetpsnames.ufo/glyphs/C_ombR_ingA_bv.glif36
-rw-r--r--tests/reference/ufo/psfsetpsnames.ufo/glyphs/C_ombT_ilde.glif36
-rw-r--r--tests/reference/ufo/psfsetpsnames.ufo/glyphs/C_omma.glif24
-rw-r--r--tests/reference/ufo/psfsetpsnames.ufo/glyphs/D_igitE_ight.glif63
-rw-r--r--tests/reference/ufo/psfsetpsnames.ufo/glyphs/D_igitF_ive.glif44
-rw-r--r--tests/reference/ufo/psfsetpsnames.ufo/glyphs/D_igitF_our.glif27
-rw-r--r--tests/reference/ufo/psfsetpsnames.ufo/glyphs/D_igitN_ine.glif49
-rw-r--r--tests/reference/ufo/psfsetpsnames.ufo/glyphs/D_igitO_ne.glif22
-rw-r--r--tests/reference/ufo/psfsetpsnames.ufo/glyphs/D_igitS_even.glif25
-rw-r--r--tests/reference/ufo/psfsetpsnames.ufo/glyphs/D_igitS_ix.glif49
-rw-r--r--tests/reference/ufo/psfsetpsnames.ufo/glyphs/D_igitT_hree.glif52
-rw-r--r--tests/reference/ufo/psfsetpsnames.ufo/glyphs/D_igitT_wo.glif37
-rw-r--r--tests/reference/ufo/psfsetpsnames.ufo/glyphs/D_igitZ_ero.glif49
-rw-r--r--tests/reference/ufo/psfsetpsnames.ufo/glyphs/D_ollarS_gn.glif57
-rw-r--r--tests/reference/ufo/psfsetpsnames.ufo/glyphs/D_ottedC_irc.glif235
-rw-r--r--tests/reference/ufo/psfsetpsnames.ufo/glyphs/E_qS_gn.glif19
-rw-r--r--tests/reference/ufo/psfsetpsnames.ufo/glyphs/E_xclamationM_rk.glif31
-rw-r--r--tests/reference/ufo/psfsetpsnames.ufo/glyphs/F_ullS_top.glif21
-rw-r--r--tests/reference/ufo/psfsetpsnames.ufo/glyphs/G_T_S_gn.glif16
-rw-r--r--tests/reference/ufo/psfsetpsnames.ufo/glyphs/G_raveA_ccent.glif14
-rw-r--r--tests/reference/ufo/psfsetpsnames.ufo/glyphs/H_yphen.glif14
-rw-r--r--tests/reference/ufo/psfsetpsnames.ufo/glyphs/H_yphenM_inus.glif14
-rw-r--r--tests/reference/ufo/psfsetpsnames.ufo/glyphs/H_yphen_S_oft.glif9
-rw-r--r--tests/reference/ufo/psfsetpsnames.ufo/glyphs/L_T_S_gn.glif16
-rw-r--r--tests/reference/ufo/psfsetpsnames.ufo/glyphs/L_ftC_urlyB_rac.glif50
-rw-r--r--tests/reference/ufo/psfsetpsnames.ufo/glyphs/L_ftP_aren.glif29
-rw-r--r--tests/reference/ufo/psfsetpsnames.ufo/glyphs/L_ftS_qrB_rac.glif17
-rw-r--r--tests/reference/ufo/psfsetpsnames.ufo/glyphs/L_owL_ine.glif13
-rw-r--r--tests/reference/ufo/psfsetpsnames.ufo/glyphs/L_tnC_apA_.glif32
-rw-r--r--tests/reference/ufo/psfsetpsnames.ufo/glyphs/L_tnC_apA_D_iaer.glif13
-rw-r--r--tests/reference/ufo/psfsetpsnames.ufo/glyphs/L_tnC_apB_.glif62
-rw-r--r--tests/reference/ufo/psfsetpsnames.ufo/glyphs/L_tnC_apC_.glif38
-rw-r--r--tests/reference/ufo/psfsetpsnames.ufo/glyphs/L_tnC_apD_.glif51
-rw-r--r--tests/reference/ufo/psfsetpsnames.ufo/glyphs/L_tnC_apE_.glif35
-rw-r--r--tests/reference/ufo/psfsetpsnames.ufo/glyphs/L_tnC_apF_.glif30
-rw-r--r--tests/reference/ufo/psfsetpsnames.ufo/glyphs/L_tnC_apG_.glif48
-rw-r--r--tests/reference/ufo/psfsetpsnames.ufo/glyphs/L_tnC_apH_.glif40
-rw-r--r--tests/reference/ufo/psfsetpsnames.ufo/glyphs/L_tnC_apI_.glif26
-rw-r--r--tests/reference/ufo/psfsetpsnames.ufo/glyphs/L_tnC_apJ_.glif32
-rw-r--r--tests/reference/ufo/psfsetpsnames.ufo/glyphs/L_tnC_apK_.glif35
-rw-r--r--tests/reference/ufo/psfsetpsnames.ufo/glyphs/L_tnC_apL_.glif28
-rw-r--r--tests/reference/ufo/psfsetpsnames.ufo/glyphs/L_tnC_apM_.glif38
-rw-r--r--tests/reference/ufo/psfsetpsnames.ufo/glyphs/L_tnC_apN_.glif37
-rw-r--r--tests/reference/ufo/psfsetpsnames.ufo/glyphs/L_tnC_apO_.glif40
-rw-r--r--tests/reference/ufo/psfsetpsnames.ufo/glyphs/L_tnC_apP_.glif50
-rw-r--r--tests/reference/ufo/psfsetpsnames.ufo/glyphs/L_tnC_apQ_.glif52
-rw-r--r--tests/reference/ufo/psfsetpsnames.ufo/glyphs/L_tnC_apR_.glif55
-rw-r--r--tests/reference/ufo/psfsetpsnames.ufo/glyphs/L_tnC_apS_.glif50
-rw-r--r--tests/reference/ufo/psfsetpsnames.ufo/glyphs/L_tnC_apT_.glif32
-rw-r--r--tests/reference/ufo/psfsetpsnames.ufo/glyphs/L_tnC_apU_.glif44
-rw-r--r--tests/reference/ufo/psfsetpsnames.ufo/glyphs/L_tnC_apV_.glif26
-rw-r--r--tests/reference/ufo/psfsetpsnames.ufo/glyphs/L_tnC_apW_.glif45
-rw-r--r--tests/reference/ufo/psfsetpsnames.ufo/glyphs/L_tnC_apX_.glif39
-rw-r--r--tests/reference/ufo/psfsetpsnames.ufo/glyphs/L_tnC_apY_.glif39
-rw-r--r--tests/reference/ufo/psfsetpsnames.ufo/glyphs/L_tnS_mA_.glif79
-rw-r--r--tests/reference/ufo/psfsetpsnames.ufo/glyphs/L_tnS_mA_A_cute.glif14
-rw-r--r--tests/reference/ufo/psfsetpsnames.ufo/glyphs/L_tnS_mA_C_ircum.glif14
-rw-r--r--tests/reference/ufo/psfsetpsnames.ufo/glyphs/L_tnS_mA_D_iaer.glif14
-rw-r--r--tests/reference/ufo/psfsetpsnames.ufo/glyphs/L_tnS_mA_G_rave.glif14
-rw-r--r--tests/reference/ufo/psfsetpsnames.ufo/glyphs/L_tnS_mA_R_ingA_bv.glif14
-rw-r--r--tests/reference/ufo/psfsetpsnames.ufo/glyphs/L_tnS_mA_T_ilde.glif14
-rw-r--r--tests/reference/ufo/psfsetpsnames.ufo/glyphs/L_tnS_mB_.glif55
-rw-r--r--tests/reference/ufo/psfsetpsnames.ufo/glyphs/L_tnS_mC_.glif39
-rw-r--r--tests/reference/ufo/psfsetpsnames.ufo/glyphs/L_tnS_mD_.glif65
-rw-r--r--tests/reference/ufo/psfsetpsnames.ufo/glyphs/L_tnS_mE_.glif52
-rw-r--r--tests/reference/ufo/psfsetpsnames.ufo/glyphs/L_tnS_mF_.glif44
-rw-r--r--tests/reference/ufo/psfsetpsnames.ufo/glyphs/L_tnS_mG_.glif91
-rw-r--r--tests/reference/ufo/psfsetpsnames.ufo/glyphs/L_tnS_mH_.glif54
-rw-r--r--tests/reference/ufo/psfsetpsnames.ufo/glyphs/L_tnS_mI_.glif50
-rw-r--r--tests/reference/ufo/psfsetpsnames.ufo/glyphs/L_tnS_mJ_.glif45
-rw-r--r--tests/reference/ufo/psfsetpsnames.ufo/glyphs/L_tnS_mK_.glif45
-rw-r--r--tests/reference/ufo/psfsetpsnames.ufo/glyphs/L_tnS_mL_.glif35
-rw-r--r--tests/reference/ufo/psfsetpsnames.ufo/glyphs/L_tnS_mM_.glif80
-rw-r--r--tests/reference/ufo/psfsetpsnames.ufo/glyphs/L_tnS_mN_.glif57
-rw-r--r--tests/reference/ufo/psfsetpsnames.ufo/glyphs/L_tnS_mO_.glif40
-rw-r--r--tests/reference/ufo/psfsetpsnames.ufo/glyphs/L_tnS_mP_.glif66
-rw-r--r--tests/reference/ufo/psfsetpsnames.ufo/glyphs/L_tnS_mQ_.glif54
-rw-r--r--tests/reference/ufo/psfsetpsnames.ufo/glyphs/L_tnS_mR_.glif42
-rw-r--r--tests/reference/ufo/psfsetpsnames.ufo/glyphs/L_tnS_mS_.glif50
-rw-r--r--tests/reference/ufo/psfsetpsnames.ufo/glyphs/L_tnS_mT_.glif45
-rw-r--r--tests/reference/ufo/psfsetpsnames.ufo/glyphs/L_tnS_mU_.glif57
-rw-r--r--tests/reference/ufo/psfsetpsnames.ufo/glyphs/L_tnS_mV_.glif34
-rw-r--r--tests/reference/ufo/psfsetpsnames.ufo/glyphs/L_tnS_mW_.glif50
-rw-r--r--tests/reference/ufo/psfsetpsnames.ufo/glyphs/L_tnS_mX_.glif40
-rw-r--r--tests/reference/ufo/psfsetpsnames.ufo/glyphs/L_tnS_mY_.glif45
-rw-r--r--tests/reference/ufo/psfsetpsnames.ufo/glyphs/N_onB_reakingH_yphen.glif9
-rw-r--r--tests/reference/ufo/psfsetpsnames.ufo/glyphs/N_umS_gn.glif31
-rw-r--r--tests/reference/ufo/psfsetpsnames.ufo/glyphs/P_ercentS_gn.glif93
-rw-r--r--tests/reference/ufo/psfsetpsnames.ufo/glyphs/P_lusS_gn.glif19
-rw-r--r--tests/reference/ufo/psfsetpsnames.ufo/glyphs/Q_stnM_rk.glif49
-rw-r--r--tests/reference/ufo/psfsetpsnames.ufo/glyphs/Q_uotM_rk.glif27
-rw-r--r--tests/reference/ufo/psfsetpsnames.ufo/glyphs/R_everseS_olidus.glif13
-rw-r--r--tests/reference/ufo/psfsetpsnames.ufo/glyphs/R_tC_urlyB_rac.glif47
-rw-r--r--tests/reference/ufo/psfsetpsnames.ufo/glyphs/R_tP_aren.glif29
-rw-r--r--tests/reference/ufo/psfsetpsnames.ufo/glyphs/R_tS_qrB_rac.glif17
-rw-r--r--tests/reference/ufo/psfsetpsnames.ufo/glyphs/S_emicolon.glif38
-rw-r--r--tests/reference/ufo/psfsetpsnames.ufo/glyphs/S_olidus.glif13
-rw-r--r--tests/reference/ufo/psfsetpsnames.ufo/glyphs/S_pace.glif6
-rw-r--r--tests/reference/ufo/psfsetpsnames.ufo/glyphs/T_ilde.glif29
-rw-r--r--tests/reference/ufo/psfsetpsnames.ufo/glyphs/V_ertL_ine.glif13
-rw-r--r--tests/reference/ufo/psfsetpsnames.ufo/glyphs/_notdef.glif18
-rw-r--r--tests/reference/ufo/psfsetpsnames.ufo/glyphs/_null.glif4
-rw-r--r--tests/reference/ufo/psfsetpsnames.ufo/glyphs/contents.plist232
-rw-r--r--tests/reference/ufo/psfsetpsnames.ufo/glyphs/nonmarkingreturn.glif5
-rw-r--r--tests/reference/ufo/psfsetpsnames.ufo/layercontents.plist10
-rw-r--r--tests/reference/ufo/psfsetpsnames.ufo/lib.plist368
-rw-r--r--tests/reference/ufo/psfsetpsnames.ufo/metainfo.plist10
-rw-r--r--tests/reference/ufo/psfsetunicodes.lg149
-rw-r--r--tests/reference/ufo/psfsetunicodes.ufo/fontinfo.plist240
-rw-r--r--tests/reference/ufo/psfsetunicodes.ufo/glyphs/A_mpersand.glif61
-rw-r--r--tests/reference/ufo/psfsetunicodes.ufo/glyphs/A_pos.glif17
-rw-r--r--tests/reference/ufo/psfsetunicodes.ufo/glyphs/A_sterisk.glif51
-rw-r--r--tests/reference/ufo/psfsetunicodes.ufo/glyphs/A_tS_gn.glif104
-rw-r--r--tests/reference/ufo/psfsetunicodes.ufo/glyphs/C_ircumA_ccent.glif17
-rw-r--r--tests/reference/ufo/psfsetunicodes.ufo/glyphs/C_olon.glif35
-rw-r--r--tests/reference/ufo/psfsetunicodes.ufo/glyphs/C_ombA_cute.glif14
-rw-r--r--tests/reference/ufo/psfsetunicodes.ufo/glyphs/C_ombC_ircum.glif17
-rw-r--r--tests/reference/ufo/psfsetunicodes.ufo/glyphs/C_ombD_iaer.glif36
-rw-r--r--tests/reference/ufo/psfsetunicodes.ufo/glyphs/C_ombG_rave.glif14
-rw-r--r--tests/reference/ufo/psfsetunicodes.ufo/glyphs/C_ombR_ingA_bv.glif36
-rw-r--r--tests/reference/ufo/psfsetunicodes.ufo/glyphs/C_ombT_ilde.glif36
-rw-r--r--tests/reference/ufo/psfsetunicodes.ufo/glyphs/C_omma.glif23
-rw-r--r--tests/reference/ufo/psfsetunicodes.ufo/glyphs/D_igitE_ight.glif63
-rw-r--r--tests/reference/ufo/psfsetunicodes.ufo/glyphs/D_igitF_ive.glif44
-rw-r--r--tests/reference/ufo/psfsetunicodes.ufo/glyphs/D_igitF_our.glif27
-rw-r--r--tests/reference/ufo/psfsetunicodes.ufo/glyphs/D_igitN_ine.glif49
-rw-r--r--tests/reference/ufo/psfsetunicodes.ufo/glyphs/D_igitO_ne.glif22
-rw-r--r--tests/reference/ufo/psfsetunicodes.ufo/glyphs/D_igitS_even.glif25
-rw-r--r--tests/reference/ufo/psfsetunicodes.ufo/glyphs/D_igitS_ix.glif49
-rw-r--r--tests/reference/ufo/psfsetunicodes.ufo/glyphs/D_igitT_hree.glif52
-rw-r--r--tests/reference/ufo/psfsetunicodes.ufo/glyphs/D_igitT_wo.glif37
-rw-r--r--tests/reference/ufo/psfsetunicodes.ufo/glyphs/D_igitZ_ero.glif49
-rw-r--r--tests/reference/ufo/psfsetunicodes.ufo/glyphs/D_ollarS_gn.glif53
-rw-r--r--tests/reference/ufo/psfsetunicodes.ufo/glyphs/D_ottedC_irc.glif235
-rw-r--r--tests/reference/ufo/psfsetunicodes.ufo/glyphs/E_qS_gn.glif19
-rw-r--r--tests/reference/ufo/psfsetunicodes.ufo/glyphs/E_xclamationM_rk.glif31
-rw-r--r--tests/reference/ufo/psfsetunicodes.ufo/glyphs/F_ullS_top.glif21
-rw-r--r--tests/reference/ufo/psfsetunicodes.ufo/glyphs/G_T_S_gn.glif16
-rw-r--r--tests/reference/ufo/psfsetunicodes.ufo/glyphs/G_raveA_ccent.glif14
-rw-r--r--tests/reference/ufo/psfsetunicodes.ufo/glyphs/H_yphen.glif14
-rw-r--r--tests/reference/ufo/psfsetunicodes.ufo/glyphs/H_yphenM_inus.glif14
-rw-r--r--tests/reference/ufo/psfsetunicodes.ufo/glyphs/H_yphen_S_oft.glif9
-rw-r--r--tests/reference/ufo/psfsetunicodes.ufo/glyphs/L_T_S_gn.glif16
-rw-r--r--tests/reference/ufo/psfsetunicodes.ufo/glyphs/L_ftC_urlyB_rac.glif50
-rw-r--r--tests/reference/ufo/psfsetunicodes.ufo/glyphs/L_ftP_aren.glif29
-rw-r--r--tests/reference/ufo/psfsetunicodes.ufo/glyphs/L_ftS_qrB_rac.glif17
-rw-r--r--tests/reference/ufo/psfsetunicodes.ufo/glyphs/L_owL_ine.glif13
-rw-r--r--tests/reference/ufo/psfsetunicodes.ufo/glyphs/L_tnC_apA_.glif32
-rw-r--r--tests/reference/ufo/psfsetunicodes.ufo/glyphs/L_tnC_apA_D_iaer.glif13
-rw-r--r--tests/reference/ufo/psfsetunicodes.ufo/glyphs/L_tnC_apB_.glif62
-rw-r--r--tests/reference/ufo/psfsetunicodes.ufo/glyphs/L_tnC_apC_.glif38
-rw-r--r--tests/reference/ufo/psfsetunicodes.ufo/glyphs/L_tnC_apD_.glif51
-rw-r--r--tests/reference/ufo/psfsetunicodes.ufo/glyphs/L_tnC_apE_.glif35
-rw-r--r--tests/reference/ufo/psfsetunicodes.ufo/glyphs/L_tnC_apF_.glif30
-rw-r--r--tests/reference/ufo/psfsetunicodes.ufo/glyphs/L_tnC_apG_.glif48
-rw-r--r--tests/reference/ufo/psfsetunicodes.ufo/glyphs/L_tnC_apH_.glif36
-rw-r--r--tests/reference/ufo/psfsetunicodes.ufo/glyphs/L_tnC_apI_.glif26
-rw-r--r--tests/reference/ufo/psfsetunicodes.ufo/glyphs/L_tnC_apJ_.glif30
-rw-r--r--tests/reference/ufo/psfsetunicodes.ufo/glyphs/L_tnC_apK_.glif35
-rw-r--r--tests/reference/ufo/psfsetunicodes.ufo/glyphs/L_tnC_apL_.glif28
-rw-r--r--tests/reference/ufo/psfsetunicodes.ufo/glyphs/L_tnC_apM_.glif36
-rw-r--r--tests/reference/ufo/psfsetunicodes.ufo/glyphs/L_tnC_apN_.glif37
-rw-r--r--tests/reference/ufo/psfsetunicodes.ufo/glyphs/L_tnC_apO_.glif40
-rw-r--r--tests/reference/ufo/psfsetunicodes.ufo/glyphs/L_tnC_apP_.glif50
-rw-r--r--tests/reference/ufo/psfsetunicodes.ufo/glyphs/L_tnC_apQ_.glif52
-rw-r--r--tests/reference/ufo/psfsetunicodes.ufo/glyphs/L_tnC_apR_.glif55
-rw-r--r--tests/reference/ufo/psfsetunicodes.ufo/glyphs/L_tnC_apS_.glif50
-rw-r--r--tests/reference/ufo/psfsetunicodes.ufo/glyphs/L_tnC_apT_.glif32
-rw-r--r--tests/reference/ufo/psfsetunicodes.ufo/glyphs/L_tnC_apU_.glif44
-rw-r--r--tests/reference/ufo/psfsetunicodes.ufo/glyphs/L_tnC_apV_.glif26
-rw-r--r--tests/reference/ufo/psfsetunicodes.ufo/glyphs/L_tnC_apW_.glif44
-rw-r--r--tests/reference/ufo/psfsetunicodes.ufo/glyphs/L_tnC_apX_.glif39
-rw-r--r--tests/reference/ufo/psfsetunicodes.ufo/glyphs/L_tnC_apY_.glif39
-rw-r--r--tests/reference/ufo/psfsetunicodes.ufo/glyphs/L_tnS_mA_.glif77
-rw-r--r--tests/reference/ufo/psfsetunicodes.ufo/glyphs/L_tnS_mA_A_cute.glif14
-rw-r--r--tests/reference/ufo/psfsetunicodes.ufo/glyphs/L_tnS_mA_C_ircum.glif14
-rw-r--r--tests/reference/ufo/psfsetunicodes.ufo/glyphs/L_tnS_mA_D_iaer.glif14
-rw-r--r--tests/reference/ufo/psfsetunicodes.ufo/glyphs/L_tnS_mA_G_rave.glif14
-rw-r--r--tests/reference/ufo/psfsetunicodes.ufo/glyphs/L_tnS_mA_R_ingA_bv.glif14
-rw-r--r--tests/reference/ufo/psfsetunicodes.ufo/glyphs/L_tnS_mA_T_ilde.glif14
-rw-r--r--tests/reference/ufo/psfsetunicodes.ufo/glyphs/L_tnS_mB_.glif55
-rw-r--r--tests/reference/ufo/psfsetunicodes.ufo/glyphs/L_tnS_mC_.glif39
-rw-r--r--tests/reference/ufo/psfsetunicodes.ufo/glyphs/L_tnS_mD_.glif65
-rw-r--r--tests/reference/ufo/psfsetunicodes.ufo/glyphs/L_tnS_mE_.glif52
-rw-r--r--tests/reference/ufo/psfsetunicodes.ufo/glyphs/L_tnS_mF_.glif44
-rw-r--r--tests/reference/ufo/psfsetunicodes.ufo/glyphs/L_tnS_mG_.glif100
-rw-r--r--tests/reference/ufo/psfsetunicodes.ufo/glyphs/L_tnS_mH_.glif54
-rw-r--r--tests/reference/ufo/psfsetunicodes.ufo/glyphs/L_tnS_mI_.glif50
-rw-r--r--tests/reference/ufo/psfsetunicodes.ufo/glyphs/L_tnS_mJ_.glif45
-rw-r--r--tests/reference/ufo/psfsetunicodes.ufo/glyphs/L_tnS_mK_.glif50
-rw-r--r--tests/reference/ufo/psfsetunicodes.ufo/glyphs/L_tnS_mL_.glif35
-rw-r--r--tests/reference/ufo/psfsetunicodes.ufo/glyphs/L_tnS_mM_.glif80
-rw-r--r--tests/reference/ufo/psfsetunicodes.ufo/glyphs/L_tnS_mN_.glif57
-rw-r--r--tests/reference/ufo/psfsetunicodes.ufo/glyphs/L_tnS_mO_.glif40
-rw-r--r--tests/reference/ufo/psfsetunicodes.ufo/glyphs/L_tnS_mP_.glif66
-rw-r--r--tests/reference/ufo/psfsetunicodes.ufo/glyphs/L_tnS_mQ_.glif54
-rw-r--r--tests/reference/ufo/psfsetunicodes.ufo/glyphs/L_tnS_mR_.glif42
-rw-r--r--tests/reference/ufo/psfsetunicodes.ufo/glyphs/L_tnS_mS_.glif50
-rw-r--r--tests/reference/ufo/psfsetunicodes.ufo/glyphs/L_tnS_mT_.glif45
-rw-r--r--tests/reference/ufo/psfsetunicodes.ufo/glyphs/L_tnS_mU_.glif57
-rw-r--r--tests/reference/ufo/psfsetunicodes.ufo/glyphs/L_tnS_mV_.glif34
-rw-r--r--tests/reference/ufo/psfsetunicodes.ufo/glyphs/L_tnS_mW_.glif50
-rw-r--r--tests/reference/ufo/psfsetunicodes.ufo/glyphs/L_tnS_mX_.glif40
-rw-r--r--tests/reference/ufo/psfsetunicodes.ufo/glyphs/L_tnS_mY_.glif45
-rw-r--r--tests/reference/ufo/psfsetunicodes.ufo/glyphs/N_onB_reakingH_yphen.glif9
-rw-r--r--tests/reference/ufo/psfsetunicodes.ufo/glyphs/N_umS_gn.glif31
-rw-r--r--tests/reference/ufo/psfsetunicodes.ufo/glyphs/P_ercentS_gn.glif93
-rw-r--r--tests/reference/ufo/psfsetunicodes.ufo/glyphs/P_lusS_gn.glif19
-rw-r--r--tests/reference/ufo/psfsetunicodes.ufo/glyphs/Q_stnM_rk.glif49
-rw-r--r--tests/reference/ufo/psfsetunicodes.ufo/glyphs/Q_uotM_rk.glif27
-rw-r--r--tests/reference/ufo/psfsetunicodes.ufo/glyphs/R_everseS_olidus.glif13
-rw-r--r--tests/reference/ufo/psfsetunicodes.ufo/glyphs/R_tC_urlyB_rac.glif50
-rw-r--r--tests/reference/ufo/psfsetunicodes.ufo/glyphs/R_tP_aren.glif29
-rw-r--r--tests/reference/ufo/psfsetunicodes.ufo/glyphs/R_tS_qrB_rac.glif17
-rw-r--r--tests/reference/ufo/psfsetunicodes.ufo/glyphs/S_emicolon.glif38
-rw-r--r--tests/reference/ufo/psfsetunicodes.ufo/glyphs/S_olidus.glif13
-rw-r--r--tests/reference/ufo/psfsetunicodes.ufo/glyphs/S_pace.glif6
-rw-r--r--tests/reference/ufo/psfsetunicodes.ufo/glyphs/T_ilde.glif29
-rw-r--r--tests/reference/ufo/psfsetunicodes.ufo/glyphs/V_ertL_ine.glif13
-rw-r--r--tests/reference/ufo/psfsetunicodes.ufo/glyphs/_notdef.glif18
-rw-r--r--tests/reference/ufo/psfsetunicodes.ufo/glyphs/_null.glif4
-rw-r--r--tests/reference/ufo/psfsetunicodes.ufo/glyphs/contents.plist232
-rw-r--r--tests/reference/ufo/psfsetunicodes.ufo/glyphs/nonmarkingreturn.glif5
-rw-r--r--tests/reference/ufo/psfsetunicodes.ufo/layercontents.plist10
-rw-r--r--tests/reference/ufo/psfsetunicodes.ufo/lib.plist534
-rw-r--r--tests/reference/ufo/psfsetunicodes.ufo/metainfo.plist10
-rw-r--r--tests/reference/ufo/psfsyncmasters-Bold-fontinfo.plist245
-rw-r--r--tests/reference/ufo/psfsyncmasters-Bold-lib.plist536
-rw-r--r--tests/reference/ufo/psfsyncmasters-BoldItalic-fontinfo.plist243
-rw-r--r--tests/reference/ufo/psfsyncmasters-Italic-fontinfo.plist243
-rw-r--r--tests/reference/ufo/psfsyncmasters.lg12
-rw-r--r--tests/reference/ufo/psfufo2ttf.lg4
-rw-r--r--tests/reference/ufo/psfufo2ttf.ttfbin0 -> 22532 bytes
-rw-r--r--tests/resetreferencelogs.py67
-rw-r--r--tests/runlocalufotests.py63
-rw-r--r--tests/runmakefeatests.py46
-rw-r--r--tests/setuplocalufotests.py69
-rw-r--r--tests/setuptestdata.py47
-rw-r--r--tests/ufo/test_10_psfbuildcomp.py37
-rw-r--r--tests/ufo/test_16_psfchangettfglyphnames.py37
-rw-r--r--tests/ufo/test_18_psfcheckbasicchars.py36
-rw-r--r--tests/ufo/test_23_psfcopyglyphs.py41
-rw-r--r--tests/ufo/test_30_psfdeleteglyphs.py37
-rw-r--r--tests/ufo/test_34_psfexportanchors.py36
-rw-r--r--tests/ufo/test_36_psfexportunicodes.py36
-rw-r--r--tests/ufo/test_38_psfgenftml.py75
-rw-r--r--tests/ufo/test_40_psfglyphs2ufo.py64
-rw-r--r--tests/ufo/test_42_psfmakefea.py37
-rw-r--r--tests/ufo/test_44_psfmakewoffmetatdata.py37
-rw-r--r--tests/ufo/test_46_psfrenameglyphs.py37
-rw-r--r--tests/ufo/test_50_psfsetassocfeat.py37
-rw-r--r--tests/ufo/test_52_psfsetassocuids.py37
-rw-r--r--tests/ufo/test_54_psfsetglyphorder.py37
-rw-r--r--tests/ufo/test_56_psfsetkeys.py37
-rw-r--r--tests/ufo/test_60_psfsetpsnames.py37
-rw-r--r--tests/ufo/test_62_psfsetunicodes.py37
-rw-r--r--tests/ufo/test_80_psfsyncmasters.py73
-rw-r--r--tests/ufo/test_88_psfufo2ttf.py37
-rw-r--r--tests/ufo/test_99_psfnormalize.py37
-rwxr-xr-xupdate_headers.py196
2402 files changed, 153252 insertions, 0 deletions
diff --git a/.gitattributes b/.gitattributes
new file mode 100644
index 0000000..b9f392c
--- /dev/null
+++ b/.gitattributes
@@ -0,0 +1,42 @@
+# .gitattributes for pysilfont
+
+# Based on https://github.com/alexkaratarakis/gitattributes/blob/master/Python.gitattributes
+# plus additions for pysilfont
+
+# Designed to tell git how to best deal with certain file formats
+# The goal for eols is to have LF in the repo and platform-specific
+# endings, when appropriate, in the working copy on all platforms.
+# To tweak to your particular needs,
+# see http://git-scm.com/book/en/Customizing-Git-Git-Attributes
+
+# The following causes git to auto detect text files which will have eol
+# conversion applied according to core.autocrlf and core.eol
+* text=auto
+
+
+# Text files
+# ============
+*.md text
+*.fea* text
+*.pxd text
+*.py text
+*.py3 text
+*.pyw text
+*.pyx text
+*.sh text
+*.txt text
+
+# Binary files
+# ============
+*.db binary
+*.p binary
+*.pkl binary
+*.pyc binary
+*.pyd binary
+*.pyo binary
+*.png binary
+
+# Note: .db, .p, and .pkl files are associated
+# with the python modules ``pickle``, ``dbm.*``,
+# ``shelve``, ``marshal``, ``anydbm``, & ``bsddb``
+# (among others). \ No newline at end of file
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..afa6363
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,24 @@
+*.pyc
+*.log
+*~
+*.sw?
+
+
+installed-files.txt
+pysilfont.cfg
+
+/build
+/dist
+/local
+/dev
+/venv
+
+/lib/pysilfont.egg-info
+/pysilfont.egg-info
+/setuptools-*
+/.pytest_cache
+/tests/localufos.csv
+
+.idea
+
+.DS_Store
diff --git a/CHANGELOG.md b/CHANGELOG.md
new file mode 100644
index 0000000..7c8cc23
--- /dev/null
+++ b/CHANGELOG.md
@@ -0,0 +1,170 @@
+# Changelog
+
+## [1.6.0] - 2022-07-25 Maintenance Release - general updates
+
+General updates over the last two years, adding new scripts and updating existing in response to new
+needs or to adjust for changes to third-party software.
+
+### Added
+
+| Command | Description |
+| ------- | ----------- |
+| [psfcheckclassorders](docs/scripts.md#psfcheckclassorders) | Verify classes defined in xml have correct ordering where needed |
+| [psfcheckftml](docs/scripts.md#psfcheckftml) | Check ftml files for structural integrity |
+| [psfcheckglyphinventory](docs/scripts.md#psfcheckglyphinventory) | Warn for differences in glyph inventory and encoding between UFO and input file (e.g., glyph_data.csv) |
+| [psfcheckinterpolatable](docs/scripts.md#psfcheckinterpolatable) | Check UFOs in a designspace file are compatible with interpolation |
+| [psffixfontlab](docs/scripts.md#psffixfontlab) | Make changes needed to a UFO following processing by FontLab |
+| [psfsetdummydsig](docs/scripts.md#psfsetdummydsig) | Add a dummy DSIG table into a TTF font |
+| [psfsetglyphdata](docs/scripts.md#psfsetglyphdata) | Update and/or sort glyph_data.csv based on input file(s) |
+| [psfshownames](docs/scripts.md#psfshownames) | Display name fields and other bits for linking fonts into families |
+| [psfwoffit](docs/scripts.md#psfwoffit) | Convert between ttf, woff, and woff2 |
+
+### Changed
+
+Multiple changes!
+
+### Removed
+
+None
+
+## [1.5.0] - 2020-05-20 - Maintenance Release; Python 2 support removed
+
+Added support for Font Bakery to make it simple for projects to run a standard set ot checks designed to fit in
+with [Font Development Best Practices](https://silnrsi.github.io/FDBP/en-US/index.html).
+
+Improvements to feax support
+
+Many other updates
+
+### Added
+
+| Command | Description |
+| ------- | ----------- |
+| [psfftml2TThtml](docs/scripts.md#psfftml2TThtml) | Convert FTML document to html and fonts for testing TypeTuner |
+| [psfmakescaledshifted](docs/scripts.md#psfmakescaledshifted) | Creates scaled and shifted versions of glyphs |
+| [psfrunfbchecks](docs/scripts.md#psfrunfbchecks) | Run Font Bakery checks using a standard profile with option to specify an alternative profile |
+| [psfsetdummydsig](docs/scripts.md#psfsetdummydsig) | Put a dummy DSIG table into a TTF font |
+
+### Changed
+
+Multiple minor changes and bug fixes
+
+### Removed
+
+None
+
+## [1.4.2] - 2019-07-30 - Maintenance release
+
+Updated the execute() framework used by scripts to add support for opening fonts with fontParts and remove support for opening fonts with FontForge.
+
+Updates to normalization and check&fix to work better with FontForge-based workflows
+
+Improvements to command-line help to display info on params and default values
+
+Improvements to log file creation, including logs, by default, going to a logs sub-directory
+
+Some changes are detailed below, but check commit logs for full details.
+
+### Added
+
+| Command | Description |
+| ------- | ----------- |
+| [psfbuildcompgc](docs/scripts.md#psfbuildcompgc) | Add composite glyphs to UFO using glyphConstruction based on a CD file |
+| [psfdeflang](docs/scripts.md#psfdeflang) | Changes default language behaviour in a font |
+| [psfdupglyphs](docs/scripts.md#psfdupglyphs) | Duplicates glyphs in a UFO based on a csv definition |
+| [psfexportmarkcolors](docs/scripts.md#psfexportmarkcolors) | Export csv of mark colors |
+| [psffixffglifs](docs/scripts.md#psffixffglifs) | Make changes needed to a UFO following processing by FontForge |
+| [psfgetglyphnames](docs/scripts.md#psfgetglyphnames) | Create a file of glyphs to import from a list of characters to import |
+| [psfmakedeprecated](docs/scripts.md#psfmakedeprecated) | Creates deprecated versions of glyphs |
+| [psfsetmarkcolors](docs/scripts.md#psfsetmarkcolors) | Set mark colors based on csv file |
+| [psftuneraliases](docs/scripts.md#psftuneraliases) | Merge alias information into TypeTuner feature xml file |
+
+### Changed
+
+Multiple minor changes and bug fixes
+
+### Removed
+
+The following scripts moved from installed scripts to examples
+
+- ffchangeglyphnames
+- ffcopyglyphs
+- ffremovealloverlaps
+
+## [1.4.1] - 2019-03-04 - Maintenance release
+
+Nearly all scripts should work under Python 2 & 3
+
+**Future work will be tested just with Python 3** but most may still work with Python 2.
+
+Some changes are detailed below, but check commit logs for full details.
+
+### Added
+
+psfversion - Report version info for pysilfont, python and various dependencies
+psfufo2gylphs - Creates a .gypyhs file from UFOs using glyphsLib
+
+### Changed
+
+psfremovegliflibkeys now has -b option to remove keys beginning with specified string
+
+psfglyphs2ufo updated to match new psfufo2glyphs. Now has -r to restore specific keys
+
+Many changes to .fea support
+
+The pytest-based test setup has been expanded and refined
+
+### Removed
+
+Some scripts moved from installed scripts to examples
+
+## [1.4.0] - 2018-10-03 - Python 2+3 support
+
+### Added
+
+### Changed
+
+Libraries and most installed scripts updated to work with Python 2 and python 3
+
+All scripts should work as before under Python 2, but a few scripts need further work to run under Python 3:
+- All ff* scripts
+- psfaddanchors
+- psfcsv2comp
+- psfexpandstroke
+- psfsubset
+
+The following scripts have not been fully tested with the new libraries
+- psfchangegdlnames
+- psfcompdef2xml
+- psfcopymeta
+- psfexportpsnames
+- psfftml2odt
+- psfremovegliflibkeys
+- psfsetversion
+- psfsyncmeta
+- psftoneletters
+- psfxml2compdef
+
+### Removed
+
+## [1.3.1] - 2018-09-27 - Stable release prior to Python 2+3 merge
+
+### Added
+- psfcopyglyphs
+- psfcreateinstances
+- psfcsv2comp
+- psfmakefea
+- psfremovegliflibkeys
+- psfsetkeys
+- psfsubset
+
+Regression testing framework
+
+### Changed
+
+(Changes not documented here)
+
+### Removed
+
+
+## [1.3.0] - 2018-04-25 - First versioned release
diff --git a/LICENSE b/LICENSE
new file mode 100644
index 0000000..c7cc0a8
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,20 @@
+
+Copyright (c) 2015, SIL International (http://www.sil.org)
+Released under the MIT license cited below:
+
+Permission is hereby granted, free of charge, to any person obtaining a copy of
+this software and associated documentation files (the "Software"), to deal in
+the Software without restriction, including without limitation the rights to
+use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
+the Software, and to permit persons to whom the Software is furnished to do so,
+subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
+FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
diff --git a/MANIFEST.in b/MANIFEST.in
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/MANIFEST.in
diff --git a/README.md b/README.md
new file mode 100644
index 0000000..01d6aea
--- /dev/null
+++ b/README.md
@@ -0,0 +1,40 @@
+# Pysilfont - a collection of utilities for font development
+
+Pysilfont is a collection of tools to support font development, with an emphasis on UFO-based workflows. With some limitations, all UFO scripts in Pysilfont should work with UFO2 or UFO3 source files - and can convert from one format to the other.
+
+In addition, all scripts will output UFOs in a normalized form, designed to work with source control systems.
+
+Please read the main [documentation](docs/docs.md) in the docs folder for more details. Within there is a list of [scripts](docs/scripts.md).
+
+## Installation
+
+Pysilfont requires Python 3.6+ and pip3. Some scripts also need other libraries.
+
+### Simple install
+To just install the main scripts without cloning the github repository run:
+```
+sudo python3 -m pip install git+https://github.com/silnrsi/pysilfont
+```
+
+This will allow you to run the scripts listed in [scripts.md](docs/scripts.md), but won’t give access
+to the example scripts or give you the code locally to look at.
+
+### Full install
+
+First clone this repository or download the files from this [github URL](https://github.com/silnrsi/pysilfont).
+Then navigate to the resulting pysilfont directory and run:
+```
+sudo python3 -m pip install .
+```
+in the pysilfont directory
+
+### Uninstalling pysilfont
+
+pip3 can be used to uninstall pysilfont:
+```
+sudo pip3 uninstall pysilfont
+```
+
+## Contributing to the project
+
+Pysilfont is developed and maintained by SIL International’s [Writing Systems Technology team ](https://software.sil.org/wstech/), though contributions from anyone are welcome. Pysilfont is copyright (c) 2014-2022 [SIL International](http://www.sil.org) and licensed under the [MIT license](http://en.wikipedia.org/wiki/MIT_License). The project is hosted at [https://github.com/silnrsi/pysilfont](https://github.com/silnrsi/pysilfont).
diff --git a/actionsosx/README.txt b/actionsosx/README.txt
new file mode 100644
index 0000000..ac63546
--- /dev/null
+++ b/actionsosx/README.txt
@@ -0,0 +1,19 @@
+This folder contains actions for use in Mac OS X based on tools in pysilfont.
+
+UFO NORMALIZE
+
+This action takes a .ufo (Unified Font Object) and normalizes the file to standardize the formatting. Some of the changes include:
+ - standard indenting in the xml files
+ - sorting plists alphabetically
+ - uniform handling of capitals & underscores in glif filenames
+
+To install the UFO Normalize action:
+
+- install the pysilfont package using the steps in INSTALL.txt (important!)
+- double-click on UFO Normalize.workflow
+
+To use the UFO Normalize action:
+
+- right-click on a UFO file, and choose Services>UFO Normalize
+
+The action first makes a copy of the UFO in a backups subfolder.
diff --git a/actionsosx/UFO Normalize.workflow/Contents/Info.plist b/actionsosx/UFO Normalize.workflow/Contents/Info.plist
new file mode 100644
index 0000000..7e01663
--- /dev/null
+++ b/actionsosx/UFO Normalize.workflow/Contents/Info.plist
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+ <key>NSServices</key>
+ <array>
+ <dict>
+ <key>NSMenuItem</key>
+ <dict>
+ <key>default</key>
+ <string>UFO Normalize</string>
+ </dict>
+ <key>NSMessage</key>
+ <string>runWorkflowAsService</string>
+ <key>NSRequiredContext</key>
+ <dict>
+ <key>NSApplicationIdentifier</key>
+ <string>com.apple.finder</string>
+ </dict>
+ <key>NSSendFileTypes</key>
+ <array>
+ <string>public.item</string>
+ </array>
+ </dict>
+ </array>
+</dict>
+</plist>
diff --git a/actionsosx/UFO Normalize.workflow/Contents/QuickLook/Thumbnail.png b/actionsosx/UFO Normalize.workflow/Contents/QuickLook/Thumbnail.png
new file mode 100644
index 0000000..97fea58
--- /dev/null
+++ b/actionsosx/UFO Normalize.workflow/Contents/QuickLook/Thumbnail.png
Binary files differ
diff --git a/actionsosx/UFO Normalize.workflow/Contents/document.wflow b/actionsosx/UFO Normalize.workflow/Contents/document.wflow
new file mode 100644
index 0000000..d00336f
--- /dev/null
+++ b/actionsosx/UFO Normalize.workflow/Contents/document.wflow
@@ -0,0 +1,204 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+ <key>AMApplicationBuild</key>
+ <string>428</string>
+ <key>AMApplicationVersion</key>
+ <string>2.7</string>
+ <key>AMDocumentVersion</key>
+ <string>2</string>
+ <key>actions</key>
+ <array>
+ <dict>
+ <key>action</key>
+ <dict>
+ <key>AMAccepts</key>
+ <dict>
+ <key>Container</key>
+ <string>List</string>
+ <key>Optional</key>
+ <true/>
+ <key>Types</key>
+ <array>
+ <string>com.apple.cocoa.string</string>
+ </array>
+ </dict>
+ <key>AMActionVersion</key>
+ <string>2.0.3</string>
+ <key>AMApplication</key>
+ <array>
+ <string>Automator</string>
+ </array>
+ <key>AMParameterProperties</key>
+ <dict>
+ <key>COMMAND_STRING</key>
+ <dict/>
+ <key>CheckedForUserDefaultShell</key>
+ <dict/>
+ <key>inputMethod</key>
+ <dict/>
+ <key>shell</key>
+ <dict/>
+ <key>source</key>
+ <dict/>
+ </dict>
+ <key>AMProvides</key>
+ <dict>
+ <key>Container</key>
+ <string>List</string>
+ <key>Types</key>
+ <array>
+ <string>com.apple.cocoa.string</string>
+ </array>
+ </dict>
+ <key>ActionBundlePath</key>
+ <string>/System/Library/Automator/Run Shell Script.action</string>
+ <key>ActionName</key>
+ <string>Run Shell Script</string>
+ <key>ActionParameters</key>
+ <dict>
+ <key>COMMAND_STRING</key>
+ <string>for f in "$@"
+do
+ /usr/local/bin/psfnormalize "$f"
+done</string>
+ <key>CheckedForUserDefaultShell</key>
+ <true/>
+ <key>inputMethod</key>
+ <integer>1</integer>
+ <key>shell</key>
+ <string>/bin/bash</string>
+ <key>source</key>
+ <string></string>
+ </dict>
+ <key>BundleIdentifier</key>
+ <string>com.apple.RunShellScript</string>
+ <key>CFBundleVersion</key>
+ <string>2.0.3</string>
+ <key>CanShowSelectedItemsWhenRun</key>
+ <false/>
+ <key>CanShowWhenRun</key>
+ <true/>
+ <key>Category</key>
+ <array>
+ <string>AMCategoryUtilities</string>
+ </array>
+ <key>Class Name</key>
+ <string>RunShellScriptAction</string>
+ <key>InputUUID</key>
+ <string>A5DDB5A1-5587-4252-BDF2-2088FB0C18DA</string>
+ <key>Keywords</key>
+ <array>
+ <string>Shell</string>
+ <string>Script</string>
+ <string>Command</string>
+ <string>Run</string>
+ <string>Unix</string>
+ </array>
+ <key>OutputUUID</key>
+ <string>C1A7AC3D-90D6-472B-8DBA-C3F2CD74F083</string>
+ <key>UUID</key>
+ <string>C4284E07-22D9-4635-9306-D48F8EA7946F</string>
+ <key>UnlocalizedApplications</key>
+ <array>
+ <string>Automator</string>
+ </array>
+ <key>arguments</key>
+ <dict>
+ <key>0</key>
+ <dict>
+ <key>default value</key>
+ <integer>0</integer>
+ <key>name</key>
+ <string>inputMethod</string>
+ <key>required</key>
+ <string>0</string>
+ <key>type</key>
+ <string>0</string>
+ <key>uuid</key>
+ <string>0</string>
+ </dict>
+ <key>1</key>
+ <dict>
+ <key>default value</key>
+ <string></string>
+ <key>name</key>
+ <string>source</string>
+ <key>required</key>
+ <string>0</string>
+ <key>type</key>
+ <string>0</string>
+ <key>uuid</key>
+ <string>1</string>
+ </dict>
+ <key>2</key>
+ <dict>
+ <key>default value</key>
+ <false/>
+ <key>name</key>
+ <string>CheckedForUserDefaultShell</string>
+ <key>required</key>
+ <string>0</string>
+ <key>type</key>
+ <string>0</string>
+ <key>uuid</key>
+ <string>2</string>
+ </dict>
+ <key>3</key>
+ <dict>
+ <key>default value</key>
+ <string></string>
+ <key>name</key>
+ <string>COMMAND_STRING</string>
+ <key>required</key>
+ <string>0</string>
+ <key>type</key>
+ <string>0</string>
+ <key>uuid</key>
+ <string>3</string>
+ </dict>
+ <key>4</key>
+ <dict>
+ <key>default value</key>
+ <string>/bin/sh</string>
+ <key>name</key>
+ <string>shell</string>
+ <key>required</key>
+ <string>0</string>
+ <key>type</key>
+ <string>0</string>
+ <key>uuid</key>
+ <string>4</string>
+ </dict>
+ </dict>
+ <key>isViewVisible</key>
+ <true/>
+ <key>location</key>
+ <string>309.000000:253.000000</string>
+ <key>nibPath</key>
+ <string>/System/Library/Automator/Run Shell Script.action/Contents/Resources/English.lproj/main.nib</string>
+ </dict>
+ <key>isViewVisible</key>
+ <true/>
+ </dict>
+ </array>
+ <key>connectors</key>
+ <dict/>
+ <key>workflowMetaData</key>
+ <dict>
+ <key>serviceApplicationBundleID</key>
+ <string>com.apple.finder</string>
+ <key>serviceApplicationPath</key>
+ <string>/System/Library/CoreServices/Finder.app</string>
+ <key>serviceInputTypeIdentifier</key>
+ <string>com.apple.Automator.fileSystemObject</string>
+ <key>serviceOutputTypeIdentifier</key>
+ <string>com.apple.Automator.nothing</string>
+ <key>serviceProcessesInput</key>
+ <integer>0</integer>
+ <key>workflowTypeIdentifier</key>
+ <string>com.apple.Automator.servicesMenu</string>
+ </dict>
+</dict>
+</plist>
diff --git a/docs/composite.md b/docs/composite.md
new file mode 100644
index 0000000..ac6c9b7
--- /dev/null
+++ b/docs/composite.md
@@ -0,0 +1,106 @@
+# Defining composite glyphs
+
+A composite glyph is one that is defined in terms of one or more other glyphs.
+The composite definition syntax described in this document is a subset of the [GlyphConstruction](https://github.com/typemytype/GlyphConstruction) syntax used by Robofont, but with extensions for additional functionality.
+Composites defined in this syntax can be applied to a UFO using the [psfbuildcomp](scripts.md#psfbuildcomp) tool.
+
+# Overview
+
+Each composite definition is on a single line and has the format:
+```
+<result> = <one or more glyphs> <parameters> # comment
+```
+where
+- `<result>` is the name of the composite glyph being constructed
+- `<one or more glyphs>` represents one or more glyphs used in the construction of the composite glyph, with optional glyph-level parameters described below
+- `<parameters>` represents adjustments made to the `<result>` glyph, using the following optional parameters:
+ - at most one of the two following options:
+ - `^x,y` (where `x` is the amount added to the left margin and `y` is the amount added to the right margin)
+ - `^a` (where `a` is the advance width of the resulting glyph)
+ - `|usv` where `usv` is the 4-, 5- or 6-digit hex Unicode scalar value assigned to the resulting glyph
+ - `!colordef` (currently ignored by SIL tools)
+ - `[key1=value1;key2=value2;...]` to add one or more `key=value` pairs (representing SIL-specific properties documented below) to the resulting glyph
+- `# comment` is an optional comment (everything from the `#` to the end of the line is ignored)
+
+In addition, a line that begins with `#` is considered a comment and is ignored (as are blank lines).
+
+If `[key=value]` properties for the resulting glyph are specified but no `|usv` is specified, then a `|` must be included before the `[`.
+This insures that the properties are applied to the resulting composite glyph and not to the last glyph in the composite specification.
+
+# Examples
+
+In the following examples,
+- `glyph` represents the resulting glyph being constructed
+- `base`, `base1`, `base2` represent base glyphs being used in the construction
+- `diac`, `diac1`, `diac2` represent diacritic glyphs being used in the construction
+- `AP` represents an attachment point (also known as an anchor)
+
+## glyph = base
+```
+Minus = Hyphen
+```
+This defines one glyph (`Minus`) in terms of another (`Hyphen`), without having to duplicate the contours used to create the shape.
+
+## glyph = base1 & base2
+```
+ffi = f & f & i
+```
+This construct causes a glyph to be composed by aligning the origin of each successive base with the origin+advancewidth of the previous base. Unless overridden by the `^` parameter, the left sidebearing of the composite is that of the first base, the right sidebearing is that of the last, and the advancewidth of the composite is the sum of the advance widths of all the component base glyphs. [Unsure how this changes for right-to-left scripts]
+
+## glyph = base + diac@AP
+```
+Aacute = A + acute@U
+```
+The resulting composite has the APs of the base(s), minus any APs used to attach the diacritics, plus the APs of the diacritics (adjusted for any displacement, as would be the case for stacked diacritics). In this example, glyph `acute` attaches to glyph `A` at AP `U` on `A` (by default using the `_U` AP on `tilde`). The `U` AP from `A` is removed (as is the `_U` AP on the `tilde`) and the `U` AP from `acute` is added.
+
+Unless overridden by the `^` parameter, the advance width of the resulting composite is that of the base.
+
+## glyph = base + diac1@AP + diac2@APonpreviousdiac
+```
+Ocircumflexacute = O + circumflex@U + acute@U
+```
+The acute is positioned according to the `U` AP on the immediately preceding glyph (`circumflex`), not the `U` AP on the base (`O`).
+
+## glyph = base + diac@anyglyph:anyAP
+
+The syntax allows you to express diacritic positioning using any arbitrary AP on any arbitrary glyph in the font, for example:
+```
+barredOacute = barredO + acute@O:U # not supported
+```
+Current SIL tools, however, only support an `anyglyph` that appears earlier in the composite definition, so the above example is **not** supported.
+
+This syntax, however, makes it possible to override the default behavior of attaching to the immediately preceding glyph, so the following is supported (since the `@O:L` refers to the glyph `O` which appears earlier in the definition):
+```
+Ocircumflexdotaccent = O + circumflex@U + dotaccent@O:L
+```
+The `@O:L` causes the `dotaccent` diacritic to attach to the base glyph `O` (rather the immediately preceding `circumflex` glyph) using the `L` AP on the glyph `O` and the `_L` AP on the glyph `dotaccent`.
+
+## glyph = base + diac@AP | usv
+```
+Aacute = A + acute@U | 00C1
+```
+USV is always given as four- to six-digit hexadecimal number with no leading "U+" or "0x".
+
+## glyph = base + diac@AP ^ leftmarginadd,rightmarginadd
+```
+itilde = i + tilde@U ^ 50,50
+```
+This adds the values (in design units) to the left and right sidebearings. Note that these values could be negative.
+
+# SIL Extensions
+
+SIL extensions are all expressed as property lists (`key=value`) separated by semicolons and enclosed in square brackets: `[key1=value1;key2=value2]`.
+- Properties that apply to a glyph being used in the construction of the composite appear after the glyph.
+- Properties that apply to the resulting composite glyph appear after `|` (either that of the `|usv` or a single `|` if no `|usv` is present).
+
+## glyph = base + diac@atAP[with=AP]
+```
+Aacute = A + acute@Ucap[with=_U]
+```
+The `with` property can be used to override the default AP, \_AP convention. The `_U` attachment point on the `acute` glyph is paired with the `Ucap` attachment point on the
+
+## glyph = base + diac@AP[shift=x,y]
+
+Aacute = A + acute@U[shift=100,100]
+
+By applying the `shift` property to the `acute` glyph, the position of the diacritic relative to the base glyph `A` is changed.
diff --git a/docs/docs.md b/docs/docs.md
new file mode 100644
index 0000000..e8e2268
--- /dev/null
+++ b/docs/docs.md
@@ -0,0 +1,204 @@
+# Pysilfont - utilities for font development
+
+Pysilfont is a collection of tools to support font development, with an emphasis on [UFO](#ufo-support-in-pysilfont)-based workflows.
+
+In addition to the UFO utilities, there is also support for testing using [FTML](#font-test-markup-language) and [Composite Definitions](#composite-definitions).
+
+Some scripts are written specifically to fit in with the approaches recommended in [Font Development Best Practices](https://silnrsi.github.io/FDBP/en-US/index.html)
+
+# Documentation
+
+Documentation is held in the following documents:
+
+- docs.md: This document - the main document for users
+- [scripts.md](scripts.md): User documentation for all command-line tools and other scripts
+- [technical.md](technical.md): Technical details for those wanting write scripts or other development tasks
+- Other sub-documents, with links from the above
+
+Installation instructions are in [README.md](../README.md)
+
+# Scripts and commands
+Many Pysilfont scripts are installed to be used as command-line tools, and these are all listed, with usage instructions, in [scripts.md](scripts.md). This also has details of some other example python scripts.
+
+All scripts work using a standard framework designed to give users a consistent interface across scripts, and common features of these scripts are described in the following sections, so the **documentation below** needs to be read in conjunction with that in [scripts.md](scripts.md).
+
+## Standard command line options
+
+Nearly all scripts support these:
+
+- `-h, --help`
+ - Basic usage help for the command
+ - `-h d`
+ - Display -h info with added info about default values
+ - `-h p`
+ - Display information about parameters (-p --params below)
+- `-q, --quiet`
+ - Quiet mode - only display severe errors. See reporting below
+- `-l LOG, --log LOG`
+ - Log file name (if not using the default name). By default logs will go in a logs subdirectory. If just a directory path is given, the log will go in there using the default name.
+- `-p PARAMS, --params PARAMS`
+ - Other parameters - see below
+
+The individual script documentation in scripts.md should indicate if some don't apply for a particular script
+
+(There is also a hidden option --nq which overrides -q for use with automated systems like [smith](https://github.com/silnrsi/smith) which run scripts using -q by default)
+
+# Parameters
+
+There are many parameters that can be set to change the behaviour of scripts, either on the command line (using -p) or via a config file.
+
+To set a parameter on the command line, use ``-p <param name>=<param value>``, eg
+```
+psfnormalize font.ufo -p scrlevel=w
+```
+-p can be used multiple times on a single command.
+
+Commonly used command-line parameters include:
+- scrlevel, loglevel
+ - Set the screen/logfile level from increasingly verbose options
+ - E - Errors
+ - P - Progress (default for scrlevel)
+ - W - Warnings (default for loglevel)
+ - I - Information
+ - V - Verbose
+- checkfix (UFOs only)
+ - Validity tests when opening UFOs. Choice of None, Check, Fix with default Check
+ - See description of check & fix under [normalization](#normalization)
+
+For a full list of parameters and how to set them via a config file (or in a UFO font) see [parameters.md](parameters.md).
+
+
+## Default values
+
+Most scripts have defaults for file names and other arguments - except for the main file the script is running against.
+
+### Font/file name defaults
+
+Once the initial input file (eg input font) has been given, most other font and file names will have defaults based on those.
+
+This applies to other input font names, output font names, input file names and output file names and is done to minimise retyping repeated information like the path the files reside in. For example, simply using:
+
+```
+psfsetpsnames path/font.ufo
+```
+
+will:
+
+- open (and update) `path/font.ufo`
+- backup the font to `path/backups/font.ufo.nnn~`
+- read its input from `path/font_psnames.csv`
+- write its log to `path/logs/font_psnames.log`
+
+If only part of a file name is supplied, other parts will default. So if only "test" is supplied for the output font name, the font would be output to `path/test.ufo`.
+
+If a full file name is supplied, but no path, the current working directory will be used, so if “test.ufo” is supplied it won’t have `path/` added.
+
+### Other defaults
+
+Other parameters will just have standard default values.
+
+### Displaying defaults for a command
+
+Use `-h d` to see what defaults are for a given command. For example,
+
+```
+psfsetpsnames -h d
+```
+
+will output its help text with the following appended:
+
+```
+Defaults for parameters/options
+
+ Font/file names
+ -i _PSnames.csv
+ -l _PSnames.log
+```
+
+If the default value starts with “\_” (as with \_PSnames.csv above) then the input file name will be prepended to the default value; otherwise just the default value will be used.
+
+## Reporting
+Most scripts support standardised reporting (logging), both to screen and a log file, with different levels of reporting available. Levels are set for via loglevel and scrlevel parameters which can be set to one of:
+- E Errors
+- P Progress - Reports basic progress messages and all errors
+- W Warning - As P but with warning messages as well
+- I Info - As W but with information messages as well
+- V Verbose - even more messages!
+
+For most scripts these default to W for loglevel and P for scrlevel and can be set using -p (eg to set screen reporting to verbose use -p scrlevel=v).
+
+-q --quiet sets quiet mode where all normal screen messages are suppressed. However, if there are any errors during the script execution, a single message is output on completion listing the counts for errors and warnings.
+
+## Backups for fonts
+
+If the output font name is the same as the input font name (which is the default behaviour for most scripts), then a backup is made original font prior to updating it.
+
+By default, the last 5 copies of backups are kept in a sub-directory called “backups”. These defaults can be changed using the following parameters:
+
+- `backup` - if set to 0, no backups are done
+- `backupdir` - alternative directory for backups
+- `backupkeep` - number of backups to keep
+
+# UFO support in Pysilfont
+With some limitations, all UFO scripts in Pysilfont should work with UFO2 or UFO3 source files - and can convert from one format to the other.
+
+In addition most scripts will output in a normalized form, designed to work with source control systems. Most aspects of the normalization can be set by parameters, so projects are not forced to use Pysilfont’s default normalization.
+
+The simplest script is psfnormalize, which will normalize a UFO (and optionally convert between UFO 2 and UFO3 if -v is used to specify the alternative version)
+
+Note that other scripts also normalize, so psfnormalize is usually only needed after fonts have been processed by external font tools.
+
+## Normalization
+By default scripts normalize the UFOs and also run various check & fix tests to ensure the validity of the UFO metadata.
+
+Default normalization behaviours include:
+- XML formatting
+ - Use 2 spaces as indents
+ - Don’t indent the ``<dict>`` for plists
+ - Sort all ``<dict>``s in ascending key order
+ - Where values can be “integer or float”, store integer values as ``<integer>``
+ - Limit ``<real>`` limit decimal precision to 6
+ - For attributes identified as numeric, limit decimal precision to 6
+- glif file names - use the UFO 3 suggested algorithm, even for UFO 2 fonts
+- order glif elements and attributes in the order they are described in the UFO spec
+
+Most of the above can be overridden by [parameters](#parameters)
+
+The check & fix tests are based on [Font Development Best Practices](https://silnrsi.github.io/FDBP/en-US/index.html) and include:
+- fontinfo.plist
+ - Required fields
+ - Fields to be deleted
+ - Fields to constructed from other fields
+ - Specific recommended values for some fields
+- lib.plist
+ - Required fields
+ - Recommended values
+ - Fields that should not be present
+
+The check & fix behaviour can be controlled by [parameters](#parameters), currently just the checkfix parameter which defaults to 'check' (just report what is wrong), but can be set to 'fix' to fix what it can, or none for no checking.
+
+## Known limitations
+The following are known limitations that will be addressed in the future:
+- UFO 3 specific folders (data and images) are preserved, even if present in a UFO 2 font.
+- Converting from UFO 3 to UFO 2 only handles data that has a place in UFO 2, but does include converting UFO 3 anchors to the standard way of handling them in UFO 2
+- If a project uses non-standard files within the UFO folder, they are deleted
+
+# Font Test Markup Language
+
+Font Test Markup Language (FTML) is a file format for specifying the content and structure of font test data. It is designed to support complex test data, such as strings with specific language tags or data that should presented with certain font features activated. It also allows for indication of what portions of test data are in focus and which are only present to provide context.
+
+FTML is described in the [FTML github project](https://github.com/silnrsi/ftml).
+
+Pysilfont includes some python scripts for working with FTML, and a python library, [ftml.py](technical.md#ftml.py), so that new scripts can be developed to read and write FTML files.
+
+# Composite definitions
+
+Pysilfont includes tools for automatically adding composite glyphs to fonts. The syntax used for composite definitions is a subset of that used by RoboFont plus some extensions - see [Composite Tools](https://silnrsi.github.io/FDBP/en-US/Composite_Tools.html) in the Font Development Best Practices documentation for more details.
+
+The current tools (psfbuildcomp, psfcomp2xml and psfxml2comp) are documented in [scripts.md](scripts.md).
+
+The tools are based on a python module, [comp.py](technical.md#comppy).
+
+# Contributing to the project
+
+Pysilfont is developed and maintained by SIL International’s [Writing Systems Technology team ](https://software.sil.org/wstech/), though contributions from anyone are welcome. Pysilfont is copyright (c) 2014-2017 [SIL International](http://www.sil.org) and licensed under the [MIT license](http://en.wikipedia.org/wiki/MIT_License). The project is hosted at [https://github.com/silnrsi/pysilfont](https://github.com/silnrsi/pysilfont).
diff --git a/docs/examples.md b/docs/examples.md
new file mode 100644
index 0000000..de5212b
--- /dev/null
+++ b/docs/examples.md
@@ -0,0 +1,236 @@
+# Pysilfont example scripts
+
+In addition to the main pysilfont [scripts](scripts.md), there are many further scripts under pysilfont/examples and its sub-directories.
+
+They are not maintained in the same way as the main scripts, and come in many categories including:
+
+- Scripts under development
+- Examples of how to do things
+- Deprecated scripts
+- Left-overs from previous development plans!
+
+Note - all FontForge-based scripts need updating, since FontForge (as "FF") is no longer a supported tool for execute()
+
+Some are documented below.
+
+## Table of scripts
+
+| Command | Status | Description |
+| ------- | ------ | ----------- |
+| [accesslibplist.py](#accesslibplist) | ? | Demo script for accessing fields in lib.plist |
+| [chaindemo.py](#chaindemo) | ? | Demo of how to chain calls to multiple scripts together |
+| [ffchangeglyphnames](#ffchangeglyphnames) | ? | Update glyph names in a ttf font based on csv file |
+| [ffcopyglyphs](#ffcopyglyphs) | ? | Copy glyphs from one font to another, without using ffbuilder |
+| [ffremovealloverlaps](#ffremovealloverlaps) | ? | Remove overlap on all glyphs in a ttf font |
+| [FFmapGdlNames.py](#ffmapgdlnames) | ? | Write mapping of graphite names to new graphite names |
+| [FFmapGdlNames2.py](#ffmapgdlnames2) | ? | Write mapping of graphite names to new graphite names |
+| [FLWriteXml.py](#flwritexml) | ? | Outputs attachment point information and notes as XML file for TTFBuilder |
+| [FTaddEmptyOT.py](#ftaddemptyot) | ? | Add empty Opentype tables to ttf font |
+| [FTMLnorm.py](#ftmlnorm) | ? | Normalize an FTML file |
+| [psfaddGlyphDemo.py](#psfaddglyphdemo) | ? | Demo script to add a glyph to a UFO font |
+| [psfexpandstroke.py](#psfexpandstroke) | ? | Expands an unclosed UFO stroke font into monoline forms with a fixed width |
+| [psfexportnamesunicodesfp.py](#psfexportnamesunicodesfp) | ? | Outputs an unsorted csv file containing the names of all the glyphs in the default layer |
+| [psfgenftml.py](#psfgenftml) | ? | generate ftml tests from glyph_data.csv and UFO |
+| [psftoneletters.py](#psftoneletters) | ? | Creates Latin script tone letters (pitch contours) |
+| [xmlDemo.py](#xmldemo) | ? | Demo script for use of ETWriter |
+
+
+---
+#### accesslibplist
+Usage: **` python accesslibplist.py ...`**
+
+_([Standard options](docs.md#standard-command-line-options) may also apply)_
+
+Demo script for accessing fields in lib.plist
+
+
+---
+#### chaindemo
+Usage: **` python chaindemo.py ...`**
+
+_([Standard options](docs.md#standard-command-line-options) also apply)_
+
+Demo of how to chain calls to multiple scripts together.
+Running
+
+`python chaindemo.py infont outfont --featfile feat.csv --uidsfile uids.csv`
+
+will run execute() against psfnormalize, psfsetassocfeat and psfsetassocuids passing the font, parameters
+and logger objects from one call to the next. So:
+- the font is only opened once and written once
+- there is a single log file produced
+
+
+---
+#### ffchangeglyphnames
+Usage: **`ffchangeglyphnames [-i INPUT] [--reverse] ifont [ofont]`**
+
+_([Standard options](docs.md#standard-command-line-options) also apply)_
+
+Update the glyph names in a ttf font based on csv file.
+
+Example usage:
+
+```
+ffchangeglyphnames -i glyphmap.csv font.ttf
+```
+will update the glyph names in the font based on mapping file glyphmap.csv
+
+If \-\-reverse is used, it change names in reverse.
+
+---
+#### ffcopyglyphs
+Usage: **`ffcopyglyphs -i INPUT [-r RANGE] [--rangefile RANGEFILE] [-n NAME] [--namefile NAMEFILE] [-a] [-f] [-s SCALE] ifont [ofont]`**
+
+_([Standard options](docs.md#standard-command-line-options) also apply)_
+
+_This section is Work In Progress!_
+
+optional arguments:
+
+```
+ -h, --help show this help message and exit
+ -i INPUT, --input INPUT
+ Font to get glyphs from
+ -r RANGE, --range RANGE
+ StartUnicode..EndUnicode no spaces, e.g. 20..7E
+ --rangefile RANGEFILE
+ File with USVs e.g. 20 or a range e.g. 20..7E or both
+ -n NAME, --name NAME Include glyph named name
+ --namefile NAMEFILE File with glyph names
+ -a, --anchors Copy across anchor points
+ -f, --force Overwrite existing glyphs in the font
+ -s SCALE, --scale SCALE
+ Scale glyphs by this factor
+```
+
+---
+#### ffremovealloverlaps
+Usage: **`ffremovealloverlaps ifont [ofont]`**
+
+_([Standard options](docs.md#standard-command-line-options) also apply)_
+
+Remove overlap on all glyphs in a ttf font
+
+---
+#### FFmapGdlNames
+Usage: **` python FFmapGdlNames2.py ...`**
+
+_([Standard options](docs.md#standard-command-line-options) may also apply)_
+
+Write mapping of graphite names to new graphite names based on:
+ - two ttf files
+ - the gdl files produced by makeGdl run against those fonts
+ This could be different versions of makeGdl
+ - a csv mapping glyph names used in original ttf to those in the new font
+
+
+---
+#### FFmapGdlNames2
+Usage: **` python FFmapGdlNames.py ...`**
+
+_([Standard options](docs.md#standard-command-line-options) may also apply)_
+
+Write mapping of graphite names to new graphite names based on:
+ - an original ttf font
+ - the gdl file produced by makeGdl when original font was produced
+ - a csv mapping glyph names used in original ttf to those in the new font
+ - pysilfont's gdl library - so assumes pysilfonts makeGdl will be used with new font
+
+
+---
+#### FLWriteXml
+Usage: **` python FLWriteXml.py ...`**
+
+_([Standard options](docs.md#standard-command-line-options) may also apply)_
+
+Outputs attachment point information and notes as XML file for TTFBuilder
+
+
+---
+#### FTaddEmptyOT
+Usage: **` python FTaddEmptyOT.py ...`**
+
+_([Standard options](docs.md#standard-command-line-options) may also apply)_
+
+Add empty Opentype tables to ttf font
+
+
+---
+#### FTMLnorm
+Usage: **` python FTMLnorm.py ...`**
+
+_([Standard options](docs.md#standard-command-line-options) may also apply)_
+
+Normalize an FTML file
+
+
+---
+#### psfaddGlyphDemo
+Usage: **` python psfaddGlyphDemo.py ...`**
+
+_([Standard options](docs.md#standard-command-line-options) may also apply)_
+
+Demo script to add a glyph to a UFO font
+
+
+---
+#### psfexpandstroke
+
+Usage: **`psfexpandstroke infont outfont expansion`**
+
+_([Standard options](docs.md#standard-command-line-options) also apply)_
+
+Expands the outlines (typically unclosed) in an UFO stroke font into monoline forms with a fixed width.
+
+Example that expands the stokes in a UFO font `SevdaStrokeMaster-Regular.ufo` by 13 units on both sides, giving them a total width of 26 units, and writes the result to `Sevda-Regular.ufo`.
+
+```
+psfexpandstroke SevdaStrokeMaster-Regular.ufo Sevda-Regular.ufo 13
+```
+
+Note that this only expands the outlines - it does not remove any resulting overlap.
+
+
+---
+#### psfexportnamesunicodesfp
+Usage: **` python psfexportnamesunicodesfp.py ...`**
+
+_([Standard options](docs.md#standard-command-line-options) may also apply)_
+
+Outputs an unsorted csv file containing the names of all the glyphs in the default layer and their primary unicode values.
+
+Format name,usv
+
+
+---
+#### psfgenftml
+Usage: **` python psfgenftml.py ...`**
+
+_([Standard options](docs.md#standard-command-line-options) may also apply)_
+
+generate ftml tests from glyph_data.csv and UFO
+
+
+---
+#### psftoneletters
+Usage: **`psftoneletters infont outfont`**
+
+_([Standard options](docs.md#standard-command-line-options) also apply)_
+
+This uses the parameters from the UFO lib.plist org.sil.lcg.toneLetters key to create Latin script tone letters (pitch contours).
+
+Example usage:
+
+```
+psftoneletters Andika-Regular.ufo Andika-Regular.ufo
+```
+
+
+---
+#### xmlDemo
+Usage: **` python xmlDemo.py ...`**
+
+_([Standard options](docs.md#standard-command-line-options) may also apply)_
+
+Demo script for use of ETWriter
diff --git a/docs/fea2_proposal.md b/docs/fea2_proposal.md
new file mode 100644
index 0000000..aa3ae99
--- /dev/null
+++ b/docs/fea2_proposal.md
@@ -0,0 +1,150 @@
+# Proposed Extensions to FEA
+
+This document describes a macro extension to FEA that will enable it to grow
+and support more powerful OpenType descriptions. The proposal is presented as
+various syntax extensions to the core FEA syntax.
+
+## Functions
+
+Currently FEA makes no use of parentheses. This may be a conscious decision to
+reserve these for later ues. Such parentheses lend themselves perfectly to the
+addition of macro functions to the FEA syntax:
+
+```
+function = funcname '(' (parameter (',' parameter)*)? ')'
+
+funcname = /[A-Za-z_.][A-Za-z_0-9.]*/
+parameter = glyph | glyphlist | classref | value_record | function
+ | ('"' string '"') | ("{" tokens "}")
+tokens = noncurlytoken* | ("{" tokens "}")
+glyphlist = '[' glyph* ']'
+classref = '@' classname
+value_record = number | '<' chars '>'
+```
+
+A function call consists of a function name and a parenthesised parameter list,
+which may be empty.
+
+
+ and an optional following token list enclosed in braces. The
+token list is just that, an unparsed sequence of lexical tokens. The result of
+the function is also an unparsed sequence of lexical tokens that are then parsed
+and processed as if the function were replaced by a textual representation of
+the tokens.
+
+The parameters are parsed, so for example a classref would expand to its
+resulting list of glyphs. Likewise a function call result would be parsed to its
+single semantic item, it is not parsed as a token list. A value_record is the
+widest interpretation of a value record, including an anchor. Basically it is
+either a number or anything between < and >.
+
+A function statement is the use of a function result as a statement in the FEA
+syntax.
+
+The FEA syntax defines nothing more that functions exist and how they may be
+referenced. It is up to a particular FEA processor to supply the functions and
+to execute them to resolve them to a token list. It is also up to the particular
+FEA processor to report an error or otherwise handle an unknown function
+reference. As such this is similar to other programming languages where the
+language itself says nothing about what functions exist or what they do. That is
+for libraries.
+
+There is one exception. The `include` statement in the core FEA syntax follows
+the same syntax, apart from the missing quotation marks around the filename. As
+such `include` is not available for use as a function name.
+
+### Sample Implementation
+
+In this section we give a sample implementation based on the FEA library in
+fonttools.
+
+Functions are kept in module style namespaces, much like a simplified python module
+system. A function name then typically consists of a `modulename.funcname` The
+top level module is reserved for the fea processor itself. The following
+functions are defined in the top level module (i.e. no modulename.)
+
+#### load
+
+The `load` function takes a path to a file containing python definitions.
+Whether this python code is preprocessed for security purposes or not is an open
+question. It also takes a modulename as its second parameter.
+
+```
+load("path/to/pythonfile.py", "mymodule")
+```
+
+The function returns an empty token string but has the effect of loading all the
+functions defined in the python file as those functions prefixed by the
+modulename, as described above.
+
+#### set
+
+This sets a variable to a token list. Variables are described in a later syntax
+extension. The first parameter is the name of a variable. The token list is then
+used for the variable expansion.
+
+```
+set("distance") { 30 };
+```
+
+Other non top level module may be supplied with the core FEA processing module.
+
+#### core.refilter
+
+This function is passed a glyphlist (or via a classref) and a regular
+expression. The result is a glyphlist consisting of all the glyphs whose name
+matches the regular expression. For example:
+
+```
+@csc = core.refilter("\.sc$", @allglyphs)
+```
+
+#### core.pairup
+
+This function is passed two classnames, a regular expression and a glyph list.
+The result is two class definitions for the two classnames. One class is
+of all the glyphs which match the regular expression. The other class is a
+corresponding list of glyphs whose name is the same as the matching regular
+expression with the matching regular expression text removed. If no such glyph
+exists in the font, then neither the name or the glyph matching the regular
+expression is included. The resulting classes may therefore be used in a simple
+substitution. For example:
+
+```
+core.pairup("cnosc", "csc", "\.sc$", [a.sc b.sc fred.sc]);
+lookup smallcap {
+ sub @cnosc by @csc;
+} smallcap;
+```
+
+Assuming `fred.sc` exists but `fred` does not, this is equivalent to:
+
+```
+@cnosc = [a b];
+@csc = [a.sc b.sc];
+lookup smallcap {
+ sub @cnosc by @csc;
+} smallcap;
+```
+
+## Variables
+
+A further extension to the FEA syntax is to add a simple variable expansion. A
+variable expands to a token list. Since variables may occur anywhere they need a
+syntactic identifier. The proposed identifier is an initial `$`.
+
+```
+variable = '$' funcname
+```
+
+Variables are expanded at the point of expansion. Since expansion is recursive,
+the variable may contain a function call which expands when the variable
+expands.
+
+There is no syntax for defining a variable. This is unnatural and may be
+revisited if a suitable syntax can be found. Definition is therefore a processor
+specific activity.
+
+It is undecided whether undefined variables expand to an empty token list or an
+error.
+
diff --git a/docs/feaextensions.md b/docs/feaextensions.md
new file mode 100644
index 0000000..65f3eb9
--- /dev/null
+++ b/docs/feaextensions.md
@@ -0,0 +1,518 @@
+# FEA Extensions Current
+
+This document describes the functionality of `psfmakefea` and lists the extensions to fea that are currently supported.
+<!-- TOC -->
+
+- [Generated Classes](#generated-classes)
+ - [Variant glyph classes](#variant-glyph-classes)
+ - [Ligatures](#ligatures)
+- [Statements](#statements)
+ - [baseclass](#baseclass)
+ - [Cursive Attachment](#cursive-attachment)
+ - [Mark Attachment](#mark-attachment)
+ - [Ligature Attachment](#ligature-attachment)
+ - [ifinfo](#ifinfo)
+ - [ifclass](#ifclass)
+ - [do](#do)
+ - [SubStatements](#substatements)
+ - [for](#for)
+ - [let](#let)
+ - [if](#if)
+ - [Examples](#examples)
+ - [Simple calculation](#simple-calculation)
+ - [More complex calculation](#more-complex-calculation)
+ - [Right Guard](#right-guard)
+ - [Left Guard](#left-guard)
+ - [Left Kern](#left-kern)
+ - [Myanmar Great Ya](#myanmar-great-ya)
+ - [Advance for Ldot on U](#advance-for-ldot-on-u)
+ - [def](#def)
+ - [python support](#python-support)
+ - [kernpairs](#kernpairs)
+- [Capabilities](#capabilities)
+ - [Permit classes on both sides of GSUB type 2 (multiple) and type 4 (ligature) lookups](#permit-classes-on-both-sides-of-gsub-type-2-multiple-and-type-4-ligature-lookups)
+ - [Processing](#processing)
+ - [Example](#example)
+ - [Support classes in alternate lookups](#support-classes-in-alternate-lookups)
+ - [groups.plist](#groupsplist)
+
+<!-- /TOC -->
+## Generated Classes
+
+`psfmakefea` simplifies the hand creation of fea code by analysing the glyphs in the input font, particularly with regard to their names. Names are assumed to conform to the Adobe Glyph List conventions regarding `_` for ligatures and `.` for glyph variants.
+
+### Variant glyph classes
+
+If a font contains a glyph with a final variant (there may be more than one listed for a glyph, in sequence) and also a glyph without that final variant, then `psfmakefea` will create two classes based on the variant name: @c\__variant_ contains the glyph with the variant and @cno\__variant_ contains the glyph without the variant. The two lists are aligned such that a simple classes based replacement will change all the glyphs without the variant into ones with the variant.
+
+For example, U+025B is an open e that occurs in some African languages. Consider a font that contains the glyphs `uni025B` and `uni025B.smcp` for a small caps version of the glyph. `psfmakefea` will create two classes:
+
+```
+@c_smcp = [uni025B.scmp];
+@cno_smcp = [uni025B];
+```
+
+In addition, if this font contains two other glyphs `uni025B.alt`, an alternative shape to `uni025B` and `uni025B.alt.smcp`, the small caps version of the alternate. `psfmakefea` will create the following classes:
+
+```
+@c_smcp = [uni025B.scmp uni025B.alt.smcp];
+@cno_smcp = [uni025B uni025B.alt];
+@c_alt = [uni025B.alt];
+@cno_alt = [uni025B];
+```
+
+Notice that the classes with multiple glyphs, while keeping the alignment, do not guarantee any particular order of the glyphs in one of the classes. Only that the other class will align its glyph order correctly. Notice also that `uni025B.alt.smcp` does not appear in the `@c_alt` class. This latter behaviour may change.
+
+### Ligatures
+
+Unless instructed on the command line via the `-L` or `--ligmode` option, `psfmakefea` does nothing special with ligatures and treats them simply as glyphs that may take variants. There are four ligature modes. The most commonly used is `-L last`. This says to create classes based on the last components in all ligatures. Thus if the font from the previous section also included `uni025B_acutecomb` and the corresponding small caps `uni025B_acutecomb.smcp`. We also need an `acutecomb`. If the command line included `-L last`, the generated classes would be:
+
+```
+@c_smcp = [uni025B.scmp uni025B.alt.smcp uni025B_acutecomb.smcp];
+@cno_smcp = [uni025B uni025B.alt uni025B_acutecomb];
+@c_alt = [uni025B.alt];
+@cno_alt = [uni025B];
+@clig_acutecomb = [uni025B_acutecomb];
+@cligno_acutecomb = [uni025B];
+```
+
+And if the command line option were `-L first`, the last two lines of the above code fragment would become:
+
+```
+@clig_uni025B = [uni025B_acutecomb];
+@cligno_uni025B = [acutecomb];
+```
+
+while the variant classes would remain the same.
+
+There are two other ligaturemodes: `lastcomp` and `firstcomp`. These act like `last` and `first`, but in addition they say that any final variants must be handled differently. Instead of seeing the final variants (those on the last ligature component) as applying to the whole ligature, they are only to be treated as applying to the last component. To demonstrate this we need to add the nonsensical `acutecomb.smcp`. With either `-L last` or `-L first` we get the same ligature classes as above. (Although we would add `acutecomb.smcp` to the `@c_smcp` and `acutecomb` to `@cno_smcp`) With `-L firstcomp` we get:
+
+```
+@c_smcp = [uni025B.scmp uni025B.alt.smcp acutecomb.smcp];
+@cno_smcp = [uni025B uni025B.alt acutecomb];
+@c_alt = [uni025B.alt];
+@cno_alt = [uni025B];
+@clig_uni025B = [uni025B_acutecomb uni025B_acutecomb.smcp];
+@cligno_uni025B = [acutecomb acutecomb.smcp];
+```
+
+Notice the removal of `uni025B_acutecomb.smcp` from `@c_smcp`, since `uni025B_acutecomb.smcp` is considered by `-L firstcomp` to be a ligature of `uni025B` and `acutecomb.smcp` there is no overall ligature `uni025B_acutecomb` with a variant `.smcp` that would fit into `@c_smcp`. If we use `-L lastcomp` we change the last two classes to:
+
+```
+@clig_acutecomb = [uni025B_acutecomb];
+@cligno_acutecomb = [uni025B];
+@clig_acutecomb_smcp = [uni025B_acutecomb.smcp];
+@cligno_acutecomb_smcp = [un025B];
+```
+
+With any `.` in the variant being changed to `_` in the class name.
+
+In our example, if the author wanted to use `-L lastcomp` or `-L firstcomp`, they might find it more helpful to rename `uni025B_acutecomb.smcp` to `uni025B.smcp_acutecomb` and remove the nonsensical `acutecomb.smcp`. This would give, for `-L lastcomp`:
+
+```
+@c_smcp = [uni025B.scmp uni025B.alt.smcp];
+@cno_smcp = [uni025B uni025B.alt];
+@c_alt = [uni025B.alt];
+@cno_alt = [uni025B];
+@clig_acutecomb = [uni025B_acutecomb uni025B.smcp_acutecomb];
+@cligno_acutecomb = [uni025B uni025B.smcp];
+```
+
+and for `-L firstcomp`, the last two classes become:
+
+```
+@clig_uni025B = [uni025B_acutecomb];
+@cligno_uni025B = [acutecomb];
+@clig_uni025B_smcp = [uni025B.smcp_acutecomb];
+@cligno_uni025B_smcp = [acutecomb];
+```
+
+## Statements
+
+### baseclass
+
+A baseclass is the base equivalent of a markclass. It specifies the position of a particular class of anchor points on a base, be that a true base or a mark base. The syntax is the same as for a markclass, but it is used differently in a pos rule:
+
+```
+markClass [acute] <anchor 350 0> @TOP_MARKS;
+baseClass [a] <anchor 500 500> @BASE_TOPS;
+baseClass b <anchor 500 750> @BASE_TOPS;
+
+feature test {
+ pos base @BASE_TOPS mark @TOP_MARKS;
+} test;
+```
+
+Which is the functional equivalent of:
+
+```
+markClass [acute] <anchor 350 0> @TOP_MARKS;
+
+feature test {
+ pos base [a] <anchor 500 500> mark @TOP_MARKS;
+ pos base b <anchor 500 750> mark @TOP_MARKS;
+} test;
+```
+
+It should be borne in mind that both markClasses and baseClasses can also be used as normal glyph classes and as such use the same namespace.
+
+The baseClass statement is a high priority need in order to facilitate auto generation of attachment point information without having to create what might be redundant lookups in the wrong order.
+
+Given a set of base glyphs with attachment point A and marks with attachment point \_A, psfmakefea will generate the following:
+
+- baseClass A - containing all bases with attachment point A
+- markClass \_A - containing all marks with attachment point \_A
+- baseClass A\_MarkBase - containing all marks with attachment point A
+
+#### Cursive Attachment
+
+Cursive attachment involves two base anchors, one for the entry and one for the exit. We can extend the use of baseClasses to support this, by passing two baseClasses to the pos cursive statement:
+
+```
+baseClass meem.medial <anchor 700 50> @ENTRIES;
+baseClass meem.medial <anchor 0 10> @EXITS;
+
+feature test {
+ pos cursive @ENTRIES @EXITS;
+} test;
+```
+
+Here we have two base classes for the two anchor points, and the pos cursive processing code works out which glyphs are in both classes, and which are in one or the other and generates the necessary pos cursive statement for each glyph. I.e. there will be statements for the union of the two classes but with null anchors for those only in one (according to which baseClass they are in). This has the added advantage that any code generating baseClasses does not need to know whether a particular attachment point is being used in a cursive attachment. That is entirely up to the user of the baseClass.
+
+#### Mark Attachment
+
+The current mark attachment syntax is related to the base mark attachment in that the base mark has to be specified explicitly and we cannot currently use a markclass as the base mark in a mark attachment lookup. We can extend the mark attachment in the same way as we extend the base attachment, by allowing the mark base to be a markclass. Thus:
+
+```
+pos mark @MARK_BASE_CLASS mark @MARK_MARK_CLASS;
+```
+
+Would expand out to a list of mark mark attachment rules.
+
+#### Ligature Attachment
+
+Ligature attachment involves all the attachments to a ligature in a single rule. Given a list of possible ligature glyphs, the ligature positioning rule has been extended to allow the use of baseClasses instead of the base anchor on the ligature. For a noddy example:
+
+```
+baseClass a <anchor 200 200> @TOP_1;
+baseClass fi <anchor 200 0> @BOTTOM_1;
+baseClass fi <anchor 400 0> @BOTTOM_2;
+markClass acute <anchor 0 200> @TOP;
+markClass circumflex <anchor 200 0> @BOTTOM;
+
+pos ligature [a fi] @BOTTOM_1 mark @BOTTOM @TOP_1 mark @TOP
+ ligComponent @BOTTOM_2 mark @BOTTOM;
+```
+
+becomes
+
+```
+pos ligature a <anchor 200 200> mark @TOP
+ ligComponent <anchor NULL>;
+pos ligature fi <anchor 200 0> mark @BOTTOM
+ ligComponent <anchor 400 0> mark @BOTTOM;
+```
+
+### ifinfo
+
+This statement initiates a block either of statements or within another block. The block is only processed if the ifinfo condition is met. ifinfo takes two parameters. The first is a name that is an entry in a fontinfo.plist. The second is a string containing a regular expression that is matched against the given value in the fontinfo.plist. If there is a match, the condition is considered to be met.
+
+```
+ifinfo(familyName, "Doulos") {
+
+# statements
+
+}
+```
+
+Notice the lack of a `;` after the block close.
+
+ifinfo acts as a kind of macro, this means that the test is executed in the parser rather than collecting everything inside the block and processing it later like say the `do` statement. Notice that if you want to do something more complex than a regular expression test, then you may need to use a `do` statement and the `info()` function.
+
+### ifclass
+
+This statement initiates a block either of statements or within another block. The block is only processed if the given @class is defined and contains at least one glyph.
+
+```
+ifclass(@oddities) {
+
+# statements
+
+}
+```
+
+Notice the lack of a `;` after the block close.
+
+### do
+
+The `do` statement is a means of setting variables and repeating statement groups with variable expansion. A `do` statement is followed by various substatements that are in effect nested statements. The basic structure of the `do` statement is:
+
+`do` _substatement_ _substatement_ _..._ [ `{` _statements_ `}` ]
+
+Where _statements_ is a sequence of FEA statements. Within these statements, variables may be referenced by preceding them with a `$`. Anything, including statement words, can be the result of variable expantion. The only constraints are:
+
+- The item expands to one or more complete tokens. It cannot be joined to something preceding or following it to create a single name, token, whatever.
+
+In effect a `{}` type block following a `for` or `let` substatement is the equivalent of inserting the substatement `if True;` before the block.
+
+#### SubStatements
+
+Each substatement is terminated by a `;`. The various substatements are:
+
+##### for
+
+The `for` substatement is structured as:
+
+`for` _var_ `=` _glyphlist_ `;`
+
+This creates a variable _var_ that will iterate over the _glyphlist_.
+
+##### let
+
+The `let` substatement executes a short python expression (via `eval`), storing the result in the given variable, or variable list. The structure of the substatement is:
+
+`let` _var_ [`,` _var_]* `=` _expression_ `;`
+
+There are various python functions that are especially supported, along with the builtins. These are:
+
+| Function | Parameters | Description |
+|-------------|----------------|----------------|
+| ADVx | _glyphname_ | Returns the advanced width of the given glyph |
+| allglyphs | | Returns a list of all the glyph names in the font |
+| APx | _glyphname_, "_apname_" | Returns the x coordinate of the given attachment point on the given glyph |
+| APy | _glyphname_, "_apname_" | Returns the y coordinate of the given attachment point on the given glyph |
+| feaclass | _classname_ | Returns a list of the glyph names in a class as a python list |
+| info | _finfoelement_ | Looks up the entry in the fontinfo plist and returns its value |
+| kerninfo | | Returns a list of tuples (left, right, kern_value) |
+| opt | _defined_ | Looks up a given -D/--define variable. Returns empty string if missing |
+| MINx | _glyphname_ | Returns the minimum x value of the bounding box of the glyph |
+| MINy | _glyphname_ | Returns the minimum y value of the bounding box of the glyph |
+| MAXx | _glyphname_ | Returns the maximum x value of the bounding box of the glyph |
+| MAXy | _glyphname_ | Returns the maximum y value of the bounding box of the glyph |
+
+See the section on python in the `def` command section following.
+
+##### if
+
+The `if` substatement consists of an expression and a block of statements. `if` substatements only make sense at the end of a sequence of substatements and are executed at the end of the `do` statement, in the order they occur but after all other `for` and `let` substatements. The expression is calculated and if the result is True then the _statements_ are expanded using variable expansion.
+
+`if` _expression_ `;` `{` _statements_ `}`
+
+There can be multiple `if` substatements, each with their own block, in a `do` statement.
+
+#### Examples
+
+The `do` statement is best understood through some examples.
+
+##### Simple calculation
+
+This calculates a simple offset shift and creates a lookup to apply it:
+
+```
+do let a = -int(ADVx("u16F61") / 2);
+ {
+ lookup left_shift_vowel {
+ pos @_H <$a 0 0 0>;
+ } left_shift_vowel;
+ }
+```
+
+Notice the lack of iteration here.
+
+##### More complex calculation
+
+This calculates the guard spaces on either side of a base glyph in response to applied diacritics.
+
+```
+lookup advance_base {
+do for g = @H;
+ let a = APx(g, "H") - ADVx(g) + int(1.5 * ADVx("u16F61"));
+ let b = int(1.5 * ADVx("u16F61")) - APx(g, "H");
+ let c = a + b;
+ {
+ pos $g <$b 0 $c 0>;
+ }
+} advance_base;
+```
+
+##### Right Guard
+
+It is often desirable to give a base character extra advance width to account for a diacritic hanging over the right hand side of the glyph. Calculating this can be very difficult by hand. This code achieves this:
+
+```
+do for b = @bases;
+ for d = @diacritics;
+ let v = (ADVx(d) - APx(d, "_U")) - (ADVx(b) - APx(b, "U"));
+ if v > 0; {
+ pos $b' $v $d;
+ }
+```
+
+##### Left Guard
+
+A corresponding guarding of space for diacritics may be done on the left side of a glyph:
+
+```
+do for b = @bases;
+ for d = @diacritics;
+ let v = APx(d, "_U") - APx(b, "U");
+ if v > 0; {
+ pos $b' <$v 0 $v 0> $d;
+ }
+```
+
+##### Left Kern
+
+Consider the case where someone has used an attachment point as a kerning point. In some context they want to adjust the advance of the left glyph based on the position of the attachment point in the right glyph:
+
+```
+do for r = @rights;
+ let v = APx(r, "K"); {
+ pos @lefts' $v $r;
+ pos @lefts' $v @diacritics $r;
+ }
+```
+
+##### Myanmar Great Ya
+
+One obscure situation is the Great Ya (U+103C) in the Myanmar script, that visual wraps around the following base glyph. The great ya is given a small advance to then position the following consonant glyph within it. The advance of this consonant needs to be enough to place the next character outside the great ya. So we create an A attachment point on the great ya to emulate this intended final advance. Note that there are many variants of the great ya glyph. Thus:
+
+```
+do for y = @c103C_nar;
+ for c = @cCons_nar;
+ let v = APx(y, "A") - (ADVx(y) + ADVx(c));
+ if v > 0; {
+ pos $y' $v $c;
+ }
+
+do for y = @c103C_wide;
+ for c = @cCons_wide;
+ let v = APx(y, "A") - (ADVx(y) + ADVx(c));
+ if v > 0; {
+ pos $y' $v $c;
+ }
+```
+
+##### Advance for Ldot on U
+
+This example mirrors that used in the proposed [`setadvance`](feax_future.md#setadvance) statement. Here we want to add sufficient advance on the base to correspond to attaching an u vowel which in turn has a lower dot attached to it.
+
+```
+do for b = @cBases;
+ for u = @cLVowels;
+ let v = APx(b, "L") - APx(u, "_L") + APx(u, "LD") - APx("ldot", "_LD") + ADVx("ldot") - ADVx(b);
+ if v > 0; {
+ pos $b' $v $u ldot;
+ }
+```
+
+### def
+
+The `def` statement allows for the creation of python functions for use in `let` substatements of the `do` statement. The syntax of the `def` statement is:
+
+```
+def <fn>(<param_list>) {
+ ... python code ...
+} <fn>;
+```
+
+The `fn` must conform to a FEA name (not starting with a digit, etc.) and is repeated at the end of the block to mark the end of the function. The parameter is a standard python parameter list and the python code is standard python code, indented as if under a `def` statement.
+
+#### python support
+Here and in `let` substatements, the python that is allowed to executed is limited. Only a subset of functions from builtins is supported and the `__` may not occur in any attribute. This is to stop people escaping the sandbox in which python code is interpreted. The `math` and `re` modules are also included along with the functions available to a `let` substatement. The full list of builtins supported are:
+
+```
+True, False, None, int, float, str, abs, bool, dict, enumerate, filter, hex, len, list,
+map, max, min, ord, range, set, sorted, sum, tuple, zip
+```
+
+### kernpairs
+
+The `kernpairs` statement expands all the kerning pairs in the font into `pos` statements. For example:
+
+```
+lookup kernpairs {
+ lookupflag IgnoreMarks;
+ kernpairs;
+} kernpairs;
+```
+
+Might produce:
+
+```
+lookup kernpairs {
+ lookupflag IgnoreMarks;
+ pos @MMK_L_afii57929 -164 @MMK_R_uniA4F8;
+ pos @MMK_L_uniA4D1 -164 @MMK_R_uniA4F8;
+ pos @MMK_L_uniA4D5 -164 @MMK_R_afii57929;
+ pos @MMK_L_uniA4FA -148 @MMK_R_space;
+} kernpairs;
+```
+
+Currently, kerning information is only available from .ufo files.
+
+## Capabilities
+
+### Permit classes on both sides of GSUB type 2 (multiple) and type 4 (ligature) lookups
+
+Adobe doesn't permit compact notation using groups in 1-to-many (decomposition) rules e.g:
+
+```
+ sub @AlefPlusMark by absAlef @AlefMark ;
+```
+
+or many-to-1 (ligature) rules, e.g.:
+
+```
+ sub @ShaddaKasraMarks absShadda by @ShaddaKasraLigatures ;
+```
+
+This is implemented in FEAX as follows.
+
+#### Processing
+
+Of the four simple (i.e., non-contextual) substitution lookups, Types 2 and 4
+are the only ones using the 'by' keyword that have a *sequence* of glyphs or
+classes on one side of the rule. The other side will, necessarily, contain a
+single term -- which Adobe currently requires to be a glyph. For convenience of
+expression, we'll call the sides of the rule the *sequence side* and the *singleton side*.
+
+* Non-contextual substitution
+* Uses the 'by' keyword
+* Singleton side references a glyph class.
+
+Such rules are expanded by enumerating the singleton side class and the corresponding
+class(es) on the sequence side and writing a set of Adobe-compliant rules to give
+the same result. It is an error if the singleton and corresponding classes do
+not have the same number of glyphs.
+
+#### Example
+
+Given:
+
+```
+ @class1 = [ g1 g2 ] ;
+ @class2 = [ g1a g2a ] ;
+```
+
+then
+
+```
+ sub @class1 gOther by @class2 ;
+```
+
+would be rewritten as:
+
+```
+ sub g1 gOther by g1a ;
+ sub g2 gOther by g2a ;
+```
+
+### Support classes in alternate lookups
+
+The default behaviour in FEA is for a `sub x from [x.a x.b];` to only allow a single glyph before the `from` keyword. But it is often useful to do things like: `sub @a from [@a.lower @a.upper];`. Feax supports this by treating the right hand side list of glyphs as a single list and dividing it equally by the list on the left. Thus if `@a` is of length 3 then the first 3 glyphs in the right hand list will go one each as the first alternate for each glyph in `@a`, then the next 3 go as the second alternate, and so on until they are all consumed. If any are left over in that one of the glyphs ends up with a different number of alternates to another, then an error is given.
+
+### groups.plist
+
+If a .ufo file contains a `groups.plist` file, the groups declared there are propagated straight through to the output file and can be referenced within a source file.
+
diff --git a/docs/feax_future.md b/docs/feax_future.md
new file mode 100644
index 0000000..a989a5d
--- /dev/null
+++ b/docs/feax_future.md
@@ -0,0 +1,283 @@
+# FEA Extensions Future
+
+## Introduction
+
+This document is where people can dream of the extensions they would like to see
+added to FEA. Notice that any extensions need to be convertible back to normal FEA
+so shouldn't do things that can't be expressed in FEA.
+
+As things get implemented from here, they will be moved to feaextensions.md. There
+are no guaranteees that what is in here, will end up in psfmakefea.
+The various features listed here are given priorities:
+
+| Level | Priority
+|------|-------------
+| 1 | Intended to be implemented
+| 2 | Probably will be implemented but after priority 1 stuff
+| 3 | Almost certainly won't be implemented
+
+There are a number of possible things that can be added to FEA, the question is whether they are worth adding in terms of meeting actual need (remove from this list if added to the rest of the document):
+
+* classsubtract() classand() functions
+ * classand(x, y) = classsubtract(x, (classsubtract(x, y))
+* classbuild(class, "$.ext") builds one class out of another. What if something is missing? Or do we just build those classes on the fly from make_fea and glyph name parsing?
+
+## Statements
+
+Statements are used to make rules, lookups, etc.
+
+### setadvance
+
+Priority: 3 (since the do statement has a higher priority and covers this)
+
+This function does the calculations necessary to adjust the advance of a glyph based on information of attachment points, etc. The result is a single shift on each of the glyphs in the class. The syntax is:
+
+```
+setadvance(@glyphs, APName [, attachedGlyph[, APName, attachedGlyph [...]]])
+```
+
+In effect there are two modes for this function. The first only has two parameters
+and shifts the advance from its default designed position to the x coordinate of
+the given attachment point. The second mode adds extra glyphs. The advance is moved
+to the advance of the attachedGlyph assuming the base has the other glyphs chained
+attached at their given APs. An AP may be a number in which case that is the
+x coordinate of the AP that will be used.
+
+Typically there will be only one of these per lookup, unless the classes referenced
+are non overlapping.
+
+The statement only triggers if the resulting advance is greater than the current
+advance. Thus some glyphs may not have a statement created for them. I.e. all
+values in the lookup will be positive.
+
+#### Examples
+
+These examples also act as motivating use cases.
+
+##### Nokyung
+
+In Nokyung there is a need to kern characters that do not descend below the baseline closer to glyphs with a right underhang. This can be done through kerning pairs or we could add an attachment point to the glyphs with the right underhang and contextual adjust their advances to that position. The approach of using an AP to do kerning is certainly quirky and few designers would go that route. The contextual lookup would call a lookup that just does the single adjustment. Consider the AP to be called K (for kern). The fea might look like:
+
+```
+lookup overhangKernShift {
+ setadvance(@overhangs, K);
+} overhangKernShift;
+```
+
+And would expand, potentially, into
+
+```
+lookup overhangKernShift {
+ @overhangs <-80>;
+} overhangKernShift;
+```
+Not much, but that is because in Nokyung the overhanging glyphs all have the same overhang. If they didn't, then the list could well expand with different values for each glyph in the overhangs class. In fact, a simple implementation would do such an expansion anyway, while a more sophisticated implementation would group the results into ad hoc glyph lists.
+
+##### Myanmar
+
+An example from Myanmar is where a diacritic is attached such that the diacritic overhangs the right hand side of the base glyph and we want to extend the advance of the base glyph to encompass the diacritic. This is a primary motivating example for this statement. Such a lookup might read:
+
+```
+lookup advanceForLDotOnU {
+ setadvance(@base, L, uvowel, LD, ldot);
+} advanceForLDotOnU;
+```
+
+Which transforms to:
+
+```
+lookup advanceForLDotOnU {
+ ka <120>;
+ kha <80>;
+# …
+} advanceForLDotOnU;
+```
+
+##### Miao
+
+Miao is slightly different in that the advance we want to use is a constant,
+partly because calculating it involves a sequence of 3 vowel widths and you end up
+with a very long list of possible values and lookups for each one:
+
+```
+lookup advancesShortShortShort {
+ setadvance(@base, 1037);
+} advancesShortShortShort;
+```
+
+#### Issues
+
+* Do we want to use a syntax more akin to that used for composites, since that is, in effect, what we are describing: make the base have the advance of the composite?
+* Do we want to change the output to reflect the sequence so that there can be more statements per lookup?
+ * The problem is that then you may want to skip intervening non-contributing glyphs (like upper diacritics in the above examples), which you would do anyway from the contextual driving lookup, but wouldn't want to have to do in each situation here.
+* It's a bit of a pain that in effect there is only one setadvance() per lookup. It would be nice to do more.
+* Does this work (and have useful meaning) in RTL?
+* Appears to leave the base glyph *position* unchanged. Is there a need to handle, for example in LTR scripts, LSB change for a base due to its diacritics? (Think i-tilde, etc.)
+
+### move
+
+Priority: 2
+
+The move semantic results in a complex of lookups. See this [article](https://github.com/OpenType/opentype-layout/blob/master/docs/ligatures.md) on how to implement a move semantic successfully in OpenType. As such a move semantic can only be expressed as a statement at the highest level since it creates lookups. The move statement takes a number of parameters:
+
+```
+move lookup_basename, skipped, matched;
+```
+
+The *lookup_basename* is a name (unadorned string) prefix that is used in the naming of the lookups that the move statement creates. It also allows multiple move statements to share the same lookups where appropriate. Such lookups can be referenced by contextual chaining lookups. The lookups generated are:
+
+| | |
+| ---------------------------- | -------------------------------------------------- |
+| lookup_basename_match | Contextual chaining lookup to drive the sublookups |
+| lookup_basename_pres_matched | Converts skipped(1) to matched + skipped(1) |
+| lookup_basename_pref_matched | Converts skipped(1) to matched + skipped(1) + matched |
+| lookup_basename_back | Converts skipped(-1) + matched to skipped(-1). |
+
+Multiple instances of a move statement that use the same *lookup_basename* will correctly merge the various rules in the the lookups created since often at least parts of the *skipped* or *matched* will be the same across different statements.
+
+Since lookups may be added to, extra contextual rules can be added to the *lookup_basename*_match.
+
+*skipped* contains a sequence of glyphs (of minimum length 1), where each glyph may be a class or whatever. The move statement considers both the first and last glyph of this sequence when it comes to the other lookups it creates. *skipped(1)* is the first glyph in the sequence and *skipped(-1)* is the last.
+
+*matched* is a single glyph that is to be moved. There needs to be a two lookups for each matched glyph.
+
+Notice that only *lookup_basename*_matched should be added to a feature. The rest are sublookups and can be in any order. The *lookup_basename*_matched lookup is created at the point of the first move statement that has a first parameter of *lookup_basename*.
+
+#### Examples
+
+While there are no known use cases for this in our fonts at the moment, this is an important statement in terms of showing how complex concepts of wider interest can be implemented as extensions to fea.
+
+##### Myanmar
+
+Moving prevowels to the front of a syllable from their specified position in the sequence, in a DFLT processor is one such use of a move semantic:
+
+```
+move(pv, @cons, my-e);
+move(pv, @cons @medial, my-e);
+move(pv, @cons @medial @medial, my-e);
+move(pv, @cons @medial @medial @medial, my-e);
+move(pv, @cons, my-shane);
+move(pv, @cons, @medial, my-shane);
+```
+
+This becomes:
+
+```
+lookup pv_pres_my-e {
+ sub @cons by my-e @cons;
+} pv_pres_my-e;
+
+lookup pv_pref_my-e {
+ sub @cons by my-e @cons my-e;
+} pv_pref_my-e;
+
+lookup pv_back {
+ sub @cons my-e by @cons;
+ sub @medial my-e by @medial;
+ sub @cons my-shane by @cons;
+ sub @medial my-shane by @medial;
+} pv_back;
+
+lookup pv_match {
+ sub @cons' lookup pv_pres-my-e my-e' lookup pv_back;
+ sub @cons' lookup pv_pref-my-e @medial my-e' lookup pv_back;
+ sub @cons' lookup pv_pref-my-e @medial @medial my-e' lookup pv_back;
+ sub @cons' lookup pv_pref-my-e @medial @medial @medial my-e' lookup pv_back;
+ sub @cons' lookup pv_pres-my-shane my-shane' lookup pv_back;
+ sub @cons' lookup pv_pref-my-shane @medial my-shane' lookup pv_back;
+} pv_match;
+
+lookup pv_pres_my-shane {
+ sub @cons by my-shane @cons;
+} pv_pres_my-shane;
+
+lookup pv_pref_my-shane {
+ sub @cons by my-shane @cons my-shane;
+} pv_pref_my-shane;
+```
+
+##### Khmer Split Vowels
+
+Khmer has a system of split vowels, of which we will consider a very few:
+
+```
+lookup presplit {
+ sub km-oe by km-e km-ii;
+ sub km-ya by km-e km-yy km-ya.sub;
+ sub km-oo by km-e km-aa;
+} presplit;
+
+move(split, @cons, km-e);
+move(split, @cons @medial, km-e);
+```
+
+## Functions
+
+Functions may be used in the place of a glyph or glyph class and return a list of glyphs.
+
+### index
+
+Priority: 2
+
+Used in rules where the expansion of a rule results in a particular glyph from a class being used. Where two classes need to be synchronised, and which two classes are involved, this function specifies the rule element that drives the choice of glyph from this class. This function is motivated by the Keyman language. The parameters of index() are:
+
+```
+index(slot_index, glyphclass)
+```
+
+*slot_index* considers the rule as two sequences of slots, each slot referring to one glyph or glyphclass. The first sequence is on the left hand side of the rule and the second on the right, with the index running sequentially from one sequence to the other. Thus if a rule has 2 slots on the left hand side and 3 on the right, a *slot_index* of 5 refers to the last glyph on the right hand side. *Slot_index* values start from 1 for the first glyph on the left hand side.
+
+What makes an index() function difficult to implement is that it requires knowledge of its context in the statement it occurs in. This is tricky to implement since it is a kind of layer violation. It doesn't matter how an index() type function is represented syntactically, the same problem applies.
+
+### infont
+
+Priority: 2
+
+This function filters the glyph class that is passed to it, and returns only those glyphs, in glyphclass order, which are actually present in the font being compiled for. For example:
+
+```
+@cons = infont([ka kha gha nga]);
+```
+
+## Capabilities
+
+### Permit multiple classes on RHS of GSUB type 2 (multiple) and the LHS of type 4 (ligature) lookups
+
+Priority: 2
+
+#### Slot correspondence
+
+In Type 2 (multiple) substitutions, the LHS will be the singleton case and the RHS will be the sequence. In normal use-cases exactly one slot in the RHS will be a class -- all the others will be glyphs -- in which case that class and the singleton side class correspond.
+
+If more than one RHS slot is to contain a class, then the only logical meaning is that all such classes must also correspond to the singleton class in the LHS, and will be expanded (along with the singleton side class) in parallel. Thus all the classes must have the same number of elements.
+
+In Type 4 (ligature) substitutions, the RHS will be the singleton class. In the case that the LHS (sequence side) of the rule has class references in more than one slot, we need to identify which slot corresponds to the singleton side class. Some alternatives:
+
+* Pick the slot that, when the classes are flattened, has the same number of glyphs as the class on the singleton side. It is possible that there is more than one such slot, however.
+* Add a notation to the rule. Graphite uses the $n modifier on the RHS to identify the corresponding slot (in the context), which we could adapt to FEA as:
+
+```
+ sub @class1 @class2 @class3 by @class4$2 ;
+```
+
+Alternatively, since there can be only one such slot, we could use a simpler notation by putting something like the $ in the LHS:
+
+```
+ sub @class1 @class2$ @class3 by @class4 ;
+```
+
+[This won't look right to GDL programmers, but makes does sense for OT code]
+
+* Extra syntactic elements at the lexical level are hard to introduce. Instead a function such as:
+
+```
+sub @class1 @class2 @class3 by index(2, @class4);
+```
+
+Would give the necessary interpretation. See the discussion of the index() function for more details.
+
+Note that the other classes in the LHS of ligature rules do not need further processing since FEA allows such classes.
+
+#### Nested classes
+
+We will want to expand nested classes in a way (i.e., depth or breadth first) that is compatible with Adobe. **Concern:** Might this be different than Graphite? Is there any difference if one says always expand left to right? [a b [c [d e] f] g] flattens the same as [[[a b] c d] e f g] or whatever. The FontTools parser does not support nested glyph classes. To what extent are they required?
diff --git a/docs/parameters.md b/docs/parameters.md
new file mode 100644
index 0000000..cec8988
--- /dev/null
+++ b/docs/parameters.md
@@ -0,0 +1,179 @@
+# Pysilfont parameters
+
+In addition to normal command-line arguments (see [scripts.md](scripts.md) and [Standard Command-line Options](docs.md#standard-command-line-options)), Pysilfont supports many other parameters that can be changed either on the command-line or by settings in a config file. For UFO fonts there is also an option to set parameters within the UFO.
+
+See [List of Parameters](#list-of-parameters) for a full list, which includes the default values for each parameter.
+
+# Setting parameters
+
+Parameters can be set in multiple ways
+1. Default values are set by the core.py Pysilfont module - see [List of Parameters](#list-of-parameters)
+1. Standard values for a project can be set in a pysilfont.cfg [config file](#config-file)
+1. For UFO fonts, font-specific values can be set within the [lib.plist](#lib-plist) file
+1. On the command line \- see next section
+
+Values set by later methods override those set by earlier methods.
+
+(Scripts can also change some values, but they would normally be written to avoid overwriting command-line values)
+
+## Command line
+
+For script users, parameters can be set on the command line with -p, for example:
+```
+psfnormalize test.ufo -p scrlevel=V -p indentIncr=" "
+```
+would increase the screen reporting level to Verbose and change the xml indent from 2 spaces to 4 spaces.
+
+If a parameter has multiple values, enter them separated with commas but no spaces, eg:
+
+`-p glifElemOrder=unicode,advance,note,image,guideline,anchor,outline,lib`
+
+
+
+## Config file
+If pysilfont.cfg exists in the same directory as the first file specified on the command line (typically the font being processed) then parameters will be read from there.
+
+The format is a [ConfigParser](https://docs.python.org/2/library/configparser.html) config file, which is similar structure to a Windows .ini file.
+
+Lines starting with # are ignored, as are any blank lines.
+
+Example:
+```
+# Config file
+
+[logging]
+scrlevel: I
+
+[outparams]
+indentIncr: ' '
+glifElemOrder: unicode,advance,note,image,guideline,anchor,outline,lib
+```
+The section headers are backups, logging, outparams and ufometadata.
+
+In a font project with multiple UFO fonts in the same folder, all would use a single config file.
+
+## lib plist
+
+If, with a UFO font, org.sil.pysilfontparams exists in lib.plist, parameter values held in an array will be processed, eg
+```
+<key>org.sil.pysilfontparams</key>
+<array>
+ <indentIncr>\t</indentIncr>
+ <glifElemOrder>lib,unicode,note,image,guideline,anchor,outline,advance</glifElemOrder>
+</array>
+```
+Currently only font output parameters can be changed via lib.plist
+
+## List of parameters
+
+| Parameter | Default | Description | Notes |
+| -------- | -------- | --------------------------------------------- | ------------------------------------- |
+| **Reporting** | | | To change within a script use <br>`logger.<parameter> = <value>`|
+| scrlevel | P | Reporting level to screen. See [Reporting](docs.md#reporting) for more details | -q, --quiet option sets this to S |
+| loglevel | W | Reporting level to log file | |
+| **Backup** (font scripts only) | | | |
+| backup | True | Backup font to subdirectory | If the original font is being updated, make a backup first |
+| backupdir | backups | Sub-directory name for backups | |
+| backupkeep | 5 | Number of backups to keep | |
+| **Output** (UFO scripts only) | | | To change in a script use <br>`font.outparams[<parameter>] = <value>` |
+| indentFirst | 2 spaces | Increment for first level in xml | |
+| indentIncr | 2 spaces | Amount to increment xml indents | |
+| indentML | False | Indent multi-line text items | (indenting really messes some things up!) |
+| plistIndentFirst | Empty string | Different initial indent for plists | (dict is commonly not indented) |
+| sortDicts | True | sort all plist dicts | |
+| precision | 6 | decimal precision | |
+| renameGlifs | True | Name glifs with standard algorithm | |
+| UFOversion | (existing) | | Defaults to the version of the UFO when opened |
+| format1Glifs | False| Force output of format 1 glifs | Includes UFO2-style anchors; for use with FontForge |
+| floatAttribs | (list of attributes in the spec that hold numbers and are handled as float) | Used to know if precision needs setting. | May need items adding for lib data |
+| intAttribs | (list of attributes in the spec that hold numbers and handled as integer) | | May need items adding for lib data |
+| glifElemOrder | (list of elements in the order defined in spec) | Order for outputting elements in a glif | |
+| attribOrders | (list of attribute orders defined in spec) | Order for outputting attributes in an element. One list per element type | When setting this, the parameter name is `attribOrders.<element type>`. Currently only used with attribOrders.glif |
+| **ufometadata** (ufo scripts only) | | | |
+| checkfix | check | Metadata check & fix action | If set to "fix", some values updated (or deleted). Set to "none" for no metadata checking |
+| More may be added... | |
+
+## Within basic scripts
+### Accessing values
+If you need to access values of parameters or to see what values have been set on the command line you can look at:
+- args.paramsobj.sets[“main”]
+ - This is a dictionary containing the values for **all** parameters listed above. Where they have been specified in a config file, or overwritten on the command line, those values will be used. Otherwise the default values listed above will be used
+- args.params
+ - This is a dictionary containing any parameters specified on the command line with -p.
+
+Within a UFO Ufont object, use font.paramset, since this will include any updates as a result parameter values set in lib.plist.
+
+In addition to the parameters in the table above, two more read-only parameters can be accessed by scripts - “version” and “copyright” - which give the pysilfont library version and copyright info, based on values in core.py headers.
+
+### Updating values
+Currently only values under Output can be set via scripts, since Backup and Reporting parameters are processed by execute() prior to the script being called. For example:
+```python
+font.paramset[“precision”] = 9
+```
+would set the precision parameter to 9.
+
+Note that, whilst reporting _parameters_ can’t be set in scripts, _reporting levels_ can be updated by setting values in the args.logger() object, eg `args.logger.scrlevel = “W”.`
+
+# Technical
+
+_Note the details below are probably not needed just for developing scripts..._
+
+## Basics
+The default for all parameters are set in core.py as part of the parameters() object. Those for **all** pysilfont library modules need to be defined in core.py so that execute() can process command-line arguments without needing information from other modules.
+
+Parameters are passed to scripts via a parameters() object as args.paramsobj. This contains several parameter sets, with “main” being the standard one for scripts to use since that contains the default parameters updated with those (if any) from the config file then the same for any command-line values.
+
+Parameters can be accessed from the parameter set by parameter name, eg paramsobj.sets[“main”][“loglevel”].
+
+Although parameters are split into classes (eg backup, logging), parameter names need to be unique across all groups to allow simple access by name.
+
+If logging set set to I or V, changes to parameter values (eg config file values updating default values) are logged.
+
+There should only be ever a single parameters() object used by a script.
+
+## Paramobj
+In addition to the paramsets, the paramobj also contains
+- classes:
+ - A dictionary keyed on class, returning a list of parameter names in that class
+- paramclass:
+ - A dictionary keyed on parameter name, returning the class of that parameter
+- lcase:
+ - A dictionary keyed on lowercase version of parameter name returning the parameter name
+- type:
+ - A dictionary keyed on parameter name, returning the type of that parameter (eg str, boolean, list)
+- listtype:
+ - For list parameters, a dictionary keyed on parameter name, returning the type of that parameters in the list
+- logger:
+ - The logger object for the script
+
+## Parameter sets
+These serve two purposes:
+1. To allow multiple set of parameter values to be used - eg two different fonts might have different values in the lib.plist
+1. To keep track of the original sets of parameters (“default”, “config file” and “command line”) if needed. See UFO specific for an example of this need.
+
+Additional sets can be added with addset() and one set can be updated with values from another using updatewith(), for example, to create the “main” set, the following code is used:
+```
+params.addset("main",copyset = "default") # Make a copy of the default set
+params.sets["main"].updatewith("config file") # Update with config file values
+params.sets["main"].updatewith("command line") # Update with command-line values
+```
+## UFO-specific
+The parameter set relevant to a UFO font can be accessed by font.paramset, so font.paramset[“loglevel"] would access the loglevel.
+
+In ufo.py there is code to cope with two complications:
+1. If a script is opening multiple fonts, in they could have different lib.plist values so font-specific parameter sets are needed
+1. The parameters passed to ufo.py include the “main” set which has already had command-line parameters applied. Any in lib.plist also need to be applied, but can’t simply be applied to “main” since command-line parameters should take precedence over lib.plist ones
+
+To ensure unique names, the parameter sets are created using the full path name of the UFO. Then font.paramset is set to point to this, so scripts do not need to know the underlying set name.
+
+To apply the parameter sets updates in the correct order, ufo.py does:
+
+1. Create a new paramset from any lib parameters present
+1. Update this with any command line parameters
+1. Create the paramset for the font by copying the “main” paramset
+1. Update this with the lib paramset (which has already been updated with command line values in step 2)
+
+## Adding another parameter or class
+If there was a need to add another parameter or class, all that should be needed is to add that to defparams in the \_\_init\_\_() of parameters() in core.py. Ensure the new parameter is case-insensitively unique.
+
+If a class was Ufont-specific and needed to be supported within lib.plist, then ufo.py would also need updating to handle that similarly to how it now handles outparams and ufometadata.
diff --git a/docs/scripts.md b/docs/scripts.md
new file mode 100644
index 0000000..ab8fd43
--- /dev/null
+++ b/docs/scripts.md
@@ -0,0 +1,1544 @@
+# Pysilfont commands and scripts
+
+Below is a table listing all the commands installed by Pysilfont followed by descriptions of each command.
+
+All these commands work in consistent ways in terms of certain standard options (eg -h for help) and default names for many files - see details in [Pysilfont Documentation](docs.md#standard-command-line-options).
+
+There are further example scripts supplied with Pysilfont, and some of these are also documented in [examples.md](examples.md)
+
+## Table of scripts
+
+| Command | Description |
+| ------- | ----------- |
+| [psfaddanchors](#psfaddanchors) | Read anchor data from XML file and apply to UFO |
+| [psfbuildcomp](#psfbuildcomp) | Add composite glyphs to UFO based on a Composite Definitions file |
+| [psfbuildcompgc](#psfbuildcompgc) | Add composite glyphs to UFO using glyphConstruction based on a CD file |
+| [psfbuildfea](#psfbuildfea) | Compile a feature (.fea) file against an existing input TTF |
+| [psfchangegdlnames](#psfchangegdlnames) | Change graphite names within GDL based on mappings files |
+| [psfchangettfglyphnames](#psfchangettfglyphnames) | Change glyph names in a ttf from working names to production names |
+| [psfcheckbasicchars](#psfcheckbasicchars) | Check UFO for glyphs that represent recommended basic characters |
+| [psfcheckclassorders](#psfcheckclassorders) | Verify classes defined in xml have correct ordering where needed |
+| [psfcheckftml](#psfcheckftml) | Check ftml files for structural integrity |
+| [psfcheckglyphinventory](#psfcheckglyphinventory) | Warn for differences in glyph inventory and encoding between UFO and input file (e.g., glyph_data.csv) |
+| [psfcheckinterpolatable](#psfcheckinterpolatable) | Check UFOs in a designspace file are compatible with interpolation |
+| [psfcompdef2xml](#psfcompdef2xml) | Convert composite definition file to XML format |
+| [psfcompressgr](#psfcompressgr) | Compress Graphite tables in a ttf font |
+| [psfcopyglyphs](#psfcopyglyphs) | Copy glyphs from one UFO to another with optional scale and rename |
+| [psfcopymeta](#psfcopymeta) | Copy basic metadata from one UFO to another, for fonts in related families |
+| [psfcreateinstances](#psfcreateinstances) | Create one or more instance UFOs from one or more designspace files |
+| [psfcsv2comp](#psfcsv2comp) | Create composite definition file from csv |
+| [psfdeflang](#psfdeflang) | Changes default language behaviour in a font |
+| [psfdeleteglyphs](#psfdeleteglyphs) | Deletes glyphs from a UFO based on a list |
+| [psfdupglyphs](#psfdupglyphs) | Duplicates glyphs in a UFO based on a csv definition |
+| [psfexportanchors](#psfexportanchors) | Export UFO anchor data to a separate XML file |
+| [psfexportmarkcolors](#psfexportmarkcolors) | Export csv of mark colors |
+| [psfexportpsnames](#psfexportpsnames) | Export a map of glyph name to PS name to a csv file |
+| [psfexportunicodes](#psfexportunicodes) | Export a map of glyph name to unicode value to a csv file |
+| [psffixffglifs](#psffixffglifs) | Make changes needed to a UFO following processing by FontForge |
+| [psffixfontlab](#psffixfontlab) | Make changes needed to a UFO following processing by FontLab |
+| [psfftml2TThtml](#psfftml2tthtml) | Convert FTML document to html and fonts for testing TypeTuner |
+| [psfftml2odt](#psfftml2odt) | Create a LibreOffice Writer file from an FTML test description |
+| [psfgetglyphnames](#psfgetglyphnames) | Create a file of glyphs to import from a list of characters to import |
+| [psfglyphs2ufo](#psfglyphs2ufo) | Export all the masters in a .glyphs file to UFOs |
+| [psfmakedeprecated](#psfmakedeprecated) | Creates deprecated versions of glyphs |
+| [psfmakefea](#psfmakefea) | Make a features file base on input UFO or AP database |
+| [psfmakescaledshifted](#psfmakescaledshifted) | Creates scaled and shifted versions of glyphs |
+| [psfmakewoffmetadata](#psfmakewoffmetadata) | Make the WOFF metadata xml file based on input UFO |
+| [psfnormalize](#psfnormalize) | Normalize a UFO and optionally converts it between UFO2 and UFO3 versions |
+| [psfremovegliflibkeys](#psfremovegliflibkeys) | Remove keys from glif lib entries |
+| [psfrenameglyphs](#psfrenameglyphs) | Within a UFO and class definition, assign new working names to glyphs based on csv input file |
+| [psfrunfbchecks](#psfrunfbchecks) | Run Font Bakery checks using a standard profile with option to specify an alternative profile |
+| [psfsetassocfeat](#psfsetassocfeat) | Add associate feature info to glif lib based on a csv file |
+| [psfsetassocuids](#psfsetassocuids) | Add associate UID info to glif lib based on a csv file |
+| [psfsetdummydsig](#psfsetdummydsig) | Add a dummy DSIG table into a TTF font |
+| [psfsetglyphdata](#psfsetglyphdata) | Update and/or sort glyph_data.csv based on input file(s) |
+| [psfsetglyphorder](#psfsetglyphorder) | Load glyph order data into public.glyphOrder based on a text file |
+| [psfsetkeys](#psfsetkeys) | Set key(s) with given value(s) in a UFO p-list file |
+| [psfsetmarkcolors](#psfsetmarkcolors) | Set mark colors based on csv file |
+| [psfsetpsnames](#psfsetpsnames) | Add public.postscriptname to glif lib based on a csv file |
+| [psfsetunicodes](#psfsetunicodes) | Set unicode values for a glif based on a csv file |
+| [psfsetversion](#psfsetversion) | Change all the version-related info in a UFO's fontinfo.plist |
+| [psfshownames](#psfshownames) | Display name fields and other bits for linking fonts into families |
+| [psfsubset](#psfsubset) | Create a subset of an existing UFO |
+| [psfsyncmasters](#psfsyncmasters) | Sync metadata in master UFO files based on a Designspace file |
+| [psfsyncmeta](#psfsyncmeta) | Copy basic metadata from one member of a font family to other family members |
+| [psftuneraliases](#psftuneraliases) | Merge alias information into TypeTuner feature xml file |
+| [psfufo2glyphs](#psfufo2glyphs) | Generate a glyphs files from a designspace file and UFO(s) |
+| [psfufo2ttf](#psfufo2ttf) | Generate a ttf file without OpenType tables from a UFO |
+| [psfversion](#psfversion) | Display version info for pysilfont and dependencies |
+| [psfwoffit](#psfwoffit) | Convert between ttf, woff, and woff2 |
+| [psfxml2compdef](#psfxml2compdef) | Convert composite definition file from XML format |
+
+---
+
+#### psfaddanchors
+Usage: **`psfaddanchors [-i ANCHORINFO] [-a] [-r {X,S,E,P,W,I,V}] ifont [ofont]`**
+
+_([Standard options](docs.md#standard-command-line-options) also apply)_
+
+_This section is Work In Progress!_
+
+Read anchor data from XML file and apply to UFO
+
+optional arguments:
+
+```
+ -i ANCHORINFO, --anchorinfo ANCHORINFO
+ XML file with anchor data
+ -a, --analysis Analysis only; no output font generated
+ -r {X,S,E,P,W,I,V}, --report {X,S,E,P,W,I,V}
+ Set reporting level for log fileUpdate and/or sort glyph_data.csv based on input file(s)
+```
+
+---
+
+#### psfbuildfea
+Usage: **`psfbuildfea -o output.ttf [-m map.txt] [-v] input.fea input.ttf`**
+
+_([Standard options](docs.md#standard-command-line-options) also apply)_
+
+Uses fontTools to compile a feature (.fea) file against an existing input TTF, optionally creating a lookup map.
+
+required arguments:
+
+```
+ -o output.ttf, --output output.ttf Output file to create
+ input.fea Source features file
+ input.ttf Source ttf
+```
+
+optional arguments:
+
+```
+ -m map.txt, --lookupmap map.txt Mapping file to create
+ -v, --verbose repeat to increase verbosity
+```
+
+If `-m` parameter is supplied, the designated file will be created listing, in alphabetical order by name, each OpenType lookup name, its table (GSUB or GPOS) and its feature index. For example:
+```
+AlefMark2BelowAfterLam,GPOS,13
+AyahAlternates,GSUB,46
+CommaAlternates,GSUB,48
+```
+
+---
+
+#### psfbuildcomp
+Usage: **`psfbuildcomp [-i CDFILE] [-a] [-c] [--colors] [-f] [-n] [--remove] [--preserve] ifont [ofont]`**
+
+_([Standard options](docs.md#standard-command-line-options) also apply)_
+
+Creates or updates composite glyphs in a UFO based on an external text file of definitions. The syntax for these definitions is described in [composite.md](composite.md).
+
+Example usage:
+
+```
+# add composites to font (making backup first)
+psfbuildcomp -i composites.txt font.ufo
+
+# add composites even for glyphs that have outlines, and write to a new font
+psfbuildcomp -i comps.txt -f -r V Andika-BoldItalic.ufo new.ufo
+
+# report only, with no change to font
+psfbuildcomp -i comps.txt -a -r I font.ufo
+
+# remove unwanted anchors 'above' and 'below', including '_' versions:
+psfbuildcomp -i comps.txt --remove "_?(above|below)" font.ufo
+
+# also preserve 'diaA' and 'diaB' on composites that exist but are being replaced:
+psfbuildcomp -i comps.txt --remove "_?(above|below)" --preserve "dia[AB]" font.ufo
+
+```
+
+optional arguments:
+
+```
+ -i CDFILE, --cdfile CDFILE
+ Composite Definitions input file
+ -a, --analysis Analysis only; no output font generated
+ -c, --color Set the markColor of of generated glyphs dark green
+ --colors Set the markColor of the generated glyphs based on color(s) supplied
+ (more details below)
+ -f, --force Force overwrite of glyphs having outlines
+ -n, --noflatten Do not flatten component references
+ --remove REMOVE a regex matching anchor names that should always be
+ removed from generated composite glyphs
+ --preserve PRESERVE a regex matching anchor names that, if present in
+ glyphs about to be replaced, should not be overwritten
+```
+
+Using --colors, three colors can be supplied:
+
+- The first for glyphs already in the font which are unchanged in this run of the script
+- The second for glyphs already in the font which are updated
+- The third for new glyphs added
+
+If just one color is supplied, this is used for all three uses above
+
+If two colors are supplied, the second is also used for new glyphs
+
+Colors can be specified as described in [Specifying colors on the command line](#specifying-colors-on-the-command-line)
+
+---
+#### psfbuildcompgc
+Usage: **`psfbuildcompgc [-i CDFILE] ifont [ofont]`**
+
+_([Standard options](docs.md#standard-command-line-options) also apply)_
+
+Creates or updates composite glyphs in a UFO based on an external text file of definitions. The syntax for these definitions *not* the same as that described in [composite.md](composite.md). It uses the [GlyphConstruction syntax](https://github.com/typemytype/GlyphConstruction).
+
+Example usage:
+
+```
+psfbuildcompgc -i composites.txt font.ufo
+```
+
+optional arguments:
+
+```
+ -i CDFILE, --cdfile CDFILE
+ Composite Definitions input file
+```
+
+---
+#### psfchangegdlnames
+Usage: **`psfchangegdlnames [-n NAMES] [--names2 [NAMES2]] [--psnames PSNAMES] input [output]`**
+
+_([Standard options](docs.md#standard-command-line-options) also apply)_
+
+Changes the graphite names within GDL files(s) based on mappings file(s). It can work on an individual file or on all the gdl/gdh files within a folder. It also updates postscript names in postscript() statements
+
+Two mappings files are required (NAMES and PSNAMES). Optionally a second GDL names mapping file, NAMES2 can be supplied.
+
+The mapping files are csv files of the format `"old name,new name"`. It logs if any graphite names are in the GDL but not found in the mapping files.
+
+Example usage:
+
+```
+psfchangegdlnames -n gdlmap.csv --psnames psnames.csv source/graphite
+```
+will update all the .gdl and.gdh files within the source/graphite folder.
+
+---
+#### psfchangettfglyphnames
+Usage: **`psfchangettfglyphnames iufo ittf ottf`**
+
+_([Standard options](docs.md#standard-command-line-options) also apply)_
+
+Used to change the glyph names in a ttf from working names to production names, typically as the last step in a build sequence.
+
+The name map is obtained from the `public.postscriptNames` attribute in the input UFO and then applied to the input ttf to create the output ttf.
+
+Example usage:
+
+```
+psfchangettfglyphnames source/Harmattan-Regular.ufo results/in.ttf results/out.ttf
+```
+
+---
+#### psfcheckbasicchars
+Usage: **`psfcheckbasicchars [-r] [-s] ufo`**
+
+_([Standard options](docs.md#standard-command-line-options) also apply)_
+
+Used to check a UFO for the presence of glyphs that represent the characters in the list of
+[Recommended characters for Non-Roman fonts](https://github.com/silnrsi/pysilfont/blob/master/lib/silfont/data/required_chars.csv).
+Any missing characters are noted in the resulting log file along with the recommended AGL glyph name.
+
+By default only characters needed for all fonts (both LTR and RTL) will be checked.\
+To also check for characters that only RTL fonts need, use the -r option.\
+To include characters that are in SIL's PUA block, use the -s option.
+
+Example usage:
+
+```
+psfcheckbasicchars Nokyung-Regular.ufo
+```
+
+There is more documentation about the character list [here](https://github.com/silnrsi/pysilfont/blob/master/lib/silfont/data/required_chars.md)
+and additional information can be shown on screen or in the log file by increasing the log level to I (-p scrlevel=i or -p loglevel=i)
+
+---
+#### psfcheckclassorders
+usage: **`psfcheckclassorders [--gname GNAME] [--sort HEADER] [classes] [glyphdata]`**
+
+_([Standard options](docs.md#standard-command-line-options) also apply)_
+
+Verify classes defined in xml have correct ordering where needed.
+
+Looks for comment lines in the `classes` file that match the string:
+```
+ *NEXT n CLASSES MUST MATCH*
+```
+where `n` is the number of upcoming class definitions that must result in the
+same glyph alignment when glyph names are sorted by TTF order.
+
+```
+optional arguments:
+ classes Class definition file in XML format (default `classes.xml`)
+ glyphdata Glyph info csv file (default `glyph_data.csv`)
+ --gname GNAME Column header for glyph name (default `glyph_name`)
+ --sort HEADER Column header for sort order (default `sort_final`)
+```
+#### Notes
+
+Classes defined in xml format (typically `source/classes.xml`) can be accessed by both Graphite and OpenType code. For historical reasons there is a difference in the way they are processed: for Graphite (only), the members of the classes are re-ordered based on the glyphIDs in the ttf.
+
+For classes used just for rule contexts, glyph order doesn't matter. But for classes used for n-to-n substitutions, order *does* matter and the classes have to be "aligned".
+
+Based on the sort order information extracted from the `glyphdata` file, this tool examines specially-marked groups of class definitions from the `classes` file to determine if they remain aligned after classes are reordered, and issues error messages if not. Here is an example identifying a set of three classes that must align:
+```
+ <!-- *NEXT 3 CLASSES MUST MATCH* -->
+
+ <class name='Damma'>
+ damma-ar shadda_damma-ar hamza_damma-ar
+ </class>
+
+ <class name='Damma_filled'>
+ damma-ar.filled shadda_damma-ar.filled hamza_damma-ar.filled
+ </class>
+
+ <class name='Damma_short'>
+ damma-ar.short shadda_damma-ar.short hamza_damma-ar.short
+ </class>
+ ```
+
+Note that the Graphite workflow extracts glyph order from the ttf file, but `psfcheckclassorders` gets it from `glyphdata` argument; there is, therefore, an assumption that the glyph order indicated in `glyphdata` actually matches that in the ttf file.
+
+`psfcheckclassorders` will also issue warning a warning message if there are glyphs named in the `classes` file which are not included in the `glyphdata` file. While this is [intentionally] not an error for either Graphite or OpenType (relevant tools simply ignore such missing glyphs), it may be helpful in catching typos that result in class miss-alignment and therefore bugs. By default warning messages are sent to the log file;
+use `-p scrlevel=W` to also route them to the terminal.
+
+---
+#### psfcheckftml
+usage: **`psfcheckftml [inftml]`**
+
+_([Standard options](docs.md#standard-command-line-options) also apply)_
+
+Test structural integrity of one or more ftml files
+
+Assumes ftml files have already validated against [`FTML.dtd`](https://github.com/silnrsi/ftml/blob/master/FTML.dtd), for example by using:
+
+``` xmllint --noout --dtdvalid FTML.dtd inftml.ftml```
+
+`psfcheckftml` verifies that:
+ - `silfont.ftml` can parse the file
+ - every `stylename` is defined the `<styles>` list
+
+```
+positional arguments:
+ inftml Input ftml filename pattern (default: *.ftml)
+
+other arguments:
+ -h, --help show this help message and exit
+ -l LOG, --log LOG Log file
+ -p PARAMS, --params PARAMS
+ Other parameters - see parameters.md for details
+ -q, --quiet Quiet mode - only display severe errors
+```
+
+---
+#### psfcheckglyphinventory
+Usage: **`psfcheckglyphinventory [--indent n] [-i input] ifont`**
+
+_([Standard options](docs.md#standard-command-line-options) also apply)_
+
+`psfcheckglyphinventory` compares and warns for differences in glyph inventory and encoding between UFO and input file (e.g., glyph_data.csv).
+input file can be:
+- simple text file with one glyph name per line
+- csv file with headers, using headers `glyph_name` and, if present, `USV`
+
+required arguments:
+
+```
+ ifont input UFO
+```
+
+optional arguments:
+```
+ -i INPUT, --input INPUT
+ input file, default is glyph_data.csv in current directory
+ -indent n number of spaces to indent output lists (default 10)
+```
+
+---
+#### psfcheckinterpolatable
+Usage: **`psfcheckinterpolatable designspace`**
+
+_([Standard options](docs.md#standard-command-line-options) also apply)_
+
+Check that the UFOs listed in the designspace file are interpolatable.
+When there are more than two UFOs in the designspace files they are checked in pairs. For each pair:
+ - The glyph inventories of the UFOs are compared and any discrepancies reported.
+ - For each glyph that is in both UFOs, they are tested with fontParts isCompatible() function which checks various items - for example the number and direction of contours.
+
+---
+#### psfcompdef2xml
+Usage: **`psfcompdef2xml [-p PARAMS] input output log`**
+
+_([Standard options](docs.md#standard-command-line-options) also apply)_
+
+Convert composite definition file to XML format
+
+_This section is Work In Progress!_
+
+ input Input file of CD in single line format
+ output Output file of CD in XML format
+ log Log file
+
+ -p PARAMS, --params PARAMS
+ XML formatting parameters: indentFirst, indentIncr,
+ attOrder
+
+ Defaults
+ output \_out.xml
+ log \_log.txt
+
+---
+#### psfcompressgr
+Usage: **`psfcompressgr ifont [ofont]`**
+
+_([Standard options](docs.md#standard-command-line-options) also apply)_
+
+Compress Graphite tables in a font
+
+---
+#### psfcopyglyphs
+Usage: **`psfcopyglyphs [-i INPUT] -s SOURCE ifont [ofont]`**
+
+_([Standard options](docs.md#standard-command-line-options) also apply)_
+
+Copy selected glyphs from a source UFO to a target UFO.
+
+required arguments:
+
+```
+ ifont Target font into which glyphs will be copied
+ -s SOURCE, --source SOURCE
+ Font to get glyphs from
+```
+
+optional arguments:
+```
+ ofont output font to create instead of rewriting ifont
+ -i INPUT, --input INPUT
+ CSV file identifying glyphs to copy
+ -n NAME, --name NAME Include glyph named NAME
+ -f, --force Overwrite existing glyphs in the target font
+ --scale SCALE Scale glyphs by this factor
+ --rename COLHEADER Names column in CSV containing new names for glyphs
+ --unicode COLHEADER Names column in CSV containing USVs to assign to glyphs
+```
+
+Glyphs to be copied are specified by the `INPUT` CSV file and/or on the command line.
+
+When provided, if the CSV file has only one column, a column header is not needed and each line names one glyph to be copied.
+
+If the CSV file has more than one column, then it must have headers, including at least:
+
+- `glyph_name` contains the name of the glyph in the SOURCE that is to be copied.
+
+If `--rename` parameter is supplied, it identifies the column that will provide a new name for the glyph in the target font. For any particular glyph, if this column is empty then the glyph is not renamed.
+
+If `--unicode` parameter is supplied, it identifies the column that provides an optional Unicode Scalar Value (USV) for the glyph in the target font. For any particular glyph, if this column is empty then the glyph will not be encoded.
+
+Glyphs to be copied can also be specified on the command line via one or more `--name` parameters. Glyphs specified in this way will not be renamed or encoded.
+
+If any glyph identified by the CSV or `--name` parameter already exists in the target font, it will not be overwritten unless the `--force` parameter is supplied.
+
+If any glyph being copied is a composite glyph, then its components are also copied. In the case that a component has the same name as a glyph already in the font, the component is renamed by appending `.copyN` (where N is 1, 2, 3, etc.) before being copied.
+
+Limitations:
+
+- At present, the postscript glyph names in the target font are left unchanged and may therefore be inaccurate. Use `psfsetpsnames` if needed.
+
+---
+#### psfcopymeta
+Usage: **`psfcopymeta [-r] fromfont tofont`**
+
+_([Standard options](docs.md#standard-command-line-options) also apply)_
+
+This copies selected fontlist.plist and lib.plist metadata (eg copyright, openTypeNameVersion, decender) between fonts in different (related) families.
+
+It is usually run against the master (regular) font in each family then data synced within family afterwards using [psfsyncmeta](#psfsyncmeta).
+
+Example usage:
+
+```
+psfcopymeta GentiumPlus-Regular.ufo GentiumBookPlus-Bold
+```
+
+If run with -r or \-\-reportonly it just reports what values would be updated.
+
+Look in psfcopymeta.py for a full list of metadata copied. Note that only fontinfo.plist and lib.plist are updated; the target font is not normalized.
+
+Also psfcopymeta does not use Pysilfont's backup mechanism for fonts.
+
+---
+#### psfcreateinstances
+Usage:
+
+**`psfcreateinstances -f [--roundInstances] designspace_file_or_folder`**
+
+**`psfcreateinstances [-i INSTANCENAME] [-a INSTANCEATTR] [-v INSTANCEVAL] [-o OUTPUT]
+[--forceInterpolation] [--roundInstances] [--weightfix|-W] designspace_file`**
+
+
+Create one or more instance UFOs from one or more designspace files.
+
+There are two modes of operation, differentiated by the `-f` (folder) option:
+
+When `-f` is specified:
+- the final parameter can be either:
+ - a single designspace file
+ - a folder, in which case all designspace files within the folder are processed.
+- all instances specified in the designspace file(s) are created.
+- interpolation is always done, even when the designspace coordinates of an instance match a master.
+
+Omitting the `-f` requires that the final parameter be a designspace file (not a folder) but gives more control over instance creation, as follows:
+
+- Specific instance(s) to be created can be identified by either:
+ - instance name, specified by `-i`, or
+ - a point on one of the defined axes, specified by `-a` and `-v`. If more than one instance matches this axis value, all are built.
+- The default location for the generated UFO(s) can be changed using `-o` option to specify a path to be prefixed to that specified in the designspace.
+- In cases where the designspace coordinates of an instance match a master, glyphs will be copied rather than interpolated, which is useful for masters that do not have compatible glyph designs and thus cannot be interpolated. This behavior can be overridden using the `--forceInterpolation` option.
+
+Whenever interpolation is done, the calculations can result in non-integer values within the instance UFOs. The `--roundInstances` option will apply integer rounding to all such values.
+
+Instance weights are set based on the axes mapping in the designspace file.
+If the weight is missing from the axes mapping a dummy value of 399 is set.
+
+When `--weightfix` (or `-W`) is provided, instance weights are set to either 700 (Bold) or 400 (Regular) based on
+whether or not the `stylemapstylename` instance attribute begins with `bold`.
+
+---
+#### psfcsv2comp
+Usage: **`psfcsv2comp [-i INPUT] [--gname GNAME] [--base BASE] [--anchors ANCHORS] [--usv USV] output.txt`**
+
+_([Standard options](docs.md#standard-command-line-options) also apply)_
+
+Create a composite definitions file based on data extracted from a csv file.
+
+The INPUT csv file must have column headers and must include columns for the following data:
+- the name of the composite glyph
+- the name of the base glyph used to create the composites
+- one column for each possible anchor to which a component can be attached. The column headers identify the name of the anchor to be used, and the column content names the glyph (if any) to be attached at that anchor.
+
+Optionally, another column can be used to specify the USV (codepoint) for the composite.
+
+Command-line options:
+
+- INPUT: Name of input csv file (default `glyph_data.csv`)
+- GNAME: the column header for the column that contains the name of the composite glyph (default `gname`)
+- BASE: the column header for the column that contains the base of the composites (default `base`)
+- ANCHORS: comma-separated list of column headers naming the attachment points (default `above,below`).
+- USV: the column header for the column that contains hexadecimal USV
+
+**Limitations:** At present, this tool supports only a small subset of the capabilities of composite definition syntax. Note, in particular, that it assumes all components are attached to the _base_ rather than the _previous glyph_.
+
+---
+#### psfdeflang
+Usage: **`psfdeflang -L lang infont [outfont]`**
+
+_([Standard options](docs.md#standard-command-line-options) also apply)_
+
+This changes the default language behaviour of a .ttf font from its current default to that of the language specified. It supports both OpenType and Graphite tables.
+
+For example this command creates a new font which by default has Khamti behaviour:
+
+```
+psfdeflang -L kht Padauk-Regular.ttf Padauk_kht-Regular.ttf
+```
+
+---
+#### psfdeleteglyphs
+Usage: **`psfdeleteglyphs [-i DELETELIST] [--reverse] infont [outfont]`**
+
+_([Standard options](docs.md#standard-command-line-options) also apply)_
+
+This deletes glyphs in a UFO based on an external file with one glyphname per line.
+The `--reverse` option will instead delete all glyphs in the UFO that are not in the list.
+
+It only deletes glyphs that do exist in the default layer, but for such glyphs they are also deleted from other layers, as well as in groups.plist and kerning.plist.
+Kern groups based on the glyph name, ie public.kern1._glyphname_ or public.kern2._glyphname_ are also deleted.
+
+It does not analyze composites, so be careful not to delete glyphs that are referenced as components in other glyphs.
+
+The following example will delete all glyphs that are _not_ listed in `keepthese.txt`:
+
+```
+psfdeleteglyphs Andika-Regular.ufo -i keepthese.txt --reverse
+```
+
+---
+#### psfdupglyphs
+Usage: **`psfdupglyphs [-i INPUT] [--reverse] infont [outfont]`**
+
+_([Standard options](docs.md#standard-command-line-options) also apply)_
+
+This duplicates glyphs in a UFO based on a csv definition: source,target. It duplicates everything except unicodes.
+
+Example usage:
+
+```
+psfdupglyphs Andika-Regular.ufo -i dup.csv
+```
+
+---
+#### psfexportanchors
+Usage: **`psfexportanchors [-r {X,S,E,P,W,I,V}] [-g] [-s] ifont [output]`**
+
+_([Standard options](docs.md#standard-command-line-options) also apply)_
+
+This exports anchor data from a UFO font to an XML file. (An "anchor" is also called an "attachment point" which is sometimes abbreviated to "AP".)
+
+Example that exports the anchors contained in the UFO font `CharisSIL-Regular.ufo`, sorts the resulting glyph elements by public.glyphOrder rather than glyph ID (GID), and writes them to an XML file `CharisSIL-Regular_ap.xml`.
+
+```
+psfexportanchors -s font-charis/source/CharisSIL-Regular.ufo CharisSIL-Regular_ap.xml
+```
+
+If the command line includes
+
+- -g, then the GID attribute will be present in the glyph element.
+- -s, then the glyph elements will be sorted by public.glyphOrder in lib.plist (rather than by GID attribute).
+- -u, then the UID attribute will include a "U+" prefix
+
+---
+#### psfexportmarkcolors
+Usage: **`psfexportmarkcolors [-c COLOR] [-n] [-o OUTPUT] [--nocomments] ifont`**
+
+_([Standard options](docs.md#standard-command-line-options) also apply)_
+
+This exports a mapping of glyph name to cell mark color to a csv file, format "glyphname,colordef".
+Colordef is exported as a double-quoted string according to the [color definition standard](http://unifiedfontobject.org/versions/ufo3/conventions/#colors). It includes comments at the start saying when it was run etc unless --nocomments is specified. The csv produced will include all glyphs, whether or not they have a color definition.
+
+In some cases (see options below) colors can be reported or referred to by text names as in "g_purple". See [Specifying colors on the command line](#specifying-colors-on-the-command-line)
+
+If the command line includes
+
+- -c COLOR, then the script will instead produce a list of glyph names, one per line, of glyphs that match that single color.
+- -n, then the csv file will report colors using text names (see above) rather than using numerical definitions.
+If there is no name that matches a particular color definition then it will be exported numerically.
+
+Example that exports a csv file (glyphname, colordef) listing every glyph and its color as in `LtnSmA,"0.5,0.09,0.79,1"`:
+
+```
+psfexportmarkcolors Andika-Regular.ufo -o markcolors.csv
+```
+
+Example that exports a list of glyphs that are colored purple:
+
+```
+psfexportmarkcolors Andika-Regular.ufo -o glyphlist.txt -c "g_purple"
+```
+
+---
+#### psfexportpsnames
+Usage: **`psfexportpsnames [-o OUTPUT] [--nocomments] ifont`**
+
+_([Standard options](docs.md#standard-command-line-options) also apply)_
+
+Export a mapping of glyph name to postscript name to a csv file, format "glyphname,postscriptname"
+
+It includes comments at the start saying when it was run etc unless \-\-nocomments is specified
+
+---
+#### psfexportunicodes
+Usage: **`psfexportunicodes [-o OUTPUT] [--nocomments] [--allglyphs] ifont`**
+
+_([Standard options](docs.md#standard-command-line-options) also apply)_
+
+Export a mapping of glyph name to unicode to a csv file, format "glyphname,unicode" for glyphs that have a defined unicode. _Note: multiple-encoded glyphs will be ignored._
+
+It includes comments at the start saying when it was run etc unless \-\-nocomments is specified
+
+A complete list of glyphs (both encoded and unencoded) can be generated with \-\-allglyphs.
+
+---
+#### psffixffglifs
+Usage: **`psffixffglifs ifont [ofont]`**
+
+_([Standard options](docs.md#standard-command-line-options) also apply)_
+
+Make changes needed to a UFO following processing by FontForge. Currently FontForge copies advance and unicode fields from the default layer to the background layer; this script removes all advance and unicode fields from the background layer.
+
+Note that other changes are reversed by standard [normalization](docs.md#Normalization) and more by using pysilfont's standard check&fix system, so running psffixffglyphs with check&fix may be useful:
+
+```
+psffixffglifs font.ufo -p checkfix=y
+```
+
+#### psffixfontlab
+Usage: **`psffixfontlab ifont` **
+
+_([Standard options](docs.md#standard-command-line-options) also apply)_
+
+Make changes needed to a UFO following processing by FontLab, including restoring information from the backup of the UFO.
+
+When exporting from Fontlab, the option _Existing Font Files:_ must be set to _rename_ in order to create the backup needed.
+If there are multiple backup files, the oldest will be used on the assumption that several exports have been run since psffixfontlab was last used.
+So it is important that any old backups are deleted before re-editing a font.
+
+The changes made by `psffixfontlab` include:
+- Restoring groups.plist, kerning.plist and any layerinfo.plist files from the backups
+- Deleting various keys from fontinfo.list and lib.plist
+- Restoring guidelines in fontinfo.plist and plublic.glyphOrder from lib.plist
+
+Sample usage
+```
+psffixfontlab font.ufo -p checkfix=None
+```
+Notes
+- The above example has checkfix=None, since otherwise it will report errors and warnings prior to the script fixing them
+- Pysilfont's normal backup mechanism for fonts is not used.
+
+---
+#### psfftml2TThtml
+Usage: **`usage: psfftml2TThtml --ftml FTML --xslt XSLT ttfont map`**
+
+_([Standard options](docs.md#standard-command-line-options) also apply)_
+
+Used for testing TypeTuner code, this tool:
+- for each FTML document supplied:
+ - based on the styles therein, creates TypeTuned fonts that should do the same thing
+ - emits an HTML document that shows the FTML data rendered using both:
+ - The original font (using font features or language tags)
+ - The corresponding TypeTuned font
+
+
+positional arguments:
+```
+ ttfont Input Tunable TTF file
+ map Feature mapping CSV file
+```
+
+The `map` parameter must be a CSV that maps names of font feature tags, font feature values and language tags used in the FTML document(s) to the corresponding TypeTuner feature names and values. For example the following CSV file:
+
+```
+# Language tag mappings:
+# lang=langtag,TT feat,value
+lang=sd,Language,Sindhi
+lang=ur,Language,Urdu
+
+# Feature tag mappings:
+# OT feature,TT feat,default,value 1,value 2,...
+cv48,Heh,Standard,Sindhi-style,Urdu-style
+```
+maps:
+- langtag `sd` to the TypeTuner feature named `Language` with value `Sindhi`
+- langtag `ur` to the TypeTuner feature named `Language` with value `Urdu`
+- font feature `cv48` to the TypeTuner feature named `Heh`, with following TypeTuner value names:
+ - cv48 value `0` to `Standard`
+ - cv48 value `1` to `Sindhi-style`
+ - cv48 value `2` to `Urdu-style`
+
+other arguments:
+```
+ -h, --help show this help message and exit
+ -o OUTPUTDIR, --outputdir OUTPUTDIR
+ Output directory, default: tests/typetuner
+ --ftml FTML ftml file(s) to process. Can be used multiple
+ times and can contain filename patterns.
+ --xsl XSL standard xsl file. Default: ../tools/ftml.xsl
+ --norebuild assume existing fonts are good
+ -l LOG, --log LOG Log file
+ -p PARAMS, --params PARAMS
+ Other parameters - see parameters.md for details
+ -q, --quiet Quiet mode - only display severe errors
+```
+
+For reliability, the program re-builds each needed font even if that font was built during a previous run of the program. For debugging, specifying `--norebuild` will speed up the program by assuming previously built fonts are usable.
+
+---
+#### psfftml2odt
+Usage: **`psfftml2odt [-f FONT] input [output]`**
+
+_([Standard options](docs.md#standard-command-line-options) also apply)_
+
+This creates a LibreOffice writer document based on input test data in [Font Test Markup Language](https://github.com/silnrsi/ftml) format and font information specified with command line parameters.
+
+Example that uses FTML input contained in the file `test-ss.xml` and creates a LibreOffice writer document named `test-ss.odt`. There will be two columns in the output document, one for the installed font `Andika New Basic` and one for the font contained in the file `AndikaNewBasic-Regular.ttf`. (This compares a newly built font with an installed reference.)
+
+```
+psfftml2odt -f "Andika New Basic" -f "AndikaNewBasic-Regular.ttf" test-ss.xml test-ss.odt
+```
+
+If the font specified with the -f parameter contains a '.' it is assumed to be a file name, otherwise it is assumed to be the name of an installed font. In the former case, the font is embedded in the .odt document, in the latter case the font is expected to be installed on the machine that views the .odt document.
+
+---
+#### psfgetglyphnames
+Usage: **`psfgetglyphnames [-i INPUT] [-a AGLFN] ifont glyphs`**
+
+_([Standard options](docs.md#standard-command-line-options) also apply)_
+
+Given a list of characters to import in INPUT
+(format is one character per line, using four or more hex digits)
+and a source UFO infont (probably the source of Latin glyphs for a non-roman font),
+create a list of glyphs to import for use with the
+[psfcopyglyphs](#psfcopyglyphs) tool.
+
+The AGLFN option will rename glyphs on import if found in the
+Adobe Glyph List For New Fonts (AGLFN).
+The format for this file is the same as the AGLFN from Adobe,
+except that the delimiter is a comma, not a semi-colon.
+
+---
+#### psfglyphs2ufo
+Usage: **`psfglyphs2ufo [--nofixes] [--nofea] [--preservefea] [--restore] fontfile.glyphs masterdir`**
+
+_([Standard options](docs.md#standard-command-line-options) also apply)_
+
+Exports one UFO file per master found in the fontfile.glyphs file, and places it in the directory specified as masterdir.
+
+In a round-trip ufo -> glyphs -> ufo there is currently there is some data loss in the standard glyphs
+-> ufo conversion, so (unless `--nofixes` is set) the script fixes some data and restores some fields from the original ufos if they are present in the masterdir.
+
+Additional fields to restore can be added using `-r, --restore`. This will restore the fields listed if found in either fontinfo.plist or lib.plist
+
+Currently features.fea does not round-trip successfully, so `--nofea` can be used to suppress the production of a features.fea file.
+
+To leave any features.fea files in existing UFOs untouched use `--preservefea`
+
+Example usage:
+
+```
+psfglyphs2ufo CharisSIL-RB.glyphs masterufos
+psfglyphs2ufo CharisSIL-RB.glyphs masterufos -r key1,key2
+```
+
+If this Glyphs file contains two masters, Regular and Bold, then it will export a UFO for each into a 'masterufos' directory. To have the fonts exported to the current directory, give it a blank directory name:
+
+```
+psfglyphs2ufo CharisSIL-RB.glyphs ""
+```
+---
+#### psfmakedeprecated
+Usage: **`psfmakedeprecated [-i INPUT] [--reverse] infont [outfont]`**
+
+_([Standard options](docs.md#standard-command-line-options) also apply)_
+
+Creates deprecated versions of glyphs: takes the specified glyph and creates a duplicate with an additional box surrounding it so that it becomes reversed, and assigns a new unicode encoding to it.
+Input is a csv with three fields: original,new,unicode
+
+Example usage:
+
+```
+psfmakedeprecated Andika-Regular.ufo -i deprecate.csv
+```
+
+---
+#### psfmakefea
+Usage: **`usage: psfmakefea [-i INPUT] [-o OUTPUT] [-c CLASSFILE]
+ [--classprops] [--omitaps OMITAPS] infile`**
+
+_([Standard options](docs.md#standard-command-line-options) also apply)_
+
+Creates OUTPUT feature (FEA) file by merging the INPUT feature (FEA or FEAX) file with information gleaned from an input UFO or [attachment point (AP)](https://metacpan.org/pod/distribution/Font-TTF-Scripts/scripts/ttfbuilder#Attachment-Points) xml file. For more information about FEAX see [Fea Extensions](feaextensions.md) documentation.
+
+required arguments:
+
+```
+ infile UFO or AP xml files
+ INPUT FEA or FEAX input file
+```
+
+optional arguments:
+```
+ OUTPUT name of FEA file to create (if not supplied, only error checking is done)
+ CLASSFILE name of xml class definition file
+ --classprops if specified, class properties will be read from CLASSFILE
+ OMITAPS comma-separated list of attachment points to ignore when creating classes
+```
+
+---
+#### psfmakescaledshifted
+Usage: **`psfmakescaledshifted [-c] [--color COLOR] -i INPUT -t TRANSFORM infont [outfont]`**
+
+_([Standard options](docs.md#standard-command-line-options) also apply)_
+
+Creates scaled and shifted versions of glyphs: takes the specified glyph and creates a duplicate that is scaled and shifted according to the specified transform, and assigns a new unicode encoding to it. Optional -c marks cells of generated glyphs (dark blue).
+
+Input is a csv with three fields: *original,new,unicode*.
+
+Transform takes two types of input:
+
+- a string of the form "(xx, xy, yx, yy, x, y)" where xx = amount to scale horizontally, yy = amount to scale vertically, x = amount to shift horizontally, y = amount to shift vertically. xy and yx are generally not used and remain 0.
+- the name of a specific type of transform defined in the UFO lib.plist *org.sil.lcg.transforms* key, such as superscript. Example:
+
+```
+<key>org.sil.lcg.transforms</key>
+<dict>
+ <key>superscript</key>
+ <dict>
+ <key>adjustMetrics</key>
+ <integer>0</integer>
+ <key>scaleX</key>
+ <real>0.66</real>
+ <key>scaleY</key>
+ <real>0.6</real>
+ <key>shiftX</key>
+ <integer>-125</integer>
+ <key>shiftY</key>
+ <integer>-460</integer>
+ <key>skew</key>
+ <real>-0.01</real>
+ </dict>
+</dict>
+```
+
+Note that this second type of input allows for two other parameters:
+
+- _adjustMetrics_ indicates how much additional space in units should be added to _both_ sides of the glyph.
+
+- _skew_ indicates how much the glyph should be skewed, with a skew of 1 indicating a 45° skew. The origin for the skew is (0,0).
+
+There are also two further transformation parameters that can be added to _org.sil.lcg.transforms_ solely for the purpose of documenting post-transformation manual design adjustments. **These are not read or applied by the script. They are only to hold information for the designer.**:
+
+- _manAdjustX_ indicates how much x-axis weight in units should be manually added to glyphs after the script has been applied.
+
+- _manAdjustY_ indicates how much y-axis weight in units should be manually added to glyphs after the script has been applied.
+
+Examples:
+
+```
+psfmakescaledshifted -i newglyphs.csv DoulosSIL-Regular.ufo -t "(0.72, 0, 0, 0.6, 10, 806)"
+```
+
+This will take the definitions in newglyphs.csv and create the new glyphs using a transformation that includes x-scale 72%, y-scale 60%, x-shift 10 units, y-shift 806 units.
+
+```
+psfmakescaledshifted -i newglyphs.csv DoulosSIL-Regular.ufo -t superscript
+```
+
+This will take the definitions in newglyphs.csv and create the new glyphs using the *superscript* transformation defined in the UFO lib.plist *org.sil.lcg.transforms* key.
+
+`-c` or `--color COLOR` can be used to set the mark color for the generated glyphs. `-c` sets the color to blue, and with
+`--color` the color specified as described in [Specifying colors on the command line](#specifying-colors-on-the-command-line)
+
+---
+#### psfmakewoffmetadata
+Usage: **`psfmakewoffmetadata -n PRIMARYFONTNAME -i ORGID [-f FONTLOG] [-o OUTPUT] [--populateufowoff] fontfile.ufo`**
+
+
+Make the WOFF metadata xml file based on input UFO. If woffMetadataCredits and/or woffMetadataDescription are missing
+from the UFO, they will be constructed from FONTLOG - see below
+
+The primary font name and orgid need to be supplied on the command line. By default it outputs to *primaryfontname*-WOFF-metadata.xml.
+
+Example:
+
+```
+psfmakewoffmetadata -n "Nokyung" -i "org.sil.fonts" source/Nokyung-Regular.ufo
+```
+
+It constructs the information needed from:
+
+- The supplied primary font name and orgid
+- Information within the primary font file
+
+If it needs to construct the credits and description fields from FONTLOG, that file needs to be formatted according to the
+pattern used for most SIL font packages.
+The description is created using the contents of the FONTLOG, starting after the "Basic Font Information" header
+and finishing before the "Information for Contributors" header (if present) or the "Acknowledgements" header otherwise.
+The credits are created from the N:, W:, D: and E: sets of values in the acknowledgements section, though E: is not used.
+One credit is created from each set of values and sets should be separated by blank lines.
+By default it reads FONTLOG.txt from the folder it is run in.
+
+If woffMetadataCredits and woffMetadataDescription are missing from the UFO you can use `--populateufowoff` to update
+these fields with the values constructed from FONTLOG:
+```
+ --populateufowoff Add woffMetadataCredits and woffMetadataDescription to UFO if missing
+```
+--popoulateufowoff also adds a place-holder url to woffMetadataDescription which should be hand-edited afterwards to a url appropirate to the project.
+
+---
+#### psfnormalize
+Usage: **`psfnormalize [-v VERSION] ifont [ofont]`**
+
+_([Standard options](docs.md#standard-command-line-options) also apply)_
+
+This normalizes a UFO font (and optionally converts from one version to another if -v is specified). _Note that most pysilfont scripts automatically output normalized UFOs, so psfnormalize is normally only needed after fonts have been processed by external font tools._
+
+Example that normalizes the named font:
+
+```
+psfnormalize Nokyung-Regular.ufo
+```
+
+The normalization follows the [default behaviours](docs.md#normalization), but these can be overridden using [custom parameters](parameters.md)
+
+\-v VERSION can be 2, 3
+
+If you are a macOS user, see _pysilfont/actionsosx/README.txt_ to install an action that will enable you to run psfnormalize without using the command line.
+
+---
+#### psfremovegliflibkeys
+Usage: **`psfremovegliflibkeys [-o OFONT] ifont [key [key ...]] [-b [BEGINS [BEGINS ...]]]`**
+
+_([Standard options](docs.md#standard-command-line-options) also apply)_
+
+This removes the specified key(s) from the lib section of .glif files if they exist.
+
+```
+psfremovegliflibkeys GentiumPlus-Regular.ufo key1 key2 -b start1 start2
+```
+
+This will remove any keys that match key1 or key2 or begin with start1 or start2
+
+Note - Special handling for com.schriftgestaltung.Glyphs.originalWidth:
+- Due to a glyphsLib bug, advance width is sometimes moved to this key, so if this key is set for deletion
+ - If advance width is not set in the glif, it is set to com.schriftgestaltung.Glyphs.originalWidth
+ - com.schriftgestaltung.Glyphs.originalWidth is then deleted
+
+---
+#### psfrenameglyphs
+Usage: **`psfrenameglyphs [--mergecomps] [-c CLASSFILE] -i INPUT ifont [ofont]`**
+
+_([Standard options](docs.md#standard-command-line-options) also apply)_
+
+Assign new working names to glyphs based on csv input file, format "oldname,newname". The algorithm will handle circular rename specifications such as:
+```
+glyph1,glyph2
+glyph2,glyph1
+```
+Unless default value for `renameGlyphs` [parameter](parameters.md) is overridden, the .glif filenames in the UFO will also be adjusted.
+
+This program modifies the glyphs themselves and, if present in lib.plist, the `public.glyphOrder`, `public.postscriptNames`, `com.schriftgestaltung.glyphOrder` and `com.schriftgestaltung.customParameter.GSFont.DisplayStrings` definitions. Any composite glyphs that reference renamed glyphs are adjusted accordingly.
+
+If groups.plist is present, glyph names in groups are renamed. In addition, groups named public.kern1._glyphname_ or public.kern2._glyphname_ will also be renamed, but group names not matching that pattern are left unchanged.
+
+If kerning.plist is present, glyph names in kern pairs are changed and kern group names that match the pattern described above are also changed.
+
+If -c specified, the changes are also made to the named classes definition file.
+
+When there are multiple layers in the UFO, glyphs will be renamed in all layers providing the glyph is in the default layer. If the glyph is only in non-default layers the glyph will need renaming manually.
+
+In normal usage, all oldnames and all newnames mentioned in the csv must be unique.
+
+The `--mergecomps` option enables special processing that allows newnames to occur more than once in the csv, with the result that the first mention is a normal rename while subsequent mentions indicate glyphs that should be deleted but any references updated to the first (renamed) glyph. Any moving anchors (i.e., those whose names start with `_`) on the deleted glyphs will be copied to the first glyph. For example:
+```
+dotabove,dot1 # this glyph has _above anchor
+dotbelow,dot1 # this glyph has _below anchor
+dotcenter,dot1 # this glyph has _center anchor
+```
+would cause `dotabove` to be renamed `dot1` while `dotbelow` and `dotabove` would be deleted. Any composite glyphs that reference any of `dotabove`, `dotbelow`, or `dotcenter` will be adjusted to refer to `dot1`. The `_below` anchor from `dotbelow` and the `_center` anchor from `dotcenter` will be copied to `dot1` (overwriting any anchors by the same names).
+
+Any `--mergecomps` run should be done in a separate run of `psfrenameglyphs` from other renaming, and group and kerning data is not processed on mergecomps runs.
+
+---
+#### psfrunfbchecks
+Usage: **`psfrunfbchecks [--profile PROFILE] [--html HTMLFILE] [--csv CSV]
+ [--full-lists] [--ttfaudit] fonts [fonts ...]`**
+
+_([Standard options](docs.md#standard-command-line-options) also apply)_
+
+Run Font Bakery tests using a standard profile and report results in a table on screen. Multiple fonts can be specified,
+including using wildcards, but all should be in the same directory.
+
+Currently this just works for ttf files, and the default profile used will be Pysilfont's ttfchecks.py.
+
+An alternative profile can be specified with `--profile`. This profile needs to be specifically designed to work with this script - see examples/fbttfchecks.py. This profile amends the behaviour of ttfchecks.py and includes options to change which checks are run and to override the status reported by checks. Project-specific checks can also be added.
+
+Example use with a project-specific profile:
+
+```
+psfrunfbchecks --profile fbttfchecks.py results/*.ttf
+```
+To see more details of results, use `--html HTMLFILE` to write an html file in the same format that Font Bakery outputs.
+
+`--csv CSV` creates a csv file with one line per check that is run. This can be used with diff tools to compare results from different runs (or following upgrades to Font Bakery.)
+
+Pysilfont's standard logging parameters (-p scrlevel and -p loglevel) also change the level of information `psfrunfbchecks` outputs.
+
+By default Font Bakery truncates long lists of items within check reports. Use `--full-lists` to get full lists of items.
+
+A special option, `--ttfaudit` compares the list of checks within ttfchecks.py against those in Font Bakery and reports any descrepancies to screen.
+It also writes a csv file containing a list of all checks. Usage `psfrunfbchecks --ttfaudit csvfile`
+
+---
+#### psfsetassocfeat
+Usage: **`psfsetassocfeat [-i INPUT] ifont [ofont]`**
+
+_([Standard options](docs.md#standard-command-line-options) also apply)_
+
+Add associate feature info to org.sil.assocFeatureValue glif lib based on a csv file, format "glyphname,featurename[,featurevalue]"
+
+---
+#### psfsetassocuids
+Usage: **`psfsetassocuids [-i INPUT] ifont [ofont]`**
+
+_([Standard options](docs.md#standard-command-line-options) also apply)_
+
+Add associate UID info to org.sil.assocUIDs in glif lib based on a csv file - could be one value for variant UIDs and multiple for ligatures, format "glyphname,UID[,UID]"
+
+---
+#### psfsetdummydsig
+Usage: **`psfsetdummydsig -i inputfont -o outputfont`**
+
+_([Standard options](docs.md#standard-command-line-options) also apply)_
+
+Put a dummy DSIG table into a font in TTF format (using fontTools)
+
+```
+-i [--ifont] inputfont (Input file in TTF format)
+-o [--ofont] outputfont (Output file in TTF format)
+```
+---
+#### psfsetglyphdata
+Usage: **`psfsetglyphdata [-a ADDCSV] [-d DELETIONS] [-s SORTHEADER] [--sortalpha] [-f] glyphdata [outglyphdata]`**
+
+_([Standard options](docs.md#standard-command-line-options) also apply)_
+
+Update a csv containing glyph data. The updates can be:
+ - Additions, based on an input csv
+ - Deletions, based on a text file with a list of glyph names
+ - Sorting based on a column header
+
+Any combination of the above can be used.
+```
+ glyphdata glyph_data csv file to update
+ outglyphdata Alternative output file name
+ -a [--addcsv] Records to add to glyphdata
+ -d [--deletions] Records to delete from glyphdata
+ -s [--sortheader] Column header to sort by
+ --sortalpha Use with sortheader to sort alphabetically not numerically
+ -f, --force When adding, if glyph exists, overwrite existing data
+```
+
+The input glyph data file must have column headers, and those must include a glyph_name column.
+
+Headers are optional for ADDCSV:
+ - If no headers, the rows must contain the same number of fields (and in the same order) as the glyph data file
+ - If headers are used, then there must be a glyph_name header.
+ - Headers can be in any order, and if glyph data headers are missing, then those fields will be left empty
+
+If `--sortheader` is supplied then the file will be sorted by that column;
+otherwise the new records will be added to the end of the file.
+By default sorting is done numerically, but `--sortalpha` can be used for alphabetic sorting.
+
+If a glyph already exists, it won't be overwritten unless
+ - The glyph is in DELETIONS, since they are processed before additions
+ - `--force` is used to force overwriting of any existing glyphs
+
+---
+#### psfsetglyphorder
+Usage: **`psfsetglyphorder [--gname GNAME] [--header HEADER] [--field FIELD] [-i INPUT] [-x] ifont [ofont]`**
+
+_([Standard options](docs.md#standard-command-line-options) also apply)_
+
+From the INPUT file, load `public.glyphOrder` in lib.plist to control the order of glyphs in generated TTF files. FIELD can be used to specify a different order to load, such as `com.schriftgestaltung.glyphOrder`.
+
+The input file can be in one of two formats:
+- Plain text file with one glyph name per line in the desired order
+- csv file with headers using glyph_name and sort_final columns
+
+With the csv file:
+- The glyph names are sorted by the values in the sort_final column, which can be integer or real. HEADER can be used to specify alternate column header to sort_final. Multiple comma-separated values can be used with `--header` and `--field` to update two or more orders in a single command call.
+- GNAME can be used to specify column header to use instead of glyph_name.
+
+By default all entries in the input file are added, even if the glyph is not in the font. The UFO spec allows this so a common list can be used across groups of fonts. Use -x to only add entries for glyphs that exist in the font.
+
+Example that imports the data based on glyph_name and sort_final columns in the csv, only adding entries for glyphs in the font:
+```
+psfsetglyphorder Andika-Regular.ufo -i glyphdata.csv -x
+```
+Example that imports the data from the sort_final column to public.glyphorder and from the sort_designer into com.schriftgestaltung.glyphOrder:
+```
+psfsetglyphorder Andika-Regular.ufo -i glyphdata.csv --header sort_final,sort_designer --field public.glyphOrder,com.schriftgestaltung.glyphOrder
+```
+---
+#### psfsetkeys
+Usage: **`psfsetkeys [--plist PLIST] [-i INPUT] [-k KEY] [-v VALUE] [--file FILE] [--filepart FILEPART] ifont [ofont]`**
+
+_([Standard options](docs.md#standard-command-line-options) also apply)_
+
+Set keys in a UFO p-list file.
+A single key can be set by specifying KEY and one of VALUE, FILE, or FILEPART.
+VALUE should be a single line string, FILE and FILEPART should be a filename.
+With FILEPART, the contents of the file are read until the first blank line.
+This is useful for setting the copyright key from the OFL.txt file.
+
+Multiple keys can be set using a csv INPUT file, format "key,value".
+A filename to read cannot be specified in the csv file.
+
+By default keys are stored with type string in the UFO.
+Values of true or false are converted to type boolean.
+Values that can be converted to integer are stored as type integer.
+
+PLIST selects which p-list to modify.
+If not specified defaults to `fontinfo` which means the `fontinfo.plist` file is modified.
+
+Example:
+
+Set a key in the file `lib.plist`.
+```
+psfsetkeys --plist lib -k com.schriftgestaltung.width -v Regular font.ufo
+```
+
+---
+#### psfsetmarkcolors
+Usage: **`psfsetmarkcolors [-c COLOR] [-i INPUT] [-u] [-x] ifont [ofont]`**
+
+_([Standard options](docs.md#standard-command-line-options) also apply)_
+
+This sets the cell mark color of a glyph according to the [color definition standard](http://unifiedfontobject.org/versions/ufo3/conventions/#colors) based on a list of glyph names in INPUT, one glyph name per line.
+COLOR may be defined as described in [Specifying colors on the command line](#specifying-colors-on-the-command-line)
+
+If the command line includes:
+- -u, then the INPUT file will be treated as a list of unicode values rather than glyph names, and the color set on any glyph that is encoded with those unicode values.
+- -x, then the color definition will be removed altogether. If no INPUT is given all color definitions will be removed from all glyphs.
+
+Example that sets the cell mark color of all glyphs listed in glyphlist.txt to purple (0.5,0.09,0.79,1):
+```
+psfsetmarkcolors Andika-Regular.ufo -i glyphlist.txt -c "0.5,0.09,0.79,1"
+```
+Example that sets the cell mark color of all glyphs that have the unicode values listed in unicode.txt to purple (0.5,0.09,0.79,1):
+```
+psfsetmarkcolorss Andika-Regular.ufo -u -i unicode.txt -c "g_purple"
+```
+Example that sets the cell mark color of all glyphs that have the unicode values listed in unicode.txt to purple (0.5,0.09,0.79,1):
+```
+psfsetmarkcolors Andika-Regular.ufo -u -i unicode.txt -c "g_purple"
+```
+Example that removes all color definitions from all glyphs: (this is effectively equivalent to `psfremovegliflibkeys Andika-Regular.ufo public.markColor`)
+```
+psfsetmarkcolors Andika-Regular.ufo -x
+```
+
+---
+#### psfsetpsnames
+Usage: **`psfsetpsnames [--gname GNAME] [-i INPUT] [-x] ifont [ofont]`**
+
+_([Standard options](docs.md#standard-command-line-options) also apply)_
+
+From the INPUT file, populate `public.postscriptName` in lib.plist to specify final production names for glyphs.
+
+The input file can be in one of two formats:
+- simple csv in form glyphname,postscriptname
+- csv file with headers using glyph_name and ps_name columns
+
+With the csv file, GNAME can be used to specify column header to use instead of glyph_name.
+
+By default all entries in the input file are added, even if the glyph is not in the font. The UFO spec allows this so a common list can be used across groups of fonts. Use -x to only add entries for glyphs that exist in the font.
+
+Example usage:
+```
+psfsetpsnames Andika-Regular.ufo -i psnames.txt
+```
+
+---
+#### psfsetunicodes
+Usage: **`psfsetunicodes [-i INPUT] ifont [ofont]`**
+
+_([Standard options](docs.md#standard-command-line-options) also apply)_
+
+Set the unicodes of glyphs in a font based on a csv file with format "glyphname,UID [,UID2 [,UID3]]". Unicode values must be hex digits with no prefix.
+
+Up to 3 UIDs can be specified per glyph.
+
+Any existing Unicode values for the glyph will be removed, and any other glyph that has that same Unicode value will have that Unicode value removed.
+
+---
+#### psfsetversion
+Usage: **`psfsetversion font [newversion]`**
+
+_([Standard options](docs.md#standard-command-line-options) also apply)_
+
+This updates the various font version fields based on 'newversion' supplied which may be:
+
+- Full openTypeNameVersion string, except for the opening "Version " text, eg "1.234 beta2"
+- +1 to increment to the patch version number - see below
+- not supplied, in which case the current values will be validated and existing openTypeNameVersion string displayed
+
+It will update the openTypeNameVersion, versionMajor and versionMinor fields. It works assuming that openTypeNameVersion is of the form:
+
+"Version M.mpp" or "Version M.mpp extrainfo", eg "Version 1.323 Beta2"
+
+
+Based on [FDBP](https://silnrsi.github.io/FDBP/en-US/Versioning.html), the version number is parsed as M.mpp where M is major, m is minor and pp is patch number. M matches the versionMajor and mpp the versionMinor fields.
+
+Incrementing will fail if either the openTypeNameVersion is not formatted correctly or the version numbers in there don’t match those in versionMajor and versionMinor.
+
+Examples of usage:
+
+```
+psfsetversion font.ufo "1.423"
+```
+
+will set:
+
+- openTypeNameVersion to "Version 1.423"
+- versionMajor to 1
+- versionMinor to 423
+
+`psfsetversion font.ufo +1`
+
+If values were originally as in the first example, openTypeNameVersion will be changed to "Version 1.424" and versionMinor to 424
+
+Note that only fontinfo.plist is updated, so the font is not normalized and Pysilfont's backup mechanism for fonts is not used.
+
+---
+#### psfshownames
+Usage: **`psfshownames [--bits] [--multiline] ifont [infont1 [ifont2]]`**
+
+_([Standard options](docs.md#standard-command-line-options) also apply)_
+
+Show fields from the name table and optionally various bits
+that control linking font styles into font families.
+The default output is a table, use the `--multiline` option to produce a line oriented output.
+
+Fonts have bits to indicate if they are a Regular (R), Bold (B), and or Italic (I) style.
+There are two groups of bits, one for Microsoft Windows (W), one for Apple macOS (M).
+If a bit for a particular style is set a W and/or M is shown to indicate which platform's
+set of bits is set. For Regular, there is not a corresponding bit for macOS.
+Therefore, if the Regular bit is set for Windows, then W- is displayed.
+The dash (-) indicates that macOS does not have that particular bit, not that the bit is 0.
+
+Similarly, there are bits for macOS to indicate if a font is normal, condensed, or extended width.
+Windows uses a number to indicate the width.
+As with the Regular style, there is no bit on macOS for normal width.
+
+More details are at the [Name String Example](https://docs.microsoft.com/en-us/typography/opentype/spec/namesmp) from Microsoft.
+
+Example usage:
+
+```
+psfshownames --bits Padauk-Regular.ttf
+```
+
+---
+#### psfsubset
+Usage: **`psfsubset -i INPUT [--header HEADER] ifont ofont`**
+
+_([Standard options](docs.md#standard-command-line-options) also apply)_
+
+This script writes an output UFO that is a subset of the input UFO. The subset contains only the glyphs identified in the INPUT file (plus any components needed for them).
+
+The INPUT file can be a plain text file (one glyph per line) or a csv file. In the case of csv, the HEADER parameter is used to indicate which column from the csv to use (default is `glyph_name`).
+
+Glyphs can be identified either by their name or the Unicode codepoint (USV). Glyph names and USVs can be intermixed in the list: anything that is between 4 and 6 hexadecimal digits is first processed as a USV and then, if there is no glyph encoded with that USV, processed as a glyph name.
+
+Glyph orders and psname mappings, if present in the font, are likewise subsetted.
+
+---
+#### psfsyncmasters
+Usage: **`psfsyncmasters primaryds [secondds] [--complex][-n]`**
+
+_([Standard options](docs.md#standard-command-line-options) also apply)_
+
+Synchronises/validates some fontinfo.plist and lib.plist metadata across a family of fonts based
+on a designspace file. It looks in the designspace file for a master with `info copy="1"` set then syncs the values from that master to other masters defined in the file.
+
+If a second designspace file is supplied, it also syncs to masters found in there.
+
+Some validation is different for complex families (ie not RIBBI families) - use `--complex` to inicate that a family is complex.
+
+Example usage:
+
+```
+psfsyncmasters CharisSIL.designspace
+```
+
+Note that only fontinfo.plist and lib.plist files are updated, so fonts are not normalized and Pysilfont's backup mechanism for fonts is not used.
+
+-n (--new) appends \_new to ufo and file names for testing purposes
+
+Note that currently the code also assumes a family is complex if the ufo names include 'master', though this check will
+removed in the future, so `--complex` should be used instead of relying on this.
+
+---
+#### psfsyncmeta
+Usage: **`psfsyncmeta [-s] [-m [MASTER]] [-r] [-n] [--normalize] ifont`**
+
+_([Standard options](docs.md#standard-command-line-options) also apply)_
+
+Verifies and synchronises some fontinfo.plist and lib.plist metadata across a family of fonts. By default it uses the regular font as the master and updates any other fonts that exist assuming standard name endings of -Regular, -Italic, -Bold and -BoldItalic. Optionally a single font file can be synced against any other font as master, regardless of file naming.
+
+Example usage for family of fonts:
+
+```
+psfsyncmeta CharisSIL-Regular.ufo
+```
+
+This will sync the metadata in CharisSIL-Italic, CharisSIL-Bold and CharisSIL-BoldItalic against values in CharisSIL-Regular. In addition it will verify certain fields in all fonts (including Regular) are valid and follow [FDBP](https://silnrsi.github.io/FDBP/en-US/index.html) best-practice standards.
+
+Example usages for a single font:
+
+```
+psfsyncmeta -s font-Italic.ufo
+psfsyncmeta -s font-Italic.ufo -m otherfont.ufo
+```
+The first will sync font-Italic against font-Regular and the second against otherfont.
+
+Look in psfsyncmeta.py for a full details of metadata actions.
+
+Note that by default only fontinfo.plist and lib.plist are updated, so fonts are not normalized. Use \-\-normalize to additionally normalize all fonts in the family.
+
+Also psfsyncmeta does not use Pysilfont's backup mechanism for fonts.
+
+-n (--new) appends \_new to ufo and file names for testing purposes
+
+---
+#### psftuneraliases
+Usage: **`psftuneraliases [-m map.csv] [-f font.ttf] feat_in.xml feat_out.xml`**
+
+_([Standard options](docs.md#standard-command-line-options) also apply)_
+
+Merges lookup identifiers gleaned from the map.csv file (emitted from [psfbuildfea](#psfbuildfea)), along with OpenType and Graphite feature identifiers (obtained from a compiled font), into the `<aliases>` section of a TypeTuner features.xml file. At least one of `-m` and `-f` must be provided.
+
+Aliases for OpenType features will generated only for the default language of each script and the alias names will be of the form `<featureTag>_<scriptTag>_dflt`. Alias names for Graphite features will be of the form `gr_<featureID>`.
+
+As per prior technology, the OpenType feature alias names do not distinguish between GSUB and GPOS lookups and features, therefore using the same lookup name or feature tag for both GSUB and GPOS will cause the program to exit with an error.
+
+---
+#### psfufo2glyphs
+Usage: **`psfufo2glyphs [--glyphsformat GLYPHSFORMAT] [--nofea] designspace [glyphsfile]`**
+
+_([Standard options](docs.md#standard-command-line-options) also apply)_
+
+This generate a glyphs files from a designspace file and associated UFO(s).
+
+If no glyphsfile is specified, one will be created in the same directory as the designspace file and based on the name of the designspace file.
+
+By default it creates the glyphs file in glyphs v2 file format, but this can be changed using `--glyphsformat 3`.
+Note that round-tripping using v3 format has not yet been tested.
+
+Use `--nofea` to suppress processing of any features.fea files present in the UFOs.
+
+Example usage:
+
+```
+psfglyphs2ufo AndikaItalic.designspace AndikaItalic.glyphs
+```
+
+Note: This is just bare-bones code at present so does the same as glyphsLib's ufo2glyphs command. It was designed so that data could be massaged, if necessary, on the way but no such need has been found so far
+
+---
+#### psfufo2ttf
+Usage: **`psfufo2ttf [--removeOverlaps] [--decomposeComponents] iufo ottf`**
+
+_([Standard options](docs.md#standard-command-line-options) also apply)_
+
+This is based on ufo2ft and generates a ttf file without OpenType tables from a UFO.
+
+If `--removeOverlaps` is used it merges overlapping contours
+
+ufo2ft filters
+
+- The decomposeTransformedComponents and flattenComponents filters are always used
+- decomposeComponents is used if `--decomposeComponents` is set (or the filter is set in lib.plist)
+- Other ufo2ft filters can also be set in lib.plist - see ufo2ft documentation for details
+
+---
+#### psfversion
+Usage: **`psfversion`**
+
+This displays version info for pysilfont and many of its dependencies. It is intended for troubleshooting purposes - eg send the output in if reporting a problem - and includes which version of Python is being used and where the code is being executed from.
+
+---
+#### psfwoffit
+Usage: **`usage: psfwoffit[-m METADATA] [--privatedata PRIVATEDATA] [-v VERSION]
+ [--ttf [TTF] [--woff [WOFF]] [--woff2 [WOFF2]] infont`**
+
+_([Standard options](docs.md#standard-command-line-options) also apply)_
+
+Converts between ttf, woff, and woff2
+
+required arguments:
+
+```
+ infont an input font; can be ttf, woff, or woff2
+```
+
+optional arguments:
+```
+ -m METADATA, --metadata METADATA
+ file containing XML WOFF metadata
+ --privatedata PRIVATEDATA
+ file containing WOFF privatedata
+ -v VERSION, --version VERSION
+ woff font version number in major.minor
+ --ttf [TTF] name of ttf file to be written
+ --woff [WOFF] name of woff file to be written
+ --woff2 [WOFF2] name of woff2 file to be written
+```
+The `--version`, `--metatadata` and `--privatedata` provide data to be added to the WOFF file.
+Each of these is optional and if absent the following rules apply
+
+* if the input file is woff or woff2:
+ * the missing values are copied from the input file
+* if the input file is a ttf:
+ * missing `metadata` or `privatedata` will be empty in the output fonts
+ * the version will be taken from the `fontRevison` field of the `head` table of the input ttf file.
+
+The output filenames can be omitted (as long as another option follows) or `-`; in either case
+the output filename are calculated from the `infont` parameter.
+
+Examples:
+
+```
+psfwoffit --woff2 output.woff2 input.woff
+```
+creates an output woff2 font file from an input woff font file, copying the version as well any metadata and privatedata from the input woff.
+
+```
+psfwoffit -m woffmetadata.xml -v 1.3 --woff output.woff --woff2 output.woff2 input.ttf
+```
+creates explicitly named woff and woff2 font files from an input ttf, setting woff metadata and version from the command line.
+
+```
+psfwoffit --woff --woff2 -m woffmetadata.xml -v 1.3 path/font.ttf
+```
+creates implicitly named `path/font.woff` and `path/font.woff2`, setting woff metadata and version from the command line.
+
+```
+psfwoffit --woff - --woff2 - -m woffmetadata.xml path/to/font.ttf
+```
+same as above but uses font version from the ttf.
+
+---
+#### psfxml2compdef
+Usage: **`psfxml2compdef input output`**
+
+_([Standard options](docs.md#standard-command-line-options) also apply)_
+
+Convert composite definition file from XML format
+
+_This section is Work In Progress!_
+
+- input Input file of CD in XML format
+- output Output file of CD in single line format
+
+
+---
+
+### Specifying colors on the command line
+
+A color can be specified as a name (eg g_dark_green) or in RBGA format (eg (0,0.67,0.91,1)).
+
+Where multiple colors are supplied they should be separated by commas.
+
+Two special cases are also allowed (if applicable for the script):
+
+- "none" where the color should be removed
+- "leave" where any existing color should be left unchanged
+
+All values are case-insensitive
+
+Examples:
+
+```
+--colors="g_cyan,g_blue"
+--colors="g_dark_green, leave, (0,0.67,0.91,1)"
+--color=g_red
+```
+Color names can be one of the 12 cell colors definable in the GlyphsApp UI: g_red, g_orange, g_brown, g_yellow,
+ g_light_green, g_dark_green, g_cyan, g_blue, g_purple, g_pink, g_light_gray, g_dark_gray.
+
+
+
+## Example Scripts
+
+When Pysilfont is downloaded, there are example scripts in pysilfont/examples. These are a mixture of scripts that are under development, scripts that work but would likely need amending for a specific project's need and others that are just examples of how things could be done. Deprecated scripts are also placed in there.
+
+See [examples.md](examples.md) for further information
diff --git a/docs/technical.md b/docs/technical.md
new file mode 100644
index 0000000..e2089e3
--- /dev/null
+++ b/docs/technical.md
@@ -0,0 +1,342 @@
+# Pysilfont Technical Documentation
+This section is for script writers and developers.
+
+See [docs.md](docs.md) for the main Pysilfont user documentation.
+
+# Writing scripts
+The Pysilfont modules are designed so that all scripts operate using a standard framework based on the execute() command in core.py. The purpose of the framework is to:
+- Simplify the writing of scripts, with much work (eg parameter parsing, opening fonts) being handled there rather than within the script.
+- Provide a consistent user interface for all Pysilfont command-line scripts
+
+The framework covers:
+- Parsing arguments (parameters and options)
+- Defaults for arguments
+- Extended parameter support by command-line or config file
+- Producing help text
+- Opening fonts and other files
+- Outputting fonts (including normalization for UFO fonts)
+- Initial error handling
+- Reporting (logging) - both to screen and log file
+
+## Basic use of the framework
+
+The structure of a command-line script should be:
+```
+<header lines>
+<general imports, if any>
+
+from silfont.core import execute
+
+argspec = [ <parameter/option definitions> ]
+
+def doit(args):
+ <main script code>
+ return <output font, if any>
+
+<other function definitions>
+
+def cmd() : execute(Tool,doit, argspec)
+if __name__ == "__main__": cmd()
+```
+
+The following sections work through this, using psfnormalize, which normalizes a UFO, with the option to convert between different UFO versions:
+```
+#!/usr/bin/env python
+'''Normalize a UFO and optionally convert between UFO2 and UFO3.
+- If no options are chosen, the output font will simply be a normalized version of the font.'''
+__url__ = 'http://github.com/silnrsi/pysilfont'
+__copyright__ = 'Copyright (c) 2015 SIL International (http://www.sil.org)'
+__license__ = 'Released under the MIT License (http://opensource.org/licenses/MIT)'
+__author__ = 'David Raymond'
+
+from silfont.core import execute
+
+argspec = [
+ ('ifont',{'help': 'Input font file'}, {'type': 'infont'}),
+ ('ofont',{'help': 'Output font file','nargs': '?' }, {'type': 'outfont'}),
+ ('-l','--log',{'help': 'Log file'}, {'type': 'outfile', 'def': '_conv.log'}),
+ ('-v','--version',{'help': 'UFO version to convert to'},{})]
+
+def doit(args) :
+
+ if args.version is not None : args.ifont.outparams['UFOversion'] = args.version
+
+ return args.ifont
+
+def cmd() : execute("UFO",doit, argspec)
+if __name__ == "__main__": cmd()
+```
+#### Header lines
+Sample headers:
+```
+#!/usr/bin/env python
+'''Normalize a UFO and optionally convert between UFO2 and UFO3.
+- If no options are chosen, the output font will simply be a normalized version of the font.'''
+__url__ = 'http://github.com/silnrsi/pysilfont'
+__copyright__ = 'Copyright (c) 2015 SIL International (http://www.sil.org)'
+__license__ = 'Released under the MIT License (http://opensource.org/licenses/MIT)'
+__author__ = 'David Raymond'
+```
+As well as providing the information for someone looking at the source file, the description comment (second line, which can be multi-line) is used by the framework when constructing the help text.
+
+#### Import statement(s)
+```
+from silfont.core import execute
+```
+is required. Other imports from pysilfont or other libraries should be added, if needed.
+#### Argument specification
+The argument specifications take the form of a list of tuples, with one tuple per argument, eg:
+```
+argspec = [
+ ('ifont',{'help': 'Input font file'}, {'type': 'infont'}),
+ ('ofont',{'help': 'Output font file','nargs': '?' }, {'type': 'outfont'}),
+ ('-l','--log',{'help': 'Log file'}, {'type': 'outfile', 'def': '_conv.log'}),
+ ('-v','--version',{'help': 'UFO version to convert to'},{})]
+```
+Each argument has the format:
+```
+(argument name(s),argparse dict,framework dict)
+```
+argument name is either
+- name for positional parameters, eg *‘ifont’*
+- *-n, --name* or *--name* for other arguments, eg *‘-v’, ‘--version’*
+
+**argparse dict** follows standard [argparse usage for .add_argument()](https://docs.python.org/2/library/argparse.html#the-add-argument-method). Help should always be included.
+
+**framework dict** has optional values for:
+- ‘type’ - the type of parameter, eg ‘outfile’
+- ‘def’ - default for file names. Only applies if ‘type’ is a font or file.
+- 'optlog' - For logs only. Flag to indicate the log file is optional - default False
+
+‘Type’ can be one of:
+
+| Value | Action |
+|-------|-------------------------------------|
+|infont|Open a font of that name and pass the font to the main function|
+|outfont|If the main function to returns a font, save that to the supplied name|
+|infile|Open a file for read and pass the file handle to the main function|
+|incsv|Open a [csv](#support-for-csv-files) file for input and pass iterator to the main function|
+|outfile|Open a file for writing and pass the file handle to the main function|
+|filename|Filename to be passed as text|
+|optiondict|Expects multiple values in the form name=val and passes a dictionary containing them|
+
+If ‘def’ is supplied, the parameter value is passed through the [file name defaulting](#default-values-for-arguments) as specified below. Applies to all the above types except for optiondict.
+
+In addition to options supplied in argspec, the framework adds [standard options](docs.md#standard-command-line-options), ie:
+
+- -h, --help
+- -q, --quiet
+- -p, --params
+- -l, --log
+
+so these do not need to be included in argspec.
+
+With -l, --log, this is still usually set in argspec to create default log file names. Set optlog to False if you want the log file to be optional.
+
+#### doit() function
+The main code of the script is in the doit() function.
+
+The name is just by convention - it just needs to match what is passed to execute() at the end of the script. The
+execute() function passes an args object to doit() containing:
+- An entry for each command-line argument as appropriate, based on the full name of the argument
+ - eg with ``'-v','--version'``, args.version is set.
+ - Values are set for every entry in argspec, plus params, quiet and log added by the framework
+ - If no value is given on the command-line and the argument has no default then None is used.
+- logger for the loggerobj()
+- clarguments for a list of what was actually specified on the command line
+- For parameters:
+ - params is a list of what parameters, if any, were specified on the command line
+ - paramsobj is the parameters object containing all [parameter](parameters.md) details
+
+#### The final lines
+
+These should always be:
+```
+def cmd() : execute(Tool,doit, argspec)
+if __name__ == "__main__": cmd()
+```
+The first line defines the function that actually calls execute() to do the work, where Tool is one of:
+- “UFO” to open fonts with pysilfont’s ufo.py module, returning a Ufont object
+- “FP” to open fonts with fontParts, returning a font object
+- “FT” to open fonts with FontTools, returning a TTfont object
+- None if no font to be opened by execute()
+- Other tools may be added in the future
+
+The function must be called cmd(), since this is used by setup.py to install the commands.
+
+The second line is the python way of saying, if you run this file as a script (rather than using it as a python module), execute the cmd() function.
+
+Even if a script is initially just going to be used to be run manually, include these lines so no modification is needed to make it installable at a later date.
+
+# Further framework notes
+## Default values for arguments
+Default values in [docs.md](docs.md#default-values) describes how file name defaulting works from a user perspective.
+
+To set default values, either use the ‘default’ keyword in the argparse dict (for standard defaults) or the ‘def’ keyword in the framework dict to use Pysilfont’s file-name defaulting mechanism. Only one of these should be used. 'def' can't be used with the first positional parameter.
+
+Note if you want a fixed file name, ie to bypass the file name defaulting mechanism, then use the argparse default keyword.
+
+## Reporting
+args.logger is a loggerobj(), and used to report messages to screen and log file. If no log file is set, messages are just to screen.
+
+Messages are sent using
+```
+logger.log(<message text>, [severity level]>
+```
+Where severity level has a default value of W and can be set to one of:
+- X Exception - For fatal programming errors
+- S Severe - For fatal errors - eg input file missing
+- E Errors - For serious errors that must be reported to screen
+- P Progress - Progress messages
+- W Warning - General warnings about anything not correct
+- I Info - For more detailed reporting - eg the name of each glif file opened
+- V Verbose - For even more messages!
+
+Errors are reported to screen if the severity level is higher or equal to logger.scrlevel (default P) and to log based on loglevel (default W). The defaults for these can be set via parameters or within a script, if needed.
+
+With X and S, the script is terminated. S should be used for user problems (eg file does not exist, font is invalid) and X for programming issues (eg an invalid value has been set by code). Exception errors are mainly used by the libraries and force a stack trace.
+
+With Ufont objects, font.logger also points to the logger, but this is used primarily within the libraries rather than in scripts.
+
+There would normally only be a single logger object used by a script.
+
+### Changing reporting levels
+
+loglevel and scrlevel *can* be set by scripts, but care should be taken not to override values set on the command line. To increase screen logging temporarily, use logger.raisescrlevel(<new level>) then set to previous value with logger.resetscrlevel(), eg
+
+```
+ if not(args.quiet or "scrlevel" in params.sets["command line"]) :
+ logger.raisescrlevel("W") # Raise level to W if not already W or higher
+
+ <code>
+
+ logger.resetscrlevel()
+```
+
+### Error and warning counts
+
+These are kept in logger.errorcount and logger.warningcount.
+
+For scripts using the execute() framework, these counts are reported as progress messages when the script completes.
+
+## Support for csv files
+csv file support has been added to core.py with a csvreader() object (using the python csv module). In addition to the basic handling that the csv module provides, the following are supported:
+- csvreader.firstline returns the first line of the file, so analyse headers if needed. Iteration still starts with the first line.
+- Specifying the number of values expected (with minfields, maxfields, numfields)
+- Comments (lines starting with #) are ignored
+- Blank lines are also ignored
+
+The csvreader() object is an iterator which returns the next line in the file after validating it against the min, max and num settings, if any, so the script does not have to do such validation. For example:
+```
+incsv = csvreader(<filespec>)
+incsv.minfields = 2
+Incsv.maxfields = 3
+for line in inscv:
+ <code>
+```
+Will run `<code>` against each line in the file, skipping comments and blank lines. If any lines don’t have 2 or 3 fields, an error will be reported and the line skipped.
+
+## Parameters
+[Parameters.md](parameters.md) contains user, technical and developer’s notes on these.
+
+## Chaining
+With ufo.py scripts, core.py has a mechanism for chaining script function calls together to avoid writing a font to disk then reading it in again for the next call. In theory it could be used simply to call another script’s function from within a script.
+
+This has not yet been used in practice, and will be documented (and perhaps debugged!) when there is a need, but there are example scripts to show how it was designed to work.
+
+# pysilfont modules
+
+These notes should be read in conjunction with looking at the comments in the code (and the code itself!).
+
+## core.py
+
+This is the main module that has the code to support:
+- Reporting
+- Logging
+- The execute() function
+- Chaining
+- csvreader()
+
+## etutil.py
+
+Code to support xml handling based on xml.etree cElementTree objects. It covers the following:
+- ETWriter() - a general purpose pretty-printer for outputting xml in a normalized form including
+ - Various controls on indenting
+ - inline elements
+ - Sorting attributes based on a supplied order
+ - Setting decimal precision for specific attributes
+ - doctype, comments and commentsafter
+- xmlitem() class
+ - For reading and writing xml files
+ - Keeps record of original and final xml strings, so only needs to write to disk if changed
+- ETelement() class
+ - For handling an ElementTree element
+ - For each tag in the element, ETelement[tag] returns a list of sub-elements with that tag
+ - process_attributes() processes the attributes of the element based on a supplied spec
+ - process_subelements() processes the subelements of the element based on a supplied spec
+
+xmlitem() and ETelement() are mainly used as parent classes for other classes, eg in ufo.py.
+
+The process functions validate the attributes/subelements against the spec. See code comments for details.
+
+#### Immutable containers
+
+Both xmlitem and ETelement objects are immutable containers, where
+- object[name] can be used to reference items
+- the object can be iterated over
+- object.keys() returns a list of keys in the object
+
+however, values can't be set with `object[name] = ... `; rather values need to be set using methods within child objects. For example, with a Uglif object, you can refer to the Uadvance object with glif['advance'], but to add a Uadvance object you need to use glif.addObject().
+
+This is done so that values can be easily referenced and iterated over, but values can only be changed if appropriate methods have been defined.
+
+Other Pysilfont objects also use such immutable containers.
+
+## util.py
+
+Module for general utilities. Currently just contains dirtree code.
+
+#### dirTree
+
+A dirTree() object represents all the directories and files in a directory tree and keeps track of the status of the directories/files in various ways. It was designed for use with ufo.py, so, after changes to the ufo, only files that had been added or changed were written to disk and files that were no longer part of the ufo were deleted. Could have other uses!
+
+Each dirTreeItem() in the tree has details about the directory or file:
+- type
+ - "d" or "f" to indicate directory or file
+- dirtree
+ - For sub-directories, a dirtree() for the sub-directory
+- read
+ - Item has been read by the script
+- added
+ - Item has been added to dirtree, so does not exist on disk
+- changed
+ - Item has been changed, so may need updating on disk
+- towrite
+ - Item should be written out to disk
+- written
+ - Item has been written to disk
+- fileObject
+ - An object representing the file
+- fileType
+ - The type of the file object
+- flags
+ - Any other flags a script might need
+
+
+## ufo.py
+
+See [ufo.md](ufo.md) for details
+
+## ftml.py
+
+To be written
+
+## comp.py
+
+To be written
+
+# Developer's notes
+
+To cover items relevant to extending the library modules or adding new
+
+To be written
diff --git a/docs/ufo.md b/docs/ufo.md
new file mode 100644
index 0000000..55049d7
--- /dev/null
+++ b/docs/ufo.md
@@ -0,0 +1,159 @@
+# Pysilfont - ufo support technical docs
+
+# The Basics
+
+UFO support is provided by the ufo.py library.
+
+Most scripts work by reading a UFO into a Ufont object, making changes to it and writing it out again. The Ufont object contains many separate objects representing the UFO in a UFO 3 based hierarchy, even if the original UFO was format 2 - see [UFO 2 or UFO 3?](#ufo-2-or-ufo-3-) below.
+
+Details of the [Ufont Object Model](#ufont-object-model) are given below, but in summary:
+
+- There is an object for each file within the UFO (based on [xmlitem](technical.md#etutil.py))
+- There is an object for each xml element within a parent object (based on [ETelement](technical.md#etutil.py))
+- Data within objects can always(?) be accessed via generic methods based on the xml element tags
+- For much data, there are object-specific methods to access data, which is easier than the generic methods
+
+For example, a .glif file is:
+- Read into a Uglif object which has:
+ - Methods for glyph-level data (eg name, format)
+ - objects for all the sub-elements within a glyph (eg advance, outline)
+ - Where an element type can only appear once in a glyph, eg advance, Uglif.*element-name* returns the relevant object
+ - Where an element can occur multiple times (eg anchor), Uglif.*element-name* returns a list of objects
+- If an sub-element itself has sub-elements, then there are usually sub-element objects for that following the same pattern, eg Uglif.outline has lists of Ucontour and Ucomponent objects
+
+It is planned that more object-specific methods will be added as needs arise, so raise in issue if you see specific needs that are likely to be useful in multiple scripts.
+
+
+
+### UFO 2 or UFO 3?
+
+The Ufont() object model UFO 3 based, so UFO 2 format fonts are converted to UFO 3 when read and then converted back to UFO 2 when written out to disk. Unless a script has code that is specific to a particular UFO format, scripts do not need to know the format of the font that was opened; rather they can just work in the UFO 3 format and leave the conversion to the library.
+
+The main differences this makes in practice are:
+- **Layers** The Ufont() always has layers. With UFO 2 fonts, there will be only one, and it can be accessed via Ufont.deflayer
+- **Anchors** If a UFO 2 font uses the accepted practice of anchors being single point contours with a name and a type of "Move" then
+ - On reading the font, they will be removed from the list of contours and added to the list of anchors
+ - On writing the font, they will be added back into the list of contours
+
+Despite being based on UFO 3 (for future-proofing), nearly all use of Pysilfont's UFO scripts has been with UFO 2-based projects so testing with UFO 3 has been minimal - and there are some [known limitations](docs.md#known-limitations).
+
+
+# Ufont Object Model
+
+A **Ufont** object represents the font using the following objects:
+
+- font.**metainfo**: [Uplist](#uplist) object created from metainfo.plist
+- font.**fontinfo**: [Uplist](#uplist) object created from fontinfo.plist, if present
+- font.**groups**: [Uplist](#uplist) object created from groups.plist, if present
+- font.**kerning**: [Uplist](#uplist) object created from kerning.plist, if present
+- font.**lib**: [Uplist](#uplist) object created from lib.plist, if present
+- self.**layercontents**: [Uplist](#uplist) object
+ - created from layercontents.plist for UFO 3 fonts
+ - synthesized based on the font's single layer for UFO 2 fonts
+- font.**layers**: List of [Ulayer](#ulayer) objects, where each layer contains:
+ - layer.**contents**: [Uplist](#uplist) object created from contents.plist
+ - layer[**_glyph name_**]: A [Uglif](#uglif) object for each glyph in the font which contains:
+ - glif['**advance**']: Uadvance object
+ - glif['**unicode**']: List of Uunicode objects
+ - glif['**note**']: Unote object (UFO 3 only)
+ - glif['**image**']: Uimage object (UFO 3 only)
+ - glif['**guideline**']: List of Uguideline objects (UFO 3 only)
+ - glif['**anchor**']: List of Uanchor objects
+ - glif['**outline**']: Uoutline object which contains
+ - outline.**contours**: List of Ucontour objects
+ - outline.**components**: List of Ucomponent objects
+ - glif['**lib**']: Ulib object
+- font.**features**: UfeatureFile created from features.fea, if present
+
+## General Notes
+
+Except for UfeatureFile (and Ufont itself), all the above objects are set up as [immutable containers](technical.md#immutable-containers), though the contents, if any, depend on the particular object.
+
+Objects usually have a link back to their parent object, eg glif.layer points to the Ulayer object containing that glif.
+
+## Specific classes
+
+**Note - the sections below don't list all the class details** so also look in the code in ufo.py if you need something not listed - it might be there!
+
+### Ufont
+
+In addition to the objects listed above, a Ufont object contains:
+- self.params: The [parameters](parameters.md) object for the font
+- self.paramsset: The parameter set within self.params specific to the font
+- self.logger: The logger object for the script
+- self.ufodir: Text string of the UFO location
+- self.UFOversion: from formatVersion in metainfo.plist
+- self.dtree: [dirTree](technical.md#dirtree) object representing all the files on fisk and their status
+- self.outparams: The output parameters for the font, initially set from self.paramset
+- self.deflayer:
+ - The single layer for UFO 2 fonts
+ - The layer called public.default for UFO 3 fonts
+
+When creating a new Ufont() object in a script, it is normal to pass args.paramsobj for params so that it has all the settings for parameters and logging.
+
+self.write(outputdir) will write the UFO to disk. For basic scripts this will usually be done by the execute() function - see [writing scripts](technical.md#writing-scripts).
+
+self.addfile(type) will add an empty entry for any of the optional plist files (fontinfo, groups, kerning or lib).
+
+When writing to disk, the UFO is always normalized, and only changed files will actually be written to disk. The format for normalization, as well as the output UFO version, are controlled by values in self.outparams.
+
+### Uplist
+
+Used to represent any .plist file, as listed above.
+
+For each key,value pair in the file, self[key] contains a list:
+- self[key][0] is an elementtree element for the key
+- self[key][1] is an elementtree element for the value
+
+self.getval(key) will return:
+- the value, if the value type is integer, real or string
+- a list if the value type is array
+- a dict if the value type is dict
+- None, for other value types (which would only occur in lib.plist)
+- It will throw an exception if the key does not exist
+- for dict and array, it will recursively process dict and/or array subelements
+
+Methods are available for adding, changing and deleting values - see class \_plist in ufo.py for details.
+
+self.font points to the parent Ufont object
+
+### Ulayer
+
+Represents a layer in the font. With UFO 2 fonts, a single layer is synthesized from the glifs folder.
+
+For each glyph, layer[glyphname] returns a Uglif object for the glyph. It has addGlyph and delGlyph functions.
+
+### Uglif
+
+Represents a glyph within a layer. It has child objects, as listed below, and functions self.add and self.remove for adding and removing them. For UFO 2 fonts, and contours identified as anchors will have been removed from Uoutline and added as Uanchor objects.
+
+#### glif child objects
+
+There are 8 child objects for a glif:
+
+| Name | Notes | UFO 2 | Multi |
+| ---- | -------------------------------- | --- | --- |
+| Uadvance | Has width & height attributes | Y | |
+| Uunicode | Has hex attribute | Y | Y |
+| Uoutline | | Y | |
+| Ulib | | Y | |
+| Unote | | | |
+| Uimage | | | |
+| Uguideline | | | Y |
+| Uanchor | | | Y |
+
+They all have separate object classes, but currently (except for setting attributes), only Uoutline and Ulib have any extra code - though more will be added in the future.
+
+(With **Uanchor**, the conversion between UFO 3 anchors and the UFO 2 way of handling anchors is handled by code in Uglif and Ucontour)
+
+**Ulib** shares a parent class (\_plist) with [Uplist](#uplist) so has the same functionality for managing key,value pairs.
+
+#### Uoutline
+
+This has Ucomponent and Ucontour child objects, with addobject, appendobject and insertobject methods for managing them.
+
+With Ucontour, self['point'] returns a list of the point subelements within the contour, and points can be managed using the methods in Ulelement. other than that, changes need to be made by changing the elements using elementtree methods.
+
+# Module Developer Notes
+
+To be written
diff --git a/examples/FFmapGdlNames.py b/examples/FFmapGdlNames.py
new file mode 100755
index 0000000..20dc268
--- /dev/null
+++ b/examples/FFmapGdlNames.py
@@ -0,0 +1,99 @@
+#!/usr/bin/env python
+'''Write mapping of graphite names to new graphite names based on:
+ - two ttf files
+ - the gdl files produced by makeGdl run against those fonts
+ This could be different versions of makeGdl
+ - a csv mapping glyph names used in original ttf to those in the new font '''
+__url__ = 'http://github.com/silnrsi/pysilfont'
+__copyright__ = 'Copyright (c) 2016 SIL International (http://www.sil.org)'
+__license__ = 'Released under the MIT License (http://opensource.org/licenses/MIT)'
+__author__ = 'David Raymond'
+
+from silfont.core import execute
+import datetime
+
+suffix = "_mapGDLnames2"
+argspec = [
+ ('ifont1',{'help': 'First ttf font file'}, {'type': 'infont'}),
+ ('ifont2',{'help': 'Second ttf font file'}, {'type': 'infont'}),
+ ('gdl1',{'help': 'Original make_gdl file'}, {'type': 'infile'}),
+ ('gdl2',{'help': 'Updated make_gdl file'}, {'type': 'infile'}),
+ ('-m','--mapping',{'help': 'Mapping csv file'}, {'type': 'incsv', 'def': '_map.csv'}),
+ ('-o','--output',{'help': 'Ouput csv file'}, {'type': 'outfile', 'def': suffix+'.csv'}),
+ ('-l','--log',{'help': 'Log file'}, {'type': 'outfile', 'def': suffix+'.log'}),
+ ('--nocomments',{'help': 'No comments in output files', 'action': 'store_true', 'default': False},{})]
+
+def doit(args) :
+ logger = args.paramsobj.logger
+ # Check input fonts are ttf
+ fontfile1 = args.cmdlineargs[1]
+ fontfile2 = args.cmdlineargs[2]
+
+ if fontfile1[-3:] != "ttf" or fontfile2[-3:] != "ttf" :
+ logger.log("Input fonts needs to be ttf files", "S")
+
+ font1 = args.ifont1
+ font2 = args.ifont2
+ gdlfile1 = args.gdl1
+ gdlfile2 = args.gdl2
+ mapping = args.mapping
+ outfile = args.output
+
+ # Add initial comments to outfile
+ if not args.nocomments :
+ outfile.write("# " + datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S ") + args.cmdlineargs[0] + "\n")
+ outfile.write("# "+" ".join(args.cmdlineargs[1:])+"\n\n")
+
+ # Process gdl files
+ oldgrnames = {}
+ for line in gdlfile1 :
+ # Look for lines of format <grname> = glyphid(nnn)...
+ pos = line.find(" = glyphid(")
+ if pos == -1 : continue
+ grname = line[0:pos]
+ gid = line[pos+11:line.find(")")]
+ oldgrnames[int(gid)]=grname
+
+ newgrnames = {}
+ for line in gdlfile2 :
+ # Look for lines of format <grname> = glyphid(nnn)...
+ pos = line.find(" = glyphid(")
+ if pos == -1 : continue
+ grname = line[0:pos]
+ gid = line[pos+11:line.find(")")]
+ newgrnames[int(gid)]=grname
+
+ # Process mapping file
+ SILnames = {}
+ mapping.numfields = 2
+ for line in mapping : SILnames[line[1]] = line[0]
+
+ # Map SIL name to gids in font 2
+ SILtogid2={}
+ for glyph in font2.glyphs(): SILtogid2[glyph.glyphname] = glyph.originalgid
+
+ # Combine all the mappings via ttf1!
+ cnt1 = 0
+ cnt2 = 0
+ for glyph in font1.glyphs():
+ gid1 = glyph.originalgid
+ gname1 = glyph.glyphname
+ gname2 = SILnames[gname1]
+ gid2 = SILtogid2[gname2]
+ oldgrname = oldgrnames[gid1] if gid1 in oldgrnames else None
+ newgrname = newgrnames[gid2] if gid2 in newgrnames else None
+ if oldgrname is None or newgrname is None :
+ print type(gid1), gname1, oldgrname
+ print gid2, gname2, newgrname
+ cnt2 += 1
+ if cnt2 > 10 : break
+ else:
+ outfile.write(oldgrname + "," + newgrname+"\n")
+ cnt1 += 1
+
+ print cnt1,cnt2
+
+ outfile.close()
+ return
+
+execute("FF",doit, argspec)
diff --git a/examples/FFmapGdlNames2.py b/examples/FFmapGdlNames2.py
new file mode 100755
index 0000000..13f1356
--- /dev/null
+++ b/examples/FFmapGdlNames2.py
@@ -0,0 +1,72 @@
+#!/usr/bin/env python
+'''Write mapping of graphite names to new graphite names based on:
+ - an original ttf font
+ - the gdl file produced by makeGdl when original font was produced
+ - a csv mapping glyph names used in original ttf to those in the new font
+ - pysilfont's gdl library - so assumes pysilfonts makeGdl will be used with new font'''
+__url__ = 'http://github.com/silnrsi/pysilfont'
+__copyright__ = 'Copyright (c) 2016 SIL International (http://www.sil.org)'
+__license__ = 'Released under the MIT License (http://opensource.org/licenses/MIT)'
+__author__ = 'David Raymond'
+
+from silfont.core import execute
+import silfont.gdl.psnames as ps
+import datetime
+
+suffix = "_mapGDLnames"
+argspec = [
+ ('ifont',{'help': 'Input ttf font file'}, {'type': 'infont'}),
+ ('-g','--gdl',{'help': 'Input gdl file'}, {'type': 'infile', 'def': '.gdl'}),
+ ('-m','--mapping',{'help': 'Mapping csv file'}, {'type': 'incsv', 'def': '_map.csv'}),
+ ('-o','--output',{'help': 'Ouput csv file'}, {'type': 'outfile', 'def': suffix+'.csv'}),
+ ('-l','--log',{'help': 'Log file'}, {'type': 'outfile', 'def': suffix+'.log'}),
+ ('--nocomments',{'help': 'No comments in output files', 'action': 'store_true', 'default': False},{})]
+
+def doit(args) :
+ logger = args.paramsobj.logger
+ # Check input font is a ttf
+ fontfile = args.cmdlineargs[1]
+ if fontfile[-3:] != "ttf" :
+ logger.log("Input font needs to be a ttf file", "S")
+
+ font = args.ifont
+ gdlfile = args.gdl
+ mapping = args.mapping
+ outfile = args.output
+
+ # Add initial comments to outfile
+ if not args.nocomments :
+ outfile.write("# " + datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S ") + args.cmdlineargs[0] + "\n")
+ outfile.write("# "+" ".join(args.cmdlineargs[1:])+"\n\n")
+
+ # Process gdl file
+ oldgrnames = {}
+ for line in args.gdl :
+ # Look for lines of format <grname> = glyphid(nnn)...
+ pos = line.find(" = glyphid(")
+ if pos == -1 : continue
+ grname = line[0:pos]
+ gid = line[pos+11:line.find(")")]
+ oldgrnames[int(gid)]=grname
+
+ # Create map from AGL name to new graphite name
+ newgrnames = {}
+ mapping.numfields = 2
+ for line in mapping :
+ AGLname = line[1]
+ SILname = line[0]
+ grname = ps.Name(SILname).GDL()
+ newgrnames[AGLname] = grname
+
+ # Find glyph names in ttf font
+ for glyph in font.glyphs():
+ gid = glyph.originalgid
+ gname = glyph.glyphname
+ oldgrname = oldgrnames[gid] if gid in oldgrnames else None
+ newgrname = newgrnames[gname] if gname in newgrnames else None
+ outfile.write(oldgrname + "," + newgrname+"\n")
+
+ outfile.close()
+ return
+
+execute("FF",doit, argspec)
diff --git a/examples/FLWriteXml.py b/examples/FLWriteXml.py
new file mode 100755
index 0000000..e174f6d
--- /dev/null
+++ b/examples/FLWriteXml.py
@@ -0,0 +1,118 @@
+#!/usr/bin/env python
+'''Outputs attachment point information and notes as XML file for TTFBuilder'''
+__url__ = 'http://github.com/silnrsi/pysilfont'
+__copyright__ = 'Copyright (c) 2015 SIL International (http://www.sil.org)'
+__license__ = 'Released under the MIT License (http://opensource.org/licenses/MIT)'
+__author__ = 'M Hosken'
+
+# user controls
+
+# output entries for all glyphs even those with nothing interesting to say about them
+all_glyphs = 1
+
+# output the glyph id as part of the information
+output_gid = 1
+
+# output the glyph notes
+output_note = 0
+
+# output UID with "U+" prefix
+output_uid_prefix = 0
+
+# print progress indicator
+print_progress = 0
+
+# no user serviceable parts under here!
+from xml.sax.saxutils import XMLGenerator
+import os
+
+def print_glyph(font, glyph, index):
+ if print_progress and index % 100 == 0:
+ print "%d: %s" % (index, glyph.name)
+
+ if (not all_glyphs and len(glyph.anchors) == 0 and len(glyph.components) == 0 and
+ not (glyph.note and output_note)):
+ return
+ attribs = {}
+ if output_gid:
+ attribs["GID"] = unicode(index)
+ if glyph.unicode:
+ if output_uid_prefix:
+ attribs["UID"] = unicode("U+%04X" % glyph.unicode)
+ else:
+ attribs["UID"] = unicode("%04X" % glyph.unicode)
+ if glyph.name:
+ attribs["PSName"] = unicode(glyph.name)
+ xg.startElement("glyph", attribs)
+
+ for anchor in (glyph.anchors):
+ xg.startElement("point", {"type":unicode(anchor.name), "mark":unicode(anchor.mark)})
+ xg.startElement("location", {"x":unicode(anchor.x), "y":unicode(anchor.y)})
+ xg.endElement("location")
+ xg.endElement("point")
+
+ for comp in (glyph.components):
+ g = font.glyphs[comp.index]
+ r = g.GetBoundingRect()
+ x0 = 0.5 * (r.ll.x * (1 + comp.scale.x) + r.ur.x * (1 - comp.scale.x)) + comp.delta.x
+ y0 = 0.5 * (r.ll.y * (1 + comp.scale.y) + r.ur.y * (1 - comp.scale.y)) + comp.delta.y
+ x1 = 0.5 * (r.ll.x * (1 - comp.scale.x) + r.ur.x * (1 + comp.scale.x)) + comp.delta.x
+ y1 = 0.5 * (r.ll.y * (1 - comp.scale.x) + r.ur.y * (1 + comp.scale.y)) + comp.delta.y
+
+ attribs = {"bbox":unicode("%d, %d, %d, %d" % (x0, y0, x1, y1))}
+ attribs["GID"] = unicode(comp.index)
+ if (g.unicode):
+ if output_uid_prefix:
+ attribs["UID"] = unicode("U+%04X" % g.unicode)
+ else:
+ attribs["UID"] = unicode("%04X" % g.unicode)
+ if (g.name):
+ attribs["PSName"] = unicode(g.name)
+ xg.startElement("compound", attribs)
+ xg.endElement("compound")
+
+ if glyph.mark:
+ xg.startElement("property", {"name":unicode("mark"), "value":unicode(glyph.mark)})
+ xg.endElement("property")
+
+ if glyph.customdata:
+ xg.startElement("customdata", {})
+ xg.characters(unicode(glyph.customdata.strip()))
+ xg.endElement("customdata")
+
+ if glyph.note and output_note:
+ xg.startElement("note", {})
+ xg.characters(glyph.note)
+ xg.endElement("note")
+ xg.endElement("glyph")
+
+outname = fl.font.file_name.replace(".vfb", "_tmp.xml")
+fh = open(outname, "w")
+xg = XMLGenerator(fh, "utf-8")
+xg.startDocument()
+
+#fl.font.full_name is needed to get the name as it appears to Windows
+#fl.font.font_name seems to be the PS name. This messes up GenTest.pl when it generates WPFeatures.wpx
+xg.startElement("font", {'name':unicode(fl.font.full_name), "upem":unicode(fl.font.upm)})
+for i in range(0, len(fl.font.glyphs)):
+ print_glyph(fl.font, fl.font.glyphs[i], i)
+xg.endElement("font")
+
+xg.endDocument()
+fh.close()
+
+#somehow this enables UNC naming (\\Gutenberg vs i:) to work when Saxon is called with popen
+#without this, if outname is UNC-based, then drive letters and UNC volumes are invisible
+# if outname is drive-letter-based, then drive letters and UNC volumes are already visible
+if (outname[0:2] == r'\\'):
+ os.chdir("c:")
+tidy = "tidy -i -xml -n -wrap 0 --char-encoding utf8 --indent-spaces 4 --quote-nbsp no --tab-size 4 -m %s"
+saxon = "saxon %s %s" % ('"' + outname + '"', r'"C:\Roman Font\rfs_font\10 Misc Utils\glyph_norm.xsl"') #handle spaces in file name
+f = os.popen(saxon, "rb")
+g = open(outname.replace("_tmp.xml", ".xml"), "wb")
+output = f.read()
+g.write(output)
+f.close()
+g.close()
+
+print "Done"
diff --git a/examples/FTMLnorm.py b/examples/FTMLnorm.py
new file mode 100644
index 0000000..638b2db
--- /dev/null
+++ b/examples/FTMLnorm.py
@@ -0,0 +1,24 @@
+#!/usr/bin/env python
+'Normalize an FTML file'
+__url__ = 'http://github.com/silnrsi/pysilfont'
+__copyright__ = 'Copyright (c) 2016 SIL International (http://www.sil.org)'
+__license__ = 'Released under the MIT License (http://opensource.org/licenses/MIT)'
+__author__ = 'David Raymond'
+
+from silfont.core import execute
+import silfont.ftml as ftml
+from xml.etree import cElementTree as ET
+
+argspec = [
+ ('infile',{'help': 'Input ftml file'}, {'type': 'infile'}),
+ ('outfile',{'help': 'Output ftml file', 'nargs': '?'}, {'type': 'outfile', 'def': '_new.xml'}),
+ ('-l','--log',{'help': 'Log file'}, {'type': 'outfile', 'def': '_ftmltest.log'})
+ ]
+
+def doit(args) :
+ f = ftml.Fxml(args.infile)
+ f.save(args.outfile)
+
+def cmd() : execute("",doit,argspec)
+if __name__ == "__main__": cmd()execute("", doit, argspec)
+
diff --git a/examples/FTaddEmptyOT.py b/examples/FTaddEmptyOT.py
new file mode 100644
index 0000000..926388f
--- /dev/null
+++ b/examples/FTaddEmptyOT.py
@@ -0,0 +1,49 @@
+#!/usr/bin/env python
+'Add empty Opentype tables to ttf font'
+__url__ = 'http://github.com/silnrsi/pysilfont'
+__copyright__ = 'Copyright (c) 2014 SIL International (http://www.sil.org)'
+__license__ = 'Released under the MIT License (http://opensource.org/licenses/MIT)'
+__author__ = 'Martin Hosken'
+
+from silfont.core import execute
+from fontTools import ttLib
+from fontTools.ttLib.tables import otTables
+
+argspec = [
+ ('ifont',{'help': 'Input font file'}, {'type': 'infont'}),
+ ('ofont',{'help': 'Output font file','nargs': '?' }, {'type': 'outfont'}),
+ ('-l','--log',{'help': 'Log file'}, {'type': 'outfile', 'def': '_conv.log'}),
+ ('-s','--script',{'help': 'Script tag to generate [DFLT]', 'default': 'DFLT', }, {}),
+ ('-t','--type',{'help': 'Table to create: gpos, gsub, [both]', 'default': 'both', }, {}) ]
+
+def doit(args) :
+ font = args.ifont
+ args.type = args.type.upper()
+
+ for tag in ('GSUB', 'GPOS') :
+ if tag == args.type or args.type == 'BOTH' :
+ table = ttLib.getTableClass(tag)()
+ t = getattr(otTables, tag, None)()
+ t.Version = 1.0
+ t.ScriptList = otTables.ScriptList()
+ t.ScriptList.ScriptRecord = []
+ t.FeatureList = otTables.FeatureList()
+ t.FeatureList.FeatureRecord = []
+ t.LookupList = otTables.LookupList()
+ t.LookupList.Lookup = []
+ srec = otTables.ScriptRecord()
+ srec.ScriptTag = args.script
+ srec.Script = otTables.Script()
+ srec.Script.DefaultLangSys = None
+ srec.Script.LangSysRecord = []
+ t.ScriptList.ScriptRecord.append(srec)
+ t.ScriptList.ScriptCount = 1
+ t.FeatureList.FeatureCount = 0
+ t.LookupList.LookupCount = 0
+ table.table = t
+ font[tag] = table
+
+ return font
+
+def cmd() : execute("FT",doit, argspec)
+if __name__ == "__main__": cmd()
diff --git a/examples/accesslibplist.py b/examples/accesslibplist.py
new file mode 100644
index 0000000..9d03179
--- /dev/null
+++ b/examples/accesslibplist.py
@@ -0,0 +1,34 @@
+#!/usr/bin/env python
+'Demo script for accessing fields in lib.plist'
+__url__ = 'http://github.com/silnrsi/pysilfont'
+__copyright__ = 'Copyright (c) 2017 SIL International (http://www.sil.org)'
+__license__ = 'Released under the MIT License (http://opensource.org/licenses/MIT)'
+__author__ = 'David Raymond'
+
+from silfont.core import execute
+
+argspec = [
+ ('ifont', {'help': 'Input font file'}, {'type': 'infont'}),
+ ('field', {'help': 'field to access'},{})]
+
+def doit(args):
+ font = args.ifont
+ field = args.field
+ lib = font.lib
+
+ if field in lib:
+ val = lib.getval(field)
+ print
+ print val
+ print
+ print "Field " + field + " is type " + lib[field][1].tag + " in xml"
+
+ print "The retrieved value is " + str(type(val)) + " in Python"
+ else:
+ print "Field not in lib.plist"
+
+ return
+
+
+def cmd(): execute("UFO", doit, argspec)
+if __name__ == "__main__": cmd()
diff --git a/examples/chaindemo.py b/examples/chaindemo.py
new file mode 100644
index 0000000..c832dc2
--- /dev/null
+++ b/examples/chaindemo.py
@@ -0,0 +1,43 @@
+#!/usr/bin/env python
+''' Demo of how to chain calls to multiple scripts together.
+Running
+ python chaindemo.py infont outfont --featfile feat.csv --uidsfile uids.csv
+will run execute() against psfnormalize, psfsetassocfeat and psfsetassocuids passing the font, parameters
+and logger objects from one call to the next. So:
+- the font is only opened once and written once
+- there is a single log file produced
+'''
+__url__ = 'http://github.com/silnrsi/pysilfont'
+__copyright__ = 'Copyright (c) 2017 SIL International (http://www.sil.org)'
+__license__ = 'Released under the MIT License (http://opensource.org/licenses/MIT)'
+__author__ = 'David Raymond'
+
+from silfont.core import execute, chain
+import silfont.scripts.psfnormalize as psfnormalize
+import silfont.scripts.psfsetassocfeat as psfsetassocfeat
+import silfont.scripts.psfsetassocuids as psfsetassocuids
+
+argspec = [
+ ('ifont',{'help': 'Input font file'}, {'type': 'infont'}),
+ ('ofont',{'help': 'Output font file','nargs': '?' }, {'type': 'outfont'}),
+ ('--featfile',{'help': 'Associate features csv'}, {'type': 'filename'}),
+ ('--uidsfile', {'help': 'Associate uids csv'}, {'type': 'filename'}),
+ ('-l','--log',{'help': 'Log file'}, {'type': 'outfile', 'def': '_chain.log'})]
+
+def doit(args) :
+
+ argv = ['psfnormalize', 'dummy'] # 'dummy' replaces input font since font object is being passed. Other parameters could be added.
+ font = chain(argv, psfnormalize.doit, psfnormalize.argspec, args.ifont, args.paramsobj, args.logger, args.quiet)
+
+ argv = ['psfsetassocfeat', 'dummy', '-i', args.featfile]
+ font = chain(argv, psfsetassocfeat.doit, psfsetassocfeat.argspec, font, args.paramsobj, args.logger, args.quiet)
+
+ argv = ['psfsetassocuids', 'dummy', '-i', args.uidsfile]
+ font = chain(argv, psfsetassocuids.doit, psfsetassocuids.argspec, font, args.paramsobj, args.logger, args.quiet)
+
+ return font
+
+def cmd() : execute("UFO",doit, argspec)
+
+if __name__ == "__main__": cmd()
+
diff --git a/examples/fbonecheck.py b/examples/fbonecheck.py
new file mode 100644
index 0000000..6f0dd2e
--- /dev/null
+++ b/examples/fbonecheck.py
@@ -0,0 +1,17 @@
+#!/usr/bin/env python
+'''Example profile for use with psfrunfbchecks that will just run one or more specified checks'''
+__url__ = 'http://github.com/silnrsi/pysilfont'
+__copyright__ = 'Copyright (c) 2022 SIL International (http://www.sil.org)'
+__license__ = 'Released under the MIT License (http://opensource.org/licenses/MIT)'
+__author__ = 'David Raymond'
+
+from silfont.fbtests.ttfchecks import psfcheck_list, make_profile, check, PASS, FAIL
+
+# Exclude all checks bar those listed
+for check in psfcheck_list:
+ if check not in ["org.sil/check/whitespace_widths"]:
+ psfcheck_list[check] = {'exclude': True}
+
+# Create the fontbakery profile
+profile = make_profile(psfcheck_list, variable_font = False)
+
diff --git a/examples/fbttfchecks.py b/examples/fbttfchecks.py
new file mode 100644
index 0000000..81a54f4
--- /dev/null
+++ b/examples/fbttfchecks.py
@@ -0,0 +1,65 @@
+#!/usr/bin/env python
+'''Example for making project-specific changes to the standard pysilfont set of Font Bakery ttf checks.
+It will start with all the checks normally run by pysilfont's ttfchecks profile then modify as described below'''
+__url__ = 'http://github.com/silnrsi/pysilfont'
+__copyright__ = 'Copyright (c) 2020 SIL International (http://www.sil.org)'
+__license__ = 'Released under the MIT License (http://opensource.org/licenses/MIT)'
+__author__ = 'David Raymond'
+
+from silfont.fbtests.ttfchecks import psfcheck_list, make_profile, check, PASS, FAIL
+
+#
+# General settings
+#
+psfvariable_font = False # Set to True for variable fonts, so different checks will be run
+
+#
+# psfcheck_list is a dictionary of all standard Fontbakery checks with a dictionary for each check indicating
+# pysilfont's standard processing of that check
+#
+# Specifically:
+# - If the dictionary has "exclude" set to True, that check will be excluded from the profile
+# - If change_status is set, the status values reported by psfrunfbchecks will be changed based on its values
+# - If a change in status is temporary - eg just until something is fixed, use temp_change_status instead
+#
+# Projects can edit this dictionary to change behaviour from Pysilfont defaults. See examples below
+
+# To reinstate the copyright check (which is normally excluded):
+psfcheck_list["com.google.fonts/check/metadata/copyright"]["exclude"] = False
+
+# To prevent the hinting_impact check from running:
+psfcheck_list["com.google.fonts/check/hinting_impact"]["exclude"] = True
+
+# To change a FAIL status for com.google.fonts/check/whitespace_glyphnames to WARN:
+psfcheck_list["com.google.fonts/check/whitespace_glyphnames"]["temp_change_status"] = {
+ "FAIL": "WARN", "reason": "This font currently uses non-standard names"}
+
+#
+# Create the fontbakery profile
+#
+profile = make_profile(psfcheck_list, variable_font = psfvariable_font)
+
+# Add any project-specific tests (This dummy test should normally be commented out!)
+
+@profile.register_check
+@check(
+ id = 'org.sil/dummy',
+ rationale = """
+ There is no reason for this test!
+ """
+)
+def org_sil_dummy():
+ """Dummy test that always fails"""
+ if True: yield FAIL, "Oops!"
+
+'''
+Run this using
+
+ $ psfrunfbchecks --profile fbttfchecks.py <ttf file(s) to check> ...
+
+It can also be used with fontbakery directly if you want to use options that psfrunfbchecks does not support, however
+status changes will not be actioned.
+
+ $ fontbakery check-profile fbttfchecks.py <ttf file(s) to check> ...
+
+''' \ No newline at end of file
diff --git a/examples/ffchangeglyphnames.py b/examples/ffchangeglyphnames.py
new file mode 100755
index 0000000..7959f4f
--- /dev/null
+++ b/examples/ffchangeglyphnames.py
@@ -0,0 +1,65 @@
+#!/usr/bin/env python
+from __future__ import unicode_literals
+'''Update glyph names in a font based on csv file
+ - Using FontForge rather than UFOlib so it can work with ttf (or sfd) files'''
+__url__ = 'http://github.com/silnrsi/pysilfont'
+__copyright__ = 'Copyright (c) 2016 SIL International (http://www.sil.org)'
+__license__ = 'Released under the MIT License (http://opensource.org/licenses/MIT)'
+__author__ = 'David Raymond'
+
+from silfont.core import execute
+
+''' This will need updating, since FontForge is no longer supported as a tool by execute() So:
+- ifont and ofont will need to be changed to have type 'filename'
+- ifont will then need to be opened using fontforge.open
+- The font will need to be saved with font.save
+- execute will need to be called with the tool set to None instead of "FF"
+'''
+
+argspec = [
+ ('ifont',{'help': 'Input ttf font file'}, {'type': 'infont'}),
+ ('ofont',{'help': 'Output font file','nargs': '?' }, {'type': 'outfont'}),
+ ('-i','--input',{'help': 'Mapping csv file'}, {'type': 'incsv', 'def': 'psnames.csv'}),
+ ('-l','--log',{'help': 'Log file'}, {'type': 'outfile', 'def': '_setPostNames.log'}),
+ ('--reverse',{'help': 'Change names in reverse', 'action': 'store_true', 'default': False},{})]
+
+def doit(args) :
+ logger = args.paramsobj.logger
+
+ font = args.ifont
+
+ # Process csv
+ csv = args.input
+ csv.numfields = 2
+ newnames={}
+ namescheck=[]
+ missingnames = False
+ for line in csv :
+ if args.reverse :
+ newnames[line[1]] = line[0]
+ namescheck.append(line[1])
+ else :
+ newnames[line[0]] = line[1]
+ namescheck.append(line[0])
+
+ for glyph in font.glyphs():
+ gname = glyph.glyphname
+ if gname in newnames :
+ namescheck.remove(gname)
+ glyph.glyphname = newnames[gname]
+ else:
+ missingnames = True
+ logger.log(gname + " in font but not csv file","W")
+
+ if missingnames : logger.log("Font glyph names missing from csv - see log for details","E")
+
+ for name in namescheck : # Any names left in namescheck were in csv but not ttf
+ logger.log(name + " in csv but not in font","W")
+
+ if namescheck != [] : logger.log("csv file names missing from font - see log for details","E")
+
+ return font
+
+def cmd() : execute("FF",doit,argspec)
+if __name__ == "__main__": cmd()
+
diff --git a/examples/ffcopyglyphs.py b/examples/ffcopyglyphs.py
new file mode 100644
index 0000000..06c831a
--- /dev/null
+++ b/examples/ffcopyglyphs.py
@@ -0,0 +1,161 @@
+#!/usr/bin/env python3
+'''FontForge: Copy glyphs from one font to another, without using ffbuilder'''
+__url__ = 'http://github.com/silnrsi/pysilfont'
+__copyright__ = 'Copyright (c) 2015-2019 SIL International (http://www.sil.org)'
+__license__ = 'Released under the MIT License (http://opensource.org/licenses/MIT)'
+__author__ = 'Martin Hosken'
+
+from silfont.core import execute
+import psMat
+import io
+
+
+''' This will need updating, since FontForge is no longer supported as a tool by execute() So:
+- ifont and ofont will need to be changed to have type 'filename'
+- ifont will then need to be opened using fontforge.open
+- The font will need to be saved with font.save
+- execute will need to be called with the tool set to None instead of "FF"
+'''
+
+
+argspec = [
+ ('ifont',{'help': 'Input font file'}, {'type': 'infont'}),
+ ('ofont',{'help': 'Output font file','nargs': '?' }, {'type': 'outfont', 'def': 'new'}),
+ ('-i','--input',{'help': 'Font to get glyphs from', 'required' : True}, {'type': 'infont'}),
+ ('-r','--range',{'help': 'StartUnicode..EndUnicode no spaces, e.g. 20..7E', 'action' : 'append'}, {}),
+ ('--rangefile',{'help': 'File with USVs e.g. 20 or a range e.g. 20..7E or both', 'action' : 'append'}, {}),
+ ('-n','--name',{'help': 'Include glyph named name', 'action' : 'append'}, {}),
+ ('--namefile',{'help': 'File with glyph names', 'action' : 'append'}, {}),
+ ('-a','--anchors',{'help' : 'Copy across anchor points', 'action' : 'store_true'}, {}),
+ ('-f','--force',{'help' : 'Overwrite existing glyphs in the font', 'action' : 'store_true'}, {}),
+ ('-s','--scale',{'type' : float, 'help' : 'Scale glyphs by this factor'}, {})
+]
+
+def copyglyph(font, infont, g, u, args) :
+ extras = set()
+ if args.scale is None :
+ scale = psMat.identity()
+ else :
+ scale = psMat.scale(args.scale)
+ o = font.findEncodingSlot(u)
+ if o == -1 :
+ glyph = font.createChar(u, g.glyphname)
+ else :
+ glyph = font[o]
+ if len(g.references) == 0 :
+ font.selection.select(glyph)
+ pen = glyph.glyphPen()
+ g.draw(pen)
+ glyph.transform(scale)
+ else :
+ for r in g.references :
+ t = psMat.compose(r[1], scale)
+ newt = psMat.compose(psMat.identity(), psMat.translate(t[4], t[5]))
+ glyph.addReference(r[0], newt)
+ extras.add(r[0])
+ glyph.width = g.width * scale[0]
+ if args.anchors :
+ for a in g.anchorPoints :
+ try :
+ l = font.getSubtableOfAnchor(a[1])
+ except EnvironmentError :
+ font.addAnchorClass("", a[0]*scale[0], a[1]*scale[3])
+ glyph.anchorPoints = g.anchorPoints
+ return list(extras)
+
+def doit(args) :
+ font = args.ifont
+ infont = args.input
+ font.encoding = "Original"
+ infont.encoding = "Original" # compact the font so findEncodingSlot will work
+ infont.layers["Fore"].is_quadratic = font.layers["Fore"].is_quadratic
+
+ # list of glyphs to copy
+ glist = list()
+
+ # glyphs specified on the command line
+ for n in args.name or [] :
+ glist.append(n)
+
+ # glyphs specified in a file
+ for filename in args.namefile or [] :
+ namefile = io.open(filename, 'r')
+ for line in namefile :
+ # ignore comments
+ line = line.partition('#')[0]
+ line = line.strip()
+
+ # ignore blank lines
+ if (line == ''):
+ continue
+
+ glist.append(line)
+
+ # copy glyphs by name
+ reportErrors = True
+ while len(glist) :
+ tglist = glist[:]
+ glist = []
+ for n in tglist:
+ if n in font and not args.force :
+ if reportErrors :
+ print("Glyph {} already present. Skipping".format(n))
+ continue
+ if n not in infont :
+ print("Can't find glyph {}".format(n))
+ continue
+ g = infont[n]
+ glist.extend(copyglyph(font, infont, g, -1, args))
+ reportErrors = False
+
+ # list of characters to copy
+ ulist = list()
+
+ # characters specified on the command line
+ for r in args.range or [] :
+ (rstart, rend) = [int(x, 16) for x in r.split('..')]
+ for u in range(rstart, rend + 1) :
+ ulist.append(u)
+
+ # characters specified in a file
+ for filename in args.rangefile or [] :
+ rangefile = io.open(filename, 'r')
+ for line in rangefile :
+ # ignore comments
+ line = line.partition('#')[0]
+ line = line.strip()
+
+ # ignore blank lines
+ if (line == ''):
+ continue
+
+ # obtain USVs
+ try:
+ (rstart, rend) = line.split('..')
+ except ValueError:
+ rstart = line
+ rend = line
+
+ rstart = int(rstart, 16)
+ rend = int(rend, 16)
+
+ for u in range(rstart, rend + 1):
+ ulist.append(u)
+
+ # copy the characters from the generated list
+ for u in ulist:
+ o = font.findEncodingSlot(u)
+ if o != -1 and not args.force :
+ print("Glyph for {:x} already present. Skipping".format(u))
+ continue
+ e = infont.findEncodingSlot(u)
+ if e == -1 :
+ print("Can't find glyph for {:04x}".format(u))
+ continue
+ g = infont[e]
+ copyglyph(font, infont, g, u, args)
+
+ return font
+
+def cmd() : execute("FF",doit,argspec)
+if __name__ == "__main__": cmd()
diff --git a/examples/ffremovealloverlaps.py b/examples/ffremovealloverlaps.py
new file mode 100755
index 0000000..d5fe178
--- /dev/null
+++ b/examples/ffremovealloverlaps.py
@@ -0,0 +1,31 @@
+#!/usr/bin/env python
+from __future__ import unicode_literals
+'FontForge: Remove overlap on all glyphs in font'
+__url__ = 'http://github.com/silnrsi/pysilfont'
+__copyright__ = 'Copyright (c) 2015 SIL International (http://www.sil.org)'
+__license__ = 'Released under the MIT License (http://opensource.org/licenses/MIT)'
+__author__ = 'Victor Gaultney'
+
+from silfont.core import execute
+
+
+''' This will need updating, since FontForge is no longer supported as a tool by execute() So:
+- ifont and ofont will need to be changed to have type 'filename'
+- ifont will then need to be opened using fontforge.open
+- The font will need to be saved with font.save
+- execute will need to be called with the tool set to None instead of "FF"
+'''
+
+
+argspec = [
+ ('ifont',{'help': 'Input font file'}, {'type': 'infont'}),
+ ('ofont',{'help': 'Output font file','nargs': '?' }, {'type': 'outfont', 'def': 'new'})]
+
+def doit(args) :
+ font = args.ifont
+ for glyph in font:
+ font[glyph].removeOverlap()
+ return font
+
+def cmd() : execute("FF",doit,argspec)
+if __name__ == "__main__": cmd()
diff --git a/examples/fontforge-old/FFaddPUA.py b/examples/fontforge-old/FFaddPUA.py
new file mode 100755
index 0000000..6bd4a96
--- /dev/null
+++ b/examples/fontforge-old/FFaddPUA.py
@@ -0,0 +1,31 @@
+#!/usr/bin/env python
+'''FontForge: Add cmap entries for all glyphs in the font'''
+__url__ = 'http://github.com/silnrsi/pysilfont'
+__copyright__ = 'Copyright (c) 2016 SIL International (http://www.sil.org)'
+__license__ = 'Released under the MIT License (http://opensource.org/licenses/MIT)'
+__author__ = 'Martin Hosken'
+
+from silfont.core import execute
+
+argspec = [
+ ('ifont',{'help': 'Input font file'}, {'type': 'infont'}),
+ ('ofont',{'help': 'Output font file','nargs': '?' }, {'type': 'outfont', 'def': 'new'})
+]
+
+def nextpua(p) :
+ if p == 0 : return 0xE000
+ if p == 0xF8FF : return 0xF0000
+ return p + 1
+
+def doit(args) :
+ p = nextpua(0)
+ font = args.ifont
+ for n in font :
+ g = font[n]
+ if g.unicode == -1 :
+ g.unicode = p
+ p = nextpua(p)
+ return font
+
+def cmd() : execute("FF",doit,argspec)
+if __name__ == "__main__": cmd()
diff --git a/examples/fontforge-old/FFcheckDupUSV.py b/examples/fontforge-old/FFcheckDupUSV.py
new file mode 100755
index 0000000..d6d948c
--- /dev/null
+++ b/examples/fontforge-old/FFcheckDupUSV.py
@@ -0,0 +1,62 @@
+#!/usr/bin/env python
+'FontForge: Check for duplicate USVs in unicode or altuni fields'
+__url__ = 'http://github.com/silnrsi/pysilfont'
+__copyright__ = 'Copyright (c) 2015 SIL International (http://www.sil.org)'
+__license__ = 'Released under the MIT License (http://opensource.org/licenses/MIT)'
+__author__ = 'David Raymond'
+
+from silfont.core import execute
+
+argspec = [
+ ('ifont',{'help': 'Input font file'}, {'type': 'infont'}),
+ ('-o','--output',{'help': 'Output text file'}, {'type': 'outfile', 'def': 'DupUSV.txt'})]
+
+def doit(args) :
+ font = args.ifont
+ outf = args.output
+
+ # Process unicode and altunicode for all glyphs
+ usvs={}
+ for glyph in font:
+ g = font[glyph]
+ if g.unicode != -1:
+ usv=UniStr(g.unicode)
+ AddUSV(usvs,usv,glyph)
+ # Check any alternate usvs
+ altuni=g.altuni
+ if altuni != None:
+ for au in altuni:
+ usv=UniStr(au[0]) # (may need to check variant flag)
+ AddUSV(usvs,usv,glyph + ' (alt)')
+
+ items = usvs.items()
+ items = filter(lambda x: len(x[1]) > 1, items)
+ items.sort()
+
+ for i in items:
+ usv = i[0]
+ print usv + ' has duplicates'
+ gl = i[1]
+ glyphs = gl[0]
+ for j in range(1,len(gl)):
+ glyphs = glyphs + ', ' + gl[j]
+
+ outf.write('%s: %s\n' % (usv,glyphs))
+
+ outf.close()
+ print "Done!"
+
+def UniStr(u):
+ if u:
+ return "U+{0:04X}".format(u)
+ else:
+ return "No USV" #length same as above
+
+def AddUSV(usvs,usv,glyph):
+ if not usvs.has_key(usv):
+ usvs[usv] = [glyph]
+ else:
+ usvs[usv].append(glyph)
+
+def cmd() : execute("FF",doit,argspec)
+if __name__ == "__main__": cmd()
diff --git a/examples/fontforge-old/FFcolourGlyphs.py b/examples/fontforge-old/FFcolourGlyphs.py
new file mode 100755
index 0000000..e49594b
--- /dev/null
+++ b/examples/fontforge-old/FFcolourGlyphs.py
@@ -0,0 +1,51 @@
+#!/usr/bin/env python
+'Set Glyph colours based on a csv file - format glyphname,colour'
+__url__ = 'http://github.com/silnrsi/pysilfont'
+__copyright__ = 'Copyright (c) 2015 SIL International (http://www.sil.org)'
+__license__ = 'Released under the MIT License (http://opensource.org/licenses/MIT)'
+__author__ = 'David Raymond'
+
+from silfont.core import execute
+
+argspec = [
+ ('ifont',{'help': 'Input font file'}, {'type': 'infont'}),
+ ('ofont',{'help': 'Output font file','nargs': '?' }, {'type': 'outfont', 'def': 'new'}),
+ ('-i','--input',{'help': 'Input csv file'}, {'type': 'infile', 'def': 'colourGlyphs.csv'}),
+ ('-l','--log',{'help': 'Log file'}, {'type': 'outfile', 'def': 'colourGlyphs.log'})]
+
+def doit(args) :
+ font=args.ifont
+ inpf = args.input
+ logf = args.log
+# define colours
+ colours = {
+ 'black' :0x000000,
+ 'red' :0xFF0000,
+ 'green' :0x00FF00,
+ 'blue' :0x0000FF,
+ 'cyan' :0x00FFFF,
+ 'magenta':0xFF00FF,
+ 'yellow' :0xFFFF00,
+ 'white' :0xFFFFFF }
+
+# Change colour of Glyphs
+ for line in inpf.readlines() :
+ glyphn, colour = line.strip().split(",") # will exception if not 2 elements
+ colour=colour.lower()
+ if glyphn[0] in '"\'' : glyphn = glyphn[1:-1] # slice off quote marks, if present
+ if glyphn not in font:
+ logf.write("Glyph %s not in font\n" % (glyphn))
+ print "Glyph %s not in font" % (glyphn)
+ continue
+ g = font[glyphn]
+ if colour in colours.keys():
+ g.color=colours[colour]
+ else:
+ logf.write("Glyph: %s - non-standard colour %s\n" % (glyphn,colour))
+ print "Glyph: %s - non-standard colour %s" % (glyphn,colour)
+
+ logf.close()
+ return font
+
+def cmd() : execute("FF",doit,argspec)
+if __name__ == "__main__": cmd()
diff --git a/examples/fontforge-old/FFcompareFonts.py b/examples/fontforge-old/FFcompareFonts.py
new file mode 100755
index 0000000..66f2079
--- /dev/null
+++ b/examples/fontforge-old/FFcompareFonts.py
@@ -0,0 +1,44 @@
+#!/usr/bin/env python
+'Compare two fonts based on specified criteria and report differences'
+__url__ = 'http://github.com/silnrsi/pysilfont'
+__copyright__ = 'Copyright (c) 2015 SIL International (http://www.sil.org)'
+__license__ = 'Released under the MIT License (http://opensource.org/licenses/MIT)'
+__author__ = 'David Raymond'
+
+from silfont.core import execute
+
+argspec = [
+ ('ifont',{'help': 'Input font file'}, {'type': 'infont'}),
+ ('ifont2',{'help': 'Input font file 2'}, {'type': 'infont', 'def': 'new'}),
+ ('-l','--log',{'help': 'Log file'}, {'type': 'outfile', 'def': 'compareFonts.log'}),
+ ('-o','--options',{'help': 'Options', 'choices': ['c'], 'nargs': '*'}, {})
+ ]
+
+def doit(args) :
+ font1=args.ifont
+ font2=args.ifont2
+ logf = args.log
+ options = args.options
+ logf.write("Comparing fonts: \n %s (%s)\n %s (%s)\n" % (font1.path,font1.fontname,font2.path,font2.fontname))
+ if options != None : logf.write('with options: %s\n' % (options))
+ logf.write("\n")
+ compare(font1,font2,logf,options)
+ compare(font2,font1,logf,None) # Compare again the other way around, just looking for missing Glyphs
+ logf.close()
+ return
+
+def compare(fonta,fontb,logf,options) :
+ for glyph in fonta :
+ if glyph in fontb :
+ if options != None : # Do extra checks based on options supplied
+ ga=fonta[glyph]
+ gb=fontb[glyph]
+ for opt in options :
+ if opt == "c" :
+ if len(ga.references) != len(gb.references) :
+ logf.write("Glyph %s: number of components is different - %s v %s\n" % (glyph,len(ga.references),len(gb.references)))
+ else :
+ logf.write("Glyph %s missing from %s\n" % (glyph,fonta.path))
+
+def cmd() : execute("FF",doit,argspec)
+if __name__ == "__main__": cmd()
diff --git a/examples/fontforge-old/FFdblEncode.py b/examples/fontforge-old/FFdblEncode.py
new file mode 100755
index 0000000..781267b
--- /dev/null
+++ b/examples/fontforge-old/FFdblEncode.py
@@ -0,0 +1,48 @@
+#!/usr/bin/env python
+'''FontForge: Double encode glyphs based on double encoding data in a file
+Lines in file should look like: "LtnSmARetrHook",U+F236,U+1D8F'''
+__url__ = 'http://github.com/silnrsi/pysilfont'
+__copyright__ = 'Copyright (c) 2015 SIL International (http://www.sil.org)'
+__license__ = 'Released under the MIT License (http://opensource.org/licenses/MIT)'
+__author__ = 'David Raymond'
+
+from silfont.core import execute
+
+argspec = [
+ ('ifont',{'help': 'Input font file'}, {'type': 'infont'}),
+ ('ofont',{'help': 'Output font file','nargs': '?' }, {'type': 'outfont', 'def': 'new'}),
+ ('-i','--input',{'help': 'Input csv text file'}, {'type': 'infile', 'def': 'DblEnc.txt'}),
+ ('-l','--log',{'help': 'Log file'}, {'type': 'outfile', 'def': 'DblEnc.log'})]
+
+def doit(args) :
+ font = args.ifont
+ inpf = args.input
+ logf = args.log
+#Create dbl_encode list from the input file
+ dbl_encode = {}
+ for line in inpf.readlines() :
+ glyphn, pua_usv_str, std_usv_str = line.strip().split(",") # will exception if not 3 elements
+ if glyphn[0] in '"\'' : glyphn = glyphn[1:-1] # slice off quote marks, if present
+ pua_usv, std_usv = int(pua_usv_str[2:], 16), int(std_usv_str[2:], 16)
+ dbl_encode[glyphn] = [std_usv, pua_usv]
+ inpf.close()
+
+ for glyph in sorted(dbl_encode.keys()) :
+ if glyph not in font:
+ logf.write("Glyph %s not in font\n" % (glyph))
+ continue
+ g = font[glyph]
+ ousvs=[g.unicode]
+ oalt=g.altuni
+ if oalt != None:
+ for au in oalt:
+ ousvs.append(au[0]) # (may need to check variant flag)
+ dbl = dbl_encode[glyph]
+ g.unicode = dbl[0]
+ g.altuni = ((dbl[1],),)
+ logf.write("encoding for %s changed: %s -> %s\n" % (glyph, ousvs, dbl))
+ logf.close()
+ return font
+
+def cmd() : execute("FF",doit,argspec)
+if __name__ == "__main__": cmd()
diff --git a/examples/fontforge-old/FFfromAP.py b/examples/fontforge-old/FFfromAP.py
new file mode 100755
index 0000000..ab66a29
--- /dev/null
+++ b/examples/fontforge-old/FFfromAP.py
@@ -0,0 +1,74 @@
+#!/usr/bin/env python
+'''Import Attachment Point database into a fontforge font'''
+__url__ = 'http://github.com/silnrsi/pysilfont'
+__copyright__ = 'Copyright (c) 2015 SIL International (http://www.sil.org)'
+__license__ = 'Released under the MIT License (http://opensource.org/licenses/MIT)'
+__author__ = 'Martin Hosken'
+
+from silfont.core import execute
+
+argspec = [
+ ('ifont', {'help': 'Input font file'}, {'type': 'infont'}),
+ ('ofont', {'help': 'Output font file'}, {'type': 'outfont'}),
+ ('-a','--ap', {'nargs' : 1, 'help': 'Input AP database (required)'}, {})
+]
+
+def assign(varlist, expr) :
+ """passes a variable to be assigned as a list and returns the value"""
+ varlist[0] = expr
+ return expr
+
+def getuidenc(e, f) :
+ if 'UID' in e.attrib :
+ u = int(e.get('UID'), 16)
+ return f.findEncodingSlot(u)
+ else :
+ return -1
+
+def getgid(e, f) :
+ if 'GID' in e.attrib :
+ return int(e.get('GID'))
+ else :
+ return -1
+
+def doit(args) :
+ from xml.etree.ElementTree import parse
+
+ f = args.ifont
+ g = None
+ etree = parse(args.ap)
+ u = []
+ for e in etree.getroot().iterfind("glyph") :
+ name = e.get('PSName')
+ if name in f :
+ g = f[name]
+ elif assign(u, getuidenc(e, f)) != -1 :
+ g = f[u[0]]
+ elif assign(u, getgid(e, f)) != -1 :
+ g = f[u[0]]
+ elif g is not None : # assume a rename so just take next glyph
+ g = f[g.encoding + 1]
+ else :
+ g = f[0]
+ g.name = name
+ g.anchorPoints = ()
+ for p in e.iterfind('point') :
+ pname = p.get('type')
+ l = p[0]
+ x = int(l.get('x'))
+ y = int(l.get('y'))
+ if pname.startswith('_') :
+ ptype = 'mark'
+ pname = pname[1:]
+ else :
+ ptype = 'base'
+ g.addAnchorPoint(pname, ptype, float(x), float(y))
+ comment = []
+ for p in e.iterfind('property') :
+ comment.append("{}: {}".format(e.get('name'), e.get('value')))
+ for p in e.iterfind('note') :
+ comment.append(e.text.strip())
+ g.comment = "\n".join(comment)
+
+def cmd() : execute("FF",doit,argspec)
+if __name__ == "__main__": cmd()
diff --git a/examples/fontforge-old/FFlistAPNum.py b/examples/fontforge-old/FFlistAPNum.py
new file mode 100755
index 0000000..ebba84b
--- /dev/null
+++ b/examples/fontforge-old/FFlistAPNum.py
@@ -0,0 +1,38 @@
+#!/usr/bin/env python
+'FontForge: Report Glyph name, number of anchors - sorted by number of anchors'
+__url__ = 'http://github.com/silnrsi/pysilfont'
+__copyright__ = 'Copyright (c) 2015 SIL International (http://www.sil.org)'
+__license__ = 'Released under the MIT License (http://opensource.org/licenses/MIT)'
+__author__ = 'David Raymond'
+
+from silfont.core import execute
+
+argspec = [
+ ('ifont',{'help': 'Input font file'}, {'type': 'infont'}),
+ ('-o','--output',{'help': 'Output text file'}, {'type': 'outfile', 'def': 'APnum.txt'})]
+
+def doit(args) :
+ font = args.ifont
+ outf = args.output
+
+ # Make a list of glyphs and number of anchor points
+ AP_lst = []
+ for glyph in font:
+ AP_lst.append( [glyph, len(font[glyph].anchorPoints)] )
+ # Sort by numb of APs then glyphname
+ AP_lst.sort(AP_cmp)
+ for AP in AP_lst:
+ outf.write("%s,%s\n" % (AP[0], AP[1]))
+
+ outf.close()
+ print "done"
+
+def AP_cmp(a, b): # Comparison to sort first by number of attachment points) then by Glyph name
+ c = cmp(a[1], b[1])
+ if c != 0:
+ return c
+ else:
+ return cmp(a[0], b[0])
+
+def cmd() : execute("FF",doit,argspec)
+if __name__ == "__main__": cmd()
diff --git a/examples/fontforge-old/FFlistGlyphNames.py b/examples/fontforge-old/FFlistGlyphNames.py
new file mode 100755
index 0000000..3967df0
--- /dev/null
+++ b/examples/fontforge-old/FFlistGlyphNames.py
@@ -0,0 +1,22 @@
+#!/usr/bin/env python
+'FontForge: List all gyphs with encoding and name'
+__url__ = 'http://github.com/silnrsi/pysilfont'
+__copyright__ = 'Copyright (c) 2015 SIL International (http://www.sil.org)'
+__license__ = 'Released under the MIT License (http://opensource.org/licenses/MIT)'
+__author__ = 'David Raymond'
+
+from silfont.core import execute
+
+argspec = [
+ ('ifont',{'help': 'Input font file'}, {'type': 'infont'}),
+ ('-o','--output',{'help': 'Output text file'}, {'type': 'outfile', 'def': 'Gnames.txt'})]
+
+def doit(args) :
+ outf = args.output
+ for glyph in args.ifont:
+ g = args.ifont[glyph]
+ outf.write('%s: %s, %s\n' % (glyph, g.encoding, g.glyphname))
+ outf.close()
+
+def cmd() : execute("FF",doit,argspec)
+if __name__ == "__main__": cmd()
diff --git a/examples/fontforge-old/FFlistGlyphinfo.py b/examples/fontforge-old/FFlistGlyphinfo.py
new file mode 100755
index 0000000..00736b8
--- /dev/null
+++ b/examples/fontforge-old/FFlistGlyphinfo.py
@@ -0,0 +1,61 @@
+#!/usr/bin/env python
+'FontForge: List all the data in a glyph object in key, value pairs'
+__url__ = 'http://github.com/silnrsi/pysilfont'
+__copyright__ = 'Copyright (c) 2015 SIL International (http://www.sil.org)'
+__license__ = 'Released under the MIT License (http://opensource.org/licenses/MIT)'
+__author__ = 'David Raymond'
+
+import fontforge, types, sys
+from silfont.core import execute
+
+argspec = [
+ ('font',{'help': 'Input font file'}, {'type': 'infont'}),
+ ('-o','--output',{'help': 'Output text file'}, {'type': 'outfile', 'def': 'glyphinfo.txt'})]
+
+
+def doit(args) :
+ font=args.font
+ outf = args.output
+
+ glyphn = raw_input("Glyph name or number: ")
+
+ while glyphn:
+
+ isglyph=True
+ if not(glyphn in font):
+ try:
+ glyphn=int(glyphn)
+ except ValueError:
+ isglyph=False
+ else:
+ if not(glyphn in font):
+ isglyph=False
+
+ if isglyph:
+ g=font[glyphn]
+ outf.write("\n%s\n\n" % glyphn)
+ # Write to file all normal key,value pairs - exclude __ and built in functions
+ for k in dir(g):
+ if k[0:2] == "__": continue
+ attrk=getattr(g,k)
+ if attrk is None: continue
+ tk=type(attrk)
+ if tk == types.BuiltinFunctionType: continue
+ if k == "ttinstrs": # ttinstr values are not printable characters
+ outf.write("%s,%s\n" % (k,"<has values>"))
+ else:
+ outf.write("%s,%s\n" % (k,attrk))
+ # Write out all normal keys where value is none
+ for k in dir(g):
+ attrk=getattr(g,k)
+ if attrk is None:
+ outf.write("%s,%s\n" % (k,attrk))
+ else:
+ print "Invalid glyph"
+
+ glyphn = raw_input("Glyph name or number: ")
+ print "done"
+ outf.close
+
+def cmd() : execute("FF",doit,argspec)
+if __name__ == "__main__": cmd()
diff --git a/examples/fontforge-old/FFlistRefNum.py b/examples/fontforge-old/FFlistRefNum.py
new file mode 100755
index 0000000..e709781
--- /dev/null
+++ b/examples/fontforge-old/FFlistRefNum.py
@@ -0,0 +1,33 @@
+#!/usr/bin/env python
+'FontForge: Report Glyph name, Number of references (components)'
+__url__ = 'http://github.com/silnrsi/pysilfont'
+__copyright__ = 'Copyright (c) 2015 SIL International (http://www.sil.org)'
+__license__ = 'Released under the MIT License (http://opensource.org/licenses/MIT)'
+__author__ = 'David Raymond'
+
+from silfont.core import execute
+
+argspec = [
+ ('ifont',{'help': 'Input font file'}, {'type': 'infont'}),
+ ('-o','--output',{'help': 'Output text file'}, {'type': 'outfile', 'def': 'RefNum.txt'})]
+
+def doit(args) :
+ font = args.ifont
+ outf = args.output
+
+ outf.write("# glyphs with number of components\n\n")
+ for glyph in font:
+ gname=font[glyph].glyphname
+ ref = font[glyph].references
+ if ref is None:
+ n=0
+ else:
+ n=len(ref)
+ outf.write("%s %i\n" % (gname,n))
+
+ outf.close()
+
+ print "Done!"
+
+def cmd() : execute("FF",doit,argspec)
+if __name__ == "__main__": cmd()
diff --git a/examples/fontforge-old/FFnameSearchNReplace.py b/examples/fontforge-old/FFnameSearchNReplace.py
new file mode 100755
index 0000000..ce6fb7e
--- /dev/null
+++ b/examples/fontforge-old/FFnameSearchNReplace.py
@@ -0,0 +1,38 @@
+#!/usr/bin/env python
+'Search and replace strings in Glyph names. Strings can be regular expressions'
+__url__ = 'http://github.com/silnrsi/pysilfont'
+__copyright__ = 'Copyright (c) 2015 SIL International (http://www.sil.org)'
+__license__ = 'Released under the MIT License (http://opensource.org/licenses/MIT)'
+__author__ = 'David Raymond'
+
+from silfont.core import execute
+import re
+
+argspec = [
+ ('ifont',{'help': 'Input font file'}, {'type': 'infont'}),
+ ('ofont',{'help': 'Output font file','nargs': '?' }, {'type': 'outfont', 'def': 'new'}),
+ ('search',{'help': 'Expression to search for'}, {}),
+ ('replace',{'help': 'Expression to replace with'}, {}),
+ ('-l','--log',{'help': 'Log file'}, {'type': 'outfile', 'def': 'searchNReplace.log'})]
+
+def doit(args) :
+ font=args.ifont
+ search=args.search
+ replace=args.replace
+ logf = args.log
+
+ changes=False
+ for glyph in font :
+ newname = re.sub(search, replace, glyph)
+ if newname != glyph :
+ font[glyph].glyphname=newname
+ changes=True
+ logf.write('Glyph %s renamed to %s\n' % (glyph,newname))
+ logf.close()
+ if changes :
+ return font
+ else :
+ return
+
+def cmd() : execute("FF",doit,argspec)
+if __name__ == "__main__": cmd()
diff --git a/examples/fontforge-old/FFundblEncode.py b/examples/fontforge-old/FFundblEncode.py
new file mode 100755
index 0000000..651a7e3
--- /dev/null
+++ b/examples/fontforge-old/FFundblEncode.py
@@ -0,0 +1,50 @@
+#!/usr/bin/env python
+'''FontForge: Re-encode double-encoded glyphs based on double encoding data in a file
+Lines in file should look like: "LtnSmARetrHook",U+F236,U+1D8F'''
+__url__ = 'http://github.com/silnrsi/pysilfont'
+__copyright__ = 'Copyright (c) 2015 SIL International (http://www.sil.org)'
+__license__ = 'Released under the MIT License (http://opensource.org/licenses/MIT)'
+__author__ = 'David Raymond'
+
+from silfont.core import execute
+
+argspec = [
+ ('ifont',{'help': 'Input font file'}, {'type': 'infont'}),
+ ('ofont',{'help': 'Output font file','nargs': '?' }, {'type': 'outfont', 'def': 'new'}),
+ ('-i','--input',{'help': 'Input csv text file'}, {'type': 'infile', 'def': 'DblEnc.txt'}),
+ ('-l','--log',{'help': 'Log file'}, {'type': 'outfile', 'def': 'unDblEnc.log'})]
+
+def doit(args) :
+ font=args.ifont
+ inpf = args.input
+ logf = args.log
+# Create dbl_encode list from the input file
+ dbl_encode = {}
+ for line in inpf.readlines():
+ glyphn, pua_usv_str, std_usv_str = line.strip().split(",") # will exception if not 3 elements
+ if glyphn[0] in '"\'' : glyphn = glyphn[1:-1] # slice off quote marks, if present
+ pua_usv, std_usv = int(pua_usv_str[2:], 16), int(std_usv_str[2:], 16)
+ dbl_encode[glyphn] = [std_usv, pua_usv]
+ inpf.close()
+
+ for glyph in sorted(dbl_encode.keys()):
+ logf.write (reincode(font,glyph,dbl_encode[glyph][0]))
+ logf.write (reincode(font,glyph+"Dep",dbl_encode[glyph][1]))
+ logf.close()
+ return font
+
+def reincode(font,glyph,usv):
+ if glyph not in font:
+ return ("Glyph %s not in font\n" % (glyph))
+ g = font[glyph]
+ ousvs=[g.unicode]
+ oalt=g.altuni
+ if oalt != None:
+ for au in oalt:
+ ousvs.append(au[0]) # (may need to check variant flag)
+ g.unicode = usv
+ g.altuni = None
+ return ("encoding for %s changed: %s -> %s\n" % (glyph, ousvs, usv))
+
+def cmd() : execute("FF",doit,argspec)
+if __name__ == "__main__": cmd()
diff --git a/examples/fontforge-old/demoAddToMenu.py b/examples/fontforge-old/demoAddToMenu.py
new file mode 100755
index 0000000..6af6580
--- /dev/null
+++ b/examples/fontforge-old/demoAddToMenu.py
@@ -0,0 +1,38 @@
+#!/usr/bin/env python
+'FontForge: Demo script to add menu items to FF tools menu'
+__url__ = 'http://github.com/silnrsi/pysilfont'
+__copyright__ = 'Copyright (c) 2014 SIL International (http://www.sil.org)'
+__license__ = 'Released under the MIT License (http://opensource.org/licenses/MIT)'
+__author__ = 'David Raymond'
+
+import sys, os, fontforge
+sys.path.append(os.path.join(os.environ['HOME'], 'src/pysilfont/scripts'))
+import samples.demoFunctions
+from samples.demoFunctions import functionList, callFunctions
+#from samples.demoCallFunctions import callFunctions
+
+def toolMenuFunction(functionGroup,font) :
+ reload (samples.demoFunctions)
+ callFunctions(functionGroup,font)
+
+funcList=functionList()
+
+for functionGroup in funcList :
+ menuType = funcList[functionGroup][0]
+ fontforge.registerMenuItem(toolMenuFunction,None,functionGroup,menuType,None,functionGroup);
+ print functionGroup, " registered"
+
+''' This script needs to be called from one of the folders that FontForge looks in for scripts to
+run when it is started. With current versions of FontForge, one is Home/.config/fontforge/python.
+You may need to turn on showing hidden files (ctrl-H in Nautilus) before you can see the .config
+folder. Within there create a one-line python script, say call sampledemo.py containing a call
+to this script, eg:
+
+execfile("/home/david/src/pysilfont/scripts/samples/demoAddToMenu.py")
+
+Due to the reload(samples.demoFunctions) line above, changes functions defined in demoFunctions.py
+are dynamic, ie FontForge does not have to be restarted (as would be the case if the functions were
+called directly from the tools menu. Functions can even be added dynamically to the function groups.
+
+If new function groups are defined, FontForge does have to be restarted to add them to the tools menu.
+'''
diff --git a/examples/fontforge-old/demoExecuteScript.py b/examples/fontforge-old/demoExecuteScript.py
new file mode 100755
index 0000000..22a3094
--- /dev/null
+++ b/examples/fontforge-old/demoExecuteScript.py
@@ -0,0 +1,29 @@
+#!/usr/bin/env python
+'FontForge: Demo code to paste into the "Execute Script" dialog'
+__url__ = 'http://github.com/silnrsi/pysilfont'
+__copyright__ = 'Copyright (c) 2013 SIL International (http://www.sil.org)'
+__license__ = 'Released under the MIT License (http://opensource.org/licenses/MIT)'
+__author__ = 'David Raymond'
+
+import sys, os, fontforge
+sys.path.append(os.path.join(os.environ['HOME'], 'src/pysilfont/scripts'))
+import samples.demoFunctions # Loads demoFunctions.py module from src/pysilfont/scripts/samples
+reload (samples.demoFunctions) # Reload the demo module each time you execute the script to pick up any recent edits
+samples.demoFunctions.callFunctions("Colour Glyphs",fontforge.activeFont())
+
+'''Demo usage:
+Open the "Execute Script" dialog (from the FontForge File menu or press ctrl+.),
+paste just the code section this (from "import..." to "samples...") into there then
+run it (Alt+o) and see how it pops up a dialogue with a choice of 3 functions to run.
+Edit demoFunctions.py and alter one of the functions.
+Execute the script again and see that that the function's behaviour has changed.
+
+Additional functions can be added to demoFunctions.py and, if also defined functionList()
+become availably immdiately.
+
+If you want to see the output from print statements, or use commands like input, (eg
+for degugging purposes) then start FontForge from a terminal window rather than the
+desktop launcher.
+
+When starting from a terminal window, you can also specify the font to use,
+eg $ fontforge /home/david/RFS/GenBasR.sfd''' \ No newline at end of file
diff --git a/examples/fontforge-old/demoFunctions.py b/examples/fontforge-old/demoFunctions.py
new file mode 100755
index 0000000..be065a1
--- /dev/null
+++ b/examples/fontforge-old/demoFunctions.py
@@ -0,0 +1,90 @@
+#!/usr/bin/env python
+'FontForge: Sample functions to call from other demo scripts'
+__url__ = 'http://github.com/silnrsi/pysilfont'
+__copyright__ = 'Copyright (c) 2014 SIL International (http://www.sil.org)'
+__license__ = 'Released under the MIT License (http://opensource.org/licenses/MIT)'
+__author__ = 'David Raymond'
+
+import fontforge
+
+def colLtnAGlyphs(font) :
+
+ #print "Toggling colour of glyphs with LtnCapA in their name"
+ for glyph in font:
+ g = font[glyph]
+ if glyph.find('LtnCapA') >= 0:
+ if g.color != 0x00FF00:
+ g.color = 0x00FF00 # Green
+ else :
+ g.color = 0xFFFFFF # White
+ print "LtnCapA glyphs coloured"
+
+def markOverlaps(font) :
+ print "Toggling colour of glyphs where contours overlap"
+ for glyph in font:
+ g = font[glyph]
+ if g.selfIntersects() :
+ if g.color != 0xFF0000:
+ g.color = 0xFF0000 # Red
+ else :
+ g.color = 0xFFFFFF # White
+ print "Glyphs coloured"
+
+def markScaled(font) :
+ print "Toggling colour of glyphs with scaled components"
+ for glyph in font:
+ g = font[glyph]
+ for ref in g.references:
+ transform=ref[1]
+ if transform[0] != 1.0 or transform[3] != 1.0 :
+ if g.color != 0xFF0000:
+ g.color = 0xFF0000 # Red
+ else :
+ g.color = 0xFFFFFF # White
+ print "Glyphs coloured"
+
+def clearColours(font) :
+ for glyph in font :
+ g = font[glyph]
+ g.color = 0xFFFFFF
+
+def functionList() :
+ ''' Returns a dictionary to be used by callFunctions() and demoAddToMenu.py
+ The dictionary is indexed by a group name which could be used as Tools menu
+ entry or to reference the group of functions. For each group there is a tuple
+ consisting of the Tools menu type (Font or Glyph) then one tuple per function.
+ For each function the tuple contains:
+ Function name
+ Label for the individual function in dialog box called from Tools menu
+ Actual function object'''
+ funcList = {
+ "Colour Glyphs":("Font",
+ ("colLtnAGlyphs","Colour Latin A Glyphs",colLtnAGlyphs),
+ ("markOverlaps","Mark Overlaps",markOverlaps),
+ ("markScaled","Mark Scaled",markScaled),
+ ("clearColours","Clear all colours",clearColours)),
+ "Group with single item":("Font",
+ ("clearColours","Clear all colours",clearColours))}
+ return funcList
+
+def callFunctions(functionGroup,font) :
+ funcList=functionList()[functionGroup]
+ i=0
+ for tuple in funcList :
+ if i == 0 :
+ pass # Font/Glyph parameter not relevant here
+ elif i == 1 :
+ functionDescs=[tuple[1]]
+ functions=[tuple[2]]
+ else :
+ functionDescs.append(tuple[1])
+ functions.append(tuple[2])
+ i=i+1
+
+ if i == 2 : # Only one function in the group, so just call the function
+ functions[0](font)
+ else :
+ functionNum=fontforge.ask(functionGroup,"Please choose the function to run",functionDescs)
+ functions[functionNum](font)
+
+ \ No newline at end of file
diff --git a/examples/gdl/__init__.py b/examples/gdl/__init__.py
new file mode 100644
index 0000000..9f6ca1c
--- /dev/null
+++ b/examples/gdl/__init__.py
@@ -0,0 +1,20 @@
+# Copyright 2012, SIL International
+# All rights reserved.
+#
+# This library is free software; you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License as published
+# by the Free Software Foundation; either version 2.1 of License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should also have received a copy of the GNU Lesser General Public
+# License along with this library in the file named "LICENSE".
+# If not, write to the Free Software Foundation, 51 Franklin Street,
+# suite 500, Boston, MA 02110-1335, USA or visit their web page on the
+# internet at http://www.fsf.org/licenses/lgpl.html.
+
+__all__ = ['makegdl', 'psnames']
diff --git a/examples/gdl/font.py b/examples/gdl/font.py
new file mode 100644
index 0000000..01f7691
--- /dev/null
+++ b/examples/gdl/font.py
@@ -0,0 +1,394 @@
+#!/usr/bin/env python
+'The main font object for GDL creation. Depends on fonttools'
+__url__ = 'http://github.com/silnrsi/pysilfont'
+__copyright__ = 'Copyright (c) 2012 SIL International (http://www.sil.org)'
+__license__ = 'Released under the MIT License (http://opensource.org/licenses/MIT)'
+
+import os, re, traceback
+from silfont.gdl.glyph import Glyph
+from silfont.gdl.psnames import Name
+from xml.etree.cElementTree import ElementTree, parse, Element
+from fontTools.ttLib import TTFont
+
+# A collection of glyphs that have a given attachment point defined
+class PointClass(object) :
+
+ def __init__(self, name) :
+ self.name = name
+ self.glyphs = []
+ self.dias = []
+
+ def addBaseGlyph(self, g) :
+ self.glyphs.append(g)
+
+ def addDiaGlyph(self, g) :
+ self.dias.append(g)
+ g.isDia = True
+
+ def hasDias(self) :
+ if len(self.dias) and len(self.glyphs) :
+ return True
+ else :
+ return False
+
+ def classGlyphs(self, isDia = False) :
+ if isDia :
+ return self.dias
+ else :
+ return self.glyphs
+
+ def isNotInClass(self, g, isDia = False) :
+ if not g : return False
+ if not g.isDia : return False
+
+ if isDia :
+ return g not in self.dias
+ else :
+ return g not in self.dias and g not in self.glyphs
+
+
+class FontClass(object) :
+
+ def __init__(self, elements = None, fname = None, lineno = None, generated = False, editable = False) :
+ self.elements = elements or []
+ self.fname = fname
+ self.lineno = lineno
+ self.generated = generated
+ self.editable = editable
+
+ def append(self, element) :
+ self.elements.append(element)
+
+
+class Font(object) :
+
+ def __init__(self, fontfile) :
+ self.glyphs = []
+ self.psnames = {}
+ self.canons = {}
+ self.gdls = {}
+ self.anchors = {}
+ self.ligs = {}
+ self.subclasses = {}
+ self.points = {}
+ self.classes = {}
+ self.aliases = {}
+ self.rules = {}
+ self.posRules = {}
+ if fontfile :
+ self.font = TTFont(fontfile)
+ for i, n in enumerate(self.font.getGlyphOrder()) :
+ self.addGlyph(i, n)
+ else :
+ self.font = None
+
+ def __len__(self) :
+ return len(self.glyphs)
+
+ # [] syntax returns the indicated element of the glyphs array.
+ def __getitem__(self, y) :
+ try :
+ return self.glyphs[y]
+ except IndexError :
+ return None
+
+ def glyph(self, name) :
+ return self.psnames.get(name, None)
+
+ def alias(self, s) :
+ return self.aliases.get(s, s)
+
+ def emunits(self) :
+ return 0
+
+ def initGlyphs(self, nGlyphs) :
+ #print "Font::initGlyphs",nGlyphs
+ self.glyphs = [None] * nGlyphs
+ self.numRealGlyphs = nGlyphs # does not include pseudo-glyphs
+ self.psnames = {}
+ self.canons = {}
+ self.gdls = {}
+ self.classes = {}
+
+ def addGlyph(self, index = None, psName = None, gdlName = None, factory = Glyph) :
+ #print "Font::addGlyph",index,psName,gdlName
+ if psName in self.psnames :
+ return self.psnames[psName]
+ if index is not None and index < len(self.glyphs) and self.glyphs[index] :
+ g = self.glyphs[index]
+ return g
+ g = factory(psName, index) # create a new glyph of the given class
+ self.renameGlyph(g, psName, gdlName)
+ if index is None : # give it the next available index
+ index = len(self.glyphs)
+ self.glyphs.append(g)
+ elif index >= len(self.glyphs) :
+ self.glyphs.extend([None] * (len(self.glyphs) - index + 1))
+ self.glyphs[index] = g
+ return g
+
+ def renameGlyph(self, g, name, gdlName = None) :
+ if g.psname != name :
+ for n in g.parseNames() :
+ del self.psnames[n.psname]
+ del self.canons[n.canonical()]
+ if gdlName :
+ self.setGDL(g, gdlName)
+ else :
+ self.setGDL(g, g.GDLName())
+ for n in g.parseNames() :
+ if n is None : break
+ self.psnames[n.psname] = g
+ self.canons[n.canonical()] = (n, g)
+
+ def setGDL(self, glyph, name) :
+ if not glyph : return
+ n = glyph.GDLName()
+ if n != name and n in self.gdls : del self.gdls[n]
+ if name and name in self.gdls and self.gdls[name] is not glyph :
+ count = 1
+ index = -2
+ name = name + "_1"
+ while name in self.gdls :
+ if self.gdls[name] is glyph : break
+ count = count + 1
+ name = name[0:index] + "_" + str(count)
+ if count == 10 : index = -3
+ if count == 100 : index = -4
+ self.gdls[name] = glyph
+ glyph.setGDL(name)
+
+ def addClass(self, name, elements, fname = None, lineno = 0, generated = False, editable = False) :
+ if name :
+ self.classes[name] = FontClass(elements, fname, lineno, generated, editable)
+
+ def addGlyphClass(self, name, gid, editable = False) :
+ if name not in self.classes :
+ self.classes[name] = FontClass()
+ if gid not in self.classes[name].elements :
+ self.classes[name].append(gid)
+
+ def addRules(self, rules, index) :
+ self.rules[index] = rules
+
+ def addPosRules(self, rules, index) :
+ self.posRules[index] = rules
+
+ def classUpdated(self, name, value) :
+ c = []
+ if name in self.classes :
+ for gid in self.classes[name].elements :
+ g = self[gid]
+ if g : g.removeClass(name)
+ if value is None and name in classes :
+ del self.classes[name]
+ return
+ for n in value.split() :
+ g = self.gdls.get(n, None)
+ if g :
+ c.append(g.gid)
+ g.addClass(name)
+ if name in self.classes :
+ self.classes[name].elements = c
+ else :
+ self.classes[name] = FontClass(c)
+
+ # Return the list of classes that should be updated in the AP XML file.
+ # This does not include classes that are auto-generated or defined in the hand-crafted GDL code.
+ def filterAutoClasses(self, names, autoGdlFile) :
+ res = []
+ for n in names :
+ c = self.classes[n]
+ if not c.generated and (not c.fname or c.fname == autoGdlFile) : res.append(n)
+ return res
+
+ def loadAlias(self, fname) :
+ with open(fname) as f :
+ for l in f.readlines() :
+ l = l.strip()
+ l = re.sub(ur'#.*$', '', l).strip()
+ if not len(l) : continue
+ try :
+ k, v = re.split(ur'\s*[,;\s]\s*', l, 1)
+ except ValueError :
+ k = l
+ v = ''
+ self.aliases[k] = v
+
+ # TODO: move this method to GraideFont, or refactor
+ def loadAP(self, apFileName) :
+ if not os.path.exists(apFileName) : return False
+ etree = parse(apFileName)
+ self.initGlyphs(len(etree.getroot())) # guess each child is a glyph
+ i = 0
+ for e in etree.getroot().iterfind("glyph") :
+ g = self.addGlyph(i, e.get('PSName'))
+ g.readAP(e, self)
+ i += 1
+ return True
+
+ def saveAP(self, apFileName, autoGdlFile) :
+ root = Element('font')
+ root.set('upem', str(self.emunits()))
+ root.set('producer', 'graide 1.0')
+ root.text = "\n\n"
+ for g in self.glyphs :
+ if g : g.createAP(root, self, autoGdlFile)
+ ElementTree(root).write(apFileName, encoding="utf-8", xml_declaration=True)
+
+ def createClasses(self) :
+ self.subclasses = {}
+ for k, v in self.canons.items() :
+ if v[0].ext :
+ h = v[0].head()
+ o = self.canons.get(h.canonical(), None)
+ if o :
+ if v[0].ext not in self.subclasses : self.subclasses[v[0].ext] = {}
+ self.subclasses[v[0].ext][o[1].GDLName()] = v[1].GDLName()
+# for g in self.glyphs :
+# if not g : continue
+# for c in g.classes :
+# if c not in self.classes :
+# self.classes[c] = []
+# self.classes[c].append(g.gid)
+
+ def calculatePointClasses(self) :
+ self.points = {}
+ for g in self.glyphs :
+ if not g : continue
+ for apName in g.anchors.keys() :
+ genericName = apName[:-1] # without the M or S
+ if genericName not in self.points :
+ self.points[genericName] = PointClass(genericName)
+ if apName.endswith('S') :
+ self.points[genericName].addBaseGlyph(g)
+ else :
+ self.points[genericName].addDiaGlyph(g)
+
+ def calculateOTLookups(self) :
+ if self.font :
+ for t in ('GSUB', 'GPOS') :
+ if t in self.font :
+ self.font[t].table.LookupList.process(self)
+
+ def getPointClasses(self) :
+ if len(self.points) == 0 :
+ self.calculatePointClasses()
+ return self.points
+
+ def ligClasses(self) :
+ self.ligs = {}
+ for g in self.glyphs :
+ if not g or not g.name : continue
+ (h, t) = g.name.split_last()
+ if t :
+ o = self.canons.get(h.canonical(), None)
+ if o and o[0].ext == t.ext :
+ t.ext = None
+ t.cname = None
+ tn = t.canonical(noprefix = True)
+ if tn in self.ligs :
+ self.ligs[tn].append((g.GDLName(), o[0].GDL()))
+ else :
+ self.ligs[tn] = [(g.GDLName(), o[0].GDL())]
+
+ def outGDL(self, fh, args) :
+ munits = self.emunits()
+ fh.write('table(glyph) {MUnits = ' + str(munits) + '};\n')
+ nglyphs = 0
+ for g in self.glyphs :
+ if not g or not g.psname : continue
+ if g.psname == '.notdef' :
+ fh.write(g.GDLName() + ' = glyphid(0)')
+ else :
+ fh.write(g.GDLName() + ' = postscript("' + g.psname + '")')
+ outs = []
+ if len(g.anchors) :
+ for a in g.anchors.keys() :
+ v = g.anchors[a]
+ outs.append(a + "=point(" + str(int(v[0])) + "m, " + str(int(v[1])) + "m)")
+ for (p, v) in g.gdl_properties.items() :
+ outs.append("%s=%s" % (p, v))
+ if len(outs) : fh.write(" {" + "; ".join(outs) + "}")
+ fh.write(";\n")
+ nglyphs += 1
+ fh.write("\n")
+ fh.write("\n/* Point Classes */\n")
+ for p in sorted(self.points.values(), key=lambda x: x.name) :
+ if not p.hasDias() : continue
+ n = p.name + "Dia"
+ self.outclass(fh, "c" + n, p.classGlyphs(True))
+ self.outclass(fh, "cTakes" + n, p.classGlyphs(False))
+ self.outclass(fh, 'cn' + n, filter(lambda x : p.isNotInClass(x, True), self.glyphs))
+ self.outclass(fh, 'cnTakes' + n, filter(lambda x : p.isNotInClass(x, False), self.glyphs))
+ fh.write("\n/* Classes */\n")
+ for c in sorted(self.classes.keys()) : # c = class name, l = class object
+ if c not in self.subclasses and not self.classes[c].generated : # don't output the class to the AP file if it was autogenerated
+ self.outclass(fh, c, self.classes[c].elements)
+ for p in self.subclasses.keys() :
+ ins = []
+ outs = []
+ for k, v in self.subclasses[p].items() :
+ ins.append(k)
+ outs.append(v)
+ n = p.replace('.', '_')
+ self.outclass(fh, 'cno_' + n, ins)
+ self.outclass(fh, 'c' + n, outs)
+ fh.write("/* Ligature Classes */\n")
+ for k in sorted(self.ligs.keys()) :
+ self.outclass(fh, "clig" + k, map(lambda x: self.gdls[x[0]], self.ligs[k]))
+ self.outclass(fh, "cligno_" + k, map(lambda x: self.gdls[x[1]], self.ligs[k]))
+ fh.write("\nendtable;\n")
+ fh.write("/* Substitution Rules */\n")
+ for k, v in sorted(self.rules.items(), key=lambda x:map(int,x[0].split('_'))) :
+ fh.write('\n// lookup ' + k + '\n')
+ fh.write('// ' + "\n// ".join(v) + "\n")
+ fh.write("\n/* Positioning Rules */\n")
+ for k, v in sorted(self.posRules.items(), key=lambda x:map(int,x[0].split('_'))) :
+ fh.write('\n// lookup ' + k + '\n')
+ fh.write('// ' + "\n// ".join(v) + "\n")
+ fh.write("\n\n#define MAXGLYPH %d\n\n" % (nglyphs - 1))
+ if args.include :
+ fh.write("#include \"%s\"\n" % args.include)
+
+ def outPosRules(self, fh, num) :
+ fh.write("""
+#ifndef opt2
+#define opt(x) [x]?
+#define opt2(x) [opt(x) x]?
+#define opt3(x) [opt2(x) x]?
+#define opt4(x) [opt3(x) x]?
+#endif
+#define posrule(x) c##x##Dia {attach{to=@1; at=x##S; with=x##M}} / cTakes##x##Dia opt4(cnTakes##x##Dia) _;
+
+table(positioning);
+pass(%d);
+""" % num)
+ for p in self.points.values() :
+ if p.hasDias() :
+ fh.write("posrule(%s);\n" % p.name)
+ fh.write("endpass;\nendtable;\n")
+
+
+ def outclass(self, fh, name, glyphs) :
+ fh.write(name + " = (")
+ count = 1
+ sep = ""
+ for g in glyphs :
+ if not g : continue
+
+
+ if isinstance(g, basestring) :
+ fh.write(sep + g)
+ else :
+ if g.GDLName() is None :
+ print "Can't output " + str(g.gid) + " to class " + name
+ else :
+ fh.write(sep + g.GDLName())
+ if count % 8 == 0 :
+ sep = ',\n '
+ else :
+ sep = ', '
+ count += 1
+ fh.write(');\n\n')
+
diff --git a/examples/gdl/glyph.py b/examples/gdl/glyph.py
new file mode 100644
index 0000000..66944e0
--- /dev/null
+++ b/examples/gdl/glyph.py
@@ -0,0 +1,174 @@
+#!/usr/bin/env python
+'Corresponds to a glyph, for analysis purposes, for GDL generation'
+__url__ = 'http://github.com/silnrsi/pysilfont'
+__copyright__ = 'Copyright (c) 2012 SIL International (http://www.sil.org)'
+__license__ = 'Released under the MIT License (http://opensource.org/licenses/MIT)'
+
+import re, traceback
+from silfont.gdl.psnames import Name
+from xml.etree.cElementTree import SubElement
+
+# Convert from Graphite AP name to the standard name, eg upperM -> _upper
+def gr_ap(txt) :
+ if txt.endswith('M') :
+ return "_" + txt[:-1]
+ elif txt.endswith('S') :
+ return txt[:-1]
+ else :
+ return txt
+
+# Convert from standard AP name to the Graphite name, eg _upper -> upperM
+def ap_gr(txt) :
+ if txt.startswith('_') :
+ return txt[1:] + 'M'
+ else :
+ return txt + 'S'
+
+
+class Glyph(object) :
+
+ isDia = False
+
+ def __init__(self, name, gid = 0) :
+ self.clear()
+ self.setName(name)
+ self.gdl = None
+ self.gid = gid
+ self.uid = "" # this is a string!
+ self.comment = ""
+ self.isDia = False
+
+ def clear(self) :
+ self.anchors = {}
+ self.classes = set()
+ self.gdl_properties = {}
+ self.properties = {}
+
+ def setName(self, name) :
+ self.psname = name
+ self.name = next(self.parseNames())
+
+ def setAnchor(self, name, x, y, t = None) :
+ send = True
+ if name in self.anchors :
+ if x is None and y is None :
+ del self.anchors[name]
+ return True
+ if x is None : x = self.anchors[name][0]
+ if y is None : y = self.anchors[name][1]
+ send = self.anchors[name] != (x, y)
+ self.anchors[name] = (x, y)
+ return send
+ # if not name.startswith("_") and t != 'basemark' :
+ # self.isBase = True
+
+ def parseNames(self) :
+ if self.psname :
+ for name in self.psname.split("/") :
+ res = Name(name)
+ yield res
+ else :
+ yield None
+
+ def GDLName(self) :
+ if self.gdl :
+ return self.gdl
+ elif self.name :
+ return self.name.GDL()
+ else :
+ return None
+
+ def setGDL(self, name) :
+ self.gdl = name
+
+ def readAP(self, elem, font) :
+ self.uid = elem.get('UID', None)
+ for p in elem.iterfind('property') :
+ n = p.get('name')
+ if n == 'GDLName' :
+ self.setGDL(p.get('value'))
+ elif n.startswith('GDL_') :
+ self.gdl_properties[n[4:]] = p.get('value')
+ else :
+ self.properties[n] = p.get('value')
+ for p in elem.iterfind('point') :
+ l = p.find('location')
+ self.setAnchor(ap_gr(p.get('type')), int(l.get('x', 0)), int(l.get('y', 0)))
+ p = elem.find('note')
+ if p is not None and p.text :
+ self.comment = p.text
+ if 'classes' in self.properties :
+ for c in self.properties['classes'].split() :
+ if c not in self.classes :
+ self.classes.add(c)
+ font.addGlyphClass(c, self, editable = True)
+
+ def createAP(self, elem, font, autoGdlFile) :
+ e = SubElement(elem, 'glyph')
+ if self.psname : e.set('PSName', self.psname)
+ if self.uid : e.set('UID', self.uid)
+ if self.gid is not None : e.set('GID', str(self.gid))
+ ce = None
+ if 'classes' in self.properties and self.properties['classes'].strip() :
+ tempClasses = self.properties['classes']
+ self.properties['classes'] = " ".join(font.filterAutoClasses(self.properties['classes'].split(), autoGdlFile))
+
+ for k in sorted(self.anchors.keys()) :
+ v = self.anchors[k]
+ p = SubElement(e, 'point')
+ p.set('type', gr_ap(k))
+ p.text = "\n "
+ l = SubElement(p, 'location')
+ l.set('x', str(v[0]))
+ l.set('y', str(v[1]))
+ l.tail = "\n "
+ if ce is not None : ce.tail = "\n "
+ ce = p
+
+ for k in sorted(self.gdl_properties.keys()) :
+ if k == "*skipPasses*" : continue # not set in GDL
+
+ v = self.gdl_properties[k]
+ if v :
+ p = SubElement(e, 'property')
+ p.set('name', 'GDL_' + k)
+ p.set('value', v)
+ if ce is not None : ce.tail = "\n "
+ ce = p
+
+ if self.gdl and (not self.name or self.gdl != self.name.GDL()) :
+ p = SubElement(e, 'property')
+ p.set('name', 'GDLName')
+ p.set('value', self.GDLName())
+ if ce is not None : ce.tail = "\n "
+ ce = p
+
+ for k in sorted(self.properties.keys()) :
+ v = self.properties[k]
+ if v :
+ p = SubElement(e, 'property')
+ p.set('name', k)
+ p.set('value', v)
+ if ce is not None : ce.tail = "\n "
+ ce = p
+
+ if self.comment :
+ p = SubElement(e, 'note')
+ p.text = self.comment
+ if ce is not None : ce.tail = "\n "
+ ce = p
+
+ if 'classes' in self.properties and self.properties['classes'].strip() :
+ self.properties['classes'] = tempClasses
+ if ce is not None :
+ ce.tail = "\n"
+ e.text = "\n "
+ e.tail = "\n"
+ return e
+
+def isMakeGDLSpecialClass(name) :
+# if re.match(r'^cn?(Takes)?.*?Dia$', name) : return True
+# if name.startswith('clig') : return True
+# if name.startswith('cno_') : return True
+ if re.match(r'^\*GC\d+\*$', name) : return True # auto-pseudo glyph with name = *GCXXXX*
+ return False
diff --git a/examples/gdl/makeGdl.py b/examples/gdl/makeGdl.py
new file mode 100755
index 0000000..d8eaf78
--- /dev/null
+++ b/examples/gdl/makeGdl.py
@@ -0,0 +1,31 @@
+#!/usr/bin/env python
+'Analyse a font and generate GDL to help with the creation of graphite fonts'
+__url__ = 'http://github.com/silnrsi/pysilfont'
+__copyright__ = 'Copyright (c) 2015 SIL International (http://www.sil.org)'
+__license__ = 'Released under the MIT License (http://opensource.org/licenses/MIT)'
+
+from gdl.font import Font
+import gdl.ot
+from argparse import ArgumentParser
+
+parser = ArgumentParser()
+parser.add_argument('infont')
+parser.add_argument('outgdl')
+parser.add_argument('-a','--ap')
+parser.add_argument('-i','--include')
+parser.add_argument('-y','--alias')
+args = parser.parse_args()
+
+f = Font(args.infont)
+if args.alias : f.loadAlias(args.alias)
+if args.ap : f.loadAP(args.ap)
+
+f.createClasses()
+f.calculateOTLookups()
+f.calculatePointClasses()
+f.ligClasses()
+
+outf = open(args.outgdl, "w")
+f.outGDL(outf, args)
+outf.close()
+
diff --git a/examples/gdl/ot.py b/examples/gdl/ot.py
new file mode 100644
index 0000000..a3ed50d
--- /dev/null
+++ b/examples/gdl/ot.py
@@ -0,0 +1,448 @@
+#!/usr/bin/env python
+'OpenType analysis for GDL conversion'
+__url__ = 'http://github.com/silnrsi/pysilfont'
+__copyright__ = 'Copyright (c) 2012 SIL International (http://www.sil.org)'
+__license__ = 'Released under the MIT License (http://opensource.org/licenses/MIT)'
+
+import re, traceback, logging
+from fontTools.ttLib.tables import otTables
+
+def compress_strings(strings) :
+ '''If we replace one column in the string with different lists, can we reduce the number
+ of strings? Each string is a tuple of the string and a single value that will be put into
+ a class as well when list compression occurs'''
+ maxlen = max(map(lambda x: len(x[0]), strings))
+ scores = []
+ for r in range(maxlen) :
+ allchars = {}
+ count = 0
+ for s in strings :
+ if r >= len(s[0]) : continue
+ c = tuple(s[0][0:r] + (s[0][r+1:] if r < len(s[0]) - 1 else []))
+ if c in allchars :
+ allchars[c] += 1
+ else :
+ allchars[c] = 0
+ count += 1
+ scores.append((max(allchars.values()), len(allchars), count))
+ best = maxlen
+ bestr = 0
+ for r in range(maxlen) :
+ score = maxlen - (scores[r][2] - scores[r][1])
+ if score < best :
+ best = score
+ bestr = r
+ numstrings = len(strings)
+ i = 0
+ allchars = {}
+ while i < len(strings) :
+ s = strings[i][0]
+ if bestr >= len(s) :
+ i += 1
+ continue
+ c = tuple(s[0:bestr] + (s[bestr+1:] if bestr < len(s) - 1 else []))
+ if c in allchars :
+ allchars[c][1].append(s[bestr])
+ allchars[c][2].append(strings[i][1])
+ strings.pop(i)
+ else :
+ allchars[c] = [i, [s[bestr]], [strings[i][1]]]
+ i += 1
+ for v in allchars.values() :
+ if len(set(v[1])) != 1 : # if all values in the list identical, don't output list
+ strings[v[0]][0][bestr] = v[1]
+ if len(v[2]) > 1 : # don't need a list if length 1
+ strings[v[0]][1] = v[2]
+ return strings
+
+def make_rule(left, right = None, before = None, after = None) :
+ res = " ".join(map(lambda x: x or "_", left))
+ if right :
+ res += " > " + " ".join(map(lambda x: x or "_", right))
+ if before or after :
+ res += " / "
+ if before : res += " ".join(map(lambda x: x or 'ANY', before))
+ res += " " + "_ " * len(left) + " "
+ if after : res += " ".join(map(lambda x: x or 'ANY', after))
+ res += ";"
+ return res
+
+def add_class_classes(font, name, ctable) :
+ vals = {}
+ for k, v in ctable.classDefs.items() :
+ if v not in vals : vals[v] = []
+ vals[v].append(k)
+ numk = max(vals.keys())
+ res = [None] * (numk + 1)
+ for k, v in vals.items() :
+ if len(v) > 1 :
+ res[k] = font.alias(name+"{}".format(k))
+ font.addClass(res[k], map(font.glyph, v))
+ else :
+ res[k] = font.glyph(v[0]).GDLName()
+ return res
+
+vrgdlmap = {
+ 'XPlacement' : 'shift.x',
+ 'YPlacement' : 'shift.y',
+ 'XAdvance' : 'advance'
+}
+def valuerectogdl(vr) :
+ res = "{"
+ for k, v in vrgdlmap.items() :
+ if hasattr(vr, k) :
+ res += "{}={}; ".format(v, getattr(vr, k))
+ res = res[:-1] + "}"
+ if len(res) == 1 : return ""
+ return res
+
+def _add_method(*clazzes):
+ """Returns a decorator function that adds a new method to one or
+ more classes."""
+ def wrapper(method):
+ for c in clazzes:
+ assert c.__name__ != 'DefaultTable', \
+ 'Oops, table class not found.'
+ assert not hasattr(c, method.__name__), \
+ "Oops, class '%s' has method '%s'." % (c.__name__,
+ method.__name__)
+ setattr(c, method.__name__, method)
+ return None
+ return wrapper
+
+@_add_method(otTables.Lookup)
+def process(self, font, index) :
+ for i, s in enumerate(self.SubTable) :
+ if hasattr(s, 'process') :
+ s.process(font, index + "_{}".format(i))
+ else :
+ logging.warning("No processing of {} {}_{}".format(str(s), index, i))
+
+@_add_method(otTables.LookupList)
+def process(self, font) :
+ for i, s in enumerate(self.Lookup) :
+ s.process(font, str(i))
+
+@_add_method(otTables.ExtensionSubst, otTables.ExtensionPos)
+def process(self, font, index) :
+ x = self.ExtSubTable
+ if hasattr(x, 'process') :
+ x.process(font, index)
+ else :
+ logging.warning("No processing of {} {}".format(str(x), index))
+
+@_add_method(otTables.SingleSubst)
+def process(self, font, index) :
+ cname = "cot_s{}".format(index)
+ if not len(font.alias(cname)) : return
+ lists = zip(*self.mapping.items())
+ font.addClass(font.alias(cname+"l"), map(font.glyph, lists[0]))
+ font.addClass(font.alias(cname+"r"), map(font.glyph, lists[1]))
+
+@_add_method(otTables.MultipleSubst)
+def process(self, font, index) :
+ cname = "cot_m{}".format(index)
+ if not len(font.alias(cname)) : return
+ nums = len(self.Coverage.glyphs)
+ strings = []
+ for i in range(nums) :
+ strings.append([self.Sequence[i].Substitute, self.Coverage.glyphs[i]])
+ res = compress_strings(strings)
+ count = 0
+ rules = []
+ for r in res :
+ if hasattr(r[1], '__iter__') :
+ lname = font.alias(cname+"l{}".format(count))
+ font.addClass(lname, map(font.glyph, r[1]))
+ rule = lname
+ else :
+ rule = font.glyph(r[1]).GDLName()
+ rule += " _" * (len(r[0]) - 1) + " >"
+ for c in r[0] :
+ if hasattr(c, '__iter__') :
+ rname = font.alias(cname+"r{}".format(count))
+ font.addClass(rname, map(font.glyph, c))
+ rule += " " + rname
+ count += 1
+ else :
+ rule += " " + font.glyph(c).GDLName()
+ rule += ';'
+ rules.append(rule)
+ font.addRules(rules, index)
+
+@_add_method(otTables.LigatureSubst)
+def process(self, font, index) :
+ cname = "cot_l{}".format(index)
+ if not len(font.alias(cname)) : return
+ strings = []
+ for lg, ls in self.ligatures.items() :
+ for l in ls :
+ strings.append([[lg] + l.Component, l.LigGlyph])
+ res = compress_strings(strings)
+ count = 0
+ rules = []
+ for r in res :
+ rule = ""
+ besti = 0
+ for i, c in enumerate(r[0]) :
+ if hasattr(c, '__iter__') :
+ lname = font.alias(cname+"l{}".format(count))
+ font.addClass(lname, map(font.glyph, c))
+ rule += lname + " "
+ besti = i
+ else :
+ rule += font.glyph(c).GDLName() + " "
+ rule += "> " + "_ " * besti
+ if hasattr(r[1], '__iter__') :
+ rname = font.alias(cname+"r{}".format(count))
+ font.addClass(rname, map(font.glyph, r[1]))
+ rule += rname
+ count += 1
+ else :
+ rule += font.glyph(r[1]).GDLName()
+ rule += " _" * (len(r[0]) - 1 - besti) + ";"
+ rules.append(rule)
+ font.addRules(rules, index)
+
+@_add_method(otTables.ChainContextSubst)
+def process(self, font, index) :
+
+ def procsubst(rule, action) :
+ for s in rule.SubstLookupRecord :
+ action[s.SequenceIndex] += "/*{}*/".format(s.LookupListIndex)
+ def procCover(cs, name) :
+ res = []
+ for i, c in enumerate(cs) :
+ if len(c.glyphs) > 1 :
+ n = font.alias(name+"{}".format(i))
+ font.addClass(n, map(font.glyph, c.glyphs))
+ res.append(n)
+ else :
+ res.append(font.glyph(c.glyphs[0]).GDLName())
+ return res
+
+ cname = "cot_c{}".format(index)
+ if not len(font.alias(cname)) : return
+ rules = []
+ if self.Format == 1 :
+ for i in range(len(self.ChainSubRuleSet)) :
+ for r in self.ChainSubRuleSet[i].ChainSubRule :
+ action = [self.Coverage.glyphs[i]] + r.Input
+ procsubst(r, action)
+ rules.append(make_rule(action, None, r.Backtrack, r.LookAhead))
+ elif self.Format == 2 :
+ ilist = add_class_classes(font, cname+"i", self.InputClassDef)
+ if self.BacktrackClassDef :
+ blist = add_class_classes(font, cname+"b", self.BacktrackClassDef)
+ if self.LookAheadClassDef :
+ alist = add_class_classes(font, cname+"a", self.LookAheadClassDef)
+ for i, s in enumerate(self.ChainSubClassSet) :
+ if s is None : continue
+ for r in s.ChainSubClassRule :
+ action = map(lambda x:ilist[x], [i]+r.Input)
+ procsubst(r, action)
+ rules.append(make_rule(action, None,
+ map(lambda x:blist[x], r.Backtrack or []),
+ map(lambda x:alist[x], r.LookAhead or [])))
+ elif self.Format == 3 :
+ backs = procCover(self.BacktrackCoverage, cname+"b")
+ aheads = procCover(self.LookAheadCoverage, cname+"a")
+ actions = procCover(self.InputCoverage, cname+"i")
+ procsubst(self, actions)
+ rules.append(make_rule(actions, None, backs, aheads))
+ font.addRules(rules, index)
+
+@_add_method(otTables.SinglePos)
+def process(self, font, index) :
+ cname = "cot_p{}".format(index)
+ if self.Format == 1 :
+ font.addClass(font.alias(cname), map(font.glyph, self.Coverage.glyphs))
+ rule = cname + " " + valuerectogdl(self.Value)
+ font.addPosRules([rule], index)
+ elif self.Format == 2 :
+ rules = []
+ for i, g in enumerage(map(font.glyph, self.Coverage.glyphs)) :
+ rule = font.glyph(g).GDLName()
+ rule += " " + valuerectogdl(self.Value[i])
+ rules.append(rule)
+ font.addPosRules(rules, index)
+
+@_add_method(otTables.PairPos)
+def process(self, font, index) :
+ pass
+
+@_add_method(otTables.CursivePos)
+def process(self, font, index) :
+ apname = "P{}".format(index)
+ if not len(font.alias(apname)) : return
+ if self.Format == 1 :
+ mark_names = self.Coverage.glyphs
+ for i, g in enumerate(map(font.glyph, mark_names)) :
+ rec = self.EntryExitRecord[i]
+ if rec.EntryAnchor is not None :
+ g.setAnchor(font.alias(apname+"_{}M".format(rec.EntryAnchor)),
+ rec.EntryAnchor.XCoordinate, rec.EntryAnchor.YCoordinate)
+ if rec.ExitAnchor is not None :
+ g.setAnchor(font.alias(apname+"_{}S".format(rec.ExitAnchor)),
+ rec.ExitAnchor.XCoordinate, rec.ExitAnchor.YCoordinate)
+
+@_add_method(otTables.MarkBasePos)
+def process(self, font, index) :
+ apname = "P{}".format(index)
+ if not len(font.alias(apname)) : return
+ if self.Format == 1 :
+ mark_names = self.MarkCoverage.glyphs
+ for i, g in enumerate(map(font.glyph, mark_names)) :
+ rec = self.MarkArray.MarkRecord[i]
+ g.setAnchor(font.alias(apname+"_{}M".format(rec.Class)),
+ rec.MarkAnchor.XCoordinate, rec.MarkAnchor.YCoordinate)
+ base_names = self.BaseCoverage.glyphs
+ for i, g in enumerate(map(font.glyph, base_names)) :
+ for j,b in enumerate(self.BaseArray.BaseRecord[i].BaseAnchor) :
+ if b : g.setAnchor(font.alias(apname+"_{}S".format(j)),
+ b.XCoordinate, b.YCoordinate)
+
+@_add_method(otTables.MarkMarkPos)
+def process(self, font, index) :
+ apname = "P{}".format(index)
+ if not len(font.alias(apname)) : return
+ if self.Format == 1 :
+ mark_names = self.Mark1Coverage.glyphs
+ for i, g in enumerate(map(font.glyph, mark_names)) :
+ rec = self.Mark1Array.MarkRecord[i]
+ g.setAnchor(font.alias(apname+"_{}M".format(rec.Class)),
+ rec.MarkAnchor.XCoordinate, rec.MarkAnchor.YCoordinate)
+ base_names = self.Mark2Coverage.glyphs
+ for i, g in enumerate(map(font.glyph, base_names)) :
+ for j,b in enumerate(self.Mark2Array.Mark2Record[i].Mark2Anchor) :
+ if b : g.setAnchor(font.alias(apname+"_{}S".format(j)),
+ b.XCoordinate, b.YCoordinate)
+
+@_add_method(otTables.ContextSubst)
+def process(self, font, index) :
+
+ def procsubst(rule, action) :
+ for s in rule.SubstLookupRecord :
+ action[s.SequenceIndex] += "/*{}*/".format(s.LookupListIndex)
+ def procCover(cs, name) :
+ res = []
+ for i, c in enumerate(cs) :
+ if len(c.glyphs) > 1 :
+ n = font.alias(name+"{}".format(i))
+ font.addClass(n, map(font.glyph, c.glyphs))
+ res.append(n)
+ else :
+ res.append(font.glyph(c.glyphs[0]).GDLName())
+ return res
+
+ cname = "cot_cs{}".format(index)
+ if not len(font.alias(cname)) : return
+ rules = []
+ if self.Format == 1 :
+ for i in range(len(self.SubRuleSet)) :
+ for r in self.SubRuleSet[i].SubRule :
+ action = [self.Coverage.glyphs[i]] + r.Input
+ procsubst(r, action)
+ rules.append(make_rule(action, None, None, None))
+ elif self.Format == 2 :
+ ilist = add_class_classes(font, cname+"i", self.ClassDef)
+ for i, s in enumerate(self.SubClassSet) :
+ if s is None : continue
+ for r in s.SubClassRule :
+ action = map(lambda x:ilist[x], [i]+r.Class)
+ procsubst(r, action)
+ rules.append(make_rule(action, None, None, None))
+ elif self.Format == 3 :
+ actions = procCover(self.Coverage, cname+"i")
+ procsubst(self, actions)
+ rules.append(make_rule(actions, None, None, None))
+ font.addRules(rules, index)
+
+@_add_method(otTables.ContextPos)
+def process(self, font, index) :
+
+ def procsubst(rule, action) :
+ for s in rule.PosLookupRecord :
+ action[s.SequenceIndex] += "/*{}*/".format(s.LookupListIndex)
+ def procCover(cs, name) :
+ res = []
+ for i, c in enumerate(cs) :
+ if len(c.glyphs) > 1 :
+ n = font.alias(name+"{}".format(i))
+ font.addClass(n, map(font.glyph, c.glyphs))
+ res.append(n)
+ else :
+ res.append(font.glyph(c.glyphs[0]).GDLName())
+ return res
+
+ cname = "cot_cp{}".format(index)
+ if not len(font.alias(cname)) : return
+ rules = []
+ if self.Format == 1 :
+ for i in range(len(self.PosRuleSet)) :
+ for r in self.PosRuleSet[i] :
+ action = [self.Coverage.glyphs[i]] + r.Input
+ procsubst(r, action)
+ rules.append(make_rule(action, None, None, None))
+ elif self.Format == 2 :
+ ilist = add_class_classes(font, cname+"i", self.ClassDef)
+ for i, s in enumerate(self.PosClassSet) :
+ if s is None : continue
+ for r in s.PosClassRule :
+ action = map(lambda x:ilist[x], [i]+r.Class)
+ procsubst(r, action)
+ rules.append(make_rule(action, None, None, None))
+ elif self.Format == 3 :
+ actions = procCover(self.Coverage, cname+"i")
+ procsubst(self, actions)
+ rules.append(make_rule(actions, None, None, None))
+ font.addPosRules(rules, index)
+
+@_add_method(otTables.ChainContextPos)
+def process(self, font, index) :
+
+ def procsubst(rule, action) :
+ for s in rule.PosLookupRecord :
+ action[s.SequenceIndex] += "/*{}*/".format(s.LookupListIndex)
+ def procCover(cs, name) :
+ res = []
+ for i, c in enumerate(cs) :
+ if len(c.glyphs) > 1 :
+ n = font.alias(name+"{}".format(i))
+ font.addClass(n, map(font.glyph, c.glyphs))
+ res.append(n)
+ else :
+ res.append(font.glyph(c.glyphs[0]).GDLName())
+ return res
+
+ cname = "cot_c{}".format(index)
+ if not len(font.alias(cname)) : return
+ rules = []
+ if self.Format == 1 :
+ for i in range(len(self.ChainPosRuleSet)) :
+ for r in self.ChainPosRuleSet[i].ChainPosRule :
+ action = [self.Coverage.glyphs[i]] + r.Input
+ procsubst(r, action)
+ rules.append(make_rule(action, None, r.Backtrack, r.LookAhead))
+ elif self.Format == 2 :
+ ilist = add_class_classes(font, cname+"i", self.InputClassDef)
+ if self.BacktrackClassDef :
+ blist = add_class_classes(font, cname+"b", self.BacktrackClassDef)
+ if self.LookAheadClassDef :
+ alist = add_class_classes(font, cname+"a", self.LookAheadClassDef)
+ for i, s in enumerate(self.ChainPosClassSet) :
+ if s is None : continue
+ for r in s.ChainPosClassRule :
+ action = map(lambda x:ilist[x], [i]+r.Input)
+ procsubst(r, action)
+ rules.append(make_rule(action, None,
+ map(lambda x:blist[x], r.Backtrack or []),
+ map(lambda x:alist[x], r.LookAhead or [])))
+ elif self.Format == 3 :
+ backs = procCover(self.BacktrackCoverage, cname+"b")
+ aheads = procCover(self.LookAheadCoverage, cname+"a")
+ actions = procCover(self.InputCoverage, cname+"i")
+ procsubst(self, actions)
+ rules.append(make_rule(actions, None, backs, aheads))
+ font.addPosRules(rules, index)
+
diff --git a/examples/gdl/psnames.py b/examples/gdl/psnames.py
new file mode 100644
index 0000000..77bd2fb
--- /dev/null
+++ b/examples/gdl/psnames.py
@@ -0,0 +1,4506 @@
+#!/usr/bin/env python
+'Glyph name analyser to create GDL names from AGL type names'
+__url__ = 'http://github.com/silnrsi/pysilfont'
+__copyright__ = 'Copyright (c) 2012 SIL International (http://www.sil.org)'
+__license__ = 'Released under the MIT License (http://opensource.org/licenses/MIT)'
+
+import re
+import traceback # Debug
+
+uniToPsnameMap = {
+ '0020' : 'space',
+ '0021' : 'exclam',
+ '0022' : 'quotedbl',
+ '0023' : 'numbersign',
+ '0024' : 'dollar',
+ '0025' : 'percent',
+ '0026' : 'ampersand',
+ '0027' : 'quotesingle',
+ '0028' : 'parenleft',
+ '0029' : 'parenright',
+ '002A' : 'asterisk',
+ '002B' : 'plus',
+ '002C' : 'comma',
+ '002D' : 'hyphen',
+ '002E' : 'period',
+ '002F' : 'slash',
+ '0030' : 'zero',
+ '0031' : 'one',
+ '0032' : 'two',
+ '0033' : 'three',
+ '0034' : 'four',
+ '0035' : 'five',
+ '0036' : 'six',
+ '0037' : 'seven',
+ '0038' : 'eight',
+ '0039' : 'nine',
+ '003A' : 'colon',
+ '003B' : 'semicolon',
+ '003C' : 'less',
+ '003D' : 'equal',
+ '003E' : 'greater',
+ '003F' : 'question',
+ '0040' : 'at',
+ '0041' : 'A',
+ '0042' : 'B',
+ '0043' : 'C',
+ '0044' : 'D',
+ '0045' : 'E',
+ '0046' : 'F',
+ '0047' : 'G',
+ '0048' : 'H',
+ '0049' : 'I',
+ '004A' : 'J',
+ '004B' : 'K',
+ '004C' : 'L',
+ '004D' : 'M',
+ '004E' : 'N',
+ '004F' : 'O',
+ '0050' : 'P',
+ '0051' : 'Q',
+ '0052' : 'R',
+ '0053' : 'S',
+ '0054' : 'T',
+ '0055' : 'U',
+ '0056' : 'V',
+ '0057' : 'W',
+ '0058' : 'X',
+ '0059' : 'Y',
+ '005A' : 'Z',
+ '005B' : 'bracketleft',
+ '005C' : 'backslash',
+ '005D' : 'bracketright',
+ '005E' : 'asciicircum',
+ '005F' : 'underscore',
+ '0060' : 'grave',
+ '0061' : 'a',
+ '0062' : 'b',
+ '0063' : 'c',
+ '0064' : 'd',
+ '0065' : 'e',
+ '0066' : 'f',
+ '0067' : 'g',
+ '0068' : 'h',
+ '0069' : 'i',
+ '006A' : 'j',
+ '006B' : 'k',
+ '006C' : 'l',
+ '006D' : 'm',
+ '006E' : 'n',
+ '006F' : 'o',
+ '0070' : 'p',
+ '0071' : 'q',
+ '0072' : 'r',
+ '0073' : 's',
+ '0074' : 't',
+ '0075' : 'u',
+ '0076' : 'v',
+ '0077' : 'w',
+ '0078' : 'x',
+ '0079' : 'y',
+ '007A' : 'z',
+ '007B' : 'braceleft',
+ '007C' : 'bar',
+ '007D' : 'braceright',
+ '007E' : 'asciitilde',
+# '00A0' : 'space',
+ '00A1' : 'exclamdown',
+ '00A2' : 'cent',
+ '00A3' : 'sterling',
+ '00A4' : 'currency',
+ '00A5' : 'yen',
+ '00A6' : 'brokenbar',
+ '00A7' : 'section',
+ '00A8' : 'dieresis',
+ '00A9' : 'copyright',
+ '00AA' : 'ordfeminine',
+ '00AB' : 'guillemotleft',
+ '00AC' : 'logicalnot',
+# '00AD' : 'hyphen',
+ '00AE' : 'registered',
+ '00AF' : 'macron',
+ '00B0' : 'degree',
+ '00B1' : 'plusminus',
+ '00B2' : 'twosuperior',
+ '00B3' : 'threesuperior',
+ '00B4' : 'acute',
+ '00B5' : 'mu',
+ '00B6' : 'paragraph',
+ '00B7' : 'periodcentered',
+ '00B8' : 'cedilla',
+ '00B9' : 'onesuperior',
+ '00BA' : 'ordmasculine',
+ '00BB' : 'guillemotright',
+ '00BC' : 'onequarter',
+ '00BD' : 'onehalf',
+ '00BE' : 'threequarters',
+ '00BF' : 'questiondown',
+ '00C0' : 'Agrave',
+ '00C1' : 'Aacute',
+ '00C2' : 'Acircumflex',
+ '00C3' : 'Atilde',
+ '00C4' : 'Adieresis',
+ '00C5' : 'Aring',
+ '00C6' : 'AE',
+ '00C7' : 'Ccedilla',
+ '00C8' : 'Egrave',
+ '00C9' : 'Eacute',
+ '00CA' : 'Ecircumflex',
+ '00CB' : 'Edieresis',
+ '00CC' : 'Igrave',
+ '00CD' : 'Iacute',
+ '00CE' : 'Icircumflex',
+ '00CF' : 'Idieresis',
+ '00D0' : 'Eth',
+ '00D1' : 'Ntilde',
+ '00D2' : 'Ograve',
+ '00D3' : 'Oacute',
+ '00D4' : 'Ocircumflex',
+ '00D5' : 'Otilde',
+ '00D6' : 'Odieresis',
+ '00D7' : 'multiply',
+ '00D8' : 'Oslash',
+ '00D9' : 'Ugrave',
+ '00DA' : 'Uacute',
+ '00DB' : 'Ucircumflex',
+ '00DC' : 'Udieresis',
+ '00DD' : 'Yacute',
+ '00DE' : 'Thorn',
+ '00DF' : 'germandbls',
+ '00E0' : 'agrave',
+ '00E1' : 'aacute',
+ '00E2' : 'acircumflex',
+ '00E3' : 'atilde',
+ '00E4' : 'adieresis',
+ '00E5' : 'aring',
+ '00E6' : 'ae',
+ '00E7' : 'ccedilla',
+ '00E8' : 'egrave',
+ '00E9' : 'eacute',
+ '00EA' : 'ecircumflex',
+ '00EB' : 'edieresis',
+ '00EC' : 'igrave',
+ '00ED' : 'iacute',
+ '00EE' : 'icircumflex',
+ '00EF' : 'idieresis',
+ '00F0' : 'eth',
+ '00F1' : 'ntilde',
+ '00F2' : 'ograve',
+ '00F3' : 'oacute',
+ '00F4' : 'ocircumflex',
+ '00F5' : 'otilde',
+ '00F6' : 'odieresis',
+ '00F7' : 'divide',
+ '00F8' : 'oslash',
+ '00F9' : 'ugrave',
+ '00FA' : 'uacute',
+ '00FB' : 'ucircumflex',
+ '00FC' : 'udieresis',
+ '00FD' : 'yacute',
+ '00FE' : 'thorn',
+ '00FF' : 'ydieresis',
+ '0100' : 'Amacron',
+ '0101' : 'amacron',
+ '0102' : 'Abreve',
+ '0103' : 'abreve',
+ '0104' : 'Aogonek',
+ '0105' : 'aogonek',
+ '0106' : 'Cacute',
+ '0107' : 'cacute',
+ '0108' : 'Ccircumflex',
+ '0109' : 'ccircumflex',
+ '010A' : 'Cdotaccent',
+ '010B' : 'cdotaccent',
+ '010C' : 'Ccaron',
+ '010D' : 'ccaron',
+ '010E' : 'Dcaron',
+ '010F' : 'dcaron',
+ '0110' : 'Dcroat',
+ '0111' : 'dcroat',
+ '0112' : 'Emacron',
+ '0113' : 'emacron',
+ '0114' : 'Ebreve',
+ '0115' : 'ebreve',
+ '0116' : 'Edotaccent',
+ '0117' : 'edotaccent',
+ '0118' : 'Eogonek',
+ '0119' : 'eogonek',
+ '011A' : 'Ecaron',
+ '011B' : 'ecaron',
+ '011C' : 'Gcircumflex',
+ '011D' : 'gcircumflex',
+ '011E' : 'Gbreve',
+ '011F' : 'gbreve',
+ '0120' : 'Gdotaccent',
+ '0121' : 'gdotaccent',
+ '0122' : 'Gcommaaccent',
+ '0123' : 'gcommaaccent',
+ '0124' : 'Hcircumflex',
+ '0125' : 'hcircumflex',
+ '0126' : 'Hbar',
+ '0127' : 'hbar',
+ '0128' : 'Itilde',
+ '0129' : 'itilde',
+ '012A' : 'Imacron',
+ '012B' : 'imacron',
+ '012C' : 'Ibreve',
+ '012D' : 'ibreve',
+ '012E' : 'Iogonek',
+ '012F' : 'iogonek',
+ '0130' : 'Idotaccent',
+ '0131' : 'dotlessi',
+ '0132' : 'IJ',
+ '0133' : 'ij',
+ '0134' : 'Jcircumflex',
+ '0135' : 'jcircumflex',
+ '0136' : 'Kcommaaccent',
+ '0137' : 'kcommaaccent',
+ '0138' : 'kgreenlandic',
+ '0139' : 'Lacute',
+ '013A' : 'lacute',
+ '013B' : 'Lcommaaccent',
+ '013C' : 'lcommaaccent',
+ '013D' : 'Lcaron',
+ '013E' : 'lcaron',
+ '013F' : 'Ldot',
+ '0140' : 'ldot',
+ '0141' : 'Lslash',
+ '0142' : 'lslash',
+ '0143' : 'Nacute',
+ '0144' : 'nacute',
+ '0145' : 'Ncommaaccent',
+ '0146' : 'ncommaaccent',
+ '0147' : 'Ncaron',
+ '0148' : 'ncaron',
+ '0149' : 'napostrophe',
+ '014A' : 'Eng',
+ '014B' : 'eng',
+ '014C' : 'Omacron',
+ '014D' : 'omacron',
+ '014E' : 'Obreve',
+ '014F' : 'obreve',
+ '0150' : 'Ohungarumlaut',
+ '0151' : 'ohungarumlaut',
+ '0152' : 'OE',
+ '0153' : 'oe',
+ '0154' : 'Racute',
+ '0155' : 'racute',
+ '0156' : 'Rcommaaccent',
+ '0157' : 'rcommaaccent',
+ '0158' : 'Rcaron',
+ '0159' : 'rcaron',
+ '015A' : 'Sacute',
+ '015B' : 'sacute',
+ '015C' : 'Scircumflex',
+ '015D' : 'scircumflex',
+ '015E' : 'Scedilla',
+ '015F' : 'scedilla',
+ '0160' : 'Scaron',
+ '0161' : 'scaron',
+ '0162' : 'Tcommaaccent',
+ '0163' : 'tcommaaccent',
+ '0164' : 'Tcaron',
+ '0165' : 'tcaron',
+ '0166' : 'Tbar',
+ '0167' : 'tbar',
+ '0168' : 'Utilde',
+ '0169' : 'utilde',
+ '016A' : 'Umacron',
+ '016B' : 'umacron',
+ '016C' : 'Ubreve',
+ '016D' : 'ubreve',
+ '016E' : 'Uring',
+ '016F' : 'uring',
+ '0170' : 'Uhungarumlaut',
+ '0171' : 'uhungarumlaut',
+ '0172' : 'Uogonek',
+ '0173' : 'uogonek',
+ '0174' : 'Wcircumflex',
+ '0175' : 'wcircumflex',
+ '0176' : 'Ycircumflex',
+ '0177' : 'ycircumflex',
+ '0178' : 'Ydieresis',
+ '0179' : 'Zacute',
+ '017A' : 'zacute',
+ '017B' : 'Zdotaccent',
+ '017C' : 'zdotaccent',
+ '017D' : 'Zcaron',
+ '017E' : 'zcaron',
+ '017F' : 'longs',
+ '0192' : 'florin',
+ '01A0' : 'Ohorn',
+ '01A1' : 'ohorn',
+ '01AF' : 'Uhorn',
+ '01B0' : 'uhorn',
+ '01E6' : 'Gcaron',
+ '01E7' : 'gcaron',
+ '01FA' : 'Aringacute',
+ '01FB' : 'aringacute',
+ '01FC' : 'AEacute',
+ '01FD' : 'aeacute',
+ '01FE' : 'Oslashacute',
+ '01FF' : 'oslashacute',
+ '0218' : 'Scommaaccent',
+ '0219' : 'scommaaccent',
+# '021A' : 'Tcommaaccent',
+# '021B' : 'tcommaaccent',
+ '02BC' : 'afii57929',
+ '02BD' : 'afii64937',
+ '02C6' : 'circumflex',
+ '02C7' : 'caron',
+# '02C9' : 'macron',
+ '02D8' : 'breve',
+ '02D9' : 'dotaccent',
+ '02DA' : 'ring',
+ '02DB' : 'ogonek',
+ '02DC' : 'tilde',
+ '02DD' : 'hungarumlaut',
+ '0300' : 'gravecomb',
+ '0301' : 'acutecomb',
+ '0303' : 'tildecomb',
+ '0309' : 'hookabovecomb',
+ '0323' : 'dotbelowcomb',
+ '0384' : 'tonos',
+ '0385' : 'dieresistonos',
+ '0386' : 'Alphatonos',
+ '0387' : 'anoteleia',
+ '0388' : 'Epsilontonos',
+ '0389' : 'Etatonos',
+ '038A' : 'Iotatonos',
+ '038C' : 'Omicrontonos',
+ '038E' : 'Upsilontonos',
+ '038F' : 'Omegatonos',
+ '0390' : 'iotadieresistonos',
+ '0391' : 'Alpha',
+ '0392' : 'Beta',
+ '0393' : 'Gamma',
+# '0394' : 'Delta',
+ '0395' : 'Epsilon',
+ '0396' : 'Zeta',
+ '0397' : 'Eta',
+ '0398' : 'Theta',
+ '0399' : 'Iota',
+ '039A' : 'Kappa',
+ '039B' : 'Lambda',
+ '039C' : 'Mu',
+ '039D' : 'Nu',
+ '039E' : 'Xi',
+ '039F' : 'Omicron',
+ '03A0' : 'Pi',
+ '03A1' : 'Rho',
+ '03A3' : 'Sigma',
+ '03A4' : 'Tau',
+ '03A5' : 'Upsilon',
+ '03A6' : 'Phi',
+ '03A7' : 'Chi',
+ '03A8' : 'Psi',
+# '03A9' : 'Omega',
+ '03AA' : 'Iotadieresis',
+ '03AB' : 'Upsilondieresis',
+ '03AC' : 'alphatonos',
+ '03AD' : 'epsilontonos',
+ '03AE' : 'etatonos',
+ '03AF' : 'iotatonos',
+ '03B0' : 'upsilondieresistonos',
+ '03B1' : 'alpha',
+ '03B2' : 'beta',
+ '03B3' : 'gamma',
+ '03B4' : 'delta',
+ '03B5' : 'epsilon',
+ '03B6' : 'zeta',
+ '03B7' : 'eta',
+ '03B8' : 'theta',
+ '03B9' : 'iota',
+ '03BA' : 'kappa',
+ '03BB' : 'lambda',
+# '03BC' : 'mu',
+ '03BD' : 'nu',
+ '03BE' : 'xi',
+ '03BF' : 'omicron',
+ '03C0' : 'pi',
+ '03C1' : 'rho',
+ '03C2' : 'sigma1',
+ '03C3' : 'sigma',
+ '03C4' : 'tau',
+ '03C5' : 'upsilon',
+ '03C6' : 'phi',
+ '03C7' : 'chi',
+ '03C8' : 'psi',
+ '03C9' : 'omega',
+ '03CA' : 'iotadieresis',
+ '03CB' : 'upsilondieresis',
+ '03CC' : 'omicrontonos',
+ '03CD' : 'upsilontonos',
+ '03CE' : 'omegatonos',
+ '03D1' : 'theta1',
+ '03D2' : 'Upsilon1',
+ '03D5' : 'phi1',
+ '03D6' : 'omega1',
+ '1E80' : 'Wgrave',
+ '1E81' : 'wgrave',
+ '1E82' : 'Wacute',
+ '1E83' : 'wacute',
+ '1E84' : 'Wdieresis',
+ '1E85' : 'wdieresis',
+ '1EF2' : 'Ygrave',
+ '1EF3' : 'ygrave',
+ '2012' : 'figuredash',
+ '2013' : 'endash',
+ '2014' : 'emdash',
+ '2015' : 'afii00208',
+ '2017' : 'underscoredbl',
+ '2018' : 'quoteleft',
+ '2019' : 'quoteright',
+ '201A' : 'quotesinglbase',
+ '201B' : 'quotereversed',
+ '201C' : 'quotedblleft',
+ '201D' : 'quotedblright',
+ '201E' : 'quotedblbase',
+ '2020' : 'dagger',
+ '2021' : 'daggerdbl',
+ '2022' : 'bullet',
+ '2024' : 'onedotenleader',
+ '2025' : 'twodotenleader',
+ '2026' : 'ellipsis',
+ '202C' : 'afii61573',
+ '202D' : 'afii61574',
+ '202E' : 'afii61575',
+ '2030' : 'perthousand',
+ '2032' : 'minute',
+ '2033' : 'second',
+ '2039' : 'guilsinglleft',
+ '203A' : 'guilsinglright',
+ '203C' : 'exclamdbl',
+ '2044' : 'fraction',
+# '2070' : 'zerosuperior',
+# '2074' : 'foursuperior',
+# '2075' : 'fivesuperior',
+# '2076' : 'sixsuperior',
+# '2077' : 'sevensuperior',
+# '2078' : 'eightsuperior',
+# '2079' : 'ninesuperior',
+# '207D' : 'parenleftsuperior',
+# '207E' : 'parenrightsuperior',
+# '207F' : 'nsuperior',
+# '2080' : 'zeroinferior',
+# '2081' : 'oneinferior',
+# '2082' : 'twoinferior',
+# '2083' : 'threeinferior',
+# '2084' : 'fourinferior',
+# '2085' : 'fiveinferior',
+# '2086' : 'sixinferior',
+# '2087' : 'seveninferior',
+# '2088' : 'eightinferior',
+# '2089' : 'nineinferior',
+# '208D' : 'parenleftinferior',
+# '208E' : 'parenrightinferior',
+ '20A1' : 'colonmonetary',
+ '20A3' : 'franc',
+ '20A4' : 'lira',
+ '20A7' : 'peseta',
+ '20AA' : 'afii57636',
+ '20AB' : 'dong',
+ '20AC' : 'Euro',
+ '2105' : 'afii61248',
+ '2111' : 'Ifraktur',
+ '2113' : 'afii61289',
+ '2116' : 'afii61352',
+ '2118' : 'weierstrass',
+ '211C' : 'Rfraktur',
+ '211E' : 'prescription',
+ '2122' : 'trademark',
+ '2126' : 'Omega',
+ '212E' : 'estimated',
+ '2135' : 'aleph',
+ '2153' : 'onethird',
+ '2154' : 'twothirds',
+ '215B' : 'oneeighth',
+ '215C' : 'threeeighths',
+ '215D' : 'fiveeighths',
+ '215E' : 'seveneighths',
+ '2190' : 'arrowleft',
+ '2191' : 'arrowup',
+ '2192' : 'arrowright',
+ '2193' : 'arrowdown',
+ '2194' : 'arrowboth',
+ '2195' : 'arrowupdn',
+ '21A8' : 'arrowupdnbse',
+ '21B5' : 'carriagereturn',
+ '21D0' : 'arrowdblleft',
+ '21D1' : 'arrowdblup',
+ '21D2' : 'arrowdblright',
+ '21D3' : 'arrowdbldown',
+ '21D4' : 'arrowdblboth',
+ '2200' : 'universal',
+ '2202' : 'partialdiff',
+ '2203' : 'existential',
+ '2205' : 'emptyset',
+ '2206' : 'Delta',
+ '2207' : 'gradient',
+ '2208' : 'element',
+ '2209' : 'notelement',
+ '220B' : 'suchthat',
+ '220F' : 'product',
+ '2211' : 'summation',
+ '2212' : 'minus',
+# '2215' : 'fraction',
+ '2217' : 'asteriskmath',
+# '2219' : 'periodcentered',
+ '221A' : 'radical',
+ '221D' : 'proportional',
+ '221E' : 'infinity',
+ '221F' : 'orthogonal',
+ '2220' : 'angle',
+ '2227' : 'logicaland',
+ '2228' : 'logicalor',
+ '2229' : 'intersection',
+ '222A' : 'union',
+ '222B' : 'integral',
+ '2234' : 'therefore',
+ '223C' : 'similar',
+ '2245' : 'congruent',
+ '2248' : 'approxequal',
+ '2260' : 'notequal',
+ '2261' : 'equivalence',
+ '2264' : 'lessequal',
+ '2265' : 'greaterequal',
+ '2282' : 'propersubset',
+ '2283' : 'propersuperset',
+ '2284' : 'notsubset',
+ '2286' : 'reflexsubset',
+ '2287' : 'reflexsuperset',
+ '2295' : 'circleplus',
+ '2297' : 'circlemultiply',
+ '22A5' : 'perpendicular',
+ '22C5' : 'dotmath',
+ '2302' : 'house',
+ '2310' : 'revlogicalnot',
+ '2320' : 'integraltp',
+ '2321' : 'integralbt',
+ '2329' : 'angleleft',
+ '232A' : 'angleright',
+ '2580' : 'upblock',
+ '2584' : 'dnblock',
+ '2588' : 'block',
+ '258C' : 'lfblock',
+ '2590' : 'rtblock',
+ '2591' : 'ltshade',
+ '2592' : 'shade',
+ '2593' : 'dkshade',
+ '25A0' : 'filledbox',
+ '25A1' : 'H22073',
+ '25AA' : 'H18543',
+ '25AB' : 'H18551',
+ '25AC' : 'filledrect',
+ '25B2' : 'triagup',
+ '25BA' : 'triagrt',
+ '25BC' : 'triagdn',
+ '25C4' : 'triaglf',
+ '25CA' : 'lozenge',
+ '25CB' : 'circle',
+ '25CC' : 'circledash',
+ '25CF' : 'H18533',
+ '25D8' : 'invbullet',
+ '25D9' : 'invcircle',
+ '25E6' : 'openbullet',
+ '263A' : 'smileface',
+ '263B' : 'invsmileface',
+ '263C' : 'sun',
+ '2640' : 'female',
+ '2642' : 'male',
+ '2660' : 'spade',
+ '2663' : 'club',
+ '2665' : 'heart',
+ '2666' : 'diamond',
+ '266A' : 'musicalnote',
+ '266B' : 'musicalnotedbl',
+ 'FB00' : 'ff',
+ 'FB01' : 'fi',
+ 'FB02' : 'fl',
+ 'FB03' : 'ffi',
+ 'FB04' : 'ffl'
+}
+
+uniToAfiinameMap = {
+ '0401' : 'afii10023',
+ '0402' : 'afii10051',
+ '0403' : 'afii10052',
+ '0404' : 'afii10053',
+ '0405' : 'afii10054',
+ '0406' : 'afii10055',
+ '0407' : 'afii10056',
+ '0408' : 'afii10057',
+ '0409' : 'afii10058',
+ '040A' : 'afii10059',
+ '040B' : 'afii10060',
+ '040C' : 'afii10061',
+ '040E' : 'afii10062',
+ '040F' : 'afii10145',
+ '0410' : 'afii10017',
+ '0411' : 'afii10018',
+ '0412' : 'afii10019',
+ '0413' : 'afii10020',
+ '0414' : 'afii10021',
+ '0415' : 'afii10022',
+ '0416' : 'afii10024',
+ '0417' : 'afii10025',
+ '0418' : 'afii10026',
+ '0419' : 'afii10027',
+ '041A' : 'afii10028',
+ '041B' : 'afii10029',
+ '041C' : 'afii10030',
+ '041D' : 'afii10031',
+ '041E' : 'afii10032',
+ '041F' : 'afii10033',
+ '0420' : 'afii10034',
+ '0421' : 'afii10035',
+ '0422' : 'afii10036',
+ '0423' : 'afii10037',
+ '0424' : 'afii10038',
+ '0425' : 'afii10039',
+ '0426' : 'afii10040',
+ '0427' : 'afii10041',
+ '0428' : 'afii10042',
+ '0429' : 'afii10043',
+ '042A' : 'afii10044',
+ '042B' : 'afii10045',
+ '042C' : 'afii10046',
+ '042D' : 'afii10047',
+ '042E' : 'afii10048',
+ '042F' : 'afii10049',
+ '0430' : 'afii10065',
+ '0431' : 'afii10066',
+ '0432' : 'afii10067',
+ '0433' : 'afii10068',
+ '0434' : 'afii10069',
+ '0435' : 'afii10070',
+ '0436' : 'afii10072',
+ '0437' : 'afii10073',
+ '0438' : 'afii10074',
+ '0439' : 'afii10075',
+ '043A' : 'afii10076',
+ '043B' : 'afii10077',
+ '043C' : 'afii10078',
+ '043D' : 'afii10079',
+ '043E' : 'afii10080',
+ '043F' : 'afii10081',
+ '0440' : 'afii10082',
+ '0441' : 'afii10083',
+ '0442' : 'afii10084',
+ '0443' : 'afii10085',
+ '0444' : 'afii10086',
+ '0445' : 'afii10087',
+ '0446' : 'afii10088',
+ '0447' : 'afii10089',
+ '0448' : 'afii10090',
+ '0449' : 'afii10091',
+ '044A' : 'afii10092',
+ '044B' : 'afii10093',
+ '044C' : 'afii10094',
+ '044D' : 'afii10095',
+ '044E' : 'afii10096',
+ '044F' : 'afii10097',
+ '0451' : 'afii10071',
+ '0452' : 'afii10099',
+ '0453' : 'afii10100',
+ '0454' : 'afii10101',
+ '0455' : 'afii10102',
+ '0456' : 'afii10103',
+ '0457' : 'afii10104',
+ '0458' : 'afii10105',
+ '0459' : 'afii10106',
+ '045A' : 'afii10107',
+ '045B' : 'afii10108',
+ '045C' : 'afii10109',
+ '045E' : 'afii10110',
+ '045F' : 'afii10193',
+ '0462' : 'afii10146',
+ '0463' : 'afii10194',
+ '0472' : 'afii10147',
+ '0473' : 'afii10195',
+ '0474' : 'afii10148',
+ '0475' : 'afii10196',
+ '0490' : 'afii10050',
+ '0491' : 'afii10098',
+ '04D9' : 'afii10846',
+ '05B0' : 'afii57799',
+ '05B1' : 'afii57801',
+ '05B2' : 'afii57800',
+ '05B3' : 'afii57802',
+ '05B4' : 'afii57793',
+ '05B5' : 'afii57794',
+ '05B6' : 'afii57795',
+ '05B7' : 'afii57798',
+ '05B8' : 'afii57797',
+ '05B9' : 'afii57806',
+ '05BB' : 'afii57796',
+ '05BC' : 'afii57807',
+ '05BD' : 'afii57839',
+ '05BE' : 'afii57645',
+ '05BF' : 'afii57841',
+ '05C0' : 'afii57842',
+ '05C1' : 'afii57804',
+ '05C2' : 'afii57803',
+ '05C3' : 'afii57658',
+ '05D0' : 'afii57664',
+ '05D1' : 'afii57665',
+ '05D2' : 'afii57666',
+ '05D3' : 'afii57667',
+ '05D4' : 'afii57668',
+ '05D5' : 'afii57669',
+ '05D6' : 'afii57670',
+ '05D7' : 'afii57671',
+ '05D8' : 'afii57672',
+ '05D9' : 'afii57673',
+ '05DA' : 'afii57674',
+ '05DB' : 'afii57675',
+ '05DC' : 'afii57676',
+ '05DD' : 'afii57677',
+ '05DE' : 'afii57678',
+ '05DF' : 'afii57679',
+ '05E0' : 'afii57680',
+ '05E1' : 'afii57681',
+ '05E2' : 'afii57682',
+ '05E3' : 'afii57683',
+ '05E4' : 'afii57684',
+ '05E5' : 'afii57685',
+ '05E6' : 'afii57686',
+ '05E7' : 'afii57687',
+ '05E8' : 'afii57688',
+ '05E9' : 'afii57689',
+ '05EA' : 'afii57690',
+ '05F0' : 'afii57716',
+ '05F1' : 'afii57717',
+ '05F2' : 'afii57718',
+ '060C' : 'afii57388',
+ '061B' : 'afii57403',
+ '061F' : 'afii57407',
+ '0621' : 'afii57409',
+ '0622' : 'afii57410',
+ '0623' : 'afii57411',
+ '0624' : 'afii57412',
+ '0625' : 'afii57413',
+ '0626' : 'afii57414',
+ '0627' : 'afii57415',
+ '0628' : 'afii57416',
+ '0629' : 'afii57417',
+ '062A' : 'afii57418',
+ '062B' : 'afii57419',
+ '062C' : 'afii57420',
+ '062D' : 'afii57421',
+ '062E' : 'afii57422',
+ '062F' : 'afii57423',
+ '0630' : 'afii57424',
+ '0631' : 'afii57425',
+ '0632' : 'afii57426',
+ '0633' : 'afii57427',
+ '0634' : 'afii57428',
+ '0635' : 'afii57429',
+ '0636' : 'afii57430',
+ '0637' : 'afii57431',
+ '0638' : 'afii57432',
+ '0639' : 'afii57433',
+ '063A' : 'afii57434',
+ '0640' : 'afii57440',
+ '0641' : 'afii57441',
+ '0642' : 'afii57442',
+ '0643' : 'afii57443',
+ '0644' : 'afii57444',
+ '0645' : 'afii57445',
+ '0646' : 'afii57446',
+ '0647' : 'afii57470',
+ '0648' : 'afii57448',
+ '0649' : 'afii57449',
+ '064A' : 'afii57450',
+ '064B' : 'afii57451',
+ '064C' : 'afii57452',
+ '064D' : 'afii57453',
+ '064E' : 'afii57454',
+ '064F' : 'afii57455',
+ '0650' : 'afii57456',
+ '0651' : 'afii57457',
+ '0652' : 'afii57458',
+ '0660' : 'afii57392',
+ '0661' : 'afii57393',
+ '0662' : 'afii57394',
+ '0663' : 'afii57395',
+ '0664' : 'afii57396',
+ '0665' : 'afii57397',
+ '0666' : 'afii57398',
+ '0667' : 'afii57399',
+ '0668' : 'afii57400',
+ '0669' : 'afii57401',
+ '066A' : 'afii57381',
+ '066D' : 'afii63167',
+ '0679' : 'afii57511',
+ '067E' : 'afii57506',
+ '0686' : 'afii57507',
+ '0688' : 'afii57512',
+ '0691' : 'afii57513',
+ '0698' : 'afii57508',
+ '06A4' : 'afii57505',
+ '06AF' : 'afii57509',
+ '06BA' : 'afii57514',
+ '06D2' : 'afii57519',
+ '06D5' : 'afii57534',
+ '2500' : 'SF100000',
+ '2502' : 'SF110000',
+ '250C' : 'SF010000',
+ '2510' : 'SF030000',
+ '2514' : 'SF020000',
+ '2518' : 'SF040000',
+ '251C' : 'SF080000',
+ '2524' : 'SF090000',
+ '252C' : 'SF060000',
+ '2534' : 'SF070000',
+ '253C' : 'SF050000',
+ '2550' : 'SF430000',
+ '2551' : 'SF240000',
+ '2552' : 'SF510000',
+ '2553' : 'SF520000',
+ '2554' : 'SF390000',
+ '2555' : 'SF220000',
+ '2556' : 'SF210000',
+ '2557' : 'SF250000',
+ '2558' : 'SF500000',
+ '2559' : 'SF490000',
+ '255A' : 'SF380000',
+ '255B' : 'SF280000',
+ '255C' : 'SF270000',
+ '255D' : 'SF260000',
+ '255E' : 'SF360000',
+ '255F' : 'SF370000',
+ '2560' : 'SF420000',
+ '2561' : 'SF190000',
+ '2562' : 'SF200000',
+ '2563' : 'SF230000',
+ '2564' : 'SF470000',
+ '2565' : 'SF480000',
+ '2566' : 'SF410000',
+ '2567' : 'SF450000',
+ '2568' : 'SF460000',
+ '2569' : 'SF400000',
+ '256A' : 'SF540000',
+ '256B' : 'SF530000',
+ '256C' : 'SF440000',
+ 'FB1F' : 'afii57705',
+ 'FB2A' : 'afii57694',
+ 'FB2B' : 'afii57695',
+ 'FB35' : 'afii57723',
+ 'FB4B' : 'afii57700'
+}
+
+
+# Adobe Glyph List 2.0 (sans those in glyph list for *new* fonts) -- thus
+# these are all historic names that could occur in fonts
+# from http://partners.adobe.com/asn/tech/type/glyphlist.txt
+
+aglToUniMap = {
+ 'AEmacron' : u"\u01E2",
+ 'AEsmall' : u"\uF7E6",
+ 'Aacutesmall' : u"\uF7E1",
+ 'Abreveacute' : u"\u1EAE",
+ 'Abrevecyrillic' : u"\u04D0",
+ 'Abrevedotbelow' : u"\u1EB6",
+ 'Abrevegrave' : u"\u1EB0",
+ 'Abrevehookabove' : u"\u1EB2",
+ 'Abrevetilde' : u"\u1EB4",
+ 'Acaron' : u"\u01CD",
+ 'Acircle' : u"\u24B6",
+ 'Acircumflexacute' : u"\u1EA4",
+ 'Acircumflexdotbelow' : u"\u1EAC",
+ 'Acircumflexgrave' : u"\u1EA6",
+ 'Acircumflexhookabove' : u"\u1EA8",
+ 'Acircumflexsmall' : u"\uF7E2",
+ 'Acircumflextilde' : u"\u1EAA",
+ 'Acute' : u"\uF6C9",
+ 'Acutesmall' : u"\uF7B4",
+ 'Acyrillic' : u"\u0410",
+ 'Adblgrave' : u"\u0200",
+ 'Adieresiscyrillic' : u"\u04D2",
+ 'Adieresismacron' : u"\u01DE",
+ 'Adieresissmall' : u"\uF7E4",
+ 'Adotbelow' : u"\u1EA0",
+ 'Adotmacron' : u"\u01E0",
+ 'Agravesmall' : u"\uF7E0",
+ 'Ahookabove' : u"\u1EA2",
+ 'Aiecyrillic' : u"\u04D4",
+ 'Ainvertedbreve' : u"\u0202",
+ 'Amonospace' : u"\uFF21",
+ 'Aringbelow' : u"\u1E00",
+ 'Aringsmall' : u"\uF7E5",
+ 'Asmall' : u"\uF761",
+ 'Atildesmall' : u"\uF7E3",
+ 'Aybarmenian' : u"\u0531",
+ 'Bcircle' : u"\u24B7",
+ 'Bdotaccent' : u"\u1E02",
+ 'Bdotbelow' : u"\u1E04",
+ 'Becyrillic' : u"\u0411",
+ 'Benarmenian' : u"\u0532",
+ 'Bhook' : u"\u0181",
+ 'Blinebelow' : u"\u1E06",
+ 'Bmonospace' : u"\uFF22",
+ 'Brevesmall' : u"\uF6F4",
+ 'Bsmall' : u"\uF762",
+ 'Btopbar' : u"\u0182",
+ 'Caarmenian' : u"\u053E",
+ 'Caron' : u"\uF6CA",
+ 'Caronsmall' : u"\uF6F5",
+ 'Ccedillaacute' : u"\u1E08",
+ 'Ccedillasmall' : u"\uF7E7",
+ 'Ccircle' : u"\u24B8",
+ 'Cdot' : u"\u010A",
+ 'Cedillasmall' : u"\uF7B8",
+ 'Chaarmenian' : u"\u0549",
+ 'Cheabkhasiancyrillic' : u"\u04BC",
+ 'Checyrillic' : u"\u0427",
+ 'Chedescenderabkhasiancyrillic' : u"\u04BE",
+ 'Chedescendercyrillic' : u"\u04B6",
+ 'Chedieresiscyrillic' : u"\u04F4",
+ 'Cheharmenian' : u"\u0543",
+ 'Chekhakassiancyrillic' : u"\u04CB",
+ 'Cheverticalstrokecyrillic' : u"\u04B8",
+ 'Chook' : u"\u0187",
+ 'Circumflexsmall' : u"\uF6F6",
+ 'Cmonospace' : u"\uFF23",
+ 'Coarmenian' : u"\u0551",
+ 'Csmall' : u"\uF763",
+ 'DZ' : u"\u01F1",
+ 'DZcaron' : u"\u01C4",
+ 'Daarmenian' : u"\u0534",
+ 'Dafrican' : u"\u0189",
+ 'Dcedilla' : u"\u1E10",
+ 'Dcircle' : u"\u24B9",
+ 'Dcircumflexbelow' : u"\u1E12",
+ 'Ddotaccent' : u"\u1E0A",
+ 'Ddotbelow' : u"\u1E0C",
+ 'Decyrillic' : u"\u0414",
+ 'Deicoptic' : u"\u03EE",
+ 'Deltagreek' : u"\u0394",
+ 'Dhook' : u"\u018A",
+ 'Dieresis' : u"\uF6CB",
+ 'DieresisAcute' : u"\uF6CC",
+ 'DieresisGrave' : u"\uF6CD",
+ 'Dieresissmall' : u"\uF7A8",
+ 'Digammagreek' : u"\u03DC",
+ 'Djecyrillic' : u"\u0402",
+ 'Dlinebelow' : u"\u1E0E",
+ 'Dmonospace' : u"\uFF24",
+ 'Dotaccentsmall' : u"\uF6F7",
+ 'Dslash' : u"\u0110",
+ 'Dsmall' : u"\uF764",
+ 'Dtopbar' : u"\u018B",
+ 'Dz' : u"\u01F2",
+ 'Dzcaron' : u"\u01C5",
+ 'Dzeabkhasiancyrillic' : u"\u04E0",
+ 'Dzecyrillic' : u"\u0405",
+ 'Dzhecyrillic' : u"\u040F",
+ 'Eacutesmall' : u"\uF7E9",
+ 'Ecedillabreve' : u"\u1E1C",
+ 'Echarmenian' : u"\u0535",
+ 'Ecircle' : u"\u24BA",
+ 'Ecircumflexacute' : u"\u1EBE",
+ 'Ecircumflexbelow' : u"\u1E18",
+ 'Ecircumflexdotbelow' : u"\u1EC6",
+ 'Ecircumflexgrave' : u"\u1EC0",
+ 'Ecircumflexhookabove' : u"\u1EC2",
+ 'Ecircumflexsmall' : u"\uF7EA",
+ 'Ecircumflextilde' : u"\u1EC4",
+ 'Ecyrillic' : u"\u0404",
+ 'Edblgrave' : u"\u0204",
+ 'Edieresissmall' : u"\uF7EB",
+ 'Edot' : u"\u0116",
+ 'Edotbelow' : u"\u1EB8",
+ 'Efcyrillic' : u"\u0424",
+ 'Egravesmall' : u"\uF7E8",
+ 'Eharmenian' : u"\u0537",
+ 'Ehookabove' : u"\u1EBA",
+ 'Eightroman' : u"\u2167",
+ 'Einvertedbreve' : u"\u0206",
+ 'Eiotifiedcyrillic' : u"\u0464",
+ 'Elcyrillic' : u"\u041B",
+ 'Elevenroman' : u"\u216A",
+ 'Emacronacute' : u"\u1E16",
+ 'Emacrongrave' : u"\u1E14",
+ 'Emcyrillic' : u"\u041C",
+ 'Emonospace' : u"\uFF25",
+ 'Encyrillic' : u"\u041D",
+ 'Endescendercyrillic' : u"\u04A2",
+ 'Enghecyrillic' : u"\u04A4",
+ 'Enhookcyrillic' : u"\u04C7",
+ 'Eopen' : u"\u0190",
+ 'Ercyrillic' : u"\u0420",
+ 'Ereversed' : u"\u018E",
+ 'Ereversedcyrillic' : u"\u042D",
+ 'Escyrillic' : u"\u0421",
+ 'Esdescendercyrillic' : u"\u04AA",
+ 'Esh' : u"\u01A9",
+ 'Esmall' : u"\uF765",
+ 'Etarmenian' : u"\u0538",
+ 'Ethsmall' : u"\uF7F0",
+ 'Etilde' : u"\u1EBC",
+ 'Etildebelow' : u"\u1E1A",
+ 'Ezh' : u"\u01B7",
+ 'Ezhcaron' : u"\u01EE",
+ 'Ezhreversed' : u"\u01B8",
+ 'Fcircle' : u"\u24BB",
+ 'Fdotaccent' : u"\u1E1E",
+ 'Feharmenian' : u"\u0556",
+ 'Feicoptic' : u"\u03E4",
+ 'Fhook' : u"\u0191",
+ 'Fitacyrillic' : u"\u0472",
+ 'Fiveroman' : u"\u2164",
+ 'Fmonospace' : u"\uFF26",
+ 'Fourroman' : u"\u2163",
+ 'Fsmall' : u"\uF766",
+ 'GBsquare' : u"\u3387",
+ 'Gacute' : u"\u01F4",
+ 'Gammaafrican' : u"\u0194",
+ 'Gangiacoptic' : u"\u03EA",
+ 'Gcedilla' : u"\u0122",
+ 'Gcircle' : u"\u24BC",
+ 'Gdot' : u"\u0120",
+ 'Gecyrillic' : u"\u0413",
+ 'Ghadarmenian' : u"\u0542",
+ 'Ghemiddlehookcyrillic' : u"\u0494",
+ 'Ghestrokecyrillic' : u"\u0492",
+ 'Gheupturncyrillic' : u"\u0490",
+ 'Ghook' : u"\u0193",
+ 'Gimarmenian' : u"\u0533",
+ 'Gjecyrillic' : u"\u0403",
+ 'Gmacron' : u"\u1E20",
+ 'Gmonospace' : u"\uFF27",
+ 'Grave' : u"\uF6CE",
+ 'Gravesmall' : u"\uF760",
+ 'Gsmall' : u"\uF767",
+ 'Gsmallhook' : u"\u029B",
+ 'Gstroke' : u"\u01E4",
+ 'HPsquare' : u"\u33CB",
+ 'Haabkhasiancyrillic' : u"\u04A8",
+ 'Hadescendercyrillic' : u"\u04B2",
+ 'Hardsigncyrillic' : u"\u042A",
+ 'Hbrevebelow' : u"\u1E2A",
+ 'Hcedilla' : u"\u1E28",
+ 'Hcircle' : u"\u24BD",
+ 'Hdieresis' : u"\u1E26",
+ 'Hdotaccent' : u"\u1E22",
+ 'Hdotbelow' : u"\u1E24",
+ 'Hmonospace' : u"\uFF28",
+ 'Hoarmenian' : u"\u0540",
+ 'Horicoptic' : u"\u03E8",
+ 'Hsmall' : u"\uF768",
+ 'Hungarumlaut' : u"\uF6CF",
+ 'Hungarumlautsmall' : u"\uF6F8",
+ 'Hzsquare' : u"\u3390",
+ 'IAcyrillic' : u"\u042F",
+ 'IUcyrillic' : u"\u042E",
+ 'Iacutesmall' : u"\uF7ED",
+ 'Icaron' : u"\u01CF",
+ 'Icircle' : u"\u24BE",
+ 'Icircumflexsmall' : u"\uF7EE",
+ 'Icyrillic' : u"\u0406",
+ 'Idblgrave' : u"\u0208",
+ 'Idieresisacute' : u"\u1E2E",
+ 'Idieresiscyrillic' : u"\u04E4",
+ 'Idieresissmall' : u"\uF7EF",
+ 'Idot' : u"\u0130",
+ 'Idotbelow' : u"\u1ECA",
+ 'Iebrevecyrillic' : u"\u04D6",
+ 'Iecyrillic' : u"\u0415",
+ 'Igravesmall' : u"\uF7EC",
+ 'Ihookabove' : u"\u1EC8",
+ 'Iicyrillic' : u"\u0418",
+ 'Iinvertedbreve' : u"\u020A",
+ 'Iishortcyrillic' : u"\u0419",
+ 'Imacroncyrillic' : u"\u04E2",
+ 'Imonospace' : u"\uFF29",
+ 'Iniarmenian' : u"\u053B",
+ 'Iocyrillic' : u"\u0401",
+ 'Iotaafrican' : u"\u0196",
+ 'Ismall' : u"\uF769",
+ 'Istroke' : u"\u0197",
+ 'Itildebelow' : u"\u1E2C",
+ 'Izhitsacyrillic' : u"\u0474",
+ 'Izhitsadblgravecyrillic' : u"\u0476",
+ 'Jaarmenian' : u"\u0541",
+ 'Jcircle' : u"\u24BF",
+ 'Jecyrillic' : u"\u0408",
+ 'Jheharmenian' : u"\u054B",
+ 'Jmonospace' : u"\uFF2A",
+ 'Jsmall' : u"\uF76A",
+ 'KBsquare' : u"\u3385",
+ 'KKsquare' : u"\u33CD",
+ 'Kabashkircyrillic' : u"\u04A0",
+ 'Kacute' : u"\u1E30",
+ 'Kacyrillic' : u"\u041A",
+ 'Kadescendercyrillic' : u"\u049A",
+ 'Kahookcyrillic' : u"\u04C3",
+ 'Kastrokecyrillic' : u"\u049E",
+ 'Kaverticalstrokecyrillic' : u"\u049C",
+ 'Kcaron' : u"\u01E8",
+ 'Kcedilla' : u"\u0136",
+ 'Kcircle' : u"\u24C0",
+ 'Kdotbelow' : u"\u1E32",
+ 'Keharmenian' : u"\u0554",
+ 'Kenarmenian' : u"\u053F",
+ 'Khacyrillic' : u"\u0425",
+ 'Kheicoptic' : u"\u03E6",
+ 'Khook' : u"\u0198",
+ 'Kjecyrillic' : u"\u040C",
+ 'Klinebelow' : u"\u1E34",
+ 'Kmonospace' : u"\uFF2B",
+ 'Koppacyrillic' : u"\u0480",
+ 'Koppagreek' : u"\u03DE",
+ 'Ksicyrillic' : u"\u046E",
+ 'Ksmall' : u"\uF76B",
+ 'LJ' : u"\u01C7",
+ 'LL' : u"\uF6BF",
+ 'Lcedilla' : u"\u013B",
+ 'Lcircle' : u"\u24C1",
+ 'Lcircumflexbelow' : u"\u1E3C",
+ 'Ldotaccent' : u"\u013F",
+ 'Ldotbelow' : u"\u1E36",
+ 'Ldotbelowmacron' : u"\u1E38",
+ 'Liwnarmenian' : u"\u053C",
+ 'Lj' : u"\u01C8",
+ 'Ljecyrillic' : u"\u0409",
+ 'Llinebelow' : u"\u1E3A",
+ 'Lmonospace' : u"\uFF2C",
+ 'Lslashsmall' : u"\uF6F9",
+ 'Lsmall' : u"\uF76C",
+ 'MBsquare' : u"\u3386",
+ 'Macron' : u"\uF6D0",
+ 'Macronsmall' : u"\uF7AF",
+ 'Macute' : u"\u1E3E",
+ 'Mcircle' : u"\u24C2",
+ 'Mdotaccent' : u"\u1E40",
+ 'Mdotbelow' : u"\u1E42",
+ 'Menarmenian' : u"\u0544",
+ 'Mmonospace' : u"\uFF2D",
+ 'Msmall' : u"\uF76D",
+ 'Mturned' : u"\u019C",
+ 'NJ' : u"\u01CA",
+ 'Ncedilla' : u"\u0145",
+ 'Ncircle' : u"\u24C3",
+ 'Ncircumflexbelow' : u"\u1E4A",
+ 'Ndotaccent' : u"\u1E44",
+ 'Ndotbelow' : u"\u1E46",
+ 'Nhookleft' : u"\u019D",
+ 'Nineroman' : u"\u2168",
+ 'Nj' : u"\u01CB",
+ 'Njecyrillic' : u"\u040A",
+ 'Nlinebelow' : u"\u1E48",
+ 'Nmonospace' : u"\uFF2E",
+ 'Nowarmenian' : u"\u0546",
+ 'Nsmall' : u"\uF76E",
+ 'Ntildesmall' : u"\uF7F1",
+ 'OEsmall' : u"\uF6FA",
+ 'Oacutesmall' : u"\uF7F3",
+ 'Obarredcyrillic' : u"\u04E8",
+ 'Obarreddieresiscyrillic' : u"\u04EA",
+ 'Ocaron' : u"\u01D1",
+ 'Ocenteredtilde' : u"\u019F",
+ 'Ocircle' : u"\u24C4",
+ 'Ocircumflexacute' : u"\u1ED0",
+ 'Ocircumflexdotbelow' : u"\u1ED8",
+ 'Ocircumflexgrave' : u"\u1ED2",
+ 'Ocircumflexhookabove' : u"\u1ED4",
+ 'Ocircumflexsmall' : u"\uF7F4",
+ 'Ocircumflextilde' : u"\u1ED6",
+ 'Ocyrillic' : u"\u041E",
+ 'Odblacute' : u"\u0150",
+ 'Odblgrave' : u"\u020C",
+ 'Odieresiscyrillic' : u"\u04E6",
+ 'Odieresissmall' : u"\uF7F6",
+ 'Odotbelow' : u"\u1ECC",
+ 'Ogoneksmall' : u"\uF6FB",
+ 'Ogravesmall' : u"\uF7F2",
+ 'Oharmenian' : u"\u0555",
+ 'Ohm' : u"\u2126",
+ 'Ohookabove' : u"\u1ECE",
+ 'Ohornacute' : u"\u1EDA",
+ 'Ohorndotbelow' : u"\u1EE2",
+ 'Ohorngrave' : u"\u1EDC",
+ 'Ohornhookabove' : u"\u1EDE",
+ 'Ohorntilde' : u"\u1EE0",
+ 'Oi' : u"\u01A2",
+ 'Oinvertedbreve' : u"\u020E",
+ 'Omacronacute' : u"\u1E52",
+ 'Omacrongrave' : u"\u1E50",
+ 'Omegacyrillic' : u"\u0460",
+ 'Omegagreek' : u"\u03A9",
+ 'Omegaroundcyrillic' : u"\u047A",
+ 'Omegatitlocyrillic' : u"\u047C",
+ 'Omonospace' : u"\uFF2F",
+ 'Oneroman' : u"\u2160",
+ 'Oogonek' : u"\u01EA",
+ 'Oogonekmacron' : u"\u01EC",
+ 'Oopen' : u"\u0186",
+ 'Oslashsmall' : u"\uF7F8",
+ 'Osmall' : u"\uF76F",
+ 'Ostrokeacute' : u"\u01FE",
+ 'Otcyrillic' : u"\u047E",
+ 'Otildeacute' : u"\u1E4C",
+ 'Otildedieresis' : u"\u1E4E",
+ 'Otildesmall' : u"\uF7F5",
+ 'Pacute' : u"\u1E54",
+ 'Pcircle' : u"\u24C5",
+ 'Pdotaccent' : u"\u1E56",
+ 'Pecyrillic' : u"\u041F",
+ 'Peharmenian' : u"\u054A",
+ 'Pemiddlehookcyrillic' : u"\u04A6",
+ 'Phook' : u"\u01A4",
+ 'Piwrarmenian' : u"\u0553",
+ 'Pmonospace' : u"\uFF30",
+ 'Psicyrillic' : u"\u0470",
+ 'Psmall' : u"\uF770",
+ 'Qcircle' : u"\u24C6",
+ 'Qmonospace' : u"\uFF31",
+ 'Qsmall' : u"\uF771",
+ 'Raarmenian' : u"\u054C",
+ 'Rcedilla' : u"\u0156",
+ 'Rcircle' : u"\u24C7",
+ 'Rdblgrave' : u"\u0210",
+ 'Rdotaccent' : u"\u1E58",
+ 'Rdotbelow' : u"\u1E5A",
+ 'Rdotbelowmacron' : u"\u1E5C",
+ 'Reharmenian' : u"\u0550",
+ 'Ringsmall' : u"\uF6FC",
+ 'Rinvertedbreve' : u"\u0212",
+ 'Rlinebelow' : u"\u1E5E",
+ 'Rmonospace' : u"\uFF32",
+ 'Rsmall' : u"\uF772",
+ 'Rsmallinverted' : u"\u0281",
+ 'Rsmallinvertedsuperior' : u"\u02B6",
+ 'Sacutedotaccent' : u"\u1E64",
+ 'Sampigreek' : u"\u03E0",
+ 'Scarondotaccent' : u"\u1E66",
+ 'Scaronsmall' : u"\uF6FD",
+ 'Schwa' : u"\u018F",
+ 'Schwacyrillic' : u"\u04D8",
+ 'Schwadieresiscyrillic' : u"\u04DA",
+ 'Scircle' : u"\u24C8",
+ 'Sdotaccent' : u"\u1E60",
+ 'Sdotbelow' : u"\u1E62",
+ 'Sdotbelowdotaccent' : u"\u1E68",
+ 'Seharmenian' : u"\u054D",
+ 'Sevenroman' : u"\u2166",
+ 'Shaarmenian' : u"\u0547",
+ 'Shacyrillic' : u"\u0428",
+ 'Shchacyrillic' : u"\u0429",
+ 'Sheicoptic' : u"\u03E2",
+ 'Shhacyrillic' : u"\u04BA",
+ 'Shimacoptic' : u"\u03EC",
+ 'Sixroman' : u"\u2165",
+ 'Smonospace' : u"\uFF33",
+ 'Softsigncyrillic' : u"\u042C",
+ 'Ssmall' : u"\uF773",
+ 'Stigmagreek' : u"\u03DA",
+ 'Tcedilla' : u"\u0162",
+ 'Tcircle' : u"\u24C9",
+ 'Tcircumflexbelow' : u"\u1E70",
+ 'Tdotaccent' : u"\u1E6A",
+ 'Tdotbelow' : u"\u1E6C",
+ 'Tecyrillic' : u"\u0422",
+ 'Tedescendercyrillic' : u"\u04AC",
+ 'Tenroman' : u"\u2169",
+ 'Tetsecyrillic' : u"\u04B4",
+ 'Thook' : u"\u01AC",
+ 'Thornsmall' : u"\uF7FE",
+ 'Threeroman' : u"\u2162",
+ 'Tildesmall' : u"\uF6FE",
+ 'Tiwnarmenian' : u"\u054F",
+ 'Tlinebelow' : u"\u1E6E",
+ 'Tmonospace' : u"\uFF34",
+ 'Toarmenian' : u"\u0539",
+ 'Tonefive' : u"\u01BC",
+ 'Tonesix' : u"\u0184",
+ 'Tonetwo' : u"\u01A7",
+ 'Tretroflexhook' : u"\u01AE",
+ 'Tsecyrillic' : u"\u0426",
+ 'Tshecyrillic' : u"\u040B",
+ 'Tsmall' : u"\uF774",
+ 'Twelveroman' : u"\u216B",
+ 'Tworoman' : u"\u2161",
+ 'Uacutesmall' : u"\uF7FA",
+ 'Ucaron' : u"\u01D3",
+ 'Ucircle' : u"\u24CA",
+ 'Ucircumflexbelow' : u"\u1E76",
+ 'Ucircumflexsmall' : u"\uF7FB",
+ 'Ucyrillic' : u"\u0423",
+ 'Udblacute' : u"\u0170",
+ 'Udblgrave' : u"\u0214",
+ 'Udieresisacute' : u"\u01D7",
+ 'Udieresisbelow' : u"\u1E72",
+ 'Udieresiscaron' : u"\u01D9",
+ 'Udieresiscyrillic' : u"\u04F0",
+ 'Udieresisgrave' : u"\u01DB",
+ 'Udieresismacron' : u"\u01D5",
+ 'Udieresissmall' : u"\uF7FC",
+ 'Udotbelow' : u"\u1EE4",
+ 'Ugravesmall' : u"\uF7F9",
+ 'Uhookabove' : u"\u1EE6",
+ 'Uhornacute' : u"\u1EE8",
+ 'Uhorndotbelow' : u"\u1EF0",
+ 'Uhorngrave' : u"\u1EEA",
+ 'Uhornhookabove' : u"\u1EEC",
+ 'Uhorntilde' : u"\u1EEE",
+ 'Uhungarumlautcyrillic' : u"\u04F2",
+ 'Uinvertedbreve' : u"\u0216",
+ 'Ukcyrillic' : u"\u0478",
+ 'Umacroncyrillic' : u"\u04EE",
+ 'Umacrondieresis' : u"\u1E7A",
+ 'Umonospace' : u"\uFF35",
+ 'Upsilonacutehooksymbolgreek' : u"\u03D3",
+ 'Upsilonafrican' : u"\u01B1",
+ 'Upsilondieresishooksymbolgreek' : u"\u03D4",
+ 'Upsilonhooksymbol' : u"\u03D2",
+ 'Ushortcyrillic' : u"\u040E",
+ 'Usmall' : u"\uF775",
+ 'Ustraightcyrillic' : u"\u04AE",
+ 'Ustraightstrokecyrillic' : u"\u04B0",
+ 'Utildeacute' : u"\u1E78",
+ 'Utildebelow' : u"\u1E74",
+ 'Vcircle' : u"\u24CB",
+ 'Vdotbelow' : u"\u1E7E",
+ 'Vecyrillic' : u"\u0412",
+ 'Vewarmenian' : u"\u054E",
+ 'Vhook' : u"\u01B2",
+ 'Vmonospace' : u"\uFF36",
+ 'Voarmenian' : u"\u0548",
+ 'Vsmall' : u"\uF776",
+ 'Vtilde' : u"\u1E7C",
+ 'Wcircle' : u"\u24CC",
+ 'Wdotaccent' : u"\u1E86",
+ 'Wdotbelow' : u"\u1E88",
+ 'Wmonospace' : u"\uFF37",
+ 'Wsmall' : u"\uF777",
+ 'Xcircle' : u"\u24CD",
+ 'Xdieresis' : u"\u1E8C",
+ 'Xdotaccent' : u"\u1E8A",
+ 'Xeharmenian' : u"\u053D",
+ 'Xmonospace' : u"\uFF38",
+ 'Xsmall' : u"\uF778",
+ 'Yacutesmall' : u"\uF7FD",
+ 'Yatcyrillic' : u"\u0462",
+ 'Ycircle' : u"\u24CE",
+ 'Ydieresissmall' : u"\uF7FF",
+ 'Ydotaccent' : u"\u1E8E",
+ 'Ydotbelow' : u"\u1EF4",
+ 'Yericyrillic' : u"\u042B",
+ 'Yerudieresiscyrillic' : u"\u04F8",
+ 'Yhook' : u"\u01B3",
+ 'Yhookabove' : u"\u1EF6",
+ 'Yiarmenian' : u"\u0545",
+ 'Yicyrillic' : u"\u0407",
+ 'Yiwnarmenian' : u"\u0552",
+ 'Ymonospace' : u"\uFF39",
+ 'Ysmall' : u"\uF779",
+ 'Ytilde' : u"\u1EF8",
+ 'Yusbigcyrillic' : u"\u046A",
+ 'Yusbigiotifiedcyrillic' : u"\u046C",
+ 'Yuslittlecyrillic' : u"\u0466",
+ 'Yuslittleiotifiedcyrillic' : u"\u0468",
+ 'Zaarmenian' : u"\u0536",
+ 'Zcaronsmall' : u"\uF6FF",
+ 'Zcircle' : u"\u24CF",
+ 'Zcircumflex' : u"\u1E90",
+ 'Zdot' : u"\u017B",
+ 'Zdotbelow' : u"\u1E92",
+ 'Zecyrillic' : u"\u0417",
+ 'Zedescendercyrillic' : u"\u0498",
+ 'Zedieresiscyrillic' : u"\u04DE",
+ 'Zhearmenian' : u"\u053A",
+ 'Zhebrevecyrillic' : u"\u04C1",
+ 'Zhecyrillic' : u"\u0416",
+ 'Zhedescendercyrillic' : u"\u0496",
+ 'Zhedieresiscyrillic' : u"\u04DC",
+ 'Zlinebelow' : u"\u1E94",
+ 'Zmonospace' : u"\uFF3A",
+ 'Zsmall' : u"\uF77A",
+ 'Zstroke' : u"\u01B5",
+ 'aabengali' : u"\u0986",
+ 'aadeva' : u"\u0906",
+ 'aagujarati' : u"\u0A86",
+ 'aagurmukhi' : u"\u0A06",
+ 'aamatragurmukhi' : u"\u0A3E",
+ 'aarusquare' : u"\u3303",
+ 'aavowelsignbengali' : u"\u09BE",
+ 'aavowelsigndeva' : u"\u093E",
+ 'aavowelsigngujarati' : u"\u0ABE",
+ 'abbreviationmarkarmenian' : u"\u055F",
+ 'abbreviationsigndeva' : u"\u0970",
+ 'abengali' : u"\u0985",
+ 'abopomofo' : u"\u311A",
+ 'abreveacute' : u"\u1EAF",
+ 'abrevecyrillic' : u"\u04D1",
+ 'abrevedotbelow' : u"\u1EB7",
+ 'abrevegrave' : u"\u1EB1",
+ 'abrevehookabove' : u"\u1EB3",
+ 'abrevetilde' : u"\u1EB5",
+ 'acaron' : u"\u01CE",
+ 'acircle' : u"\u24D0",
+ 'acircumflexacute' : u"\u1EA5",
+ 'acircumflexdotbelow' : u"\u1EAD",
+ 'acircumflexgrave' : u"\u1EA7",
+ 'acircumflexhookabove' : u"\u1EA9",
+ 'acircumflextilde' : u"\u1EAB",
+ 'acutebelowcmb' : u"\u0317",
+ 'acutecmb' : u"\u0301",
+ 'acutedeva' : u"\u0954",
+ 'acutelowmod' : u"\u02CF",
+ 'acutetonecmb' : u"\u0341",
+ 'acyrillic' : u"\u0430",
+ 'adblgrave' : u"\u0201",
+ 'addakgurmukhi' : u"\u0A71",
+ 'adeva' : u"\u0905",
+ 'adieresiscyrillic' : u"\u04D3",
+ 'adieresismacron' : u"\u01DF",
+ 'adotbelow' : u"\u1EA1",
+ 'adotmacron' : u"\u01E1",
+ 'aekorean' : u"\u3150",
+ 'aemacron' : u"\u01E3",
+ 'afii08941' : u"\u20A4",
+ 'afii10063' : u"\uF6C4",
+ 'afii10064' : u"\uF6C5",
+ 'afii10192' : u"\uF6C6",
+ 'afii10831' : u"\uF6C7",
+ 'afii10832' : u"\uF6C8",
+ 'agujarati' : u"\u0A85",
+ 'agurmukhi' : u"\u0A05",
+ 'ahiragana' : u"\u3042",
+ 'ahookabove' : u"\u1EA3",
+ 'aibengali' : u"\u0990",
+ 'aibopomofo' : u"\u311E",
+ 'aideva' : u"\u0910",
+ 'aiecyrillic' : u"\u04D5",
+ 'aigujarati' : u"\u0A90",
+ 'aigurmukhi' : u"\u0A10",
+ 'aimatragurmukhi' : u"\u0A48",
+ 'ainarabic' : u"\u0639",
+ 'ainfinalarabic' : u"\uFECA",
+ 'aininitialarabic' : u"\uFECB",
+ 'ainmedialarabic' : u"\uFECC",
+ 'ainvertedbreve' : u"\u0203",
+ 'aivowelsignbengali' : u"\u09C8",
+ 'aivowelsigndeva' : u"\u0948",
+ 'aivowelsigngujarati' : u"\u0AC8",
+ 'akatakana' : u"\u30A2",
+ 'akatakanahalfwidth' : u"\uFF71",
+ 'akorean' : u"\u314F",
+ 'alef' : u"\u05D0",
+ 'alefarabic' : u"\u0627",
+ 'alefdageshhebrew' : u"\uFB30",
+ 'aleffinalarabic' : u"\uFE8E",
+ 'alefhamzaabovearabic' : u"\u0623",
+ 'alefhamzaabovefinalarabic' : u"\uFE84",
+ 'alefhamzabelowarabic' : u"\u0625",
+ 'alefhamzabelowfinalarabic' : u"\uFE88",
+ 'alefhebrew' : u"\u05D0",
+ 'aleflamedhebrew' : u"\uFB4F",
+ 'alefmaddaabovearabic' : u"\u0622",
+ 'alefmaddaabovefinalarabic' : u"\uFE82",
+ 'alefmaksuraarabic' : u"\u0649",
+ 'alefmaksurafinalarabic' : u"\uFEF0",
+ 'alefmaksurainitialarabic' : u"\uFEF3",
+ 'alefmaksuramedialarabic' : u"\uFEF4",
+ 'alefpatahhebrew' : u"\uFB2E",
+ 'alefqamatshebrew' : u"\uFB2F",
+ 'allequal' : u"\u224C",
+ 'amonospace' : u"\uFF41",
+ 'ampersandmonospace' : u"\uFF06",
+ 'ampersandsmall' : u"\uF726",
+ 'amsquare' : u"\u33C2",
+ 'anbopomofo' : u"\u3122",
+ 'angbopomofo' : u"\u3124",
+ 'angkhankhuthai' : u"\u0E5A",
+ 'anglebracketleft' : u"\u3008",
+ 'anglebracketleftvertical' : u"\uFE3F",
+ 'anglebracketright' : u"\u3009",
+ 'anglebracketrightvertical' : u"\uFE40",
+ 'angstrom' : u"\u212B",
+ 'anudattadeva' : u"\u0952",
+ 'anusvarabengali' : u"\u0982",
+ 'anusvaradeva' : u"\u0902",
+ 'anusvaragujarati' : u"\u0A82",
+ 'apaatosquare' : u"\u3300",
+ 'aparen' : u"\u249C",
+ 'apostrophearmenian' : u"\u055A",
+ 'apostrophemod' : u"\u02BC",
+ 'apple' : u"\uF8FF",
+ 'approaches' : u"\u2250",
+ 'approxequalorimage' : u"\u2252",
+ 'approximatelyequal' : u"\u2245",
+ 'araeaekorean' : u"\u318E",
+ 'araeakorean' : u"\u318D",
+ 'arc' : u"\u2312",
+ 'arighthalfring' : u"\u1E9A",
+ 'aringbelow' : u"\u1E01",
+ 'arrowdashdown' : u"\u21E3",
+ 'arrowdashleft' : u"\u21E0",
+ 'arrowdashright' : u"\u21E2",
+ 'arrowdashup' : u"\u21E1",
+ 'arrowdownleft' : u"\u2199",
+ 'arrowdownright' : u"\u2198",
+ 'arrowdownwhite' : u"\u21E9",
+ 'arrowheaddownmod' : u"\u02C5",
+ 'arrowheadleftmod' : u"\u02C2",
+ 'arrowheadrightmod' : u"\u02C3",
+ 'arrowheadupmod' : u"\u02C4",
+ 'arrowhorizex' : u"\uF8E7",
+ 'arrowleftdbl' : u"\u21D0",
+ 'arrowleftdblstroke' : u"\u21CD",
+ 'arrowleftoverright' : u"\u21C6",
+ 'arrowleftwhite' : u"\u21E6",
+ 'arrowrightdblstroke' : u"\u21CF",
+ 'arrowrightheavy' : u"\u279E",
+ 'arrowrightoverleft' : u"\u21C4",
+ 'arrowrightwhite' : u"\u21E8",
+ 'arrowtableft' : u"\u21E4",
+ 'arrowtabright' : u"\u21E5",
+ 'arrowupdownbase' : u"\u21A8",
+ 'arrowupleft' : u"\u2196",
+ 'arrowupleftofdown' : u"\u21C5",
+ 'arrowupright' : u"\u2197",
+ 'arrowupwhite' : u"\u21E7",
+ 'arrowvertex' : u"\uF8E6",
+ 'asciicircummonospace' : u"\uFF3E",
+ 'asciitildemonospace' : u"\uFF5E",
+ 'ascript' : u"\u0251",
+ 'ascriptturned' : u"\u0252",
+ 'asmallhiragana' : u"\u3041",
+ 'asmallkatakana' : u"\u30A1",
+ 'asmallkatakanahalfwidth' : u"\uFF67",
+ 'asteriskaltonearabic' : u"\u066D",
+ 'asteriskarabic' : u"\u066D",
+ 'asteriskmonospace' : u"\uFF0A",
+ 'asterisksmall' : u"\uFE61",
+ 'asterism' : u"\u2042",
+ 'asuperior' : u"\uF6E9",
+ 'asymptoticallyequal' : u"\u2243",
+ 'atmonospace' : u"\uFF20",
+ 'atsmall' : u"\uFE6B",
+ 'aturned' : u"\u0250",
+ 'aubengali' : u"\u0994",
+ 'aubopomofo' : u"\u3120",
+ 'audeva' : u"\u0914",
+ 'augujarati' : u"\u0A94",
+ 'augurmukhi' : u"\u0A14",
+ 'aulengthmarkbengali' : u"\u09D7",
+ 'aumatragurmukhi' : u"\u0A4C",
+ 'auvowelsignbengali' : u"\u09CC",
+ 'auvowelsigndeva' : u"\u094C",
+ 'auvowelsigngujarati' : u"\u0ACC",
+ 'avagrahadeva' : u"\u093D",
+ 'aybarmenian' : u"\u0561",
+ 'ayin' : u"\u05E2",
+ 'ayinaltonehebrew' : u"\uFB20",
+ 'ayinhebrew' : u"\u05E2",
+ 'babengali' : u"\u09AC",
+ 'backslashmonospace' : u"\uFF3C",
+ 'badeva' : u"\u092C",
+ 'bagujarati' : u"\u0AAC",
+ 'bagurmukhi' : u"\u0A2C",
+ 'bahiragana' : u"\u3070",
+ 'bahtthai' : u"\u0E3F",
+ 'bakatakana' : u"\u30D0",
+ 'barmonospace' : u"\uFF5C",
+ 'bbopomofo' : u"\u3105",
+ 'bcircle' : u"\u24D1",
+ 'bdotaccent' : u"\u1E03",
+ 'bdotbelow' : u"\u1E05",
+ 'beamedsixteenthnotes' : u"\u266C",
+ 'because' : u"\u2235",
+ 'becyrillic' : u"\u0431",
+ 'beharabic' : u"\u0628",
+ 'behfinalarabic' : u"\uFE90",
+ 'behinitialarabic' : u"\uFE91",
+ 'behiragana' : u"\u3079",
+ 'behmedialarabic' : u"\uFE92",
+ 'behmeeminitialarabic' : u"\uFC9F",
+ 'behmeemisolatedarabic' : u"\uFC08",
+ 'behnoonfinalarabic' : u"\uFC6D",
+ 'bekatakana' : u"\u30D9",
+ 'benarmenian' : u"\u0562",
+ 'bet' : u"\u05D1",
+ 'betasymbolgreek' : u"\u03D0",
+ 'betdagesh' : u"\uFB31",
+ 'betdageshhebrew' : u"\uFB31",
+ 'bethebrew' : u"\u05D1",
+ 'betrafehebrew' : u"\uFB4C",
+ 'bhabengali' : u"\u09AD",
+ 'bhadeva' : u"\u092D",
+ 'bhagujarati' : u"\u0AAD",
+ 'bhagurmukhi' : u"\u0A2D",
+ 'bhook' : u"\u0253",
+ 'bihiragana' : u"\u3073",
+ 'bikatakana' : u"\u30D3",
+ 'bilabialclick' : u"\u0298",
+ 'bindigurmukhi' : u"\u0A02",
+ 'birusquare' : u"\u3331",
+ 'blackcircle' : u"\u25CF",
+ 'blackdiamond' : u"\u25C6",
+ 'blackdownpointingtriangle' : u"\u25BC",
+ 'blackleftpointingpointer' : u"\u25C4",
+ 'blackleftpointingtriangle' : u"\u25C0",
+ 'blacklenticularbracketleft' : u"\u3010",
+ 'blacklenticularbracketleftvertical' : u"\uFE3B",
+ 'blacklenticularbracketright' : u"\u3011",
+ 'blacklenticularbracketrightvertical' : u"\uFE3C",
+ 'blacklowerlefttriangle' : u"\u25E3",
+ 'blacklowerrighttriangle' : u"\u25E2",
+ 'blackrectangle' : u"\u25AC",
+ 'blackrightpointingpointer' : u"\u25BA",
+ 'blackrightpointingtriangle' : u"\u25B6",
+ 'blacksmallsquare' : u"\u25AA",
+ 'blacksmilingface' : u"\u263B",
+ 'blacksquare' : u"\u25A0",
+ 'blackstar' : u"\u2605",
+ 'blackupperlefttriangle' : u"\u25E4",
+ 'blackupperrighttriangle' : u"\u25E5",
+ 'blackuppointingsmalltriangle' : u"\u25B4",
+ 'blackuppointingtriangle' : u"\u25B2",
+ 'blank' : u"\u2423",
+ 'blinebelow' : u"\u1E07",
+ 'bmonospace' : u"\uFF42",
+ 'bobaimaithai' : u"\u0E1A",
+ 'bohiragana' : u"\u307C",
+ 'bokatakana' : u"\u30DC",
+ 'bparen' : u"\u249D",
+ 'bqsquare' : u"\u33C3",
+ 'braceex' : u"\uF8F4",
+ 'braceleftbt' : u"\uF8F3",
+ 'braceleftmid' : u"\uF8F2",
+ 'braceleftmonospace' : u"\uFF5B",
+ 'braceleftsmall' : u"\uFE5B",
+ 'bracelefttp' : u"\uF8F1",
+ 'braceleftvertical' : u"\uFE37",
+ 'bracerightbt' : u"\uF8FE",
+ 'bracerightmid' : u"\uF8FD",
+ 'bracerightmonospace' : u"\uFF5D",
+ 'bracerightsmall' : u"\uFE5C",
+ 'bracerighttp' : u"\uF8FC",
+ 'bracerightvertical' : u"\uFE38",
+ 'bracketleftbt' : u"\uF8F0",
+ 'bracketleftex' : u"\uF8EF",
+ 'bracketleftmonospace' : u"\uFF3B",
+ 'bracketlefttp' : u"\uF8EE",
+ 'bracketrightbt' : u"\uF8FB",
+ 'bracketrightex' : u"\uF8FA",
+ 'bracketrightmonospace' : u"\uFF3D",
+ 'bracketrighttp' : u"\uF8F9",
+ 'brevebelowcmb' : u"\u032E",
+ 'brevecmb' : u"\u0306",
+ 'breveinvertedbelowcmb' : u"\u032F",
+ 'breveinvertedcmb' : u"\u0311",
+ 'breveinverteddoublecmb' : u"\u0361",
+ 'bridgebelowcmb' : u"\u032A",
+ 'bridgeinvertedbelowcmb' : u"\u033A",
+ 'bstroke' : u"\u0180",
+ 'bsuperior' : u"\uF6EA",
+ 'btopbar' : u"\u0183",
+ 'buhiragana' : u"\u3076",
+ 'bukatakana' : u"\u30D6",
+ 'bulletinverse' : u"\u25D8",
+ 'bulletoperator' : u"\u2219",
+ 'bullseye' : u"\u25CE",
+ 'caarmenian' : u"\u056E",
+ 'cabengali' : u"\u099A",
+ 'cadeva' : u"\u091A",
+ 'cagujarati' : u"\u0A9A",
+ 'cagurmukhi' : u"\u0A1A",
+ 'calsquare' : u"\u3388",
+ 'candrabindubengali' : u"\u0981",
+ 'candrabinducmb' : u"\u0310",
+ 'candrabindudeva' : u"\u0901",
+ 'candrabindugujarati' : u"\u0A81",
+ 'capslock' : u"\u21EA",
+ 'careof' : u"\u2105",
+ 'caronbelowcmb' : u"\u032C",
+ 'caroncmb' : u"\u030C",
+ 'cbopomofo' : u"\u3118",
+ 'ccedillaacute' : u"\u1E09",
+ 'ccircle' : u"\u24D2",
+ 'ccurl' : u"\u0255",
+ 'cdot' : u"\u010B",
+ 'cdsquare' : u"\u33C5",
+ 'cedillacmb' : u"\u0327",
+ 'centigrade' : u"\u2103",
+ 'centinferior' : u"\uF6DF",
+ 'centmonospace' : u"\uFFE0",
+ 'centoldstyle' : u"\uF7A2",
+ 'centsuperior' : u"\uF6E0",
+ 'chaarmenian' : u"\u0579",
+ 'chabengali' : u"\u099B",
+ 'chadeva' : u"\u091B",
+ 'chagujarati' : u"\u0A9B",
+ 'chagurmukhi' : u"\u0A1B",
+ 'chbopomofo' : u"\u3114",
+ 'cheabkhasiancyrillic' : u"\u04BD",
+ 'checkmark' : u"\u2713",
+ 'checyrillic' : u"\u0447",
+ 'chedescenderabkhasiancyrillic' : u"\u04BF",
+ 'chedescendercyrillic' : u"\u04B7",
+ 'chedieresiscyrillic' : u"\u04F5",
+ 'cheharmenian' : u"\u0573",
+ 'chekhakassiancyrillic' : u"\u04CC",
+ 'cheverticalstrokecyrillic' : u"\u04B9",
+ 'chieuchacirclekorean' : u"\u3277",
+ 'chieuchaparenkorean' : u"\u3217",
+ 'chieuchcirclekorean' : u"\u3269",
+ 'chieuchkorean' : u"\u314A",
+ 'chieuchparenkorean' : u"\u3209",
+ 'chochangthai' : u"\u0E0A",
+ 'chochanthai' : u"\u0E08",
+ 'chochingthai' : u"\u0E09",
+ 'chochoethai' : u"\u0E0C",
+ 'chook' : u"\u0188",
+ 'cieucacirclekorean' : u"\u3276",
+ 'cieucaparenkorean' : u"\u3216",
+ 'cieuccirclekorean' : u"\u3268",
+ 'cieuckorean' : u"\u3148",
+ 'cieucparenkorean' : u"\u3208",
+ 'cieucuparenkorean' : u"\u321C",
+ 'circledash' : u"\u25CC",
+ 'circleot' : u"\u2299", # Actual Adobe glyph list entry -- identified as typo, May 2008
+ 'circledot' : u"\u2299", # What it should have been
+ 'circlepostalmark' : u"\u3036",
+ 'circlewithlefthalfblack' : u"\u25D0",
+ 'circlewithrighthalfblack' : u"\u25D1",
+ 'circumflexbelowcmb' : u"\u032D",
+ 'circumflexcmb' : u"\u0302",
+ 'clear' : u"\u2327",
+ 'clickalveolar' : u"\u01C2",
+ 'clickdental' : u"\u01C0",
+ 'clicklateral' : u"\u01C1",
+ 'clickretroflex' : u"\u01C3",
+ 'clubsuitblack' : u"\u2663",
+ 'clubsuitwhite' : u"\u2667",
+ 'cmcubedsquare' : u"\u33A4",
+ 'cmonospace' : u"\uFF43",
+ 'cmsquaredsquare' : u"\u33A0",
+ 'coarmenian' : u"\u0581",
+ 'colonmonospace' : u"\uFF1A",
+ 'colonsign' : u"\u20A1",
+ 'colonsmall' : u"\uFE55",
+ 'colontriangularhalfmod' : u"\u02D1",
+ 'colontriangularmod' : u"\u02D0",
+ 'commaabovecmb' : u"\u0313",
+ 'commaaboverightcmb' : u"\u0315",
+ 'commaaccent' : u"\uF6C3",
+ 'commaarabic' : u"\u060C",
+ 'commaarmenian' : u"\u055D",
+ 'commainferior' : u"\uF6E1",
+ 'commamonospace' : u"\uFF0C",
+ 'commareversedabovecmb' : u"\u0314",
+ 'commareversedmod' : u"\u02BD",
+ 'commasmall' : u"\uFE50",
+ 'commasuperior' : u"\uF6E2",
+ 'commaturnedabovecmb' : u"\u0312",
+ 'commaturnedmod' : u"\u02BB",
+ 'compass' : u"\u263C",
+ 'contourintegral' : u"\u222E",
+ 'control' : u"\u2303",
+ 'controlACK' : u"\u0006",
+ 'controlBEL' : u"\u0007",
+ 'controlBS' : u"\u0008",
+ 'controlCAN' : u"\u0018",
+ 'controlCR' : u"\u000D",
+ 'controlDC1' : u"\u0011",
+ 'controlDC2' : u"\u0012",
+ 'controlDC3' : u"\u0013",
+ 'controlDC4' : u"\u0014",
+ 'controlDEL' : u"\u007F",
+ 'controlDLE' : u"\u0010",
+ 'controlEM' : u"\u0019",
+ 'controlENQ' : u"\u0005",
+ 'controlEOT' : u"\u0004",
+ 'controlESC' : u"\u001B",
+ 'controlETB' : u"\u0017",
+ 'controlETX' : u"\u0003",
+ 'controlFF' : u"\u000C",
+ 'controlFS' : u"\u001C",
+ 'controlGS' : u"\u001D",
+ 'controlHT' : u"\u0009",
+ 'controlLF' : u"\u000A",
+ 'controlNAK' : u"\u0015",
+ 'controlRS' : u"\u001E",
+ 'controlSI' : u"\u000F",
+ 'controlSO' : u"\u000E",
+ 'controlSOT' : u"\u0002",
+ 'controlSTX' : u"\u0001",
+ 'controlSUB' : u"\u001A",
+ 'controlSYN' : u"\u0016",
+ 'controlUS' : u"\u001F",
+ 'controlVT' : u"\u000B",
+ 'copyrightsans' : u"\uF8E9",
+ 'copyrightserif' : u"\uF6D9",
+ 'cornerbracketleft' : u"\u300C",
+ 'cornerbracketlefthalfwidth' : u"\uFF62",
+ 'cornerbracketleftvertical' : u"\uFE41",
+ 'cornerbracketright' : u"\u300D",
+ 'cornerbracketrighthalfwidth' : u"\uFF63",
+ 'cornerbracketrightvertical' : u"\uFE42",
+ 'corporationsquare' : u"\u337F",
+ 'cosquare' : u"\u33C7",
+ 'coverkgsquare' : u"\u33C6",
+ 'cparen' : u"\u249E",
+ 'cruzeiro' : u"\u20A2",
+ 'cstretched' : u"\u0297",
+ 'curlyand' : u"\u22CF",
+ 'curlyor' : u"\u22CE",
+ 'cyrBreve' : u"\uF6D1",
+ 'cyrFlex' : u"\uF6D2",
+ 'cyrbreve' : u"\uF6D4",
+ 'cyrflex' : u"\uF6D5",
+ 'daarmenian' : u"\u0564",
+ 'dabengali' : u"\u09A6",
+ 'dadarabic' : u"\u0636",
+ 'dadeva' : u"\u0926",
+ 'dadfinalarabic' : u"\uFEBE",
+ 'dadinitialarabic' : u"\uFEBF",
+ 'dadmedialarabic' : u"\uFEC0",
+ 'dagesh' : u"\u05BC",
+ 'dageshhebrew' : u"\u05BC",
+ 'dagujarati' : u"\u0AA6",
+ 'dagurmukhi' : u"\u0A26",
+ 'dahiragana' : u"\u3060",
+ 'dakatakana' : u"\u30C0",
+ 'dalarabic' : u"\u062F",
+ 'dalet' : u"\u05D3",
+ 'daletdagesh' : u"\uFB33",
+ 'daletdageshhebrew' : u"\uFB33",
+ 'dalethatafpatah' : u"\u05D3\u05B2",
+ 'dalethatafpatahhebrew' : u"\u05D3\u05B2",
+ 'dalethatafsegol' : u"\u05D3\u05B1",
+ 'dalethatafsegolhebrew' : u"\u05D3\u05B1",
+ 'dalethebrew' : u"\u05D3",
+ 'dalethiriq' : u"\u05D3\u05B4",
+ 'dalethiriqhebrew' : u"\u05D3\u05B4",
+ 'daletholam' : u"\u05D3\u05B9",
+ 'daletholamhebrew' : u"\u05D3\u05B9",
+ 'daletpatah' : u"\u05D3\u05B7",
+ 'daletpatahhebrew' : u"\u05D3\u05B7",
+ 'daletqamats' : u"\u05D3\u05B8",
+ 'daletqamatshebrew' : u"\u05D3\u05B8",
+ 'daletqubuts' : u"\u05D3\u05BB",
+ 'daletqubutshebrew' : u"\u05D3\u05BB",
+ 'daletsegol' : u"\u05D3\u05B6",
+ 'daletsegolhebrew' : u"\u05D3\u05B6",
+ 'daletsheva' : u"\u05D3\u05B0",
+ 'daletshevahebrew' : u"\u05D3\u05B0",
+ 'dalettsere' : u"\u05D3\u05B5",
+ 'dalettserehebrew' : u"\u05D3\u05B5",
+ 'dalfinalarabic' : u"\uFEAA",
+ 'dammaarabic' : u"\u064F",
+ 'dammalowarabic' : u"\u064F",
+ 'dammatanaltonearabic' : u"\u064C",
+ 'dammatanarabic' : u"\u064C",
+ 'danda' : u"\u0964",
+ 'dargahebrew' : u"\u05A7",
+ 'dargalefthebrew' : u"\u05A7",
+ 'dasiapneumatacyrilliccmb' : u"\u0485",
+ 'dblGrave' : u"\uF6D3",
+ 'dblanglebracketleft' : u"\u300A",
+ 'dblanglebracketleftvertical' : u"\uFE3D",
+ 'dblanglebracketright' : u"\u300B",
+ 'dblanglebracketrightvertical' : u"\uFE3E",
+ 'dblarchinvertedbelowcmb' : u"\u032B",
+ 'dblarrowleft' : u"\u21D4",
+ 'dblarrowright' : u"\u21D2",
+ 'dbldanda' : u"\u0965",
+ 'dblgrave' : u"\uF6D6",
+ 'dblgravecmb' : u"\u030F",
+ 'dblintegral' : u"\u222C",
+ 'dbllowline' : u"\u2017",
+ 'dbllowlinecmb' : u"\u0333",
+ 'dbloverlinecmb' : u"\u033F",
+ 'dblprimemod' : u"\u02BA",
+ 'dblverticalbar' : u"\u2016",
+ 'dblverticallineabovecmb' : u"\u030E",
+ 'dbopomofo' : u"\u3109",
+ 'dbsquare' : u"\u33C8",
+ 'dcedilla' : u"\u1E11",
+ 'dcircle' : u"\u24D3",
+ 'dcircumflexbelow' : u"\u1E13",
+ 'ddabengali' : u"\u09A1",
+ 'ddadeva' : u"\u0921",
+ 'ddagujarati' : u"\u0AA1",
+ 'ddagurmukhi' : u"\u0A21",
+ 'ddalarabic' : u"\u0688",
+ 'ddalfinalarabic' : u"\uFB89",
+ 'dddhadeva' : u"\u095C",
+ 'ddhabengali' : u"\u09A2",
+ 'ddhadeva' : u"\u0922",
+ 'ddhagujarati' : u"\u0AA2",
+ 'ddhagurmukhi' : u"\u0A22",
+ 'ddotaccent' : u"\u1E0B",
+ 'ddotbelow' : u"\u1E0D",
+ 'decimalseparatorarabic' : u"\u066B",
+ 'decimalseparatorpersian' : u"\u066B",
+ 'decyrillic' : u"\u0434",
+ 'dehihebrew' : u"\u05AD",
+ 'dehiragana' : u"\u3067",
+ 'deicoptic' : u"\u03EF",
+ 'dekatakana' : u"\u30C7",
+ 'deleteleft' : u"\u232B",
+ 'deleteright' : u"\u2326",
+ 'deltaturned' : u"\u018D",
+ 'denominatorminusonenumeratorbengali' : u"\u09F8",
+ 'dezh' : u"\u02A4",
+ 'dhabengali' : u"\u09A7",
+ 'dhadeva' : u"\u0927",
+ 'dhagujarati' : u"\u0AA7",
+ 'dhagurmukhi' : u"\u0A27",
+ 'dhook' : u"\u0257",
+ 'dialytikatonos' : u"\u0385",
+ 'dialytikatonoscmb' : u"\u0344",
+ 'diamondsuitwhite' : u"\u2662",
+ 'dieresisacute' : u"\uF6D7",
+ 'dieresisbelowcmb' : u"\u0324",
+ 'dieresiscmb' : u"\u0308",
+ 'dieresisgrave' : u"\uF6D8",
+ 'dihiragana' : u"\u3062",
+ 'dikatakana' : u"\u30C2",
+ 'dittomark' : u"\u3003",
+ 'divides' : u"\u2223",
+ 'divisionslash' : u"\u2215",
+ 'djecyrillic' : u"\u0452",
+ 'dlinebelow' : u"\u1E0F",
+ 'dlsquare' : u"\u3397",
+ 'dmacron' : u"\u0111",
+ 'dmonospace' : u"\uFF44",
+ 'dochadathai' : u"\u0E0E",
+ 'dodekthai' : u"\u0E14",
+ 'dohiragana' : u"\u3069",
+ 'dokatakana' : u"\u30C9",
+ 'dollarinferior' : u"\uF6E3",
+ 'dollarmonospace' : u"\uFF04",
+ 'dollaroldstyle' : u"\uF724",
+ 'dollarsmall' : u"\uFE69",
+ 'dollarsuperior' : u"\uF6E4",
+ 'dorusquare' : u"\u3326",
+ 'dotaccentcmb' : u"\u0307",
+ 'dotbelowcmb' : u"\u0323",
+ 'dotkatakana' : u"\u30FB",
+ 'dotlessj' : u"\uF6BE",
+ 'dotlessjstrokehook' : u"\u0284",
+ 'dottedcircle' : u"\u25CC",
+ 'doubleyodpatah' : u"\uFB1F",
+ 'doubleyodpatahhebrew' : u"\uFB1F",
+ 'downtackbelowcmb' : u"\u031E",
+ 'downtackmod' : u"\u02D5",
+ 'dparen' : u"\u249F",
+ 'dsuperior' : u"\uF6EB",
+ 'dtail' : u"\u0256",
+ 'dtopbar' : u"\u018C",
+ 'duhiragana' : u"\u3065",
+ 'dukatakana' : u"\u30C5",
+ 'dz' : u"\u01F3",
+ 'dzaltone' : u"\u02A3",
+ 'dzcaron' : u"\u01C6",
+ 'dzcurl' : u"\u02A5",
+ 'dzeabkhasiancyrillic' : u"\u04E1",
+ 'dzecyrillic' : u"\u0455",
+ 'dzhecyrillic' : u"\u045F",
+ 'earth' : u"\u2641",
+ 'ebengali' : u"\u098F",
+ 'ebopomofo' : u"\u311C",
+ 'ecandradeva' : u"\u090D",
+ 'ecandragujarati' : u"\u0A8D",
+ 'ecandravowelsigndeva' : u"\u0945",
+ 'ecandravowelsigngujarati' : u"\u0AC5",
+ 'ecedillabreve' : u"\u1E1D",
+ 'echarmenian' : u"\u0565",
+ 'echyiwnarmenian' : u"\u0587",
+ 'ecircle' : u"\u24D4",
+ 'ecircumflexacute' : u"\u1EBF",
+ 'ecircumflexbelow' : u"\u1E19",
+ 'ecircumflexdotbelow' : u"\u1EC7",
+ 'ecircumflexgrave' : u"\u1EC1",
+ 'ecircumflexhookabove' : u"\u1EC3",
+ 'ecircumflextilde' : u"\u1EC5",
+ 'ecyrillic' : u"\u0454",
+ 'edblgrave' : u"\u0205",
+ 'edeva' : u"\u090F",
+ 'edot' : u"\u0117",
+ 'edotbelow' : u"\u1EB9",
+ 'eegurmukhi' : u"\u0A0F",
+ 'eematragurmukhi' : u"\u0A47",
+ 'efcyrillic' : u"\u0444",
+ 'egujarati' : u"\u0A8F",
+ 'eharmenian' : u"\u0567",
+ 'ehbopomofo' : u"\u311D",
+ 'ehiragana' : u"\u3048",
+ 'ehookabove' : u"\u1EBB",
+ 'eibopomofo' : u"\u311F",
+ 'eightarabic' : u"\u0668",
+ 'eightbengali' : u"\u09EE",
+ 'eightcircle' : u"\u2467",
+ 'eightcircleinversesansserif' : u"\u2791",
+ 'eightdeva' : u"\u096E",
+ 'eighteencircle' : u"\u2471",
+ 'eighteenparen' : u"\u2485",
+ 'eighteenperiod' : u"\u2499",
+ 'eightgujarati' : u"\u0AEE",
+ 'eightgurmukhi' : u"\u0A6E",
+ 'eighthackarabic' : u"\u0668",
+ 'eighthangzhou' : u"\u3028",
+ 'eighthnotebeamed' : u"\u266B",
+ 'eightideographicparen' : u"\u3227",
+ 'eightinferior' : u"\u2088",
+ 'eightmonospace' : u"\uFF18",
+ 'eightoldstyle' : u"\uF738",
+ 'eightparen' : u"\u247B",
+ 'eightperiod' : u"\u248F",
+ 'eightpersian' : u"\u06F8",
+ 'eightroman' : u"\u2177",
+ 'eightsuperior' : u"\u2078",
+ 'eightthai' : u"\u0E58",
+ 'einvertedbreve' : u"\u0207",
+ 'eiotifiedcyrillic' : u"\u0465",
+ 'ekatakana' : u"\u30A8",
+ 'ekatakanahalfwidth' : u"\uFF74",
+ 'ekonkargurmukhi' : u"\u0A74",
+ 'ekorean' : u"\u3154",
+ 'elcyrillic' : u"\u043B",
+ 'elevencircle' : u"\u246A",
+ 'elevenparen' : u"\u247E",
+ 'elevenperiod' : u"\u2492",
+ 'elevenroman' : u"\u217A",
+ 'ellipsisvertical' : u"\u22EE",
+ 'emacronacute' : u"\u1E17",
+ 'emacrongrave' : u"\u1E15",
+ 'emcyrillic' : u"\u043C",
+ 'emdashvertical' : u"\uFE31",
+ 'emonospace' : u"\uFF45",
+ 'emphasismarkarmenian' : u"\u055B",
+ 'enbopomofo' : u"\u3123",
+ 'encyrillic' : u"\u043D",
+ 'endashvertical' : u"\uFE32",
+ 'endescendercyrillic' : u"\u04A3",
+ 'engbopomofo' : u"\u3125",
+ 'enghecyrillic' : u"\u04A5",
+ 'enhookcyrillic' : u"\u04C8",
+ 'enspace' : u"\u2002",
+ 'eokorean' : u"\u3153",
+ 'eopen' : u"\u025B",
+ 'eopenclosed' : u"\u029A",
+ 'eopenreversed' : u"\u025C",
+ 'eopenreversedclosed' : u"\u025E",
+ 'eopenreversedhook' : u"\u025D",
+ 'eparen' : u"\u24A0",
+ 'equalmonospace' : u"\uFF1D",
+ 'equalsmall' : u"\uFE66",
+ 'equalsuperior' : u"\u207C",
+ 'erbopomofo' : u"\u3126",
+ 'ercyrillic' : u"\u0440",
+ 'ereversed' : u"\u0258",
+ 'ereversedcyrillic' : u"\u044D",
+ 'escyrillic' : u"\u0441",
+ 'esdescendercyrillic' : u"\u04AB",
+ 'esh' : u"\u0283",
+ 'eshcurl' : u"\u0286",
+ 'eshortdeva' : u"\u090E",
+ 'eshortvowelsigndeva' : u"\u0946",
+ 'eshreversedloop' : u"\u01AA",
+ 'eshsquatreversed' : u"\u0285",
+ 'esmallhiragana' : u"\u3047",
+ 'esmallkatakana' : u"\u30A7",
+ 'esmallkatakanahalfwidth' : u"\uFF6A",
+ 'esuperior' : u"\uF6EC",
+ 'etarmenian' : u"\u0568",
+ 'etilde' : u"\u1EBD",
+ 'etildebelow' : u"\u1E1B",
+ 'etnahtafoukhhebrew' : u"\u0591",
+ 'etnahtafoukhlefthebrew' : u"\u0591",
+ 'etnahtahebrew' : u"\u0591",
+ 'etnahtalefthebrew' : u"\u0591",
+ 'eturned' : u"\u01DD",
+ 'eukorean' : u"\u3161",
+ 'euro' : u"\u20AC",
+ 'evowelsignbengali' : u"\u09C7",
+ 'evowelsigndeva' : u"\u0947",
+ 'evowelsigngujarati' : u"\u0AC7",
+ 'exclamarmenian' : u"\u055C",
+ 'exclamdownsmall' : u"\uF7A1",
+ 'exclammonospace' : u"\uFF01",
+ 'exclamsmall' : u"\uF721",
+ 'ezh' : u"\u0292",
+ 'ezhcaron' : u"\u01EF",
+ 'ezhcurl' : u"\u0293",
+ 'ezhreversed' : u"\u01B9",
+ 'ezhtail' : u"\u01BA",
+ 'fadeva' : u"\u095E",
+ 'fagurmukhi' : u"\u0A5E",
+ 'fahrenheit' : u"\u2109",
+ 'fathaarabic' : u"\u064E",
+ 'fathalowarabic' : u"\u064E",
+ 'fathatanarabic' : u"\u064B",
+ 'fbopomofo' : u"\u3108",
+ 'fcircle' : u"\u24D5",
+ 'fdotaccent' : u"\u1E1F",
+ 'feharabic' : u"\u0641",
+ 'feharmenian' : u"\u0586",
+ 'fehfinalarabic' : u"\uFED2",
+ 'fehinitialarabic' : u"\uFED3",
+ 'fehmedialarabic' : u"\uFED4",
+ 'feicoptic' : u"\u03E5",
+ 'fifteencircle' : u"\u246E",
+ 'fifteenparen' : u"\u2482",
+ 'fifteenperiod' : u"\u2496",
+ 'finalkaf' : u"\u05DA",
+ 'finalkafdagesh' : u"\uFB3A",
+ 'finalkafdageshhebrew' : u"\uFB3A",
+ 'finalkafhebrew' : u"\u05DA",
+ 'finalkafqamats' : u"\u05DA\u05B8",
+ 'finalkafqamatshebrew' : u"\u05DA\u05B8",
+ 'finalkafsheva' : u"\u05DA\u05B0",
+ 'finalkafshevahebrew' : u"\u05DA\u05B0",
+ 'finalmem' : u"\u05DD",
+ 'finalmemhebrew' : u"\u05DD",
+ 'finalnun' : u"\u05DF",
+ 'finalnunhebrew' : u"\u05DF",
+ 'finalpe' : u"\u05E3",
+ 'finalpehebrew' : u"\u05E3",
+ 'finaltsadi' : u"\u05E5",
+ 'finaltsadihebrew' : u"\u05E5",
+ 'firsttonechinese' : u"\u02C9",
+ 'fisheye' : u"\u25C9",
+ 'fitacyrillic' : u"\u0473",
+ 'fivearabic' : u"\u0665",
+ 'fivebengali' : u"\u09EB",
+ 'fivecircle' : u"\u2464",
+ 'fivecircleinversesansserif' : u"\u278E",
+ 'fivedeva' : u"\u096B",
+ 'fivegujarati' : u"\u0AEB",
+ 'fivegurmukhi' : u"\u0A6B",
+ 'fivehackarabic' : u"\u0665",
+ 'fivehangzhou' : u"\u3025",
+ 'fiveideographicparen' : u"\u3224",
+ 'fiveinferior' : u"\u2085",
+ 'fivemonospace' : u"\uFF15",
+ 'fiveoldstyle' : u"\uF735",
+ 'fiveparen' : u"\u2478",
+ 'fiveperiod' : u"\u248C",
+ 'fivepersian' : u"\u06F5",
+ 'fiveroman' : u"\u2174",
+ 'fivesuperior' : u"\u2075",
+ 'fivethai' : u"\u0E55",
+ 'fmonospace' : u"\uFF46",
+ 'fmsquare' : u"\u3399",
+ 'fofanthai' : u"\u0E1F",
+ 'fofathai' : u"\u0E1D",
+ 'fongmanthai' : u"\u0E4F",
+ 'forall' : u"\u2200",
+ 'fourarabic' : u"\u0664",
+ 'fourbengali' : u"\u09EA",
+ 'fourcircle' : u"\u2463",
+ 'fourcircleinversesansserif' : u"\u278D",
+ 'fourdeva' : u"\u096A",
+ 'fourgujarati' : u"\u0AEA",
+ 'fourgurmukhi' : u"\u0A6A",
+ 'fourhackarabic' : u"\u0664",
+ 'fourhangzhou' : u"\u3024",
+ 'fourideographicparen' : u"\u3223",
+ 'fourinferior' : u"\u2084",
+ 'fourmonospace' : u"\uFF14",
+ 'fournumeratorbengali' : u"\u09F7",
+ 'fouroldstyle' : u"\uF734",
+ 'fourparen' : u"\u2477",
+ 'fourperiod' : u"\u248B",
+ 'fourpersian' : u"\u06F4",
+ 'fourroman' : u"\u2173",
+ 'foursuperior' : u"\u2074",
+ 'fourteencircle' : u"\u246D",
+ 'fourteenparen' : u"\u2481",
+ 'fourteenperiod' : u"\u2495",
+ 'fourthai' : u"\u0E54",
+ 'fourthtonechinese' : u"\u02CB",
+ 'fparen' : u"\u24A1",
+ 'gabengali' : u"\u0997",
+ 'gacute' : u"\u01F5",
+ 'gadeva' : u"\u0917",
+ 'gafarabic' : u"\u06AF",
+ 'gaffinalarabic' : u"\uFB93",
+ 'gafinitialarabic' : u"\uFB94",
+ 'gafmedialarabic' : u"\uFB95",
+ 'gagujarati' : u"\u0A97",
+ 'gagurmukhi' : u"\u0A17",
+ 'gahiragana' : u"\u304C",
+ 'gakatakana' : u"\u30AC",
+ 'gammalatinsmall' : u"\u0263",
+ 'gammasuperior' : u"\u02E0",
+ 'gangiacoptic' : u"\u03EB",
+ 'gbopomofo' : u"\u310D",
+ 'gcedilla' : u"\u0123",
+ 'gcircle' : u"\u24D6",
+ 'gdot' : u"\u0121",
+ 'gecyrillic' : u"\u0433",
+ 'gehiragana' : u"\u3052",
+ 'gekatakana' : u"\u30B2",
+ 'geometricallyequal' : u"\u2251",
+ 'gereshaccenthebrew' : u"\u059C",
+ 'gereshhebrew' : u"\u05F3",
+ 'gereshmuqdamhebrew' : u"\u059D",
+ 'gershayimaccenthebrew' : u"\u059E",
+ 'gershayimhebrew' : u"\u05F4",
+ 'getamark' : u"\u3013",
+ 'ghabengali' : u"\u0998",
+ 'ghadarmenian' : u"\u0572",
+ 'ghadeva' : u"\u0918",
+ 'ghagujarati' : u"\u0A98",
+ 'ghagurmukhi' : u"\u0A18",
+ 'ghainarabic' : u"\u063A",
+ 'ghainfinalarabic' : u"\uFECE",
+ 'ghaininitialarabic' : u"\uFECF",
+ 'ghainmedialarabic' : u"\uFED0",
+ 'ghemiddlehookcyrillic' : u"\u0495",
+ 'ghestrokecyrillic' : u"\u0493",
+ 'gheupturncyrillic' : u"\u0491",
+ 'ghhadeva' : u"\u095A",
+ 'ghhagurmukhi' : u"\u0A5A",
+ 'ghook' : u"\u0260",
+ 'ghzsquare' : u"\u3393",
+ 'gihiragana' : u"\u304E",
+ 'gikatakana' : u"\u30AE",
+ 'gimarmenian' : u"\u0563",
+ 'gimel' : u"\u05D2",
+ 'gimeldagesh' : u"\uFB32",
+ 'gimeldageshhebrew' : u"\uFB32",
+ 'gimelhebrew' : u"\u05D2",
+ 'gjecyrillic' : u"\u0453",
+ 'glottalinvertedstroke' : u"\u01BE",
+ 'glottalstop' : u"\u0294",
+ 'glottalstopinverted' : u"\u0296",
+ 'glottalstopmod' : u"\u02C0",
+ 'glottalstopreversed' : u"\u0295",
+ 'glottalstopreversedmod' : u"\u02C1",
+ 'glottalstopreversedsuperior' : u"\u02E4",
+ 'glottalstopstroke' : u"\u02A1",
+ 'glottalstopstrokereversed' : u"\u02A2",
+ 'gmacron' : u"\u1E21",
+ 'gmonospace' : u"\uFF47",
+ 'gohiragana' : u"\u3054",
+ 'gokatakana' : u"\u30B4",
+ 'gparen' : u"\u24A2",
+ 'gpasquare' : u"\u33AC",
+ 'gravebelowcmb' : u"\u0316",
+ 'gravecmb' : u"\u0300",
+ 'gravedeva' : u"\u0953",
+ 'gravelowmod' : u"\u02CE",
+ 'gravemonospace' : u"\uFF40",
+ 'gravetonecmb' : u"\u0340",
+ 'greaterequalorless' : u"\u22DB",
+ 'greatermonospace' : u"\uFF1E",
+ 'greaterorequivalent' : u"\u2273",
+ 'greaterorless' : u"\u2277",
+ 'greateroverequal' : u"\u2267",
+ 'greatersmall' : u"\uFE65",
+ 'gscript' : u"\u0261",
+ 'gstroke' : u"\u01E5",
+ 'guhiragana' : u"\u3050",
+ 'gukatakana' : u"\u30B0",
+ 'guramusquare' : u"\u3318",
+ 'gysquare' : u"\u33C9",
+ 'haabkhasiancyrillic' : u"\u04A9",
+ 'haaltonearabic' : u"\u06C1",
+ 'habengali' : u"\u09B9",
+ 'hadescendercyrillic' : u"\u04B3",
+ 'hadeva' : u"\u0939",
+ 'hagujarati' : u"\u0AB9",
+ 'hagurmukhi' : u"\u0A39",
+ 'haharabic' : u"\u062D",
+ 'hahfinalarabic' : u"\uFEA2",
+ 'hahinitialarabic' : u"\uFEA3",
+ 'hahiragana' : u"\u306F",
+ 'hahmedialarabic' : u"\uFEA4",
+ 'haitusquare' : u"\u332A",
+ 'hakatakana' : u"\u30CF",
+ 'hakatakanahalfwidth' : u"\uFF8A",
+ 'halantgurmukhi' : u"\u0A4D",
+ 'hamzaarabic' : u"\u0621",
+ 'hamzadammaarabic' : u"\u0621\u064F",
+ 'hamzadammatanarabic' : u"\u0621\u064C",
+ 'hamzafathaarabic' : u"\u0621\u064E",
+ 'hamzafathatanarabic' : u"\u0621\u064B",
+ 'hamzalowarabic' : u"\u0621",
+ 'hamzalowkasraarabic' : u"\u0621\u0650",
+ 'hamzalowkasratanarabic' : u"\u0621\u064D",
+ 'hamzasukunarabic' : u"\u0621\u0652",
+ 'hangulfiller' : u"\u3164",
+ 'hardsigncyrillic' : u"\u044A",
+ 'harpoonleftbarbup' : u"\u21BC",
+ 'harpoonrightbarbup' : u"\u21C0",
+ 'hasquare' : u"\u33CA",
+ 'hatafpatah' : u"\u05B2",
+ 'hatafpatah16' : u"\u05B2",
+ 'hatafpatah23' : u"\u05B2",
+ 'hatafpatah2f' : u"\u05B2",
+ 'hatafpatahhebrew' : u"\u05B2",
+ 'hatafpatahnarrowhebrew' : u"\u05B2",
+ 'hatafpatahquarterhebrew' : u"\u05B2",
+ 'hatafpatahwidehebrew' : u"\u05B2",
+ 'hatafqamats' : u"\u05B3",
+ 'hatafqamats1b' : u"\u05B3",
+ 'hatafqamats28' : u"\u05B3",
+ 'hatafqamats34' : u"\u05B3",
+ 'hatafqamatshebrew' : u"\u05B3",
+ 'hatafqamatsnarrowhebrew' : u"\u05B3",
+ 'hatafqamatsquarterhebrew' : u"\u05B3",
+ 'hatafqamatswidehebrew' : u"\u05B3",
+ 'hatafsegol' : u"\u05B1",
+ 'hatafsegol17' : u"\u05B1",
+ 'hatafsegol24' : u"\u05B1",
+ 'hatafsegol30' : u"\u05B1",
+ 'hatafsegolhebrew' : u"\u05B1",
+ 'hatafsegolnarrowhebrew' : u"\u05B1",
+ 'hatafsegolquarterhebrew' : u"\u05B1",
+ 'hatafsegolwidehebrew' : u"\u05B1",
+ 'hbopomofo' : u"\u310F",
+ 'hbrevebelow' : u"\u1E2B",
+ 'hcedilla' : u"\u1E29",
+ 'hcircle' : u"\u24D7",
+ 'hdieresis' : u"\u1E27",
+ 'hdotaccent' : u"\u1E23",
+ 'hdotbelow' : u"\u1E25",
+ 'he' : u"\u05D4",
+ 'heartsuitblack' : u"\u2665",
+ 'heartsuitwhite' : u"\u2661",
+ 'hedagesh' : u"\uFB34",
+ 'hedageshhebrew' : u"\uFB34",
+ 'hehaltonearabic' : u"\u06C1",
+ 'heharabic' : u"\u0647",
+ 'hehebrew' : u"\u05D4",
+ 'hehfinalaltonearabic' : u"\uFBA7",
+ 'hehfinalalttwoarabic' : u"\uFEEA",
+ 'hehfinalarabic' : u"\uFEEA",
+ 'hehhamzaabovefinalarabic' : u"\uFBA5",
+ 'hehhamzaaboveisolatedarabic' : u"\uFBA4",
+ 'hehinitialaltonearabic' : u"\uFBA8",
+ 'hehinitialarabic' : u"\uFEEB",
+ 'hehiragana' : u"\u3078",
+ 'hehmedialaltonearabic' : u"\uFBA9",
+ 'hehmedialarabic' : u"\uFEEC",
+ 'heiseierasquare' : u"\u337B",
+ 'hekatakana' : u"\u30D8",
+ 'hekatakanahalfwidth' : u"\uFF8D",
+ 'hekutaarusquare' : u"\u3336",
+ 'henghook' : u"\u0267",
+ 'herutusquare' : u"\u3339",
+ 'het' : u"\u05D7",
+ 'hethebrew' : u"\u05D7",
+ 'hhook' : u"\u0266",
+ 'hhooksuperior' : u"\u02B1",
+ 'hieuhacirclekorean' : u"\u327B",
+ 'hieuhaparenkorean' : u"\u321B",
+ 'hieuhcirclekorean' : u"\u326D",
+ 'hieuhkorean' : u"\u314E",
+ 'hieuhparenkorean' : u"\u320D",
+ 'hihiragana' : u"\u3072",
+ 'hikatakana' : u"\u30D2",
+ 'hikatakanahalfwidth' : u"\uFF8B",
+ 'hiriq' : u"\u05B4",
+ 'hiriq14' : u"\u05B4",
+ 'hiriq21' : u"\u05B4",
+ 'hiriq2d' : u"\u05B4",
+ 'hiriqhebrew' : u"\u05B4",
+ 'hiriqnarrowhebrew' : u"\u05B4",
+ 'hiriqquarterhebrew' : u"\u05B4",
+ 'hiriqwidehebrew' : u"\u05B4",
+ 'hlinebelow' : u"\u1E96",
+ 'hmonospace' : u"\uFF48",
+ 'hoarmenian' : u"\u0570",
+ 'hohipthai' : u"\u0E2B",
+ 'hohiragana' : u"\u307B",
+ 'hokatakana' : u"\u30DB",
+ 'hokatakanahalfwidth' : u"\uFF8E",
+ 'holam' : u"\u05B9",
+ 'holam19' : u"\u05B9",
+ 'holam26' : u"\u05B9",
+ 'holam32' : u"\u05B9",
+ 'holamhebrew' : u"\u05B9",
+ 'holamnarrowhebrew' : u"\u05B9",
+ 'holamquarterhebrew' : u"\u05B9",
+ 'holamwidehebrew' : u"\u05B9",
+ 'honokhukthai' : u"\u0E2E",
+ 'hookcmb' : u"\u0309",
+ 'hookpalatalizedbelowcmb' : u"\u0321",
+ 'hookretroflexbelowcmb' : u"\u0322",
+ 'hoonsquare' : u"\u3342",
+ 'horicoptic' : u"\u03E9",
+ 'horizontalbar' : u"\u2015",
+ 'horncmb' : u"\u031B",
+ 'hotsprings' : u"\u2668",
+ 'hparen' : u"\u24A3",
+ 'hsuperior' : u"\u02B0",
+ 'hturned' : u"\u0265",
+ 'huhiragana' : u"\u3075",
+ 'huiitosquare' : u"\u3333",
+ 'hukatakana' : u"\u30D5",
+ 'hukatakanahalfwidth' : u"\uFF8C",
+ 'hungarumlautcmb' : u"\u030B",
+ 'hv' : u"\u0195",
+ 'hypheninferior' : u"\uF6E5",
+ 'hyphenmonospace' : u"\uFF0D",
+ 'hyphensmall' : u"\uFE63",
+ 'hyphensuperior' : u"\uF6E6",
+ 'hyphentwo' : u"\u2010",
+ 'iacyrillic' : u"\u044F",
+ 'ibengali' : u"\u0987",
+ 'ibopomofo' : u"\u3127",
+ 'icaron' : u"\u01D0",
+ 'icircle' : u"\u24D8",
+ 'icyrillic' : u"\u0456",
+ 'idblgrave' : u"\u0209",
+ 'ideographearthcircle' : u"\u328F",
+ 'ideographfirecircle' : u"\u328B",
+ 'ideographicallianceparen' : u"\u323F",
+ 'ideographiccallparen' : u"\u323A",
+ 'ideographiccentrecircle' : u"\u32A5",
+ 'ideographicclose' : u"\u3006",
+ 'ideographiccomma' : u"\u3001",
+ 'ideographiccommaleft' : u"\uFF64",
+ 'ideographiccongratulationparen' : u"\u3237",
+ 'ideographiccorrectcircle' : u"\u32A3",
+ 'ideographicearthparen' : u"\u322F",
+ 'ideographicenterpriseparen' : u"\u323D",
+ 'ideographicexcellentcircle' : u"\u329D",
+ 'ideographicfestivalparen' : u"\u3240",
+ 'ideographicfinancialcircle' : u"\u3296",
+ 'ideographicfinancialparen' : u"\u3236",
+ 'ideographicfireparen' : u"\u322B",
+ 'ideographichaveparen' : u"\u3232",
+ 'ideographichighcircle' : u"\u32A4",
+ 'ideographiciterationmark' : u"\u3005",
+ 'ideographiclaborcircle' : u"\u3298",
+ 'ideographiclaborparen' : u"\u3238",
+ 'ideographicleftcircle' : u"\u32A7",
+ 'ideographiclowcircle' : u"\u32A6",
+ 'ideographicmedicinecircle' : u"\u32A9",
+ 'ideographicmetalparen' : u"\u322E",
+ 'ideographicmoonparen' : u"\u322A",
+ 'ideographicnameparen' : u"\u3234",
+ 'ideographicperiod' : u"\u3002",
+ 'ideographicprintcircle' : u"\u329E",
+ 'ideographicreachparen' : u"\u3243",
+ 'ideographicrepresentparen' : u"\u3239",
+ 'ideographicresourceparen' : u"\u323E",
+ 'ideographicrightcircle' : u"\u32A8",
+ 'ideographicsecretcircle' : u"\u3299",
+ 'ideographicselfparen' : u"\u3242",
+ 'ideographicsocietyparen' : u"\u3233",
+ 'ideographicspace' : u"\u3000",
+ 'ideographicspecialparen' : u"\u3235",
+ 'ideographicstockparen' : u"\u3231",
+ 'ideographicstudyparen' : u"\u323B",
+ 'ideographicsunparen' : u"\u3230",
+ 'ideographicsuperviseparen' : u"\u323C",
+ 'ideographicwaterparen' : u"\u322C",
+ 'ideographicwoodparen' : u"\u322D",
+ 'ideographiczero' : u"\u3007",
+ 'ideographmetalcircle' : u"\u328E",
+ 'ideographmooncircle' : u"\u328A",
+ 'ideographnamecircle' : u"\u3294",
+ 'ideographsuncircle' : u"\u3290",
+ 'ideographwatercircle' : u"\u328C",
+ 'ideographwoodcircle' : u"\u328D",
+ 'ideva' : u"\u0907",
+ 'idieresisacute' : u"\u1E2F",
+ 'idieresiscyrillic' : u"\u04E5",
+ 'idotbelow' : u"\u1ECB",
+ 'iebrevecyrillic' : u"\u04D7",
+ 'iecyrillic' : u"\u0435",
+ 'ieungacirclekorean' : u"\u3275",
+ 'ieungaparenkorean' : u"\u3215",
+ 'ieungcirclekorean' : u"\u3267",
+ 'ieungkorean' : u"\u3147",
+ 'ieungparenkorean' : u"\u3207",
+ 'igujarati' : u"\u0A87",
+ 'igurmukhi' : u"\u0A07",
+ 'ihiragana' : u"\u3044",
+ 'ihookabove' : u"\u1EC9",
+ 'iibengali' : u"\u0988",
+ 'iicyrillic' : u"\u0438",
+ 'iideva' : u"\u0908",
+ 'iigujarati' : u"\u0A88",
+ 'iigurmukhi' : u"\u0A08",
+ 'iimatragurmukhi' : u"\u0A40",
+ 'iinvertedbreve' : u"\u020B",
+ 'iishortcyrillic' : u"\u0439",
+ 'iivowelsignbengali' : u"\u09C0",
+ 'iivowelsigndeva' : u"\u0940",
+ 'iivowelsigngujarati' : u"\u0AC0",
+ 'ikatakana' : u"\u30A4",
+ 'ikatakanahalfwidth' : u"\uFF72",
+ 'ikorean' : u"\u3163",
+ 'ilde' : u"\u02DC",
+ 'iluyhebrew' : u"\u05AC",
+ 'imacroncyrillic' : u"\u04E3",
+ 'imageorapproximatelyequal' : u"\u2253",
+ 'imatragurmukhi' : u"\u0A3F",
+ 'imonospace' : u"\uFF49",
+ 'increment' : u"\u2206",
+ 'iniarmenian' : u"\u056B",
+ 'integralbottom' : u"\u2321",
+ 'integralex' : u"\uF8F5",
+ 'integraltop' : u"\u2320",
+ 'intisquare' : u"\u3305",
+ 'iocyrillic' : u"\u0451",
+ 'iotalatin' : u"\u0269",
+ 'iparen' : u"\u24A4",
+ 'irigurmukhi' : u"\u0A72",
+ 'ismallhiragana' : u"\u3043",
+ 'ismallkatakana' : u"\u30A3",
+ 'ismallkatakanahalfwidth' : u"\uFF68",
+ 'issharbengali' : u"\u09FA",
+ 'istroke' : u"\u0268",
+ 'isuperior' : u"\uF6ED",
+ 'iterationhiragana' : u"\u309D",
+ 'iterationkatakana' : u"\u30FD",
+ 'itildebelow' : u"\u1E2D",
+ 'iubopomofo' : u"\u3129",
+ 'iucyrillic' : u"\u044E",
+ 'ivowelsignbengali' : u"\u09BF",
+ 'ivowelsigndeva' : u"\u093F",
+ 'ivowelsigngujarati' : u"\u0ABF",
+ 'izhitsacyrillic' : u"\u0475",
+ 'izhitsadblgravecyrillic' : u"\u0477",
+ 'jaarmenian' : u"\u0571",
+ 'jabengali' : u"\u099C",
+ 'jadeva' : u"\u091C",
+ 'jagujarati' : u"\u0A9C",
+ 'jagurmukhi' : u"\u0A1C",
+ 'jbopomofo' : u"\u3110",
+ 'jcaron' : u"\u01F0",
+ 'jcircle' : u"\u24D9",
+ 'jcrossedtail' : u"\u029D",
+ 'jdotlessstroke' : u"\u025F",
+ 'jecyrillic' : u"\u0458",
+ 'jeemarabic' : u"\u062C",
+ 'jeemfinalarabic' : u"\uFE9E",
+ 'jeeminitialarabic' : u"\uFE9F",
+ 'jeemmedialarabic' : u"\uFEA0",
+ 'jeharabic' : u"\u0698",
+ 'jehfinalarabic' : u"\uFB8B",
+ 'jhabengali' : u"\u099D",
+ 'jhadeva' : u"\u091D",
+ 'jhagujarati' : u"\u0A9D",
+ 'jhagurmukhi' : u"\u0A1D",
+ 'jheharmenian' : u"\u057B",
+ 'jis' : u"\u3004",
+ 'jmonospace' : u"\uFF4A",
+ 'jparen' : u"\u24A5",
+ 'jsuperior' : u"\u02B2",
+ 'kabashkircyrillic' : u"\u04A1",
+ 'kabengali' : u"\u0995",
+ 'kacute' : u"\u1E31",
+ 'kacyrillic' : u"\u043A",
+ 'kadescendercyrillic' : u"\u049B",
+ 'kadeva' : u"\u0915",
+ 'kaf' : u"\u05DB",
+ 'kafarabic' : u"\u0643",
+ 'kafdagesh' : u"\uFB3B",
+ 'kafdageshhebrew' : u"\uFB3B",
+ 'kaffinalarabic' : u"\uFEDA",
+ 'kafhebrew' : u"\u05DB",
+ 'kafinitialarabic' : u"\uFEDB",
+ 'kafmedialarabic' : u"\uFEDC",
+ 'kafrafehebrew' : u"\uFB4D",
+ 'kagujarati' : u"\u0A95",
+ 'kagurmukhi' : u"\u0A15",
+ 'kahiragana' : u"\u304B",
+ 'kahookcyrillic' : u"\u04C4",
+ 'kakatakana' : u"\u30AB",
+ 'kakatakanahalfwidth' : u"\uFF76",
+ 'kappasymbolgreek' : u"\u03F0",
+ 'kapyeounmieumkorean' : u"\u3171",
+ 'kapyeounphieuphkorean' : u"\u3184",
+ 'kapyeounpieupkorean' : u"\u3178",
+ 'kapyeounssangpieupkorean' : u"\u3179",
+ 'karoriisquare' : u"\u330D",
+ 'kashidaautoarabic' : u"\u0640",
+ 'kashidaautonosidebearingarabic' : u"\u0640",
+ 'kasmallkatakana' : u"\u30F5",
+ 'kasquare' : u"\u3384",
+ 'kasraarabic' : u"\u0650",
+ 'kasratanarabic' : u"\u064D",
+ 'kastrokecyrillic' : u"\u049F",
+ 'katahiraprolongmarkhalfwidth' : u"\uFF70",
+ 'kaverticalstrokecyrillic' : u"\u049D",
+ 'kbopomofo' : u"\u310E",
+ 'kcalsquare' : u"\u3389",
+ 'kcaron' : u"\u01E9",
+ 'kcedilla' : u"\u0137",
+ 'kcircle' : u"\u24DA",
+ 'kdotbelow' : u"\u1E33",
+ 'keharmenian' : u"\u0584",
+ 'kehiragana' : u"\u3051",
+ 'kekatakana' : u"\u30B1",
+ 'kekatakanahalfwidth' : u"\uFF79",
+ 'kenarmenian' : u"\u056F",
+ 'kesmallkatakana' : u"\u30F6",
+ 'khabengali' : u"\u0996",
+ 'khacyrillic' : u"\u0445",
+ 'khadeva' : u"\u0916",
+ 'khagujarati' : u"\u0A96",
+ 'khagurmukhi' : u"\u0A16",
+ 'khaharabic' : u"\u062E",
+ 'khahfinalarabic' : u"\uFEA6",
+ 'khahinitialarabic' : u"\uFEA7",
+ 'khahmedialarabic' : u"\uFEA8",
+ 'kheicoptic' : u"\u03E7",
+ 'khhadeva' : u"\u0959",
+ 'khhagurmukhi' : u"\u0A59",
+ 'khieukhacirclekorean' : u"\u3278",
+ 'khieukhaparenkorean' : u"\u3218",
+ 'khieukhcirclekorean' : u"\u326A",
+ 'khieukhkorean' : u"\u314B",
+ 'khieukhparenkorean' : u"\u320A",
+ 'khokhaithai' : u"\u0E02",
+ 'khokhonthai' : u"\u0E05",
+ 'khokhuatthai' : u"\u0E03",
+ 'khokhwaithai' : u"\u0E04",
+ 'khomutthai' : u"\u0E5B",
+ 'khook' : u"\u0199",
+ 'khorakhangthai' : u"\u0E06",
+ 'khzsquare' : u"\u3391",
+ 'kihiragana' : u"\u304D",
+ 'kikatakana' : u"\u30AD",
+ 'kikatakanahalfwidth' : u"\uFF77",
+ 'kiroguramusquare' : u"\u3315",
+ 'kiromeetorusquare' : u"\u3316",
+ 'kirosquare' : u"\u3314",
+ 'kiyeokacirclekorean' : u"\u326E",
+ 'kiyeokaparenkorean' : u"\u320E",
+ 'kiyeokcirclekorean' : u"\u3260",
+ 'kiyeokkorean' : u"\u3131",
+ 'kiyeokparenkorean' : u"\u3200",
+ 'kiyeoksioskorean' : u"\u3133",
+ 'kjecyrillic' : u"\u045C",
+ 'klinebelow' : u"\u1E35",
+ 'klsquare' : u"\u3398",
+ 'kmcubedsquare' : u"\u33A6",
+ 'kmonospace' : u"\uFF4B",
+ 'kmsquaredsquare' : u"\u33A2",
+ 'kohiragana' : u"\u3053",
+ 'kohmsquare' : u"\u33C0",
+ 'kokaithai' : u"\u0E01",
+ 'kokatakana' : u"\u30B3",
+ 'kokatakanahalfwidth' : u"\uFF7A",
+ 'kooposquare' : u"\u331E",
+ 'koppacyrillic' : u"\u0481",
+ 'koreanstandardsymbol' : u"\u327F",
+ 'koroniscmb' : u"\u0343",
+ 'kparen' : u"\u24A6",
+ 'kpasquare' : u"\u33AA",
+ 'ksicyrillic' : u"\u046F",
+ 'ktsquare' : u"\u33CF",
+ 'kturned' : u"\u029E",
+ 'kuhiragana' : u"\u304F",
+ 'kukatakana' : u"\u30AF",
+ 'kukatakanahalfwidth' : u"\uFF78",
+ 'kvsquare' : u"\u33B8",
+ 'kwsquare' : u"\u33BE",
+ 'labengali' : u"\u09B2",
+ 'ladeva' : u"\u0932",
+ 'lagujarati' : u"\u0AB2",
+ 'lagurmukhi' : u"\u0A32",
+ 'lakkhangyaothai' : u"\u0E45",
+ 'lamaleffinalarabic' : u"\uFEFC",
+ 'lamalefhamzaabovefinalarabic' : u"\uFEF8",
+ 'lamalefhamzaaboveisolatedarabic' : u"\uFEF7",
+ 'lamalefhamzabelowfinalarabic' : u"\uFEFA",
+ 'lamalefhamzabelowisolatedarabic' : u"\uFEF9",
+ 'lamalefisolatedarabic' : u"\uFEFB",
+ 'lamalefmaddaabovefinalarabic' : u"\uFEF6",
+ 'lamalefmaddaaboveisolatedarabic' : u"\uFEF5",
+ 'lamarabic' : u"\u0644",
+ 'lambdastroke' : u"\u019B",
+ 'lamed' : u"\u05DC",
+ 'lameddagesh' : u"\uFB3C",
+ 'lameddageshhebrew' : u"\uFB3C",
+ 'lamedhebrew' : u"\u05DC",
+ 'lamedholam' : u"\u05DC\u05B9",
+ 'lamedholamdagesh' : u"\u05DC\u05B9\u05BC",
+ 'lamedholamdageshhebrew' : u"\u05DC\u05B9\u05BC",
+ 'lamedholamhebrew' : u"\u05DC\u05B9",
+ 'lamfinalarabic' : u"\uFEDE",
+ 'lamhahinitialarabic' : u"\uFCCA",
+ 'laminitialarabic' : u"\uFEDF",
+ 'lamjeeminitialarabic' : u"\uFCC9",
+ 'lamkhahinitialarabic' : u"\uFCCB",
+ 'lamlamhehisolatedarabic' : u"\uFDF2",
+ 'lammedialarabic' : u"\uFEE0",
+ 'lammeemhahinitialarabic' : u"\uFD88",
+ 'lammeeminitialarabic' : u"\uFCCC",
+ 'lammeemjeeminitialarabic' : u"\uFEDF\uFEE4\uFEA0",
+ 'lammeemkhahinitialarabic' : u"\uFEDF\uFEE4\uFEA8",
+ 'largecircle' : u"\u25EF",
+ 'lbar' : u"\u019A",
+ 'lbelt' : u"\u026C",
+ 'lbopomofo' : u"\u310C",
+ 'lcedilla' : u"\u013C",
+ 'lcircle' : u"\u24DB",
+ 'lcircumflexbelow' : u"\u1E3D",
+ 'ldotaccent' : u"\u0140",
+ 'ldotbelow' : u"\u1E37",
+ 'ldotbelowmacron' : u"\u1E39",
+ 'leftangleabovecmb' : u"\u031A",
+ 'lefttackbelowcmb' : u"\u0318",
+ 'lessequalorgreater' : u"\u22DA",
+ 'lessmonospace' : u"\uFF1C",
+ 'lessorequivalent' : u"\u2272",
+ 'lessorgreater' : u"\u2276",
+ 'lessoverequal' : u"\u2266",
+ 'lesssmall' : u"\uFE64",
+ 'lezh' : u"\u026E",
+ 'lhookretroflex' : u"\u026D",
+ 'liwnarmenian' : u"\u056C",
+ 'lj' : u"\u01C9",
+ 'ljecyrillic' : u"\u0459",
+ 'll' : u"\uF6C0",
+ 'lladeva' : u"\u0933",
+ 'llagujarati' : u"\u0AB3",
+ 'llinebelow' : u"\u1E3B",
+ 'llladeva' : u"\u0934",
+ 'llvocalicbengali' : u"\u09E1",
+ 'llvocalicdeva' : u"\u0961",
+ 'llvocalicvowelsignbengali' : u"\u09E3",
+ 'llvocalicvowelsigndeva' : u"\u0963",
+ 'lmiddletilde' : u"\u026B",
+ 'lmonospace' : u"\uFF4C",
+ 'lmsquare' : u"\u33D0",
+ 'lochulathai' : u"\u0E2C",
+ 'logicalnotreversed' : u"\u2310",
+ 'lolingthai' : u"\u0E25",
+ 'lowlinecenterline' : u"\uFE4E",
+ 'lowlinecmb' : u"\u0332",
+ 'lowlinedashed' : u"\uFE4D",
+ 'lparen' : u"\u24A7",
+ 'lsquare' : u"\u2113",
+ 'lsuperior' : u"\uF6EE",
+ 'luthai' : u"\u0E26",
+ 'lvocalicbengali' : u"\u098C",
+ 'lvocalicdeva' : u"\u090C",
+ 'lvocalicvowelsignbengali' : u"\u09E2",
+ 'lvocalicvowelsigndeva' : u"\u0962",
+ 'lxsquare' : u"\u33D3",
+ 'mabengali' : u"\u09AE",
+ 'macronbelowcmb' : u"\u0331",
+ 'macroncmb' : u"\u0304",
+ 'macronlowmod' : u"\u02CD",
+ 'macronmonospace' : u"\uFFE3",
+ 'macute' : u"\u1E3F",
+ 'madeva' : u"\u092E",
+ 'magujarati' : u"\u0AAE",
+ 'magurmukhi' : u"\u0A2E",
+ 'mahapakhhebrew' : u"\u05A4",
+ 'mahapakhlefthebrew' : u"\u05A4",
+ 'mahiragana' : u"\u307E",
+ 'maichattawalowleftthai' : u"\uF895",
+ 'maichattawalowrightthai' : u"\uF894",
+ 'maichattawathai' : u"\u0E4B",
+ 'maichattawaupperleftthai' : u"\uF893",
+ 'maieklowleftthai' : u"\uF88C",
+ 'maieklowrightthai' : u"\uF88B",
+ 'maiekthai' : u"\u0E48",
+ 'maiekupperleftthai' : u"\uF88A",
+ 'maihanakatleftthai' : u"\uF884",
+ 'maihanakatthai' : u"\u0E31",
+ 'maitaikhuleftthai' : u"\uF889",
+ 'maitaikhuthai' : u"\u0E47",
+ 'maitholowleftthai' : u"\uF88F",
+ 'maitholowrightthai' : u"\uF88E",
+ 'maithothai' : u"\u0E49",
+ 'maithoupperleftthai' : u"\uF88D",
+ 'maitrilowleftthai' : u"\uF892",
+ 'maitrilowrightthai' : u"\uF891",
+ 'maitrithai' : u"\u0E4A",
+ 'maitriupperleftthai' : u"\uF890",
+ 'maiyamokthai' : u"\u0E46",
+ 'makatakana' : u"\u30DE",
+ 'makatakanahalfwidth' : u"\uFF8F",
+ 'mansyonsquare' : u"\u3347",
+ 'maqafhebrew' : u"\u05BE",
+ 'mars' : u"\u2642",
+ 'masoracirclehebrew' : u"\u05AF",
+ 'masquare' : u"\u3383",
+ 'mbopomofo' : u"\u3107",
+ 'mbsquare' : u"\u33D4",
+ 'mcircle' : u"\u24DC",
+ 'mcubedsquare' : u"\u33A5",
+ 'mdotaccent' : u"\u1E41",
+ 'mdotbelow' : u"\u1E43",
+ 'meemarabic' : u"\u0645",
+ 'meemfinalarabic' : u"\uFEE2",
+ 'meeminitialarabic' : u"\uFEE3",
+ 'meemmedialarabic' : u"\uFEE4",
+ 'meemmeeminitialarabic' : u"\uFCD1",
+ 'meemmeemisolatedarabic' : u"\uFC48",
+ 'meetorusquare' : u"\u334D",
+ 'mehiragana' : u"\u3081",
+ 'meizierasquare' : u"\u337E",
+ 'mekatakana' : u"\u30E1",
+ 'mekatakanahalfwidth' : u"\uFF92",
+ 'mem' : u"\u05DE",
+ 'memdagesh' : u"\uFB3E",
+ 'memdageshhebrew' : u"\uFB3E",
+ 'memhebrew' : u"\u05DE",
+ 'menarmenian' : u"\u0574",
+ 'merkhahebrew' : u"\u05A5",
+ 'merkhakefulahebrew' : u"\u05A6",
+ 'merkhakefulalefthebrew' : u"\u05A6",
+ 'merkhalefthebrew' : u"\u05A5",
+ 'mhook' : u"\u0271",
+ 'mhzsquare' : u"\u3392",
+ 'middledotkatakanahalfwidth' : u"\uFF65",
+ 'middot' : u"\u00B7",
+ 'mieumacirclekorean' : u"\u3272",
+ 'mieumaparenkorean' : u"\u3212",
+ 'mieumcirclekorean' : u"\u3264",
+ 'mieumkorean' : u"\u3141",
+ 'mieumpansioskorean' : u"\u3170",
+ 'mieumparenkorean' : u"\u3204",
+ 'mieumpieupkorean' : u"\u316E",
+ 'mieumsioskorean' : u"\u316F",
+ 'mihiragana' : u"\u307F",
+ 'mikatakana' : u"\u30DF",
+ 'mikatakanahalfwidth' : u"\uFF90",
+ 'minusbelowcmb' : u"\u0320",
+ 'minuscircle' : u"\u2296",
+ 'minusmod' : u"\u02D7",
+ 'minusplus' : u"\u2213",
+ 'miribaarusquare' : u"\u334A",
+ 'mirisquare' : u"\u3349",
+ 'mlonglegturned' : u"\u0270",
+ 'mlsquare' : u"\u3396",
+ 'mmcubedsquare' : u"\u33A3",
+ 'mmonospace' : u"\uFF4D",
+ 'mmsquaredsquare' : u"\u339F",
+ 'mohiragana' : u"\u3082",
+ 'mohmsquare' : u"\u33C1",
+ 'mokatakana' : u"\u30E2",
+ 'mokatakanahalfwidth' : u"\uFF93",
+ 'molsquare' : u"\u33D6",
+ 'momathai' : u"\u0E21",
+ 'moverssquare' : u"\u33A7",
+ 'moverssquaredsquare' : u"\u33A8",
+ 'mparen' : u"\u24A8",
+ 'mpasquare' : u"\u33AB",
+ 'mssquare' : u"\u33B3",
+ 'msuperior' : u"\uF6EF",
+ 'mturned' : u"\u026F",
+ 'mu1' : u"\u00B5",
+ 'muasquare' : u"\u3382",
+ 'muchgreater' : u"\u226B",
+ 'muchless' : u"\u226A",
+ 'mufsquare' : u"\u338C",
+ 'mugreek' : u"\u03BC",
+ 'mugsquare' : u"\u338D",
+ 'muhiragana' : u"\u3080",
+ 'mukatakana' : u"\u30E0",
+ 'mukatakanahalfwidth' : u"\uFF91",
+ 'mulsquare' : u"\u3395",
+ 'mumsquare' : u"\u339B",
+ 'munahhebrew' : u"\u05A3",
+ 'munahlefthebrew' : u"\u05A3",
+ 'musicflatsign' : u"\u266D",
+ 'musicsharpsign' : u"\u266F",
+ 'mussquare' : u"\u33B2",
+ 'muvsquare' : u"\u33B6",
+ 'muwsquare' : u"\u33BC",
+ 'mvmegasquare' : u"\u33B9",
+ 'mvsquare' : u"\u33B7",
+ 'mwmegasquare' : u"\u33BF",
+ 'mwsquare' : u"\u33BD",
+ 'nabengali' : u"\u09A8",
+ 'nabla' : u"\u2207",
+ 'nadeva' : u"\u0928",
+ 'nagujarati' : u"\u0AA8",
+ 'nagurmukhi' : u"\u0A28",
+ 'nahiragana' : u"\u306A",
+ 'nakatakana' : u"\u30CA",
+ 'nakatakanahalfwidth' : u"\uFF85",
+ 'nasquare' : u"\u3381",
+ 'nbopomofo' : u"\u310B",
+ 'nbspace' : u"\u00A0",
+ 'ncedilla' : u"\u0146",
+ 'ncircle' : u"\u24DD",
+ 'ncircumflexbelow' : u"\u1E4B",
+ 'ndotaccent' : u"\u1E45",
+ 'ndotbelow' : u"\u1E47",
+ 'nehiragana' : u"\u306D",
+ 'nekatakana' : u"\u30CD",
+ 'nekatakanahalfwidth' : u"\uFF88",
+ 'newsheqelsign' : u"\u20AA",
+ 'nfsquare' : u"\u338B",
+ 'ngabengali' : u"\u0999",
+ 'ngadeva' : u"\u0919",
+ 'ngagujarati' : u"\u0A99",
+ 'ngagurmukhi' : u"\u0A19",
+ 'ngonguthai' : u"\u0E07",
+ 'nhiragana' : u"\u3093",
+ 'nhookleft' : u"\u0272",
+ 'nhookretroflex' : u"\u0273",
+ 'nieunacirclekorean' : u"\u326F",
+ 'nieunaparenkorean' : u"\u320F",
+ 'nieuncieuckorean' : u"\u3135",
+ 'nieuncirclekorean' : u"\u3261",
+ 'nieunhieuhkorean' : u"\u3136",
+ 'nieunkorean' : u"\u3134",
+ 'nieunpansioskorean' : u"\u3168",
+ 'nieunparenkorean' : u"\u3201",
+ 'nieunsioskorean' : u"\u3167",
+ 'nieuntikeutkorean' : u"\u3166",
+ 'nihiragana' : u"\u306B",
+ 'nikatakana' : u"\u30CB",
+ 'nikatakanahalfwidth' : u"\uFF86",
+ 'nikhahitleftthai' : u"\uF899",
+ 'nikhahitthai' : u"\u0E4D",
+ 'ninearabic' : u"\u0669",
+ 'ninebengali' : u"\u09EF",
+ 'ninecircle' : u"\u2468",
+ 'ninecircleinversesansserif' : u"\u2792",
+ 'ninedeva' : u"\u096F",
+ 'ninegujarati' : u"\u0AEF",
+ 'ninegurmukhi' : u"\u0A6F",
+ 'ninehackarabic' : u"\u0669",
+ 'ninehangzhou' : u"\u3029",
+ 'nineideographicparen' : u"\u3228",
+ 'nineinferior' : u"\u2089",
+ 'ninemonospace' : u"\uFF19",
+ 'nineoldstyle' : u"\uF739",
+ 'nineparen' : u"\u247C",
+ 'nineperiod' : u"\u2490",
+ 'ninepersian' : u"\u06F9",
+ 'nineroman' : u"\u2178",
+ 'ninesuperior' : u"\u2079",
+ 'nineteencircle' : u"\u2472",
+ 'nineteenparen' : u"\u2486",
+ 'nineteenperiod' : u"\u249A",
+ 'ninethai' : u"\u0E59",
+ 'nj' : u"\u01CC",
+ 'njecyrillic' : u"\u045A",
+ 'nkatakana' : u"\u30F3",
+ 'nkatakanahalfwidth' : u"\uFF9D",
+ 'nlegrightlong' : u"\u019E",
+ 'nlinebelow' : u"\u1E49",
+ 'nmonospace' : u"\uFF4E",
+ 'nmsquare' : u"\u339A",
+ 'nnabengali' : u"\u09A3",
+ 'nnadeva' : u"\u0923",
+ 'nnagujarati' : u"\u0AA3",
+ 'nnagurmukhi' : u"\u0A23",
+ 'nnnadeva' : u"\u0929",
+ 'nohiragana' : u"\u306E",
+ 'nokatakana' : u"\u30CE",
+ 'nokatakanahalfwidth' : u"\uFF89",
+ 'nonbreakingspace' : u"\u00A0",
+ 'nonenthai' : u"\u0E13",
+ 'nonuthai' : u"\u0E19",
+ 'noonarabic' : u"\u0646",
+ 'noonfinalarabic' : u"\uFEE6",
+ 'noonghunnaarabic' : u"\u06BA",
+ 'noonghunnafinalarabic' : u"\uFB9F",
+ 'noonhehinitialarabic' : u"\uFEE7\uFEEC",
+ 'nooninitialarabic' : u"\uFEE7",
+ 'noonjeeminitialarabic' : u"\uFCD2",
+ 'noonjeemisolatedarabic' : u"\uFC4B",
+ 'noonmedialarabic' : u"\uFEE8",
+ 'noonmeeminitialarabic' : u"\uFCD5",
+ 'noonmeemisolatedarabic' : u"\uFC4E",
+ 'noonnoonfinalarabic' : u"\uFC8D",
+ 'notcontains' : u"\u220C",
+ 'notelementof' : u"\u2209",
+ 'notgreater' : u"\u226F",
+ 'notgreaternorequal' : u"\u2271",
+ 'notgreaternorless' : u"\u2279",
+ 'notidentical' : u"\u2262",
+ 'notless' : u"\u226E",
+ 'notlessnorequal' : u"\u2270",
+ 'notparallel' : u"\u2226",
+ 'notprecedes' : u"\u2280",
+ 'notsucceeds' : u"\u2281",
+ 'notsuperset' : u"\u2285",
+ 'nowarmenian' : u"\u0576",
+ 'nparen' : u"\u24A9",
+ 'nssquare' : u"\u33B1",
+ 'nsuperior' : u"\u207F",
+ 'nuhiragana' : u"\u306C",
+ 'nukatakana' : u"\u30CC",
+ 'nukatakanahalfwidth' : u"\uFF87",
+ 'nuktabengali' : u"\u09BC",
+ 'nuktadeva' : u"\u093C",
+ 'nuktagujarati' : u"\u0ABC",
+ 'nuktagurmukhi' : u"\u0A3C",
+ 'numbersignmonospace' : u"\uFF03",
+ 'numbersignsmall' : u"\uFE5F",
+ 'numeralsigngreek' : u"\u0374",
+ 'numeralsignlowergreek' : u"\u0375",
+ 'numero' : u"\u2116",
+ 'nun' : u"\u05E0",
+ 'nundagesh' : u"\uFB40",
+ 'nundageshhebrew' : u"\uFB40",
+ 'nunhebrew' : u"\u05E0",
+ 'nvsquare' : u"\u33B5",
+ 'nwsquare' : u"\u33BB",
+ 'nyabengali' : u"\u099E",
+ 'nyadeva' : u"\u091E",
+ 'nyagujarati' : u"\u0A9E",
+ 'nyagurmukhi' : u"\u0A1E",
+ 'oangthai' : u"\u0E2D",
+ 'obarred' : u"\u0275",
+ 'obarredcyrillic' : u"\u04E9",
+ 'obarreddieresiscyrillic' : u"\u04EB",
+ 'obengali' : u"\u0993",
+ 'obopomofo' : u"\u311B",
+ 'ocandradeva' : u"\u0911",
+ 'ocandragujarati' : u"\u0A91",
+ 'ocandravowelsigndeva' : u"\u0949",
+ 'ocandravowelsigngujarati' : u"\u0AC9",
+ 'ocaron' : u"\u01D2",
+ 'ocircle' : u"\u24DE",
+ 'ocircumflexacute' : u"\u1ED1",
+ 'ocircumflexdotbelow' : u"\u1ED9",
+ 'ocircumflexgrave' : u"\u1ED3",
+ 'ocircumflexhookabove' : u"\u1ED5",
+ 'ocircumflextilde' : u"\u1ED7",
+ 'ocyrillic' : u"\u043E",
+ 'odblacute' : u"\u0151",
+ 'odblgrave' : u"\u020D",
+ 'odeva' : u"\u0913",
+ 'odieresiscyrillic' : u"\u04E7",
+ 'odotbelow' : u"\u1ECD",
+ 'oekorean' : u"\u315A",
+ 'ogonekcmb' : u"\u0328",
+ 'ogujarati' : u"\u0A93",
+ 'oharmenian' : u"\u0585",
+ 'ohiragana' : u"\u304A",
+ 'ohookabove' : u"\u1ECF",
+ 'ohornacute' : u"\u1EDB",
+ 'ohorndotbelow' : u"\u1EE3",
+ 'ohorngrave' : u"\u1EDD",
+ 'ohornhookabove' : u"\u1EDF",
+ 'ohorntilde' : u"\u1EE1",
+ 'oi' : u"\u01A3",
+ 'oinvertedbreve' : u"\u020F",
+ 'okatakana' : u"\u30AA",
+ 'okatakanahalfwidth' : u"\uFF75",
+ 'okorean' : u"\u3157",
+ 'olehebrew' : u"\u05AB",
+ 'omacronacute' : u"\u1E53",
+ 'omacrongrave' : u"\u1E51",
+ 'omdeva' : u"\u0950",
+ 'omegacyrillic' : u"\u0461",
+ 'omegalatinclosed' : u"\u0277",
+ 'omegaroundcyrillic' : u"\u047B",
+ 'omegatitlocyrillic' : u"\u047D",
+ 'omgujarati' : u"\u0AD0",
+ 'omonospace' : u"\uFF4F",
+ 'onearabic' : u"\u0661",
+ 'onebengali' : u"\u09E7",
+ 'onecircle' : u"\u2460",
+ 'onecircleinversesansserif' : u"\u278A",
+ 'onedeva' : u"\u0967",
+ 'onefitted' : u"\uF6DC",
+ 'onegujarati' : u"\u0AE7",
+ 'onegurmukhi' : u"\u0A67",
+ 'onehackarabic' : u"\u0661",
+ 'onehangzhou' : u"\u3021",
+ 'oneideographicparen' : u"\u3220",
+ 'oneinferior' : u"\u2081",
+ 'onemonospace' : u"\uFF11",
+ 'onenumeratorbengali' : u"\u09F4",
+ 'oneoldstyle' : u"\uF731",
+ 'oneparen' : u"\u2474",
+ 'oneperiod' : u"\u2488",
+ 'onepersian' : u"\u06F1",
+ 'oneroman' : u"\u2170",
+ 'onethai' : u"\u0E51",
+ 'oogonek' : u"\u01EB",
+ 'oogonekmacron' : u"\u01ED",
+ 'oogurmukhi' : u"\u0A13",
+ 'oomatragurmukhi' : u"\u0A4B",
+ 'oopen' : u"\u0254",
+ 'oparen' : u"\u24AA",
+ 'option' : u"\u2325",
+ 'oshortdeva' : u"\u0912",
+ 'oshortvowelsigndeva' : u"\u094A",
+ 'osmallhiragana' : u"\u3049",
+ 'osmallkatakana' : u"\u30A9",
+ 'osmallkatakanahalfwidth' : u"\uFF6B",
+ 'ostrokeacute' : u"\u01FF",
+ 'osuperior' : u"\uF6F0",
+ 'otcyrillic' : u"\u047F",
+ 'otildeacute' : u"\u1E4D",
+ 'otildedieresis' : u"\u1E4F",
+ 'oubopomofo' : u"\u3121",
+ 'overline' : u"\u203E",
+ 'overlinecenterline' : u"\uFE4A",
+ 'overlinecmb' : u"\u0305",
+ 'overlinedashed' : u"\uFE49",
+ 'overlinedblwavy' : u"\uFE4C",
+ 'overlinewavy' : u"\uFE4B",
+ 'overscore' : u"\u00AF",
+ 'ovowelsignbengali' : u"\u09CB",
+ 'ovowelsigndeva' : u"\u094B",
+ 'ovowelsigngujarati' : u"\u0ACB",
+ 'paampssquare' : u"\u3380",
+ 'paasentosquare' : u"\u332B",
+ 'pabengali' : u"\u09AA",
+ 'pacute' : u"\u1E55",
+ 'padeva' : u"\u092A",
+ 'pagedown' : u"\u21DF",
+ 'pageup' : u"\u21DE",
+ 'pagujarati' : u"\u0AAA",
+ 'pagurmukhi' : u"\u0A2A",
+ 'pahiragana' : u"\u3071",
+ 'paiyannoithai' : u"\u0E2F",
+ 'pakatakana' : u"\u30D1",
+ 'palatalizationcyrilliccmb' : u"\u0484",
+ 'palochkacyrillic' : u"\u04C0",
+ 'pansioskorean' : u"\u317F",
+ 'parallel' : u"\u2225",
+ 'parenleftaltonearabic' : u"\uFD3E",
+ 'parenleftbt' : u"\uF8ED",
+ 'parenleftex' : u"\uF8EC",
+ 'parenleftinferior' : u"\u208D",
+ 'parenleftmonospace' : u"\uFF08",
+ 'parenleftsmall' : u"\uFE59",
+ 'parenleftsuperior' : u"\u207D",
+ 'parenlefttp' : u"\uF8EB",
+ 'parenleftvertical' : u"\uFE35",
+ 'parenrightaltonearabic' : u"\uFD3F",
+ 'parenrightbt' : u"\uF8F8",
+ 'parenrightex' : u"\uF8F7",
+ 'parenrightinferior' : u"\u208E",
+ 'parenrightmonospace' : u"\uFF09",
+ 'parenrightsmall' : u"\uFE5A",
+ 'parenrightsuperior' : u"\u207E",
+ 'parenrighttp' : u"\uF8F6",
+ 'parenrightvertical' : u"\uFE36",
+ 'paseqhebrew' : u"\u05C0",
+ 'pashtahebrew' : u"\u0599",
+ 'pasquare' : u"\u33A9",
+ 'patah' : u"\u05B7",
+ 'patah11' : u"\u05B7",
+ 'patah1d' : u"\u05B7",
+ 'patah2a' : u"\u05B7",
+ 'patahhebrew' : u"\u05B7",
+ 'patahnarrowhebrew' : u"\u05B7",
+ 'patahquarterhebrew' : u"\u05B7",
+ 'patahwidehebrew' : u"\u05B7",
+ 'pazerhebrew' : u"\u05A1",
+ 'pbopomofo' : u"\u3106",
+ 'pcircle' : u"\u24DF",
+ 'pdotaccent' : u"\u1E57",
+ 'pe' : u"\u05E4",
+ 'pecyrillic' : u"\u043F",
+ 'pedagesh' : u"\uFB44",
+ 'pedageshhebrew' : u"\uFB44",
+ 'peezisquare' : u"\u333B",
+ 'pefinaldageshhebrew' : u"\uFB43",
+ 'peharabic' : u"\u067E",
+ 'peharmenian' : u"\u057A",
+ 'pehebrew' : u"\u05E4",
+ 'pehfinalarabic' : u"\uFB57",
+ 'pehinitialarabic' : u"\uFB58",
+ 'pehiragana' : u"\u307A",
+ 'pehmedialarabic' : u"\uFB59",
+ 'pekatakana' : u"\u30DA",
+ 'pemiddlehookcyrillic' : u"\u04A7",
+ 'perafehebrew' : u"\uFB4E",
+ 'percentarabic' : u"\u066A",
+ 'percentmonospace' : u"\uFF05",
+ 'percentsmall' : u"\uFE6A",
+ 'periodarmenian' : u"\u0589",
+ 'periodhalfwidth' : u"\uFF61",
+ 'periodinferior' : u"\uF6E7",
+ 'periodmonospace' : u"\uFF0E",
+ 'periodsmall' : u"\uFE52",
+ 'periodsuperior' : u"\uF6E8",
+ 'perispomenigreekcmb' : u"\u0342",
+ 'pfsquare' : u"\u338A",
+ 'phabengali' : u"\u09AB",
+ 'phadeva' : u"\u092B",
+ 'phagujarati' : u"\u0AAB",
+ 'phagurmukhi' : u"\u0A2B",
+ 'phieuphacirclekorean' : u"\u327A",
+ 'phieuphaparenkorean' : u"\u321A",
+ 'phieuphcirclekorean' : u"\u326C",
+ 'phieuphkorean' : u"\u314D",
+ 'phieuphparenkorean' : u"\u320C",
+ 'philatin' : u"\u0278",
+ 'phinthuthai' : u"\u0E3A",
+ 'phisymbolgreek' : u"\u03D5",
+ 'phook' : u"\u01A5",
+ 'phophanthai' : u"\u0E1E",
+ 'phophungthai' : u"\u0E1C",
+ 'phosamphaothai' : u"\u0E20",
+ 'pieupacirclekorean' : u"\u3273",
+ 'pieupaparenkorean' : u"\u3213",
+ 'pieupcieuckorean' : u"\u3176",
+ 'pieupcirclekorean' : u"\u3265",
+ 'pieupkiyeokkorean' : u"\u3172",
+ 'pieupkorean' : u"\u3142",
+ 'pieupparenkorean' : u"\u3205",
+ 'pieupsioskiyeokkorean' : u"\u3174",
+ 'pieupsioskorean' : u"\u3144",
+ 'pieupsiostikeutkorean' : u"\u3175",
+ 'pieupthieuthkorean' : u"\u3177",
+ 'pieuptikeutkorean' : u"\u3173",
+ 'pihiragana' : u"\u3074",
+ 'pikatakana' : u"\u30D4",
+ 'pisymbolgreek' : u"\u03D6",
+ 'piwrarmenian' : u"\u0583",
+ 'plusbelowcmb' : u"\u031F",
+ 'pluscircle' : u"\u2295",
+ 'plusmod' : u"\u02D6",
+ 'plusmonospace' : u"\uFF0B",
+ 'plussmall' : u"\uFE62",
+ 'plussuperior' : u"\u207A",
+ 'pmonospace' : u"\uFF50",
+ 'pmsquare' : u"\u33D8",
+ 'pohiragana' : u"\u307D",
+ 'pointingindexdownwhite' : u"\u261F",
+ 'pointingindexleftwhite' : u"\u261C",
+ 'pointingindexrightwhite' : u"\u261E",
+ 'pointingindexupwhite' : u"\u261D",
+ 'pokatakana' : u"\u30DD",
+ 'poplathai' : u"\u0E1B",
+ 'postalmark' : u"\u3012",
+ 'postalmarkface' : u"\u3020",
+ 'pparen' : u"\u24AB",
+ 'precedes' : u"\u227A",
+ 'primemod' : u"\u02B9",
+ 'primereversed' : u"\u2035",
+ 'projective' : u"\u2305",
+ 'prolongedkana' : u"\u30FC",
+ 'propellor' : u"\u2318",
+ 'proportion' : u"\u2237",
+ 'psicyrillic' : u"\u0471",
+ 'psilipneumatacyrilliccmb' : u"\u0486",
+ 'pssquare' : u"\u33B0",
+ 'puhiragana' : u"\u3077",
+ 'pukatakana' : u"\u30D7",
+ 'pvsquare' : u"\u33B4",
+ 'pwsquare' : u"\u33BA",
+ 'qadeva' : u"\u0958",
+ 'qadmahebrew' : u"\u05A8",
+ 'qafarabic' : u"\u0642",
+ 'qaffinalarabic' : u"\uFED6",
+ 'qafinitialarabic' : u"\uFED7",
+ 'qafmedialarabic' : u"\uFED8",
+ 'qamats' : u"\u05B8",
+ 'qamats10' : u"\u05B8",
+ 'qamats1a' : u"\u05B8",
+ 'qamats1c' : u"\u05B8",
+ 'qamats27' : u"\u05B8",
+ 'qamats29' : u"\u05B8",
+ 'qamats33' : u"\u05B8",
+ 'qamatsde' : u"\u05B8",
+ 'qamatshebrew' : u"\u05B8",
+ 'qamatsnarrowhebrew' : u"\u05B8",
+ 'qamatsqatanhebrew' : u"\u05B8",
+ 'qamatsqatannarrowhebrew' : u"\u05B8",
+ 'qamatsqatanquarterhebrew' : u"\u05B8",
+ 'qamatsqatanwidehebrew' : u"\u05B8",
+ 'qamatsquarterhebrew' : u"\u05B8",
+ 'qamatswidehebrew' : u"\u05B8",
+ 'qarneyparahebrew' : u"\u059F",
+ 'qbopomofo' : u"\u3111",
+ 'qcircle' : u"\u24E0",
+ 'qhook' : u"\u02A0",
+ 'qmonospace' : u"\uFF51",
+ 'qof' : u"\u05E7",
+ 'qofdagesh' : u"\uFB47",
+ 'qofdageshhebrew' : u"\uFB47",
+ 'qofhatafpatah' : u"\u05E7\u05B2",
+ 'qofhatafpatahhebrew' : u"\u05E7\u05B2",
+ 'qofhatafsegol' : u"\u05E7\u05B1",
+ 'qofhatafsegolhebrew' : u"\u05E7\u05B1",
+ 'qofhebrew' : u"\u05E7",
+ 'qofhiriq' : u"\u05E7\u05B4",
+ 'qofhiriqhebrew' : u"\u05E7\u05B4",
+ 'qofholam' : u"\u05E7\u05B9",
+ 'qofholamhebrew' : u"\u05E7\u05B9",
+ 'qofpatah' : u"\u05E7\u05B7",
+ 'qofpatahhebrew' : u"\u05E7\u05B7",
+ 'qofqamats' : u"\u05E7\u05B8",
+ 'qofqamatshebrew' : u"\u05E7\u05B8",
+ 'qofqubuts' : u"\u05E7\u05BB",
+ 'qofqubutshebrew' : u"\u05E7\u05BB",
+ 'qofsegol' : u"\u05E7\u05B6",
+ 'qofsegolhebrew' : u"\u05E7\u05B6",
+ 'qofsheva' : u"\u05E7\u05B0",
+ 'qofshevahebrew' : u"\u05E7\u05B0",
+ 'qoftsere' : u"\u05E7\u05B5",
+ 'qoftserehebrew' : u"\u05E7\u05B5",
+ 'qparen' : u"\u24AC",
+ 'quarternote' : u"\u2669",
+ 'qubuts' : u"\u05BB",
+ 'qubuts18' : u"\u05BB",
+ 'qubuts25' : u"\u05BB",
+ 'qubuts31' : u"\u05BB",
+ 'qubutshebrew' : u"\u05BB",
+ 'qubutsnarrowhebrew' : u"\u05BB",
+ 'qubutsquarterhebrew' : u"\u05BB",
+ 'qubutswidehebrew' : u"\u05BB",
+ 'questionarabic' : u"\u061F",
+ 'questionarmenian' : u"\u055E",
+ 'questiondownsmall' : u"\uF7BF",
+ 'questiongreek' : u"\u037E",
+ 'questionmonospace' : u"\uFF1F",
+ 'questionsmall' : u"\uF73F",
+ 'quotedblmonospace' : u"\uFF02",
+ 'quotedblprime' : u"\u301E",
+ 'quotedblprimereversed' : u"\u301D",
+ 'quoteleftreversed' : u"\u201B",
+ 'quoterightn' : u"\u0149",
+ 'quotesinglemonospace' : u"\uFF07",
+ 'raarmenian' : u"\u057C",
+ 'rabengali' : u"\u09B0",
+ 'radeva' : u"\u0930",
+ 'radicalex' : u"\uF8E5",
+ 'radoverssquare' : u"\u33AE",
+ 'radoverssquaredsquare' : u"\u33AF",
+ 'radsquare' : u"\u33AD",
+ 'rafe' : u"\u05BF",
+ 'rafehebrew' : u"\u05BF",
+ 'ragujarati' : u"\u0AB0",
+ 'ragurmukhi' : u"\u0A30",
+ 'rahiragana' : u"\u3089",
+ 'rakatakana' : u"\u30E9",
+ 'rakatakanahalfwidth' : u"\uFF97",
+ 'ralowerdiagonalbengali' : u"\u09F1",
+ 'ramiddlediagonalbengali' : u"\u09F0",
+ 'ramshorn' : u"\u0264",
+ 'ratio' : u"\u2236",
+ 'rbopomofo' : u"\u3116",
+ 'rcedilla' : u"\u0157",
+ 'rcircle' : u"\u24E1",
+ 'rdblgrave' : u"\u0211",
+ 'rdotaccent' : u"\u1E59",
+ 'rdotbelow' : u"\u1E5B",
+ 'rdotbelowmacron' : u"\u1E5D",
+ 'referencemark' : u"\u203B",
+ 'registersans' : u"\uF8E8",
+ 'registerserif' : u"\uF6DA",
+ 'reharabic' : u"\u0631",
+ 'reharmenian' : u"\u0580",
+ 'rehfinalarabic' : u"\uFEAE",
+ 'rehiragana' : u"\u308C",
+ 'rehyehaleflamarabic' : u"\u0631\uFEF3\uFE8E\u0644",
+ 'rekatakana' : u"\u30EC",
+ 'rekatakanahalfwidth' : u"\uFF9A",
+ 'resh' : u"\u05E8",
+ 'reshdageshhebrew' : u"\uFB48",
+ 'reshhatafpatah' : u"\u05E8\u05B2",
+ 'reshhatafpatahhebrew' : u"\u05E8\u05B2",
+ 'reshhatafsegol' : u"\u05E8\u05B1",
+ 'reshhatafsegolhebrew' : u"\u05E8\u05B1",
+ 'reshhebrew' : u"\u05E8",
+ 'reshhiriq' : u"\u05E8\u05B4",
+ 'reshhiriqhebrew' : u"\u05E8\u05B4",
+ 'reshholam' : u"\u05E8\u05B9",
+ 'reshholamhebrew' : u"\u05E8\u05B9",
+ 'reshpatah' : u"\u05E8\u05B7",
+ 'reshpatahhebrew' : u"\u05E8\u05B7",
+ 'reshqamats' : u"\u05E8\u05B8",
+ 'reshqamatshebrew' : u"\u05E8\u05B8",
+ 'reshqubuts' : u"\u05E8\u05BB",
+ 'reshqubutshebrew' : u"\u05E8\u05BB",
+ 'reshsegol' : u"\u05E8\u05B6",
+ 'reshsegolhebrew' : u"\u05E8\u05B6",
+ 'reshsheva' : u"\u05E8\u05B0",
+ 'reshshevahebrew' : u"\u05E8\u05B0",
+ 'reshtsere' : u"\u05E8\u05B5",
+ 'reshtserehebrew' : u"\u05E8\u05B5",
+ 'reversedtilde' : u"\u223D",
+ 'reviahebrew' : u"\u0597",
+ 'reviamugrashhebrew' : u"\u0597",
+ 'rfishhook' : u"\u027E",
+ 'rfishhookreversed' : u"\u027F",
+ 'rhabengali' : u"\u09DD",
+ 'rhadeva' : u"\u095D",
+ 'rhook' : u"\u027D",
+ 'rhookturned' : u"\u027B",
+ 'rhookturnedsuperior' : u"\u02B5",
+ 'rhosymbolgreek' : u"\u03F1",
+ 'rhotichookmod' : u"\u02DE",
+ 'rieulacirclekorean' : u"\u3271",
+ 'rieulaparenkorean' : u"\u3211",
+ 'rieulcirclekorean' : u"\u3263",
+ 'rieulhieuhkorean' : u"\u3140",
+ 'rieulkiyeokkorean' : u"\u313A",
+ 'rieulkiyeoksioskorean' : u"\u3169",
+ 'rieulkorean' : u"\u3139",
+ 'rieulmieumkorean' : u"\u313B",
+ 'rieulpansioskorean' : u"\u316C",
+ 'rieulparenkorean' : u"\u3203",
+ 'rieulphieuphkorean' : u"\u313F",
+ 'rieulpieupkorean' : u"\u313C",
+ 'rieulpieupsioskorean' : u"\u316B",
+ 'rieulsioskorean' : u"\u313D",
+ 'rieulthieuthkorean' : u"\u313E",
+ 'rieultikeutkorean' : u"\u316A",
+ 'rieulyeorinhieuhkorean' : u"\u316D",
+ 'rightangle' : u"\u221F",
+ 'righttackbelowcmb' : u"\u0319",
+ 'righttriangle' : u"\u22BF",
+ 'rihiragana' : u"\u308A",
+ 'rikatakana' : u"\u30EA",
+ 'rikatakanahalfwidth' : u"\uFF98",
+ 'ringbelowcmb' : u"\u0325",
+ 'ringcmb' : u"\u030A",
+ 'ringhalfleft' : u"\u02BF",
+ 'ringhalfleftarmenian' : u"\u0559",
+ 'ringhalfleftbelowcmb' : u"\u031C",
+ 'ringhalfleftcentered' : u"\u02D3",
+ 'ringhalfright' : u"\u02BE",
+ 'ringhalfrightbelowcmb' : u"\u0339",
+ 'ringhalfrightcentered' : u"\u02D2",
+ 'rinvertedbreve' : u"\u0213",
+ 'rittorusquare' : u"\u3351",
+ 'rlinebelow' : u"\u1E5F",
+ 'rlongleg' : u"\u027C",
+ 'rlonglegturned' : u"\u027A",
+ 'rmonospace' : u"\uFF52",
+ 'rohiragana' : u"\u308D",
+ 'rokatakana' : u"\u30ED",
+ 'rokatakanahalfwidth' : u"\uFF9B",
+ 'roruathai' : u"\u0E23",
+ 'rparen' : u"\u24AD",
+ 'rrabengali' : u"\u09DC",
+ 'rradeva' : u"\u0931",
+ 'rragurmukhi' : u"\u0A5C",
+ 'rreharabic' : u"\u0691",
+ 'rrehfinalarabic' : u"\uFB8D",
+ 'rrvocalicbengali' : u"\u09E0",
+ 'rrvocalicdeva' : u"\u0960",
+ 'rrvocalicgujarati' : u"\u0AE0",
+ 'rrvocalicvowelsignbengali' : u"\u09C4",
+ 'rrvocalicvowelsigndeva' : u"\u0944",
+ 'rrvocalicvowelsigngujarati' : u"\u0AC4",
+ 'rsuperior' : u"\uF6F1",
+ 'rturned' : u"\u0279",
+ 'rturnedsuperior' : u"\u02B4",
+ 'ruhiragana' : u"\u308B",
+ 'rukatakana' : u"\u30EB",
+ 'rukatakanahalfwidth' : u"\uFF99",
+ 'rupeemarkbengali' : u"\u09F2",
+ 'rupeesignbengali' : u"\u09F3",
+ 'rupiah' : u"\uF6DD",
+ 'ruthai' : u"\u0E24",
+ 'rvocalicbengali' : u"\u098B",
+ 'rvocalicdeva' : u"\u090B",
+ 'rvocalicgujarati' : u"\u0A8B",
+ 'rvocalicvowelsignbengali' : u"\u09C3",
+ 'rvocalicvowelsigndeva' : u"\u0943",
+ 'rvocalicvowelsigngujarati' : u"\u0AC3",
+ 'sabengali' : u"\u09B8",
+ 'sacutedotaccent' : u"\u1E65",
+ 'sadarabic' : u"\u0635",
+ 'sadeva' : u"\u0938",
+ 'sadfinalarabic' : u"\uFEBA",
+ 'sadinitialarabic' : u"\uFEBB",
+ 'sadmedialarabic' : u"\uFEBC",
+ 'sagujarati' : u"\u0AB8",
+ 'sagurmukhi' : u"\u0A38",
+ 'sahiragana' : u"\u3055",
+ 'sakatakana' : u"\u30B5",
+ 'sakatakanahalfwidth' : u"\uFF7B",
+ 'sallallahoualayhewasallamarabic' : u"\uFDFA",
+ 'samekh' : u"\u05E1",
+ 'samekhdagesh' : u"\uFB41",
+ 'samekhdageshhebrew' : u"\uFB41",
+ 'samekhhebrew' : u"\u05E1",
+ 'saraaathai' : u"\u0E32",
+ 'saraaethai' : u"\u0E41",
+ 'saraaimaimalaithai' : u"\u0E44",
+ 'saraaimaimuanthai' : u"\u0E43",
+ 'saraamthai' : u"\u0E33",
+ 'saraathai' : u"\u0E30",
+ 'saraethai' : u"\u0E40",
+ 'saraiileftthai' : u"\uF886",
+ 'saraiithai' : u"\u0E35",
+ 'saraileftthai' : u"\uF885",
+ 'saraithai' : u"\u0E34",
+ 'saraothai' : u"\u0E42",
+ 'saraueeleftthai' : u"\uF888",
+ 'saraueethai' : u"\u0E37",
+ 'saraueleftthai' : u"\uF887",
+ 'sarauethai' : u"\u0E36",
+ 'sarauthai' : u"\u0E38",
+ 'sarauuthai' : u"\u0E39",
+ 'sbopomofo' : u"\u3119",
+ 'scarondotaccent' : u"\u1E67",
+ 'schwa' : u"\u0259",
+ 'schwacyrillic' : u"\u04D9",
+ 'schwadieresiscyrillic' : u"\u04DB",
+ 'schwahook' : u"\u025A",
+ 'scircle' : u"\u24E2",
+ 'sdotaccent' : u"\u1E61",
+ 'sdotbelow' : u"\u1E63",
+ 'sdotbelowdotaccent' : u"\u1E69",
+ 'seagullbelowcmb' : u"\u033C",
+ 'secondtonechinese' : u"\u02CA",
+ 'seenarabic' : u"\u0633",
+ 'seenfinalarabic' : u"\uFEB2",
+ 'seeninitialarabic' : u"\uFEB3",
+ 'seenmedialarabic' : u"\uFEB4",
+ 'segol' : u"\u05B6",
+ 'segol13' : u"\u05B6",
+ 'segol1f' : u"\u05B6",
+ 'segol2c' : u"\u05B6",
+ 'segolhebrew' : u"\u05B6",
+ 'segolnarrowhebrew' : u"\u05B6",
+ 'segolquarterhebrew' : u"\u05B6",
+ 'segoltahebrew' : u"\u0592",
+ 'segolwidehebrew' : u"\u05B6",
+ 'seharmenian' : u"\u057D",
+ 'sehiragana' : u"\u305B",
+ 'sekatakana' : u"\u30BB",
+ 'sekatakanahalfwidth' : u"\uFF7E",
+ 'semicolonarabic' : u"\u061B",
+ 'semicolonmonospace' : u"\uFF1B",
+ 'semicolonsmall' : u"\uFE54",
+ 'semivoicedmarkkana' : u"\u309C",
+ 'semivoicedmarkkanahalfwidth' : u"\uFF9F",
+ 'sentisquare' : u"\u3322",
+ 'sentosquare' : u"\u3323",
+ 'sevenarabic' : u"\u0667",
+ 'sevenbengali' : u"\u09ED",
+ 'sevencircle' : u"\u2466",
+ 'sevencircleinversesansserif' : u"\u2790",
+ 'sevendeva' : u"\u096D",
+ 'sevengujarati' : u"\u0AED",
+ 'sevengurmukhi' : u"\u0A6D",
+ 'sevenhackarabic' : u"\u0667",
+ 'sevenhangzhou' : u"\u3027",
+ 'sevenideographicparen' : u"\u3226",
+ 'seveninferior' : u"\u2087",
+ 'sevenmonospace' : u"\uFF17",
+ 'sevenoldstyle' : u"\uF737",
+ 'sevenparen' : u"\u247A",
+ 'sevenperiod' : u"\u248E",
+ 'sevenpersian' : u"\u06F7",
+ 'sevenroman' : u"\u2176",
+ 'sevensuperior' : u"\u2077",
+ 'seventeencircle' : u"\u2470",
+ 'seventeenparen' : u"\u2484",
+ 'seventeenperiod' : u"\u2498",
+ 'seventhai' : u"\u0E57",
+ 'sfthyphen' : u"\u00AD",
+ 'shaarmenian' : u"\u0577",
+ 'shabengali' : u"\u09B6",
+ 'shacyrillic' : u"\u0448",
+ 'shaddaarabic' : u"\u0651",
+ 'shaddadammaarabic' : u"\uFC61",
+ 'shaddadammatanarabic' : u"\uFC5E",
+ 'shaddafathaarabic' : u"\uFC60",
+ 'shaddafathatanarabic' : u"\u0651\u064B",
+ 'shaddakasraarabic' : u"\uFC62",
+ 'shaddakasratanarabic' : u"\uFC5F",
+ 'shadedark' : u"\u2593",
+ 'shadelight' : u"\u2591",
+ 'shademedium' : u"\u2592",
+ 'shadeva' : u"\u0936",
+ 'shagujarati' : u"\u0AB6",
+ 'shagurmukhi' : u"\u0A36",
+ 'shalshelethebrew' : u"\u0593",
+ 'shbopomofo' : u"\u3115",
+ 'shchacyrillic' : u"\u0449",
+ 'sheenarabic' : u"\u0634",
+ 'sheenfinalarabic' : u"\uFEB6",
+ 'sheeninitialarabic' : u"\uFEB7",
+ 'sheenmedialarabic' : u"\uFEB8",
+ 'sheicoptic' : u"\u03E3",
+ 'sheqel' : u"\u20AA",
+ 'sheqelhebrew' : u"\u20AA",
+ 'sheva' : u"\u05B0",
+ 'sheva115' : u"\u05B0",
+ 'sheva15' : u"\u05B0",
+ 'sheva22' : u"\u05B0",
+ 'sheva2e' : u"\u05B0",
+ 'shevahebrew' : u"\u05B0",
+ 'shevanarrowhebrew' : u"\u05B0",
+ 'shevaquarterhebrew' : u"\u05B0",
+ 'shevawidehebrew' : u"\u05B0",
+ 'shhacyrillic' : u"\u04BB",
+ 'shimacoptic' : u"\u03ED",
+ 'shin' : u"\u05E9",
+ 'shindagesh' : u"\uFB49",
+ 'shindageshhebrew' : u"\uFB49",
+ 'shindageshshindot' : u"\uFB2C",
+ 'shindageshshindothebrew' : u"\uFB2C",
+ 'shindageshsindot' : u"\uFB2D",
+ 'shindageshsindothebrew' : u"\uFB2D",
+ 'shindothebrew' : u"\u05C1",
+ 'shinhebrew' : u"\u05E9",
+ 'shinshindot' : u"\uFB2A",
+ 'shinshindothebrew' : u"\uFB2A",
+ 'shinsindot' : u"\uFB2B",
+ 'shinsindothebrew' : u"\uFB2B",
+ 'shook' : u"\u0282",
+ 'sigmafinal' : u"\u03C2",
+ 'sigmalunatesymbolgreek' : u"\u03F2",
+ 'sihiragana' : u"\u3057",
+ 'sikatakana' : u"\u30B7",
+ 'sikatakanahalfwidth' : u"\uFF7C",
+ 'siluqhebrew' : u"\u05BD",
+ 'siluqlefthebrew' : u"\u05BD",
+ 'sindothebrew' : u"\u05C2",
+ 'siosacirclekorean' : u"\u3274",
+ 'siosaparenkorean' : u"\u3214",
+ 'sioscieuckorean' : u"\u317E",
+ 'sioscirclekorean' : u"\u3266",
+ 'sioskiyeokkorean' : u"\u317A",
+ 'sioskorean' : u"\u3145",
+ 'siosnieunkorean' : u"\u317B",
+ 'siosparenkorean' : u"\u3206",
+ 'siospieupkorean' : u"\u317D",
+ 'siostikeutkorean' : u"\u317C",
+ 'sixarabic' : u"\u0666",
+ 'sixbengali' : u"\u09EC",
+ 'sixcircle' : u"\u2465",
+ 'sixcircleinversesansserif' : u"\u278F",
+ 'sixdeva' : u"\u096C",
+ 'sixgujarati' : u"\u0AEC",
+ 'sixgurmukhi' : u"\u0A6C",
+ 'sixhackarabic' : u"\u0666",
+ 'sixhangzhou' : u"\u3026",
+ 'sixideographicparen' : u"\u3225",
+ 'sixinferior' : u"\u2086",
+ 'sixmonospace' : u"\uFF16",
+ 'sixoldstyle' : u"\uF736",
+ 'sixparen' : u"\u2479",
+ 'sixperiod' : u"\u248D",
+ 'sixpersian' : u"\u06F6",
+ 'sixroman' : u"\u2175",
+ 'sixsuperior' : u"\u2076",
+ 'sixteencircle' : u"\u246F",
+ 'sixteencurrencydenominatorbengali' : u"\u09F9",
+ 'sixteenparen' : u"\u2483",
+ 'sixteenperiod' : u"\u2497",
+ 'sixthai' : u"\u0E56",
+ 'slashmonospace' : u"\uFF0F",
+ 'slong' : u"\u017F",
+ 'slongdotaccent' : u"\u1E9B",
+ 'smonospace' : u"\uFF53",
+ 'sofpasuqhebrew' : u"\u05C3",
+ 'softhyphen' : u"\u00AD",
+ 'softsigncyrillic' : u"\u044C",
+ 'sohiragana' : u"\u305D",
+ 'sokatakana' : u"\u30BD",
+ 'sokatakanahalfwidth' : u"\uFF7F",
+ 'soliduslongoverlaycmb' : u"\u0338",
+ 'solidusshortoverlaycmb' : u"\u0337",
+ 'sorusithai' : u"\u0E29",
+ 'sosalathai' : u"\u0E28",
+ 'sosothai' : u"\u0E0B",
+ 'sosuathai' : u"\u0E2A",
+ 'spacehackarabic' : u"\u0020",
+ 'spadesuitblack' : u"\u2660",
+ 'spadesuitwhite' : u"\u2664",
+ 'sparen' : u"\u24AE",
+ 'squarebelowcmb' : u"\u033B",
+ 'squarecc' : u"\u33C4",
+ 'squarecm' : u"\u339D",
+ 'squarediagonalcrosshatchfill' : u"\u25A9",
+ 'squarehorizontalfill' : u"\u25A4",
+ 'squarekg' : u"\u338F",
+ 'squarekm' : u"\u339E",
+ 'squarekmcapital' : u"\u33CE",
+ 'squareln' : u"\u33D1",
+ 'squarelog' : u"\u33D2",
+ 'squaremg' : u"\u338E",
+ 'squaremil' : u"\u33D5",
+ 'squaremm' : u"\u339C",
+ 'squaremsquared' : u"\u33A1",
+ 'squareorthogonalcrosshatchfill' : u"\u25A6",
+ 'squareupperlefttolowerrightfill' : u"\u25A7",
+ 'squareupperrighttolowerleftfill' : u"\u25A8",
+ 'squareverticalfill' : u"\u25A5",
+ 'squarewhitewithsmallblack' : u"\u25A3",
+ 'srsquare' : u"\u33DB",
+ 'ssabengali' : u"\u09B7",
+ 'ssadeva' : u"\u0937",
+ 'ssagujarati' : u"\u0AB7",
+ 'ssangcieuckorean' : u"\u3149",
+ 'ssanghieuhkorean' : u"\u3185",
+ 'ssangieungkorean' : u"\u3180",
+ 'ssangkiyeokkorean' : u"\u3132",
+ 'ssangnieunkorean' : u"\u3165",
+ 'ssangpieupkorean' : u"\u3143",
+ 'ssangsioskorean' : u"\u3146",
+ 'ssangtikeutkorean' : u"\u3138",
+ 'ssuperior' : u"\uF6F2",
+ 'sterlingmonospace' : u"\uFFE1",
+ 'strokelongoverlaycmb' : u"\u0336",
+ 'strokeshortoverlaycmb' : u"\u0335",
+ 'subset' : u"\u2282",
+ 'subsetnotequal' : u"\u228A",
+ 'subsetorequal' : u"\u2286",
+ 'succeeds' : u"\u227B",
+ 'suhiragana' : u"\u3059",
+ 'sukatakana' : u"\u30B9",
+ 'sukatakanahalfwidth' : u"\uFF7D",
+ 'sukunarabic' : u"\u0652",
+ 'superset' : u"\u2283",
+ 'supersetnotequal' : u"\u228B",
+ 'supersetorequal' : u"\u2287",
+ 'svsquare' : u"\u33DC",
+ 'syouwaerasquare' : u"\u337C",
+ 'tabengali' : u"\u09A4",
+ 'tackdown' : u"\u22A4",
+ 'tackleft' : u"\u22A3",
+ 'tadeva' : u"\u0924",
+ 'tagujarati' : u"\u0AA4",
+ 'tagurmukhi' : u"\u0A24",
+ 'taharabic' : u"\u0637",
+ 'tahfinalarabic' : u"\uFEC2",
+ 'tahinitialarabic' : u"\uFEC3",
+ 'tahiragana' : u"\u305F",
+ 'tahmedialarabic' : u"\uFEC4",
+ 'taisyouerasquare' : u"\u337D",
+ 'takatakana' : u"\u30BF",
+ 'takatakanahalfwidth' : u"\uFF80",
+ 'tatweelarabic' : u"\u0640",
+ 'tav' : u"\u05EA",
+ 'tavdages' : u"\uFB4A",
+ 'tavdagesh' : u"\uFB4A",
+ 'tavdageshhebrew' : u"\uFB4A",
+ 'tavhebrew' : u"\u05EA",
+ 'tbopomofo' : u"\u310A",
+ 'tccurl' : u"\u02A8",
+ 'tcedilla' : u"\u0163",
+ 'tcheharabic' : u"\u0686",
+ 'tchehfinalarabic' : u"\uFB7B",
+ 'tchehinitialarabic' : u"\uFB7C",
+ 'tchehmedialarabic' : u"\uFB7D",
+ 'tchehmeeminitialarabic' : u"\uFB7C\uFEE4",
+ 'tcircle' : u"\u24E3",
+ 'tcircumflexbelow' : u"\u1E71",
+ 'tdieresis' : u"\u1E97",
+ 'tdotaccent' : u"\u1E6B",
+ 'tdotbelow' : u"\u1E6D",
+ 'tecyrillic' : u"\u0442",
+ 'tedescendercyrillic' : u"\u04AD",
+ 'teharabic' : u"\u062A",
+ 'tehfinalarabic' : u"\uFE96",
+ 'tehhahinitialarabic' : u"\uFCA2",
+ 'tehhahisolatedarabic' : u"\uFC0C",
+ 'tehinitialarabic' : u"\uFE97",
+ 'tehiragana' : u"\u3066",
+ 'tehjeeminitialarabic' : u"\uFCA1",
+ 'tehjeemisolatedarabic' : u"\uFC0B",
+ 'tehmarbutaarabic' : u"\u0629",
+ 'tehmarbutafinalarabic' : u"\uFE94",
+ 'tehmedialarabic' : u"\uFE98",
+ 'tehmeeminitialarabic' : u"\uFCA4",
+ 'tehmeemisolatedarabic' : u"\uFC0E",
+ 'tehnoonfinalarabic' : u"\uFC73",
+ 'tekatakana' : u"\u30C6",
+ 'tekatakanahalfwidth' : u"\uFF83",
+ 'telephone' : u"\u2121",
+ 'telephoneblack' : u"\u260E",
+ 'telishagedolahebrew' : u"\u05A0",
+ 'telishaqetanahebrew' : u"\u05A9",
+ 'tencircle' : u"\u2469",
+ 'tenideographicparen' : u"\u3229",
+ 'tenparen' : u"\u247D",
+ 'tenperiod' : u"\u2491",
+ 'tenroman' : u"\u2179",
+ 'tesh' : u"\u02A7",
+ 'tet' : u"\u05D8",
+ 'tetdagesh' : u"\uFB38",
+ 'tetdageshhebrew' : u"\uFB38",
+ 'tethebrew' : u"\u05D8",
+ 'tetsecyrillic' : u"\u04B5",
+ 'tevirhebrew' : u"\u059B",
+ 'tevirlefthebrew' : u"\u059B",
+ 'thabengali' : u"\u09A5",
+ 'thadeva' : u"\u0925",
+ 'thagujarati' : u"\u0AA5",
+ 'thagurmukhi' : u"\u0A25",
+ 'thalarabic' : u"\u0630",
+ 'thalfinalarabic' : u"\uFEAC",
+ 'thanthakhatlowleftthai' : u"\uF898",
+ 'thanthakhatlowrightthai' : u"\uF897",
+ 'thanthakhatthai' : u"\u0E4C",
+ 'thanthakhatupperleftthai' : u"\uF896",
+ 'theharabic' : u"\u062B",
+ 'thehfinalarabic' : u"\uFE9A",
+ 'thehinitialarabic' : u"\uFE9B",
+ 'thehmedialarabic' : u"\uFE9C",
+ 'thereexists' : u"\u2203",
+ 'thetasymbolgreek' : u"\u03D1",
+ 'thieuthacirclekorean' : u"\u3279",
+ 'thieuthaparenkorean' : u"\u3219",
+ 'thieuthcirclekorean' : u"\u326B",
+ 'thieuthkorean' : u"\u314C",
+ 'thieuthparenkorean' : u"\u320B",
+ 'thirteencircle' : u"\u246C",
+ 'thirteenparen' : u"\u2480",
+ 'thirteenperiod' : u"\u2494",
+ 'thonangmonthothai' : u"\u0E11",
+ 'thook' : u"\u01AD",
+ 'thophuthaothai' : u"\u0E12",
+ 'thothahanthai' : u"\u0E17",
+ 'thothanthai' : u"\u0E10",
+ 'thothongthai' : u"\u0E18",
+ 'thothungthai' : u"\u0E16",
+ 'thousandcyrillic' : u"\u0482",
+ 'thousandsseparatorarabic' : u"\u066C",
+ 'thousandsseparatorpersian' : u"\u066C",
+ 'threearabic' : u"\u0663",
+ 'threebengali' : u"\u09E9",
+ 'threecircle' : u"\u2462",
+ 'threecircleinversesansserif' : u"\u278C",
+ 'threedeva' : u"\u0969",
+ 'threegujarati' : u"\u0AE9",
+ 'threegurmukhi' : u"\u0A69",
+ 'threehackarabic' : u"\u0663",
+ 'threehangzhou' : u"\u3023",
+ 'threeideographicparen' : u"\u3222",
+ 'threeinferior' : u"\u2083",
+ 'threemonospace' : u"\uFF13",
+ 'threenumeratorbengali' : u"\u09F6",
+ 'threeoldstyle' : u"\uF733",
+ 'threeparen' : u"\u2476",
+ 'threeperiod' : u"\u248A",
+ 'threepersian' : u"\u06F3",
+ 'threequartersemdash' : u"\uF6DE",
+ 'threeroman' : u"\u2172",
+ 'threethai' : u"\u0E53",
+ 'thzsquare' : u"\u3394",
+ 'tihiragana' : u"\u3061",
+ 'tikatakana' : u"\u30C1",
+ 'tikatakanahalfwidth' : u"\uFF81",
+ 'tikeutacirclekorean' : u"\u3270",
+ 'tikeutaparenkorean' : u"\u3210",
+ 'tikeutcirclekorean' : u"\u3262",
+ 'tikeutkorean' : u"\u3137",
+ 'tikeutparenkorean' : u"\u3202",
+ 'tildebelowcmb' : u"\u0330",
+ 'tildecmb' : u"\u0303",
+ 'tildedoublecmb' : u"\u0360",
+ 'tildeoperator' : u"\u223C",
+ 'tildeoverlaycmb' : u"\u0334",
+ 'tildeverticalcmb' : u"\u033E",
+ 'timescircle' : u"\u2297",
+ 'tipehahebrew' : u"\u0596",
+ 'tipehalefthebrew' : u"\u0596",
+ 'tippigurmukhi' : u"\u0A70",
+ 'titlocyrilliccmb' : u"\u0483",
+ 'tiwnarmenian' : u"\u057F",
+ 'tlinebelow' : u"\u1E6F",
+ 'tmonospace' : u"\uFF54",
+ 'toarmenian' : u"\u0569",
+ 'tohiragana' : u"\u3068",
+ 'tokatakana' : u"\u30C8",
+ 'tokatakanahalfwidth' : u"\uFF84",
+ 'tonebarextrahighmod' : u"\u02E5",
+ 'tonebarextralowmod' : u"\u02E9",
+ 'tonebarhighmod' : u"\u02E6",
+ 'tonebarlowmod' : u"\u02E8",
+ 'tonebarmidmod' : u"\u02E7",
+ 'tonefive' : u"\u01BD",
+ 'tonesix' : u"\u0185",
+ 'tonetwo' : u"\u01A8",
+ 'tonsquare' : u"\u3327",
+ 'topatakthai' : u"\u0E0F",
+ 'tortoiseshellbracketleft' : u"\u3014",
+ 'tortoiseshellbracketleftsmall' : u"\uFE5D",
+ 'tortoiseshellbracketleftvertical' : u"\uFE39",
+ 'tortoiseshellbracketright' : u"\u3015",
+ 'tortoiseshellbracketrightsmall' : u"\uFE5E",
+ 'tortoiseshellbracketrightvertical' : u"\uFE3A",
+ 'totaothai' : u"\u0E15",
+ 'tpalatalhook' : u"\u01AB",
+ 'tparen' : u"\u24AF",
+ 'trademarksans' : u"\uF8EA",
+ 'trademarkserif' : u"\uF6DB",
+ 'tretroflexhook' : u"\u0288",
+ 'ts' : u"\u02A6",
+ 'tsadi' : u"\u05E6",
+ 'tsadidagesh' : u"\uFB46",
+ 'tsadidageshhebrew' : u"\uFB46",
+ 'tsadihebrew' : u"\u05E6",
+ 'tsecyrillic' : u"\u0446",
+ 'tsere' : u"\u05B5",
+ 'tsere12' : u"\u05B5",
+ 'tsere1e' : u"\u05B5",
+ 'tsere2b' : u"\u05B5",
+ 'tserehebrew' : u"\u05B5",
+ 'tserenarrowhebrew' : u"\u05B5",
+ 'tserequarterhebrew' : u"\u05B5",
+ 'tserewidehebrew' : u"\u05B5",
+ 'tshecyrillic' : u"\u045B",
+ 'tsuperior' : u"\uF6F3",
+ 'ttabengali' : u"\u099F",
+ 'ttadeva' : u"\u091F",
+ 'ttagujarati' : u"\u0A9F",
+ 'ttagurmukhi' : u"\u0A1F",
+ 'tteharabic' : u"\u0679",
+ 'ttehfinalarabic' : u"\uFB67",
+ 'ttehinitialarabic' : u"\uFB68",
+ 'ttehmedialarabic' : u"\uFB69",
+ 'tthabengali' : u"\u09A0",
+ 'tthadeva' : u"\u0920",
+ 'tthagujarati' : u"\u0AA0",
+ 'tthagurmukhi' : u"\u0A20",
+ 'tturned' : u"\u0287",
+ 'tuhiragana' : u"\u3064",
+ 'tukatakana' : u"\u30C4",
+ 'tukatakanahalfwidth' : u"\uFF82",
+ 'tusmallhiragana' : u"\u3063",
+ 'tusmallkatakana' : u"\u30C3",
+ 'tusmallkatakanahalfwidth' : u"\uFF6F",
+ 'twelvecircle' : u"\u246B",
+ 'twelveparen' : u"\u247F",
+ 'twelveperiod' : u"\u2493",
+ 'twelveroman' : u"\u217B",
+ 'twentycircle' : u"\u2473",
+ 'twentyhangzhou' : u"\u5344",
+ 'twentyparen' : u"\u2487",
+ 'twentyperiod' : u"\u249B",
+ 'twoarabic' : u"\u0662",
+ 'twobengali' : u"\u09E8",
+ 'twocircle' : u"\u2461",
+ 'twocircleinversesansserif' : u"\u278B",
+ 'twodeva' : u"\u0968",
+ 'twodotleader' : u"\u2025",
+ 'twodotleadervertical' : u"\uFE30",
+ 'twogujarati' : u"\u0AE8",
+ 'twogurmukhi' : u"\u0A68",
+ 'twohackarabic' : u"\u0662",
+ 'twohangzhou' : u"\u3022",
+ 'twoideographicparen' : u"\u3221",
+ 'twoinferior' : u"\u2082",
+ 'twomonospace' : u"\uFF12",
+ 'twonumeratorbengali' : u"\u09F5",
+ 'twooldstyle' : u"\uF732",
+ 'twoparen' : u"\u2475",
+ 'twoperiod' : u"\u2489",
+ 'twopersian' : u"\u06F2",
+ 'tworoman' : u"\u2171",
+ 'twostroke' : u"\u01BB",
+ 'twothai' : u"\u0E52",
+ 'ubar' : u"\u0289",
+ 'ubengali' : u"\u0989",
+ 'ubopomofo' : u"\u3128",
+ 'ucaron' : u"\u01D4",
+ 'ucircle' : u"\u24E4",
+ 'ucircumflexbelow' : u"\u1E77",
+ 'ucyrillic' : u"\u0443",
+ 'udattadeva' : u"\u0951",
+ 'udblacute' : u"\u0171",
+ 'udblgrave' : u"\u0215",
+ 'udeva' : u"\u0909",
+ 'udieresisacute' : u"\u01D8",
+ 'udieresisbelow' : u"\u1E73",
+ 'udieresiscaron' : u"\u01DA",
+ 'udieresiscyrillic' : u"\u04F1",
+ 'udieresisgrave' : u"\u01DC",
+ 'udieresismacron' : u"\u01D6",
+ 'udotbelow' : u"\u1EE5",
+ 'ugujarati' : u"\u0A89",
+ 'ugurmukhi' : u"\u0A09",
+ 'uhiragana' : u"\u3046",
+ 'uhookabove' : u"\u1EE7",
+ 'uhornacute' : u"\u1EE9",
+ 'uhorndotbelow' : u"\u1EF1",
+ 'uhorngrave' : u"\u1EEB",
+ 'uhornhookabove' : u"\u1EED",
+ 'uhorntilde' : u"\u1EEF",
+ 'uhungarumlautcyrillic' : u"\u04F3",
+ 'uinvertedbreve' : u"\u0217",
+ 'ukatakana' : u"\u30A6",
+ 'ukatakanahalfwidth' : u"\uFF73",
+ 'ukcyrillic' : u"\u0479",
+ 'ukorean' : u"\u315C",
+ 'umacroncyrillic' : u"\u04EF",
+ 'umacrondieresis' : u"\u1E7B",
+ 'umatragurmukhi' : u"\u0A41",
+ 'umonospace' : u"\uFF55",
+ 'underscoremonospace' : u"\uFF3F",
+ 'underscorevertical' : u"\uFE33",
+ 'underscorewavy' : u"\uFE4F",
+ 'uparen' : u"\u24B0",
+ 'upperdothebrew' : u"\u05C4",
+ 'upsilonlatin' : u"\u028A",
+ 'uptackbelowcmb' : u"\u031D",
+ 'uptackmod' : u"\u02D4",
+ 'uragurmukhi' : u"\u0A73",
+ 'ushortcyrillic' : u"\u045E",
+ 'usmallhiragana' : u"\u3045",
+ 'usmallkatakana' : u"\u30A5",
+ 'usmallkatakanahalfwidth' : u"\uFF69",
+ 'ustraightcyrillic' : u"\u04AF",
+ 'ustraightstrokecyrillic' : u"\u04B1",
+ 'utildeacute' : u"\u1E79",
+ 'utildebelow' : u"\u1E75",
+ 'uubengali' : u"\u098A",
+ 'uudeva' : u"\u090A",
+ 'uugujarati' : u"\u0A8A",
+ 'uugurmukhi' : u"\u0A0A",
+ 'uumatragurmukhi' : u"\u0A42",
+ 'uuvowelsignbengali' : u"\u09C2",
+ 'uuvowelsigndeva' : u"\u0942",
+ 'uuvowelsigngujarati' : u"\u0AC2",
+ 'uvowelsignbengali' : u"\u09C1",
+ 'uvowelsigndeva' : u"\u0941",
+ 'uvowelsigngujarati' : u"\u0AC1",
+ 'vadeva' : u"\u0935",
+ 'vagujarati' : u"\u0AB5",
+ 'vagurmukhi' : u"\u0A35",
+ 'vakatakana' : u"\u30F7",
+ 'vav' : u"\u05D5",
+ 'vavdagesh' : u"\uFB35",
+ 'vavdagesh65' : u"\uFB35",
+ 'vavdageshhebrew' : u"\uFB35",
+ 'vavhebrew' : u"\u05D5",
+ 'vavholam' : u"\uFB4B",
+ 'vavholamhebrew' : u"\uFB4B",
+ 'vavvavhebrew' : u"\u05F0",
+ 'vavyodhebrew' : u"\u05F1",
+ 'vcircle' : u"\u24E5",
+ 'vdotbelow' : u"\u1E7F",
+ 'vecyrillic' : u"\u0432",
+ 'veharabic' : u"\u06A4",
+ 'vehfinalarabic' : u"\uFB6B",
+ 'vehinitialarabic' : u"\uFB6C",
+ 'vehmedialarabic' : u"\uFB6D",
+ 'vekatakana' : u"\u30F9",
+ 'venus' : u"\u2640",
+ 'verticalbar' : u"\u007C",
+ 'verticallineabovecmb' : u"\u030D",
+ 'verticallinebelowcmb' : u"\u0329",
+ 'verticallinelowmod' : u"\u02CC",
+ 'verticallinemod' : u"\u02C8",
+ 'vewarmenian' : u"\u057E",
+ 'vhook' : u"\u028B",
+ 'vikatakana' : u"\u30F8",
+ 'viramabengali' : u"\u09CD",
+ 'viramadeva' : u"\u094D",
+ 'viramagujarati' : u"\u0ACD",
+ 'visargabengali' : u"\u0983",
+ 'visargadeva' : u"\u0903",
+ 'visargagujarati' : u"\u0A83",
+ 'vmonospace' : u"\uFF56",
+ 'voarmenian' : u"\u0578",
+ 'voicediterationhiragana' : u"\u309E",
+ 'voicediterationkatakana' : u"\u30FE",
+ 'voicedmarkkana' : u"\u309B",
+ 'voicedmarkkanahalfwidth' : u"\uFF9E",
+ 'vokatakana' : u"\u30FA",
+ 'vparen' : u"\u24B1",
+ 'vtilde' : u"\u1E7D",
+ 'vturned' : u"\u028C",
+ 'vuhiragana' : u"\u3094",
+ 'vukatakana' : u"\u30F4",
+ 'waekorean' : u"\u3159",
+ 'wahiragana' : u"\u308F",
+ 'wakatakana' : u"\u30EF",
+ 'wakatakanahalfwidth' : u"\uFF9C",
+ 'wakorean' : u"\u3158",
+ 'wasmallhiragana' : u"\u308E",
+ 'wasmallkatakana' : u"\u30EE",
+ 'wattosquare' : u"\u3357",
+ 'wavedash' : u"\u301C",
+ 'wavyunderscorevertical' : u"\uFE34",
+ 'wawarabic' : u"\u0648",
+ 'wawfinalarabic' : u"\uFEEE",
+ 'wawhamzaabovearabic' : u"\u0624",
+ 'wawhamzaabovefinalarabic' : u"\uFE86",
+ 'wbsquare' : u"\u33DD",
+ 'wcircle' : u"\u24E6",
+ 'wdotaccent' : u"\u1E87",
+ 'wdotbelow' : u"\u1E89",
+ 'wehiragana' : u"\u3091",
+ 'wekatakana' : u"\u30F1",
+ 'wekorean' : u"\u315E",
+ 'weokorean' : u"\u315D",
+ 'whitebullet' : u"\u25E6",
+ 'whitecircle' : u"\u25CB",
+ 'whitecircleinverse' : u"\u25D9",
+ 'whitecornerbracketleft' : u"\u300E",
+ 'whitecornerbracketleftvertical' : u"\uFE43",
+ 'whitecornerbracketright' : u"\u300F",
+ 'whitecornerbracketrightvertical' : u"\uFE44",
+ 'whitediamond' : u"\u25C7",
+ 'whitediamondcontainingblacksmalldiamond' : u"\u25C8",
+ 'whitedownpointingsmalltriangle' : u"\u25BF",
+ 'whitedownpointingtriangle' : u"\u25BD",
+ 'whiteleftpointingsmalltriangle' : u"\u25C3",
+ 'whiteleftpointingtriangle' : u"\u25C1",
+ 'whitelenticularbracketleft' : u"\u3016",
+ 'whitelenticularbracketright' : u"\u3017",
+ 'whiterightpointingsmalltriangle' : u"\u25B9",
+ 'whiterightpointingtriangle' : u"\u25B7",
+ 'whitesmallsquare' : u"\u25AB",
+ 'whitesmilingface' : u"\u263A",
+ 'whitesquare' : u"\u25A1",
+ 'whitestar' : u"\u2606",
+ 'whitetelephone' : u"\u260F",
+ 'whitetortoiseshellbracketleft' : u"\u3018",
+ 'whitetortoiseshellbracketright' : u"\u3019",
+ 'whiteuppointingsmalltriangle' : u"\u25B5",
+ 'whiteuppointingtriangle' : u"\u25B3",
+ 'wihiragana' : u"\u3090",
+ 'wikatakana' : u"\u30F0",
+ 'wikorean' : u"\u315F",
+ 'wmonospace' : u"\uFF57",
+ 'wohiragana' : u"\u3092",
+ 'wokatakana' : u"\u30F2",
+ 'wokatakanahalfwidth' : u"\uFF66",
+ 'won' : u"\u20A9",
+ 'wonmonospace' : u"\uFFE6",
+ 'wowaenthai' : u"\u0E27",
+ 'wparen' : u"\u24B2",
+ 'wring' : u"\u1E98",
+ 'wsuperior' : u"\u02B7",
+ 'wturned' : u"\u028D",
+ 'wynn' : u"\u01BF",
+ 'xabovecmb' : u"\u033D",
+ 'xbopomofo' : u"\u3112",
+ 'xcircle' : u"\u24E7",
+ 'xdieresis' : u"\u1E8D",
+ 'xdotaccent' : u"\u1E8B",
+ 'xeharmenian' : u"\u056D",
+ 'xmonospace' : u"\uFF58",
+ 'xparen' : u"\u24B3",
+ 'xsuperior' : u"\u02E3",
+ 'yaadosquare' : u"\u334E",
+ 'yabengali' : u"\u09AF",
+ 'yadeva' : u"\u092F",
+ 'yaekorean' : u"\u3152",
+ 'yagujarati' : u"\u0AAF",
+ 'yagurmukhi' : u"\u0A2F",
+ 'yahiragana' : u"\u3084",
+ 'yakatakana' : u"\u30E4",
+ 'yakatakanahalfwidth' : u"\uFF94",
+ 'yakorean' : u"\u3151",
+ 'yamakkanthai' : u"\u0E4E",
+ 'yasmallhiragana' : u"\u3083",
+ 'yasmallkatakana' : u"\u30E3",
+ 'yasmallkatakanahalfwidth' : u"\uFF6C",
+ 'yatcyrillic' : u"\u0463",
+ 'ycircle' : u"\u24E8",
+ 'ydotaccent' : u"\u1E8F",
+ 'ydotbelow' : u"\u1EF5",
+ 'yeharabic' : u"\u064A",
+ 'yehbarreearabic' : u"\u06D2",
+ 'yehbarreefinalarabic' : u"\uFBAF",
+ 'yehfinalarabic' : u"\uFEF2",
+ 'yehhamzaabovearabic' : u"\u0626",
+ 'yehhamzaabovefinalarabic' : u"\uFE8A",
+ 'yehhamzaaboveinitialarabic' : u"\uFE8B",
+ 'yehhamzaabovemedialarabic' : u"\uFE8C",
+ 'yehinitialarabic' : u"\uFEF3",
+ 'yehmedialarabic' : u"\uFEF4",
+ 'yehmeeminitialarabic' : u"\uFCDD",
+ 'yehmeemisolatedarabic' : u"\uFC58",
+ 'yehnoonfinalarabic' : u"\uFC94",
+ 'yehthreedotsbelowarabic' : u"\u06D1",
+ 'yekorean' : u"\u3156",
+ 'yenmonospace' : u"\uFFE5",
+ 'yeokorean' : u"\u3155",
+ 'yeorinhieuhkorean' : u"\u3186",
+ 'yerahbenyomohebrew' : u"\u05AA",
+ 'yerahbenyomolefthebrew' : u"\u05AA",
+ 'yericyrillic' : u"\u044B",
+ 'yerudieresiscyrillic' : u"\u04F9",
+ 'yesieungkorean' : u"\u3181",
+ 'yesieungpansioskorean' : u"\u3183",
+ 'yesieungsioskorean' : u"\u3182",
+ 'yetivhebrew' : u"\u059A",
+ 'yhook' : u"\u01B4",
+ 'yhookabove' : u"\u1EF7",
+ 'yiarmenian' : u"\u0575",
+ 'yicyrillic' : u"\u0457",
+ 'yikorean' : u"\u3162",
+ 'yinyang' : u"\u262F",
+ 'yiwnarmenian' : u"\u0582",
+ 'ymonospace' : u"\uFF59",
+ 'yod' : u"\u05D9",
+ 'yoddagesh' : u"\uFB39",
+ 'yoddageshhebrew' : u"\uFB39",
+ 'yodhebrew' : u"\u05D9",
+ 'yodyodhebrew' : u"\u05F2",
+ 'yodyodpatahhebrew' : u"\uFB1F",
+ 'yohiragana' : u"\u3088",
+ 'yoikorean' : u"\u3189",
+ 'yokatakana' : u"\u30E8",
+ 'yokatakanahalfwidth' : u"\uFF96",
+ 'yokorean' : u"\u315B",
+ 'yosmallhiragana' : u"\u3087",
+ 'yosmallkatakana' : u"\u30E7",
+ 'yosmallkatakanahalfwidth' : u"\uFF6E",
+ 'yotgreek' : u"\u03F3",
+ 'yoyaekorean' : u"\u3188",
+ 'yoyakorean' : u"\u3187",
+ 'yoyakthai' : u"\u0E22",
+ 'yoyingthai' : u"\u0E0D",
+ 'yparen' : u"\u24B4",
+ 'ypogegrammeni' : u"\u037A",
+ 'ypogegrammenigreekcmb' : u"\u0345",
+ 'yr' : u"\u01A6",
+ 'yring' : u"\u1E99",
+ 'ysuperior' : u"\u02B8",
+ 'ytilde' : u"\u1EF9",
+ 'yturned' : u"\u028E",
+ 'yuhiragana' : u"\u3086",
+ 'yuikorean' : u"\u318C",
+ 'yukatakana' : u"\u30E6",
+ 'yukatakanahalfwidth' : u"\uFF95",
+ 'yukorean' : u"\u3160",
+ 'yusbigcyrillic' : u"\u046B",
+ 'yusbigiotifiedcyrillic' : u"\u046D",
+ 'yuslittlecyrillic' : u"\u0467",
+ 'yuslittleiotifiedcyrillic' : u"\u0469",
+ 'yusmallhiragana' : u"\u3085",
+ 'yusmallkatakana' : u"\u30E5",
+ 'yusmallkatakanahalfwidth' : u"\uFF6D",
+ 'yuyekorean' : u"\u318B",
+ 'yuyeokorean' : u"\u318A",
+ 'yyabengali' : u"\u09DF",
+ 'yyadeva' : u"\u095F",
+ 'zaarmenian' : u"\u0566",
+ 'zadeva' : u"\u095B",
+ 'zagurmukhi' : u"\u0A5B",
+ 'zaharabic' : u"\u0638",
+ 'zahfinalarabic' : u"\uFEC6",
+ 'zahinitialarabic' : u"\uFEC7",
+ 'zahiragana' : u"\u3056",
+ 'zahmedialarabic' : u"\uFEC8",
+ 'zainarabic' : u"\u0632",
+ 'zainfinalarabic' : u"\uFEB0",
+ 'zakatakana' : u"\u30B6",
+ 'zaqefgadolhebrew' : u"\u0595",
+ 'zaqefqatanhebrew' : u"\u0594",
+ 'zarqahebrew' : u"\u0598",
+ 'zayin' : u"\u05D6",
+ 'zayindagesh' : u"\uFB36",
+ 'zayindageshhebrew' : u"\uFB36",
+ 'zayinhebrew' : u"\u05D6",
+ 'zbopomofo' : u"\u3117",
+ 'zcircle' : u"\u24E9",
+ 'zcircumflex' : u"\u1E91",
+ 'zcurl' : u"\u0291",
+ 'zdot' : u"\u017C",
+ 'zdotbelow' : u"\u1E93",
+ 'zecyrillic' : u"\u0437",
+ 'zedescendercyrillic' : u"\u0499",
+ 'zedieresiscyrillic' : u"\u04DF",
+ 'zehiragana' : u"\u305C",
+ 'zekatakana' : u"\u30BC",
+ 'zeroarabic' : u"\u0660",
+ 'zerobengali' : u"\u09E6",
+ 'zerodeva' : u"\u0966",
+ 'zerogujarati' : u"\u0AE6",
+ 'zerogurmukhi' : u"\u0A66",
+ 'zerohackarabic' : u"\u0660",
+ 'zeroinferior' : u"\u2080",
+ 'zeromonospace' : u"\uFF10",
+ 'zerooldstyle' : u"\uF730",
+ 'zeropersian' : u"\u06F0",
+ 'zerosuperior' : u"\u2070",
+ 'zerothai' : u"\u0E50",
+ 'zerowidthjoiner' : u"\uFEFF",
+ 'zerowidthnonjoiner' : u"\u200C",
+ 'zerowidthspace' : u"\u200B",
+ 'zhbopomofo' : u"\u3113",
+ 'zhearmenian' : u"\u056A",
+ 'zhebrevecyrillic' : u"\u04C2",
+ 'zhecyrillic' : u"\u0436",
+ 'zhedescendercyrillic' : u"\u0497",
+ 'zhedieresiscyrillic' : u"\u04DD",
+ 'zihiragana' : u"\u3058",
+ 'zikatakana' : u"\u30B8",
+ 'zinorhebrew' : u"\u05AE",
+ 'zlinebelow' : u"\u1E95",
+ 'zmonospace' : u"\uFF5A",
+ 'zohiragana' : u"\u305E",
+ 'zokatakana' : u"\u30BE",
+ 'zparen' : u"\u24B5",
+ 'zretroflexhook' : u"\u0290",
+ 'zstroke' : u"\u01B6",
+ 'zuhiragana' : u"\u305A",
+ 'zukatakana' : u"\u30BA"
+ }
+
+for k, v in uniToPsnameMap.items() :
+ aglToUniMap[v] = unichr(int(k, 16))
+
+def parse(name) :
+ res = []
+ return res
+
+class Name(object) :
+ def __init__(self, name = None, finalcomp = False) :
+ self.psname = name
+ self.components = []
+ self.ext = None
+ self.cname = None
+ self.GDLName = None
+ self.finalcomp = finalcomp
+ if not name : return
+
+ # Determine the components for any glyph that represents multiple USVs.
+ for comp in name.split("_") :
+ base, dot, mod = comp.partition(".")
+ if not base and mod :
+ base = dot + mod
+ mod = None
+ else :
+ mod = mod.split(".")
+ if re.match(r"^uni[0-9A-Fa-f]{4}", base) :
+ self.components.extend((int(x, 16), None) for x in re.findall(r"[0-9A-Fa-f]{4}", base))
+ if mod :
+ self.components[-1] = (self.components[-1][0], mod)
+ elif re.match(r"^u?[0-9A-Fa-f]{4,6}$", base) :
+ if base[0] == 'u' :
+ self.components.append((int(base[1:], 16), mod))
+ else :
+ self.components.append((int(base, 16), mod))
+ elif base in aglToUniMap :
+ self.components.append((ord(aglToUniMap[base]), mod))
+ elif len(self.components) :
+ self.components[-1] = (self.components[-1][0], mod)
+ else :
+ self.components.append((base, mod))
+ if not finalcomp or len(self.components) == 1 :
+ if self.components[-1][1] :
+ self.ext = self.components[-1][1].pop()
+ if not len(self.components[-1][1]) :
+ self.components[-1] = (self.components[-1][0], None)
+ if self.ext and not self.components[-1][0] :
+ self.components.pop()
+ self.canonical()
+ return
+
+ @classmethod
+ def createFromGDL(cls, name) :
+ """Convert from GDLName back to canonical name. An inexact science"""
+ self = cls()
+ if name.startswith("g_") :
+ name = name[2:]
+ # assume only first letter can be capitalised, everything else is components
+ if name.startswith("_") :
+ c = name[1].upper()
+ name = name[2:]
+ else :
+ c = name[0]
+ name = name[1:]
+ cs = name.split("_")
+ cs[0] = c + cs[0]
+ for i in range(len(cs)) :
+ if cs[i] in aglToUniMap :
+ self.components.append((0, c))
+ else :
+ self.ext = ".".join(cs[i:])
+ break
+ self.psname = self.canonical()
+ return self
+
+ # Calculate the canonical name (if necessary) and return it.
+ def canonical(self, noprefix = False) :
+ if self.cname and not noprefix : return self.cname
+ res = ""
+ if not len(self.components) :
+ self.cname = self.psname
+ return self.cname
+ for k in self.components :
+ u = k[0]
+ if not isinstance(u, basestring) and u :
+ n = "%04X" % u
+ else :
+ n = u
+ if not u :
+ pass
+ elif n in uniToPsnameMap :
+ res += uniToPsnameMap[n]
+ elif not res and not noprefix :
+ res = "u" + n
+ else :
+ res += n
+ if k[1] :
+ res += "." + ".".join(k[1])
+ res += "_"
+ cname = res[0:-1]
+ if self.ext :
+ cname += "." + self.ext
+ if not noprefix : self.cname = cname
+ return cname
+
+ def GDL(self) :
+ if self.GDLName :
+ return self.GDLName
+ res = ""
+ if not len(self.components) :
+ if not self.psname :
+ return None
+
+ res = "g_" + self.psname.replace('.', '_')
+ self.GDLName = re.sub(r"([A-Z])", lambda x : "_" + x.group(1).lower(), res)
+ return self.GDLName
+
+ for k in self.components :
+ u = k[0]
+ if not isinstance(u, basestring) and u :
+ n = "%04X" % u
+ elif u :
+ n = u.replace('.', '_')
+
+ if not u :
+ pass
+ elif n in uniToPsnameMap :
+ if not res : res = "g_"
+ res += re.sub("([A-Z])", lambda x : "_" + x.group(1).lower(), uniToPsnameMap[n])
+ elif not res :
+ res = "g" + n.lower()
+ else :
+ res += n.lower()
+ if res and k[1] :
+ res += "_" + "_".join(k[1])
+ res += "_"
+
+ self.GDLName = res[0:-1]
+
+ if self.ext :
+ self.GDLName += "_" + self.ext.lower().replace('.', '_')
+
+ if self.GDLName == "" : # last resort for some names
+ self.GDLName = "g" + self.psname
+ if self.GDLName[0:1] == "_" :
+ self.GDLName = "g" + self.GDLName
+
+ return self.GDLName
+
+ def head(self) :
+ res = Name()
+ comps = list(self.components)
+ if len(comps) and not self.ext :
+ comps[-1] = (comps[-1], None)
+ res.components = comps
+ return res
+
+ def split_last(self) :
+ if len(self.components) < 2 :
+ return (self, None)
+ head = Name(finalcomp = self.finalcomp)
+ head.components = self.components[:-1]
+ head.ext = self.ext
+ head.psname = head.canonical()
+ tail = Name(finalcomp = self.finalcomp)
+ tail.components = [self.components[-1]]
+ tail.ext = self.ext
+ tail.psname = tail.canonical()
+ return (head, tail)
+
+ def __str__(self) : return self.psname
+
diff --git a/examples/preflight b/examples/preflight
new file mode 100755
index 0000000..65e790c
--- /dev/null
+++ b/examples/preflight
@@ -0,0 +1,9 @@
+#!/bin/sh
+# Sample script for calling multiple routines on a project, typically prior to committing to a repository.
+# Place this in root of a project, adjust the font path, then set it to be executable by typing:
+# chmod +x preflight
+
+psfnormalize -p checkfix=fix source/font-Regular.ufo
+psfnormalize -p checkfix=fix source/font-Bold.ufo
+
+psfsyncmasters source/font-RB.designspace
diff --git a/examples/psfaddGlyphDemo.py b/examples/psfaddGlyphDemo.py
new file mode 100755
index 0000000..d933c65
--- /dev/null
+++ b/examples/psfaddGlyphDemo.py
@@ -0,0 +1,53 @@
+#!/usr/bin/env python
+'''Demo script for UFOlib to add a glyph to a UFO font'''
+__url__ = 'http://github.com/silnrsi/pysilfont'
+__copyright__ = 'Copyright (c) 2015 SIL International (http://www.sil.org)'
+__license__ = 'Released under the MIT License (http://opensource.org/licenses/MIT)'
+__author__ = 'David Raymond'
+
+from silfont.core import execute
+import silfont.ufo as ufo
+from xml.etree import cElementTree as ET
+
+suffix = '_addGlyph'
+argspec = [
+ ('ifont',{'help': 'Input font file'}, {'type': 'infont'}),
+ ('ofont',{'help': 'Output font file','nargs': '?' }, {'type': 'outfont'}),
+ ('-l','--log',{'help': 'Log file'}, {'type': 'outfile', 'def': suffix+'log'})]
+
+def doit(args) :
+ ''' This will add the following glyph to the font
+
+ <?xml version="1.0" encoding="UTF-8"?>
+ <glyph name="Test" format="1">
+ <unicode hex="007D"/>
+ <outline>
+ <contour>
+ <point x="275" y="1582" type="line"/>
+ <point x="275" y="-493" type="line"/>
+ </contour>
+ </outline>
+ </glyph>
+ '''
+
+ font = args.ifont
+
+ # Create basic glyph
+ newglyph = ufo.Uglif(layer = font.deflayer, name = "Test")
+ newglyph.add("unicode", {"hex": "007D"})
+ # Add an outline
+ newglyph.add("outline")
+ # Create a contour and add to outline
+ element = ET.Element("contour")
+ ET.SubElement(element, "point", {"x": "275", "y": "1582", "type": "line"})
+ ET.SubElement(element, "point", {"x": "275", "y": "-493", "type": "line"})
+ contour =ufo.Ucontour(newglyph["outline"],element)
+ newglyph["outline"].appendobject(contour, "contour")
+
+ font.deflayer.addGlyph(newglyph)
+
+ return args.ifont
+
+def cmd() : execute("UFO",doit,argspec)
+if __name__ == "__main__": cmd()
+
diff --git a/examples/psfexpandstroke.py b/examples/psfexpandstroke.py
new file mode 100755
index 0000000..32eb504
--- /dev/null
+++ b/examples/psfexpandstroke.py
@@ -0,0 +1,641 @@
+#!/usr/bin/env python
+from __future__ import unicode_literals
+'''Expands an unclosed UFO stroke font into monoline forms with a fixed width'''
+__url__ = 'http://github.com/silnrsi/pysilfont'
+__copyright__ = 'Copyright (c) 2017 SIL International (http://www.sil.org), based on outlinerRoboFontExtension Copyright (c) 2016 Frederik Berlaen'
+__license__ = 'Released under the MIT License (http://opensource.org/licenses/MIT)'
+__author__ = 'Victor Gaultney'
+
+# Usage: psfexpandstroke ifont ofont expansion
+# expansion is the number of units added to each side of the stroke
+
+# To Do
+# - Simplify to assume round caps and corners
+
+# main input, output, and execution handled by pysilfont framework
+from silfont.core import execute
+
+from fontTools.pens.basePen import BasePen
+from fontTools.misc.bezierTools import splitCubicAtT
+from robofab.world import OpenFont
+from robofab.pens.pointPen import AbstractPointPen
+from robofab.pens.reverseContourPointPen import ReverseContourPointPen
+from robofab.pens.adapterPens import PointToSegmentPen
+
+from defcon import Glyph
+
+from math import sqrt, cos, sin, acos, asin, degrees, radians, pi
+
+suffix = '_expanded'
+argspec = [
+ ('ifont',{'help': 'Input font file'}, {'type': 'filename'}),
+ ('ofont',{'help': 'Output font file','nargs': '?' }, {'type': 'filename', 'def': "_"+suffix}),
+ ('thickness',{'help': 'Stroke thickness'}, {}),
+ ('-l','--log',{'help': 'Log file'}, {'type': 'outfile', 'def': suffix+'.log'})]
+
+
+# The following functions are straight from outlinerRoboFontExtension
+
+def roundFloat(f):
+ error = 1000000.
+ return round(f*error)/error
+
+def checkSmooth(firstAngle, lastAngle):
+ if firstAngle is None or lastAngle is None:
+ return True
+ error = 4
+ firstAngle = degrees(firstAngle)
+ lastAngle = degrees(lastAngle)
+
+ if int(firstAngle) + error >= int(lastAngle) >= int(firstAngle) - error:
+ return True
+ return False
+
+def checkInnerOuter(firstAngle, lastAngle):
+ if firstAngle is None or lastAngle is None:
+ return True
+ dirAngle = degrees(firstAngle) - degrees(lastAngle)
+
+ if dirAngle > 180:
+ dirAngle = 180 - dirAngle
+ elif dirAngle < -180:
+ dirAngle = -180 - dirAngle
+
+ if dirAngle > 0:
+ return True
+
+ if dirAngle <= 0:
+ return False
+
+
+def interSect((seg1s, seg1e), (seg2s, seg2e)):
+ denom = (seg2e.y - seg2s.y)*(seg1e.x - seg1s.x) - (seg2e.x - seg2s.x)*(seg1e.y - seg1s.y)
+ if roundFloat(denom) == 0:
+ # print 'parallel: %s' % denom
+ return None
+ uanum = (seg2e.x - seg2s.x)*(seg1s.y - seg2s.y) - (seg2e.y - seg2s.y)*(seg1s.x - seg2s.x)
+ ubnum = (seg1e.x - seg1s.x)*(seg1s.y - seg2s.y) - (seg1e.y - seg1s.y)*(seg1s.x - seg2s.x)
+ ua = uanum / denom
+ # ub = ubnum / denom
+ x = seg1s.x + ua*(seg1e.x - seg1s.x)
+ y = seg1s.y + ua*(seg1e.y - seg1s.y)
+ return MathPoint(x, y)
+
+
+def pointOnACurve((x1, y1), (cx1, cy1), (cx2, cy2), (x2, y2), value):
+ dx = x1
+ cx = (cx1 - dx) * 3.0
+ bx = (cx2 - cx1) * 3.0 - cx
+ ax = x2 - dx - cx - bx
+ dy = y1
+ cy = (cy1 - dy) * 3.0
+ by = (cy2 - cy1) * 3.0 - cy
+ ay = y2 - dy - cy - by
+ mx = ax*(value)**3 + bx*(value)**2 + cx*(value) + dx
+ my = ay*(value)**3 + by*(value)**2 + cy*(value) + dy
+ return MathPoint(mx, my)
+
+
+class MathPoint(object):
+
+ def __init__(self, x, y=None):
+ if y is None:
+ x, y = x
+ self.x = x
+ self.y = y
+
+ def __repr__(self):
+ return "<MathPoint x:%s y:%s>" % (self.x, self.y)
+
+ def __getitem__(self, index):
+ if index == 0:
+ return self.x
+ if index == 1:
+ return self.y
+ raise IndexError
+
+ def __iter__(self):
+ for value in [self.x, self.y]:
+ yield value
+
+ def __add__(self, p): # p+ p
+ if not isinstance(p, self.__class__):
+ return self.__class__(self.x + p, self.y + p)
+ return self.__class__(self.x + p.x, self.y + p.y)
+
+ def __sub__(self, p): # p - p
+ if not isinstance(p, self.__class__):
+ return self.__class__(self.x - p, self.y - p)
+ return self.__class__(self.x - p.x, self.y - p.y)
+
+ def __mul__(self, p): # p * p
+ if not isinstance(p, self.__class__):
+ return self.__class__(self.x * p, self.y * p)
+ return self.__class__(self.x * p.x, self.y * p.y)
+
+ def __div__(self, p):
+ if not isinstance(p, self.__class__):
+ return self.__class__(self.x / p, self.y / p)
+ return self.__class__(self.x / p.x, self.y / p.y)
+
+ def __eq__(self, p): # if p == p
+ if not isinstance(p, self.__class__):
+ return False
+ return roundFloat(self.x) == roundFloat(p.x) and roundFloat(self.y) == roundFloat(p.y)
+
+ def __ne__(self, p): # if p != p
+ return not self.__eq__(p)
+
+ def copy(self):
+ return self.__class__(self.x, self.y)
+
+ def round(self):
+ self.x = round(self.x)
+ self.y = round(self.y)
+
+ def distance(self, p):
+ return sqrt((p.x - self.x)**2 + (p.y - self.y)**2)
+
+ def angle(self, other, add=90):
+ # returns the angle of a Line in radians
+ b = other.x - self.x
+ a = other.y - self.y
+ c = sqrt(a**2 + b**2)
+ if c == 0:
+ return None
+ if add is None:
+ return b/c
+ cosAngle = degrees(acos(b/c))
+ sinAngle = degrees(asin(a/c))
+ if sinAngle < 0:
+ cosAngle = 360 - cosAngle
+ return radians(cosAngle + add)
+
+
+class CleanPointPen(AbstractPointPen):
+
+ def __init__(self, pointPen):
+ self.pointPen = pointPen
+ self.currentContour = None
+
+ def processContour(self):
+ pointPen = self.pointPen
+ contour = self.currentContour
+
+ index = 0
+ prevAngle = None
+ toRemove = []
+ for data in contour:
+ if data["segmentType"] in ["line", "move"]:
+ prevPoint = contour[index-1]
+ if prevPoint["segmentType"] in ["line", "move"]:
+ angle = MathPoint(data["point"]).angle(MathPoint(prevPoint["point"]))
+ if prevAngle is not None and angle is not None and roundFloat(prevAngle) == roundFloat(angle):
+ prevPoint["uniqueID"] = id(prevPoint)
+ toRemove.append(prevPoint)
+ prevAngle = angle
+ else:
+ prevAngle = None
+ else:
+ prevAngle = None
+ index += 1
+
+ for data in toRemove:
+ contour.remove(data)
+
+ pointPen.beginPath()
+ for data in contour:
+ pointPen.addPoint(data["point"], **data)
+ pointPen.endPath()
+
+ def beginPath(self):
+ assert self.currentContour is None
+ self.currentContour = []
+ self.onCurve = []
+
+ def endPath(self):
+ assert self.currentContour is not None
+ self.processContour()
+ self.currentContour = None
+
+ def addPoint(self, pt, segmentType=None, smooth=False, name=None, **kwargs):
+ data = dict(point=pt, segmentType=segmentType, smooth=smooth, name=name)
+ data.update(kwargs)
+ self.currentContour.append(data)
+
+ def addComponent(self, glyphName, transform):
+ assert self.currentContour is None
+ self.pointPen.addComponent(glyphName, transform)
+
+# The following class has been been adjusted to work around how outline types use closePath() and endPath(),
+# to remove unneeded bits, and hard-code some assumptions.
+
+class OutlinePen(BasePen):
+
+ pointClass = MathPoint
+ magicCurve = 0.5522847498
+
+ def __init__(self, glyphSet, offset=10, contrast=0, contrastAngle=0, connection="round", cap="round", miterLimit=None, optimizeCurve=True):
+ BasePen.__init__(self, glyphSet)
+
+ self.offset = abs(offset)
+ self.contrast = abs(contrast)
+ self.contrastAngle = contrastAngle
+ self._inputmiterLimit = miterLimit
+ if miterLimit is None:
+ miterLimit = self.offset * 2
+ self.miterLimit = abs(miterLimit)
+
+ self.optimizeCurve = optimizeCurve
+
+ self.connectionCallback = getattr(self, "connection%s" % (connection.title()))
+ self.capCallback = getattr(self, "cap%s" % (cap.title()))
+
+ self.originalGlyph = Glyph()
+ self.originalPen = self.originalGlyph.getPen()
+
+ self.outerGlyph = Glyph()
+ self.outerPen = self.outerGlyph.getPen()
+ self.outerCurrentPoint = None
+ self.outerFirstPoint = None
+ self.outerPrevPoint = None
+
+ self.innerGlyph = Glyph()
+ self.innerPen = self.innerGlyph.getPen()
+ self.innerCurrentPoint = None
+ self.innerFirstPoint = None
+ self.innerPrevPoint = None
+
+ self.prevPoint = None
+ self.firstPoint = None
+ self.firstAngle = None
+ self.prevAngle = None
+
+ self.shouldHandleMove = True
+
+ self.components = []
+
+ self.drawSettings()
+
+ def _moveTo(self, (x, y)):
+ if self.offset == 0:
+ self.outerPen.moveTo((x, y))
+ self.innerPen.moveTo((x, y))
+ return
+ self.originalPen.moveTo((x, y))
+
+ p = self.pointClass(x, y)
+ self.prevPoint = p
+ self.firstPoint = p
+ self.shouldHandleMove = True
+
+ def _lineTo(self, (x, y)):
+ if self.offset == 0:
+ self.outerPen.lineTo((x, y))
+ self.innerPen.lineTo((x, y))
+ return
+ self.originalPen.lineTo((x, y))
+
+ currentPoint = self.pointClass(x, y)
+ if currentPoint == self.prevPoint:
+ return
+
+ self.currentAngle = self.prevPoint.angle(currentPoint)
+ thickness = self.getThickness(self.currentAngle)
+ self.innerCurrentPoint = self.prevPoint - self.pointClass(cos(self.currentAngle), sin(self.currentAngle)) * thickness
+ self.outerCurrentPoint = self.prevPoint + self.pointClass(cos(self.currentAngle), sin(self.currentAngle)) * thickness
+
+ if self.shouldHandleMove:
+ self.shouldHandleMove = False
+
+ self.innerPen.moveTo(self.innerCurrentPoint)
+ self.innerFirstPoint = self.innerCurrentPoint
+
+ self.outerPen.moveTo(self.outerCurrentPoint)
+ self.outerFirstPoint = self.outerCurrentPoint
+
+ self.firstAngle = self.currentAngle
+ else:
+ self.buildConnection()
+
+ self.innerCurrentPoint = currentPoint - self.pointClass(cos(self.currentAngle), sin(self.currentAngle)) * thickness
+ self.innerPen.lineTo(self.innerCurrentPoint)
+ self.innerPrevPoint = self.innerCurrentPoint
+
+ self.outerCurrentPoint = currentPoint + self.pointClass(cos(self.currentAngle), sin(self.currentAngle)) * thickness
+ self.outerPen.lineTo(self.outerCurrentPoint)
+ self.outerPrevPoint = self.outerCurrentPoint
+
+ self.prevPoint = currentPoint
+ self.prevAngle = self.currentAngle
+
+ def _curveToOne(self, (x1, y1), (x2, y2), (x3, y3)):
+ if self.optimizeCurve:
+ curves = splitCubicAtT(self.prevPoint, (x1, y1), (x2, y2), (x3, y3), .5)
+ else:
+ curves = [(self.prevPoint, (x1, y1), (x2, y2), (x3, y3))]
+ for curve in curves:
+ p1, h1, h2, p2 = curve
+ self._processCurveToOne(h1, h2, p2)
+
+ def _processCurveToOne(self, (x1, y1), (x2, y2), (x3, y3)):
+ if self.offset == 0:
+ self.outerPen.curveTo((x1, y1), (x2, y2), (x3, y3))
+ self.innerPen.curveTo((x1, y1), (x2, y2), (x3, y3))
+ return
+ self.originalPen.curveTo((x1, y1), (x2, y2), (x3, y3))
+
+ p1 = self.pointClass(x1, y1)
+ p2 = self.pointClass(x2, y2)
+ p3 = self.pointClass(x3, y3)
+
+ if p1 == self.prevPoint:
+ p1 = pointOnACurve(self.prevPoint, p1, p2, p3, 0.01)
+ if p2 == p3:
+ p2 = pointOnACurve(self.prevPoint, p1, p2, p3, 0.99)
+
+ a1 = self.prevPoint.angle(p1)
+ a2 = p2.angle(p3)
+
+ self.currentAngle = a1
+ tickness1 = self.getThickness(a1)
+ tickness2 = self.getThickness(a2)
+
+ a1bis = self.prevPoint.angle(p1, 0)
+ a2bis = p3.angle(p2, 0)
+ intersectPoint = interSect((self.prevPoint, self.prevPoint + self.pointClass(cos(a1), sin(a1)) * 100),
+ (p3, p3 + self.pointClass(cos(a2), sin(a2)) * 100))
+ self.innerCurrentPoint = self.prevPoint - self.pointClass(cos(a1), sin(a1)) * tickness1
+ self.outerCurrentPoint = self.prevPoint + self.pointClass(cos(a1), sin(a1)) * tickness1
+
+ if self.shouldHandleMove:
+ self.shouldHandleMove = False
+
+ self.innerPen.moveTo(self.innerCurrentPoint)
+ self.innerFirstPoint = self.innerPrevPoint = self.innerCurrentPoint
+
+ self.outerPen.moveTo(self.outerCurrentPoint)
+ self.outerFirstPoint = self.outerPrevPoint = self.outerCurrentPoint
+
+ self.firstAngle = a1
+ else:
+ self.buildConnection()
+
+ h1 = None
+ if intersectPoint is not None:
+ h1 = interSect((self.innerCurrentPoint, self.innerCurrentPoint + self.pointClass(cos(a1bis), sin(a1bis)) * tickness1), (intersectPoint, p1))
+ if h1 is None:
+ h1 = p1 - self.pointClass(cos(a1), sin(a1)) * tickness1
+
+ self.innerCurrentPoint = p3 - self.pointClass(cos(a2), sin(a2)) * tickness2
+
+ h2 = None
+ if intersectPoint is not None:
+ h2 = interSect((self.innerCurrentPoint, self.innerCurrentPoint + self.pointClass(cos(a2bis), sin(a2bis)) * tickness2), (intersectPoint, p2))
+ if h2 is None:
+ h2 = p2 - self.pointClass(cos(a1), sin(a1)) * tickness1
+
+ self.innerPen.curveTo(h1, h2, self.innerCurrentPoint)
+ self.innerPrevPoint = self.innerCurrentPoint
+
+ ########
+ h1 = None
+ if intersectPoint is not None:
+ h1 = interSect((self.outerCurrentPoint, self.outerCurrentPoint + self.pointClass(cos(a1bis), sin(a1bis)) * tickness1), (intersectPoint, p1))
+ if h1 is None:
+ h1 = p1 + self.pointClass(cos(a1), sin(a1)) * tickness1
+
+ self.outerCurrentPoint = p3 + self.pointClass(cos(a2), sin(a2)) * tickness2
+
+ h2 = None
+ if intersectPoint is not None:
+ h2 = interSect((self.outerCurrentPoint, self.outerCurrentPoint + self.pointClass(cos(a2bis), sin(a2bis)) * tickness2), (intersectPoint, p2))
+ if h2 is None:
+ h2 = p2 + self.pointClass(cos(a1), sin(a1)) * tickness1
+ self.outerPen.curveTo(h1, h2, self.outerCurrentPoint)
+ self.outerPrevPoint = self.outerCurrentPoint
+
+ self.prevPoint = p3
+ self.currentAngle = a2
+ self.prevAngle = a2
+
+ def _closePath(self):
+ if self.shouldHandleMove:
+ return
+
+ self.originalPen.endPath()
+ self.innerPen.endPath()
+ self.outerPen.endPath()
+
+ innerContour = self.innerGlyph[-1]
+ outerContour = self.outerGlyph[-1]
+
+ innerContour.reverse()
+
+ innerContour[0].segmentType = "line"
+ outerContour[0].segmentType = "line"
+
+ self.buildCap(outerContour, innerContour)
+
+ for point in innerContour:
+ outerContour.addPoint((point.x, point.y), segmentType=point.segmentType, smooth=point.smooth)
+
+ self.innerGlyph.removeContour(innerContour)
+
+ def _endPath(self):
+ # The current way glyph outlines are processed means that _endPath() would not be called
+ # _closePath() is used instead
+ pass
+
+ def addComponent(self, glyphName, transform):
+ self.components.append((glyphName, transform))
+
+ # thickness
+
+ def getThickness(self, angle):
+ a2 = angle + pi * .5
+ f = abs(sin(a2 + radians(self.contrastAngle)))
+ f = f ** 5
+ return self.offset + self.contrast * f
+
+ # connections
+
+ def buildConnection(self, close=False):
+ if not checkSmooth(self.prevAngle, self.currentAngle):
+ if checkInnerOuter(self.prevAngle, self.currentAngle):
+ self.connectionCallback(self.outerPrevPoint, self.outerCurrentPoint, self.outerPen, close)
+ self.connectionInnerCorner(self.innerPrevPoint, self.innerCurrentPoint, self.innerPen, close)
+ else:
+ self.connectionCallback(self.innerPrevPoint, self.innerCurrentPoint, self.innerPen, close)
+ self.connectionInnerCorner(self.outerPrevPoint, self.outerCurrentPoint, self.outerPen, close)
+
+ def connectionRound(self, first, last, pen, close):
+ angle_1 = radians(degrees(self.prevAngle)+90)
+ angle_2 = radians(degrees(self.currentAngle)+90)
+
+ tempFirst = first - self.pointClass(cos(angle_1), sin(angle_1)) * self.miterLimit
+ tempLast = last + self.pointClass(cos(angle_2), sin(angle_2)) * self.miterLimit
+
+ newPoint = interSect((first, tempFirst), (last, tempLast))
+ if newPoint is None:
+ pen.lineTo(last)
+ return
+ distance1 = newPoint.distance(first)
+ distance2 = newPoint.distance(last)
+ if roundFloat(distance1) > self.miterLimit + self.contrast:
+ distance1 = self.miterLimit + tempFirst.distance(tempLast) * .7
+ if roundFloat(distance2) > self.miterLimit + self.contrast:
+ distance2 = self.miterLimit + tempFirst.distance(tempLast) * .7
+
+ distance1 *= self.magicCurve
+ distance2 *= self.magicCurve
+
+ bcp1 = first - self.pointClass(cos(angle_1), sin(angle_1)) * distance1
+ bcp2 = last + self.pointClass(cos(angle_2), sin(angle_2)) * distance2
+ pen.curveTo(bcp1, bcp2, last)
+
+ def connectionInnerCorner(self, first, last, pen, close):
+ if not close:
+ pen.lineTo(last)
+
+ # caps
+
+ def buildCap(self, firstContour, lastContour):
+ first = firstContour[-1]
+ last = lastContour[0]
+ first = self.pointClass(first.x, first.y)
+ last = self.pointClass(last.x, last.y)
+
+ self.capCallback(firstContour, lastContour, first, last, self.prevAngle)
+
+ first = lastContour[-1]
+ last = firstContour[0]
+ first = self.pointClass(first.x, first.y)
+ last = self.pointClass(last.x, last.y)
+
+ angle = radians(degrees(self.firstAngle)+180)
+ self.capCallback(lastContour, firstContour, first, last, angle)
+
+ def capRound(self, firstContour, lastContour, first, last, angle):
+ hookedAngle = radians(degrees(angle)+90)
+
+ p1 = first - self.pointClass(cos(hookedAngle), sin(hookedAngle)) * self.offset
+
+ p2 = last - self.pointClass(cos(hookedAngle), sin(hookedAngle)) * self.offset
+
+ oncurve = p1 + (p2-p1)*.5
+
+ roundness = .54
+
+ h1 = first - self.pointClass(cos(hookedAngle), sin(hookedAngle)) * self.offset * roundness
+ h2 = oncurve + self.pointClass(cos(angle), sin(angle)) * self.offset * roundness
+
+ firstContour[-1].smooth = True
+
+ firstContour.addPoint((h1.x, h1.y))
+ firstContour.addPoint((h2.x, h2.y))
+ firstContour.addPoint((oncurve.x, oncurve.y), smooth=True, segmentType="curve")
+
+ h1 = oncurve - self.pointClass(cos(angle), sin(angle)) * self.offset * roundness
+ h2 = last - self.pointClass(cos(hookedAngle), sin(hookedAngle)) * self.offset * roundness
+
+ firstContour.addPoint((h1.x, h1.y))
+ firstContour.addPoint((h2.x, h2.y))
+
+ lastContour[0].segmentType = "curve"
+ lastContour[0].smooth = True
+
+ def drawSettings(self, drawOriginal=False, drawInner=False, drawOuter=True):
+ self.drawOriginal = drawOriginal
+ self.drawInner = drawInner
+ self.drawOuter = drawOuter
+
+ def drawPoints(self, pointPen):
+ if self.drawInner:
+ reversePen = ReverseContourPointPen(pointPen)
+ self.innerGlyph.drawPoints(CleanPointPen(reversePen))
+ if self.drawOuter:
+ self.outerGlyph.drawPoints(CleanPointPen(pointPen))
+
+ if self.drawOriginal:
+ if self.drawOuter:
+ pointPen = ReverseContourPointPen(pointPen)
+ self.originalGlyph.drawPoints(CleanPointPen(pointPen))
+
+ for glyphName, transform in self.components:
+ pointPen.addComponent(glyphName, transform)
+
+ def draw(self, pen):
+ pointPen = PointToSegmentPen(pen)
+ self.drawPoints(pointPen)
+
+ def getGlyph(self):
+ glyph = Glyph()
+ pointPen = glyph.getPointPen()
+ self.drawPoints(pointPen)
+ return glyph
+
+# The following functions have been decoupled from the outlinerRoboFontExtension and
+# effectively de-parameterized, with built-in assumptions
+
+def calculate(glyph, strokewidth):
+ tickness = strokewidth
+ contrast = 0
+ contrastAngle = 0
+ keepBounds = False
+ optimizeCurve = True
+ miterLimit = None #assumed
+
+ corner = "round" #assumed - other options not supported
+ cap = "round" #assumed - other options not supported
+
+ drawOriginal = False
+ drawInner = True
+ drawOuter = True
+
+ pen = OutlinePen(glyph.getParent(),
+ tickness,
+ contrast,
+ contrastAngle,
+ connection=corner,
+ cap=cap,
+ miterLimit=miterLimit,
+ optimizeCurve=optimizeCurve)
+
+ glyph.draw(pen)
+
+ pen.drawSettings(drawOriginal=drawOriginal,
+ drawInner=drawInner,
+ drawOuter=drawOuter)
+
+ result = pen.getGlyph()
+
+ return result
+
+
+def expandGlyph(glyph, strokewidth):
+ defconGlyph = glyph
+ outline = calculate(defconGlyph, strokewidth)
+
+ glyph.clearContours()
+ outline.drawPoints(glyph.getPointPen())
+
+ glyph.round()
+
+def expandFont(targetfont, strokewidth):
+ font = targetfont
+ for glyph in font:
+ expandGlyph(glyph, strokewidth)
+
+def doit(args):
+ infont = OpenFont(args.ifont)
+ outfont = args.ofont
+ # add try to catch bad input
+ strokewidth = int(args.thickness)
+ expandFont(infont, strokewidth)
+ infont.save(outfont)
+
+ return infont
+
+def cmd() : execute(None,doit,argspec)
+if __name__ == "__main__": cmd()
diff --git a/examples/psfexportnamesunicodesfp.py b/examples/psfexportnamesunicodesfp.py
new file mode 100644
index 0000000..402f930
--- /dev/null
+++ b/examples/psfexportnamesunicodesfp.py
@@ -0,0 +1,30 @@
+#!/usr/bin/env python3
+'''Outputs an unsorted csv file containing the names of all the glyphs in the default layer
+and their primary unicode values. Format name,usv'''
+__url__ = 'http://github.com/silnrsi/pysilfont'
+__copyright__ = 'Copyright (c) 2018 SIL International (http://www.sil.org)'
+__license__ = 'Released under the MIT License (http://opensource.org/licenses/MIT)'
+__author__ = 'Victor Gaultney'
+
+from silfont.core import execute
+
+suffix = "_namesunicodes"
+
+argspec = [
+ ('ifont', {'help': 'Input font file'}, {'type': 'infont'}),
+ ('-o','--output',{'help': 'Output csv file'}, {'type': 'outfile', 'def': suffix+'.csv'})]
+
+def doit(args) :
+ font = args.ifont
+ outfile = args.output
+
+ for glyph in font:
+ unival = ""
+ if glyph.unicode:
+ unival = str.upper(hex(glyph.unicode))[2:7].zfill(4)
+ outfile.write(glyph.name + "," + unival + "\n")
+
+ print("Done")
+
+def cmd() : execute("FP",doit,argspec)
+if __name__ == "__main__": cmd()
diff --git a/examples/psfgenftml.py b/examples/psfgenftml.py
new file mode 100644
index 0000000..46fa749
--- /dev/null
+++ b/examples/psfgenftml.py
@@ -0,0 +1,189 @@
+#!/usr/bin/python3
+'''
+Example script to generate ftml document from glyph_data.csv and UFO.
+
+To try this with the Harmattan font project:
+ 1) clone and build Harmattan:
+ clone https://github.com/silnrsi/font-harmattan
+ cd font-harmattan
+ smith configure
+ smith build ftml
+ 2) run psfgenftml as follows:
+ python3 psfgenftml.py \
+ -t "AllChars" \
+ --ap "_?dia[AB]$" \
+ --xsl ../tools/lib/ftml.xsl \
+ --scale 200 \
+ -i source/glyph_data.csv \
+ -s "url(../references/Harmattan-Regular-v1.ttf)=ver 1" \
+ -s "url(../results/Harmattan-Regular.ttf)=Reg-GR" \
+ -s "url(../results/tests/ftml/fonts/Harmattan-Regular_ot_arab.ttf)=Reg-OT" \
+ source/Harmattan-Regular.ufo tests/AllChars-dev.ftml
+ 3) launch resulting output file, tests/AllChars-dev.ftml, in a browser.
+ (see http://silnrsi.github.io/FDBP/en-US/Browsers%20as%20a%20font%20test%20platform.html)
+ NB: Using Firefox will allow simultaneous display of both Graphite and OpenType rendering
+ 4) As above but substitute:
+ -t "Diac Test" for the -t parameter
+ tests/DiacTest-dev.ftml for the final parameter
+ and launch tests/DiacTest-dev.ftml in a browser.
+'''
+__url__ = 'http://github.com/silnrsi/pysilfont'
+__copyright__ = 'Copyright (c) 2018,2021 SIL International (http://www.sil.org)'
+__license__ = 'Released under the MIT License (http://opensource.org/licenses/MIT)'
+__author__ = 'Bob Hallissy'
+
+import re
+from silfont.core import execute
+import silfont.ftml_builder as FB
+
+argspec = [
+ ('ifont', {'help': 'Input UFO'}, {'type': 'infont'}),
+ ('output', {'help': 'Output file ftml in XML format', 'nargs': '?'}, {'type': 'outfile', 'def': '_out.ftml'}),
+ ('-i','--input', {'help': 'Glyph info csv file'}, {'type': 'incsv', 'def': 'glyph_data.csv'}),
+ ('-f','--fontcode', {'help': 'letter to filter for glyph_data'},{}),
+ ('-l','--log', {'help': 'Set log file name'}, {'type': 'outfile', 'def': '_ftml.log'}),
+ ('--langs', {'help':'List of bcp47 language tags', 'default': None}, {}),
+ ('--rtl', {'help': 'enable right-to-left features', 'action': 'store_true'}, {}),
+ ('--norendercheck', {'help': 'do not include the RenderingUnknown check', 'action': 'store_true'}, {}),
+ ('-t', '--test', {'help': 'name of the test to generate', 'default': None}, {}),
+ ('-s','--fontsrc', {'help': 'font source: "url()" or "local()" optionally followed by "=label"', 'action': 'append'}, {}),
+ ('--scale', {'help': 'percentage to scale rendered text (default 100)'}, {}),
+ ('--ap', {'help': 'regular expression describing APs to examine', 'default': '.'}, {}),
+ ('-w', '--width', {'help': 'total width of all <string> column (default automatic)'}, {}),
+ ('--xsl', {'help': 'XSL stylesheet to use'}, {}),
+]
+
+
+def doit(args):
+ logger = args.logger
+
+ # Read input csv
+ builder = FB.FTMLBuilder(logger, incsv=args.input, fontcode=args.fontcode, font=args.ifont, ap=args.ap,
+ rtlenable=True, langs=args.langs)
+
+ # Override default base (25CC) for displaying combining marks:
+ builder.diacBase = 0x0628 # beh
+
+ # Initialize FTML document:
+ # Default name for test: AllChars or something based on the csvdata file:
+ test = args.test or 'AllChars (NG)'
+ widths = None
+ if args.width:
+ try:
+ width, units = re.match(r'(\d+)(.*)$', args.width).groups()
+ if len(args.fontsrc):
+ width = int(round(int(width)/len(args.fontsrc)))
+ widths = {'string': f'{width}{units}'}
+ logger.log(f'width: {args.width} --> {widths["string"]}', 'I')
+ except:
+ logger.log(f'Unable to parse width argument "{args.width}"', 'W')
+ # split labels from fontsource parameter
+ fontsrc = []
+ labels = []
+ for sl in args.fontsrc:
+ try:
+ s, l = sl.split('=',1)
+ fontsrc.append(s)
+ labels.append(l)
+ except ValueError:
+ fontsrc.append(sl)
+ labels.append(None)
+ ftml = FB.FTML(test, logger, rendercheck=not args.norendercheck, fontscale=args.scale,
+ widths=widths, xslfn=args.xsl, fontsrc=fontsrc, fontlabel=labels, defaultrtl=args.rtl)
+
+ if test.lower().startswith("allchars"):
+ # all chars that should be in the font:
+ ftml.startTestGroup('Encoded characters')
+ for uid in sorted(builder.uids()):
+ if uid < 32: continue
+ c = builder.char(uid)
+ # iterate over all permutations of feature settings that might affect this character:
+ for featlist in builder.permuteFeatures(uids = (uid,)):
+ ftml.setFeatures(featlist)
+ builder.render((uid,), ftml)
+ # Don't close test -- collect consecutive encoded chars in a single row
+ ftml.clearFeatures()
+ for langID in sorted(c.langs):
+ ftml.setLang(langID)
+ builder.render((uid,), ftml)
+ ftml.clearLang()
+
+ # Add unencoded specials and ligatures -- i.e., things with a sequence of USVs in the glyph_data:
+ ftml.startTestGroup('Specials & ligatures from glyph_data')
+ for basename in sorted(builder.specials()):
+ special = builder.special(basename)
+ # iterate over all permutations of feature settings that might affect this special
+ for featlist in builder.permuteFeatures(uids = special.uids):
+ ftml.setFeatures(featlist)
+ builder.render(special.uids, ftml)
+ # close test so each special is on its own row:
+ ftml.closeTest()
+ ftml.clearFeatures()
+ if len(special.langs):
+ for langID in sorted(special.langs):
+ ftml.setLang(langID)
+ builder.render(special.uids, ftml)
+ ftml.closeTest()
+ ftml.clearLang()
+
+ # Add Lam-Alef data manually
+ ftml.startTestGroup('Lam-Alef')
+ # generate list of lam and alef characters that should be in the font:
+ lamlist = list(filter(lambda x: x in builder.uids(), (0x0644, 0x06B5, 0x06B6, 0x06B7, 0x06B8, 0x076A, 0x08A6)))
+ aleflist = list(filter(lambda x: x in builder.uids(), (0x0627, 0x0622, 0x0623, 0x0625, 0x0671, 0x0672, 0x0673, 0x0675, 0x0773, 0x0774)))
+ # iterate over all combinations:
+ for lam in lamlist:
+ for alef in aleflist:
+ for featlist in builder.permuteFeatures(uids = (lam, alef)):
+ ftml.setFeatures(featlist)
+ builder.render((lam,alef), ftml)
+ # close test so each combination is on its own row:
+ ftml.closeTest()
+ ftml.clearFeatures()
+
+ if test.lower().startswith("diac"):
+ # Diac attachment:
+
+ # Representative base and diac chars:
+ repDiac = list(filter(lambda x: x in builder.uids(), (0x064E, 0x0650, 0x065E, 0x0670, 0x0616, 0x06E3, 0x08F0, 0x08F2)))
+ repBase = list(filter(lambda x: x in builder.uids(), (0x0627, 0x0628, 0x062B, 0x0647, 0x064A, 0x77F, 0x08AC)))
+
+ ftml.startTestGroup('Representative diacritics on all bases that take diacritics')
+ for uid in sorted(builder.uids()):
+ # ignore some I don't care about:
+ if uid < 32 or uid in (0xAA, 0xBA): continue
+ c = builder.char(uid)
+ # Always process Lo, but others only if that take marks:
+ if c.general == 'Lo' or c.isBase:
+ for diac in repDiac:
+ for featlist in builder.permuteFeatures(uids = (uid,diac)):
+ ftml.setFeatures(featlist)
+ # Don't automatically separate connecting or mirrored forms into separate lines:
+ builder.render((uid,diac), ftml, addBreaks = False)
+ ftml.clearFeatures()
+ ftml.closeTest()
+
+ ftml.startTestGroup('All diacritics on representative bases')
+ for uid in sorted(builder.uids()):
+ # ignore non-ABS marks
+ if uid < 0x600 or uid in range(0xFE00, 0xFE10): continue
+ c = builder.char(uid)
+ if c.general == 'Mn':
+ for base in repBase:
+ for featlist in builder.permuteFeatures(uids = (uid,base)):
+ ftml.setFeatures(featlist)
+ builder.render((base,uid), ftml, keyUID = uid, addBreaks = False)
+ ftml.clearFeatures()
+ ftml.closeTest()
+
+ ftml.startTestGroup('Special cases')
+ builder.render((0x064A, 0x065E), ftml, comment="Yeh + Fatha should keep dots")
+ builder.render((0x064A, 0x0654), ftml, comment="Yeh + Hamza should loose dots")
+ ftml.closeTest()
+
+ # Write the output ftml file
+ ftml.writeFile(args.output)
+
+
+def cmd() : execute("UFO",doit,argspec)
+if __name__ == "__main__": cmd()
diff --git a/examples/psftidyfontlabufo.py b/examples/psftidyfontlabufo.py
new file mode 100755
index 0000000..ce54c75
--- /dev/null
+++ b/examples/psftidyfontlabufo.py
@@ -0,0 +1,102 @@
+#!/usr/bin/env python
+__doc__ = '''Make changes to a backup UFO to match some changes made to another UFO by FontLab
+When a UFO is first round-tripped through Fontlab 7, many changes are made including adding 'smooth="yes"' to many points
+in glifs and removing it from others. Also if components are after contours in a glif, then they get moved to before them.
+These changes make initial comparisons hard and can mask other changes.
+This script takes the backup of the original font that Fontlab made and writes out a new version with contours changed
+to match those in the round-tripped UFO so a diff can then be done to look for other differences.
+A glif is only changed if there are no other changes to contours.
+If also moves components to match.
+'''
+__url__ = 'http://github.com/silnrsi/pysilfont'
+__copyright__ = 'Copyright (c) 2021 SIL International (http://www.sil.org)'
+__license__ = 'Released under the MIT License (http://opensource.org/licenses/MIT)'
+__author__ = 'David Raymond'
+
+from silfont.core import execute, splitfn
+from xml.etree import ElementTree as ET
+from silfont.ufo import Ufont
+import os, glob
+
+argspec = [
+ ('ifont',{'help': 'post-fontlab ufo'}, {'type': 'infont'}),
+ ('-l','--log',{'help': 'Log file'}, {'type': 'outfile', 'def': '_tidyfontlab.log'})]
+
+def doit(args) :
+
+ flfont = args.ifont
+ logger = args.logger
+ params = args.paramsobj
+ fontname = args.ifont.ufodir
+
+ # Locate the oldest backup
+ (path, base, ext) = splitfn(fontname)
+ backuppath = os.path.join(path, base + ".*-*" + ext) # Backup has date/time added in format .yymmdd-hhmm
+ backups = glob.glob(backuppath)
+ if len(backups) == 0:
+ logger.log("No backups found matching %s so aborting..." % backuppath, "P")
+ return
+ backupname = sorted(backups)[0] # Choose the oldest backup - date/time format sorts alphabetically
+ bfont = Ufont(backupname, params=params)
+ outufoname = os.path.join(path, base + ".tidied.ufo")
+
+ fllayers = {} # Dictionary of flfont layers by layer name
+ for layer in flfont.layers: fllayers[layer.layername] = layer
+
+ for layer in bfont.layers:
+ if layer.layername not in fllayers:
+ logger.log(f"layer {layer.layername} missing", "E")
+ continue
+ fllayer = fllayers[layer.layername]
+ smoothchangecount = 0
+ compchangecount = 0
+ for gname in layer:
+ glif = layer[gname]
+ flglif = fllayer[gname]
+ if "outline" in glif and "outline" in flglif:
+ changestomake = []
+ otherchange = False
+ outline = glif["outline"]
+ floutline = flglif["outline"]
+ contours = outline.contours
+ if len(contours) != len(floutline.contours): break # Different number so can't all be identical!
+ flcontours = iter(floutline.contours)
+ for contour in contours:
+ flc = next(flcontours)
+ points = contour["point"]
+ if len(points) != len(flc["point"]): # Contours must be different
+ otherchange = True
+ break
+ flpoints = iter(flc["point"])
+ for point in points:
+ flp = next(flpoints)
+ xml = ET.tostring(point).strip()
+ flxml = ET.tostring(flp).strip()
+ if xml != flxml: # points are different
+ if xml[:-2] + b'smooth="yes" />' == flxml or xml == flxml[:-2] + b'smooth="yes" />':
+ changestomake = True # Only difference is addition or removal of smooth="yes"
+ else: # Other change to glif,so can't safely make changes
+ otherchange = True
+
+ if changestomake and not otherchange: # Only changes to contours in glif are addition(s) or removal(s) of smooth="yes"
+ flcontours = iter(floutline.contours)
+ for contour in list(contours):
+ flcontour = next(flcontours)
+ outline.replaceobject(contour, flcontour, "contour")
+ smoothchangecount += 1
+
+ # Now need to move components to the front...
+ components = outline.components
+ if len(components) > 0 and len(contours) > 0 and list(outline)[0] == "contour":
+ oldcontours = list(contours) # Easiest way to 'move' components is to delete contours then append back at the end
+ for contour in oldcontours: outline.removeobject(contour, "contour")
+ for contour in oldcontours: outline.appendobject(contour, "contour")
+ compchangecount += 1
+
+ logger.log(f'{layer.layername}: {smoothchangecount} glifs changed due to smooth and {compchangecount} glifs changed due to components position', "P")
+
+ bfont.write(outufoname)
+ return
+
+def cmd() : execute("UFO",doit, argspec)
+if __name__ == "__main__": cmd()
diff --git a/examples/psftoneletters.py b/examples/psftoneletters.py
new file mode 100644
index 0000000..5fd871f
--- /dev/null
+++ b/examples/psftoneletters.py
@@ -0,0 +1,327 @@
+#!/usr/bin/env python
+from __future__ import unicode_literals
+'''Creates Latin script tone letters (pitch contours)'''
+__url__ = 'http://github.com/silnrsi/pysilfont'
+__copyright__ = 'Copyright (c) 2017 SIL International (http://www.sil.org)'
+__license__ = 'Released under the MIT License (http://opensource.org/licenses/MIT)'
+__author__ = 'Victor Gaultney'
+
+# Usage: psftoneletters ifont ofont
+# Assumption is that the named tone letters already exist in the font,
+# so this script is only to update (rebuild) them. New tone letter spaces
+# in the font can be created with psfbuildcomp.py
+
+# To Do
+# Get parameters from lib.plist org.sil.lcg.toneLetters
+
+# main input, output, and execution handled by pysilfont framework
+from silfont.core import execute
+import silfont.ufo as UFO
+
+from robofab.world import OpenFont
+
+from math import tan, radians, sqrt
+
+suffix = '_toneletters'
+argspec = [
+ ('ifont',{'help': 'Input font file'}, {'type': 'filename'}),
+ ('ofont',{'help': 'Output font file','nargs': '?' }, {'type': 'filename', 'def': "_"+suffix}),
+ ('-l','--log',{'help': 'Log file'}, {'type': 'outfile', 'def': suffix+'log'})]
+
+
+def getParameters(font):
+ global glyphHeight, marginFlatLeft, marginPointLeft, marginFlatRight, marginPointRight, contourWidth, marginDotLeft, marginDotRight, dotSpacing, italicAngle, radius, strokeHeight, strokeDepth, contourGap, fakeBottom, dotRadius, dotBCP, contourGapDot, fakeBottomDot, anchorHeight, anchorOffset
+
+ source = font.lib.getval("org.sil.lcg.toneLetters")
+
+ strokeThickness = int(source["strokeThickness"]) # total width of stroke (ideally an even number)
+ glyphHeight = int(source["glyphHeight"]) # height, including overshoot
+ glyphDepth = int(source["glyphDepth"]) # depth - essentially overshoot (typically negative)
+ marginFlatLeft = int(source["marginFlatLeft"]) # left sidebearing for straight bar
+ marginPointLeft = int(source["marginPointLeft"]) # left sidebearing for endpoints
+ marginFlatRight = int(source["marginFlatRight"]) # left sidebearing for straight bar
+ marginPointRight = int(source["marginPointRight"]) # left sidebearing for endpoints
+ contourWidth = int(source["contourWidth"]) # this is how wide the contour portions are, from the middle
+ # of one end to the other, in the horizontal axis. The actual
+ # bounding box of the contours would then be this plus the
+ # strokeThickness.
+ marginDotLeft = int(source["marginDotLeft"]) # left sidebearing for dots
+ marginDotRight = int(source["marginDotRight"]) # right sidebearing for dots
+ dotSize = int(source["dotSize"]) # the diameter of the dot, normally 150% of the stroke weight
+ # (ideally an even number)
+ dotSpacing = int(source["dotSpacing"]) # the space between the edge of the dot and the
+ # edge of the expanded stroke
+ italicAngle = float(source["italicAngle"]) # angle of italic slant, 0 for upright
+
+ radius = round(strokeThickness / 2)
+ strokeHeight = glyphHeight - radius # for the unexpanded stroke
+ strokeDepth = glyphDepth + radius
+ strokeLength = strokeHeight - strokeDepth
+ contourGap = round(strokeLength / 4) # gap between contour levels
+ fakeBottom = strokeDepth - contourGap # a false 'bottom' for building contours
+
+ dotRadius = round(dotSize / 2) # this gets redefined during nine tone process
+ dotBCP = round((dotSize / 2) * .55) # this gets redefined during nine tone process
+ contourGapDot = round(( (glyphHeight - dotRadius) - (glyphDepth + dotRadius) ) / 4)
+ fakeBottomDot = (glyphDepth + dotRadius) - contourGapDot
+
+ anchorHeight = [ 0 , strokeDepth , (strokeDepth + contourGap) , (strokeDepth + contourGap * 2) , (strokeHeight - contourGap) , strokeHeight ]
+ anchorOffset = 20 # hardcoded for now
+
+# drawing functions
+
+def drawLine(glyph,startX,startY,endX,endY):
+
+ dx = (endX - startX) # dx of original stroke
+ dy = (endY - startY) # dy of original stroke
+ len = sqrt( dx * dx + dy * dy ) # length of original stroke
+ opp = round(dy * (radius / len)) # offsets for on-curve points
+ adj = round(dx * (radius / len))
+ oppOff = round(opp * .55) # offsets for off-curve from on-curve
+ adjOff = round(adj * .55)
+
+ glyph.clearContours()
+
+ pen = glyph.getPen()
+
+ # print startX + opp, startY - adj
+
+ pen.moveTo((startX + opp, startY - adj))
+ pen.lineTo((endX + opp, endY - adj)) # first straight line
+
+ bcp1x = endX + opp + adjOff
+ bcp1y = endY - adj + oppOff
+ bcp2x = endX + adj + oppOff
+ bcp2y = endY + opp - adjOff
+ pen.curveTo((bcp1x, bcp1y), (bcp2x, bcp2y), (endX + adj, endY + opp))
+
+ bcp1x = endX + adj - oppOff
+ bcp1y = endY + opp + adjOff
+ bcp2x = endX - opp + adjOff
+ bcp2y = endY + adj + oppOff
+ pen.curveTo((bcp1x, bcp1y), (bcp2x, bcp2y), (endX - opp, endY + adj))
+
+ pen.lineTo((startX - opp, startY + adj)) # second straight line
+
+ bcp1x = startX - opp - adjOff
+ bcp1y = startY + adj - oppOff
+ bcp2x = startX - adj - oppOff
+ bcp2y = startY - opp + adjOff
+ pen.curveTo((bcp1x, bcp1y), (bcp2x, bcp2y), (startX - adj, startY - opp))
+
+ bcp1x = startX - adj + oppOff
+ bcp1y = startY - opp - adjOff
+ bcp2x = startX + opp - adjOff
+ bcp2y = startY - adj - oppOff
+ pen.curveTo((bcp1x, bcp1y), (bcp2x, bcp2y), (startX + opp, startY - adj))
+ # print startX + opp, startY - adj
+
+ pen.closePath()
+
+
+def drawDot(glyph,dotX,dotY):
+
+ glyph.clearContours()
+
+ pen = glyph.getPen()
+
+ pen.moveTo((dotX, dotY - dotRadius))
+ pen.curveTo((dotX + dotBCP, dotY - dotRadius), (dotX + dotRadius, dotY - dotBCP), (dotX + dotRadius, dotY))
+ pen.curveTo((dotX + dotRadius, dotY + dotBCP), (dotX + dotBCP, dotY + dotRadius), (dotX, dotY + dotRadius))
+ pen.curveTo((dotX - dotBCP, dotY + dotRadius), (dotX - dotRadius, dotY + dotBCP), (dotX - dotRadius, dotY))
+ pen.curveTo((dotX - dotRadius, dotY - dotBCP), (dotX - dotBCP, dotY - dotRadius), (dotX, dotY - dotRadius))
+ pen.closePath()
+
+
+def adjItalX(aiX,aiY):
+ newX = aiX + round(tan(radians(italicAngle)) * aiY)
+ return newX
+
+
+def buildComp(f,g,pieces,ancLevelLeft,ancLevelMidLeft,ancLevelMidRight,ancLevelRight):
+
+ g.clear()
+ g.width = 0
+
+ for p in pieces:
+ g.appendComponent(p, (g.width, 0))
+ g.width += f[p].width
+
+ if ancLevelLeft > 0:
+ anc_nm = "_TL"
+ anc_x = adjItalX(0,anchorHeight[ancLevelLeft])
+ if g.name[0:7] == 'TnStaff':
+ anc_x = anc_x - anchorOffset
+ anc_y = anchorHeight[ancLevelLeft]
+ g.appendAnchor(anc_nm, (anc_x, anc_y))
+
+ if ancLevelMidLeft > 0:
+ anc_nm = "_TL"
+ anc_x = adjItalX(marginPointLeft + radius,anchorHeight[ancLevelMidLeft])
+ anc_y = anchorHeight[ancLevelMidLeft]
+ g.appendAnchor(anc_nm, (anc_x, anc_y))
+
+ if ancLevelMidRight > 0:
+ anc_nm = "TL"
+ anc_x = adjItalX(g.width - marginPointRight - radius,anchorHeight[ancLevelMidRight])
+ anc_y = anchorHeight[ancLevelMidRight]
+ g.appendAnchor(anc_nm, (anc_x, anc_y))
+
+ if ancLevelRight > 0:
+ anc_nm = "TL"
+ anc_x = adjItalX(g.width,anchorHeight[ancLevelRight])
+ if g.name[0:7] == 'TnStaff':
+ anc_x = anc_x + anchorOffset
+ anc_y = anchorHeight[ancLevelRight]
+ g.appendAnchor(anc_nm, (anc_x, anc_y))
+
+
+# updating functions
+
+def updateTLPieces(targetfont):
+
+ f = targetfont
+
+ # set spacer widths
+ f["TnLtrSpcFlatLeft"].width = marginFlatLeft + radius
+ f["TnLtrSpcPointLeft"].width = marginPointLeft + radius - 1 # -1 corrects final sidebearing
+ f["TnLtrSpcFlatRight"].width = marginFlatRight + radius
+ f["TnLtrSpcPointRight"].width = marginPointRight + radius - 1 # -1 corrects final sidebearing
+ f["TnLtrSpcDotLeft"].width = marginDotLeft + dotRadius
+ f["TnLtrSpcDotMiddle"].width = dotRadius + dotSpacing + radius
+ f["TnLtrSpcDotRight"].width = dotRadius + marginDotRight
+
+ # redraw bar
+ g = f["TnLtrBar"]
+ drawLine(g,adjItalX(0,strokeDepth),strokeDepth,adjItalX(0,strokeHeight),strokeHeight)
+ g.width = 0
+
+ # redraw contours
+ namePre = 'TnLtrSeg'
+ for i in range(1,6):
+ for j in range(1,6):
+
+ nameFull = namePre + str(i) + str(j)
+
+ if i == 5: # this deals with round off errors
+ startLevel = strokeHeight
+ else:
+ startLevel = fakeBottom + i * contourGap
+ if j == 5:
+ endLevel = strokeHeight
+ else:
+ endLevel = fakeBottom + j * contourGap
+
+ g = f[nameFull]
+ g.width = contourWidth
+ drawLine(g,adjItalX(1,startLevel),startLevel,adjItalX(contourWidth-1,endLevel),endLevel)
+
+
+ # redraw dots
+ namePre = 'TnLtrDot'
+ for i in range(1,6):
+
+ nameFull = namePre + str(i)
+
+ if i == 5: # this deals with round off errors
+ dotLevel = glyphHeight - dotRadius
+ else:
+ dotLevel = fakeBottomDot + i * contourGapDot
+
+ g = f[nameFull]
+ drawDot(g,adjItalX(0,dotLevel),dotLevel)
+
+
+def rebuildTLComps(targetfont):
+
+ f = targetfont
+
+ # staff right
+ for i in range(1,6):
+ nameFull = 'TnStaffRt' + str(i)
+ buildComp(f,f[nameFull],['TnLtrBar','TnLtrSpcFlatRight'],i,0,0,0)
+
+ # staff right no outline
+ for i in range(1,6):
+ nameFull = 'TnStaffRt' + str(i) + 'no'
+ buildComp(f,f[nameFull],['TnLtrSpcFlatRight'],i,0,0,0)
+
+ # staff left
+ for i in range(1,6):
+ nameFull = 'TnStaffLft' + str(i)
+ buildComp(f,f[nameFull],['TnLtrSpcFlatLeft','TnLtrBar'],0,0,0,i)
+
+ # staff left no outline
+ for i in range(1,6):
+ nameFull = 'TnStaffLft' + str(i) + 'no'
+ buildComp(f,f[nameFull],['TnLtrSpcFlatLeft'],0,0,0,i)
+
+ # contours right
+ for i in range(1,6):
+ for j in range(1,6):
+ nameFull = 'TnContRt' + str(i) + str(j)
+ segment = 'TnLtrSeg' + str(i) + str(j)
+ buildComp(f,f[nameFull],['TnLtrSpcPointLeft',segment],0,i,0,j)
+
+ # contours left
+ for i in range(1,6):
+ for j in range(1,6):
+ nameFull = 'TnContLft' + str(i) + str(j)
+ segment = 'TnLtrSeg' + str(i) + str(j)
+ buildComp(f,f[nameFull],[segment,'TnLtrSpcPointRight'],i,0,j,0)
+
+ # basic tone letters
+ for i in range(1,6):
+ nameFull = 'TnLtr' + str(i)
+ segment = 'TnLtrSeg' + str(i) + str(i)
+ buildComp(f,f[nameFull],['TnLtrSpcPointLeft',segment,'TnLtrBar','TnLtrSpcFlatRight'],0,0,0,0)
+
+ # basic tone letters no outline
+ for i in range(1,6):
+ nameFull = 'TnLtr' + str(i) + 'no'
+ segment = 'TnLtrSeg' + str(i) + str(i)
+ buildComp(f,f[nameFull],['TnLtrSpcPointLeft',segment,'TnLtrSpcFlatRight'],0,i,0,0)
+
+ # left stem tone letters
+ for i in range(1,6):
+ nameFull = 'LftStemTnLtr' + str(i)
+ segment = 'TnLtrSeg' + str(i) + str(i)
+ buildComp(f,f[nameFull],['TnLtrSpcFlatLeft','TnLtrBar',segment,'TnLtrSpcPointRight'],0,0,0,0)
+
+ # left stem tone letters no outline
+ for i in range(1,6):
+ nameFull = 'LftStemTnLtr' + str(i) + 'no'
+ segment = 'TnLtrSeg' + str(i) + str(i)
+ buildComp(f,f[nameFull],['TnLtrSpcFlatLeft',segment,'TnLtrSpcPointRight'],0,0,i,0)
+
+ # dotted tone letters
+ for i in range(1,6):
+ nameFull = 'DotTnLtr' + str(i)
+ dot = 'TnLtrDot' + str(i)
+ buildComp(f,f[nameFull],['TnLtrSpcDotLeft',dot,'TnLtrSpcDotMiddle','TnLtrBar','TnLtrSpcFlatRight'],0,0,0,0)
+
+ # dotted left stem tone letters
+ for i in range(1,6):
+ nameFull = 'DotLftStemTnLtr' + str(i)
+ dot = 'TnLtrDot' + str(i)
+ buildComp(f,f[nameFull],['TnLtrSpcFlatLeft','TnLtrBar','TnLtrSpcDotMiddle',dot,'TnLtrSpcDotRight'],0,0,0,0)
+
+
+def doit(args):
+
+ psffont = UFO.Ufont(args.ifont, params = args.paramsobj)
+ rffont = OpenFont(args.ifont)
+ outfont = args.ofont
+
+ getParameters(psffont)
+
+ updateTLPieces(rffont)
+ rebuildTLComps(rffont)
+
+
+ rffont.save(outfont)
+
+ return
+
+def cmd() : execute(None,doit,argspec)
+if __name__ == "__main__": cmd()
diff --git a/examples/xmlDemo.py b/examples/xmlDemo.py
new file mode 100755
index 0000000..e564442
--- /dev/null
+++ b/examples/xmlDemo.py
@@ -0,0 +1,54 @@
+#!/usr/bin/env python
+'Demo script for use of ETWriter'
+__url__ = 'http://github.com/silnrsi/pysilfont'
+__copyright__ = 'Copyright (c) 2015 SIL International (http://www.sil.org)'
+__license__ = 'Released under the MIT License (http://opensource.org/licenses/MIT)'
+__author__ = 'David Raymond'
+
+from silfont.core import execute
+import silfont.etutil as etutil
+from xml.etree import cElementTree as ET
+
+argspec = [('outfile1',{'help': 'output file 1','default': './xmlDemo.xml','nargs': '?'}, {'type': 'outfile'}),
+ ('outfile2',{'help': 'output file 2','nargs': '?'}, {'type': 'outfile', 'def':'_2.xml'}),
+ ('outfile3',{'help': 'output file 3','nargs': '?'}, {'type': 'outfile', 'def':'_3.xml'})]
+
+def doit(args) :
+ ofile1 = args.outfile1
+ ofile2 = args.outfile2
+ ofile3 = args.outfile3
+
+ xmlstring = "<item>\n<subitem hello='world'>\n<subsub name='moon'>\n<value>lunar</value>\n</subsub>\n</subitem>"
+ xmlstring += "<subitem hello='jupiter'>\n<subsub name='moon'>\n<value>IO</value>\n</subsub>\n</subitem>\n</item>"
+
+ # Using etutil's xmlitem class
+
+ xmlobj = etutil.xmlitem()
+ xmlobj.etree = ET.fromstring(xmlstring)
+
+ etwobj = etutil.ETWriter(xmlobj.etree)
+ xmlobj.outxmlstr = etwobj.serialize_xml()
+
+ ofile1.write(xmlobj.outxmlstr)
+
+ # Just using ETWriter
+
+ etwobj = etutil.ETWriter( ET.fromstring(xmlstring) )
+ xmlstr = etwobj.serialize_xml()
+ ofile2.write(xmlstr)
+ # Changing parameters
+
+ etwobj = etutil.ETWriter( ET.fromstring(xmlstring) )
+ etwobj.indentIncr = " "
+ etwobj.indentFirst = ""
+ xmlstr = etwobj.serialize_xml()
+ ofile3.write(xmlstr)
+
+ # Close files and exit
+ ofile1.close()
+ ofile2.close()
+ ofile3.close()
+ return
+
+def cmd() : execute("",doit,argspec)
+if __name__ == "__main__": cmd()
diff --git a/ez_setup.py b/ez_setup.py
new file mode 100755
index 0000000..46cd209
--- /dev/null
+++ b/ez_setup.py
@@ -0,0 +1,391 @@
+#!/usr/bin/env python
+
+"""
+Setuptools bootstrapping installer.
+
+Run this script to install or upgrade setuptools.
+"""
+
+import os
+import shutil
+import sys
+import tempfile
+import zipfile
+import optparse
+import subprocess
+import platform
+import textwrap
+import contextlib
+import warnings
+
+from distutils import log
+
+try:
+ from urllib.request import urlopen
+except ImportError:
+ from urllib2 import urlopen
+
+try:
+ from site import USER_SITE
+except ImportError:
+ USER_SITE = None
+
+DEFAULT_VERSION = "17.1.1"
+DEFAULT_URL = "https://pypi.python.org/packages/source/s/setuptools/"
+DEFAULT_SAVE_DIR = os.curdir
+
+
+def _python_cmd(*args):
+ """
+ Execute a command.
+
+ Return True if the command succeeded.
+ """
+ args = (sys.executable,) + args
+ return subprocess.call(args) == 0
+
+
+def _install(archive_filename, install_args=()):
+ """Install Setuptools."""
+ with archive_context(archive_filename):
+ # installing
+ log.warn('Installing Setuptools')
+ if not _python_cmd('setup.py', 'install', *install_args):
+ log.warn('Something went wrong during the installation.')
+ log.warn('See the error message above.')
+ # exitcode will be 2
+ return 2
+
+
+def _build_egg(egg, archive_filename, to_dir):
+ """Build Setuptools egg."""
+ with archive_context(archive_filename):
+ # building an egg
+ log.warn('Building a Setuptools egg in %s', to_dir)
+ _python_cmd('setup.py', '-q', 'bdist_egg', '--dist-dir', to_dir)
+ # returning the result
+ log.warn(egg)
+ if not os.path.exists(egg):
+ raise IOError('Could not build the egg.')
+
+
+class ContextualZipFile(zipfile.ZipFile):
+
+ """Supplement ZipFile class to support context manager for Python 2.6."""
+
+ def __enter__(self):
+ return self
+
+ def __exit__(self, type, value, traceback):
+ self.close()
+
+ def __new__(cls, *args, **kwargs):
+ """Construct a ZipFile or ContextualZipFile as appropriate."""
+ if hasattr(zipfile.ZipFile, '__exit__'):
+ return zipfile.ZipFile(*args, **kwargs)
+ return super(ContextualZipFile, cls).__new__(cls)
+
+
+@contextlib.contextmanager
+def archive_context(filename):
+ """
+ Unzip filename to a temporary directory, set to the cwd.
+
+ The unzipped target is cleaned up after.
+ """
+ tmpdir = tempfile.mkdtemp()
+ log.warn('Extracting in %s', tmpdir)
+ old_wd = os.getcwd()
+ try:
+ os.chdir(tmpdir)
+ with ContextualZipFile(filename) as archive:
+ archive.extractall()
+
+ # going in the directory
+ subdir = os.path.join(tmpdir, os.listdir(tmpdir)[0])
+ os.chdir(subdir)
+ log.warn('Now working in %s', subdir)
+ yield
+
+ finally:
+ os.chdir(old_wd)
+ shutil.rmtree(tmpdir)
+
+
+def _do_download(version, download_base, to_dir, download_delay):
+ """Download Setuptools."""
+ egg = os.path.join(to_dir, 'setuptools-%s-py%d.%d.egg'
+ % (version, sys.version_info[0], sys.version_info[1]))
+ if not os.path.exists(egg):
+ archive = download_setuptools(version, download_base,
+ to_dir, download_delay)
+ _build_egg(egg, archive, to_dir)
+ sys.path.insert(0, egg)
+
+ # Remove previously-imported pkg_resources if present (see
+ # https://bitbucket.org/pypa/setuptools/pull-request/7/ for details).
+ if 'pkg_resources' in sys.modules:
+ del sys.modules['pkg_resources']
+
+ import setuptools
+ setuptools.bootstrap_install_from = egg
+
+
+def use_setuptools(
+ version=DEFAULT_VERSION, download_base=DEFAULT_URL,
+ to_dir=DEFAULT_SAVE_DIR, download_delay=15):
+ """
+ Ensure that a setuptools version is installed.
+
+ Return None. Raise SystemExit if the requested version
+ or later cannot be installed.
+ """
+ to_dir = os.path.abspath(to_dir)
+
+ # prior to importing, capture the module state for
+ # representative modules.
+ rep_modules = 'pkg_resources', 'setuptools'
+ imported = set(sys.modules).intersection(rep_modules)
+
+ try:
+ import pkg_resources
+ pkg_resources.require("setuptools>=" + version)
+ # a suitable version is already installed
+ return
+ except ImportError:
+ # pkg_resources not available; setuptools is not installed; download
+ pass
+ except pkg_resources.DistributionNotFound:
+ # no version of setuptools was found; allow download
+ pass
+ except pkg_resources.VersionConflict as VC_err:
+ if imported:
+ _conflict_bail(VC_err, version)
+
+ # otherwise, unload pkg_resources to allow the downloaded version to
+ # take precedence.
+ del pkg_resources
+ _unload_pkg_resources()
+
+ return _do_download(version, download_base, to_dir, download_delay)
+
+
+def _conflict_bail(VC_err, version):
+ """
+ Setuptools was imported prior to invocation, so it is
+ unsafe to unload it. Bail out.
+ """
+ conflict_tmpl = textwrap.dedent("""
+ The required version of setuptools (>={version}) is not available,
+ and can't be installed while this script is running. Please
+ install a more recent version first, using
+ 'easy_install -U setuptools'.
+
+ (Currently using {VC_err.args[0]!r})
+ """)
+ msg = conflict_tmpl.format(**locals())
+ sys.stderr.write(msg)
+ sys.exit(2)
+
+
+def _unload_pkg_resources():
+ del_modules = [
+ name for name in sys.modules
+ if name.startswith('pkg_resources')
+ ]
+ for mod_name in del_modules:
+ del sys.modules[mod_name]
+
+
+def _clean_check(cmd, target):
+ """
+ Run the command to download target.
+
+ If the command fails, clean up before re-raising the error.
+ """
+ try:
+ subprocess.check_call(cmd)
+ except subprocess.CalledProcessError:
+ if os.access(target, os.F_OK):
+ os.unlink(target)
+ raise
+
+
+def download_file_powershell(url, target):
+ """
+ Download the file at url to target using Powershell.
+
+ Powershell will validate trust.
+ Raise an exception if the command cannot complete.
+ """
+ target = os.path.abspath(target)
+ ps_cmd = (
+ "[System.Net.WebRequest]::DefaultWebProxy.Credentials = "
+ "[System.Net.CredentialCache]::DefaultCredentials; "
+ "(new-object System.Net.WebClient).DownloadFile(%(url)r, %(target)r)"
+ % vars()
+ )
+ cmd = [
+ 'powershell',
+ '-Command',
+ ps_cmd,
+ ]
+ _clean_check(cmd, target)
+
+
+def has_powershell():
+ """Determine if Powershell is available."""
+ if platform.system() != 'Windows':
+ return False
+ cmd = ['powershell', '-Command', 'echo test']
+ with open(os.path.devnull, 'wb') as devnull:
+ try:
+ subprocess.check_call(cmd, stdout=devnull, stderr=devnull)
+ except Exception:
+ return False
+ return True
+download_file_powershell.viable = has_powershell
+
+
+def download_file_curl(url, target):
+ cmd = ['curl', url, '--silent', '--output', target]
+ _clean_check(cmd, target)
+
+
+def has_curl():
+ cmd = ['curl', '--version']
+ with open(os.path.devnull, 'wb') as devnull:
+ try:
+ subprocess.check_call(cmd, stdout=devnull, stderr=devnull)
+ except Exception:
+ return False
+ return True
+download_file_curl.viable = has_curl
+
+
+def download_file_wget(url, target):
+ cmd = ['wget', url, '--quiet', '--output-document', target]
+ _clean_check(cmd, target)
+
+
+def has_wget():
+ cmd = ['wget', '--version']
+ with open(os.path.devnull, 'wb') as devnull:
+ try:
+ subprocess.check_call(cmd, stdout=devnull, stderr=devnull)
+ except Exception:
+ return False
+ return True
+download_file_wget.viable = has_wget
+
+
+def download_file_insecure(url, target):
+ """Use Python to download the file, without connection authentication."""
+ src = urlopen(url)
+ try:
+ # Read all the data in one block.
+ data = src.read()
+ finally:
+ src.close()
+
+ # Write all the data in one block to avoid creating a partial file.
+ with open(target, "wb") as dst:
+ dst.write(data)
+download_file_insecure.viable = lambda: True
+
+
+def get_best_downloader():
+ downloaders = (
+ download_file_powershell,
+ download_file_curl,
+ download_file_wget,
+ download_file_insecure,
+ )
+ viable_downloaders = (dl for dl in downloaders if dl.viable())
+ return next(viable_downloaders, None)
+
+
+def download_setuptools(
+ version=DEFAULT_VERSION, download_base=DEFAULT_URL,
+ to_dir=DEFAULT_SAVE_DIR, delay=15,
+ downloader_factory=get_best_downloader):
+ """
+ Download setuptools from a specified location and return its filename.
+
+ `version` should be a valid setuptools version number that is available
+ as an sdist for download under the `download_base` URL (which should end
+ with a '/'). `to_dir` is the directory where the egg will be downloaded.
+ `delay` is the number of seconds to pause before an actual download
+ attempt.
+
+ ``downloader_factory`` should be a function taking no arguments and
+ returning a function for downloading a URL to a target.
+ """
+ # making sure we use the absolute path
+ to_dir = os.path.abspath(to_dir)
+ zip_name = "setuptools-%s.zip" % version
+ url = download_base + zip_name
+ saveto = os.path.join(to_dir, zip_name)
+ if not os.path.exists(saveto): # Avoid repeated downloads
+ log.warn("Downloading %s", url)
+ downloader = downloader_factory()
+ downloader(url, saveto)
+ return os.path.realpath(saveto)
+
+
+def _build_install_args(options):
+ """
+ Build the arguments to 'python setup.py install' on the setuptools package.
+
+ Returns list of command line arguments.
+ """
+ return ['--user'] if options.user_install else []
+
+
+def _parse_args():
+ """Parse the command line for options."""
+ parser = optparse.OptionParser()
+ parser.add_option(
+ '--user', dest='user_install', action='store_true', default=False,
+ help='install in user site package (requires Python 2.6 or later)')
+ parser.add_option(
+ '--download-base', dest='download_base', metavar="URL",
+ default=DEFAULT_URL,
+ help='alternative URL from where to download the setuptools package')
+ parser.add_option(
+ '--insecure', dest='downloader_factory', action='store_const',
+ const=lambda: download_file_insecure, default=get_best_downloader,
+ help='Use internal, non-validating downloader'
+ )
+ parser.add_option(
+ '--version', help="Specify which version to download",
+ default=DEFAULT_VERSION,
+ )
+ parser.add_option(
+ '--to-dir',
+ help="Directory to save (and re-use) package",
+ default=DEFAULT_SAVE_DIR,
+ )
+ options, args = parser.parse_args()
+ # positional arguments are ignored
+ return options
+
+
+def _download_args(options):
+ """Return args for download_setuptools function from cmdline args."""
+ return dict(
+ version=options.version,
+ download_base=options.download_base,
+ downloader_factory=options.downloader_factory,
+ to_dir=options.to_dir,
+ )
+
+
+def main():
+ """Install or upgrade setuptools and EasyInstall."""
+ options = _parse_args()
+ archive = download_setuptools(**_download_args(options))
+ return _install(archive, _build_install_args(options))
+
+if __name__ == '__main__':
+ sys.exit(main())
diff --git a/lib/silfont/__init__.py b/lib/silfont/__init__.py
new file mode 100644
index 0000000..aa2763c
--- /dev/null
+++ b/lib/silfont/__init__.py
@@ -0,0 +1,5 @@
+#!/usr/bin/env python
+__url__ = 'http://github.com/silnrsi/pysilfont'
+__copyright__ = 'Copyright (c) 2014-2022 SIL International (http://www.sil.org)'
+__license__ = 'Released under the MIT License (http://opensource.org/licenses/MIT)'
+__version__ = '1.6.0'
diff --git a/lib/silfont/comp.py b/lib/silfont/comp.py
new file mode 100644
index 0000000..d99985a
--- /dev/null
+++ b/lib/silfont/comp.py
@@ -0,0 +1,358 @@
+#!/usr/bin/env python
+'Composite glyph definition'
+__url__ = 'http://github.com/silnrsi/pysilfont'
+__copyright__ = 'Copyright (c) 2015 SIL International (http://www.sil.org)'
+__license__ = 'Released under the MIT License (http://opensource.org/licenses/MIT)'
+__author__ = 'David Rowe'
+
+import re
+from xml.etree import ElementTree as ET
+
+# REs to parse (from right to left) comment, SIL extension parameters, markinfo, UID, metrics,
+# and (from left) glyph name
+
+# Extract comment from end of line (NB: Doesn't use re.VERBOSE because it contains #.)
+# beginning of line, optional whitespace, remainder, optional whitespace, comment to end of line
+inputline=re.compile(r"""^\s*(?P<remainder>.*?)(\s*#\s*(?P<commenttext>.*))?$""")
+
+# Parse SIL extension parameters in [...], but only after |
+paraminfo=re.compile(r"""^\s*
+ (?P<remainder>[^|]*
+ ($|
+ \|[^[]*$|
+ \|[^[]*\[(?P<paraminfo>[^]]*)\]))
+ \s*$""",re.VERBOSE)
+
+# Parse markinfo
+markinfo=re.compile(r"""^\s*
+ (?P<remainder>[^!]*?)
+ \s*
+ (?:!\s*(?P<markinfo>[.0-9]+(?:,[ .0-9]+){3}))? # ! markinfo
+ (?P<remainder2>[^!]*?)
+ \s*$""",re.VERBOSE)
+
+# Parse uid
+uidinfo=re.compile(r"""^\s*
+ (?P<remainder>[^|]*?)
+ \s*
+ (?:\|\s*(?P<UID>[^^!]*)?)? # | followed by nothing, or 4- to 6-digit UID
+ (?P<remainder2>[^|]*?)
+ \s*$""",re.VERBOSE)
+
+# Parse metrics
+metricsinfo=re.compile(r"""^\s*
+ (?P<remainder>[^^]*?)
+ \s*
+ (?:\^\s*(?P<metrics>[-0-9]+\s*(?:,\s*[-0-9]+)?))? # metrics (either ^x,y or ^a)
+ (?P<remainder2>[^^]*?)
+ \s*$""",re.VERBOSE)
+
+# Parse glyph information (up to =)
+glyphdef=re.compile(r"""^\s*
+ (?P<PSName>[._A-Za-z][._A-Za-z0-9-]*) # glyphname
+ \s*=\s*
+ (?P<remainder>.*?)
+ \s*$""",re.VERBOSE)
+
+# break tokens off the right hand side from right to left and finally off left hand side (up to =)
+initialtokens=[ (inputline, 'commenttext', ""),
+ (paraminfo, 'paraminfo', "Error parsing parameters in [...]"),
+ (markinfo, 'markinfo', "Error parsing information after !"),
+ (uidinfo, 'UID', "Error parsing information after |"),
+ (metricsinfo, 'metrics', "Error parsing information after ^"),
+ (glyphdef, 'PSName', "Error parsing glyph name before =") ]
+
+# Parse base and diacritic information
+compdef=re.compile(r"""^\s*
+ (?P<compname>[._A-Za-z][._A-Za-z0-9-]*) # name of base or diacritic in composite definition
+ (?:@ # @ precedes position information
+ (?:(?:\s*(?P<base>[^: ]+)):)? # optional base glyph followed by :
+ \s*
+ (?P<position>(?:[^ +&[])+) # position information (delimited by space + & [ or end of line)
+ \s*)? # end of @ clause
+ \s*
+ (?:\[(?P<params>[^]]*)\])? # parameters inside [..]
+ \s*
+ (?P<remainder>.*)$
+ """,re.VERBOSE)
+
+# Parse metrics
+lsb_rsb=re.compile(r"""^\s*
+ (?P<lsb>[-0-9]+)\s*(?:,\s*(?P<rsb>[-0-9]+))? # optional metrics (either ^lsb,rsb or ^adv)
+ \s*$""",re.VERBOSE)
+
+# RE to break off one key=value parameter from text inside [key=value;key=value;key=value]
+paramdef=re.compile(r"""^\s*
+ (?P<paramname>[a-z0-9]+) # paramname
+ \s*=\s* # = (with optional white space before/after)
+ (?P<paramval>[^;]+?) # any text up to ; or end of string
+ \s* # optional whitespace
+ (?:;\s*(?P<rest>.+)$|\s*$) # either ; and (non-empty) rest of parameters, or end of line
+ """,re.VERBOSE)
+
+class CompGlyph(object):
+
+ def __init__(self, CDelement=None, CDline=None):
+ self.CDelement = CDelement
+ self.CDline = CDline
+
+ def _parseparams(self, rest):
+ """Parse a parameter line such as:
+ key1=value1;key2=value2
+ and return a dictionary with key:value pairs.
+ """
+ params = {}
+ while rest:
+ matchparam=re.match(paramdef,rest)
+ if matchparam == None:
+ raise ValueError("Parameter error: " + rest)
+ params[matchparam.group('paramname')] = matchparam.group('paramval')
+ rest = matchparam.group('rest')
+ return(params)
+
+ def parsefromCDline(self):
+ """Parse the composite glyph information (in self.CDline) such as:
+ LtnCapADiear = LtnCapA + CombDiaer@U |00C4 ! 1, 0, 0, 1 # comment
+ and return a <glyph> element (in self.CDelement)
+ <glyph PSName="LtnCapADiear" UID="00C4">
+ <note>comment</note>
+ <property name="mark" value="1, 0, 0, 1"/>
+ <base PSName="LtnCapA">
+ <attach PSName="CombDiaer" with="_U" at="U"/>
+ </base>
+ </glyph>
+ Position info after @ can include optional base glyph name followed by colon.
+ """
+ line = self.CDline
+ results = {}
+ for parseinfo in initialtokens:
+ if len(line) > 0:
+ regex, groupname, errormsg = parseinfo
+ matchresults = re.match(regex,line)
+ if matchresults == None:
+ raise ValueError(errormsg)
+ line = matchresults.group('remainder')
+ resultsval = matchresults.group(groupname)
+ if resultsval != None:
+ results[groupname] = resultsval.strip()
+ if groupname == 'paraminfo': # paraminfo match needs to be removed from remainder
+ line = line.rstrip('['+resultsval+']')
+ if 'remainder2' in matchresults.groupdict().keys(): line += ' ' + matchresults.group('remainder2')
+# At this point results optionally may contain entries for any of 'commenttext', 'paraminfo', 'markinfo', 'UID', or 'metrics',
+# but it must have 'PSName' if any of 'paraminfo', 'markinfo', 'UID', or 'metrics' present
+ note = results.pop('commenttext', None)
+ if 'PSName' not in results:
+ if len(results) > 0:
+ raise ValueError("Missing glyph name")
+ else: # comment only, or blank line
+ return None
+ dic = {}
+ UIDpresent = 'UID' in results
+ if UIDpresent and results['UID'] == '':
+ results.pop('UID')
+ if 'paraminfo' in results:
+ paramdata = results.pop('paraminfo')
+ if UIDpresent:
+ dic = self._parseparams(paramdata)
+ else:
+ line += " [" + paramdata + "]"
+ mark = results.pop('markinfo', None)
+ if 'metrics' in results:
+ m = results.pop('metrics')
+ matchmetrics = re.match(lsb_rsb,m)
+ if matchmetrics == None:
+ raise ValueError("Error in parameters: " + m)
+ elif matchmetrics.group('rsb'):
+ metricdic = {'lsb': matchmetrics.group('lsb'), 'rsb': matchmetrics.group('rsb')}
+ else:
+ metricdic = {'advance': matchmetrics.group('lsb')}
+ else:
+ metricdic = None
+
+ # Create <glyph> element and assign attributes
+ g = ET.Element('glyph',attrib=results)
+ if note: # note from commenttext becomes <note> subelement
+ n = ET.SubElement(g,'note')
+ n.text = note.rstrip()
+ # markinfo becomes <property> subelement
+ if mark:
+ p = ET.SubElement(g, 'property', name = 'mark', value = mark)
+ # paraminfo parameters (now in dic) become <property> subelements
+ if dic:
+ for key in dic:
+ p = ET.SubElement(g, 'property', name = key, value = dic[key])
+ # metrics parameters (now in metricdic) become subelements
+ if metricdic:
+ for key in metricdic:
+ k = ET.SubElement(g, key, width=metricdic[key])
+
+ # Prepare to parse remainder of line
+ prevbase = None
+ prevdiac = None
+ remainder = line
+ expectingdiac = False
+
+ # top of loop to process remainder of line, breaking off base or diacritics from left to right
+ while remainder != "":
+ matchresults=re.match(compdef,remainder)
+ if matchresults == None or matchresults.group('compname') == "" :
+ raise ValueError("Error parsing glyph name: " + remainder)
+ propdic = {}
+ if matchresults.group('params'):
+ propdic = self._parseparams(matchresults.group('params'))
+ base = matchresults.group('base')
+ position = matchresults.group('position')
+ if expectingdiac:
+ # Determine parent element, based on previous base and diacritic glyphs and optional
+ # matchresults.group('base'), indicating diacritic attaches to a different glyph
+ if base == None:
+ if prevdiac != None:
+ parent = prevdiac
+ else:
+ parent = prevbase
+ elif base != prevbase.attrib['PSName']:
+ raise ValueError("Error in diacritic alternate base glyph: " + base)
+ else:
+ parent = prevbase
+ if prevdiac == None:
+ raise ValueError("Unnecessary diacritic alternate base glyph: " + base)
+ # Because 'with' is Python reserved word, passing it directly as a parameter
+ # causes Python syntax error, so build dictionary to pass to SubElement
+ att = {'PSName': matchresults.group('compname')}
+ if position:
+ if 'with' in propdic:
+ withval = propdic.pop('with')
+ else:
+ withval = "_" + position
+ att['at'] = position
+ att['with'] = withval
+ # Create <attach> subelement
+ e = ET.SubElement(parent, 'attach', attrib=att)
+ prevdiac = e
+ elif (base or position):
+ raise ValueError("Position information on base glyph not supported")
+ else:
+ # Create <base> subelement
+ e = ET.SubElement(g, 'base', PSName=matchresults.group('compname'))
+ prevbase = e
+ prevdiac = None
+ if 'shift' in propdic:
+ xval, yval = propdic.pop('shift').split(',')
+ s = ET.SubElement(e, 'shift', x=xval, y=yval)
+ # whatever parameters are left in propdic become <property> subelements
+ for key, val in propdic.items():
+ p = ET.SubElement(e, 'property', name=key, value=val)
+
+ remainder = matchresults.group('remainder').lstrip()
+ nextchar = remainder[:1]
+ remainder = remainder[1:].lstrip()
+ expectingdiac = nextchar == '+'
+ if nextchar == '&' or nextchar == '+':
+ if len(remainder) == 0:
+ raise ValueError("Expecting glyph name after & or +")
+ elif len(nextchar) > 0:
+ raise ValueError("Expecting & or + and found " + nextchar)
+ self.CDelement = g
+
+ def _diacinfo(self, node, parent, lastglyph):
+ """receives attach element, PSName of its parent, PSName of most recent glyph
+ returns a string equivalent of this node (and all its descendants)
+ and a string with the name of the most recent glyph
+ """
+ diacname = node.get('PSName')
+ atstring = node.get('at')
+ withstring = node.get('with')
+ propdic = {}
+ if withstring != "_" + atstring:
+ propdic['with'] = withstring
+ subattachlist = []
+ attachglyph = ""
+ if parent != lastglyph:
+ attachglyph = parent + ":"
+ for subelement in node:
+ if subelement.tag == 'property':
+ propdic[subelement.get('name')] = subelement.get('value')
+ elif subelement.tag == 'attach':
+ subattachlist.append(subelement)
+ elif subelement.tag == 'shift':
+ propdic['shift'] = subelement.get('x') + "," + subelement.get('y')
+ # else flag error/warning?
+ propstring = ""
+ if propdic:
+ propstring += " [" + ";".join( [k + "=" + v for k,v in propdic.items()] ) + "]"
+ returnstring = " + " + diacname + "@" + attachglyph + atstring + propstring
+ prevglyph = diacname
+ for s in subattachlist:
+ string, prevglyph = self._diacinfo(s, diacname, prevglyph)
+ returnstring += string
+ return returnstring, prevglyph
+
+ def _basediacinfo(self, baseelement):
+ """receives base element and returns a string equivalent of this node (and all its desendants)"""
+ basename = baseelement.get('PSName')
+ returnstring = basename
+ prevglyph = basename
+ bpropdic = {}
+ for child in baseelement:
+ if child.tag == 'attach':
+ string, prevglyph = self._diacinfo(child, basename, prevglyph)
+ returnstring += string
+ elif child.tag == 'shift':
+ bpropdic['shift'] = child.get('x') + "," + child.get('y')
+ if bpropdic:
+ returnstring += " [" + ";".join( [k + "=" + v for k,v in bpropdic.items()] ) + "]"
+ return returnstring
+
+ def parsefromCDelement(self):
+ """Parse a glyph element such as:
+ <glyph PSName="LtnSmITildeGraveDotBlw" UID="E000">
+ <note>i tilde grave dot-below</note>
+ <base PSName="LtnSmDotlessI">
+ <attach PSName="CombDotBlw" at="L" with="_L" />
+ <attach PSName="CombTilde" at="U" with="_U">
+ <attach PSName="CombGrave" at="U" with="_U" />
+ </attach>
+ </base>
+ </glyph>
+ and produce the equivalent CDline in format:
+ LtnSmITildeGraveDotBlw = LtnSmDotlessI + CombDotBlw@L + CombTilde@LtnSmDotlessI:U + CombGrave@U | E000 # i tilde grave dot-below
+ """
+ g = self.CDelement
+ lsb = None
+ rsb = None
+ adv = None
+ markinfo = None
+ note = None
+ paramdic = {}
+ outputline = [g.get('PSName')]
+ resultUID = g.get('UID')
+ basesep = " = "
+
+ for child in g:
+ if child.tag == 'note': note = child.text
+ elif child.tag == 'property':
+ if child.get('name') == 'mark': markinfo = child.get('value')
+ else: paramdic[child.get('name')] = child.get('value')
+ elif child.tag == 'lsb': lsb = child.get('width')
+ elif child.tag == 'rsb': rsb = child.get('width')
+ elif child.tag == 'advance': adv = child.get('width')
+ elif child.tag == 'base':
+ outputline.extend([basesep, self._basediacinfo(child)])
+ basesep = " & "
+
+ if paramdic and resultUID == None:
+ resultUID = " " # to force output of |
+ if adv: outputline.extend([' ^', adv])
+ if lsb and rsb: outputline.extend([' ^', lsb, ',', rsb])
+ if resultUID: outputline.extend([' |', resultUID])
+ if markinfo: outputline.extend([' !', markinfo])
+ if paramdic:
+ paramsep = " ["
+ for k in paramdic:
+ outputline.extend([paramsep, k, "=", paramdic[k]])
+ paramsep = ";"
+ outputline.append("]")
+ if note:
+ outputline.extend([" # ", note])
+ self.CDline = "".join(outputline)
+
diff --git a/lib/silfont/core.py b/lib/silfont/core.py
new file mode 100755
index 0000000..fae37ec
--- /dev/null
+++ b/lib/silfont/core.py
@@ -0,0 +1,748 @@
+#!/usr/bin/env python
+'General classes and functions for use in pysilfont scripts'
+__url__ = 'http://github.com/silnrsi/pysilfont'
+__copyright__ = 'Copyright (c) 2014-2022 SIL International (http://www.sil.org)'
+__license__ = 'Released under the MIT License (http://opensource.org/licenses/MIT)'
+__author__ = 'David Raymond'
+
+from glob import glob
+from collections import OrderedDict
+import sys, os, argparse, datetime, shutil, csv, configparser
+
+import silfont
+
+class loggerobj(object):
+ # For handling log messages.
+ # Use S for severe errors caused by data, parameters supplied by user etc
+ # Use X for severe errors caused by bad code to get traceback exception
+
+ def __init__(self, logfile=None, loglevels="", leveltext="", loglevel="W", scrlevel="P"):
+ self.logfile = logfile
+ self.loglevels = loglevels
+ self.leveltext = leveltext
+ self.errorcount = 0
+ self.warningcount = 0
+ if not self.loglevels: self.loglevels = {'X': 0, 'S': 1, 'E': 2, 'P': 3, 'W': 4, 'I': 5, 'V': 6}
+ if not self.leveltext: self.leveltext = ('Exception ', 'Severe: ', 'Error: ', 'Progress: ', 'Warning: ', 'Info: ', 'Verbose: ')
+ super(loggerobj, self).__setattr__("loglevel", "E") # Temp values so invalid log levels can be reported
+ super(loggerobj, self).__setattr__("scrlevel", "E") #
+ self.loglevel = loglevel
+ self.scrlevel = scrlevel
+
+ def __setattr__(self, name, value):
+ if name in ("loglevel", "scrlevel"):
+ if value in self.loglevels:
+ (minlevel, minnum) = ("E",2) if name == "loglevel" else ("S", 1)
+ if self.loglevels[value] < minnum:
+ value = minlevel
+ self.log(name + " increased to minimum level of " + minlevel, "E")
+ else:
+ self.log("Invalid " + name + " value: " + value, "S")
+ super(loggerobj, self).__setattr__(name, value)
+ if name == "scrlevel" : self._basescrlevel = value # Used by resetscrlevel
+
+ def log(self, logmessage, msglevel="W"):
+ levelval = self.loglevels[msglevel]
+ message = datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S ") + self.leveltext[levelval] + str(logmessage)
+ #message = datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S.%f")[0:22] +" "+ self.leveltext[levelval] + logmessage ## added milliseconds for timing tests
+ if levelval <= self.loglevels[self.scrlevel]: print(message)
+ if self.logfile and levelval <= self.loglevels[self.loglevel]: self.logfile.write(message + "\n")
+ if msglevel == "S":
+ print("\n **** Fatal error - exiting ****")
+ sys.exit(1)
+ if msglevel == "X": assert False, message
+ if msglevel == "E": self.errorcount += 1
+ if msglevel == "W": self.warningcount += 1
+
+ def raisescrlevel(self, level): # Temporarily increase screen logging
+ if level not in self.loglevels or level == "X" : self.log("Invalid scrlevel: " + level, "X")
+ if self.loglevels[level] > self.loglevels[self.scrlevel]:
+ current = self.scrlevel
+ self.scrlevel = level
+ self._basescrlevel = current
+ self.log("scrlevel raised to " + level, "I")
+
+ def resetscrlevel(self):
+ self.scrlevel = self._basescrlevel
+
+
+class parameters(object):
+ # Object for holding parameters information, organised by class (eg logging)
+
+ # Default parameters for use in pysilfont modules
+ # Names must be case-insensitively unique across all parameter classes
+ # Parameter types are deduced from the default values
+
+ def __init__(self):
+ # Default parameters for all modules
+ defparams = {}
+ defparams['system'] = {'version': silfont.__version__, 'copyright': silfont.__copyright__} # Code treats these as read-only
+ defparams['logging'] = {'scrlevel': 'P', 'loglevel': 'W'}
+ defparams['backups'] = {'backup': True, 'backupdir': 'backups', 'backupkeep': 5}
+ # Default parameters for UFO module
+ defparams['outparams'] = OrderedDict([ # Use ordered dict so parameters show in logical order with -h p
+ ("UFOversion", ""), # UFOversion - defaults to existing unless a value is supplied
+ ("indentIncr", " "), # XML Indent increment
+ ("indentFirst", " "), # First XML indent
+ ("indentML", False), # Should multi-line string values be indented?
+ ("plistIndentFirst", ""), # First indent amount for plists
+ ('precision', 6), # Decimal precision to use in XML output - both for real values and for attributes if float
+ ("floatAttribs", ['xScale', 'xyScale', 'yxScale', 'yScale', 'angle']), # Used with precision above
+ ("intAttribs", ['pos', 'width', 'height', 'xOffset', 'yOffset', 'x', 'y']),
+ ("sortDicts", True), # Should dict elements be sorted alphabetically?
+ ("renameGlifs", True), # Rename glifs based on UFO3 suggested algorithm
+ ("format1Glifs", False), # Force output format 1 glifs including UFO2-style anchors (for use with FontForge
+ ("glifElemOrder", ['advance', 'unicode', 'note', 'image', 'guideline', 'anchor', 'outline', 'lib']), # Order to output glif elements
+ ("attribOrders.glif",['pos', 'width', 'height', 'fileName', 'base', 'xScale', 'xyScale', 'yxScale', 'yScale', 'xOffset', 'yOffset',
+ 'x', 'y', 'angle', 'type', 'smooth', 'name', 'format', 'color', 'identifier'])
+ ])
+ defparams['ufometadata'] = {"checkfix": "check"} # Apply metadata fixes when reading UFOs
+
+ self.paramshelp = {} # Info used when outputting help about parame options
+ self.paramshelp["classdesc"] = {
+ "logging": "controls the level of log messages go to screen or log files.",
+ "backups": "controls backup settings for scripts that output fonts - by default backups are made if the output font is overwriting the input font",
+ "outparams": "Output options for UFOs - cover UFO version and normalization",
+ "ufometadata": "controls if UFO metadata be checked, or checked and fixed"
+ }
+ self.paramshelp["paramsdesc"] = {
+ "scrlevel": "Logging level for screen messages - one of S,E,P.W,I or V",
+ "loglevel": "Logging level for log file messages - one of E,P.W,I or V",
+ "backup": "Should font backups be made",
+ "backupdir": "Directory to use for font backups",
+ "backupkeep": "How many backups to keep",
+ "indentIncr": "XML Indent increment",
+ "indentFirst": "First XML indent",
+ "indentML": "Should multi-line string values be indented?",
+ "plistIndentFirst": "First indent amount for plists",
+ "sortDicts": "Should dict elements be sorted alphabetically?",
+ "precision": "Decimal precision to use in XML output - both for real values and for attributes if numeric",
+ "renameGlifs": "Rename glifs based on UFO3 suggested algorithm",
+ "UFOversion": "UFOversion to output - defaults to version of the input UFO",
+ "format1Glifs": "Force output format 1 glifs including UFO2-style anchors (was used with FontForge; no longer needed)",
+ "glifElemOrder": "Order to output glif elements",
+ "floatAttribs": "List of float attributes - used when setting decimal precision",
+ "intAttribs": "List of attributes that should be integers",
+ "attribOrders.glif": "Order in which to output glif attributes",
+ "checkfix": "Should check & fix tests be done - one of None, Check or Fix"
+ }
+ self.paramshelp["defaultsdesc"] = { # For use where default needs clarifying with text
+ "indentIncr" : "<two spaces>",
+ "indentFirst": "<two spaces>",
+ "plistIndentFirst": "<No indent>",
+ "UFOversion": "<Existing version>"
+ }
+
+ self.classes = {} # Dictionary containing a list of parameters in each class
+ self.paramclass = {} # Dictionary of class name for each parameter name
+ self.types = {} # Python type for each parameter deduced from initial values supplied
+ self.listtypes = {} # If type is dict, the type of values in the dict
+ self.logger = loggerobj()
+ defset = _paramset(self, "default", "defaults")
+ self.sets = {"default": defset}
+ self.lcase = {} # Lower case index of parameters names
+ for classn in defparams:
+ self.classes[classn] = []
+ for parn in defparams[classn]:
+ value = defparams[classn][parn]
+ self.classes[classn].append(parn)
+ self.paramclass[parn] = classn
+ self.types[parn] = type(value)
+ if type(value) is list: self.listtypes[parn] = type(value[0])
+ super(_paramset, defset).__setitem__(parn, value) # __setitem__ in paramset does not allow new values!
+ self.lcase[parn.lower()] = parn
+
+ def addset(self, name, sourcedesc=None, inputdict=None, configfile=None, copyset=None):
+ # Create a subset from one of a dict, config file or existing set
+ # Only one option should used per call
+ # sourcedesc should be added for user-supplied data (eg config file) for reporting purposes
+ dict = {}
+ if configfile:
+ config = configparser.ConfigParser()
+ config.read_file(open(configfile, encoding="utf-8"))
+ if sourcedesc is None: sourcedesc = configfile
+ for classn in config.sections():
+ for item in config.items(classn):
+ parn = item[0]
+ if self.paramclass[parn] == "system":
+ self.logger.log("Can't change " + parn + " parameter via config file", "S")
+ val = item[1].strip('"').strip("'")
+ dict[parn] = val
+ elif copyset:
+ if sourcedesc is None: sourcedesc = "Copy of " + copyset
+ for parn in self.sets[copyset]:
+ dict[parn] = self.sets[copyset][parn]
+ elif inputdict:
+ dict = inputdict
+ if sourcedesc is None: sourcedesc = "unspecified source"
+ self.sets[name] = _paramset(self, name, sourcedesc, dict)
+
+ def printhelp(self):
+ phelp = self.paramshelp
+ print("\nMost pysilfont scripts have -p, --params options which can be used to change default behaviour of scripts. For example '-p scrlevel=w' will log warning messages to screen \n")
+ print("Listed below are all such parameters, grouped by purpose. Not all apply to all scripts - "
+ "in partucular outparams and ufometadata only apply to scripts using pysilfont's own UFO code")
+ for classn in ("logging", "backups", "ufometadata", "outparams"):
+ print("\n" + classn[0].upper() + classn[1:] + " - " + phelp["classdesc"][classn])
+ for param in self.classes[classn]:
+ if param == "format1Glifs": continue # Param due to be phased out
+ paramdesc = phelp["paramsdesc"][param]
+ paramtype = self.types[param].__name__
+ defaultdesc = phelp["defaultsdesc"][param] if param in phelp["defaultsdesc"] else self.sets["default"][param]
+ print(' {:<20}: {}'.format(param, paramdesc))
+ print(' (Type: {:<6} Default: {})'.format(paramtype + ",", defaultdesc))
+ print("\nNote parameter names are case-insensitive\n")
+ print("For more help see https://github.com/silnrsi/pysilfont/blob/master/docs/parameters.md\n")
+
+class _paramset(dict):
+ # Set of parameter values
+ def __init__(self, params, name, sourcedesc, inputdict=None):
+ if inputdict is None: inputdict = {}
+ self.name = name
+ self.sourcedesc = sourcedesc # Description of source for reporting
+ self.params = params # Parent parameters object
+ for parn in inputdict:
+ if params.paramclass[parn] == "system": # system values can't be changed
+ if inputdict[parn] != params.sets["default"][parn]:
+ self.params.logger.log("Can't change " + parn + " - system parameters can't be changed", "X")
+ else:
+ super(_paramset, self).__setitem__(parn, inputdict[parn])
+ else:
+ self[parn] = inputdict[parn]
+
+ def __setitem__(self, parn, value):
+ origvalue = value
+ origparn = parn
+ parn = parn.lower()
+ if self.params.paramclass[origparn] == "system":
+ self.params.logger.log("Can't change " + parn + " - system parameters are read-only", "X")
+ if parn not in self.params.lcase:
+ self.params.logger.log("Invalid parameter " + origparn + " from " + self.sourcedesc, "S")
+ else:
+ parn = self.params.lcase[parn]
+ ptyp = self.params.types[parn]
+ if ptyp is bool:
+ value = str2bool(value)
+ if value is None: self.params.logger.log(self.sourcedesc+" parameter "+origparn+" must be boolean: " + origvalue, "S")
+ if ptyp is list:
+ if type(value) is not list: value = value.split(",") # Convert csv string into list
+ if len(value) < 2: self.params.logger.log(self.sourcedesc+" parameter "+origparn+" must have a list of values: " + origvalue, "S")
+ valuesOK = True
+ listtype = self.params.listtypes[parn]
+ for i, val in enumerate(value):
+ if listtype is bool:
+ val = str2bool(val)
+ if val is None: self.params.logger.log (self.sourcedesc+" parameter "+origparn+" must contain boolean values: " + origvalue, "S")
+ value[i] = val
+ if type(val) != listtype:
+ valuesOK = False
+ badtype = str(type(val))
+ if not valuesOK: self.params.logger.log("Invalid "+badtype+" parameter type for "+origparn+": "+self.params.types[parn], "S")
+ if parn in ("loglevel", "scrlevel"): # Need to check log level is valid before setting it since otherwise logging will fail
+ value = value.upper()
+ if value not in self.params.logger.loglevels: self.params.logger.log (self.sourcedesc+" parameter "+parn+" invalid", "S")
+ super(_paramset, self).__setitem__(parn, value)
+
+ def updatewith(self, update, sourcedesc=None, log=True):
+ # Update a set with values from another set
+ if sourcedesc is None: sourcedesc = self.params.sets[update].sourcedesc
+ for parn in self.params.sets[update]:
+ oldval = self[parn] if parn in self else ""
+ self[parn] = self.params.sets[update][parn]
+ if log and oldval != "" and self[parn] != oldval:
+ old = str(oldval)
+ new = str(self[parn])
+ if old != old.strip() or new != new.strip(): # Add quotes if there are leading or trailing spaces
+ old = '"'+old+'"'
+ new = '"'+new+'"'
+ self.params.logger.log(sourcedesc + " parameters: changing "+parn+" from " + old + " to " + new, "I")
+
+
+class csvreader(object): # Iterator for csv files, skipping comments and checking number of fields
+ def __init__(self, filename, minfields=0, maxfields=999, numfields=None, logger=None):
+ self.filename = filename
+ self.minfields = minfields
+ self.maxfields = maxfields
+ self.numfields = numfields
+ self.logger = logger if logger else loggerobj() # If no logger supplied, will just log to screen
+ # Open the file and create reader
+ try:
+ file = open(filename, "rt", encoding="utf-8")
+ except Exception as e:
+ print(e)
+ sys.exit(1)
+ self.file = file
+ self.reader = csv.reader(file)
+ # Find the first non-comment line then reset so __iter__ still returns the first line
+ # This is so scripts can analyse first line (eg to look for headers) before starting iterating
+ self.firstline = None
+ self._commentsbeforefirstline = -1
+ while not self.firstline:
+ row = next(self.reader, None)
+ if row is None: logger.log("Input csv is empty or all lines are comments or blank", "S")
+ self._commentsbeforefirstline += 1
+ if row == []: continue # Skip blank lines
+ if row[0].lstrip().startswith("#"): continue # Skip comments - ie lines starting with #
+ self.firstline = row
+ file.seek(0) # Reset the csv and skip comments
+ for i in range(self._commentsbeforefirstline): next(self.reader, None)
+
+ def __setattr__(self, name, value):
+ if name == "numfields" and value is not None: # If numfields is changed, reset min and max fields
+ self.minfields = value
+ self.maxfields = value
+ super(csvreader, self).__setattr__(name, value)
+
+ def __iter__(self):
+ for row in self.reader:
+ self.line_num = self.reader.line_num - 1 - self._commentsbeforefirstline # Count is out due to reading first line in __init__
+ if row == []: continue # Skip blank lines
+ if row[0].lstrip().startswith("#"): continue # Skip comments - ie lines starting with #
+ if len(row) < self.minfields or len(row) > self.maxfields:
+ self.logger.log("Invalid number of fields on line " + str(self.line_num) + " in "+self.filename, "E" )
+ continue
+ yield row
+
+
+def execute(tool, fn, scriptargspec, chain = None):
+ # Function to handle parameter parsing, font and file opening etc in command-line scripts
+ # Supports opening (and saving) fonts using PysilFont UFO (UFO), fontParts (FP) or fontTools (FT)
+ # Special handling for:
+ # -d variation on -h to print extra info about defaults
+ # -q quiet mode - only output a single line with count of errors (if there are any)
+ # -l opens log file and also creates a logger function to write to the log file
+ # -p other parameters. Includes backup settings and loglevel/scrlevel settings for logger
+ # for UFOlib scripts, also includes all outparams keys and ufometadata settings
+
+ argspec = list(scriptargspec)
+
+ chainfirst = False
+ if chain == "first": # If first call to execute has this set, only do the final return part of chaining
+ chainfirst = True
+ chain = None
+
+ params = chain["params"] if chain else parameters()
+ logger = chain["logger"] if chain else params.logger # paramset has already created a basic logger
+ argv = chain["argv"] if chain else sys.argv
+
+ if tool == "UFO":
+ from silfont.ufo import Ufont
+ elif tool == "FT":
+ from fontTools import ttLib
+ elif tool == "FP":
+ from fontParts.world import OpenFont
+ elif tool == "" or tool is None:
+ tool = None
+ else:
+ logger.log("Invalid tool in call to execute()", "X")
+ return
+ basemodule = sys.modules[fn.__module__]
+ poptions = {}
+ poptions['prog'] = splitfn(argv[0])[1]
+ poptions['description'] = basemodule.__doc__
+ poptions['formatter_class'] = argparse.RawDescriptionHelpFormatter
+ epilog = "For more help options use -h ?. For more documentation see https://github.com/silnrsi/pysilfont/blob/master/docs/scripts.md#" + poptions['prog'] + "\n\n"
+ poptions['epilog'] = epilog + "Version: " + params.sets['default']['version'] + "\n" + params.sets['default']['copyright']
+
+ parser = argparse.ArgumentParser(**poptions)
+ parser._optionals.title = "other arguments"
+
+
+ # Add standard arguments
+ standardargs = {
+ 'quiet': ('-q', '--quiet', {'help': 'Quiet mode - only display severe errors', 'action': 'store_true'}, {}),
+ 'log': ('-l', '--log', {'help': 'Log file'}, {'type': 'outfile'}),
+ 'params': ('-p', '--params', {'help': 'Other parameters - see parameters.md for details', 'action': 'append'}, {'type': 'optiondict'}),
+ 'nq': ('--nq', {'help': argparse.SUPPRESS, 'action': 'store_true'}, {})}
+
+ suppliedargs = []
+ for a in argspec:
+ argn = a[:-2][-1] # [:-2] will give either 1 or 2, the last of which is the full argument name
+ if argn[0:2] == "--": argn = argn[2:] # Will start with -- for options
+ suppliedargs.append(argn)
+ for arg in sorted(standardargs):
+ if arg not in suppliedargs: argspec.append(standardargs[arg])
+
+ defhelp = False
+ if "-h" in argv: # Look for help option supplied
+ pos = argv.index("-h")
+ if pos < len(argv)-1: # There is something following -h!
+ opt = argv[pos+1]
+ if opt in ("d", "defaults"):
+ defhelp = True # Normal help will be displayed with default info displayed by the epilog
+ deffiles = []
+ defother = []
+ elif opt in ("p", "params"):
+ params.printhelp()
+ sys.exit(0)
+ else:
+ if opt != "?":
+ print("Invalid -h value")
+ print("-h ? displays help options")
+ print("-h d (or -h defaults) lists details of default values for arguments and parameters")
+ print("-h p (or -h params) gives help on parameters that can be set with -p or --params")
+ sys.exit(0)
+
+ quiet = True if "-q" in argv and '--nq' not in argv else False
+ if quiet: logger.scrlevel = "S"
+
+ # Process the supplied argument specs, add args to parser, store other info in arginfo
+ arginfo = []
+ logdef = None
+ for a in argspec:
+ # Process all but last tuple entry as argparse arguments
+ nonkwds = a[:-2]
+ kwds = a[-2]
+ parser.add_argument(*nonkwds, **kwds)
+ # Create ainfo, a dict of framework keywords using argument name
+ argn = nonkwds[-1] # Find the argument name from first 1 or 2 tuple entries
+ if argn[0:2] == "--": # Will start with -- for options
+ argn = argn[2:].replace("-", "_") # Strip the -- and replace any - in name with _
+ ainfo=dict(a[-1]) #Make a copy so original argspec is not changed
+ for key in ainfo: # Check all keys are valid
+ if key not in ("def", "type", "optlog") : logger.log("Invalid argspec framework key: " + key, "X")
+ ainfo['name']=argn
+ if argn == 'log':
+ logdef = ainfo['def'] if 'def' in ainfo else None
+ optlog = ainfo['optlog'] if 'optlog' in ainfo else False
+ arginfo.append(ainfo)
+ if defhelp:
+ arg = nonkwds[0]
+ if 'def' in ainfo:
+ defval = ainfo['def']
+ if argn == 'log' and logdef: defval += " in logs subdirectory"
+ deffiles.append([arg, defval])
+ elif 'default' in kwds:
+ defother.append([arg, kwds['default']])
+
+ # if -h d specified, change the help epilog to info about argument defaults
+ if defhelp:
+ if not (deffiles or defother):
+ deftext = "No defaults for parameters/options"
+ else:
+ deftext = "Defaults for parameters/options - see user docs for details\n"
+ if deffiles:
+ deftext = deftext + "\n Font/file names\n"
+ for (param, defv) in deffiles:
+ deftext = deftext + ' {:<20}{}\n'.format(param, defv)
+ if defother:
+ deftext = deftext + "\n Other parameters\n"
+ for (param, defv) in defother:
+ deftext = deftext + ' {:<20}{}\n'.format(param, defv)
+ parser.epilog = deftext + "\n\n" + parser.epilog
+
+ # Parse the command-line arguments. If errors or -h used, procedure will exit here
+ args = parser.parse_args(argv[1:])
+
+ # Process the first positional parameter to get defaults for file names
+ fppval = getattr(args, arginfo[0]['name'])
+ if isinstance(fppval, list): # When nargs="+" or nargs="*" is used a list is returned
+ (fppath, fpbase, fpext) = splitfn(fppval[0])
+ if len(fppval) > 1 : fpbase = "wildcard"
+ else:
+ if fppval is None: fppval = "" # For scripts that can be run with no positional parameters
+ (fppath, fpbase, fpext) = splitfn(fppval) # First pos param use for defaulting
+
+ # Process parameters
+ if chain:
+ execparams = params.sets["main"]
+ args.params = {} # clparams not used when chaining
+ else:
+ # Read config file from disk if it exists
+ configname = os.path.join(fppath, "pysilfont.cfg")
+ if os.path.exists(configname):
+ params.addset("config file", configname, configfile=configname)
+ else:
+ params.addset("config file") # Create empty set
+ if not quiet and "scrlevel" in params.sets["config file"]: logger.scrlevel = params.sets["config file"]["scrlevel"]
+
+ # Process command-line parameters
+ clparams = {}
+ if 'params' in args.__dict__:
+ if args.params is not None:
+ for param in args.params:
+ x = param.split("=", 1)
+ if len(x) != 2:
+ logger.log("params must be of the form 'param=value'", "S")
+ if x[1] == "\\t": x[1] = "\t" # Special handling for tab characters
+ clparams[x[0]] = x[1]
+
+ args.params = clparams
+ params.addset("command line", "command line", inputdict=clparams)
+ if not quiet and "scrlevel" in params.sets["command line"]: logger.scrlevel = params.sets["command line"]["scrlevel"]
+
+ # Create main set of parameters based on defaults then update with config file values and command line values
+ params.addset("main", copyset="default")
+ params.sets["main"].updatewith("config file")
+ params.sets["main"].updatewith("command line")
+ execparams = params.sets["main"]
+
+ # Set up logging
+ if chain:
+ setattr(args, 'logger', logger)
+ args.logfile = logger.logfile
+ else:
+ logfile = None
+ logname = args.log if 'log' in args.__dict__ and args.log is not None else ""
+ if 'log' in args.__dict__:
+ if logdef is not None and (logname != "" or optlog == False):
+ (path, base, ext) = splitfn(logname)
+ (dpath, dbase, dext) = splitfn(logdef)
+ if not path:
+ if base and ext: # If both specified then use cwd, ie no path
+ path = ""
+ else:
+ path = (fppath if dpath == "" else os.path.join(fppath, dpath))
+ path = os.path.join(path, "logs")
+ if not base:
+ if dbase == "":
+ base = fpbase
+ elif dbase[0] == "_": # Append to font name if starts with _
+ base = fpbase + dbase
+ else:
+ base = dbase
+ if not ext and dext: ext = dext
+ logname = os.path.join(path, base+ext)
+ if logname == "":
+ logfile = None
+ else:
+ (logname, logpath, exists) = fullpath(logname)
+ if not exists:
+ (parent,subd) = os.path.split(logpath)
+ if subd == "logs" and os.path.isdir(parent): # Create directory if just logs subdir missing
+ logger.log("Creating logs subdirectory in " + parent, "P")
+ os.mkdir(logpath)
+ else: # Fails, since missing dir is probably a typo!
+ logger.log("Directory " + parent + " does not exist", "S")
+ logger.log('Opening log file for output: ' + logname, "P")
+ try:
+ logfile = open(logname, "w", encoding="utf-8")
+ except Exception as e:
+ print(e)
+ sys.exit(1)
+ args.log = logfile
+ # Set up logger details
+ logger.loglevel = execparams['loglevel'].upper()
+ logger.logfile = logfile
+ if not quiet: logger.scrlevel = "E" # suppress next log message from screen
+ logger.log("Running: " + " ".join(argv), "P")
+ if not quiet: logger.scrlevel = execparams['scrlevel'].upper()
+ setattr(args, 'logger', logger)
+
+# Process the argument values returned from argparse
+
+ outfont = None
+ infontlist = []
+ for c, ainfo in enumerate(arginfo):
+ aval = getattr(args, ainfo['name'])
+ if ainfo['name'] in ('params', 'log'): continue # params and log already processed
+ atype = None
+ adef = None
+ if 'type' in ainfo:
+ atype = ainfo['type']
+ if atype not in ('infont', 'outfont', 'infile', 'outfile', 'incsv', 'filename', 'optiondict'):
+ logger.log("Invalid type of " + atype + " supplied in argspec", "X")
+ if atype != 'optiondict': # All other types are file types, so adef must be set, even if just to ""
+ adef = ainfo['def'] if 'def' in ainfo else ""
+ if adef is None and aval is None: # If def explicitly set to None then this is optional
+ setattr(args, ainfo['name'], None)
+ continue
+
+ if c == 0:
+ if aval is None : logger.log("Invalid first positional parameter spec", "X")
+ if aval[-1] in ("\\","/"): aval = aval[0:-1] # Remove trailing slashes
+ else: #Handle defaults for all but first positional parameter
+ if adef is not None:
+ if not aval: aval = ""
+# if aval == "" and adef == "": # Only valid for output font parameter
+# if atype != "outfont":
+# logger.log("No value suppiled for " + ainfo['name'], "S")
+# ## Not sure why this needs to fail - we need to cope with other optional file or filename parameters
+ (apath, abase, aext) = splitfn(aval)
+ (dpath, dbase, dext) = splitfn(adef) # dpath should be None
+ if not apath:
+ if abase and aext: # If both specified then use cwd, ie no path
+ apath = ""
+ else:
+ apath = fppath
+ if not abase:
+ if dbase == "":
+ abase = fpbase
+ elif dbase[0] == "_": # Append to font name if starts with _
+ abase = fpbase + dbase
+ else:
+ abase = dbase
+ if not aext:
+ if dext:
+ aext = dext
+ elif (atype == 'outfont' or atype == 'infont'): aext = fpext
+ aval = os.path.join(apath, abase+aext)
+
+ # Open files/fonts
+ if atype == 'infont':
+ if tool is None:
+ logger.log("Can't specify a font without a font tool", "X")
+ infontlist.append((ainfo['name'], aval)) # Build list of fonts to open when other args processed
+ elif atype == 'infile':
+ logger.log('Opening file for input: '+aval, "P")
+ try:
+ aval = open(aval, "r", encoding="utf-8")
+ except Exception as e:
+ print(e)
+ sys.exit(1)
+ elif atype == 'incsv':
+ logger.log('Opening file for input: '+aval, "P")
+ aval = csvreader(aval, logger=logger)
+ elif atype == 'outfile':
+ (aval, path, exists) = fullpath(aval)
+ if not exists:
+ logger.log("Output file directory " + path + " does not exist", "S")
+ logger.log('Opening file for output: ' + aval, "P")
+ try:
+ aval = open(aval, 'w', encoding="utf-8")
+ except Exception as e:
+ print(e)
+ sys.exit(1)
+ elif atype == 'outfont':
+ if tool is None:
+ logger.log("Can't specify a font without a font tool", "X")
+ outfont = aval
+ outfontpath = apath
+ outfontbase = abase
+ outfontext = aext
+
+ elif atype == 'optiondict': # Turn multiple options in the form ['opt1=a', 'opt2=b'] into a dictionary
+ avaldict={}
+ if aval is not None:
+ for option in aval:
+ x = option.split("=", 1)
+ if len(x) != 2:
+ logger.log("options must be of the form 'param=value'", "S")
+ if x[1] == "\\t": x[1] = "\t" # Special handling for tab characters
+ avaldict[x[0]] = x[1]
+ aval = avaldict
+
+ setattr(args, ainfo['name'], aval)
+
+# Open fonts - needs to be done after processing other arguments so logger and params are defined
+
+ for name, aval in infontlist:
+ if chain and name == 'ifont':
+ aval = chain["font"]
+ else:
+ if tool == "UFO": aval = Ufont(aval, params=params)
+ if tool == "FT" : aval = ttLib.TTFont(aval)
+ if tool == "FP" : aval = OpenFont(aval)
+ setattr(args, name, aval) # Assign the font object to args attribute
+
+# All arguments processed, now call the main function
+ setattr(args, "paramsobj", params)
+ setattr(args, "cmdlineargs", argv)
+ newfont = fn(args)
+# If an output font is expected and one is returned, output the font
+ if chainfirst: chain = True # Special handling for first call of chaining
+ if newfont:
+ if chain: # return font to be handled by chain()
+ return (args, newfont)
+ else:
+ if outfont:
+ # Backup the font if output is overwriting original input font
+ if outfont == infontlist[0][1]:
+ backupdir = os.path.join(outfontpath, execparams['backupdir'])
+ backupmax = int(execparams['backupkeep'])
+ backup = str2bool(execparams['backup'])
+
+ if backup:
+ if not os.path.isdir(backupdir): # Create backup directory if not present
+ try:
+ os.mkdir(backupdir)
+ except Exception as e:
+ print(e)
+ sys.exit(1)
+ backupbase = os.path.join(backupdir, outfontbase+outfontext)
+ # Work out backup name based on existing backups
+ nums = sorted([int(i[len(backupbase)+1-len(i):-1]) for i in glob(backupbase+".*~")]) # Extract list of backup numbers from existing backups
+ newnum = max(nums)+1 if nums else 1
+ backupname = backupbase+"."+str(newnum)+"~"
+ # Backup the font
+ logger.log("Backing up input font to "+backupname, "P")
+ shutil.copytree(outfont, backupname)
+ # Purge old backups
+ for i in range(0, len(nums) - backupmax + 1):
+ backupname = backupbase+"."+str(nums[i])+"~"
+ logger.log("Purging old backup "+backupname, "I")
+ shutil.rmtree(backupname)
+ else:
+ logger.log("No font backup done due to backup parameter setting", "W")
+ # Output the font
+ if tool in ("FT", "FP"):
+ logger.log("Saving font to " + outfont, "P")
+ newfont.save(outfont)
+ else: # Must be Pyslifont Ufont
+ newfont.write(outfont)
+ else:
+ logger.log("Font returned to execute() but no output font is specified in arg spec", "X")
+ elif chain: # ) When chaining return just args - the font can be accessed by args.ifont
+ return (args, None) # ) assuming that the script has not changed the input font
+
+ if logger.errorcount or logger.warningcount:
+ message = "Command completed with " + str(logger.errorcount) + " errors and " + str(logger.warningcount) + " warnings"
+ if logger.scrlevel in ("S", "E") and logname != "":
+ if logger.scrlevel == "S" or logger.warningcount: message = message + " - see " + logname
+ if logger.errorcount:
+ if quiet: logger.raisescrlevel("E")
+ logger.log(message, "E")
+ logger.resetscrlevel()
+ else:
+ logger.log(message, "P")
+ if logger.scrlevel == "P" and logger.warningcount: logger.log("See log file for warning messages or rerun with '-p scrlevel=w'", "P")
+ else:
+ logger.log("Command completed with no warnings", "P")
+
+ return (args, newfont)
+
+
+def chain(argv, function, argspec, font, params, logger, quiet): # Chain multiple command-line scripts using UFO module together without writing font to disk
+ ''' argv is a command-line call to a script in sys.argv format. function and argspec are from the script being called.
+ Although input font name must be supplied for the command line to be parsed correctly by execute() it is not used - instead the supplied
+ font object is used. Similarly -params, logfile and quiet settings in argv are not used by execute() when chaining is used'''
+ if quiet and "-q" not in argv: argv.append("-q")
+ logger.log("Chaining to " + argv[0], "P")
+ font = execute("UFO", function, argspec,
+ {'argv' : argv,
+ 'font' : font,
+ 'params': params,
+ 'logger': logger,
+ 'quiet' : quiet})
+ logger.log("Returning from " + argv[0], "P")
+ return font
+
+
+def splitfn(fn): # Split filename into path, base and extension
+ if fn: # Remove trailing slashes
+ if fn[-1] in ("\\","/"): fn = fn[0:-1]
+ (path, base) = os.path.split(fn)
+ (base, ext) = os.path.splitext(base)
+ # Handle special case where just a directory is supplied
+ if ext == "": # If there's an extension, treat as file name, eg a ufo directory
+ if os.path.isdir(fn):
+ path = fn
+ base = ""
+ return (path, base, ext)
+
+
+def str2bool(v): # If v is not a boolean, convert from string to boolean
+ if type(v) == bool: return v
+ v = v.lower()
+ if v in ("yes", "y", "true", "t", "1"):
+ v = True
+ elif v in ("no", "n", "false", "f", "0"):
+ v = False
+ else:
+ v = None
+ return v
+
+def fullpath(filen): # Changes file name to one with full path and checks directory exists
+ fullname = os.path.abspath(filen)
+ (fpath,dummy) = os.path.split(fullname)
+ return fullname, fpath, os.path.isdir(fpath)
diff --git a/lib/silfont/data/required_chars.csv b/lib/silfont/data/required_chars.csv
new file mode 100644
index 0000000..939c371
--- /dev/null
+++ b/lib/silfont/data/required_chars.csv
@@ -0,0 +1,308 @@
+USV,ps_name,glyph_name,sil_set,rationale,additional_notes
+U+0020,space,space,basic,A,
+U+0021,exclam,exclam,basic,A,
+U+0022,quotedbl,quotedbl,basic,A,
+U+0023,numbersign,numbersign,basic,A,
+U+0024,dollar,dollar,basic,A,
+U+0025,percent,percent,basic,A,
+U+0026,ampersand,ampersand,basic,A,
+U+0027,quotesingle,quotesingle,basic,A,
+U+0028,parenleft,parenleft,basic,A,
+U+0029,parenright,parenright,basic,A,
+U+002A,asterisk,asterisk,basic,A,
+U+002B,plus,plus,basic,A,
+U+002C,comma,comma,basic,A,
+U+002D,hyphen,hyphen,basic,A,
+U+002E,period,period,basic,A,
+U+002F,slash,slash,basic,A,
+U+0030,zero,zero,basic,A,
+U+0031,one,one,basic,A,
+U+0032,two,two,basic,A,
+U+0033,three,three,basic,A,
+U+0034,four,four,basic,A,
+U+0035,five,five,basic,A,
+U+0036,six,six,basic,A,
+U+0037,seven,seven,basic,A,
+U+0038,eight,eight,basic,A,
+U+0039,nine,nine,basic,A,
+U+003A,colon,colon,basic,A,
+U+003B,semicolon,semicolon,basic,A,
+U+003C,less,less,basic,A,
+U+003D,equal,equal,basic,A,
+U+003E,greater,greater,basic,A,
+U+003F,question,question,basic,A,
+U+0040,at,at,basic,A,
+U+0041,A,A,basic,A,
+U+0042,B,B,basic,A,
+U+0043,C,C,basic,A,
+U+0044,D,D,basic,A,
+U+0045,E,E,basic,A,
+U+0046,F,F,basic,A,
+U+0047,G,G,basic,A,
+U+0048,H,H,basic,A,
+U+0049,I,I,basic,A,
+U+004A,J,J,basic,A,
+U+004B,K,K,basic,A,
+U+004C,L,L,basic,A,
+U+004D,M,M,basic,A,
+U+004E,N,N,basic,A,
+U+004F,O,O,basic,A,
+U+0050,P,P,basic,A,
+U+0051,Q,Q,basic,A,
+U+0052,R,R,basic,A,
+U+0053,S,S,basic,A,
+U+0054,T,T,basic,A,
+U+0055,U,U,basic,A,
+U+0056,V,V,basic,A,
+U+0057,W,W,basic,A,
+U+0058,X,X,basic,A,
+U+0059,Y,Y,basic,A,
+U+005A,Z,Z,basic,A,
+U+005B,bracketleft,bracketleft,basic,A,
+U+005C,backslash,backslash,basic,A,
+U+005D,bracketright,bracketright,basic,A,
+U+005E,asciicircum,asciicircum,basic,A,
+U+005F,underscore,underscore,basic,A,
+U+0060,grave,grave,basic,A,
+U+0061,a,a,basic,A,
+U+0062,b,b,basic,A,
+U+0063,c,c,basic,A,
+U+0064,d,d,basic,A,
+U+0065,e,e,basic,A,
+U+0066,f,f,basic,A,
+U+0067,g,g,basic,A,
+U+0068,h,h,basic,A,
+U+0069,i,i,basic,A,
+U+006A,j,j,basic,A,
+U+006B,k,k,basic,A,
+U+006C,l,l,basic,A,
+U+006D,m,m,basic,A,
+U+006E,n,n,basic,A,
+U+006F,o,o,basic,A,
+U+0070,p,p,basic,A,
+U+0071,q,q,basic,A,
+U+0072,r,r,basic,A,
+U+0073,s,s,basic,A,
+U+0074,t,t,basic,A,
+U+0075,u,u,basic,A,
+U+0076,v,v,basic,A,
+U+0077,w,w,basic,A,
+U+0078,x,x,basic,A,
+U+0079,y,y,basic,A,
+U+007A,z,z,basic,A,
+U+007B,braceleft,braceleft,basic,A,
+U+007C,bar,bar,basic,A,
+U+007D,braceright,braceright,basic,A,
+U+007E,asciitilde,asciitilde,basic,A,
+U+00A0,uni00A0,nbspace,basic,A,
+U+00A1,exclamdown,exclamdown,basic,A,
+U+00A2,cent,cent,basic,A,
+U+00A3,sterling,sterling,basic,A,
+U+00A4,currency,currency,basic,A,
+U+00A5,yen,yen,basic,A,
+U+00A6,brokenbar,brokenbar,basic,A,
+U+00A7,section,section,basic,A,
+U+00A8,dieresis,dieresis,basic,A,
+U+00A9,copyright,copyright,basic,A,
+U+00AA,ordfeminine,ordfeminine,basic,A,
+U+00AB,guillemotleft,guillemetleft,basic,A,
+U+00AC,logicalnot,logicalnot,basic,A,
+U+00AD,uni00AD,softhyphen,basic,A,
+U+00AE,registered,registered,basic,A,
+U+00AF,macron,macron,basic,A,
+U+00B0,degree,degree,basic,A,
+U+00B1,plusminus,plusminus,basic,A,
+U+00B2,uni00B2,twosuperior,basic,A,
+U+00B3,uni00B3,threesuperior,basic,A,
+U+00B4,acute,acute,basic,A,
+U+00B5,mu,micro,basic,A,
+U+00B6,paragraph,paragraph,basic,A,
+U+00B7,periodcentered,periodcentered,basic,A,
+U+00B8,cedilla,cedilla,basic,A,
+U+00B9,uni00B9,onesuperior,basic,A,
+U+00BA,ordmasculine,ordmasculine,basic,A,
+U+00BB,guillemotright,guillemetright,basic,A,
+U+00BC,onequarter,onequarter,basic,A,
+U+00BD,onehalf,onehalf,basic,A,
+U+00BE,threequarters,threequarters,basic,A,
+U+00BF,questiondown,questiondown,basic,A,
+U+00C0,Agrave,Agrave,basic,A,
+U+00C1,Aacute,Aacute,basic,A,
+U+00C2,Acircumflex,Acircumflex,basic,A,
+U+00C3,Atilde,Atilde,basic,A,
+U+00C4,Adieresis,Adieresis,basic,A,
+U+00C5,Aring,Aring,basic,A,
+U+00C6,AE,AE,basic,A,
+U+00C7,Ccedilla,Ccedilla,basic,A,
+U+00C8,Egrave,Egrave,basic,A,
+U+00C9,Eacute,Eacute,basic,A,
+U+00CA,Ecircumflex,Ecircumflex,basic,A,
+U+00CB,Edieresis,Edieresis,basic,A,
+U+00CC,Igrave,Igrave,basic,A,
+U+00CD,Iacute,Iacute,basic,A,
+U+00CE,Icircumflex,Icircumflex,basic,A,
+U+00CF,Idieresis,Idieresis,basic,A,
+U+00D0,Eth,Eth,basic,A,
+U+00D1,Ntilde,Ntilde,basic,A,
+U+00D2,Ograve,Ograve,basic,A,
+U+00D3,Oacute,Oacute,basic,A,
+U+00D4,Ocircumflex,Ocircumflex,basic,A,
+U+00D5,Otilde,Otilde,basic,A,
+U+00D6,Odieresis,Odieresis,basic,A,
+U+00D7,multiply,multiply,basic,A,
+U+00D8,Oslash,Oslash,basic,A,
+U+00D9,Ugrave,Ugrave,basic,A,
+U+00DA,Uacute,Uacute,basic,A,
+U+00DB,Ucircumflex,Ucircumflex,basic,A,
+U+00DC,Udieresis,Udieresis,basic,A,
+U+00DD,Yacute,Yacute,basic,A,
+U+00DE,Thorn,Thorn,basic,A,
+U+00DF,germandbls,germandbls,basic,A,
+U+00E0,agrave,agrave,basic,A,
+U+00E1,aacute,aacute,basic,A,
+U+00E2,acircumflex,acircumflex,basic,A,
+U+00E3,atilde,atilde,basic,A,
+U+00E4,adieresis,adieresis,basic,A,
+U+00E5,aring,aring,basic,A,
+U+00E6,ae,ae,basic,A,
+U+00E7,ccedilla,ccedilla,basic,A,
+U+00E8,egrave,egrave,basic,A,
+U+00E9,eacute,eacute,basic,A,
+U+00EA,ecircumflex,ecircumflex,basic,A,
+U+00EB,edieresis,edieresis,basic,A,
+U+00EC,igrave,igrave,basic,A,
+U+00ED,iacute,iacute,basic,A,
+U+00EE,icircumflex,icircumflex,basic,A,
+U+00EF,idieresis,idieresis,basic,A,
+U+00F0,eth,eth,basic,A,
+U+00F1,ntilde,ntilde,basic,A,
+U+00F2,ograve,ograve,basic,A,
+U+00F3,oacute,oacute,basic,A,
+U+00F4,ocircumflex,ocircumflex,basic,A,
+U+00F5,otilde,otilde,basic,A,
+U+00F6,odieresis,odieresis,basic,A,
+U+00F7,divide,divide,basic,A,
+U+00F8,oslash,oslash,basic,A,
+U+00F9,ugrave,ugrave,basic,A,
+U+00FA,uacute,uacute,basic,A,
+U+00FB,ucircumflex,ucircumflex,basic,A,
+U+00FC,udieresis,udieresis,basic,A,
+U+00FD,yacute,yacute,basic,A,
+U+00FE,thorn,thorn,basic,A,
+U+00FF,ydieresis,ydieresis,basic,A,
+U+0131,dotlessi,idotless,basic,B,
+U+0152,OE,OE,basic,A,
+U+0153,oe,oe,basic,A,
+U+0160,Scaron,Scaron,basic,A,
+U+0161,scaron,scaron,basic,A,
+U+0178,Ydieresis,Ydieresis,basic,A,
+U+017D,Zcaron,Zcaron,basic,A,
+U+017E,zcaron,zcaron,basic,A,
+U+0192,florin,florin,basic,A,
+U+02C6,circumflex,circumflex,basic,A,
+U+02C7,caron,caron,basic,B,
+U+02D8,breve,breve,basic,B,
+U+02D9,dotaccent,dotaccent,basic,B,
+U+02DA,ring,ring,basic,B,
+U+02DB,ogonek,ogonek,basic,B,
+U+02DC,tilde,tilde,basic,A,
+U+02DD,hungarumlaut,hungarumlaut,basic,B,
+U+034F,uni034F,graphemejoinercomb,basic,D,
+U+03C0,pi,pi,basic,B,
+U+2000,uni2000,enquad,basic,C,
+U+2001,uni2001,emquad,basic,C,
+U+2002,uni2002,enspace,basic,C,
+U+2003,uni2003,emspace,basic,C,
+U+2004,uni2004,threeperemspace,basic,C,
+U+2005,uni2005,fourperemspace,basic,C,
+U+2006,uni2006,sixperemspace,basic,C,
+U+2007,uni2007,figurespace,basic,C,
+U+2008,uni2008,punctuationspace,basic,C,
+U+2009,uni2009,thinspace,basic,C,
+U+200A,uni200A,hairspace,basic,C,
+U+200B,uni200B,zerowidthspace,basic,C,
+U+200C,uni200C,zerowidthnonjoiner,basic,D,
+U+200D,uni200D,zerowidthjoiner,basic,D,
+U+200E,uni200E,lefttorightmark,rtl,D,
+U+200F,uni200F,righttoleftmark,rtl,D,
+U+2010,uni2010,hyphentwo,basic,C,
+U+2011,uni2011,nonbreakinghyphen,basic,C,
+U+2012,figuredash,figuredash,basic,C,
+U+2013,endash,endash,basic,A,
+U+2014,emdash,emdash,basic,A,
+U+2015,uni2015,horizontalbar,basic,C,
+U+2018,quoteleft,quoteleft,basic,A,
+U+2019,quoteright,quoteright,basic,A,
+U+201A,quotesinglbase,quotesinglbase,basic,A,
+U+201C,quotedblleft,quotedblleft,basic,A,
+U+201D,quotedblright,quotedblright,basic,A,
+U+201E,quotedblbase,quotedblbase,basic,A,
+U+2020,dagger,dagger,basic,A,
+U+2021,daggerdbl,daggerdbl,basic,A,
+U+2022,bullet,bullet,basic,A,
+U+2026,ellipsis,ellipsis,basic,A,
+U+2027,uni2027,hyphenationpoint,basic,C,
+U+2028,uni2028,lineseparator,basic,C,
+U+2029,uni2029,paragraphseparator,basic,C,
+U+202A,uni202A,lefttorightembedding,rtl,D,
+U+202B,uni202B,righttoleftembedding,rtl,D,
+U+202C,uni202C,popdirectionalformatting,rtl,D,
+U+202D,uni202D,lefttorightoverride,rtl,D,
+U+202E,uni202E,righttoleftoverride,rtl,D,
+U+202F,uni202F,narrownbspace,basic,C,
+U+2030,perthousand,perthousand,basic,A,
+U+2039,guilsinglleft,guilsinglleft,basic,A,
+U+203A,guilsinglright,guilsinglright,basic,A,
+U+2044,fraction,fraction,basic,B,
+U+2060,uni2060,wordjoiner,basic,D,
+U+2066,uni2066,lefttorightisolate,rtl,D,
+U+2067,uni2067,righttoleftisolate,rtl,D,
+U+2068,uni2068,firststrongisolate,rtl,D,
+U+2069,uni2069,popdirectionalisolate,rtl,D,
+U+206C,uni206C,inhibitformshaping-ar,rtl,D,
+U+206D,uni206D,activateformshaping-ar,rtl,D,
+U+2074,uni2074,foursuperior,basic,E,
+U+20AC,Euro,euro,basic,A,
+U+2122,trademark,trademark,basic,A,
+U+2126,Omega,Ohm,basic,B,
+U+2202,partialdiff,partialdiff,basic,B,
+U+2206,Delta,Delta,basic,B,
+U+220F,product,product,basic,B,
+U+2211,summation,summation,basic,B,
+U+2212,minus,minus,basic,E,
+U+2215,uni2215,divisionslash,basic,E,
+U+2219,uni2219,bulletoperator,basic,C,Some applications use this instead of 00B7
+U+221A,radical,radical,basic,B,
+U+221E,infinity,infinity,basic,B,
+U+222B,integral,integral,basic,B,
+U+2248,approxequal,approxequal,basic,B,
+U+2260,notequal,notequal,basic,B,
+U+2264,lessequal,lessequal,basic,B,
+U+2265,greaterequal,greaterequal,basic,B,
+U+2423,uni2423,blank,basic,F,Advanced width should probably be the same as a space.
+U+25CA,lozenge,lozenge,basic,B,
+U+25CC,uni25CC,dottedCircle,basic,J,"If your OpenType font supports combining diacritics, be sure to include U+25CC DOTTED CIRCLE in your font, and optionally include this in your positioning rules for all your combining marks. This is because Uniscribe will insert U+25CC between ""illegal"" diacritic sequences (such as two U+064E characters in a row) to make the mistake more visible. (https://docs.microsoft.com/en-us/typography/script-development/arabic#handling-invalid-combining-marks)"
+U+F130,uniF130,FontBslnSideBrngMrkrLft,sil,K,
+U+F131,uniF131,FontBslnSideBrngMrkrRt,sil,K,
+U+FB01,uniFB01,fi,basic,B,
+U+FB02,uniFB02,fl,basic,B,
+U+FE00,uniFE00,VS1,basic,H,Add this to the cmap and point them to null glyphs
+U+FE01,uniFE01,VS2,basic,H,Add this to the cmap and point them to null glyphs
+U+FE02,uniFE02,VS3,basic,H,Add this to the cmap and point them to null glyphs
+U+FE03,uniFE03,VS4,basic,H,Add this to the cmap and point them to null glyphs
+U+FE04,uniFE04,VS5,basic,H,Add this to the cmap and point them to null glyphs
+U+FE05,uniFE05,VS6,basic,H,Add this to the cmap and point them to null glyphs
+U+FE06,uniFE06,VS7,basic,H,Add this to the cmap and point them to null glyphs
+U+FE07,uniFE07,VS8,basic,H,Add this to the cmap and point them to null glyphs
+U+FE08,uniFE08,VS9,basic,H,Add this to the cmap and point them to null glyphs
+U+FE09,uniFE09,VS10,basic,H,Add this to the cmap and point them to null glyphs
+U+FE0A,uniFE0A,VS11,basic,H,Add this to the cmap and point them to null glyphs
+U+FE0B,uniFE0B,VS12,basic,H,Add this to the cmap and point them to null glyphs
+U+FE0C,uniFE0C,VS13,basic,H,Add this to the cmap and point them to null glyphs
+U+FE0D,uniFE0D,VS14,basic,H,Add this to the cmap and point them to null glyphs
+U+FE0E,uniFE0E,VS15,basic,H,Add this to the cmap and point them to null glyphs
+U+FE0F,uniFE0F,VS16,basic,H,Add this to the cmap and point them to null glyphs
+U+FEFF,uniFEFF,zeroWidthNoBreakSpace,basic,I,Making this visible might be helpful
+U+FFFC,uniFFFC,objectReplacementCharacter,basic,G,It is easier for someone looking at the converted text to figure out what's going on if these have a visual representation.
+U+FFFD,uniFFFD,replacementCharacter,basic,G,It is easier for someone looking at the converted text to figure out what's going on if these have a visual representation.
+,,,,,
diff --git a/lib/silfont/data/required_chars.md b/lib/silfont/data/required_chars.md
new file mode 100644
index 0000000..444f2e6
--- /dev/null
+++ b/lib/silfont/data/required_chars.md
@@ -0,0 +1,32 @@
+# required_chars - recommended characters for Non-Roman fonts
+
+For optimal compatibility with a variety of operating systems, all Non-Roman fonts should include
+a set of glyphs for basic Roman characters and punctuation. Ideally this should include all the
+following characters, although some depend on other considerations (see the notes). The basis
+for this list is a union of the Windows Codepage 1252 and MacRoman character sets plus additional
+useful characters.
+
+The csv includes the following headers:
+
+* USV - Unicode Scalar Value
+* ps_name - postscript name of glyph that will end up in production
+* glyph_name - glyphsApp name that will be used in UFO
+* sil_set - set to include in a font
+ * basic - should be included in any Non-Roman font
+ * rtl - should be included in any right-to-left script font
+ * sil - should be included in any SIL font
+* rationale - worded to complete the phrase: "This character is needed ..."
+ * A - in Codepage 1252
+ * B - in MacRoman
+ * C - for publishing
+ * D - for Non-Roman fonts and publishing
+ * E - by Google Fonts
+ * F - by TeX for visible space
+ * G - for encoding conversion utilities
+ * H - in case Variation Sequences are defined in future
+ * I - to detect byte order
+ * J - to render combining marks in isolation
+ * K - to view sidebearings for every glyph using these characters
+* additional_notes - how the character might be used
+
+The list was previously maintained here: https://scriptsource.org/entry/gg5wm9hhd3
diff --git a/lib/silfont/etutil.py b/lib/silfont/etutil.py
new file mode 100644
index 0000000..3587231
--- /dev/null
+++ b/lib/silfont/etutil.py
@@ -0,0 +1,270 @@
+#!/usr/bin/env python
+'Classes and functions for handling XML files in pysilfont scripts'
+__url__ = 'http://github.com/silnrsi/pysilfont'
+__copyright__ = 'Copyright (c) 2015 SIL International (http://www.sil.org)'
+__license__ = 'Released under the MIT License (http://opensource.org/licenses/MIT)'
+__author__ = 'David Raymond'
+
+from xml.etree import ElementTree as ET
+import silfont.core
+
+import re, os, codecs, io, collections
+
+_elementprotect = {
+ '&' : '&amp;',
+ '<' : '&lt;',
+ '>' : '&gt;' }
+_attribprotect = dict(_elementprotect)
+_attribprotect['"'] = '&quot;' # Copy of element protect with double quote added
+
+class ETWriter(object) :
+ """ General purpose ElementTree pretty printer complete with options for attribute order
+ beyond simple sorting, and which elements should use cdata
+
+ Note there is no support for namespaces. Originally there was, and if it is needed in the future look at
+ commits from 10th May 2018 or earlier. The code there would need reworking!"""
+
+ def __init__(self, etree, attributeOrder = {}, takesCData = set(),
+ indentIncr = " ", indentFirst = " ", indentML = False, inlineelem=[], precision = None, floatAttribs = [], intAttribs = []):
+ self.root = etree
+ self.attributeOrder = attributeOrder # Sort order for attributes - just one list for all elements
+ self.takesCData = takesCData
+ self.indentIncr = indentIncr # Incremental increase in indent
+ self.indentFirst = indentFirst # Indent for first level
+ self.indentML = indentML # Add indent to multi-line strings
+ self.inlineelem = inlineelem # For supporting in-line elements. Does not work with mix of inline and other subelements in same element
+ self.precision = precision # Precision to use outputting numeric attribute values
+ self.floatAttribs = floatAttribs # List of float/real attributes used with precision
+ self.intAttribs = intAttribs
+
+ def _protect(self, txt, base=_attribprotect) :
+ return re.sub(r'['+r"".join(base.keys())+r"]", lambda m: base[m.group(0)], txt)
+
+ def serialize_xml(self, base = None, indent = '') :
+ # Create the xml and return as a string
+ outstrings = []
+ outstr=""
+ if base is None :
+ base = self.root
+ outstr += '<?xml version="1.0" encoding="UTF-8"?>\n'
+ if '.pi' in base.attrib : # Processing instructions
+ for pi in base.attrib['.pi'].split(",") : outstr += '<?{}?>\n'.format(pi)
+
+ if '.doctype' in base.attrib : outstr += '<!DOCTYPE {}>\n'.format(base.attrib['.doctype'])
+
+ tag = base.tag
+ attribs = base.attrib
+
+ if '.comments' in attribs :
+ for c in attribs['.comments'].split(",") : outstr += '{}<!--{}-->\n'.format(indent, c)
+
+ i = indent if tag not in self.inlineelem else ""
+ outstr += '{}<{}'.format(i, tag)
+
+ for k in sorted(list(attribs.keys()), key=lambda x: self.attributeOrder.get(x, x)):
+ if k[0] != '.' :
+ att = attribs[k]
+ if self.precision is not None and k in self.floatAttribs :
+ if "." in att:
+ num = round(float(att), self.precision)
+ att = int(num) if num == int(num) else num
+ elif k in self.intAttribs :
+ att = int(round(float(att)))
+ else:
+ att = self._protect(att)
+ outstr += ' {}="{}"'.format(k, att)
+
+ if len(base) or (base.text and base.text.strip()) :
+ outstr += '>'
+ if base.text and base.text.strip() :
+ if tag not in self.takesCData :
+ t = base.text
+ if self.indentML : t = t.replace('\n', '\n' + indent)
+ t = self._protect(t, base=_elementprotect)
+ else :
+ t = "<![CDATA[\n\t" + indent + base.text.replace('\n', '\n\t' + indent) + "\n" + indent + "]]>"
+ outstr += t
+ if len(base) :
+ if base[0].tag not in self.inlineelem : outstr += '\n'
+ if base == self.root:
+ incr = self.indentFirst
+ else:
+ incr = self.indentIncr
+ outstrings.append(outstr); outstr=""
+ for b in base : outstrings.append(self.serialize_xml(base=b, indent=indent + incr))
+ if base[-1].tag not in self.inlineelem : outstr += indent
+ outstr += '</{}>'.format(tag)
+ else :
+ outstr += '/>'
+ if base.tail and base.tail.strip() :
+ outstr += self._protect(base.tail, base=_elementprotect)
+ if tag not in self.inlineelem : outstr += "\n"
+
+ if '.commentsafter' in base.attrib :
+ for c in base.attrib['.commentsafter'].split(",") : outstr += '{}<!--{}-->\n'.format(indent, c)
+
+ outstrings.append(outstr)
+ return "".join(outstrings)
+
+class _container(object) :
+ # Parent class for other objects
+ def __init_(self) :
+ self._contents = {}
+ # Define methods so it acts like an imutable container
+ # (changes should be made via object functions etc)
+ def __len__(self):
+ return len(self._contents)
+ def __getitem__(self, key):
+ return self._contents[key]
+ def __iter__(self):
+ return iter(self._contents)
+ def keys(self) :
+ return self._contents.keys()
+
+class xmlitem(_container):
+ """ The xml data item for an xml file"""
+
+ def __init__(self, dirn = None, filen = None, parse = True, logger=None) :
+ self.logger = logger if logger else silfont.core.loggerobj()
+ self._contents = {}
+ self.dirn = dirn
+ self.filen = filen
+ self.inxmlstr = ""
+ self.outxmlstr = ""
+ self.etree = None
+ self.type = None
+ if filen and dirn :
+ fulln = os.path.join( dirn, filen)
+ self.inxmlstr = io.open(fulln, "rt", encoding="utf-8").read()
+ if parse :
+ try:
+ self.etree = ET.fromstring(self.inxmlstr)
+ except:
+ try:
+ self.etree = ET.fromstring(self.inxmlstr.encode("utf-8"))
+ except Exception as e:
+ self.logger.log("Failed to parse xml for " + fulln, "E")
+ self.logger.log(str(e), "S")
+
+ def write_to_file(self,dirn,filen) :
+ outfile = io.open(os.path.join(dirn,filen),'w', encoding="utf-8")
+ outfile.write(self.outxmlstr)
+
+class ETelement(_container):
+ # Class for an etree element. Mainly used as a parent class
+ # For each tag in the element, ETelement[tag] returns a list of sub-elements with that tag
+ # process_subelements can set attributes for each tag based on a supplied spec
+ def __init__(self,element) :
+ self.element = element
+ self._contents = {}
+ self.reindex()
+
+ def reindex(self) :
+ self._contents = collections.defaultdict(list)
+ for e in self.element :
+ self._contents[e.tag].append(e)
+
+ def remove(self,subelement) :
+ self._contents[subelement.tag].remove(subelement)
+ self.element.remove(subelement)
+
+ def append(self,subelement) :
+ self._contents[subelement.tag].append(subelement)
+ self.element.append(subelement)
+
+ def insert(self,index,subelement) :
+ self._contents[subelement.tag].insert(index,subelement)
+ self.element.insert(index,subelement)
+
+ def replace(self,index,subelement) :
+ self._contents[subelement.tag][index] = subelement
+ self.element[index] = subelement
+
+ def process_attributes(self, attrspec, others = False) :
+ # Process attributes based on list of attributes in the format:
+ # (element attr name, object attr name, required)
+ # If attr does not exist and is not required, set to None
+ # If others is True, attributes not in the list are allowed
+ # Attributes should be listed in the order they should be output if writing xml out
+
+ if not hasattr(self,"parseerrors") or self.parseerrors is None: self.parseerrors=[]
+
+ speclist = {}
+ for (i,spec) in enumerate(attrspec) : speclist[spec[0]] = attrspec[i]
+
+ for eaname in speclist :
+ (eaname,oaname,req) = speclist[eaname]
+ setattr(self, oaname, getattrib(self.element,eaname))
+ if req and getattr(self, oaname) is None : self.parseerrors.append("Required attribute " + eaname + " missing")
+
+ # check for any other attributes
+ for att in self.element.attrib :
+ if att not in speclist :
+ if others:
+ setattr(self, att, getattrib(self.element,att))
+ else :
+ self.parseerrors.append("Invalid attribute " + att)
+
+ def process_subelements(self,subspec, offspec = False) :
+ # Process all subelements based on spec of expected elements
+ # subspec is a list of elements, with each list in the format:
+ # (element name, attribute name, class name, required, multiple valeus allowed)
+ # If cl is set, attribute is set to an object made with that class; otherwise just text of the element
+
+ if not hasattr(self,"parseerrors") or self.parseerrors is None : self.parseerrors=[]
+
+ def make_obj(self,cl,element) : # Create object from element and cascade parse errors down
+ if cl is None : return element.text
+ if cl is ETelement :
+ obj = cl(element) # ETelement does not require parent object, ie self
+ else :
+ obj = cl(self,element)
+ if hasattr(obj,"parseerrors") and obj.parseerrors != [] :
+ if hasattr(obj,"name") and obj.name is not None : # Try to find a name for error reporting
+ name = obj.name
+ elif hasattr(obj,"label") and obj.label is not None :
+ name = obj.label
+ else :
+ name = ""
+
+ self.parseerrors.append("Errors parsing " + element.tag + " element: " + name)
+ for error in obj.parseerrors :
+ self.parseerrors.append(" " + error)
+ return obj
+
+ speclist = {}
+ for (i,spec) in enumerate(subspec) : speclist[spec[0]] = subspec[i]
+
+ for ename in speclist :
+ (ename,aname,cl,req,multi) = speclist[ename]
+ initval = [] if multi else None
+ setattr(self,aname,initval)
+
+ for ename in self : # Process all elements
+ if ename in speclist :
+ (ename,aname,cl,req,multi) = speclist[ename]
+ elements = self[ename]
+ if multi :
+ for elem in elements : getattr(self,aname).append(make_obj(self,cl,elem))
+ else :
+ setattr(self,aname,make_obj(self,cl,elements[0]))
+ if len(elements) > 1 : self.parseerrors.append("Multiple " + ename + " elements not allowed")
+ else:
+ if offspec: # Elements not in spec are allowed so create list of sub-elemente.
+ setattr(self,ename,[])
+ for elem in elements : getattr(self,ename).append(ETelement(elem))
+ else :
+ self.parseerrors.append("Invalid element: " + ename)
+
+ for ename in speclist : # Check values exist for required elements etc
+ (ename,aname,cl,req,multi) = speclist[ename]
+
+ val = getattr(self,aname)
+ if req :
+ if multi and val == [] : self.parseerrors.append("No " + ename + " elements ")
+ if not multi and val == None : self.parseerrors.append("No " + ename + " element")
+
+def makeAttribOrder(attriblist) : # Turn a list of attrib names into an attributeOrder dict for ETWriter
+ return dict(map(lambda x:(x[1], x[0]), enumerate(attriblist)))
+
+def getattrib(element,attrib) : return element.attrib[attrib] if attrib in element.attrib else None \ No newline at end of file
diff --git a/lib/silfont/fbtests/__init__.py b/lib/silfont/fbtests/__init__.py
new file mode 100755
index 0000000..e69de29
--- /dev/null
+++ b/lib/silfont/fbtests/__init__.py
diff --git a/lib/silfont/fbtests/silnotcjk.py b/lib/silfont/fbtests/silnotcjk.py
new file mode 100644
index 0000000..9ebdafd
--- /dev/null
+++ b/lib/silfont/fbtests/silnotcjk.py
@@ -0,0 +1,230 @@
+#!/usr/bin/env python
+'''These are copies of checks that have the "not is_cjk" condition, but these versions have that condition removed.
+The is_cjk condition was being matched by multiple fonts that are not cjk fonts - but do have some cjk punctuation characters.
+These checks based on based on examples from Font Bakery, copyright 2017 The Font Bakery Authors, licensed under the Apache 2.0 license'''
+__url__ = 'http://github.com/silnrsi/pysilfont'
+__copyright__ = 'Copyright (c) 2022 SIL International (http://www.sil.org)'
+__license__ = 'Released under the MIT License (http://opensource.org/licenses/MIT)'
+__author__ = 'David Raymond'
+
+from fontbakery.checkrunner import Section, PASS, FAIL, WARN, ERROR, INFO, SKIP
+from fontbakery.callable import condition, check, disable
+from fontbakery.message import Message
+from fontbakery.profiles.shared_conditions import typo_metrics_enabled
+import os
+from fontbakery.constants import NameID, PlatformID, WindowsEncodingID
+
+@check(
+ id = 'org.sil/check/family/win_ascent_and_descent',
+ conditions = ['vmetrics'],
+ rationale = """
+ Based on com.google.fonts/check/family/win_ascent_and_descent but with the 'not is_cjk' condition removed
+ """
+)
+def org_sil_check_family_win_ascent_and_descent(ttFont, vmetrics):
+ """Checking OS/2 usWinAscent & usWinDescent."""
+
+ if "OS/2" not in ttFont:
+ yield FAIL,\
+ Message("lacks-OS/2",
+ "Font file lacks OS/2 table")
+ return
+
+ failed = False
+ os2_table = ttFont['OS/2']
+ win_ascent = os2_table.usWinAscent
+ win_descent = os2_table.usWinDescent
+ y_max = vmetrics['ymax']
+ y_min = vmetrics['ymin']
+
+ # OS/2 usWinAscent:
+ if win_ascent < y_max:
+ failed = True
+ yield FAIL,\
+ Message("ascent",
+ f"OS/2.usWinAscent value should be"
+ f" equal or greater than {y_max},"
+ f" but got {win_ascent} instead")
+ if win_ascent > y_max * 2:
+ failed = True
+ yield FAIL,\
+ Message("ascent",
+ f"OS/2.usWinAscent value"
+ f" {win_ascent} is too large."
+ f" It should be less than double the yMax."
+ f" Current yMax value is {y_max}")
+ # OS/2 usWinDescent:
+ if win_descent < abs(y_min):
+ failed = True
+ yield FAIL,\
+ Message("descent",
+ f"OS/2.usWinDescent value should be equal or"
+ f" greater than {abs(y_min)}, but got"
+ f" {win_descent} instead.")
+
+ if win_descent > abs(y_min) * 2:
+ failed = True
+ yield FAIL,\
+ Message("descent",
+ f"OS/2.usWinDescent value"
+ f" {win_descent} is too large."
+ f" It should be less than double the yMin."
+ f" Current absolute yMin value is {abs(y_min)}")
+ if not failed:
+ yield PASS, "OS/2 usWinAscent & usWinDescent values look good!"
+
+
+@check(
+ id = 'org.sil/check/os2_metrics_match_hhea',
+ rationale="""
+ Based on com.google.fonts/check/os2_metrics_match_hhea but with the 'not is_cjk' condition removed
+ """
+)
+def org_sil_check_os2_metrics_match_hhea(ttFont):
+ """Checking OS/2 Metrics match hhea Metrics."""
+
+ filename = os.path.basename(ttFont.reader.file.name)
+
+ # Check both OS/2 and hhea are present.
+ missing_tables = False
+
+ required = ["OS/2", "hhea"]
+ for key in required:
+ if key not in ttFont:
+ missing_tables = True
+ yield FAIL,\
+ Message(f'lacks-{key}',
+ f"{filename} lacks a '{key}' table.")
+
+ if missing_tables:
+ return
+
+ # OS/2 sTypoAscender and sTypoDescender match hhea ascent and descent
+ if ttFont["OS/2"].sTypoAscender != ttFont["hhea"].ascent:
+ yield FAIL,\
+ Message("ascender",
+ f"OS/2 sTypoAscender ({ttFont['OS/2'].sTypoAscender})"
+ f" and hhea ascent ({ttFont['hhea'].ascent})"
+ f" must be equal.")
+ elif ttFont["OS/2"].sTypoDescender != ttFont["hhea"].descent:
+ yield FAIL,\
+ Message("descender",
+ f"OS/2 sTypoDescender ({ttFont['OS/2'].sTypoDescender})"
+ f" and hhea descent ({ttFont['hhea'].descent})"
+ f" must be equal.")
+ elif ttFont["OS/2"].sTypoLineGap != ttFont["hhea"].lineGap:
+ yield FAIL,\
+ Message("lineGap",
+ f"OS/2 sTypoLineGap ({ttFont['OS/2'].sTypoLineGap})"
+ f" and hhea lineGap ({ttFont['hhea'].lineGap})"
+ f" must be equal.")
+ else:
+ yield PASS, ("OS/2.sTypoAscender/Descender values"
+ " match hhea.ascent/descent.")
+
+@check(
+ id = "org.sil/check/os2/use_typo_metrics",
+ rationale="""
+ Based on com.google.fonts/check/os2/use_typo_metrics but with the 'not is_cjk' condition removed
+ """
+ )
+def corg_sil_check_os2_fsselectionbit7(ttFonts):
+ """OS/2.fsSelection bit 7 (USE_TYPO_METRICS) is set in all fonts."""
+
+ bad_fonts = []
+ for ttFont in ttFonts:
+ if not ttFont["OS/2"].fsSelection & (1 << 7):
+ bad_fonts.append(ttFont.reader.file.name)
+
+ if bad_fonts:
+ yield FAIL,\
+ Message('missing-os2-fsselection-bit7',
+ f"OS/2.fsSelection bit 7 (USE_TYPO_METRICS) was"
+ f"NOT set in the following fonts: {bad_fonts}.")
+ else:
+ yield PASS, "OK"
+
+
+@check(
+ id = 'org.sil/check/vertical_metrics',
+# conditions = ['not remote_styles'],
+ rationale="""
+ Based on com.google.fonts/check/vertical_metrics but with the 'not is_cjk' condition removed
+ """
+)
+def org_sil_check_vertical_metrics(ttFont):
+ """Check font follows the Google Fonts vertical metric schema"""
+ filename = os.path.basename(ttFont.reader.file.name)
+
+ # Check necessary tables are present.
+ missing_tables = False
+ required = ["OS/2", "hhea", "head"]
+ for key in required:
+ if key not in ttFont:
+ missing_tables = True
+ yield FAIL,\
+ Message(f'lacks-{key}',
+ f"{filename} lacks a '{key}' table.")
+
+ if missing_tables:
+ return
+
+ font_upm = ttFont['head'].unitsPerEm
+ font_metrics = {
+ 'OS/2.sTypoAscender': ttFont['OS/2'].sTypoAscender,
+ 'OS/2.sTypoDescender': ttFont['OS/2'].sTypoDescender,
+ 'OS/2.sTypoLineGap': ttFont['OS/2'].sTypoLineGap,
+ 'hhea.ascent': ttFont['hhea'].ascent,
+ 'hhea.descent': ttFont['hhea'].descent,
+ 'hhea.lineGap': ttFont['hhea'].lineGap,
+ 'OS/2.usWinAscent': ttFont['OS/2'].usWinAscent,
+ 'OS/2.usWinDescent': ttFont['OS/2'].usWinDescent
+ }
+ expected_metrics = {
+ 'OS/2.sTypoLineGap': 0,
+ 'hhea.lineGap': 0,
+ }
+
+ failed = False
+ warn = False
+
+ # Check typo metrics and hhea lineGap match our expected values
+ for k in expected_metrics:
+ if font_metrics[k] != expected_metrics[k]:
+ failed = True
+ yield FAIL,\
+ Message(f'bad-{k}',
+ f'{k} is "{font_metrics[k]}" it should be {expected_metrics[k]}')
+
+ hhea_sum = (font_metrics['hhea.ascent'] +
+ abs(font_metrics['hhea.descent']) +
+ font_metrics['hhea.lineGap']) / font_upm
+
+ # Check the sum of the hhea metrics is not below 1.2
+ # (120% of upm or 1200 units for 1000 upm font)
+ if hhea_sum < 1.2:
+ failed = True
+ yield FAIL,\
+ Message('bad-hhea-range',
+ 'The sum of hhea.ascender+abs(hhea.descender)+hhea.lineGap '
+ f'is {int(hhea_sum*font_upm)} when it should be at least {int(font_upm*1.2)}')
+
+ # Check the sum of the hhea metrics is below 2.0
+ elif hhea_sum > 2.0:
+ failed = True
+ yield FAIL,\
+ Message('bad-hhea-range',
+ 'The sum of hhea.ascender+abs(hhea.descender)+hhea.lineGap '
+ f'is {int(hhea_sum*font_upm)} when it should be at most {int(font_upm*2.0)}')
+
+ # Check the sum of the hhea metrics is between 1.1-1.5x of the font's upm
+ elif hhea_sum > 1.5:
+ warn = True
+ yield WARN,\
+ Message('bad-hhea-range',
+ "We recommend the absolute sum of the hhea metrics should be"
+ f" between 1.2-1.5x of the font's upm. This font has {hhea_sum}x ({int(hhea_sum*font_upm)})")
+
+ if not failed and not warn:
+ yield PASS, 'Vertical metrics are good'
+
diff --git a/lib/silfont/fbtests/silttfchecks.py b/lib/silfont/fbtests/silttfchecks.py
new file mode 100644
index 0000000..d38ab77
--- /dev/null
+++ b/lib/silfont/fbtests/silttfchecks.py
@@ -0,0 +1,250 @@
+#!/usr/bin/env python
+'''Checks to be imported by ttfchecks.py
+Some checks based on examples from Font Bakery, copyright 2017 The Font Bakery Authors, licensed under the Apache 2.0 license'''
+__url__ = 'http://github.com/silnrsi/pysilfont'
+__copyright__ = 'Copyright (c) 2022 SIL International (http://www.sil.org)'
+__license__ = 'Released under the MIT License (http://opensource.org/licenses/MIT)'
+__author__ = 'David Raymond'
+
+from fontbakery.checkrunner import Section, PASS, FAIL, WARN, ERROR, INFO, SKIP
+from fontbakery.callable import condition, check, disable
+from fontbakery.message import Message
+from fontbakery.constants import NameID, PlatformID, WindowsEncodingID
+
+@check(
+ id = 'org.sil/check/name/version_format',
+ rationale = """
+ Based on com.google.fonts/check/name/version_format but:
+ - Checks for two valid formats:
+ - Production: exactly 3 digits after decimal point
+
+
+ - Allows major version to be 0
+ - Allows extra info after numbers, eg for beta or dev versions
+ """
+)
+def org_sil_version_format(ttFont):
+ "Version format is correct in 'name' table?"
+
+ from fontbakery.utils import get_name_entry_strings
+ import re
+
+ failed = False
+ version_entries = get_name_entry_strings(ttFont, NameID.VERSION_STRING)
+ if len(version_entries) == 0:
+ failed = True
+ yield FAIL,\
+ Message("no-version-string",
+ f"Font lacks a NameID.VERSION_STRING"
+ f" (nameID={NameID.VERSION_STRING}) entry")
+
+ for ventry in version_entries:
+ if not re.match(r'Version [0-9]+\.\d{3}( .+)*$', ventry):
+ failed = True
+ yield FAIL,\
+ Message("bad-version-strings",
+ f'The NameID.VERSION_STRING'
+ f' (nameID={NameID.VERSION_STRING}) value must'
+ f' follow the pattern "Version X.nnn devstring" with X.nnn'
+ f' greater than or equal to 0.000.'
+ f' Current version string is: "{ventry}"')
+ if not failed:
+ yield PASS, "Version format in NAME table entries is correct."
+
+@check(
+ id = 'org.sil/check/whitespace_widths'
+)
+def org_sil_whitespace_widths(ttFont):
+ """Checks with widths of space characters in the font against best practice"""
+ from fontbakery.utils import get_glyph_name
+
+ allok = True
+ space_data = {
+ 0x0020: ['Space'],
+ 0x00A0: ['No-break space'],
+ 0x2008: ['Punctuation space'],
+ 0x2003: ['Em space'],
+ 0x2002: ['En space'],
+ 0x2000: ['En quad'],
+ 0x2001: ['Em quad'],
+ 0x2004: ['Three-per-em space'],
+ 0x2005: ['Four-per-em space'],
+ 0x2006: ['Six-per-em space'],
+ 0x2009: ['Thin space'],
+ 0x200A: ['Hair space'],
+ 0x202F: ['Narrow no-break space'],
+ 0x002E: ['Full stop'], # Non-space character where the width is needed for comparison
+ }
+ for sp in space_data:
+ spname = get_glyph_name(ttFont, sp)
+ if spname is None:
+ spwidth = None
+ else:
+ spwidth = ttFont['hmtx'][spname][0]
+ space_data[sp].append(spname)
+ space_data[sp].append(spwidth)
+
+ # Other width info needed from the font
+ upm = ttFont['head'].unitsPerEm
+ fullstopw = space_data[46][2]
+
+ # Widths used for comparisons
+ spw = space_data[32][2]
+ if spw is None:
+ allok = False
+ yield WARN, "No space in the font so No-break space (if present) can't be checked"
+ emw = space_data[0x2003][2]
+ if emw is None:
+ allok = False
+ yield WARN, f'No em space in the font. Will be assumed to be units per em ({upm}) for other checking'
+ emw = upm
+ enw = space_data[0x2002][2]
+ if enw is None:
+ allok = False
+ yield WARN, f'No en space in the font. Will be assumed to be 1/2 em space width ({emw/2}) for checking en quad (if present)'
+ enw = emw/2
+
+ # Now check all the specific space widths. Only check if the space exists in the font
+ def checkspace(spacechar, minwidth, maxwidth=None):
+ sdata = space_data[spacechar]
+ if sdata[1]: # Name is set to None if not in font
+ # Allow for width(s) not being integer (eg em/6) so test against rounding up or down
+ minw = int(minwidth)
+ if maxwidth:
+ maxw = int(maxwidth)
+ if maxwidth > maxw: maxw += 1 # Had been rounded down, so round up
+ else:
+ maxw = minw if minw == minwidth else minw +1 # Had been rounded down, so allow rounded up as well
+ charw = sdata[2]
+ if not(minw <= charw <= maxw):
+ return (f'Width of {sdata[0]} ({spacechar:#04x}) is {str(charw)}: ', minw, maxw)
+ return (None,0,0)
+
+ # No-break space
+ (message, minw, maxw) = checkspace(0x00A0, spw)
+ if message: allok = False; yield FAIL, message + f"Should match width of space ({spw})"
+ # Punctuation space
+ (message, minw, maxw) = checkspace(0x2008, fullstopw)
+ if message: allok = False; yield FAIL, message + f"Should match width of full stop ({fullstopw})"
+ # Em space
+ (message, minw, maxw) = checkspace(0x2003, upm)
+ if message: allok = False; yield WARN, message + f"Should match units per em ({upm})"
+ # En space
+ (message, minw, maxw) = checkspace(0x2002, emw/2)
+ if message:
+ allok = False
+ widths = f'{minw}' if minw == maxw else f'{minw} or {maxw}'
+ yield WARN, message + f"Should be half the width of em ({widths})"
+ # En quad
+ (message, minw, maxw) = checkspace(0x2000, enw)
+ if message: allok = False; yield WARN, message + f"Should be the same width as en ({enw})"
+ # Em quad
+ (message, minw, maxw) = checkspace(0x2001, emw)
+ if message: allok = False; yield WARN, message + f"Should be the same width as em ({emw})"
+ # Three-per-em space
+ (message, minw, maxw) = checkspace(0x2004, emw/3)
+ if message:
+ allok = False
+ widths = f'{minw}' if minw == maxw else f'{minw} or {maxw}'
+ yield WARN, message + f"Should be 1/3 the width of em ({widths})"
+ # Four-per-em space
+ (message, minw, maxw) = checkspace(0x2005, emw/4)
+ if message:
+ allok = False
+ widths = f'{minw}' if minw == maxw else f'{minw} or {maxw}'
+ yield WARN, message + f"Should be 1/4 the width of em ({widths})",
+ # Six-per-em space
+ (message, minw, maxw) = checkspace(0x2006, emw/6)
+ if message:
+ allok = False
+ widths = f'{minw}' if minw == maxw else f'{minw} or {maxw}'
+ yield WARN, message + f"Should be 1/6 the width of em ({widths})",
+ # Thin space
+ (message, minw, maxw) = checkspace(0x2009, emw/6, emw/5)
+ if message:
+ allok = False
+ yield WARN, message + f"Should be between 1/6 and 1/5 the width of em ({minw} and {maxw})"
+ # Hair space
+ (message, minw, maxw) = checkspace(0x200A,
+ emw/16, emw/10)
+ if message:
+ allok = False
+ yield WARN, message + f"Should be between 1/16 and 1/10 the width of em ({minw} and {maxw})"
+ # Narrow no-break space
+ (message, minw, maxw) = checkspace(0x202F,
+ emw/6, emw/5)
+ if message:
+ allok = False
+ yield WARN, message + f"Should be between 1/6 and 1/5 the width of em ({minw} and {maxw})"
+
+ if allok:
+ yield PASS, "Space widths all match expected values"
+
+@check(
+ id = 'org.sil/check/number_widths'
+)
+def org_sil_number_widths(ttFont, config):
+ """Check widths of latin digits 0-9 are equal and match that of figure space"""
+ from fontbakery.utils import get_glyph_name
+
+ num_data = {
+ 0x0030: ['zero'],
+ 0x0031: ['one'],
+ 0x0032: ['two'],
+ 0x0033: ['three'],
+ 0x0034: ['four'],
+ 0x0035: ['five'],
+ 0x0036: ['six'],
+ 0x0037: ['seven'],
+ 0x0038: ['eight'],
+ 0x0039: ['nine'],
+ 0x2007: ['figurespace'] # Figure space should be the same as numerals
+ }
+
+ fontnames = []
+ for x in (ttFont['name'].names[1].string, ttFont['name'].names[2].string):
+ txt=""
+ for i in range(1,len(x),2): txt += x.decode()[i]
+ fontnames.append(txt)
+
+ for num in num_data:
+ name = get_glyph_name(ttFont, num)
+ if name is None:
+ width = -1 # So different from Zero!
+ else:
+ width = ttFont['hmtx'][name][0]
+ num_data[num].append(name)
+ num_data[num].append(width)
+
+ zerowidth = num_data[48][2]
+ if zerowidth ==-1:
+ yield FAIL, "No zero in font - remainder of check not run"
+ return
+
+ # Check non-zero digits are present and have same width as zero
+ digitsdiff = ""
+ digitsmissing = ""
+ for i in range(49,58):
+ ndata = num_data[i]
+ width = ndata[2]
+ if width != zerowidth:
+ if width == -1:
+ digitsmissing += ndata[1] + " "
+ else:
+ digitsdiff += ndata[1] + " "
+
+ # Check figure space
+ figuremess = ""
+ ndata = num_data[0x2007]
+ width = ndata[2]
+ if width != zerowidth:
+ if width == -1:
+ figuremess = "No figure space in font"
+ else:
+ figuremess = f'The width of figure space ({ndata[1]}) does not match the width of zero'
+ if digitsmissing or digitsdiff or figuremess:
+ if digitsmissing: yield FAIL, f"Digits missing: {digitsmissing}"
+ if digitsdiff: yield WARN, f"Digits with different width from Zero: {digitsdiff}"
+ if figuremess: yield WARN, figuremess
+ else:
+ yield PASS, "All number widths are OK"
diff --git a/lib/silfont/fbtests/ttfchecks.py b/lib/silfont/fbtests/ttfchecks.py
new file mode 100644
index 0000000..e05ecb1
--- /dev/null
+++ b/lib/silfont/fbtests/ttfchecks.py
@@ -0,0 +1,305 @@
+#!/usr/bin/env python
+'Support for use of Fontbakery ttf checks'
+__url__ = 'http://github.com/silnrsi/pysilfont'
+__copyright__ = 'Copyright (c) 2020 SIL International (http://www.sil.org)'
+__license__ = 'Released under the MIT License (http://opensource.org/licenses/MIT)'
+__author__ = 'David Raymond'
+
+from fontbakery.checkrunner import Section, PASS, FAIL, WARN, ERROR, INFO, SKIP
+from fontbakery.callable import condition, check, disable
+from fontbakery.message import Message
+from fontbakery.fonts_profile import profile_factory
+from fontbakery.constants import NameID, PlatformID, WindowsEncodingID
+from fontbakery.profiles.googlefonts import METADATA_CHECKS, REPO_CHECKS, DESCRIPTION_CHECKS
+from fontbakery.profiles.ufo_sources import UFO_PROFILE_CHECKS
+from fontbakery.profiles.universal import DESIGNSPACE_CHECKS
+from silfont.fbtests.silttfchecks import *
+from silfont.fbtests.silnotcjk import *
+
+from collections import OrderedDict
+
+# Set imports of standard ttf tests
+
+profile_imports = ("fontbakery.profiles.universal",
+ "fontbakery.profiles.googlefonts",
+ "fontbakery.profiles.adobefonts",
+ "fontbakery.profiles.notofonts",
+ "fontbakery.profiles.fontval")
+
+def make_base_profile():
+ profile = profile_factory(default_section=Section("SIL Fonts"))
+ profile.auto_register(globals())
+
+ # Exclude groups of checks that check files other than ttfs
+ for checkid in DESCRIPTION_CHECKS + DESIGNSPACE_CHECKS + METADATA_CHECKS + REPO_CHECKS + UFO_PROFILE_CHECKS:
+ if checkid in profile._check_registry: profile.remove_check(checkid)
+
+ return profile
+
+def make_profile(check_list, variable_font=False):
+ profile = make_base_profile()
+
+ # Exclude all the checks we don't want to run
+ for checkid in check_list:
+ if checkid in profile._check_registry:
+ check_item = check_list[checkid]
+ exclude = check_item["exclude"] if "exclude" in check_item else False
+ if exclude: profile.remove_check(checkid)
+
+ # Exclude further sets of checks to reduce number of skips and so have less clutter in html results
+ for checkid in sorted(set(profile._check_registry.keys())):
+ section = profile._check_registry[checkid]
+ check = section.get_check(checkid)
+ conditions = getattr(check, "conditions")
+ exclude = False
+ if variable_font and "not is_variable_font" in conditions: exclude = True
+ if not variable_font and "is_variable_font" in conditions: exclude = True
+ if "noto" in checkid.lower(): exclude = True # These will be specific to Noto fonts
+ if ":adobefonts" in checkid.lower(): exclude = True # Copy of standard test with overridden results so no new info
+
+ if exclude: profile.remove_check(checkid)
+ # Remove further checks that are only relevant for variable fonts but don't use the is_variable_font condition
+ if not variable_font:
+ for checkid in (
+ "com.adobe.fonts/check/stat_has_axis_value_tables",
+ "com.google.fonts/check/STAT_strings",
+ "com.google.fonts/check/STAT/axis_order"):
+ if checkid in profile._check_registry.keys(): profile.remove_check(checkid)
+ return profile
+
+def all_checks_dict(): # An ordered dict of all checks designed for exporting the data
+ profile = make_base_profile()
+ check_dict=OrderedDict()
+
+ for checkid in sorted(set(profile._check_registry.keys()), key=str.casefold):
+ if "noto" in checkid.lower(): continue # We wxclude these in make_profile()
+ if ":adobefonts" in checkid.lower(): continue # We wxclude these in make_profile()
+
+ section = profile._check_registry[checkid]
+ check = section.get_check(checkid)
+
+ conditions = getattr(check, "conditions")
+ conditionstxt=""
+ for condition in conditions:
+ conditionstxt += condition + "\n"
+ conditionstxt = conditionstxt.strip()
+
+ rationale = getattr(check,"rationale")
+ rationale = "" if rationale is None else rationale.strip().replace("\n ", "\n") # Remove extraneous whitespace
+
+ psfaction = psfcheck_list[checkid] if checkid in psfcheck_list else "Not in psfcheck_list"
+
+ item = {"psfaction": psfaction,
+ "section": section.name,
+ "description": getattr(check, "description"),
+ "rationale": rationale,
+ "conditions": conditionstxt
+ }
+ check_dict[checkid] = item
+
+ for checkid in psfcheck_list: # Look for checks no longer in Font Bakery
+ if checkid not in check_dict:
+ check_dict[checkid] = {"psfaction": psfcheck_list[checkid],
+ "section": "Missing",
+ "description": "Check not found",
+ "rationale": "",
+ "conditions": ""
+ }
+
+ return check_dict
+
+psfcheck_list = {}
+psfcheck_list['com.adobe.fonts/check/cff_call_depth'] = {'exclude': True}
+psfcheck_list['com.adobe.fonts/check/cff_deprecated_operators'] = {'exclude': True}
+psfcheck_list['com.adobe.fonts/check/cff2_call_depth'] = {'exclude': True}
+psfcheck_list['com.adobe.fonts/check/family/bold_italic_unique_for_nameid1'] = {}
+psfcheck_list['com.adobe.fonts/check/family/consistent_upm'] = {}
+psfcheck_list['com.adobe.fonts/check/family/max_4_fonts_per_family_name'] = {}
+psfcheck_list['com.adobe.fonts/check/find_empty_letters'] = {}
+psfcheck_list['com.adobe.fonts/check/freetype_rasterizer'] = {'exclude': True}
+psfcheck_list['com.adobe.fonts/check/fsselection_matches_macstyle'] = {}
+psfcheck_list['com.adobe.fonts/check/name/empty_records'] = {}
+psfcheck_list['com.adobe.fonts/check/name/postscript_name_consistency'] = {}
+psfcheck_list['com.adobe.fonts/check/nameid_1_win_english'] = {}
+psfcheck_list['com.adobe.fonts/check/name/postscript_vs_cff'] = {'exclude': True}
+psfcheck_list['com.adobe.fonts/check/sfnt_version'] = {}
+psfcheck_list['com.adobe.fonts/check/stat_has_axis_value_tables'] = {}
+psfcheck_list['com.adobe.fonts/check/varfont/distinct_instance_records'] = {}
+psfcheck_list['com.adobe.fonts/check/varfont/same_size_instance_records'] = {}
+psfcheck_list['com.adobe.fonts/check/varfont/valid_axis_nameid'] = {}
+psfcheck_list['com.adobe.fonts/check/varfont/valid_default_instance_nameids'] = {}
+psfcheck_list['com.adobe.fonts/check/varfont/valid_postscript_nameid'] = {}
+psfcheck_list['com.adobe.fonts/check/varfont/valid_subfamily_nameid'] = {}
+psfcheck_list['com.fontwerk/check/inconsistencies_between_fvar_stat'] = {}
+psfcheck_list['com.fontwerk/check/weight_class_fvar'] = {}
+psfcheck_list['com.google.fonts/check/aat'] = {}
+psfcheck_list['com.google.fonts/check/all_glyphs_have_codepoints'] = {'exclude': True}
+psfcheck_list['com.google.fonts/check/canonical_filename'] = {}
+psfcheck_list['com.google.fonts/check/cjk_chws_feature'] = {'exclude': True}
+psfcheck_list['com.google.fonts/check/cjk_not_enough_glyphs'] = {'exclude': True}
+psfcheck_list['com.google.fonts/check/cjk_vertical_metrics'] = {'exclude': True}
+psfcheck_list['com.google.fonts/check/cjk_vertical_metrics_regressions'] = {'exclude': True}
+psfcheck_list['com.google.fonts/check/cmap/alien_codepoints'] = {'exclude': True}
+psfcheck_list['com.google.fonts/check/cmap/format_12'] = {'exclude': True}
+psfcheck_list['com.google.fonts/check/cmap/unexpected_subtables'] = {}
+psfcheck_list['com.google.fonts/check/code_pages'] = {}
+psfcheck_list['com.google.fonts/check/contour_count'] = {'exclude': True}
+psfcheck_list['com.google.fonts/check/dotted_circle'] = {}
+psfcheck_list['com.google.fonts/check/dsig'] = {'exclude': True}
+psfcheck_list['com.google.fonts/check/epar'] = {'exclude': True}
+psfcheck_list['com.google.fonts/check/family/control_chars'] = {}
+psfcheck_list['com.google.fonts/check/family/equal_font_versions'] = {}
+psfcheck_list['com.google.fonts/check/family/equal_unicode_encodings'] = {}
+psfcheck_list['com.google.fonts/check/gpos7'] = {}
+psfcheck_list['com.google.fonts/check/family/has_license'] = {'exclude': True}
+psfcheck_list['com.google.fonts/check/family/italics_have_roman_counterparts'] = {}
+psfcheck_list['com.google.fonts/check/family/panose_familytype'] = {}
+psfcheck_list['com.google.fonts/check/family/panose_proportion'] = {}
+psfcheck_list['com.google.fonts/check/family/single_directory'] = {}
+psfcheck_list['com.google.fonts/check/family/tnum_horizontal_metrics'] = {}
+psfcheck_list['com.google.fonts/check/family/underline_thickness'] = {}
+psfcheck_list['com.google.fonts/check/family/vertical_metrics'] = {}
+psfcheck_list['com.google.fonts/check/family/win_ascent_and_descent'] = {'exclude': True}
+# {'change_status': {'FAIL': 'WARN', 'reason': 'Under review'}}
+psfcheck_list['com.google.fonts/check/family_naming_recommendations'] = {}
+psfcheck_list['com.google.fonts/check/file_size'] = {}
+psfcheck_list['com.google.fonts/check/font_copyright'] = {'exclude': True}
+psfcheck_list['com.google.fonts/check/font_version'] = {}
+psfcheck_list['com.google.fonts/check/fontbakery_version'] = {'exclude': True}
+psfcheck_list['com.google.fonts/check/fontdata_namecheck'] = {'exclude': True}
+psfcheck_list['com.google.fonts/check/fontv'] = {'exclude': True}
+psfcheck_list['com.google.fonts/check/fontvalidator'] = {'exclude': True}
+psfcheck_list['com.google.fonts/check/fsselection'] = {}
+psfcheck_list['com.google.fonts/check/fstype'] = {}
+psfcheck_list['com.google.fonts/check/fvar_name_entries'] = {}
+psfcheck_list['com.google.fonts/check/gasp'] = {'exclude': True}
+psfcheck_list['com.google.fonts/check/gdef_mark_chars'] = {}
+psfcheck_list['com.google.fonts/check/gdef_non_mark_chars'] = {}
+psfcheck_list['com.google.fonts/check/gdef_spacing_marks'] = {}
+psfcheck_list['com.google.fonts/check/gf-axisregistry/fvar_axis_defaults'] = {}
+psfcheck_list['com.google.fonts/check/glyf_nested_components'] = {}
+psfcheck_list['com.google.fonts/check/glyf_non_transformed_duplicate_components'] = {}
+psfcheck_list['com.google.fonts/check/glyf_unused_data'] = {}
+psfcheck_list['com.google.fonts/check/glyph_coverage'] = {'exclude': True}
+psfcheck_list['com.google.fonts/check/gpos_kerning_info'] = {}
+psfcheck_list['com.google.fonts/check/has_ttfautohint_params'] = {'exclude': True}
+psfcheck_list['com.google.fonts/check/hinting_impact'] = {}
+psfcheck_list['com.google.fonts/check/hmtx/comma_period'] = {'exclude': True}
+psfcheck_list['com.google.fonts/check/hmtx/encoded_latin_digits'] = {'exclude': True}
+psfcheck_list['com.google.fonts/check/hmtx/whitespace_advances'] = {'exclude': True}
+psfcheck_list['com.google.fonts/check/integer_ppem_if_hinted'] = {}
+psfcheck_list['com.google.fonts/check/italic_angle'] = {}
+psfcheck_list['com.google.fonts/check/kern_table'] = {}
+psfcheck_list['com.google.fonts/check/kerning_for_non_ligated_sequences'] = {'exclude': True}
+psfcheck_list['com.google.fonts/check/layout_valid_feature_tags'] = {}
+psfcheck_list['com.google.fonts/check/layout_valid_language_tags'] = \
+ {'change_status': {'FAIL': 'WARN', 'reason': 'The "invalid" ones are used by Harfbuzz'}}
+psfcheck_list['com.google.fonts/check/layout_valid_script_tags'] = {}
+psfcheck_list['com.google.fonts/check/ligature_carets'] = {'exclude': True}
+psfcheck_list['com.google.fonts/check/linegaps'] = {}
+psfcheck_list['com.google.fonts/check/loca/maxp_num_glyphs'] = {}
+psfcheck_list['com.google.fonts/check/mac_style'] = {}
+psfcheck_list['com.google.fonts/check/mandatory_avar_table'] = {}
+psfcheck_list['com.google.fonts/check/mandatory_glyphs'] = {}
+psfcheck_list['com.google.fonts/check/maxadvancewidth'] = {}
+psfcheck_list['com.google.fonts/check/meta/script_lang_tags'] = {'exclude': True}
+psfcheck_list['com.google.fonts/check/missing_small_caps_glyphs'] = {}
+psfcheck_list['com.google.fonts/check/monospace'] = {}
+psfcheck_list['com.google.fonts/check/name/ascii_only_entries'] = {}
+psfcheck_list['com.google.fonts/check/name/copyright_length'] = {}
+psfcheck_list['com.google.fonts/check/name/description_max_length'] = {}
+psfcheck_list['com.google.fonts/check/name/family_and_style_max_length'] = {}
+psfcheck_list['com.google.fonts/check/name/familyname'] = {}
+psfcheck_list['com.google.fonts/check/name/familyname_first_char'] = {}
+psfcheck_list['com.google.fonts/check/name/fullfontname'] = {}
+psfcheck_list['com.google.fonts/check/name/license'] = {'exclude': True}
+psfcheck_list['com.google.fonts/check/name/license_url'] = {'exclude': True}
+psfcheck_list['com.google.fonts/check/name/line_breaks'] = {'exclude': True}
+psfcheck_list['com.google.fonts/check/name/mandatory_entries'] = {}
+psfcheck_list['com.google.fonts/check/name/match_familyname_fullfont'] = {}
+psfcheck_list['com.google.fonts/check/name/no_copyright_on_description'] = {}
+psfcheck_list['com.google.fonts/check/name/postscriptname'] = {}
+psfcheck_list['com.google.fonts/check/name/rfn'] = {'exclude': True}
+psfcheck_list['com.google.fonts/check/name/subfamilyname'] = {}
+psfcheck_list['com.google.fonts/check/name/trailing_spaces'] = {'exclude': True}
+psfcheck_list['com.google.fonts/check/name/typographicfamilyname'] = {}
+psfcheck_list['com.google.fonts/check/name/typographicsubfamilyname'] = {}
+psfcheck_list['com.google.fonts/check/name/unwanted_chars'] = {}
+psfcheck_list['com.google.fonts/check/name/version_format'] = {'exclude': True}
+psfcheck_list['com.google.fonts/check/no_debugging_tables'] = {}
+psfcheck_list['com.google.fonts/check/old_ttfautohint'] = {'exclude': True}
+psfcheck_list['com.google.fonts/check/os2/use_typo_metrics'] = {'exclude': True}
+#psfcheck_list['com.google.fonts/check/os2/use_typo_metrics'] = \ (Left a copy commented out as an
+# {'change_status': {'FAIL': 'WARN', 'reason': 'Under review'}} example of an override!)
+psfcheck_list['com.google.fonts/check/os2_metrics_match_hhea'] = {'exclude': True}
+psfcheck_list['com.google.fonts/check/ots'] = {}
+psfcheck_list['com.google.fonts/check/outline_alignment_miss'] = {'exclude': True}
+psfcheck_list['com.google.fonts/check/outline_colinear_vectors'] = {'exclude': True}
+psfcheck_list['com.google.fonts/check/outline_jaggy_segments'] = {'exclude': True}
+psfcheck_list['com.google.fonts/check/outline_semi_vertical'] = {'exclude': True}
+psfcheck_list['com.google.fonts/check/outline_short_segments'] = {'exclude': True}
+psfcheck_list['com.google.fonts/check/points_out_of_bounds'] = {'exclude': True}
+psfcheck_list['com.google.fonts/check/post_table_version'] = {}
+psfcheck_list['com.google.fonts/check/production_glyphs_similarity'] = {'exclude': True}
+psfcheck_list['com.google.fonts/check/render_own_name'] = {}
+psfcheck_list['com.google.fonts/check/required_tables'] = {}
+psfcheck_list['com.google.fonts/check/rupee'] = {'exclude': True}
+psfcheck_list['com.google.fonts/check/shaping/collides'] = {'exclude': True}
+psfcheck_list['com.google.fonts/check/shaping/forbidden'] = {'exclude': True}
+psfcheck_list['com.google.fonts/check/shaping/regression'] = {'exclude': True}
+psfcheck_list['com.google.fonts/check/smart_dropout'] = {'exclude': True}
+psfcheck_list['com.google.fonts/check/STAT/axis_order'] = {}
+psfcheck_list['com.google.fonts/check/STAT/gf-axisregistry'] = {}
+psfcheck_list['com.google.fonts/check/STAT_strings'] = {}
+psfcheck_list['com.google.fonts/check/stylisticset_description'] = {}
+psfcheck_list['com.google.fonts/check/superfamily/list'] = {'exclude': True}
+psfcheck_list['com.google.fonts/check/superfamily/vertical_metrics'] = {'exclude': True}
+psfcheck_list['com.google.fonts/check/transformed_components'] = {}
+psfcheck_list['com.google.fonts/check/ttx-roundtrip'] = {}
+psfcheck_list['com.google.fonts/check/unicode_range_bits'] = {}
+psfcheck_list['com.google.fonts/check/unique_glyphnames'] = {}
+psfcheck_list['com.google.fonts/check/unitsperem'] = {}
+psfcheck_list['com.google.fonts/check/unitsperem_strict'] = {'exclude': True}
+psfcheck_list['com.google.fonts/check/unreachable_glyphs'] = {}
+psfcheck_list['com.google.fonts/check/unwanted_tables'] = {}
+psfcheck_list['com.google.fonts/check/usweightclass'] = {}
+psfcheck_list['com.google.fonts/check/valid_glyphnames'] = {}
+psfcheck_list['com.google.fonts/check/varfont_duplicate_instance_names'] = {}
+psfcheck_list['com.google.fonts/check/varfont_has_instances'] = {}
+psfcheck_list['com.google.fonts/check/varfont_instance_coordinates'] = {}
+psfcheck_list['com.google.fonts/check/varfont_instance_names'] = {}
+psfcheck_list['com.google.fonts/check/varfont_weight_instances'] = {}
+psfcheck_list['com.google.fonts/check/varfont/bold_wght_coord'] = {}
+psfcheck_list['com.google.fonts/check/varfont/consistent_axes'] = {}
+psfcheck_list['com.google.fonts/check/varfont/generate_static'] = {}
+psfcheck_list['com.google.fonts/check/varfont/grade_reflow'] = {}
+psfcheck_list['com.google.fonts/check/varfont/has_HVAR'] = {}
+psfcheck_list['com.google.fonts/check/varfont/regular_ital_coord'] = {}
+psfcheck_list['com.google.fonts/check/varfont/regular_opsz_coord'] = {}
+psfcheck_list['com.google.fonts/check/varfont/regular_slnt_coord'] = {}
+psfcheck_list['com.google.fonts/check/varfont/regular_wdth_coord'] = {}
+psfcheck_list['com.google.fonts/check/varfont/regular_wght_coord'] = {}
+psfcheck_list['com.google.fonts/check/varfont/slnt_range'] = {}
+psfcheck_list['com.google.fonts/check/varfont/stat_axis_record_for_each_axis'] = {}
+psfcheck_list['com.google.fonts/check/varfont/unsupported_axes'] = {}
+psfcheck_list['com.google.fonts/check/varfont/wdth_valid_range'] = {}
+psfcheck_list['com.google.fonts/check/varfont/wght_valid_range'] = {}
+psfcheck_list['com.google.fonts/check/vendor_id'] = {}
+psfcheck_list['com.google.fonts/check/version_bump'] = {'exclude': True}
+psfcheck_list['com.google.fonts/check/vertical_metrics'] = {'exclude': True}
+psfcheck_list['com.google.fonts/check/vertical_metrics_regressions'] = {'exclude': True}
+psfcheck_list['com.google.fonts/check/vttclean'] = {}
+psfcheck_list['com.google.fonts/check/whitespace_glyphnames'] = {}
+psfcheck_list['com.google.fonts/check/whitespace_glyphs'] = {}
+psfcheck_list['com.google.fonts/check/whitespace_ink'] = {}
+psfcheck_list['com.google.fonts/check/whitespace_widths'] = {}
+psfcheck_list['com.google.fonts/check/xavgcharwidth'] = {}
+psfcheck_list['org.sil/check/family/win_ascent_and_descent'] = {}
+psfcheck_list['org.sil/check/os2/use_typo_metrics'] = {}
+psfcheck_list['org.sil/check/os2_metrics_match_hhea'] = {}
+psfcheck_list['org.sil/check/vertical_metrics'] = {}
+psfcheck_list['org.sil/check/number_widths'] = {}
+psfcheck_list['org.sil/check/name/version_format'] = {}
+psfcheck_list['org.sil/check/whitespace_widths'] = {}
+
+profile = make_profile(check_list=psfcheck_list)
diff --git a/lib/silfont/feax_ast.py b/lib/silfont/feax_ast.py
new file mode 100644
index 0000000..67d45b1
--- /dev/null
+++ b/lib/silfont/feax_ast.py
@@ -0,0 +1,445 @@
+import ast as pyast
+from fontTools.feaLib import ast
+from fontTools.feaLib.ast import asFea
+from fontTools.feaLib.error import FeatureLibError
+import re, math
+
+def asFea(g):
+ if hasattr(g, 'asClassFea'):
+ return g.asClassFea()
+ elif hasattr(g, 'asFea'):
+ return g.asFea()
+ elif isinstance(g, tuple) and len(g) == 2:
+ return asFea(g[0]) + "-" + asFea(g[1]) # a range
+ elif g.lower() in ast.fea_keywords:
+ return "\\" + g
+ else:
+ return g
+
+ast.asFea = asFea
+SHIFT = ast.SHIFT
+
+def asLiteralFea(self, indent=""):
+ Element.mode = 'literal'
+ return self.asFea(indent=indent)
+ Element.mode = 'flat'
+
+ast.Element.asLiteralFea = asLiteralFea
+ast.Element.mode = 'flat'
+
+class ast_Comment(ast.Comment):
+ def __init__(self, text, location=None):
+ super(ast_Comment, self).__init__(text, location=location)
+ self.pretext = ""
+ self.posttext = ""
+
+ def asFea(self, indent=""):
+ return self.pretext + self.text + self.posttext
+
+class ast_MarkClass(ast.MarkClass):
+ # This is better fixed upstream in parser.parse_glyphclass_ to handle MarkClasses
+ def asClassFea(self, indent=""):
+ return "[" + " ".join(map(asFea, self.glyphs)) + "]"
+
+class ast_BaseClass(ast_MarkClass) :
+ def asFea(self, indent="") :
+ return "@" + self.name + " = [" + " ".join(map(asFea, self.glyphs.keys())) + "];"
+
+class ast_BaseClassDefinition(ast.MarkClassDefinition):
+ def asFea(self, indent="") :
+ # like base class asFea
+ return ("# " if self.mode != 'literal' else "") + \
+ "{}baseClass {} {} @{};".format(indent, self.glyphs.asFea(),
+ self.anchor.asFea(), self.markClass.name)
+
+class ast_MarkBasePosStatement(ast.MarkBasePosStatement):
+ def asFea(self, indent=""):
+ # handles members added by parse_position_base_ with feax syntax
+ if isinstance(self.base, ast.MarkClassName): # flattens pos @BASECLASS mark @MARKCLASS
+ res = ""
+ if self.mode == 'literal':
+ res += "pos base @{} ".format(self.base.markClass.name)
+ res += " ".join("mark @{}".format(m.name) for m in self.marks)
+ res += ";"
+ else:
+ for bcd in self.base.markClass.definitions:
+ if res != "":
+ res += "\n{}".format(indent)
+ res += "pos base {} {}".format(bcd.glyphs.asFea(), bcd.anchor.asFea())
+ res += "".join(" mark @{}".format(m.name) for m in self.marks)
+ res += ";"
+ else: # like base class method
+ res = "pos base {}".format(self.base.asFea())
+ res += "".join(" {} mark @{}".format(a.asFea(), m.name) for a, m in self.marks)
+ res += ";"
+ return res
+
+ def build(self, builder) :
+ #TODO: do the right thing here (write to ttf?)
+ pass
+
+class ast_MarkMarkPosStatement(ast.MarkMarkPosStatement):
+ # super class __init__() for reference
+ # def __init__(self, location, baseMarks, marks):
+ # Statement.__init__(self, location)
+ # self.baseMarks, self.marks = baseMarks, marks
+
+ def asFea(self, indent=""):
+ # handles members added by parse_position_base_ with feax syntax
+ if isinstance(self.baseMarks, ast.MarkClassName): # flattens pos @MARKCLASS mark @MARKCLASS
+ res = ""
+ if self.mode == 'literal':
+ res += "pos mark @{} ".format(self.base.markClass.name)
+ res += " ".join("mark @{}".format(m.name) for m in self.marks)
+ res += ";"
+ else:
+ for mcd in self.baseMarks.markClass.definitions:
+ if res != "":
+ res += "\n{}".format(indent)
+ res += "pos mark {} {}".format(mcd.glyphs.asFea(), mcd.anchor.asFea())
+ for m in self.marks:
+ res += " mark @{}".format(m.name)
+ res += ";"
+ else: # like base class method
+ res = "pos mark {}".format(self.baseMarks.asFea())
+ for a, m in self.marks:
+ res += " {} mark @{}".format(a.asFea() if a else "<anchor NULL>", m.name)
+ res += ";"
+ return res
+
+ def build(self, builder):
+ # builder.add_mark_mark_pos(self.location, self.baseMarks.glyphSet(), self.marks)
+ #TODO: do the right thing
+ pass
+
+class ast_CursivePosStatement(ast.CursivePosStatement):
+ # super class __init__() for reference
+ # def __init__(self, location, glyphclass, entryAnchor, exitAnchor):
+ # Statement.__init__(self, location)
+ # self.glyphclass = glyphclass
+ # self.entryAnchor, self.exitAnchor = entryAnchor, exitAnchor
+
+ def asFea(self, indent=""):
+ if isinstance(self.exitAnchor, ast.MarkClass): # pos cursive @BASE1 @BASE2
+ res = ""
+ if self.mode == 'literal':
+ res += "pos cursive @{} @{};".format(self.glyphclass.name, self.exitAnchor.name)
+ else:
+ allglyphs = set(self.glyphclass.glyphSet())
+ allglyphs.update(self.exitAnchor.glyphSet())
+ for g in sorted(allglyphs):
+ entry = self.glyphclass.glyphs.get(g, None)
+ exit = self.exitAnchor.glyphs.get(g, None)
+ if res != "":
+ res += "\n{}".format(indent)
+ res += "pos cursive {} {} {};".format(g,
+ (entry.anchor.asFea() if entry else "<anchor NULL>"),
+ (exit.anchor.asFea() if exit else "<anchor NULL>"))
+ else:
+ res = super(ast_CursivePosStatement, self).asFea(indent)
+ return res
+
+ def build(self, builder) :
+ #TODO: do the right thing here (write to ttf?)
+ pass
+
+class ast_MarkLigPosStatement(ast.MarkLigPosStatement):
+ def __init__(self, ligatures, marks, location=None):
+ ast.MarkLigPosStatement.__init__(self, ligatures, marks, location)
+ self.classBased = False
+ for l in marks:
+ if l is not None:
+ for m in l:
+ if m is not None and not isinstance(m[0], ast.Anchor):
+ self.classBased = True
+ break
+
+ def build(self, builder):
+ builder.add_mark_lig_pos(self.location, self.ligatures.glyphSet(), self.marks)
+
+ def asFea(self, indent=""):
+ if not self.classBased or self.mode == "literal":
+ return super(ast_MarkLigPosStatement, self).asFea(indent)
+
+ res = []
+ for g in self.ligatures.glyphSet():
+ comps = []
+ for l in self.marks:
+ onecomp = []
+ if l is not None and len(l):
+ for a, m in l:
+ if not isinstance(a, ast.Anchor):
+ if g not in a.markClass.glyphs:
+ continue
+ left = a.markClass.glyphs[g].anchor.asFea()
+ else:
+ left = a.asFea()
+ onecomp.append("{} mark @{}".format(left, m.name))
+ if not len(onecomp):
+ onecomp = ["<anchor NULL>"]
+ comps.append(" ".join(onecomp))
+ res.append("pos ligature {} ".format(asFea(g)) + ("\n"+indent+SHIFT+"ligComponent ").join(comps))
+ return (";\n"+indent).join(res) + ";"
+
+#similar to ast.MultipleSubstStatement
+#one-to-many substitution, one glyph class is on LHS, multiple glyph classes may be on RHS
+# equivalent to generation of one stmt for each glyph in the LHS class
+# that's matched to corresponding glyphs in the RHS classes
+#prefix and suffx are for contextual lookups and do not need processing
+#replacement could contain multiple slots
+#TODO: below only supports one RHS class?
+class ast_MultipleSubstStatement(ast.Statement):
+ def __init__(self, prefix, glyph, suffix, replacement, forceChain, location=None):
+ ast.Statement.__init__(self, location)
+ self.prefix, self.glyph, self.suffix = prefix, glyph, suffix
+ self.replacement = replacement
+ self.forceChain = forceChain
+ lenglyphs = len(self.glyph.glyphSet())
+ for i, r in enumerate(self.replacement) :
+ if len(r.glyphSet()) == lenglyphs:
+ self.multindex = i #first RHS slot with a glyph class
+ break
+ else:
+ if lenglyphs > 1:
+ raise FeatureLibError("No replacement class is of the same length as the matching class",
+ location)
+ else:
+ self.multindex = 0;
+
+ def build(self, builder):
+ prefix = [p.glyphSet() for p in self.prefix]
+ suffix = [s.glyphSet() for s in self.suffix]
+ glyphs = self.glyph.glyphSet()
+ replacements = self.replacement[self.multindex].glyphSet()
+ lenglyphs = len(glyphs)
+ for i in range(max(lenglyphs, len(replacements))) :
+ builder.add_multiple_subst(
+ self.location, prefix, glyphs[i if lenglyphs > 1 else 0], suffix,
+ self.replacement[0:self.multindex] + [replacements[i]] + self.replacement[self.multindex+1:],
+ self.forceChain)
+
+ def asFea(self, indent=""):
+ res = ""
+ pres = (" ".join(map(asFea, self.prefix)) + " ") if len(self.prefix) else ""
+ sufs = (" " + " ".join(map(asFea, self.suffix))) if len(self.suffix) else ""
+ mark = "'" if len(self.prefix) or len(self.suffix) or self.forceChain else ""
+ if self.mode == 'literal':
+ res += "sub " + pres + self.glyph.asFea() + mark + sufs + " by "
+ res += " ".join(asFea(g) for g in self.replacement) + ";"
+ return res
+ glyphs = self.glyph.glyphSet()
+ replacements = self.replacement[self.multindex].glyphSet()
+ lenglyphs = len(glyphs)
+ count = max(lenglyphs, len(replacements))
+ for i in range(count) :
+ res += ("\n" + indent if i > 0 else "") + "sub " + pres
+ res += asFea(glyphs[i if lenglyphs > 1 else 0]) + mark + sufs
+ res += " by "
+ res += " ".join(asFea(g) for g in self.replacement[0:self.multindex] + [replacements[i]] + self.replacement[self.multindex+1:])
+ res += ";"
+ return res
+
+
+# similar to ast.LigatureSubstStatement
+# many-to-one substitution, one glyph class is on RHS, multiple glyph classes may be on LHS
+# equivalent to generation of one stmt for each glyph in the RHS class
+# that's matched to corresponding glyphs in the LHS classes
+# it's unclear which LHS class should correspond to the RHS class
+# prefix and suffx are for contextual lookups and do not need processing
+# replacement could contain multiple slots
+#TODO: below only supports one LHS class?
+class ast_LigatureSubstStatement(ast.Statement):
+ def __init__(self, prefix, glyphs, suffix, replacement,
+ forceChain, location=None):
+ ast.Statement.__init__(self, location)
+ self.prefix, self.glyphs, self.suffix = (prefix, glyphs, suffix)
+ self.replacement, self.forceChain = replacement, forceChain
+ lenreplace = len(self.replacement.glyphSet())
+ for i, g in enumerate(self.glyphs):
+ if len(g.glyphSet()) == lenreplace:
+ self.multindex = i #first LHS slot with a glyph class
+ break
+ else:
+ if lenreplace > 1:
+ raise FeatureLibError("No class matches replacement class length", location)
+ else:
+ self.multindex = 0
+
+ def build(self, builder):
+ prefix = [p.glyphSet() for p in self.prefix]
+ glyphs = [g.glyphSet() for g in self.glyphs]
+ suffix = [s.glyphSet() for s in self.suffix]
+ replacements = self.replacement.glyphSet()
+ lenreplace = len(replacements.glyphSet())
+ glyphs = self.glyphs[self.multindex].glyphSet()
+ for i in range(max(len(glyphs), len(replacements))):
+ builder.add_ligature_subst(
+ self.location, prefix,
+ self.glyphs[:self.multindex] + glyphs[i] + self.glyphs[self.multindex+1:],
+ suffix, replacements[i if lenreplace > 1 else 0], self.forceChain)
+
+ def asFea(self, indent=""):
+ res = ""
+ pres = (" ".join(map(asFea, self.prefix)) + " ") if len(self.prefix) else ""
+ sufs = (" " + " ".join(map(asFea, self.suffix))) if len(self.suffix) else ""
+ mark = "'" if len(self.prefix) or len(self.suffix) or self.forceChain else ""
+ if self.mode == 'literal':
+ res += "sub " + pres + " ".join(asFea(g)+mark for g in self.glyphs) + sufs + " by "
+ res += self.replacements.asFea() + ";"
+ return res
+ glyphs = self.glyphs[self.multindex].glyphSet()
+ replacements = self.replacement.glyphSet()
+ lenreplace = len(replacements)
+ count = max(len(glyphs), len(replacements))
+ for i in range(count) :
+ res += ("\n" + indent if i > 0 else "") + "sub " + pres
+ res += " ".join(asFea(g)+mark for g in self.glyphs[:self.multindex] + [glyphs[i]] + self.glyphs[self.multindex+1:])
+ res += sufs + " by "
+ res += asFea(replacements[i if lenreplace > 1 else 0])
+ res += ";"
+ return res
+
+class ast_AlternateSubstStatement(ast.Statement):
+ def __init__(self, prefix, glyphs, suffix, replacements, location=None):
+ ast.Statement.__init__(self, location)
+ self.prefix, self.glyphs, self.suffix = (prefix, glyphs, suffix)
+ self.replacements = replacements
+
+ def build(self, builder):
+ prefix = [p.glyphSet() for p in self.prefix]
+ suffix = [s.glyphSet() for s in self.suffix]
+ l = len(self.glyphs.glyphSet())
+ for i, glyph in enumerate(self.glyphs.glyphSet()):
+ replacement = self.replacements.glyphSet()[i::l]
+ builder.add_alternate_subst(self.location, prefix, glyph, suffix,
+ replacement)
+
+ def asFea(self, indent=""):
+ res = ""
+ l = len(self.glyphs.glyphSet())
+ for i, glyph in enumerate(self.glyphs.glyphSet()):
+ if i > 0:
+ res += "\n" + indent
+ res += "sub "
+ if len(self.prefix) or len(self.suffix):
+ if len(self.prefix):
+ res += " ".join(map(asFea, self.prefix)) + " "
+ res += asFea(glyph) + "'" # even though we really only use 1
+ if len(self.suffix):
+ res += " " + " ".join(map(asFea, self.suffix))
+ else:
+ res += asFea(glyph)
+ res += " from "
+ replacements = ast.GlyphClass(glyphs=self.replacements.glyphSet()[i::l], location=self.location)
+ res += asFea(replacements)
+ res += ";"
+ return res
+
+class ast_IfBlock(ast.Block):
+ def __init__(self, testfn, name, cond, location=None):
+ ast.Block.__init__(self, location=location)
+ self.testfn = testfn
+ self.name = name
+
+ def asFea(self, indent=""):
+ if self.mode == 'literal':
+ res = "{}if{}({}) {{".format(indent, name, cond)
+ res += ast.Block.asFea(self, indent=indent)
+ res += indent + "}\n"
+ return res
+ elif self.testfn():
+ return ast.Block.asFea(self, indent=indent)
+ else:
+ return ""
+
+
+class ast_DoSubStatement(ast.Statement):
+ def __init__(self, varnames, location=None):
+ ast.Statement.__init__(self, location=location)
+ self.names = varnames
+
+ def items(self, variables):
+ yield ((None, None),)
+
+class ast_DoForSubStatement(ast_DoSubStatement):
+ def __init__(self, varname, glyphs, location=None):
+ ast_DoSubStatement.__init__(self, [varname], location=location)
+ self.glyphs = glyphs.glyphSet()
+
+ def items(self, variables):
+ for g in self.glyphs:
+ yield((self.names[0], g),)
+
+def safeeval(exp):
+ # no dunders in attribute names
+ for n in pyast.walk(pyast.parse(exp)):
+ v = getattr(n, 'id', "")
+ # if v in ('_getiter_', '__next__'):
+ # continue
+ if "__" in v:
+ return False
+ return True
+
+class ast_DoLetSubStatement(ast_DoSubStatement):
+ def __init__(self, varnames, expression, parser, location=None):
+ ast_DoSubStatement.__init__(self, varnames, location=location)
+ self.parser = parser
+ if not safeeval(expression):
+ expression='"Unsafe Expression"'
+ self.expr = expression
+
+ def items(self, variables):
+ gbls = dict(self.parser.fns, **variables)
+ try:
+ v = eval(self.expr, gbls)
+ except Exception as e:
+ raise FeatureLibError(str(e) + " in " + self.expr, self.location)
+ if self.names is None: # in an if
+ yield((None, v),)
+ elif len(self.names) == 1:
+ yield((self.names[0], v),)
+ else:
+ yield(zip(self.names, list(v) + [None] * (len(self.names) - len(v))))
+
+class ast_DoIfSubStatement(ast_DoLetSubStatement):
+ def __init__(self, expression, parser, block, location=None):
+ ast_DoLetSubStatement.__init__(self, None, expression, parser, location=None)
+ self.block = block
+
+ def items(self, variables):
+ (_, v) = list(ast_DoLetSubStatement.items(self, variables))[0][0]
+ yield (None, (v if v else None),)
+
+class ast_KernPairsStatement(ast.Statement):
+ def __init__(self, kerninfo, location=None):
+ super(ast_KernPairsStatement, self).__init__(location)
+ self.kerninfo = kerninfo
+
+ def asFea(self, indent=""):
+ # return ("\n"+indent).join("pos {} {} {};".format(k1, round(v), k2) \
+ # for k1, x in self.kerninfo.items() for k2, v in x.items())
+ coverage = set()
+ rules = dict()
+
+ # first sort into lists by type of rule
+ for k1, x in self.kerninfo.items():
+ for k2, v in x.items():
+ # Determine pair kern type, where:
+ # 'gg' = glyph-glyph, 'gc' = glyph-class', 'cg' = class-glyph, 'cc' = class-class
+ ruleType = 'gc'[k1[0]=='@'] + 'gc'[k2[0]=='@']
+ rules.setdefault(ruleType, list()).append([k1, round(v), k2])
+ # for glyph-glyph rules, make list of first glyphs:
+ if ruleType == 'gg':
+ coverage.add(k1)
+
+ # Now assemble lines in order and convert gc rules to gg where possible:
+ res = []
+ for ruleType in filter(lambda x: x in rules, ('gg', 'gc', 'cg', 'cc')):
+ if ruleType != 'gc':
+ res.extend(['pos {} {} {};'.format(k1, v, k2) for k1,v,k2 in rules[ruleType]])
+ else:
+ res.extend(['enum pos {} {} {};'.format(k1, v, k2) for k1, v, k2 in rules[ruleType] if k1 not in coverage])
+ res.extend(['pos {} {} {};'.format(k1, v, k2) for k1, v, k2 in rules[ruleType] if k1 in coverage])
+
+ return ("\n"+indent).join(res)
+
diff --git a/lib/silfont/feax_lexer.py b/lib/silfont/feax_lexer.py
new file mode 100644
index 0000000..58ea72d
--- /dev/null
+++ b/lib/silfont/feax_lexer.py
@@ -0,0 +1,105 @@
+from fontTools.feaLib.lexer import IncludingLexer, Lexer
+from fontTools.feaLib.error import FeatureLibError
+import re, io
+
+VARIABLE = "VARIABLE"
+
+class feax_Lexer(Lexer):
+
+ def __init__(self, *a):
+ Lexer.__init__(self, *a)
+ self.tokens_ = None
+ self.stack_ = []
+ self.empty_ = False
+
+ def next_(self, recurse=False):
+ while (not self.empty_):
+ if self.tokens_ is not None:
+ res = self.tokens_.pop(0)
+ if not len(self.tokens_):
+ self.popstack()
+ if res[0] != VARIABLE:
+ return (res[0], res[1], self.location_())
+ return self.parse_variable(res[1])
+
+ try:
+ res = Lexer.next_(self)
+ except IndexError as e:
+ self.popstack()
+ continue
+ except StopIteration as e:
+ self.popstack()
+ continue
+ except FeatureLibError as e:
+ if u"Unexpected character" not in str(e):
+ raise e
+
+ # only executes if exception occurred
+ location = self.location_()
+ text = self.text_
+ start = self.pos_
+ cur_char = text[start]
+ if cur_char == '$':
+ self.pos_ += 1
+ self.scan_over_(Lexer.CHAR_NAME_CONTINUATION_)
+ varname = text[start+1:self.pos_]
+ if len(varname) < 1 or len(varname) > 63:
+ raise FeatureLibError("Bad variable name length", location)
+ res = (VARIABLE, varname, location)
+ else:
+ raise FeatureLibError("Unexpected character: %r" % cur_char, location)
+ return res
+ raise StopIteration
+
+ def __repr__(self):
+ if self.tokens_ is not None:
+ return str(self.tokens_)
+ else:
+ return str((self.text_[self.pos_:self.pos_+20], self.pos_, self.text_length_))
+
+ def popstack(self):
+ if len(self.stack_) == 0:
+ self.empty_ = True
+ return
+ t = self.stack_.pop()
+ if t[0] == 'tokens':
+ self.tokens_ = t[1]
+ else:
+ self.text_, self.pos_, self.text_length_ = t[1]
+ self.tokens_ = None
+
+ def pushstack(self, v):
+ if self.tokens_ is None:
+ self.stack_.append(('text', (self.text_, self.pos_, self.text_length_)))
+ else:
+ self.stack_.append(('tokens', self.tokens_))
+ self.stack_.append(v)
+ self.popstack()
+
+ def pushback(self, token_type, token):
+ if self.tokens_ is not None:
+ self.tokens_.append((token_type, token))
+ else:
+ self.pushstack(('tokens', [(token_type, token)]))
+
+ def parse_variable(self, vname):
+ t = str(self.scope.get(vname, ''))
+ if t != '':
+ self.pushstack(['text', (t + " ", 0, len(t)+1)])
+ return self.next_()
+
+class feax_IncludingLexer(IncludingLexer):
+
+ @staticmethod
+ def make_lexer_(file_or_path):
+ if hasattr(file_or_path, "read"):
+ fileobj, closing = file_or_path, False
+ else:
+ filename, closing = file_or_path, True
+ fileobj = io.open(filename, mode="r", encoding="utf-8")
+ data = fileobj.read()
+ filename = getattr(fileobj, "name", None)
+ if closing:
+ fileobj.close()
+ return feax_Lexer(data, filename)
+
diff --git a/lib/silfont/feax_parser.py b/lib/silfont/feax_parser.py
new file mode 100644
index 0000000..aea3619
--- /dev/null
+++ b/lib/silfont/feax_parser.py
@@ -0,0 +1,727 @@
+from fontTools.feaLib import ast
+from fontTools.feaLib.parser import Parser
+from fontTools.feaLib.lexer import IncludingLexer, Lexer
+import silfont.feax_lexer as feax_lexer
+from fontTools.feaLib.error import FeatureLibError
+import silfont.feax_ast as astx
+import io, re, math, os
+import logging
+
+class feaplus_ast(object) :
+ MarkBasePosStatement = astx.ast_MarkBasePosStatement
+ MarkMarkPosStatement = astx.ast_MarkMarkPosStatement
+ MarkLigPosStatement = astx.ast_MarkLigPosStatement
+ CursivePosStatement = astx.ast_CursivePosStatement
+ BaseClass = astx.ast_BaseClass
+ MarkClass = astx.ast_MarkClass
+ BaseClassDefinition = astx.ast_BaseClassDefinition
+ MultipleSubstStatement = astx.ast_MultipleSubstStatement
+ LigatureSubstStatement = astx.ast_LigatureSubstStatement
+ IfBlock = astx.ast_IfBlock
+ DoForSubStatement = astx.ast_DoForSubStatement
+ DoLetSubStatement = astx.ast_DoLetSubStatement
+ DoIfSubStatement = astx.ast_DoIfSubStatement
+ AlternateSubstStatement = astx.ast_AlternateSubstStatement
+ Comment = astx.ast_Comment
+ KernPairsStatement = astx.ast_KernPairsStatement
+
+ def __getattr__(self, name):
+ return getattr(ast, name) # retrieve undefined attrs from imported fontTools.feaLib ast module
+
+class feaplus_parser(Parser) :
+ extensions = {
+ 'baseClass': lambda s: s.parseBaseClass(),
+ 'ifclass': lambda s: s.parseIfClass(),
+ 'ifinfo': lambda s: s.parseIfInfo(),
+ 'do': lambda s: s.parseDoStatement_(),
+ 'def': lambda s: s.parseDefStatement_(),
+ 'kernpairs': lambda s: s.parseKernPairsStatement_()
+ }
+ ast = feaplus_ast()
+
+ def __init__(self, filename, glyphmap, fontinfo, kerninfo, defines) :
+ if filename is None :
+ empty_file = io.StringIO("")
+ super(feaplus_parser, self).__init__(empty_file, glyphmap)
+ else :
+ super(feaplus_parser, self).__init__(filename, glyphmap)
+ self.fontinfo = fontinfo
+ self.kerninfo = kerninfo
+ self.glyphs = glyphmap
+ self.defines = defines
+ self.fns = {
+ '__builtins__': None,
+ 're' : re,
+ 'math' : math,
+ 'APx': lambda g, a, d=0: int(self.glyphs[g].anchors.get(a, [d])[0]),
+ 'APy': lambda g, a, d=0: int(self.glyphs[g].anchors.get(a, [0,d])[1]),
+ 'ADVx': lambda g: int(self.glyphs[g].advance),
+ 'MINx': lambda g: int(self.glyphs[g].bbox[0]),
+ 'MINy': lambda g: int(self.glyphs[g].bbox[1]),
+ 'MAXx': lambda g: int(self.glyphs[g].bbox[2]),
+ 'MAXy': lambda g: int(self.glyphs[g].bbox[3]),
+ 'feaclass': lambda c: self.resolve_glyphclass(c).glyphSet(),
+ 'allglyphs': lambda : self.glyphs.keys(),
+ 'lf': lambda : "\n",
+ 'info': lambda s: self.fontinfo.get(s, ""),
+ 'fileexists': lambda s: os.path.exists(s),
+ 'kerninfo': lambda s:[(k1, k2, v) for k1, x in self.kerninfo.items() for k2, v in x.items()],
+ 'opt': lambda s: self.defines.get(s, "")
+ }
+ # Document which builtins we really need. Of course still insecure.
+ for x in ('True', 'False', 'None', 'int', 'float', 'str', 'abs', 'all', 'any', 'bool',
+ 'dict', 'enumerate', 'filter', 'hasattr', 'hex', 'len', 'list', 'map', 'print',
+ 'max', 'min', 'ord', 'range', 'set', 'sorted', 'sum', 'tuple', 'zip'):
+ self.fns[x] = __builtins__[x]
+
+ def parse(self, filename=None) :
+ if filename is not None :
+ self.lexer_ = feax_lexer.feax_IncludingLexer(filename)
+ self.advance_lexer_(comments=True)
+ return super(feaplus_parser, self).parse()
+
+ def back_lexer_(self):
+ self.lexer_.lexers_[-1].pushback(self.next_token_type_, self.next_token_)
+ self.next_token_type_ = self.cur_token_type_
+ self.next_token_ = self.cur_token_
+ self.next_token_location_ = self.cur_token_location_
+
+ # methods to limit layer violations
+ def define_glyphclass(self, ap_nm, gc) :
+ self.glyphclasses_.define(ap_nm, gc)
+
+ def resolve_glyphclass(self, ap_nm):
+ try:
+ return self.glyphclasses_.resolve(ap_nm)
+ except KeyError:
+ raise FeatureLibError("Glyphclass '{}' missing".format(ap_nm), self.lexer_.location_())
+ return None
+
+ def add_statement(self, val) :
+ self.doc_.statements.append(val)
+
+ def set_baseclass(self, ap_nm) :
+ gc = self.ast.BaseClass(ap_nm)
+ if not hasattr(self.doc_, 'baseClasses') :
+ self.doc_.baseClasses = {}
+ self.doc_.baseClasses[ap_nm] = gc
+ self.define_glyphclass(ap_nm, gc)
+ return gc
+
+ def set_markclass(self, ap_nm) :
+ gc = self.ast.MarkClass(ap_nm)
+ if not hasattr(self.doc_, 'markClasses') :
+ self.doc_.markClasses = {}
+ self.doc_.markClasses[ap_nm] = gc
+ self.define_glyphclass(ap_nm, gc)
+ return gc
+
+
+ # like base class parse_position_base_ & overrides it
+ def parse_position_base_(self, enumerated, vertical):
+ location = self.cur_token_location_
+ self.expect_keyword_("base")
+ if enumerated:
+ raise FeatureLibError(
+ '"enumerate" is not allowed with '
+ 'mark-to-base attachment positioning',
+ location)
+ base = self.parse_glyphclass_(accept_glyphname=True)
+ if self.next_token_ == "<": # handle pos base [glyphs] <anchor> mark @MARKCLASS
+ marks = self.parse_anchor_marks_()
+ else: # handle pos base @BASECLASS mark @MARKCLASS; like base class parse_anchor_marks_
+ marks = []
+ while self.next_token_ == "mark": #TODO: is more than one 'mark' meaningful?
+ self.expect_keyword_("mark")
+ m = self.expect_markClass_reference_()
+ marks.append(m)
+ self.expect_symbol_(";")
+ return self.ast.MarkBasePosStatement(base, marks, location=location)
+
+ # like base class parse_position_mark_ & overrides it
+ def parse_position_mark_(self, enumerated, vertical):
+ location = self.cur_token_location_
+ self.expect_keyword_("mark")
+ if enumerated:
+ raise FeatureLibError(
+ '"enumerate" is not allowed with '
+ 'mark-to-mark attachment positioning',
+ location)
+ baseMarks = self.parse_glyphclass_(accept_glyphname=True)
+ if self.next_token_ == "<": # handle pos mark [glyphs] <anchor> mark @MARKCLASS
+ marks = self.parse_anchor_marks_()
+ else: # handle pos mark @MARKCLASS mark @MARKCLASS; like base class parse_anchor_marks_
+ marks = []
+ while self.next_token_ == "mark": #TODO: is more than one 'mark' meaningful?
+ self.expect_keyword_("mark")
+ m = self.expect_markClass_reference_()
+ marks.append(m)
+ self.expect_symbol_(";")
+ return self.ast.MarkMarkPosStatement(baseMarks, marks, location=location)
+
+ def parse_position_cursive_(self, enumerated, vertical):
+ location = self.cur_token_location_
+ self.expect_keyword_("cursive")
+ if enumerated:
+ raise FeatureLibError(
+ '"enumerate" is not allowed with '
+ 'cursive attachment positioning',
+ location)
+ glyphclass = self.parse_glyphclass_(accept_glyphname=True)
+ if self.next_token_ == "<": # handle pos cursive @glyphClass <anchor entry> <anchor exit>
+ entryAnchor = self.parse_anchor_()
+ exitAnchor = self.parse_anchor_()
+ self.expect_symbol_(";")
+ return self.ast.CursivePosStatement(
+ glyphclass, entryAnchor, exitAnchor, location=location)
+ else: # handle pos cursive @baseClass @baseClass;
+ mc = self.expect_markClass_reference_()
+ return self.ast.CursivePosStatement(glyphclass.markClass, None, mc, location=location)
+
+ def parse_position_ligature_(self, enumerated, vertical):
+ location = self.cur_token_location_
+ self.expect_keyword_("ligature")
+ if enumerated:
+ raise FeatureLibError(
+ '"enumerate" is not allowed with '
+ 'mark-to-ligature attachment positioning',
+ location)
+ ligatures = self.parse_glyphclass_(accept_glyphname=True)
+ marks = [self._parse_anchorclass_marks_()]
+ while self.next_token_ == "ligComponent":
+ self.expect_keyword_("ligComponent")
+ marks.append(self._parse_anchorclass_marks_())
+ self.expect_symbol_(";")
+ return self.ast.MarkLigPosStatement(ligatures, marks, location=location)
+
+ def _parse_anchorclass_marks_(self):
+ """Parses a sequence of [<anchor> | @BASECLASS mark @MARKCLASS]*."""
+ anchorMarks = [] # [(self.ast.Anchor, markClassName)*]
+ while True:
+ if self.next_token_ == "<":
+ anchor = self.parse_anchor_()
+ else:
+ anchor = self.parse_glyphclass_(accept_glyphname=False)
+ if anchor is not None:
+ self.expect_keyword_("mark")
+ markClass = self.expect_markClass_reference_()
+ anchorMarks.append((anchor, markClass))
+ if self.next_token_ == "ligComponent" or self.next_token_ == ";":
+ break
+ return anchorMarks
+
+ # like base class parseMarkClass
+ # but uses BaseClass and BaseClassDefinition which subclass Mark counterparts
+ def parseBaseClass(self):
+ if not hasattr(self.doc_, 'baseClasses'):
+ self.doc_.baseClasses = {}
+ location = self.cur_token_location_
+ glyphs = self.parse_glyphclass_(accept_glyphname=True)
+ anchor = self.parse_anchor_()
+ name = self.expect_class_name_()
+ self.expect_symbol_(";")
+ baseClass = self.doc_.baseClasses.get(name)
+ if baseClass is None:
+ baseClass = self.ast.BaseClass(name)
+ self.doc_.baseClasses[name] = baseClass
+ self.glyphclasses_.define(name, baseClass)
+ bcdef = self.ast.BaseClassDefinition(baseClass, anchor, glyphs, location=location)
+ baseClass.addDefinition(bcdef)
+ return bcdef
+
+ #similar to and overrides parser.parse_substitute_
+ def parse_substitute_(self):
+ assert self.cur_token_ in {"substitute", "sub", "reversesub", "rsub"}
+ location = self.cur_token_location_
+ reverse = self.cur_token_ in {"reversesub", "rsub"}
+ old_prefix, old, lookups, values, old_suffix, hasMarks = \
+ self.parse_glyph_pattern_(vertical=False)
+ if any(values):
+ raise FeatureLibError(
+ "Substitution statements cannot contain values", location)
+ new = []
+ if self.next_token_ == "by":
+ keyword = self.expect_keyword_("by")
+ while self.next_token_ != ";":
+ gc = self.parse_glyphclass_(accept_glyphname=True)
+ new.append(gc)
+ elif self.next_token_ == "from":
+ keyword = self.expect_keyword_("from")
+ new = [self.parse_glyphclass_(accept_glyphname=False)]
+ else:
+ keyword = None
+ self.expect_symbol_(";")
+ if len(new) == 0 and not any(lookups):
+ raise FeatureLibError(
+ 'Expected "by", "from" or explicit lookup references',
+ self.cur_token_location_)
+
+ # GSUB lookup type 3: Alternate substitution.
+ # Format: "substitute a from [a.1 a.2 a.3];"
+ if keyword == "from":
+ if reverse:
+ raise FeatureLibError(
+ 'Reverse chaining substitutions do not support "from"',
+ location)
+ # allow classes on lhs
+ if len(old) != 1:
+ raise FeatureLibError(
+ 'Expected single glyph or glyph class before "from"',
+ location)
+ if len(new) != 1:
+ raise FeatureLibError(
+ 'Expected a single glyphclass after "from"',
+ location)
+ if len(old[0].glyphSet()) == 0 or len(new[0].glyphSet()) % len(old[0].glyphSet()) != 0:
+ raise FeatureLibError(
+ 'The glyphclass after "from" must be a multiple of length of the glyphclass on before',
+ location)
+ return self.ast.AlternateSubstStatement(
+ old_prefix, old[0], old_suffix, new[0], location=location)
+
+ num_lookups = len([l for l in lookups if l is not None])
+
+ # GSUB lookup type 1: Single substitution.
+ # Format A: "substitute a by a.sc;"
+ # Format B: "substitute [one.fitted one.oldstyle] by one;"
+ # Format C: "substitute [a-d] by [A.sc-D.sc];"
+ if (not reverse and len(old) == 1 and len(new) == 1 and
+ num_lookups == 0):
+ glyphs = list(old[0].glyphSet())
+ replacements = list(new[0].glyphSet())
+ if len(replacements) == 1:
+ replacements = replacements * len(glyphs)
+ if len(glyphs) != len(replacements):
+ raise FeatureLibError(
+ 'Expected a glyph class with %d elements after "by", '
+ 'but found a glyph class with %d elements' %
+ (len(glyphs), len(replacements)), location)
+ return self.ast.SingleSubstStatement(
+ old, new,
+ old_prefix, old_suffix,
+ forceChain=hasMarks, location=location
+ )
+
+ # GSUB lookup type 2: Multiple substitution.
+ # Format: "substitute f_f_i by f f i;"
+ if (not reverse and
+ len(old) == 1 and len(new) > 1 and num_lookups == 0):
+ return self.ast.MultipleSubstStatement(old_prefix, old[0], old_suffix, new,
+ hasMarks, location=location)
+
+ # GSUB lookup type 4: Ligature substitution.
+ # Format: "substitute f f i by f_f_i;"
+ if (not reverse and
+ len(old) > 1 and len(new) == 1 and num_lookups == 0):
+ return self.ast.LigatureSubstStatement(old_prefix, old, old_suffix, new[0],
+ forceChain=hasMarks, location=location)
+
+ # GSUB lookup type 8: Reverse chaining substitution.
+ if reverse:
+ if len(old) != 1:
+ raise FeatureLibError(
+ "In reverse chaining single substitutions, "
+ "only a single glyph or glyph class can be replaced",
+ location)
+ if len(new) != 1:
+ raise FeatureLibError(
+ 'In reverse chaining single substitutions, '
+ 'the replacement (after "by") must be a single glyph '
+ 'or glyph class', location)
+ if num_lookups != 0:
+ raise FeatureLibError(
+ "Reverse chaining substitutions cannot call named lookups",
+ location)
+ glyphs = sorted(list(old[0].glyphSet()))
+ replacements = sorted(list(new[0].glyphSet()))
+ if len(replacements) == 1:
+ replacements = replacements * len(glyphs)
+ if len(glyphs) != len(replacements):
+ raise FeatureLibError(
+ 'Expected a glyph class with %d elements after "by", '
+ 'but found a glyph class with %d elements' %
+ (len(glyphs), len(replacements)), location)
+ return self.ast.ReverseChainSingleSubstStatement(
+ old_prefix, old_suffix, old, new, location=location)
+
+ # GSUB lookup type 6: Chaining contextual substitution.
+ assert len(new) == 0, new
+ rule = self.ast.ChainContextSubstStatement(
+ old_prefix, old, old_suffix, lookups, location=location)
+ return rule
+
+ def parse_glyphclass_(self, accept_glyphname):
+ if (accept_glyphname and
+ self.next_token_type_ in (Lexer.NAME, Lexer.CID)):
+ glyph = self.expect_glyph_()
+ return self.ast.GlyphName(glyph, location=self.cur_token_location_)
+ if self.next_token_type_ is Lexer.GLYPHCLASS:
+ self.advance_lexer_()
+ gc = self.glyphclasses_.resolve(self.cur_token_)
+ if gc is None:
+ raise FeatureLibError(
+ "Unknown glyph class @%s" % self.cur_token_,
+ self.cur_token_location_)
+ if isinstance(gc, self.ast.MarkClass):
+ return self.ast.MarkClassName(gc, location=self.cur_token_location_)
+ else:
+ return self.ast.GlyphClassName(gc, location=self.cur_token_location_)
+
+ self.expect_symbol_("[")
+ location = self.cur_token_location_
+ glyphs = self.ast.GlyphClass(location=location)
+ while self.next_token_ != "]":
+ if self.next_token_type_ is Lexer.NAME:
+ glyph = self.expect_glyph_()
+ location = self.cur_token_location_
+ if '-' in glyph and glyph not in self.glyphNames_:
+ start, limit = self.split_glyph_range_(glyph, location)
+ glyphs.add_range(
+ start, limit,
+ self.make_glyph_range_(location, start, limit))
+ elif self.next_token_ == "-":
+ start = glyph
+ self.expect_symbol_("-")
+ limit = self.expect_glyph_()
+ glyphs.add_range(
+ start, limit,
+ self.make_glyph_range_(location, start, limit))
+ else:
+ glyphs.append(glyph)
+ elif self.next_token_type_ is Lexer.CID:
+ glyph = self.expect_glyph_()
+ if self.next_token_ == "-":
+ range_location = self.cur_token_location_
+ range_start = self.cur_token_
+ self.expect_symbol_("-")
+ range_end = self.expect_cid_()
+ glyphs.add_cid_range(range_start, range_end,
+ self.make_cid_range_(range_location,
+ range_start, range_end))
+ else:
+ glyphs.append("cid%05d" % self.cur_token_)
+ elif self.next_token_type_ is Lexer.GLYPHCLASS:
+ self.advance_lexer_()
+ gc = self.glyphclasses_.resolve(self.cur_token_)
+ if gc is None:
+ raise FeatureLibError(
+ "Unknown glyph class @%s" % self.cur_token_,
+ self.cur_token_location_)
+ # fix bug don't output class definition, just the name.
+ if isinstance(gc, self.ast.MarkClass):
+ gcn = self.ast.MarkClassName(gc, location=self.cur_token_location_)
+ else:
+ gcn = self.ast.GlyphClassName(gc, location=self.cur_token_location_)
+ glyphs.add_class(gcn)
+ else:
+ raise FeatureLibError(
+ "Expected glyph name, glyph range, "
+ "or glyph class reference. Found %s" % self.next_token_,
+ self.next_token_location_)
+ self.expect_symbol_("]")
+ return glyphs
+
+ def parseIfClass(self):
+ location = self.cur_token_location_
+ self.expect_symbol_("(")
+ if self.next_token_type_ is Lexer.GLYPHCLASS:
+ self.advance_lexer_()
+ def ifClassTest():
+ gc = self.glyphclasses_.resolve(self.cur_token_)
+ return gc is not None and len(gc.glyphSet())
+ block = self.ast.IfBlock(ifClassTest, 'ifclass', '@'+self.cur_token_, location=location)
+ self.expect_symbol_(")")
+ import inspect # oh this is so ugly!
+ calledby = inspect.stack()[2][3] # called through lambda since extension
+ if calledby == 'parse_block_':
+ self.parse_subblock_(block, False)
+ else:
+ self.parse_statements_block_(block)
+ return block
+ else:
+ raise FeatureLibError("Syntax error missing glyphclass", location)
+
+ def parseIfInfo(self):
+ location = self.cur_token_location_
+ self.expect_symbol_("(")
+ name = self.expect_name_()
+ self.expect_symbol_(",")
+ reg = self.expect_string_()
+ self.expect_symbol_(")")
+ def ifInfoTest():
+ s = self.fontinfo.get(name, "")
+ return re.search(reg, s)
+ block = self.ast.IfBlock(ifInfoTest, 'ifinfo', '{}, "{}"'.format(name, reg), location=location)
+ import inspect # oh this is so ugly! Instead caller should pass in context
+ calledby = inspect.stack()[2][3] # called through a lambda since extension
+ if calledby == 'parse_block_':
+ self.parse_subblock_(block, False)
+ else:
+ self.parse_statements_block_(block)
+ return block
+
+ def parseKernPairsStatement_(self):
+ location = self.cur_token_location_
+ res = self.ast.KernPairsStatement(self.kerninfo, location)
+ return res
+
+ def parse_statements_block_(self, block):
+ self.expect_symbol_("{")
+ statements = block.statements
+ while self.next_token_ != "}" or self.cur_comments_:
+ self.advance_lexer_(comments=True)
+ if self.cur_token_type_ is Lexer.COMMENT:
+ statements.append(
+ self.ast.Comment(self.cur_token_,
+ location=self.cur_token_location_))
+ elif self.is_cur_keyword_("include"):
+ statements.append(self.parse_include_())
+ elif self.cur_token_type_ is Lexer.GLYPHCLASS:
+ statements.append(self.parse_glyphclass_definition_())
+ elif self.is_cur_keyword_(("anon", "anonymous")):
+ statements.append(self.parse_anonymous_())
+ elif self.is_cur_keyword_("anchorDef"):
+ statements.append(self.parse_anchordef_())
+ elif self.is_cur_keyword_("languagesystem"):
+ statements.append(self.parse_languagesystem_())
+ elif self.is_cur_keyword_("lookup"):
+ statements.append(self.parse_lookup_(vertical=False))
+ elif self.is_cur_keyword_("markClass"):
+ statements.append(self.parse_markClass_())
+ elif self.is_cur_keyword_("feature"):
+ statements.append(self.parse_feature_block_())
+ elif self.is_cur_keyword_("table"):
+ statements.append(self.parse_table_())
+ elif self.is_cur_keyword_("valueRecordDef"):
+ statements.append(
+ self.parse_valuerecord_definition_(vertical=False))
+ elif self.cur_token_type_ is Lexer.NAME and self.cur_token_ in self.extensions:
+ statements.append(self.extensions[self.cur_token_](self))
+ elif self.cur_token_type_ is Lexer.SYMBOL and self.cur_token_ == ";":
+ continue
+ else:
+ raise FeatureLibError(
+ "Expected feature, languagesystem, lookup, markClass, "
+ "table, or glyph class definition, got {} \"{}\"".format(self.cur_token_type_, self.cur_token_),
+ self.cur_token_location_)
+
+ self.expect_symbol_("}")
+ # self.expect_symbol_(";") # can't have }; since tokens are space separated
+
+ def parse_subblock_(self, block, vertical, stylisticset=False,
+ size_feature=None, cv_feature=None):
+ self.expect_symbol_("{")
+ for symtab in self.symbol_tables_:
+ symtab.enter_scope()
+
+ statements = block.statements
+ while self.next_token_ != "}" or self.cur_comments_:
+ self.advance_lexer_(comments=True)
+ if self.cur_token_type_ is Lexer.COMMENT:
+ statements.append(self.ast.Comment(
+ self.cur_token_, location=self.cur_token_location_))
+ elif self.cur_token_type_ is Lexer.GLYPHCLASS:
+ statements.append(self.parse_glyphclass_definition_())
+ elif self.is_cur_keyword_("anchorDef"):
+ statements.append(self.parse_anchordef_())
+ elif self.is_cur_keyword_({"enum", "enumerate"}):
+ statements.append(self.parse_enumerate_(vertical=vertical))
+ elif self.is_cur_keyword_("feature"):
+ statements.append(self.parse_feature_reference_())
+ elif self.is_cur_keyword_("ignore"):
+ statements.append(self.parse_ignore_())
+ elif self.is_cur_keyword_("language"):
+ statements.append(self.parse_language_())
+ elif self.is_cur_keyword_("lookup"):
+ statements.append(self.parse_lookup_(vertical))
+ elif self.is_cur_keyword_("lookupflag"):
+ statements.append(self.parse_lookupflag_())
+ elif self.is_cur_keyword_("markClass"):
+ statements.append(self.parse_markClass_())
+ elif self.is_cur_keyword_({"pos", "position"}):
+ statements.append(
+ self.parse_position_(enumerated=False, vertical=vertical))
+ elif self.is_cur_keyword_("script"):
+ statements.append(self.parse_script_())
+ elif (self.is_cur_keyword_({"sub", "substitute",
+ "rsub", "reversesub"})):
+ statements.append(self.parse_substitute_())
+ elif self.is_cur_keyword_("subtable"):
+ statements.append(self.parse_subtable_())
+ elif self.is_cur_keyword_("valueRecordDef"):
+ statements.append(self.parse_valuerecord_definition_(vertical))
+ elif stylisticset and self.is_cur_keyword_("featureNames"):
+ statements.append(self.parse_featureNames_(stylisticset))
+ elif cv_feature and self.is_cur_keyword_("cvParameters"):
+ statements.append(self.parse_cvParameters_(cv_feature))
+ elif size_feature and self.is_cur_keyword_("parameters"):
+ statements.append(self.parse_size_parameters_())
+ elif size_feature and self.is_cur_keyword_("sizemenuname"):
+ statements.append(self.parse_size_menuname_())
+ elif self.cur_token_type_ is Lexer.NAME and self.cur_token_ in self.extensions:
+ statements.append(self.extensions[self.cur_token_](self))
+ elif self.cur_token_ == ";":
+ continue
+ else:
+ raise FeatureLibError(
+ "Expected glyph class definition or statement: got {} {}".format(self.cur_token_type_, self.cur_token_),
+ self.cur_token_location_)
+
+ self.expect_symbol_("}")
+ for symtab in self.symbol_tables_:
+ symtab.exit_scope()
+
+ def collect_block_(self):
+ self.expect_symbol_("{")
+ tokens = [(self.cur_token_type_, self.cur_token_)]
+ count = 1
+ while count > 0:
+ self.advance_lexer_()
+ if self.cur_token_ == "{":
+ count += 1
+ elif self.cur_token_ == "}":
+ count -= 1
+ tokens.append((self.cur_token_type_, self.cur_token_))
+ return tokens
+
+ def parseDoStatement_(self):
+ location = self.cur_token_location_
+ substatements = []
+ ifs = []
+ while True:
+ self.advance_lexer_()
+ if self.is_cur_keyword_("for"):
+ substatements.append(self.parseDoFor_())
+ elif self.is_cur_keyword_("let"):
+ substatements.append(self.parseDoLet_())
+ elif self.is_cur_keyword_("if"):
+ ifs.append(self.parseDoIf_())
+ elif self.cur_token_ == '{':
+ self.back_lexer_()
+ ifs.append(self.parseEmptyIf_())
+ break
+ elif self.cur_token_type_ == Lexer.COMMENT:
+ continue
+ else:
+ self.back_lexer_()
+ break
+ res = self.ast.Block()
+ lex = self.lexer_.lexers_[-1]
+ for s in self.DoIterateValues_(substatements):
+ for i in ifs:
+ (_, v) = next(i.items(s))
+ if v:
+ lex.scope = s
+ #import pdb; pdb.set_trace()
+ lex.pushstack(('tokens', i.block[:]))
+ self.advance_lexer_()
+ self.advance_lexer_()
+ try:
+ import inspect # oh this is so ugly!
+ calledby = inspect.stack()[2][3] # called through lambda since extension
+ if calledby == 'parse_block_':
+ self.parse_subblock_(res, False)
+ else:
+ self.parse_statements_block_(res)
+ except Exception as e:
+ logging.warning("In do context: " + str(s) + " lexer: " + repr(lex) + " at: " + str((self.cur_token_, self.next_token_)))
+ raise
+ return res
+
+ def DoIterateValues_(self, substatements):
+ def updated(d, *a, **kw):
+ d.update(*a, **kw)
+ return d
+ results = [{}]
+ #import pdb; pdb.set_trace()
+ for s in substatements:
+ newresults = []
+ for x in results:
+ for r in s.items(x):
+ c = x.copy()
+ c.update(r)
+ newresults.append(c)
+ results = newresults
+ for r in results:
+ yield r
+
+ def parseDoFor_(self):
+ location = self.cur_token_location_
+ self.advance_lexer_()
+ if self.cur_token_type_ is Lexer.NAME:
+ name = self.cur_token_
+ else:
+ raise FeatureLibError("Bad name in do for statement", location)
+ self.expect_symbol_("=")
+ glyphs = self.parse_glyphclass_(True)
+ self.expect_symbol_(";")
+ res = self.ast.DoForSubStatement(name, glyphs, location=location)
+ return res
+
+ def parseDoLet_(self):
+ # import pdb; pdb.set_trace()
+ location = self.cur_token_location_
+ self.advance_lexer_()
+ names = []
+ while self.cur_token_type_ == Lexer.NAME:
+ names.append(self.cur_token_)
+ if self.next_token_type_ is Lexer.SYMBOL:
+ if self.next_token_ == ",":
+ self.advance_lexer_()
+ elif self.next_token_ == "=":
+ break
+ self.advance_lexer_()
+ else:
+ raise FeatureLibError("Expected '=', found '%s'" % self.cur_token_,
+ self.cur_token_location_)
+ lex = self.lexer_.lexers_[-1]
+ lex.scan_over_(Lexer.CHAR_WHITESPACE_)
+ start = lex.pos_
+ lex.scan_until_(";")
+ expr = lex.text_[start:lex.pos_]
+ self.advance_lexer_()
+ self.expect_symbol_(";")
+ return self.ast.DoLetSubStatement(names, expr, self, location=location)
+
+ def parseDoIf_(self):
+ location = self.cur_token_location_
+ lex = self.lexer_.lexers_[-1]
+ start = lex.pos_
+ lex.scan_until_(";")
+ expr = self.next_token_ + " " + lex.text_[start:lex.pos_]
+ self.advance_lexer_()
+ self.expect_symbol_(";")
+ block = self.collect_block_()
+ keep = (self.next_token_type_, self.next_token_)
+ block = [keep] + block + [keep]
+ return self.ast.DoIfSubStatement(expr, self, block, location=location)
+
+ def parseEmptyIf_(self):
+ location = self.cur_token_location_
+ lex = self.lexer_.lexers_[-1]
+ start = lex.pos_
+ expr = "True"
+ block = self.collect_block_()
+ keep = (self.next_token_type_, self.next_token_)
+ block = [keep] + block + [keep]
+ return self.ast.DoIfSubStatement(expr, self, block, location=location)
+
+ def parseDefStatement_(self):
+ lex = self.lexer_.lexers_[-1]
+ start = lex.pos_
+ lex.scan_until_("{")
+ fname = self.next_token_
+ fsig = fname + lex.text_[start:lex.pos_].strip()
+ tag = re.escape(fname)
+ _, content, location = lex.scan_anonymous_block(tag)
+ self.advance_lexer_()
+ start = lex.pos_
+ lex.scan_until_(";")
+ endtag = lex.text_[start:lex.pos_].strip()
+ assert(fname == endtag)
+ self.advance_lexer_()
+ self.advance_lexer_()
+ funcstr = "def " + fsig + ":\n" + content
+ if astx.safeeval(funcstr):
+ exec(funcstr, self.fns)
+ return self.ast.Comment("# def " + fname)
diff --git a/lib/silfont/ftml.py b/lib/silfont/ftml.py
new file mode 100644
index 0000000..9f63cab
--- /dev/null
+++ b/lib/silfont/ftml.py
@@ -0,0 +1,433 @@
+#!/usr/bin/env python
+'Classes and functions for use handling FTML objects in pysilfont scripts'
+__url__ = 'http://github.com/silnrsi/pysilfont'
+__copyright__ = 'Copyright (c) 2016 SIL International (http://www.sil.org)'
+__license__ = 'Released under the MIT License (http://opensource.org/licenses/MIT)'
+__author__ = 'David Raymond'
+
+from xml.etree import ElementTree as ET
+from fontTools import ttLib
+import re
+from xml.sax.saxutils import quoteattr
+import silfont.core
+import silfont.etutil as ETU
+
+# Regular expression for parsing font name
+fontspec = re.compile(r"""^ # beginning of string
+ (?P<rest>[A-Za-z ]+?) # Font Family Name
+ \s*(?P<bold>Bold)? # Bold
+ \s*(?P<italic>Italic)? # Italic
+ \s*(?P<regular>Regular)? # Regular
+ $""", re.VERBOSE) # end of string
+
+class Fxml(ETU.ETelement) :
+ def __init__(self, file = None, xmlstring = None, testgrouplabel = None, logger = None, params = None) :
+ self.logger = logger if logger is not None else silfont.core.loggerobj()
+ self.params = params if params is not None else silfont.core.parameters()
+ self.parseerrors=None
+ if not exactlyoneof(file, xmlstring, testgrouplabel) : self.logger.log("Must supply exactly one of file, xmlstring and testgrouplabel","X")
+
+ if testgrouplabel : # Create minimal valid ftml
+ xmlstring = '<ftml version="1.0"><head></head><testgroup label=' + quoteattr(testgrouplabel) +'></testgroup></ftml>'
+
+ if file and not hasattr(file, 'read') : self.logger.log("'file' is not a file object", "X") # ET.parse would also work on file name, but other code assumes file object
+
+ try :
+ if file :
+ self.element = ET.parse(file).getroot()
+ else :
+ self.element = ET.fromstring(xmlstring)
+ except Exception as e :
+ self.logger.log("Error parsing FTML input: " + str(e), "S")
+
+ super(Fxml,self).__init__(self.element)
+
+ self.version = getattrib(self.element,"version")
+ if self.version != "1.0" : self.logger.log("ftml items must have a version of 1.0", "S")
+
+ self.process_subelements((
+ ("head", "head" , Fhead, True, False),
+ ("testgroup", "testgroups", Ftestgroup, True, True )),
+ offspec = False)
+
+ self.stylesheet = {}
+ if file : # If reading from file, look to see if a stylesheet is present in xml processing instructions
+ file.seek(0) # Have to re-read file since ElementTree does not support processing instructions
+ for line in file :
+ if line[0:2] == "<?" :
+ line = line.strip()[:-2] # Strip white space and removing training ?>
+ parts = line.split(" ")
+ if parts[0] == "<?xml-stylesheet" :
+ for part in parts[1:] :
+ (name,value) = part.split("=")
+ self.stylesheet[name] = value[1:-1] # Strip quotes
+ break
+ else :
+ break
+
+ self.filename = file if file else None
+
+ if self.parseerrors:
+ self.logger.log("Errors parsing ftml element:","E")
+ for error in self.parseerrors : self.logger.log(" " + error,"E")
+ self.logger.log("Invalid FTML", "S")
+
+ def save(self, file) :
+ self.outxmlstr=""
+ element = self.create_element()
+ etw = ETU.ETWriter(element, inlineelem = ["em"])
+ self.outxmlstr = etw.serialize_xml()
+ file.write(self.outxmlstr)
+
+ def create_element(self) : # Create a new Elementtree element based on current object contents
+ element = ET.Element('ftml', version = str(self.version))
+ if self.stylesheet : # Create dummy .pi attribute for style sheet processing instruction
+ pi = "xml-stylesheet"
+ for attrib in sorted(self.stylesheet) : pi = pi + ' ' + attrib + '="' + self.stylesheet[attrib] + '"' ## Spec is not clear about what order attributes should be in
+ element.attrib['.pi'] = pi
+ element.append(self.head.create_element())
+ for testgroup in self.testgroups : element.append(testgroup.create_element())
+ return element
+
+class Fhead(ETU.ETelement) :
+ def __init__(self, parent, element) :
+ self.parent = parent
+ self.logger = parent.logger
+ super(Fhead,self).__init__(element)
+
+ self.process_subelements((
+ ("comment", "comment", None, False, False),
+ ("fontscale", "fontscale", None, False, False),
+ ("fontsrc", "fontsrc", Ffontsrc, False, True),
+ ("styles", "styles", ETU.ETelement, False, False ), # Initially just basic elements; Fstyles created below
+ ("title", "title", None, False, False),
+ ("widths", "widths", _Fwidth, False, False)),
+ offspec = True)
+
+ if self.fontscale is not None : self.fontscale = int(self.fontscale)
+ if self.styles is not None :
+ styles = {}
+ for styleelem in self.styles["style"] :
+ style = Fstyle(self, element = styleelem)
+ styles[style.name] = style
+ if style.parseerrors:
+ name = "" if style.name is None else style.name
+ self.parseerrors.append("Errors parsing style element: " + name)
+ for error in style.parseerrors : self.parseerrors.append(" " + error)
+ self.styles = styles
+ if self.widths is not None : self.widths = self.widths.widthsdict # Convert _Fwidths object into dict
+
+ self.elements = dict(self._contents) # Dictionary of all elements, particularly for handling non-standard elements
+
+ def findstyle(self, name = None, feats = None, lang = None) :
+ if self.styles is not None:
+ for s in self.styles :
+ style = self.styles[s]
+ if style.feats == feats and style.lang == lang :
+ if name is None or name == style.name : return style # if name is supplied it must match
+ return None
+
+ def addstyle(self, name, feats = None, lang = None) : # Return style if it exists otherwise create new style with newname
+ s = self.findstyle(name, feats, lang)
+ if s is None :
+ if self.styles is None:
+ self.styles = {}
+ if name in self.styles : self.logger.log("Adding duplicate style name " + name, "X")
+ s = Fstyle(self, name = name, feats = feats, lang = lang)
+ self.styles[name] = s
+ return s
+
+ def create_element(self) :
+ element = ET.Element('head')
+ # Add in-spec sub-elements in alphabetic order
+ if self.comment : x = ET.SubElement(element, 'comment') ; x.text = self.comment
+ if self.fontscale : x = ET.SubElement(element, 'fontscale') ; x.text = str(self.fontscale)
+ if isinstance(self.fontsrc, list):
+ # Allow multiple fontsrc
+ for fontsrc in self.fontsrc:
+ element.append(fontsrc.create_element())
+ elif self.fontsrc is not None:
+ element.append(self.fontsrc.create_element())
+ if self.styles :
+ x = ET.SubElement(element, 'styles')
+ for style in sorted(self.styles) : x.append(self.styles[style].create_element())
+ if self.title : y = ET.SubElement(element, 'title') ; y.text = self.title
+ if not self.widths is None :
+ x = ET.SubElement(element, 'widths')
+ for width in sorted(self.widths) :
+ if self.widths[width] is not None: x.set(width, self.widths[width])
+
+ # Add any non-spec elements
+ for el in sorted(self.elements) :
+ if el not in ("comment", "fontscale", "fontsrc", "styles", "title", "widths") :
+ for elem in self.elements[el] : element.append(elem)
+
+ return element
+
+class Ffontsrc(ETU.ETelement) :
+ # This library only supports a single font in the fontsrc as recommended by the FTML spec
+ # Currently it only supports simple url() and local() values
+
+ def __init__(self, parent, element = None, text = None, label=None) :
+ self.parent = parent
+ self.logger = parent.logger
+ self.parseerrors = []
+
+ if not exactlyoneof(element, text) : self.logger.log("Must supply exactly one of element and text","X")
+
+ try:
+ (txt, url, local) = parsefontsrc(text, allowplain=True) if text else parsefontsrc(element.text)
+ except ValueError as e :
+ txt = text if text else element.text
+ self.parseerrors.append(str(e) + ": " + txt)
+ else :
+ if text : element = ET.Element("fontsrc") ; element.text = txt
+ if label : element.set('label', label)
+ super(Ffontsrc,self).__init__(element)
+ self.process_attributes((
+ ("label", "label", False),),
+ others=False)
+ self.text = txt
+ self.url = url
+ self.local = local
+ if self.local : # Parse font name to find if bold, italic etc
+ results = re.match(fontspec, self.local) ## Does not cope with -, eg Gentium-Bold. Should it?"
+ self.fontfamily = results.group('rest')
+ self.bold = results.group('bold') != None
+ self.italic = results.group('italic') != None
+ else :
+ self.fontfamily = None # If details are needed call getweights()
+
+ def addfontinfo(self) : # set fontfamily, bold and italic by looking inside font
+ (ff, bold, italic) = getfontinfo(self.url)
+ self.fontfamily = ff
+ self.bold = bold
+ self.italic = italic
+
+ def create_element(self) :
+ element = ET.Element("fontsrc")
+ element.text = self.text
+ if self.label : element.set("label", self.label)
+ return element
+
+class Fstyle(ETU.ETelement) :
+ def __init__(self, parent, element = None, name = None, feats = None, lang = None) :
+ self.parent = parent
+ self.logger = parent.logger
+ if element is not None :
+ if name or feats or lang : parent.logger("Can't supply element and other parameters", "X")
+ else :
+ if name is None : self.logger.log("Must supply element or name to Fstyle", "X")
+ element = self.element = ET.Element("style", name = name)
+ if feats is not None :
+ if type(feats) is dict : feats = self.dict_to_string(feats)
+ element.set('feats',feats)
+ if lang is not None : element.set('lang', lang)
+ super(Fstyle,self).__init__(element)
+
+ self.process_attributes((
+ ("feats", "feats", False),
+ ("lang", "lang", False),
+ ("name", "name", True)),
+ others = False)
+
+ if type(self.feats) is str : self.feats = self.string_to_dict(self.feats)
+
+ def string_to_dict(self, string) : # Split string on ',', then add to dict splitting on " " and removing quotes
+ dict={}
+ for f in string.split(','):
+ f = f.strip()
+ m = re.match(r'''(?P<quote>['"])(\w{4})(?P=quote)\s+(\d+|on|off)$''', f)
+ if m:
+ dict[m.group(2)] = m.group(3)
+ else:
+ self.logger.log(f'Invalid feature syntax "{f}"', 'E')
+ return dict
+
+ def dict_to_string(self, dict) :
+ str=""
+ for name in sorted(dict) :
+ if dict[name] is not None : str += "'" + name + "' " + dict[name] + ", "
+ str = str[0:-2] # remove final ", "
+ return str
+
+ def create_element(self) :
+ element = ET.Element("style", name = self.name)
+ if self.feats : element.set("feats", self.dict_to_string(self.feats))
+ if self.lang : element.set("lang", self.lang)
+ return element
+
+
+class _Fwidth(ETU.ETelement) : # Only used temporarily whilst parsing xml
+ def __init__(self, parent, element) :
+ super(_Fwidth,self).__init__(element)
+ self.parent = parent
+ self.logger = parent.logger
+
+ self.process_attributes((
+ ("comment", "comment", False),
+ ("label", "label", False),
+ ("string", "string", False),
+ ("stylename", "stylename", False),
+ ("table", "table", False)),
+ others = False)
+ self.widthsdict = {
+ "comment": self.comment,
+ "label": self.label,
+ "string": self.string,
+ "stylename": self.stylename,
+ "table": self.table}
+
+class Ftestgroup(ETU.ETelement) :
+ def __init__(self, parent, element = None, label = None) :
+ self.parent = parent
+ self.logger = parent.logger
+ if not exactlyoneof(element, label) : self.logger.log("Must supply exactly one of element and label","X")
+
+ if label : element = ET.Element("testgroup", label = label)
+
+ super(Ftestgroup,self).__init__(element)
+
+ self.subgroup = True if type(parent) is Ftestgroup else False
+ self.process_attributes((
+ ("background", "background", False),
+ ("label", "label", True)),
+ others = False)
+ self.process_subelements((
+ ("comment", "comment", None, False, False),
+ ("test", "tests", Ftest, False, True),
+ ("testgroup", "testgroups", Ftestgroup, False, True)),
+ offspec = False)
+ if self.subgroup and self.testgroups != [] : parent.parseerrors.append("Only one level of testgroup nesting permitted")
+
+ # Merge any sub-testgroups into tests
+ if self.testgroups != [] :
+ tests = []
+ tg = list(self.testgroups) # Want to preserve original list
+ for elem in self.element :
+ if elem.tag == "test":
+ tests.append(self.tests.pop(0))
+ elif elem.tag == "testgroup" :
+ tests.append(tg.pop(0))
+ self.tests = tests
+
+ def create_element(self) :
+ element = ET.Element("testgroup")
+ if self.background : element.set("background", self.background)
+ element.set("label", self.label)
+ if self.comment : x = ET.SubElement(element, 'comment') ; x.text = self.comment
+ for test in self.tests : element.append(test.create_element())
+ return element
+
+class Ftest(ETU.ETelement) :
+ def __init__(self, parent, element = None, label = None, string = None) :
+ self.parent = parent
+ self.logger = parent.logger
+ if not exactlyoneof(element, (label, string)) : self.logger.log("Must supply exactly one of element and label/string","X")
+
+ if label :
+ element = ET.Element("test", label = label)
+ x = ET.SubElement(element,"string") ; x.text = string
+
+ super(Ftest,self).__init__(element)
+
+ self.process_attributes((
+ ("background", "background", False),
+ ("label", "label", True),
+ ("rtl", "rtl", False),
+ ("stylename", "stylename", False)),
+ others = False)
+
+ self.process_subelements((
+ ("comment", "comment", None, False, False),
+ ("string", "string", _Fstring, True, False)),
+ offspec = False)
+
+ self.string = self.string.string # self.string initially a temporary _Fstring element
+
+ def str(self, noems = False) : # Return formatted version of string
+ string = self.string
+ if noems :
+ string = string.replace("<em>","")
+ string = string.replace("</em>","")
+ return string ## Other formatting options to be added as needed cf ftml2odt
+
+ def create_element(self) :
+ element = ET.Element("test")
+ if self.background : element.set("background", self.background)
+ element.set("label", self.label)
+ if self.rtl : element.set("rtl", self.rtl)
+ if self.stylename : element.set("stylename", self.stylename)
+ if self.comment : x = ET.SubElement(element, "comment") ; x.text = self.comment
+ x = ET.SubElement(element, "string") ; x.text = self.string
+
+ return element
+
+class _Fstring(ETU.ETelement) : # Only used temporarily whilst parsing xml
+ def __init__(self, parent, element = None) :
+ self.parent = parent
+ self.logger = parent.logger
+ super(_Fstring,self).__init__(element)
+ self.process_subelements((("em", "em", ETU.ETelement,False, True),), offspec = False)
+ # Need to build text of string to include <em> subelements
+ self.string = element.text if element.text else ""
+ for em in self.em :
+ self.string += "<em>{}</em>{}".format(em.element.text, em.element.tail)
+
+def getattrib(element,attrib) :
+ return element.attrib[attrib] if attrib in element.attrib else None
+
+def exactlyoneof( *args ) : # Check one and only one of args is not None
+
+ last = args[-1] # Check if last argument is a tuple - in which case
+ if type(last) is tuple : # either all or none of list must be None
+ for test in last[1:] :
+ if (test is None) != (last[0] == None) : return False
+ args = list(args) # Convert to list so last val can be changed
+ args[-1] = last[0] # Now valid to test on any item in tuple
+
+ one = False
+ for test in args :
+ if test is not None :
+ if one : return False # already have found one not None
+ one = True
+ if one : return True
+ return False
+
+def parsefontsrc(text, allowplain = False) : # Check fontsrc text is valid and return normalised text, url and local values
+ ''' - if multiple (fallback) fonts are specified, just process the first one
+ - just handles simple url() or local() formats
+ - if allowplain is set, allows text without url() or local() and decides which based on "." in text '''
+ text = text.split(",")[0] # If multiple (fallback) fonts are specified, just process the first one
+ #if allowplain and not re.match(r"^(url|local)[(][^)]+[)]",text) : # Allow for text without url() or local() form
+ if allowplain and not "(" in text : # Allow for text without url() or local() form
+ plain = True
+ if "." in text :
+ type = "url"
+ else :
+ type = "local"
+ else :
+ type = text.split("(")[0]
+ if type == "url" :
+ text = text.split("(")[1][:-1].strip()
+ elif type == "local" :
+ text = text.split("(")[1][:-1].strip()
+ else : raise ValueError("Invalid fontsrc string")
+ if type == "url" :
+ return ("url("+text+")", text, None)
+ else :
+ return ("local("+text+")", None , text)
+
+ return (text,url,local)
+
+def getfontinfo(filename) : # peek inside the font for the name, weight, style
+ f = ttLib.TTFont(filename)
+ # take name from name table, NameID 1, platform ID 3, Encoding ID 1 (possible fallback platformID 1, EncodingID =0)
+ n = f['name'] # name table from font
+ fontname = n.getName(1,3,1).toUnicode() # nameID 1 = Font Family name
+ # take bold and italic info from OS/2 table, fsSelection bits 0 and 5
+ o = f['OS/2'] # OS/2 table
+ italic = (o.fsSelection & 1) > 0
+ bold = (o.fsSelection & 32) > 0
+ return (fontname, bold, italic)
+
diff --git a/lib/silfont/ftml_builder.py b/lib/silfont/ftml_builder.py
new file mode 100644
index 0000000..eb7e73b
--- /dev/null
+++ b/lib/silfont/ftml_builder.py
@@ -0,0 +1,750 @@
+#!/usr/bin/env python
+"""classes and functions for building ftml tests from glyph_data.csv and UFO"""
+__url__ = 'http://github.com/silnrsi/pysilfont'
+__copyright__ = 'Copyright (c) 2018 SIL International (http://www.sil.org)'
+__license__ = 'Released under the MIT License (http://opensource.org/licenses/MIT)'
+__author__ = 'Bob Hallissy'
+
+from silfont.ftml import Fxml, Ftestgroup, Ftest, Ffontsrc
+from palaso.unicode.ucd import get_ucd
+from itertools import product
+import re
+import collections.abc
+
+# This module comprises two related functionalities:
+# 1. The FTML object which acts as a staging object for ftml test data. The methods of this class
+# permit a gradual build-up of an ftml file, e.g.,
+#
+# startTestGroup(...)
+# setFeatures(...)
+# addToTest(...)
+# addToTest(...)
+# clearFeatures(...)
+# setLang(...)
+# addToTest(...)
+# closeTestGroup(...)
+# ...
+# writeFile(...)
+#
+# The module is clever enough, for example, to automatically close a test when changing features, languages or direction.
+#
+# 2. The FTMLBuilder object which reads and processes glyph_data.csv and provides assistance in iterating over
+# the characters, features, and languages that should be supported by the font, e.g.:
+#
+# ftml.startTestGroup('Encoded characters')
+# for uid in sorted(builder.uids()):
+# if uid < 32: continue
+# c = builder.char(uid)
+# for featlist in builder.permuteFeatures(uids=[uid]):
+# ftml.setFeatures(featlist)
+# builder.render([uid], ftml)
+# ftml.clearFeatures()
+# for langID in sorted(c.langs):
+# ftml.setLang(langID)
+# builder.render([uid], ftml)
+# ftml.clearLang()
+#
+# See examples/psfgenftml.py for ideas
+
+class FTML(object):
+ """a staging class for collecting ftml content and finally writing the xml"""
+
+ # Assumes no nesting of test groups
+
+ def __init__(self, title, logger, comment = None, fontsrc = None, fontlabel = None, fontscale = None,
+ widths = None, rendercheck = True, xslfn = None, defaultrtl = False):
+ self.logger = logger
+ # Initialize an Fxml object
+ fxml = Fxml(testgrouplabel = "dummy")
+ fxml.stylesheet = {'type': 'text/xsl', 'href': xslfn if xslfn is not None else 'ftml.xsl'}
+ fxml.head.title = title
+ fxml.head.comment = comment
+ if isinstance(fontsrc, (tuple, list)):
+ # Allow multiple fontsrc
+ fxml.head.fontsrc = [Ffontsrc(fxml.head, text=fontsrc,
+ label=fontlabel[i] if fontlabel is not None and i < len(fontlabel) else None)
+ for i, fontsrc in enumerate(fontsrc)]
+ elif fontsrc:
+ fxml.head.fontsrc = Ffontsrc(fxml.head, text=fontsrc, label=fontlabel)
+
+ if fontscale: fxml.head.fontscale = int(fontscale)
+ if widths: fxml.head.widths = widths
+ fxml.testgroups.pop() # Remove dummy test group
+ # Save object
+ self._fxml = fxml
+ # Initialize state
+ self._curTest = None
+ self.closeTestGroup()
+ self.defaultRTL = defaultrtl
+ # Add first testgroup if requested
+ if rendercheck:
+ self.startTestGroup("Rendering Check", background="#F0F0F0")
+ self.addToTest(None, "RenderingUnknown", "check", rtl = False)
+ self.closeTest()
+ self.closeTestGroup()
+
+ _colorMap = {
+ 'aqua': '#00ffff',
+ 'black': '#000000',
+ 'blue': '#0000ff',
+ 'fuchsia': '#ff00ff',
+ 'green': '#008000',
+ 'grey': '#808080',
+ 'lime': '#00ff00',
+ 'maroon': '#800000',
+ 'navy': '#000080',
+ 'olive': '#808000',
+ 'purple': '#800080',
+ 'red': '#ff0000',
+ 'silver': '#c0c0c0',
+ 'teal': '#008080',
+ 'white': '#ffffff',
+ 'yellow': '#ffff00',
+ 'orange': '#ffa500'
+ }
+
+ @staticmethod
+ def _getColor(color):
+ if color is None or len(color) == 0:
+ return None
+ color = color.lower()
+ if color in FTML._colorMap:
+ return FTML._colorMap[color]
+ if re.match(r'#[0-9a-f]{6}$', color):
+ return color
+ self.logger.log(f'Color "{color}" not understood; ignored', 'W')
+ return None
+
+ def closeTest(self, comment = None):
+ if self._curTest:
+ if comment is not None:
+ self._curTest.comment = comment
+ if self._curColor:
+ self._curTest.background = self._curColor
+ self._curTest = None
+ self._lastUID = None
+ self._lastRTL = None
+
+ def addToTest(self, uid, s = "", label = None, comment = None, rtl = None):
+ if rtl is None: rtl = self.defaultRTL
+ if (self._lastUID and uid and uid not in range(self._lastUID, self._lastUID + 2))\
+ or (self._lastRTL is not None and rtl != self._lastRTL):
+ self.closeTest()
+ self._lastUID = uid
+ self._lastRTL = rtl
+ if self._curTestGroup is None:
+ # Create a new Ftestgroup
+ self.startTestGroup("Group")
+ if self._curTest is None:
+ # Create a new Ftest
+ if label is None:
+ label = "U+{0:04X}".format(uid) if uid is not None else "test"
+ test = Ftest(self._curTestGroup, label = label, string = '')
+ if comment:
+ test.comment = comment
+ if rtl: test.rtl = "True"
+ # Construct stylename and add style if needed:
+ x = ['{}_{}'.format(t,v) for t,v in self._curFeatures.items()] if self._curFeatures else []
+ if self._curLang:
+ x.insert(0,self._curLang)
+ if len(x):
+ test.stylename = '_'.join(x)
+ self._fxml.head.addstyle(test.stylename, feats = self._curFeatures, lang = self._curLang)
+ # Append to current test group
+ self._curTestGroup.tests.append(test)
+ self._curTest = test
+ if len(self._curTest.string): self._curTest.string += ' '
+ # Special hack until we get to python3 with full unicode support
+ self._curTest.string += ''.join([ c if ord(c) < 128 else '\\u{0:06X}'.format(ord(c)) for c in s ])
+ # self._curTest.string += s
+
+ def setFeatures(self, features):
+ # features can be None or a list; list elements can be:
+ # None
+ # a feature setting in the form [tag,value]
+ if features is None:
+ return self.clearFeatures()
+ features = [x for x in features if x]
+ if len(features) == 0:
+ return self.clearFeatures()
+ features = dict(features) # Convert to a dictionary -- this is what we'll keep.
+ if features != self._curFeatures:
+ self.closeTest()
+ self._curFeatures = features
+
+ def clearFeatures(self):
+ if self._curFeatures is not None:
+ self.closeTest()
+ self._curFeatures = None
+
+ def setLang(self, langID):
+ if langID != self._curLang:
+ self.closeTest();
+ self._curLang = langID
+
+ def clearLang(self):
+ if self._curLang:
+ self.closeTest()
+ self._curLang = None
+
+ def setBackground(self, color):
+ color = self._getColor(color)
+ if color != self._curColor:
+ self.closeTest()
+ self._curColor = color
+
+ def clearBackground(self):
+ if self._curColor is not None:
+ self.closeTest()
+ self._curColor = None
+
+ def closeTestGroup(self):
+ self.closeTest()
+ self._curTestGroup = None
+ self._curFeatures = None
+ self._curLang = None
+ self._curColor = None
+
+ def startTestGroup(self, label, background = None):
+ if self._curTestGroup is not None:
+ if label == self._curTestGroup.label:
+ return
+ self.closeTestGroup()
+ # Add new test group
+ self._curTestGroup = Ftestgroup(self._fxml, label = label)
+ background = self._getColor(background)
+ if background is not None:
+ self._curTestGroup.background = background
+
+ # append to root test groups
+ self._fxml.testgroups.append(self._curTestGroup)
+
+ def writeFile(self, output):
+ self.closeTestGroup()
+ self._fxml.save(output)
+
+
+class Feature(object):
+ """abstraction of a feature"""
+
+ def __init__(self, tag):
+ self.tag = tag
+ self.default = 0
+ self.maxval = 1
+ self._tvlist = None
+
+ def __getattr__(self,name):
+ if name == "tvlist":
+ # tvlist is a list of all possible tag,value pairs (except the default but including None) for this feature
+ # This attribute shouldn't be needed until all the possible feature value are known,
+ # therefore we'll generate this the first time we need it and save it
+ if self._tvlist is None:
+ self._tvlist = [ None ]
+ for v in range (0, self.maxval+1):
+ if v != self.default:
+ self._tvlist.append( [self.tag, str(v)])
+ return self._tvlist
+
+
+class FChar(object):
+ """abstraction of an encoded glyph in the font"""
+
+ def __init__(self, uids, basename, logger):
+ self.logger = logger
+ # uids can be a singleton integer or, for multiple-encoded glyphs, some kind of sequence of integers
+ if isinstance(uids,collections.abc.Sequence):
+ uids1 = uids
+ else:
+ uids1 = (uids,)
+ # test each uid to make sure valid; remove if not.
+ uids2=[]
+ self.general = "unknown"
+ for uid in uids1:
+ try:
+ gc = get_ucd(uid,'gc')
+ if self.general == "unknown":
+ self.general = gc
+ uids2.append(uid)
+ except (TypeError, IndexError):
+ self.logger.log(f'Invalid USV "{uid}" -- ignored.', 'E')
+ continue
+ except KeyError:
+ self.logger.log('USV %04X not defined; no properties known' % uid, 'W')
+ # make sure there's at least one left
+ assert len(uids2) > 0, f'No valid USVs found in {repr(uids)}'
+ self._uids = tuple(uids2)
+ self.basename = basename
+ self.feats = set() # feat tags that affect this char
+ self.langs = set() # lang tags that affect this char
+ self.aps = set()
+ self.altnames = {} # alternate glyph names.
+ # the above is a dict keyed by either:
+ # lang tag e.g., 'ur', or
+ # feat tag and value, e.g., 'cv24=3'
+ # and returns a the glyphname for that alternate.
+ # Additional info from UFO:
+ self.takesMarks = self.isMark = self.isBase = self.notInUFO = False
+
+ # Most callers don't need to support or or care about multiple-encoded glyphs, so we
+ # support the old .uid attribute by returning the first (I guess we consider it primary) uid.
+ def __getattr__(self,name):
+ if name == 'uids':
+ return self._uids
+ elif name == 'uid':
+ return self._uids[0]
+ else:
+ raise AttributeError
+
+ # the static method FTMLBuilder.checkGlyph is likely preferred
+ # but leave this instance method for backwards compatibility
+ def checkGlyph(self, gname, font, apRE):
+ # glean info from UFO if glyph is present
+ if gname in font.deflayer:
+ self.notInUFO = False
+ for a in font.deflayer[gname]['anchor'] :
+ name = a.element.get('name')
+ if apRE.match(name) is None:
+ continue
+ self.aps.add(name)
+ if name.startswith("_") :
+ self.isMark = True
+ else:
+ self.takesMarks = True
+ self.isBase = self.takesMarks and not self.isMark
+ else:
+ self.notInUFO = True
+
+
+class FSpecial(object):
+ """abstraction of a ligature or other interesting sequence"""
+
+ # Similar to FChar but takes a uid list rather than a single uid
+ def __init__(self, uids, basename, logger):
+ self.logger = logger
+ self.uids = uids
+ self.basename = basename
+ # a couple of properties based on the first uid:
+ try:
+ self.general = get_ucd(uids[0],'gc')
+ except KeyError:
+ self.logger.log('USV %04X not defined; no properties known' % uids[0], 'W')
+ self.feats = set() # feat tags that affect this char
+ self.aps = set()
+ self.langs = set() # lang tags that affect this char
+ self.altnames = {} # alternate glyph names.
+ self.takesMarks = self.isMark = self.isBase = self.notInUFO = False
+
+class FTMLBuilder(object):
+ """glyph_data and UFO processing for building FTML"""
+
+ def __init__(self, logger, incsv = None, fontcode = None, font = None, langs = None, rtlenable = False, ap = None ):
+ self.logger = logger
+ self.rtlEnable = rtlenable
+
+ # Default diacritic base:
+ self.diacBase = 0x25CC
+
+ # Default joinBefore and joinAfter sequence
+ self.joinBefore = '\u200D' # put before a sequence to force joining shape; def = zwj
+ self.joinAfter = '\u200D' # put after a sequence to force joining shape; def = zwj
+
+ # Dict mapping tag to Feature
+ self.features = {}
+
+ # Set of all languages seen
+ if langs is not None:
+ # Use a list so we keep the order (assuming caller wouldn't give us dups
+ self.allLangs = list(re.split(r'\s*[\s,]\s*', langs)) # Allow comma- or space-separated tags
+ self._langsComplete = True # We have all the lang tags desired
+ else:
+ # use a set because the langtags are going to dribble in and be repeated.
+ self.allLangs = set()
+ self._langsComplete = False # Add lang_tags from glyph_data
+
+ # Be able to find chars and specials:
+ self._charFromUID = {}
+ self._charFromBasename = {}
+ self._specialFromUIDs = {}
+ self._specialFromBasename = {}
+
+ # list of USVs that are in the CSV but whose glyphs are not in the UFO
+ self.uidsMissingFromUFO = set()
+
+ # DummyUSV (see charAuto())
+ self.curDummyUSV = 0x100000 # Supplemental Private Use Area B
+
+ # Compile --ap parameter
+ if ap is None:
+ ap = "."
+ try:
+ self.apRE = re.compile(ap)
+ except re.error as e:
+ logger.log("--ap parameter '{}' doesn't compile as regular expression: {}".format(ap, e), "S")
+
+ if incsv is not None:
+ self.readGlyphData(incsv, fontcode, font)
+
+ def addChar(self, uids, basename):
+ # Add an FChar
+ # assume parameters are OK:
+ c = FChar(uids, basename, self.logger)
+ # fatal error if the basename or any of uids have already been seen
+ fatal = False
+ for uid in c.uids:
+ if uid in self._charFromUID:
+ self.logger.log('Attempt to add duplicate USV %04X' % uid, 'E')
+ fatal = True
+ self._charFromUID[uid] = c
+ if basename in self._charFromBasename:
+ self.logger.log('Attempt to add duplicate basename %s' % basename, 'E')
+ fatal = True
+ self._charFromBasename[basename] = c
+ if fatal:
+ self.logger.log('Cannot continue due to previous errors', 'S')
+ return c
+
+ def uids(self):
+ """ returns list of uids in glyph_data """
+ return self._charFromUID.keys()
+
+ def char(self, x):
+ """ finds an FChar based either basename or uid;
+ generates KeyError if not found."""
+ return self._charFromBasename[x] if isinstance(x, str) else self._charFromUID[x]
+
+ def charAuto(self, x):
+ """ Like char() but will issue a warning and add a dummy """
+ try:
+ return self._charFromBasename[x] if isinstance(x, str) else self._charFromUID[x]
+ except KeyError:
+ # Issue error message and create dummy Char object for this character
+ if isinstance(x, str):
+ self.logger.log(f'Glyph "{x}" isn\'t in glyph_data.csv - adding dummy', 'E')
+ while self.curDummyUSV in self._charFromUID:
+ self.curDummyUSV += 1
+ c = self.addChar(self.curDummyUSV, x)
+ else:
+ self.logger.log(f'Char U+{x:04x} isn\'t in glyph_data.csv - adding dummy', 'E')
+ c = self.addChar(x, f'U+{x:04x}')
+ return c
+
+ def addSpecial(self, uids, basename):
+ # Add an FSpecial:
+ # fatal error if basename has already been seen:
+ if basename in self._specialFromBasename:
+ self.logger.log('Attempt to add duplicate basename %s' % basename, 'S')
+ c = FSpecial(uids, basename, self.logger)
+ # remember it:
+ self._specialFromUIDs[tuple(uids)] = c
+ self._specialFromBasename[basename] = c
+ return c
+
+ def specials(self):
+ """returns a list of the basenames of specials"""
+ return self._specialFromBasename.keys()
+
+ def special(self, x):
+ """ finds an FSpecial based either basename or uid sequence;
+ generates KeyError if not found."""
+ return self._specialFromBasename[x] if isinstance(x, str) else self._specialFromUIDs[tuple(x)]
+
+ def _csvWarning(self, msg, exception = None):
+ m = "glyph_data line {1}: {0}".format(msg, self.incsv.line_num)
+ if exception is not None:
+ m += '; ' + str(exception)
+ self.logger.log(m, 'W')
+
+ def readGlyphData(self, incsv, fontcode = None, font = None):
+ # Remember csv file for other methods:
+ self.incsv = incsv
+
+ # Validate fontcode, if provided
+ if fontcode is not None:
+ whichfont = fontcode.strip().lower()
+ if len(whichfont) != 1:
+ self.logger.log('fontcode must be a single letter', 'S')
+ else:
+ whichfont = None
+
+ # Get headings from csvfile:
+ fl = incsv.firstline
+ if fl is None: self.logger.log("Empty input file", "S")
+ # required columns:
+ try:
+ nameCol = fl.index('glyph_name');
+ usvCol = fl.index('USV')
+ except ValueError as e:
+ self.logger.log('Missing csv input field: ' + str(e), 'S')
+ except Exception as e:
+ self.logger.log('Error reading csv input field: ' + str(e), 'S')
+ # optional columns:
+ # If -f specified, make sure we have the fonts column
+ if whichfont is not None:
+ if 'Fonts' not in fl: self.logger.log('-f requires "Fonts" column in glyph_data', 'S')
+ fontsCol = fl.index('Fonts')
+ # Allow for projects that use only production glyph names (ps_name same as glyph_name)
+ psCol = fl.index('ps_name') if 'ps_name' in fl else nameCol
+ # Allow for projects that have no feature and/or lang-specific behaviors
+ featCol = fl.index('Feat') if 'Feat' in fl else None
+ bcp47Col = fl.index('bcp47tags') if 'bcp47tags' in fl else None
+
+ next(incsv.reader, None) # Skip first line with headers
+
+ # RE that matches names of glyphs we don't care about
+ namesToSkipRE = re.compile('^(?:[._].*|null|cr|nonmarkingreturn|tab|glyph_name)$',re.IGNORECASE)
+
+ # RE that matches things like 'cv23' or 'cv23=4' or 'cv23=2,3'
+ featRE = re.compile('^(\w{2,4})(?:=([\d,]+))?$')
+
+ # RE that matches USV sequences for ligatures
+ ligatureRE = re.compile('^[0-9A-Fa-f]{4,6}(?:_[0-9A-Fa-f]{4,6})+$')
+
+ # RE that matches space-separated USV sequences
+ USVsRE = re.compile('^[0-9A-Fa-f]{4,6}(?:\s+[0-9A-Fa-f]{4,6})*$')
+
+ # keep track of glyph names we've seen to detect duplicates
+ namesSeen = set()
+ psnamesSeen = set()
+
+ # OK, process all records in glyph_data
+ for line in incsv:
+ gname = line[nameCol].strip()
+
+ # things to ignore:
+ if namesToSkipRE.match(gname):
+ continue
+ if whichfont is not None and line[fontsCol] != '*' and line[fontsCol].lower().find(whichfont) < 0:
+ continue
+ if len(gname) == 0:
+ self._csvWarning('empty glyph name in glyph_data; ignored')
+ continue
+ if gname.startswith('#'):
+ continue
+ if gname in namesSeen:
+ self._csvWarning('glyph name %s previously seen in glyph_data; ignored' % gname)
+ continue
+
+ psname = line[psCol].strip() or gname # If psname absent, working name will be production name
+ if psname in psnamesSeen:
+ self._csvWarning('psname %s previously seen; ignored' % psname)
+ continue
+ namesSeen.add(gname)
+ psnamesSeen.add(psname)
+
+ # compute basename-- the glyph name without extensions:
+ basename = gname.split('.',1)[0]
+
+ # Process USV(s)
+ # could be empty string, a single USV, space-separated list of USVs for multiple encoding,
+ # or underscore-connected USVs indicating ligatures.
+
+ usvs = line[usvCol].strip()
+ if len(usvs) == 0:
+ # Empty USV field, unencoded glyph
+ usvs = ()
+ elif USVsRE.match(usvs):
+ # space-separated hex values:
+ usvs = usvs.split()
+ isLigature = False
+ elif ligatureRE.match(usvs):
+ # '_' separated hex values (ligatures)
+ usvs = usvs.split('_')
+ isLigature = True
+ else:
+ self._csvWarning(f"invalid USV field '{usvs}'; ignored")
+ usvs = ()
+ uids = [int(x, 16) for x in usvs]
+
+ if len(uids) == 0:
+ # Handle unencoded glyphs
+ uids = None # Prevents using this record to set default feature values
+ if basename in self._charFromBasename:
+ c = self._charFromBasename[basename]
+ # Check for additional AP info
+ c.checkGlyph(gname, font, self.apRE)
+ elif basename in self._specialFromBasename:
+ c = self._specialFromBasename[basename]
+ else:
+ self._csvWarning('unencoded variant %s found before encoded glyph' % gname)
+ c = None
+ elif isLigature:
+ # Handle ligatures
+ c = self.addSpecial(uids, basename)
+ uids = None # Prevents using this record to set default feature values (TODO: Research this)
+ else:
+ # Handle simple encoded glyphs (could be multiple uids!)
+ # Create character object
+ c = self.addChar(uids, basename)
+ if font is not None:
+ # Examine APs to determine if this character takes marks:
+ c.checkGlyph(gname, font, self.apRE)
+ if c.notInUFO:
+ self.uidsMissingFromUFO.update(uids)
+
+ if featCol is not None:
+ feats = line[featCol].strip()
+ if len(feats) > 0 and not(feats.startswith('#')):
+ feats = feats.split(';')
+ for feat in feats:
+ m = featRE.match(feat)
+ if m is None:
+ self._csvWarning('incorrectly formed feature specification "%s"; ignored' % feat)
+ else:
+ # find/create structure for this feature:
+ tag = m.group(1)
+ try:
+ feature = self.features[tag]
+ except KeyError:
+ feature = Feature(tag)
+ self.features[tag] = feature
+ # if values supplied, collect default and maximum values for this feature:
+ if m.group(2) is not None:
+ vals = [int(i) for i in m.group(2).split(',')]
+ if len(vals) > 0:
+ if uids is not None:
+ feature.default = vals[0]
+ elif len(feats) == 1: # TODO: This seems like wrong test.
+ for v in vals:
+ # remember the glyph name for this feature/value combination:
+ feat = '{}={}'.format(tag,v)
+ if c is not None and feat not in c.altnames:
+ c.altnames[feat] = gname
+ vals.append(feature.maxval)
+ feature.maxval = max(vals)
+ if c is not None:
+ # Record that this feature affects this character:
+ c.feats.add(tag)
+ else:
+ self._csvWarning('untestable feature "%s" : no known USV' % tag)
+
+ if bcp47Col is not None:
+ bcp47 = line[bcp47Col].strip()
+ if len(bcp47) > 0 and not(bcp47.startswith('#')):
+ if c is not None:
+ for tag in re.split(r'\s*[\s,]\s*', bcp47): # Allow comma- or space-separated tags
+ c.langs.add(tag) # lang-tags mentioned for this character
+ if not self._langsComplete:
+ self.allLangs.add(tag) # keep track of all possible lang-tags
+ else:
+ self._csvWarning('untestable langs: no known USV')
+
+ # We're finally done, but if allLangs is a set, let's order it (for lack of anything better) and make a list:
+ if not self._langsComplete:
+ self.allLangs = list(sorted(self.allLangs))
+
+ def permuteFeatures(self, uids = None, feats = None):
+ """ returns an iterator that provides all combinations of feature/value pairs, for a list of uids and/or a specific list of feature tags"""
+ feats = set(feats) if feats is not None else set()
+ if uids is not None:
+ for uid in uids:
+ if uid in self._charFromUID:
+ feats.update(self._charFromUID[uid].feats)
+ l = [self.features[tag].tvlist for tag in sorted(feats)]
+ return product(*l)
+
+ @staticmethod
+ def checkGlyph(obj, gname, font, apRE):
+ # glean info from UFO if glyph is present
+ if gname in font.deflayer:
+ obj.notInUFO = False
+ for a in font.deflayer[gname]['anchor']:
+ name = a.element.get('name')
+ if apRE.match(name) is None:
+ continue
+ obj.aps.add(name)
+ if name.startswith("_"):
+ obj.isMark = True
+ else:
+ obj.takesMarks = True
+ obj.isBase = obj.takesMarks and not obj.isMark
+ else:
+ obj.notInUFO = True
+
+ @staticmethod
+ def matchMarkBase(c_mark, c_base):
+ """ test whether an _AP on c_mark matches an AP on c_base """
+ for apM in c_mark.aps:
+ if apM.startswith("_"):
+ ap = apM[1:]
+ for apB in c_base.aps:
+ if apB == ap:
+ return True
+ return False
+
+ def render(self, uids, ftml, keyUID = 0, addBreaks = True, rtl = None, dualJoinMode = 3, label = None, comment = None):
+ """ general purpose (but not required) function to generate ftml for a character sequence """
+ if len(uids) == 0:
+ return
+ # Make a copy so we don't affect caller
+ uids = list(uids)
+ # Remember first uid and original length for later
+ startUID = uids[0]
+ uidLen = len(uids)
+ # if keyUID wasn't supplied, use startUID
+ if keyUID == 0: keyUID = startUID
+ if label is None:
+ # Construct label from uids:
+ label = '\n'.join(['U+{0:04X}'.format(u) for u in uids])
+ if comment is None:
+ # Construct comment from glyph names:
+ comment = ' '.join([self._charFromUID[u].basename for u in uids])
+ # see if uid list includes a mirrored char
+ hasMirrored = bool(len([x for x in uids if get_ucd(x,'Bidi_M')]))
+ # Analyze first and last joining char
+ joiningChars = [x for x in uids if get_ucd(x, 'jt') != 'T']
+ if len(joiningChars):
+ # If first or last non-TRANSPARENT char is a joining char, then we need to emit examples with zwj
+ # Assumes any non-TRANSPARENT char that is bc != L must be a rtl character of some sort
+ uid = joiningChars[0]
+ zwjBefore = (get_ucd(uid,'jt') == 'D'
+ or (get_ucd(uid,'bc') == 'L' and get_ucd(uid,'jt') == 'L')
+ or (get_ucd(uid,'bc') != 'L' and get_ucd(uid,'jt') == 'R'))
+ uid = joiningChars[-1]
+ zwjAfter = (get_ucd(uid,'jt') == 'D'
+ or (get_ucd(uid,'bc') == 'L' and get_ucd(uid,'jt') == 'R')
+ or (get_ucd(uid,'bc') != 'L' and get_ucd(uid,'jt') == 'L'))
+ else:
+ zwjBefore = zwjAfter = False
+ if get_ucd(startUID,'gc') == 'Mn':
+ # First char is a NSM... prefix a suitable base
+ uids.insert(0, self.diacBase)
+ zwjBefore = False # No longer any need to put zwj before
+ elif get_ucd(startUID, 'WSpace'):
+ # First char is whitespace -- prefix with baseline brackets:
+ uids.insert(0, 0xF130)
+ lastNonMark = [x for x in uids if get_ucd(x,'gc') != 'Mn'][-1]
+ if get_ucd(lastNonMark, 'WSpace'):
+ # Last non-mark is whitespace -- append baseline brackets:
+ uids.append(0xF131)
+ s = ''.join([chr(uid) for uid in uids])
+ if zwjBefore or zwjAfter:
+ # Show contextual forms:
+ # Start with isolate
+ t = u'{0} '.format(s)
+ if zwjBefore and zwjAfter:
+ # For sequences that show dual-joining behavior, what we show depends on dualJoinMode:
+ if dualJoinMode & 1:
+ # show initial, medial, final separated by space:
+ t += u'{0}{2} {1}{0}{2} {1}{0} '.format(s, self.joinBefore, self.joinAfter)
+ if dualJoinMode & 2:
+ # show 3 joined forms in sequence:
+ t += u'{0}{0}{0} '.format(s)
+ elif zwjAfter:
+ t += u'{0}{1} '.format(s, self.joinAfter)
+ elif zwjBefore:
+ t += u'{1}{0} '.format(s, self.joinBefore)
+ if addBreaks: ftml.closeTest()
+ ftml.addToTest(keyUID, t, label = label, comment = comment, rtl = rtl)
+ if addBreaks: ftml.closeTest()
+ elif hasMirrored and self.rtlEnable:
+ # Contains mirrored and rtl enabled:
+ if addBreaks: ftml.closeTest()
+ ftml.addToTest(keyUID, u'{0} LTR: \u202A{0}\u202C RTL: \u202B{0}\u202C'.format(s), label = label, comment = comment, rtl = rtl)
+ if addBreaks: ftml.closeTest()
+ # elif is LRE, RLE, PDF
+ # elif is LRI, RLI, FSI, PDI
+ elif uidLen > 1:
+ ftml.addToTest(keyUID, s , label = label, comment = comment, rtl = rtl)
+ else:
+ ftml.addToTest(keyUID, s , comment = comment, rtl = rtl)
+
diff --git a/lib/silfont/harfbuzz.py b/lib/silfont/harfbuzz.py
new file mode 100755
index 0000000..b02b478
--- /dev/null
+++ b/lib/silfont/harfbuzz.py
@@ -0,0 +1,71 @@
+#!/usr/bin/python
+'Harfbuzz support for fonttools'
+
+import gi
+gi.require_version('HarfBuzz', '0.0')
+from gi.repository import HarfBuzz as hb
+from gi.repository import GLib
+
+class Glyph(object):
+ def __init__(self, gid, **kw):
+ self.gid = gid
+ for k,v in kw.items():
+ setattr(self, k, v)
+
+ def __repr__(self):
+ return "[{gid}@({offset[0]},{offset[1]})+({advance[0]},{advance[1]})]".format(**self.__dict__)
+
+def shape_text(f, text, features = [], lang=None, dir="", script="", shapers=""):
+ fontfile = f.reader.file
+ fontfile.seek(0, 0)
+ fontdata = fontfile.read()
+ blob = hb.glib_blob_create(GLib.Bytes.new(fontdata))
+ face = hb.face_create(blob, 0)
+ del blob
+ font = hb.font_create(face)
+ upem = hb.face_get_upem(face)
+ del face
+ hb.font_set_scale(font, upem, upem)
+ hb.ot_font_set_funcs(font)
+
+ buf = hb.buffer_create()
+ t = text.encode('utf-8')
+ hb.buffer_add_utf8(buf, t, 0, -1)
+ hb.buffer_guess_segment_properties(buf)
+ if dir:
+ hb.buffer_set_direction(buf, hb.direction_from_string(dir))
+ if script:
+ hb.buffer_set_script(buf, hb.script_from_string(script))
+ if lang:
+ hb.buffer_set_language(buf, hb.language_from_string(lang))
+
+ feats = []
+ if len(features):
+ for feat_string in features:
+ if hb.feature_from_string(feat_string, -1, aFeats):
+ feats.append(aFeats)
+ if shapers:
+ hb.shape_full(font, buf, feats, shapers)
+ else:
+ hb.shape(font, buf, feats)
+
+ num_glyphs = hb.buffer_get_length(buf)
+ info = hb.buffer_get_glyph_infos(buf)
+ pos = hb.buffer_get_glyph_positions(buf)
+
+ glyphs = []
+ for i in range(num_glyphs):
+ glyphs.append(Glyph(info[i].codepoint, cluster = info[i].cluster,
+ offset = (pos[i].x_offset, pos[i].y_offset),
+ advance = (pos[i].x_advance, pos[i].y_advance),
+ flags = info[i].mask))
+ return glyphs
+
+if __name__ == '__main__':
+ import sys
+ from fontTools.ttLib import TTFont
+ font = sys.argv[1]
+ text = sys.argv[2]
+ f = TTFont(font)
+ glyphs = shape_text(f, text)
+ print(glyphs)
diff --git a/lib/silfont/ipython.py b/lib/silfont/ipython.py
new file mode 100644
index 0000000..150aa97
--- /dev/null
+++ b/lib/silfont/ipython.py
@@ -0,0 +1,135 @@
+#!/usr/bin/python
+'IPython support for fonttools'
+
+__all__ = ['displayGlyphs', 'loadFont', 'displayText', 'displayRaw']
+
+from fontTools import ttLib
+from fontTools.pens.basePen import BasePen
+from fontTools.misc import arrayTools
+from IPython.display import SVG, HTML
+from defcon import Font
+from ufo2ft import compileTTF
+
+class SVGPen(BasePen) :
+
+ def __init__(self, glyphSet, scale=1.0) :
+ super(SVGPen, self).__init__(glyphSet);
+ self.__commands = []
+ self.__scale = scale
+
+ def __str__(self) :
+ return " ".join(self.__commands)
+
+ def scale(self, pt) :
+ return ((pt[0] or 0) * self.__scale, (pt[1] or 0) * self.__scale)
+
+ def _moveTo(self, pt):
+ self.__commands.append("M {0[0]} {0[1]}".format(self.scale(pt)))
+
+ def _lineTo(self, pt):
+ self.__commands.append("L {0[0]} {0[1]}".format(self.scale(pt)))
+
+ def _curveToOne(self, pt1, pt2, pt3) :
+ self.__commands.append("C {0[0]} {0[1]} {1[0]} {1[1]} {2[0]} {2[1]}".format(self.scale(pt1), self.scale(pt2), self.scale(pt3)))
+
+ def _closePath(self) :
+ self.__commands.append("Z")
+
+ def clear(self) :
+ self.__commands = []
+
+def _svgheader():
+ return '''<?xml version="1.0"?>
+<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1">
+'''
+
+def _bbox(f, gnames, points, scale=1):
+ gset = f.glyphSet
+ bbox = (0, 0, 0, 0)
+ for i, gname in enumerate(gnames):
+ if hasattr(points, '__len__') and i == len(points):
+ points.append((bbox[2] / scale, 0))
+ pt = points[i] if i < len(points) else (0, 0)
+ g = gset[gname]._glyph
+ if g is None or not hasattr(g, 'xMin') :
+ gbox = (0, 0, 0, 0)
+ else :
+ gbox = (g.xMin * scale, g.yMin * scale, g.xMax * scale, g.yMax * scale)
+ bbox = arrayTools.unionRect(bbox, arrayTools.offsetRect(gbox, pt[0] * scale, pt[1] * scale))
+ return bbox
+
+glyphsetcount = 0
+def _defglyphs(f, gnames, scale=1):
+ global glyphsetcount
+ glyphsetcount += 1
+ gset = f.glyphSet
+ p = SVGPen(gset, scale)
+ res = "<defs><g>\n"
+ for gname in sorted(set(gnames)):
+ res += '<symbol overflow="visible" id="{}_{}">\n'.format(gname, glyphsetcount)
+ g = gset[gname]
+ p.clear()
+ g.draw(p)
+ res += '<path style="stroke:none;" d="' + str(p) + '"/>\n</symbol>\n'
+ res += "</g></defs>\n"
+ return res
+
+def loadFont(fname):
+ if fname.lower().endswith(".ufo"):
+ ufo = Font(fname)
+ f = compileTTF(ufo)
+ else:
+ f = ttLib.TTFont(fname)
+ return f
+
+def displayGlyphs(f, gnames, points=None, scale=None):
+ if not hasattr(gnames, '__len__') or isinstance(gnames, basestring):
+ gnames = [gnames]
+ if not hasattr(points, '__len__'):
+ points = []
+ if not hasattr(f, 'glyphSet'):
+ f.glyphSet = f.getGlyphSet()
+ res = _svgheader()
+ if points is None:
+ points = []
+ bbox = _bbox(f, gnames, points, scale or 1)
+ maxh = 100.
+ height = bbox[3] - (bbox[1] if bbox[1] < 0 else 0)
+ if scale is None and height > maxh:
+ scale = maxh / height
+ bbox = [x * scale for x in bbox]
+ res += _defglyphs(f, gnames, scale)
+ res += '<g id="surface1" transform="matrix(1,0,0,-1,{},{})">\n'.format(-bbox[0], bbox[3])
+ res += ' <rect x="{}" y="{}" width="{}" height="{}" style="fill:white;stroke:none"/>\n'.format(
+ bbox[0], bbox[1], bbox[2]-bbox[0], bbox[3])
+ res += ' <g style="fill:black">\n'
+ for i, gname in enumerate(gnames):
+ pt = points[i] if i < len(points) else (0, 0)
+ res += ' <use xlink:href="#{0}_{3}" x="{1}" y="{2}"/>\n'.format(gname, pt[0] * scale, pt[1] * scale, glyphsetcount)
+ res += ' </g></g>\n</svg>\n'
+ return SVG(data=res)
+ #return res
+
+def displayText(f, text, features = [], lang=None, dir="", script="", shapers="", size=0):
+ import harfbuzz
+ glyphs = harfbuzz.shape_text(f, text, features, lang, dir, script, shapers)
+ gnames = []
+ points = []
+ x = 0
+ y = 0
+ for g in glyphs:
+ gnames.append(f.getGlyphName(g.gid))
+ points.append((x+g.offset[0], y+g.offset[1]))
+ x += g.advance[0]
+ y += g.advance[1]
+ if size == 0:
+ scale = None
+ else:
+ upem = f['head'].unitsPerEm
+ scale = 4. * size / (upem * 3.)
+ return displayGlyphs(f, gnames, points, scale=scale)
+
+def displayRaw(text):
+ # res = "<html><body>"+text.encode('utf-8')+"</body></html>"
+ res = u"<html><body><p>"+text+u"</p></body></html>"
+ return HTML(data=res)
diff --git a/lib/silfont/scripts/__init__.py b/lib/silfont/scripts/__init__.py
new file mode 100755
index 0000000..e69de29
--- /dev/null
+++ b/lib/silfont/scripts/__init__.py
diff --git a/lib/silfont/scripts/psfaddanchors.py b/lib/silfont/scripts/psfaddanchors.py
new file mode 100755
index 0000000..88f595f
--- /dev/null
+++ b/lib/silfont/scripts/psfaddanchors.py
@@ -0,0 +1,73 @@
+#!/usr/bin/env python
+__doc__ = 'read anchor data from XML file and apply to UFO'
+__url__ = 'http://github.com/silnrsi/pysilfont'
+__copyright__ = 'Copyright (c) 2015 SIL International (http://www.sil.org)'
+__license__ = 'Released under the MIT License (http://opensource.org/licenses/MIT)'
+__author__ = 'David Rowe'
+
+from silfont.core import execute
+from xml.etree import ElementTree as ET
+
+argspec = [
+ ('ifont',{'help': 'Input UFO'}, {'type': 'infont'}),
+ ('ofont',{'help': 'Output UFO','nargs': '?' }, {'type': 'outfont'}),
+ ('-i','--anchorinfo',{'help': 'XML file with anchor data'}, {'type': 'infile', 'def': '_anc.xml'}),
+ ('-l','--log',{'help': 'Log file'}, {'type': 'outfile', 'def': '_anc.log'}),
+ ('-a','--analysis',{'help': 'Analysis only; no output font generated', 'action': 'store_true'},{}),
+ # 'choices' for -r should correspond to infont.logger.loglevels.keys()
+ ('-r','--report',{'help': 'Set reporting level for log', 'type':str, 'choices':['X','S','E','P','W','I','V']},{})
+ ]
+
+def doit(args) :
+ infont = args.ifont
+ if args.report: infont.logger.loglevel = args.report
+ glyphcount = 0
+
+ try:
+ for g in ET.parse(args.anchorinfo).getroot().findall('glyph'): ###
+ glyphcount += 1
+ gname = g.get('PSName')
+ if gname not in infont.deflayer.keys():
+ infont.logger.log("glyph element number " + str(glyphcount) + ": " + gname + " not in font, so skipping anchor data", "W")
+ continue
+ # anchors currently in font for this glyph
+ glyph = infont.deflayer[gname]
+ anchorsinfont = set([ ( a.element.get('name'),a.element.get('x'),a.element.get('y') ) for a in glyph['anchor']])
+ # anchors in XML file to be added
+ anchorstoadd = set()
+ for p in g.findall('point'):
+ name = p.get('type')
+ x = p[0].get('x') # assume subelement location is first child
+ y = p[0].get('y')
+ if name and x and y:
+ anchorstoadd.add( (name,x,y) )
+ else:
+ infont.logger.log("Incomplete information for anchor '" + name + "' for glyph " + gname, "E")
+ # compare sets
+ if anchorstoadd == anchorsinfont:
+ if len(anchorstoadd) > 0:
+ infont.logger.log("Anchors in file already in font for glyph " + gname + ": " + str(anchorstoadd), "V")
+ else:
+ infont.logger.log("No anchors in file or in font for glyph " + gname, "V")
+ else:
+ infont.logger.log("Anchors in file for glyph " + gname + ": " + str(anchorstoadd), "I")
+ infont.logger.log("Anchors in font for glyph " + gname + ": " + str(anchorsinfont), "I")
+ for name,x,y in anchorstoadd:
+ # if anchor being added exists in font already, delete it first
+ ancnames = [a.element.get('name') for a in glyph['anchor']]
+ infont.logger.log(str(ancnames), "V") ###
+ if name in ancnames:
+ infont.logger.log("removing anchor " + name + ", index " + str(ancnames.index(name)), "V") ###
+ glyph.remove('anchor', ancnames.index(name))
+ infont.logger.log("adding anchor " + name + ": (" + x + ", " + y + ")", "V") ###
+ glyph.add('anchor', {'name': name, 'x': x, 'y': y})
+ # If analysis only, return without writing output font
+ if args.analysis: return
+ # Return changed font and let execute() write it out
+ return infont
+ except ET.ParseError as mess:
+ infont.logger.log("Error parsing XML input file: " + str(mess), "S")
+ return # but really should terminate after logging Severe error above
+
+def cmd() : execute("UFO",doit,argspec)
+if __name__ == "__main__": cmd()
diff --git a/lib/silfont/scripts/psfbuildcomp.py b/lib/silfont/scripts/psfbuildcomp.py
new file mode 100755
index 0000000..0c5d790
--- /dev/null
+++ b/lib/silfont/scripts/psfbuildcomp.py
@@ -0,0 +1,309 @@
+#!/usr/bin/env python
+__doc__ = '''Read Composite Definitions and add glyphs to a UFO font'''
+__url__ = 'http://github.com/silnrsi/pysilfont'
+__copyright__ = 'Copyright (c) 2015 SIL International (http://www.sil.org)'
+__license__ = 'Released under the MIT License (http://opensource.org/licenses/MIT)'
+__author__ = 'David Rowe'
+
+try:
+ xrange
+except NameError:
+ xrange = range
+from xml.etree import ElementTree as ET
+import re
+from silfont.core import execute
+import silfont.ufo as ufo
+from silfont.comp import CompGlyph
+from silfont.etutil import ETWriter
+from silfont.util import parsecolors
+
+argspec = [
+ ('ifont',{'help': 'Input UFO'}, {'type': 'infont'}),
+ ('ofont',{'help': 'Output UFO','nargs': '?' }, {'type': 'outfont'}),
+ ('-i','--cdfile',{'help': 'Composite Definitions input file'}, {'type': 'infile', 'def': '_CD.txt'}),
+ ('-l','--log',{'help': 'Log file'}, {'type': 'outfile', 'def': '_CD.log'}),
+ ('-a','--analysis',{'help': 'Analysis only; no output font generated', 'action': 'store_true'},{}),
+ ('-c','--color',{'help': 'Color cells of generated glyphs', 'action': 'store_true'},{}),
+ ('--colors', {'help': 'Color(s) to use when marking generated glyphs'},{}),
+ ('-f','--force',{'help': 'Force overwrite of glyphs having outlines', 'action': 'store_true'},{}),
+ ('-n','--noflatten',{'help': 'Do not flatten component references', 'action': 'store_true'},{}),
+ ('--remove',{'help': 'a regex matching anchor names that should always be removed from composites'},{}),
+ ('--preserve', {'help': 'a regex matching anchor names that, if present in glyphs about to be replace, should not be overwritten'}, {})
+ ]
+
+glyphlist = [] # accessed as global by recursive function addtolist() and main function doit()
+
+def doit(args):
+ global glyphlist
+ infont = args.ifont
+ logger = args.logger
+ params = infont.outparams
+
+ removeRE = re.compile(args.remove) if args.remove else None
+ preserveRE = re.compile(args.preserve) if args.preserve else None
+
+ colors = None
+ if args.color or args.colors:
+ colors = args.colors if args.colors else "(0.04,0.57,0.04,1)"
+ colors = parsecolors(colors, allowspecial=True)
+ invalid = False
+ for color in colors:
+ if color[0] is None:
+ invalid = True
+ logger.log(color[2], "E")
+ if len(colors) > 3:
+ logger.log("A maximum of three colors can be supplied: " + str(len(colors)) + " supplied", "E")
+ invalid = True
+ if invalid: logger.log("Re-run with valid colors", "S")
+ if len(colors) == 1: colors.append(colors[0])
+ if len(colors) == 2: colors.append(colors[1])
+ logstatuses = ("Glyph unchanged", "Glyph changed", "New glyph")
+
+ ### temp section (these may someday be passed as optional parameters)
+ RemoveUsedAnchors = True
+ ### end of temp section
+
+ cgobj = CompGlyph()
+
+ for linenum, rawCDline in enumerate(args.cdfile):
+ CDline=rawCDline.strip()
+ if len(CDline) == 0 or CDline[0] == "#": continue
+ logger.log("Processing line " + str(linenum+1) + ": " + CDline,"I")
+ cgobj.CDline=CDline
+ try:
+ cgobj.parsefromCDline()
+ except ValueError as mess:
+ logger.log("Parsing error: " + str(mess), "E")
+ continue
+ g = cgobj.CDelement
+
+ # Collect target glyph information and construct list of component glyphs
+ targetglyphname = g.get("PSName")
+ targetglyphunicode = g.get("UID")
+ glyphlist = [] # list of component glyphs
+ lsb = rsb = 0
+ adv = None
+ for e in g:
+ if e.tag == 'note': pass
+ elif e.tag == 'property': pass # ignore mark info
+ elif e.tag == 'lsb': lsb = int(e.get('width'))
+ elif e.tag == 'rsb': rsb = int(e.get('width'))
+ elif e.tag == 'advance': adv = int(e.get('width'))
+ elif e.tag == 'base':
+ addtolist(e,None)
+ logger.log(str(glyphlist),"V")
+
+ # find each component glyph and compute x,y position
+ xadvance = lsb
+ componentlist = []
+ targetglyphanchors = {} # dictionary of {name: (xOffset,yOffset)}
+ for currglyph, prevglyph, baseAP, diacAP, shiftx, shifty in glyphlist:
+ # get current glyph and its anchor names from font
+ if currglyph not in infont.deflayer:
+ logger.log(currglyph + " not found in font", "E")
+ continue
+ cg = infont.deflayer[currglyph]
+ cganc = [x.element.get('name') for x in cg['anchor']]
+ diacAPx = diacAPy = 0
+ baseAPx = baseAPy = 0
+ if prevglyph is None: # this is new 'base'
+ xOffset = xadvance
+ yOffset = 0
+ # Find advance width of currglyph and add to xadvance
+ if 'advance' in cg:
+ cgadvance = cg['advance']
+ if cgadvance is not None and cgadvance.element.get('width') is not None:
+ xadvance += int(float(cgadvance.element.get('width')))
+ else: # this is 'attach'
+ if diacAP is not None: # find diacritic Attachment Point in currglyph
+ if diacAP not in cganc:
+ logger.log("The AP '" + diacAP + "' does not exist on diacritic glyph " + currglyph, "E")
+ else:
+ i = cganc.index(diacAP)
+ diacAPx = int(float(cg['anchor'][i].element.get('x')))
+ diacAPy = int(float(cg['anchor'][i].element.get('y')))
+ else:
+ logger.log("No AP specified for diacritic " + currglyph, "E")
+ if baseAP is not None: # find base character Attachment Point in targetglyph
+ if baseAP not in targetglyphanchors.keys():
+ logger.log("The AP '" + baseAP + "' does not exist on base glyph when building " + targetglyphname, "E")
+ else:
+ baseAPx = targetglyphanchors[baseAP][0]
+ baseAPy = targetglyphanchors[baseAP][1]
+ if RemoveUsedAnchors:
+ logger.log("Removing used anchor " + baseAP, "V")
+ del targetglyphanchors[baseAP]
+ xOffset = baseAPx - diacAPx
+ yOffset = baseAPy - diacAPy
+
+ if shiftx is not None: xOffset += int(shiftx)
+ if shifty is not None: yOffset += int(shifty)
+
+ componentdic = {'base': currglyph}
+ if xOffset != 0: componentdic['xOffset'] = str(xOffset)
+ if yOffset != 0: componentdic['yOffset'] = str(yOffset)
+ componentlist.append( componentdic )
+
+ # Move anchor information to targetglyphanchors
+ for a in cg['anchor']:
+ dic = a.element.attrib
+ thisanchorname = dic['name']
+ if RemoveUsedAnchors and thisanchorname == diacAP:
+ logger.log("Skipping used anchor " + diacAP, "V")
+ continue # skip this anchor
+ # add anchor (adjusted for position in targetglyph)
+ targetglyphanchors[thisanchorname] = ( int( dic['x'] ) + xOffset, int( dic['y'] ) + yOffset )
+ logger.log("Adding anchor " + thisanchorname + ": " + str(targetglyphanchors[thisanchorname]), "V")
+ logger.log(str(targetglyphanchors),"V")
+
+ if adv is not None:
+ xadvance = adv ### if adv specified, then this advance value overrides calculated value
+ else:
+ xadvance += rsb ### adjust with rsb
+
+ logger.log("Glyph: " + targetglyphname + ", " + str(targetglyphunicode) + ", " + str(xadvance), "V")
+ for c in componentlist:
+ logger.log(str(c), "V")
+
+ # Flatten components unless -n set
+ if not args.noflatten:
+ newcomponentlist = []
+ for compdic in componentlist:
+ c = compdic['base']
+ x = compdic.get('xOffset')
+ y = compdic.get('yOffset')
+ # look up component glyph
+ g=infont.deflayer[c]
+ # check if it has only components (that is, no contours) in outline
+ if g['outline'] and g['outline'].components and not g['outline'].contours:
+ # for each component, get base, x1, y1 and create new entry with base, x+x1, y+y1
+ for subcomp in g['outline'].components:
+ componentdic = subcomp.element.attrib.copy()
+ x1 = componentdic.pop('xOffset', 0)
+ y1 = componentdic.pop('yOffset', 0)
+ xOffset = addtwo(x, x1)
+ yOffset = addtwo(y, y1)
+ if xOffset != 0: componentdic['xOffset'] = str(xOffset)
+ if yOffset != 0: componentdic['yOffset'] = str(yOffset)
+ newcomponentlist.append( componentdic )
+ else:
+ newcomponentlist.append( compdic )
+ if componentlist == newcomponentlist:
+ logger.log("No changes to flatten components", "V")
+ else:
+ componentlist = newcomponentlist
+ logger.log("Components flattened", "V")
+ for c in componentlist:
+ logger.log(str(c), "V")
+
+ # Check if this new glyph exists in the font already; if so, decide whether to replace, or issue warning
+ preservedAPs = set()
+ if targetglyphname in infont.deflayer.keys():
+ logger.log("Target glyph, " + targetglyphname + ", already exists in font.", "V")
+ targetglyph = infont.deflayer[targetglyphname]
+ if targetglyph['outline'] and targetglyph['outline'].contours and not args.force: # don't replace glyph with contours, unless -f set
+ logger.log("Not replacing existing glyph, " + targetglyphname + ", because it has contours.", "W")
+ continue
+ else:
+ logger.log("Replacing information in existing glyph, " + targetglyphname, "I")
+ glyphstatus = "Replace"
+ # delete information from existing glyph
+ targetglyph.remove('outline')
+ targetglyph.remove('advance')
+ for i in xrange(len(targetglyph['anchor'])-1,-1,-1):
+ aname = targetglyph['anchor'][i].element.attrib['name']
+ if preserveRE is not None and preserveRE.match(aname):
+ preservedAPs.add(aname)
+ logger.log("Preserving anchor " + aname, "V")
+ else:
+ targetglyph.remove('anchor',index=i)
+ else:
+ logger.log("Adding new glyph, " + targetglyphname, "I")
+ glyphstatus = "New"
+ # create glyph, using targetglyphname, targetglyphunicode
+ targetglyph = ufo.Uglif(layer=infont.deflayer, name=targetglyphname)
+ # actually add the glyph to the font
+ infont.deflayer.addGlyph(targetglyph)
+
+ if xadvance != 0: targetglyph.add('advance',{'width': str(xadvance)} )
+ if targetglyphunicode: # remove any existing unicode value(s) before adding unicode value
+ for i in xrange(len(targetglyph['unicode'])-1,-1,-1):
+ targetglyph.remove('unicode',index=i)
+ targetglyph.add('unicode',{'hex': targetglyphunicode} )
+ targetglyph.add('outline')
+ # to the outline element, add a component element for every entry in componentlist
+ for compdic in componentlist:
+ comp = ufo.Ucomponent(targetglyph['outline'],ET.Element('component',compdic))
+ targetglyph['outline'].appendobject(comp,'component')
+ # copy anchors to new glyph from targetglyphanchors which has format {'U': (500,1000), 'L': (500,0)}
+ for a in sorted(targetglyphanchors):
+ if removeRE is not None and removeRE.match(a):
+ logger.log("Skipping unwanted anchor " + a, "V")
+ continue # skip this anchor
+ if a not in preservedAPs:
+ targetglyph.add('anchor', {'name': a, 'x': str(targetglyphanchors[a][0]), 'y': str(targetglyphanchors[a][1])} )
+ # mark glyphs as being generated by setting cell mark color if -c or --colors set
+ if colors:
+ # Need to see if the target glyph has changed.
+ if glyphstatus == "Replace":
+ # Need to recreate the xml element then normalize it for comparison with original
+ targetglyph["anchor"].sort(key=lambda anchor: anchor.element.get("name"))
+ targetglyph.rebuildET()
+ attribOrder = params['attribOrders']['glif'] if 'glif' in params['attribOrders'] else {}
+ if params["sortDicts"] or params["precision"] is not None: ufo.normETdata(targetglyph.etree, params, 'glif')
+ etw = ETWriter(targetglyph.etree, attributeOrder=attribOrder, indentIncr=params["indentIncr"],
+ indentFirst=params["indentFirst"], indentML=params["indentML"], precision=params["precision"],
+ floatAttribs=params["floatAttribs"], intAttribs=params["intAttribs"])
+ newxml = etw.serialize_xml()
+ if newxml == targetglyph.inxmlstr: glyphstatus = 'Unchanged'
+
+ x = 0 if glyphstatus == "Unchanged" else 1 if glyphstatus == "Replace" else 2
+
+ color = colors[x]
+ lib = targetglyph["lib"]
+ if color[0]: # Need to set actual color
+ if lib is None: targetglyph.add("lib")
+ targetglyph["lib"].setval("public.markColor", "string", color[0])
+ logger.log(logstatuses[x] + " - setting markColor to " + color[2], "I")
+ elif x < 2: # No need to log for new glyphs
+ if color[1] == "none": # Remove existing color
+ if lib is not None and "public.markColor" in lib: lib.remove("public.markColor")
+ logger.log(logstatuses[x] + " - Removing existing markColor", "I")
+ else:
+ logger.log(logstatuses[x] + " - Leaving existing markColor (if any)", "I")
+
+ # If analysis only, return without writing output font
+ if args.analysis: return
+ # Return changed font and let execute() write it out
+ return infont
+
+def addtolist(e, prevglyph):
+ """Given an element ('base' or 'attach') and the name of previous glyph,
+ add a tuple to the list of glyphs in this composite, including
+ "at" and "with" attachment point information, and x and y shift values
+ """
+ global glyphlist
+ subelementlist = []
+ thisglyphname = e.get('PSName')
+ atvalue = e.get("at")
+ withvalue = e.get("with")
+ shiftx = shifty = None
+ for se in e:
+ if se.tag == 'property': pass
+ elif se.tag == 'shift':
+ shiftx = se.get('x')
+ shifty = se.get('y')
+ elif se.tag == 'attach':
+ subelementlist.append( se )
+ glyphlist.append( ( thisglyphname, prevglyph, atvalue, withvalue, shiftx, shifty ) )
+ for se in subelementlist:
+ addtolist(se, thisglyphname)
+
+def addtwo(a1, a2):
+ """Take two items (string, number or None), convert to integer and return sum"""
+ b1 = int(a1) if a1 is not None else 0
+ b2 = int(a2) if a2 is not None else 0
+ return b1 + b2
+
+def cmd() : execute("UFO",doit,argspec)
+if __name__ == "__main__": cmd()
diff --git a/lib/silfont/scripts/psfbuildcompgc.py b/lib/silfont/scripts/psfbuildcompgc.py
new file mode 100644
index 0000000..e3d0a3e
--- /dev/null
+++ b/lib/silfont/scripts/psfbuildcompgc.py
@@ -0,0 +1,45 @@
+#!/usr/bin/env python3
+'''Uses the GlyphConstruction library to build composite glyphs.'''
+__url__ = 'http://github.com/silnrsi/pysilfont'
+__copyright__ = 'Copyright (c) 2018 SIL International (http://www.sil.org)'
+__license__ = 'Released under the MIT License (http://opensource.org/licenses/MIT)'
+__author__ = 'Victor Gaultney'
+
+from silfont.core import execute
+from glyphConstruction import ParseGlyphConstructionListFromString, GlyphConstructionBuilder
+
+argspec = [
+ ('ifont', {'help': 'Input font filename'}, {'type': 'infont'}),
+ ('ofont',{'help': 'Output font file','nargs': '?' }, {'type': 'outfont'}),
+ ('-i','--cdfile',{'help': 'Composite Definitions input file'}, {'type': 'infile', 'def': 'constructions.txt'}),
+ ('-l','--log',{'help': 'Set log file name'}, {'type': 'outfile', 'def': '_gc.log'})]
+
+def doit(args) :
+ font = args.ifont
+ logger = args.logger
+
+ constructions = ParseGlyphConstructionListFromString(args.cdfile)
+
+ for construction in constructions :
+ # Create a new constructed glyph object
+ try:
+ constructionGlyph = GlyphConstructionBuilder(construction, font)
+ except ValueError as e:
+ logger.log("Invalid CD line '" + construction + "' - " + str(e), "E")
+ else:
+ # Make a new glyph in target font with the new glyph name
+ glyph = font.newGlyph(constructionGlyph.name)
+ # Draw the constructed object onto the new glyph
+ # This is rather odd in how it works
+ constructionGlyph.draw(glyph.getPen())
+ # Copy glyph metadata from constructed object
+ glyph.name = constructionGlyph.name
+ glyph.unicode = constructionGlyph.unicode
+ glyph.note = constructionGlyph.note
+ #glyph.markColor = constructionGlyph.mark
+ glyph.width = constructionGlyph.width
+
+ return font
+
+def cmd() : execute("FP",doit,argspec)
+if __name__ == "__main__": cmd()
diff --git a/lib/silfont/scripts/psfbuildfea.py b/lib/silfont/scripts/psfbuildfea.py
new file mode 100755
index 0000000..41cf099
--- /dev/null
+++ b/lib/silfont/scripts/psfbuildfea.py
@@ -0,0 +1,89 @@
+#!/usr/bin/python3
+__doc__ = 'Build features.fea file into a ttf font'
+# TODO: add conditional compilation, compare to fea, compile to ttf
+__url__ = 'http://github.com/silnrsi/pysilfont'
+__copyright__ = 'Copyright (c) 2017 SIL International (http://www.sil.org)'
+__license__ = 'Released under the MIT License (http://opensource.org/licenses/MIT)'
+__author__ = 'Martin Hosken'
+
+from fontTools.feaLib.builder import Builder
+from fontTools import configLogger
+from fontTools.ttLib import TTFont
+from fontTools.ttLib.tables.otTables import lookupTypes
+from fontTools.feaLib.lookupDebugInfo import LookupDebugInfo
+
+from silfont.core import execute
+
+class MyBuilder(Builder):
+
+ def __init__(self, font, featurefile, lateSortLookups=False, fronts=None):
+ super(MyBuilder, self).__init__(font, featurefile)
+ self.lateSortLookups = lateSortLookups
+ self.fronts = fronts if fronts is not None else []
+
+ def buildLookups_(self, tag):
+ assert tag in ('GPOS', 'GSUB'), tag
+ countFeatureLookups = 0
+ fronts = set([l for k, l in self.named_lookups_.items() if k in self.fronts])
+ for bldr in self.lookups_:
+ bldr.lookup_index = None
+ if bldr.table == tag and getattr(bldr, '_feature', "") != "":
+ countFeatureLookups += 1
+ lookups = []
+ latelookups = []
+ for bldr in self.lookups_:
+ if bldr.table != tag:
+ continue
+ if self.lateSortLookups and getattr(bldr, '_feature', "") == "":
+ if bldr in fronts:
+ latelookups.insert(0, bldr)
+ else:
+ latelookups.append(bldr)
+ else:
+ bldr.lookup_index = len(lookups)
+ lookups.append(bldr)
+ bldr.map_index = bldr.lookup_index
+ numl = len(lookups)
+ for i, l in enumerate(latelookups):
+ l.lookup_index = numl + i
+ l.map_index = l.lookup_index
+ for l in lookups + latelookups:
+ self.lookup_locations[tag][str(l.lookup_index)] = LookupDebugInfo(
+ location=str(l.location),
+ name=self.get_lookup_name_(l),
+ feature=None)
+ return [b.build() for b in lookups + latelookups]
+
+ def add_lookup_to_feature_(self, lookup, feature_name):
+ super(MyBuilder, self).add_lookup_to_feature_(lookup, feature_name)
+ lookup._feature = feature_name
+
+
+#TODO: provide more argument info
+argspec = [
+ ('input_fea', {'help': 'Input fea file'}, {}),
+ ('input_font', {'help': 'Input font file'}, {}),
+ ('-o', '--output', {'help': 'Output font file'}, {}),
+ ('-v', '--verbose', {'help': 'Repeat to increase verbosity', 'action': 'count', 'default': 0}, {}),
+ ('-m', '--lookupmap', {'help': 'File into which place lookup map'}, {}),
+ ('-l','--log',{'help': 'Optional log file'}, {'type': 'outfile', 'def': '_buildfea.log', 'optlog': True}),
+ ('-e','--end',{'help': 'Push lookups not in features to the end', 'action': 'store_true'}, {}),
+ ('-F','--front',{'help': 'Pull named lookups to the front of unnamed list', 'action': 'append'}, {}),
+]
+
+def doit(args) :
+ levels = ["WARNING", "INFO", "DEBUG"]
+ configLogger(level=levels[min(len(levels) - 1, args.verbose)])
+
+ font = TTFont(args.input_font)
+ builder = MyBuilder(font, args.input_fea, lateSortLookups=args.end, fronts=args.front)
+ builder.build()
+ if args.lookupmap:
+ with open(args.lookupmap, "w") as outf:
+ for n, l in sorted(builder.named_lookups_.items()):
+ if l is not None:
+ outf.write("{},{},{}\n".format(n, l.table, l.map_index))
+ font.save(args.output)
+
+def cmd(): execute(None, doit, argspec)
+if __name__ == '__main__': cmd()
diff --git a/lib/silfont/scripts/psfchangegdlnames.py b/lib/silfont/scripts/psfchangegdlnames.py
new file mode 100755
index 0000000..2a10869
--- /dev/null
+++ b/lib/silfont/scripts/psfchangegdlnames.py
@@ -0,0 +1,160 @@
+#!/usr/bin/env python
+__doc__ = '''Change graphite names within GDL based on a csv list in format
+ old name, newname
+ Logs any names not in list
+ Also updates postscript names in postscript() statements based on psnames csv'''
+__url__ = 'http://github.com/silnrsi/pysilfont'
+__copyright__ = 'Copyright (c) 2016 SIL International (http://www.sil.org)'
+__license__ = 'Released under the MIT License (http://opensource.org/licenses/MIT)'
+__author__ = 'David Raymond'
+
+from silfont.core import execute
+import os, re
+
+argspec = [
+ ('input',{'help': 'Input file or folder'}, {'type': 'filename'}),
+ ('output',{'help': 'Output file or folder', 'nargs': '?'}, {}),
+ ('-n','--names',{'help': 'Names csv file'}, {'type': 'incsv', 'def': 'gdlmap.csv'}),
+ ('--names2',{'help': '2nd names csv file', 'nargs': '?'}, {'type': 'incsv', 'def': None}),
+ ('--psnames',{'help': 'PS names csv file'}, {'type': 'incsv', 'def': 'psnames.csv'}),
+ ('-l','--log',{'help': 'Log file'}, {'type': 'outfile', 'def': 'GDLchangeNames.log'})]
+
+def doit(args) :
+ logger = args.paramsobj.logger
+
+ exceptions = ("glyph", "gamma", "greek_circ")
+
+ # Process input which may be a single file or a directory
+ input = args.input
+ gdlfiles = []
+
+ if os.path.isdir(input) :
+ inputisdir = True
+ indir = input
+ for name in os.listdir(input) :
+ ext = os.path.splitext(name)[1]
+ if ext in ('.gdl','.gdh') :
+ gdlfiles.append(name)
+ else :
+ inputisdir = False
+ indir,inname = os.path.split(input)
+ gdlfiles = [inname]
+
+ # Process output file name - execute() will not have processed file/dir name at all
+ output = "" if args.output is None else args.output
+ outdir,outfile = os.path.split(output)
+ if outfile != "" and os.path.splitext(outfile)[1] == "" : # if no extension on outfile, assume a dir was meant
+ outdir = os.path.join(outdir,outfile)
+ outfile = None
+ if outfile == "" : outfile = None
+ if outfile and inputisdir : logger.log("Can't specify an output file when input is a directory", "S")
+ outappend = None
+ if outdir == "" :
+ if outfile is None :
+ outappend = "_out"
+ else :
+ if outfile == gdlfiles[0] : logger.log("Specify a different output file", "S")
+ outdir = indir
+ else:
+ if indir == outdir :
+ if outfile :
+ if outfile == gdlfiles[0] : logger.log("Specify a different output file", "S")
+ else:
+ logger.log("Specify a different output dir", "S")
+ if not os.path.isdir(outdir) : logger.log("Output directory does not exist", "S")
+
+ # Process names csv file
+ args.names.numfields = 2
+ names = {}
+ for line in args.names : names[line[0]] = line[1]
+
+ # Process names2 csv if present
+ names2 = args.names2
+ if names2 is not None :
+ names2.numfields = 2
+ for line in names2 :
+ n1 = line[0]
+ n2 = line[1]
+ if n1 in names and n2 != names[n1] :
+ logger.log(n1 + " in both names and names2 with different values","E")
+ else :
+ names[n1] = n2
+
+ # Process psnames csv file
+ args.psnames.numfields = 2
+ psnames = {}
+ for line in args.psnames : psnames[line[1]] = line[0]
+
+ missed = []
+ psmissed = []
+ for filen in gdlfiles:
+ dbg = True if filen == 'main.gdh' else False ##
+ file = open(os.path.join(indir,filen),"r")
+ if outappend :
+ base,ext = os.path.splitext(filen)
+ outfilen = base+outappend+ext
+ else :
+ outfilen = filen
+ outfile = open(os.path.join(outdir,outfilen),"w")
+ commentblock = False
+ cnt = 0 ##
+ for line in file:
+ cnt += 1 ##
+ #if cnt > 150 : break ##
+ line = line.rstrip()
+ # Skip comment blocks
+ if line[0:2] == "/*" :
+ outfile.write(line + "\n")
+ if line.find("*/") == -1 : commentblock = True
+ continue
+ if commentblock :
+ outfile.write(line + "\n")
+ if line.find("*/") != -1 : commentblock = False
+ continue
+ # Scan for graphite names
+ cpos = line.find("//")
+ if cpos == -1 :
+ scan = line
+ comment = ""
+ else :
+ scan = line[0:cpos]
+ comment = line[cpos:]
+ tmpline = ""
+ while re.search('[\s(\[,]g\w+?[\s)\],?:;=]'," "+scan+" ") :
+ m = re.search('[\s(\[,]g\w+?[\s)\],?:;=]'," "+scan+" ")
+ gname = m.group(0)[1:-1]
+ if gname in names :
+ gname = names[gname]
+ else :
+ if gname not in missed and gname not in exceptions :
+ logger.log(gname + " from '" + line.strip() + "' in " + filen + " missing from csv", "W")
+ missed.append(gname) # only log each missed name once
+ tmpline = tmpline + scan[lastend:m.start()] + gname
+ scan = scan[m.end()-2:]
+ tmpline = tmpline + scan + comment
+
+ # Scan for postscript statements
+ scan = tmpline[0:tmpline.find("//")] if tmpline.find("//") != -1 else tmpline
+ newline = ""
+ lastend = 0
+
+ for m in re.finditer('postscript\(.+?\)',scan) :
+ psname = m.group(0)[12:-2]
+ if psname in psnames :
+ psname = psnames[psname]
+ else :
+ if psname not in psmissed :
+ logger.log(psname + " from '" + line.strip() + "' in " + filen + " missing from ps csv", "W")
+ psmissed.append(psname) # only log each missed name once
+ newline = newline + scan[lastend:m.start()+12] + psname
+ lastend = m.end()-2
+
+ newline = newline + tmpline[lastend:]
+ outfile.write(newline + "\n")
+ file.close()
+ outfile.close()
+ if missed != [] : logger.log("Names were missed from the csv file - see log file for details","E")
+ return
+
+def cmd() : execute(None,doit,argspec)
+if __name__ == "__main__": cmd()
diff --git a/lib/silfont/scripts/psfchangettfglyphnames.py b/lib/silfont/scripts/psfchangettfglyphnames.py
new file mode 100644
index 0000000..2c9fa37
--- /dev/null
+++ b/lib/silfont/scripts/psfchangettfglyphnames.py
@@ -0,0 +1,35 @@
+#!/usr/bin/env python
+__doc__ = 'Rename the glyphs in a ttf file based on production names in a UFO'
+__url__ = 'http://github.com/silnrsi/pysilfont'
+__copyright__ = 'Copyright (c) 2017 SIL International (http://www.sil.org)'
+__license__ = 'Released under the MIT License (http://opensource.org/licenses/MIT)'
+__author__ = 'Alan Ward'
+
+# Rename the glyphs in a ttf file based on production names in a UFO
+# using same technique as fontmake.
+# Production names come from ufo.lib.public.postscriptNames according to ufo2ft comments
+# but I don't know exactly where in the UFO that is
+
+from silfont.core import execute
+import defcon, fontTools.ttLib, ufo2ft
+
+argspec = [
+ ('iufo', {'help': 'Input UFO folder'}, {}),
+ ('ittf', {'help': 'Input ttf file name'}, {}),
+ ('ottf', {'help': 'Output ttf file name'}, {})]
+
+def doit(args):
+ ufo = defcon.Font(args.iufo)
+ ttf = fontTools.ttLib.TTFont(args.ittf)
+
+ args.logger.log('Renaming the input ttf glyphs based on production names in the UFO', 'P')
+ postProcessor = ufo2ft.PostProcessor(ttf, ufo)
+ ttf = postProcessor.process(useProductionNames=True, optimizeCFF=False)
+
+ args.logger.log('Saving the output ttf file', 'P')
+ ttf.save(args.ottf)
+
+ args.logger.log('Done', 'P')
+
+def cmd(): execute(None, doit, argspec)
+if __name__ == '__main__': cmd()
diff --git a/lib/silfont/scripts/psfcheckbasicchars.py b/lib/silfont/scripts/psfcheckbasicchars.py
new file mode 100644
index 0000000..c86beac
--- /dev/null
+++ b/lib/silfont/scripts/psfcheckbasicchars.py
@@ -0,0 +1,68 @@
+#!/usr/bin/env python
+__doc__ = '''Checks a UFO for the presence of glyphs that represent the
+Recommended characters for Non-Roman fonts and warns if any are missing.
+http://scriptsource.org/entry/gg5wm9hhd3'''
+__url__ = 'http://github.com/silnrsi/pysilfont'
+__copyright__ = 'Copyright (c) 2018 SIL International (http://www.sil.org)'
+__license__ = 'Released under the MIT License (http://opensource.org/licenses/MIT)'
+__author__ = 'Victor Gaultney'
+
+from silfont.core import execute
+from silfont.util import required_chars
+
+argspec = [
+ ('ifont',{'help': 'Input font file'}, {'type': 'infont'}),
+ ('-r', '--rtl', {'help': 'Also include characters just for RTL scripts', 'action': 'store_true'}, {}),
+ ('-s', '--silpua', {'help': 'Also include characters in SIL PUA block', 'action': 'store_true'}, {}),
+ ('-l','--log',{'help': 'Log file'}, {'type': 'outfile', 'def': '_checkbasicchars.log'})]
+
+def doit(args) :
+ font = args.ifont
+ logger = args.logger
+
+ rationales = {
+ "A": "in Codepage 1252",
+ "B": "in MacRoman",
+ "C": "for publishing",
+ "D": "for Non-Roman fonts and publishing",
+ "E": "by Google Fonts",
+ "F": "by TeX for visible space",
+ "G": "for encoding conversion utilities",
+ "H": "in case Variation Sequences are defined in future",
+ "I": "to detect byte order",
+ "J": "to render combining marks in isolation",
+ "K": "to view sidebearings for every glyph using these characters"}
+
+ charsets = ["basic"]
+ if args.rtl: charsets.append("rtl")
+ if args.silpua: charsets.append("sil")
+
+ req_chars = required_chars(charsets)
+
+ glyphlist = font.deflayer.keys()
+
+ for glyphn in glyphlist :
+ glyph = font.deflayer[glyphn]
+ if len(glyph["unicode"]) == 1 :
+ unival = glyph["unicode"][0].hex
+ if unival in req_chars:
+ del req_chars[unival]
+
+ cnt = len(req_chars)
+ if cnt > 0:
+ for usv in sorted(req_chars.keys()):
+ item = req_chars[usv]
+ psname = item["ps_name"]
+ gname = item["glyph_name"]
+ name = psname if psname == gname else psname + ", " + gname
+ logger.log("U+" + usv + " from the " + item["sil_set"] +
+ " set has no representative glyph (" + name + ")", "W")
+ logger.log("Rationale: This character is needed " + rationales[item["rationale"]], "I")
+ if item["notes"]:
+ logger.log(item["notes"], "I")
+ logger.log("There are " + str(cnt) + " required characters missing", "E")
+
+ return
+
+def cmd() : execute("UFO",doit,argspec)
+if __name__ == "__main__": cmd()
diff --git a/lib/silfont/scripts/psfcheckclassorders.py b/lib/silfont/scripts/psfcheckclassorders.py
new file mode 100644
index 0000000..12654c9
--- /dev/null
+++ b/lib/silfont/scripts/psfcheckclassorders.py
@@ -0,0 +1,142 @@
+#!/usr/bin/env python3
+'''verify classes defined in xml have correct ordering where needed
+
+Looks for comment lines in the classes.xml file that match the string:
+ *NEXT n CLASSES MUST MATCH*
+where n is the number of upcoming class definitions that must result in the
+same glyph alignment when glyph names are sorted by TTF order (as described
+in the glyph_data.csv file).
+'''
+__url__ = 'http://github.com/silnrsi/pysilfont'
+__copyright__ = 'Copyright (c) 2019 SIL International (http://www.sil.org)'
+__license__ = 'Released under the MIT License (http://opensource.org/licenses/MIT)'
+__author__ = 'Bob Hallissy'
+
+import re
+import types
+from xml.etree import ElementTree as ET
+from silfont.core import execute
+
+argspec = [
+ ('classes', {'help': 'class definition in XML format', 'nargs': '?', 'default': 'classes.xml'}, {'type': 'infile'}),
+ ('glyphdata', {'help': 'Glyph info csv file', 'nargs': '?', 'default': 'glyph_data.csv'}, {'type': 'incsv'}),
+ ('--gname', {'help': 'Column header for glyph name', 'default': 'glyph_name'}, {}),
+ ('--sort', {'help': 'Column header(s) for sort order', 'default': 'sort_final'}, {}),
+]
+
+# Dictionary of glyphName : sortValue
+sorts = dict()
+
+# Keep track of glyphs mentioned in classes but not in glyph_data.csv
+missingGlyphs = set()
+
+def doit(args):
+ logger = args.logger
+
+ # Read input csv to get glyph sort order
+ incsv = args.glyphdata
+ fl = incsv.firstline
+ if fl is None: logger.log("Empty input file", "S")
+ if args.gname in fl:
+ glyphnpos = fl.index(args.gname)
+ else:
+ logger.log("No" + args.gname + "field in csv headers", "S")
+ if args.sort in fl:
+ sortpos = fl.index(args.sort)
+ else:
+ logger.log('No "' + args.sort + '" heading in csv headers"', "S")
+ next(incsv.reader, None) # Skip first line with containing headers
+ for line in incsv:
+ glyphn = line[glyphnpos]
+ if len(glyphn) == 0:
+ continue # No need to include cases where name is blank
+ sorts[glyphn] = float(line[sortpos])
+
+ # RegEx we are looking for in comments
+ matchCountRE = re.compile("\*NEXT ([1-9]\d*) CLASSES MUST MATCH\*")
+
+ # parse classes.xml but include comments
+ class MyTreeBuilder(ET.TreeBuilder):
+ def comment(self, data):
+ res = matchCountRE.search(data)
+ if res:
+ # record the count of classes that must match
+ self.start(ET.Comment, {})
+ self.data(res.group(1))
+ self.end(ET.Comment)
+ doc = ET.parse(args.classes, parser=ET.XMLParser(target=MyTreeBuilder())).getroot()
+
+ # process results looking for both class elements and specially formatted comments
+ matchCount = 0
+ refClassList = None
+ refClassName = None
+
+ for child in doc:
+ if isinstance(child.tag, types.FunctionType):
+ # Special type used for comments
+ if matchCount > 0:
+ logger.log("Unexpected match request '{}': matching {} is not yet complete".format(child.text, refClassName), "E")
+ ref = None
+ matchCount = int(child.text)
+ # print "Match count = {}".format(matchCount)
+
+ elif child.tag == 'class':
+ l = orderClass(child, logger) # Do this so we record classes whether we match them or not.
+ if matchCount > 0:
+ matchCount -= 1
+ className = child.attrib['name']
+ if refClassName is None:
+ refClassList = l
+ refLen = len(refClassList)
+ refClassName = className
+ else:
+ # compare ref list and l
+ if len(l) != refLen:
+ logger.log("Class {} (length {}) and {} (length {}) have unequal length".format(refClassName, refLen, className, len(l)), "E")
+ else:
+ errCount = 0
+ for i in range(refLen):
+ if l[i][0] != refClassList[i][0]:
+ logger.log ("Class {} and {} inconsistent order glyphs {} and {}".format(refClassName, className, refClassList[i][2], l[i][2]), "E")
+ errCount += 1
+ if errCount > 5:
+ logger.log ("Abandoning compare between Classes {} and {}".format(refClassName, className), "E")
+ break
+ if matchCount == 0:
+ refClassName = None
+
+ # List glyphs mentioned in classes.xml but not present in glyph_data:
+ if len(missingGlyphs):
+ logger.log('Glyphs mentioned in classes.xml but not present in glyph_data: ' + ', '.join(sorted(missingGlyphs)), 'W')
+
+
+classes = {} # Keep record of all classes we've seen so we can flatten references
+
+def orderClass(classElement, logger):
+ # returns a list of tuples, each containing (indexWithinClass, sortOrder, glyphName)
+ # list is sorted by sortOrder
+ glyphList = classElement.text.split()
+ res = []
+ for i in range(len(glyphList)):
+ token = glyphList[i]
+ if token.startswith('@'):
+ # Nested class
+ cname = token[1:]
+ if cname in classes:
+ res.extend(classes[cname])
+ else:
+ logger.log("Invalid fea: class {} referenced before being defined".format(cname),"S")
+ else:
+ # simple glyph name -- make sure it is in glyph_data:
+ if token in sorts:
+ res.append((i, sorts[token], token))
+ else:
+ missingGlyphs.add(token)
+
+ classes[classElement.attrib['name']] = res
+ return sorted(res, key=lambda x: x[1])
+
+
+
+def cmd() : execute(None,doit,argspec)
+if __name__ == "__main__": cmd()
diff --git a/lib/silfont/scripts/psfcheckftml.py b/lib/silfont/scripts/psfcheckftml.py
new file mode 100644
index 0000000..84df95f
--- /dev/null
+++ b/lib/silfont/scripts/psfcheckftml.py
@@ -0,0 +1,65 @@
+#!/usr/bin/env python
+'''Test structural integrity of one or more ftml files
+
+Assumes ftml files have already validated against FTML.dtd, for example by using:
+ xmllint --noout --dtdvalid FTML.dtd inftml.ftml
+
+Verifies that:
+ - silfont.ftml can parse the file
+ - every stylename is defined the <styles> list '''
+__url__ = 'http://github.com/silnrsi/pysilfont'
+__copyright__ = 'Copyright (c) 2021 SIL International (http://www.sil.org)'
+__license__ = 'Released under the MIT License (http://opensource.org/licenses/MIT)'
+__author__ = 'Bob Hallissy'
+
+import glob
+from silfont.ftml import Fxml, Ftest
+from silfont.core import execute
+
+argspec = [
+ ('inftml', {'help': 'Input ftml filename pattern (default: *.ftml) ', 'nargs' : '?', 'default' : '*.ftml'}, {}),
+]
+
+def doit(args):
+ logger = args.logger
+ fnames = glob.glob(args.inftml)
+ if len(fnames) == 0:
+ logger.log(f'No files matching "{args.inftml}" found.','E')
+ for fname in glob.glob(args.inftml):
+ logger.log(f'checking {fname}', 'P')
+ unknownStyles = set()
+ usedStyles = set()
+
+ # recursively find and check all <test> elements in a <testsgroup>
+ def checktestgroup(testgroup):
+ for test in testgroup.tests:
+ # Not sure why, but sub-testgroups are also included in tests, so filter those out for now
+ if isinstance(test, Ftest) and test.stylename:
+ sname = test.stylename
+ usedStyles.add(sname)
+ if sname is not None and sname not in unknownStyles and \
+ not (hasStyles and sname in ftml.head.styles):
+ logger.log(f' stylename "{sname}" not defined in head/styles', 'E')
+ unknownStyles.add(sname)
+ # recurse to nested testgroups if any:
+ if testgroup.testgroups is not None:
+ for subgroup in testgroup.testgroups:
+ checktestgroup(subgroup)
+
+ with open(fname,encoding='utf8') as f:
+ # Attempt to parse the ftml file
+ ftml = Fxml(f)
+ hasStyles = ftml.head.styles is not None # Whether or not any styles are defined in head element
+
+ # Look through all tests for undefined styles:
+ for testgroup in ftml.testgroups:
+ checktestgroup(testgroup)
+
+ if hasStyles:
+ # look for unused styles:
+ for style in ftml.head.styles:
+ if style not in usedStyles:
+ logger.log(f' defined style "{style}" not used in any test', 'W')
+
+def cmd() : execute(None,doit, argspec)
+if __name__ == "__main__": cmd()
diff --git a/lib/silfont/scripts/psfcheckglyphinventory.py b/lib/silfont/scripts/psfcheckglyphinventory.py
new file mode 100644
index 0000000..37a5ffc
--- /dev/null
+++ b/lib/silfont/scripts/psfcheckglyphinventory.py
@@ -0,0 +1,125 @@
+#!/usr/bin/env python
+__doc__ = '''Warn for differences in glyph inventory and encoding between UFO and input file (e.g., glyph_data.csv).
+Input file can be:
+ - simple text file with one glyph name per line
+ - csv file with headers, using headers "glyph_name" and, if present, "USV"'''
+__url__ = 'http://github.com/silnrsi/pysilfont'
+__copyright__ = 'Copyright (c) 2020 SIL International (http://www.sil.org)'
+__license__ = 'Released under the MIT License (http://opensource.org/licenses/MIT)'
+__author__ = 'Bob Hallissy'
+
+from silfont.core import execute
+
+argspec = [
+ ('ifont', {'help': 'Input UFO'}, {'type': 'infont'}),
+ ('-i', '--input', {'help': 'Input text file, default glyph_data.csv in current directory', 'default': 'glyph_data.csv'}, {'type': 'incsv'}),
+ ('--indent', {'help': 'size of indent (default 10)', 'type': int, 'default': 10}, {}),
+ ('-l', '--log', {'help': 'Log file'}, {'type': 'outfile', 'def': '_checkinventory.log'})]
+
+def doit(args):
+ font = args.ifont
+ incsv = args.input
+ logger = args.logger
+ indent = ' '*args.indent
+
+ if not (args.quiet or 'scrlevel' in args.paramsobj.sets['command line']):
+ logger.raisescrlevel('W') # Raise level to W if not already W or higher
+
+ def csvWarning(msg, exception=None):
+ m = f'glyph_data line {incsv.line_num}: {msg}'
+ if exception is not None:
+ m += '; ' + exception.message
+ logger.log(m, 'W')
+
+ # Get glyph names and encoding from input file
+ glyphFromCSVuid = {}
+ uidFromCSVglyph = {}
+
+ # Identify file format (plain text or csv) from first line
+ # If csv file, it must have headers for "glyph_name" and "USV"
+ fl = incsv.firstline
+ if fl is None: logger.log('Empty input file', 'S')
+ numfields = len(fl)
+ incsv.numfields = numfields
+ usvCol = None # Use this as a flag later to determine whether to check USV inventory
+ if numfields > 1: # More than 1 column, so must have headers
+ # Required columns:
+ try:
+ nameCol = fl.index('glyph_name');
+ except ValueError as e:
+ logger.log('Missing csv input field: ' + e.message, 'S')
+ except Exception as e:
+ logger.log('Error reading csv input field: ' + e.message, 'S')
+ # Optional columns:
+ usvCol = fl.index('USV') if 'USV' in fl else None
+
+ next(incsv.reader, None) # Skip first line with headers in
+
+ glyphList = set()
+ for line in incsv:
+ gname = line[nameCol]
+ if len(gname) == 0 or line[0].strip().startswith('#'):
+ continue # No need to include cases where name is blank or comment
+ glyphList.add(gname)
+
+ # Process USV
+ # could be empty string, a single USV or space-separated list of USVs
+ try:
+ uidList = [int(x, 16) for x in line[usvCol].split()]
+ except Exception as e:
+ csvWarning("invalid USV '%s' (%s); ignored: " % (line[usvCol], e.message))
+ uidList = []
+ if len(uidList) == 1:
+ # Handle simple encoded glyphs
+ uid = uidList[0]
+ if uid in glyphFromCSVuid:
+ csvWarning('USV %04X previously seen; ignored' % uid)
+ uidList = []
+ else:
+ # Remember this glyph
+ glyphFromCSVuid[uid] = gname
+ uidFromCSVglyph[gname] = uid
+ elif numfields == 1: # Simple text file.
+ glyphList = set(line[0] for line in incsv)
+ else:
+ logger.log('Invalid csv file', 'S')
+
+ # Get the list of glyphs in the UFO
+ ufoList = set(font.deflayer.keys())
+
+ notInUFO = glyphList - ufoList
+ notInGlyphData = ufoList - glyphList
+
+ if len(notInUFO):
+ logger.log('Glyphs present in glyph_data but missing from UFO:\n' + '\n'.join(indent + g for g in sorted(notInUFO)), 'W')
+
+ if len(notInGlyphData):
+ logger.log('Glyphs present in UFO but missing from glyph_data:\n' + '\n'.join(indent + g for g in sorted(notInGlyphData)), 'W')
+
+ if len(notInUFO) == 0 and len(notInGlyphData) == 0:
+ logger.log('No glyph inventory differences found', 'P')
+
+ if usvCol:
+ # We cam check USV inventory of glyphs in common
+ inBoth = glyphList & ufoList # Glyphs we want to examine
+ csvEncodings = set(f'{gname}|{uidFromCSVglyph[gname]:04X}' for gname in filter(lambda x: x in uidFromCSVglyph, inBoth))
+ ufoEncodings = set(f'{gname}|{int(x.hex, 16):04X}' for gname in inBoth for x in font.deflayer[gname]['unicode'])
+
+ notInUFO = csvEncodings - ufoEncodings
+ notInGlyphData = ufoEncodings - csvEncodings
+
+ if len(notInUFO):
+ logger.log('Encodings present in glyph_data but missing from UFO:\n' + '\n'.join(indent + g for g in sorted(notInUFO)), 'W')
+
+ if len(notInGlyphData):
+ logger.log('Encodings present in UFO but missing from glyph_data:\n' + '\n'.join(indent + g for g in sorted(notInGlyphData)), 'W')
+
+ if len(notInUFO) == 0 and len(notInGlyphData) == 0:
+ logger.log('No glyph encoding differences found', 'P')
+
+ else:
+ logger.log('Glyph encodings not compared', 'P')
+
+
+def cmd(): execute('UFO', doit, argspec)
+if __name__ == '__main__': cmd()
diff --git a/lib/silfont/scripts/psfcheckinterpolatable.py b/lib/silfont/scripts/psfcheckinterpolatable.py
new file mode 100644
index 0000000..abcf526
--- /dev/null
+++ b/lib/silfont/scripts/psfcheckinterpolatable.py
@@ -0,0 +1,75 @@
+#!/usr/bin/env python
+__doc__ = '''Check that the ufos in a designspace file are interpolatable'''
+__url__ = 'http://github.com/silnrsi/pysilfont'
+__copyright__ = 'Copyright (c) 2021 SIL International (http://www.sil.org)'
+__license__ = 'Released under the MIT License (http://opensource.org/licenses/MIT)'
+__author__ = 'David Raymond'
+
+from silfont.core import execute
+from fontParts.world import OpenFont
+import fontTools.designspaceLib as DSD
+
+argspec = [
+ ('designspace', {'help': 'Design space file'}, {'type': 'filename'}),
+ ('-l','--log', {'help': 'Log file'}, {'type': 'outfile', 'def': '_checkinterp.log'}),
+ ]
+
+def doit(args) :
+ logger = args.logger
+
+ ds = DSD.DesignSpaceDocument()
+ ds.read(args.designspace)
+ if len(ds.sources) == 1: logger.log("The design space file has only one source UFO", "S")
+
+ # Find all the UFOs from the DS Sources. Where there are more than 2, the primary one will be considered to be
+ # the one where info copy="1" is set (as per psfsyncmasters). If not set for any, use the first ufo.
+ pufo = None
+ otherfonts = {}
+ for source in ds.sources:
+ ufo = source.path
+ try:
+ font = OpenFont(ufo)
+ except Exception as e:
+ logger.log("Unable to open " + ufo, "S")
+ if source.copyInfo:
+ if pufo: logger.log('Multiple fonts with <info copy="1" />', "S")
+ pufo = ufo
+ pfont = font
+ else:
+ otherfonts[ufo] = font
+ if pufo is None: # If we can't identify the primary font by conyInfo, just use the first one
+ pufo = ds.sources[0].path
+ pfont = otherfonts[pufo]
+ del otherfonts[pufo]
+
+ pinventory = set(glyph.name for glyph in pfont)
+
+ for oufo in otherfonts:
+ logger.log(f'Comparing {pufo} with {oufo}', 'P')
+ ofont = otherfonts[oufo]
+ oinventory = set(glyph.name for glyph in ofont)
+
+ if pinventory != oinventory:
+ logger.log("The glyph inventories in the two UFOs differ", "E")
+ for glyphn in sorted(pinventory - oinventory):
+ logger.log(f'{glyphn} is only in {pufo}', "W")
+ for glyphn in sorted(oinventory - pinventory):
+ logger.log(f'{glyphn} is only in {oufo}', "W")
+ else:
+ logger.log("The UFOs have the same glyph inventories", "P")
+ # Are glyphs compatible for interpolation
+ incompatibles = {}
+ for glyphn in pinventory & oinventory:
+ compatible, report = pfont[glyphn].isCompatible(ofont[glyphn])
+ if not compatible: incompatibles[glyphn] = report
+ if incompatibles:
+ logger.log(f'{len(incompatibles)} glyphs are not interpolatable', 'E')
+ for glyphn in sorted(incompatibles):
+ logger.log(f'{glyphn} is not interpolatable', 'W')
+ logger.log(incompatibles[glyphn], "I")
+ if logger.scrlevel == "W": logger.log("To see detailed reports run with scrlevel and/or loglevel set to I")
+ else:
+ logger.log("All the glyphs are interpolatable", "P")
+
+def cmd() : execute(None,doit, argspec)
+if __name__ == "__main__": cmd()
diff --git a/lib/silfont/scripts/psfcompdef2xml.py b/lib/silfont/scripts/psfcompdef2xml.py
new file mode 100755
index 0000000..62f9972
--- /dev/null
+++ b/lib/silfont/scripts/psfcompdef2xml.py
@@ -0,0 +1,65 @@
+#!/usr/bin/env python
+__doc__ = 'convert composite definition file to XML format'
+__url__ = 'http://github.com/silnrsi/pysilfont'
+__copyright__ = 'Copyright (c) 2015 SIL International (http://www.sil.org)'
+__license__ = 'Released under the MIT License (http://opensource.org/licenses/MIT)'
+__author__ = 'David Rowe'
+
+from silfont.core import execute
+from silfont.etutil import ETWriter
+from silfont.comp import CompGlyph
+from xml.etree import ElementTree as ET
+
+# specify three parameters: input file (single line format), output file (XML format), log file
+# and optional -p indentFirst " " -p indentIncr " " -p "PSName,UID,with,at,x,y" for XML formatting.
+argspec = [
+ ('input',{'help': 'Input file of CD in single line format'}, {'type': 'infile'}),
+ ('output',{'help': 'Output file of CD in XML format'}, {'type': 'outfile', 'def': '_out.xml'}),
+ ('log',{'help': 'Log file'},{'type': 'outfile', 'def': '_log.txt'}),
+ ('-p','--params',{'help': 'XML formatting parameters: indentFirst, indentIncr, attOrder','action': 'append'}, {'type': 'optiondict'})]
+
+def doit(args) :
+ ofile = args.output
+ lfile = args.log
+ filelinecount = 0
+ linecount = 0
+ elementcount = 0
+ cgobj = CompGlyph()
+ f = ET.Element('font')
+ for line in args.input.readlines():
+ filelinecount += 1
+ testline = line.strip()
+ if len(testline) > 0 and testline[0:1] != '#': # not whitespace or comment
+ linecount += 1
+ cgobj.CDline=line
+ cgobj.CDelement=None
+ try:
+ cgobj.parsefromCDline()
+ if cgobj.CDelement != None:
+ f.append(cgobj.CDelement)
+ elementcount += 1
+ except ValueError as e:
+ lfile.write("Line "+str(filelinecount)+": "+str(e)+'\n')
+ if linecount != elementcount:
+ lfile.write("Lines read from input file: " + str(filelinecount)+'\n')
+ lfile.write("Lines parsed (excluding blank and comment lines): " + str(linecount)+'\n')
+ lfile.write("Valid glyphs found: " + str(elementcount)+'\n')
+# instead of simple serialization with: ofile.write(ET.tostring(f))
+# create ETWriter object and specify indentation and attribute order to get normalized output
+ indentFirst = " "
+ indentIncr = " "
+ attOrder = "PSName,UID,with,at,x,y"
+ for k in args.params:
+ if k == 'indentIncr': indentIncr = args.params['indentIncr']
+ elif k == 'indentFirst': indentFirst = args.params['indentFirst']
+ elif k == 'attOrder': attOrder = args.params['attOrder']
+ x = attOrder.split(',')
+ attributeOrder = dict(zip(x,range(len(x))))
+ etwobj=ETWriter(f, indentFirst=indentFirst, indentIncr=indentIncr, attributeOrder=attributeOrder)
+ ofile.write(etwobj.serialize_xml())
+
+ return
+
+def cmd() : execute(None,doit,argspec)
+if __name__ == "__main__": cmd()
+
diff --git a/lib/silfont/scripts/psfcompressgr.py b/lib/silfont/scripts/psfcompressgr.py
new file mode 100755
index 0000000..5802cce
--- /dev/null
+++ b/lib/silfont/scripts/psfcompressgr.py
@@ -0,0 +1,100 @@
+#!/usr/bin/env python
+__doc__ = 'Compress Graphite tables in a font'
+__url__ = 'http://github.com/silnrsi/pysilfont'
+__copyright__ = 'Copyright (c) 2017 SIL International (http://www.sil.org)'
+__license__ = 'Released under the MIT License (http://opensource.org/licenses/MIT)'
+__author__ = 'Martin Hosken'
+
+argspec = [
+ ('ifont',{'help': 'Input TTF'}, {'type': 'infont'}),
+ ('ofont',{'help': 'Output TTF','nargs': '?' }, {'type': 'outfont'}),
+ ('-l','--log',{'help': 'Optional log file'}, {'type': 'outfile', 'def': '_compressgr', 'optlog': True})
+]
+
+from silfont.core import execute
+from fontTools.ttLib.tables.DefaultTable import DefaultTable
+import lz4.block
+import sys, struct
+
+class lz4tuple(object) :
+ def __init__(self, start) :
+ self.start = start
+ self.literal = start
+ self.literal_len = 0
+ self.match_dist = 0
+ self.match_len = 0
+ self.end = 0
+
+ def __str__(self) :
+ return "lz4tuple(@{},{}+{},-{}+{})={}".format(self.start, self.literal, self.literal_len, self.match_dist, self.match_len, self.end)
+
+def read_literal(t, dat, start, datlen) :
+ if t == 15 and start < datlen :
+ v = ord(dat[start:start+1])
+ t += v
+ while v == 0xFF and start < datlen :
+ start += 1
+ v = ord(dat[start:start+1])
+ t += v
+ start += 1
+ return (t, start)
+
+def write_literal(num, shift) :
+ res = []
+ if num > 14 :
+ res.append(15 << shift)
+ num -= 15
+ while num > 255 :
+ res.append(255)
+ num -= 255
+ res.append(num)
+ else :
+ res.append(num << shift)
+ return bytearray(res)
+
+def parseTuple(dat, start, datlen) :
+ res = lz4tuple(start)
+ token = ord(dat[start:start+1])
+ (res.literal_len, start) = read_literal(token >> 4, dat, start+1, datlen)
+ res.literal = start
+ start += res.literal_len
+ res.end = start
+ if start > datlen - 2 :
+ return res
+ res.match_dist = ord(dat[start:start+1]) + (ord(dat[start+1:start+2]) << 8)
+ start += 2
+ (res.match_len, start) = read_literal(token & 0xF, dat, start, datlen)
+ res.end = start
+ return res
+
+def compressGr(dat, version) :
+ if ord(dat[1:2]) < version :
+ vstr = bytes([version]) if sys.version_info.major > 2 else chr(version)
+ dat = dat[0:1] + vstr + dat[2:]
+ datc = lz4.block.compress(dat[:-4], mode='high_compression', compression=16, store_size=False)
+ # now find the final tuple
+ end = len(datc)
+ start = 0
+ curr = lz4tuple(start)
+ while curr.end < end :
+ start = curr.end
+ curr = parseTuple(datc, start, end)
+ if curr.end > end :
+ print("Sync error: {!s}".format(curr))
+ newend = write_literal(curr.literal_len + 4, 4) + datc[curr.literal:curr.literal+curr.literal_len+1] + dat[-4:]
+ lz4hdr = struct.pack(">L", (1 << 27) + (len(dat) & 0x7FFFFFF))
+ return dat[0:4] + lz4hdr + datc[0:curr.start] + newend
+
+def doit(args) :
+ infont = args.ifont
+ for tag, version in (('Silf', 5), ('Glat', 3)) :
+ dat = infont.getTableData(tag)
+ newdat = bytes(compressGr(dat, version))
+ table = DefaultTable(tag)
+ table.decompile(newdat, infont)
+ infont[tag] = table
+ return infont
+
+def cmd() : execute('FT', doit, argspec)
+if __name__ == "__main__" : cmd()
+
diff --git a/lib/silfont/scripts/psfcopyglyphs.py b/lib/silfont/scripts/psfcopyglyphs.py
new file mode 100644
index 0000000..fe37bf7
--- /dev/null
+++ b/lib/silfont/scripts/psfcopyglyphs.py
@@ -0,0 +1,243 @@
+#!/usr/bin/env python
+__doc__ = """Copy glyphs from one UFO to another"""
+__url__ = 'http://github.com/silnrsi/pysilfont'
+__copyright__ = 'Copyright (c) 2018 SIL International (http://www.sil.org)'
+__license__ = 'Released under the MIT License (http://opensource.org/licenses/MIT)'
+__author__ = 'Bob Hallissy'
+
+from xml.etree import ElementTree as ET
+from silfont.core import execute
+from silfont.ufo import makeFileName, Uglif
+import re
+
+argspec = [
+ ('ifont',{'help': 'Input font file'}, {'type': 'infont'}),
+ ('ofont',{'help': 'Output font file','nargs': '?' }, {'type': 'outfont'}),
+ ('-s','--source',{'help': 'Font to get glyphs from'}, {'type': 'infont'}),
+ ('-i','--input',{'help': 'Input csv file'}, {'type': 'incsv', 'def': 'glyphlist.csv'}),
+ ('-f','--force',{'help' : 'Overwrite existing glyphs in the font', 'action' : 'store_true'}, {}),
+ ('-l','--log',{'help': 'Set log file name'}, {'type': 'outfile', 'def': '_copy.log'}),
+ ('-n', '--name', {'help': 'Include glyph named name', 'action': 'append'}, {}),
+ ('--rename',{'help' : 'Rename glyphs to names in this column'}, {}),
+ ('--unicode', {'help': 'Re-encode glyphs to USVs in this column'}, {}),
+ ('--scale',{'type' : float, 'help' : 'Scale glyphs by this factor'}, {})
+]
+
+class Glyph:
+ """details about a glyph we have, or need to, copy; mostly just for syntactic sugar"""
+
+ # Glyphs that are used *only* as component glyphs may have to be renamed if there already exists a glyph
+ # by the same name in the target font. we compute a new name by appending .copy1, .copy2, etc until we get a
+ # unique name. We keep track of the mapping from source font glyphname to target font glyphname using a dictionary.
+ # For ease of use, glyphs named by the input file (which won't have their names changed, see --force) will also
+ # be added to this dictionary because they can also be used as components.
+ nameMap = dict()
+
+ def __init__(self, oldname, newname="", psname="", dusv=None):
+ self.oldname = oldname
+ self.newname = newname or oldname
+ self.psname = psname or None
+ self.dusv = dusv or None
+ # Keep track of old-to-new name mapping
+ Glyph.nameMap[oldname] = self.newname
+
+
+# Mapping from decimal USV to glyphname in target font
+dusv2gname = None
+
+# RE for parsing glyph names and peeling off the .copyX if present in order to search for a unique name to use:
+gcopyRE = re.compile(r'(^.+?)(?:\.copy(\d+))?$')
+
+
+def copyglyph(sfont, tfont, g, args):
+ """copy glyph from source font to target font"""
+ # Generally, 't' variables are target, 's' are source. E.g., tfont is target font.
+
+ global dusv2gname
+ if not dusv2gname:
+ # Create mappings to find exsting glyph name from decimal usv:
+ dusv2gname = {int(unicode.hex, 16): gname for gname in tfont.deflayer for unicode in tfont.deflayer[gname]['unicode']}
+ # NB: Assumes font is well-formed and has at most one glyph with any particular Unicode value.
+
+ # The layer where we want the copied glyph:
+ tlayer = tfont.deflayer
+
+ # if new name present in target layer, delete it.
+ if g.newname in tlayer:
+ # New name is already in font:
+ tfont.logger.log("Replacing glyph '{0}' with new glyph".format(g.newname), "V")
+ glyph = tlayer[g.newname]
+ # While here, remove from our mapping any Unicodes from the old glyph:
+ for unicode in glyph["unicode"]:
+ dusv = int(unicode.hex, 16)
+ if dusv in dusv2gname:
+ del dusv2gname[dusv]
+ # Ok, remove old glyph from the layer
+ tlayer.delGlyph(g.newname)
+ else:
+ # New name is not in the font:
+ tfont.logger.log("Adding glyph '{0}'".format(g.newname), "V")
+
+ # Create new glyph
+ glyph = Uglif(layer = tlayer)
+ # Set etree from source glyph
+ glyph.etree = ET.fromstring(sfont.deflayer[g.oldname].inxmlstr)
+ glyph.process_etree()
+ # Rename the glyph if needed
+ if glyph.name != g.newname:
+ # Use super to bypass normal glyph renaming logic since it isn't yet in the layer
+ super(Uglif, glyph).__setattr__("name", g.newname)
+ # add new glyph to layer:
+ tlayer.addGlyph(glyph)
+ tfont.logger.log("Added glyph '{0}'".format(g.newname), "V")
+
+ # todo: set psname if requested; adjusting any other glyphs in the font as needed.
+
+ # Adjust encoding of new glyph
+ if args.unicode:
+ # First remove any encodings the copied glyph had in the source font:
+ for i in range(len(glyph['unicode']) - 1, -1, -1):
+ glyph.remove('unicode', index=i)
+ if g.dusv:
+ # we want this glyph to be encoded.
+ # First remove this Unicode from any other glyph in the target font
+ if g.dusv in dusv2gname:
+ oglyph = tlayer[dusv2gname[g.dusv]]
+ for unicode in oglyph["unicode"]:
+ if int(unicode.hex,16) == g.dusv:
+ oglyph.remove("unicode", object=unicode)
+ tfont.logger.log("Removed USV {0:04X} from existing glyph '{1}'".format(g.dusv,dusv2gname[g.dusv]), "V")
+ break
+ # Now add and record it:
+ glyph.add("unicode", {"hex": '{:04X}'.format(g.dusv)})
+ dusv2gname[g.dusv] = g.newname
+ tfont.logger.log("Added USV {0:04X} to glyph '{1}'".format(g.dusv, g.newname), "V")
+
+ # Scale glyph if desired
+ if args.scale:
+ for e in glyph.etree.iter():
+ for attr in ('width', 'height', 'x', 'y', 'xOffset', 'yOffset'):
+ if attr in e.attrib: e.set(attr, str(int(float(e.get(attr))* args.scale)))
+
+ # Look through components, adjusting names and finding out if we need to copy some.
+ for component in glyph.etree.findall('./outline/component[@base]'):
+ oldname = component.get('base')
+ # Note: the following will cause recursion:
+ component.set('base', copyComponent(sfont, tfont, oldname ,args))
+
+
+
+def copyComponent(sfont, tfont, oldname, args):
+ """copy component glyph if not already copied; make sure name and psname are unique; return its new name"""
+ if oldname in Glyph.nameMap:
+ # already copied
+ return Glyph.nameMap[oldname]
+
+ # if oldname is already in the target font, make up a new name by adding ".copy1", incrementing as necessary
+ if oldname not in tfont.deflayer:
+ newname = oldname
+ tfont.logger.log("Copying component '{0}' with existing name".format(oldname), "V")
+ else:
+ x = gcopyRE.match(oldname)
+ base = x.group(1)
+ try: i = int(x.group(2))
+ except: i = 1
+ while "{0}.copy{1}".format(base,i) in tfont.deflayer:
+ i += 1
+ newname = "{0}.copy{1}".format(base,i)
+ tfont.logger.log("Copying component '{0}' with new name '{1}'".format(oldname, newname), "V")
+
+ # todo: something similar to above but for psname
+
+ # Now copy the glyph, giving it new name if needed.
+ copyglyph(sfont, tfont, Glyph(oldname, newname), args)
+
+ return newname
+
+def doit(args) :
+ sfont = args.source # source UFO
+ tfont = args.ifont # target UFO
+ incsv = args.input
+ logger = args.logger
+
+ # Get headings from csvfile:
+ fl = incsv.firstline
+ if fl is None: logger.log("Empty input file", "S")
+ numfields = len(fl)
+ incsv.numfields = numfields
+ # defaults for single column csv (no headers):
+ nameCol = 0
+ renameCol = None
+ psCol = None
+ usvCol = None
+ if numfields > 1 or args.rename or args.unicode:
+ # required columns:
+ try:
+ nameCol = fl.index('glyph_name');
+ if args.rename:
+ renameCol = fl.index(args.rename);
+ if args.unicode:
+ usvCol = fl.index(args.unicode);
+ except ValueError as e:
+ logger.log('Missing csv input field: ' + e.message, 'S')
+ except Exception as e:
+ logger.log('Error reading csv input field: ' + e.message, 'S')
+ # optional columns
+ psCol = fl.index('ps_name') if 'ps_name' in fl else None
+ if 'glyph_name' in fl:
+ next(incsv.reader, None) # Skip first line with headers in
+
+ # list of glyphs to copy
+ glist = list()
+
+ def checkname(oldname, newname = None):
+ if not newname: newname = oldname
+ if oldname in Glyph.nameMap:
+ logger.log("Line {0}: Glyph '{1}' specified more than once; only the first kept".format(incsv.line_num, oldname), 'W')
+ elif oldname not in sfont.deflayer:
+ logger.log("Line {0}: Glyph '{1}' is not in source font; skipping".format(incsv.line_num, oldname),"W")
+ elif newname in tfont.deflayer and not args.force:
+ logger.log("Line {0}: Glyph '{1}' already present; skipping".format(incsv.line_num, newname), "W")
+ else:
+ return True
+ return False
+
+ # glyphs specified in csv file
+ for r in incsv:
+ oldname = r[nameCol]
+ newname = r[renameCol] if args.rename else oldname
+ psname = r[psCol] if psCol is not None else None
+ if args.unicode and r[usvCol]:
+ # validate USV:
+ try:
+ dusv = int(r[usvCol],16)
+ except ValueError:
+ logger.log("Line {0}: Invalid USV '{1}'; ignored.".format(incsv.line_num, r[usvCol]), "W")
+ dusv = None
+ else:
+ dusv = None
+
+ if checkname(oldname, newname):
+ glist.append(Glyph(oldname, newname, psname, dusv))
+
+ # glyphs specified on the command line
+ if args.name:
+ for gname in args.name:
+ if checkname(gname):
+ glist.append(Glyph(gname))
+
+ # Ok, now process them:
+ if len(glist) == 0:
+ logger.log("No glyphs to copy", "S")
+
+ # copy glyphs by name
+ while len(glist) :
+ g = glist.pop(0)
+ tfont.logger.log("Copying source glyph '{0}' as '{1}'{2}".format(g.oldname, g.newname,
+ " (U+{0:04X})".format(g.dusv) if g.dusv else ""), "I")
+ copyglyph(sfont, tfont, g, args)
+
+ return tfont
+
+def cmd() : execute("UFO",doit,argspec)
+if __name__ == "__main__": cmd()
diff --git a/lib/silfont/scripts/psfcopymeta.py b/lib/silfont/scripts/psfcopymeta.py
new file mode 100755
index 0000000..1e031fd
--- /dev/null
+++ b/lib/silfont/scripts/psfcopymeta.py
@@ -0,0 +1,148 @@
+#!/usr/bin/env python
+__doc__ = '''Copy metadata between fonts in different (related) families
+Usually run against the master (regular) font in each family then data synced within family afterwards'''
+__url__ = 'http://github.com/silnrsi/pysilfont'
+__copyright__ = 'Copyright (c) 2017 SIL International (http://www.sil.org)'
+__license__ = 'Released under the MIT License (http://opensource.org/licenses/MIT)'
+__author__ = 'David Raymond'
+
+from silfont.core import execute
+import silfont.ufo as UFO
+from xml.etree import ElementTree as ET
+
+argspec = [
+ ('fromfont',{'help': 'From font file'}, {'type': 'infont'}),
+ ('tofont',{'help': 'To font file'}, {'type': 'infont'}),
+ ('-l','--log',{'help': 'Log file'}, {'type': 'outfile', 'def': '_copymeta.log'}),
+ ('-r','--reportonly', {'help': 'Report issues but no updating', 'action': 'store_true', 'default': False},{})
+ ]
+
+def doit(args) :
+
+ fields = ["copyright", "openTypeNameDescription", "openTypeNameDesigner", "openTypeNameDesignerURL", "openTypeNameLicense", # General feilds
+ "openTypeNameLicenseURL", "openTypeNameManufacturer", "openTypeNameManufacturerURL", "openTypeOS2CodePageRanges",
+ "openTypeOS2UnicodeRanges", "openTypeOS2VendorID", "trademark",
+ "openTypeNameVersion", "versionMajor", "versionMinor", # Version fields
+ "ascender", "descender", "openTypeHheaAscender", "openTypeHheaDescender", "openTypeHheaLineGap", # Design fields
+ "openTypeOS2TypoAscender", "openTypeOS2TypoDescender", "openTypeOS2TypoLineGap", "openTypeOS2WinAscent", "openTypeOS2WinDescent"]
+ libfields = ["public.postscriptNames", "public.glyphOrder", "com.schriftgestaltung.glyphOrder"]
+
+ fromfont = args.fromfont
+ tofont = args.tofont
+ logger = args.logger
+ reportonly = args.reportonly
+
+ updatemessage = " to be updated: " if reportonly else " updated: "
+ precision = fromfont.paramset["precision"]
+ # Increase screen logging level to W unless specific level supplied on command-line
+ if not(args.quiet or "scrlevel" in args.paramsobj.sets["command line"]) : logger.scrlevel = "W"
+
+ # Process fontinfo.plist
+ ffi = fromfont.fontinfo
+ tfi = tofont.fontinfo
+ fupdated = False
+ for field in fields:
+ if field in ffi :
+ felem = ffi[field][1]
+ ftag = felem.tag
+ ftext = felem.text
+ if ftag == 'real' : ftext = processnum(ftext,precision)
+ message = field + updatemessage
+
+ if field in tfi : # Need to compare values to see if update is needed
+ telem = tfi[field][1]
+ ttag = telem.tag
+ ttext = telem.text
+ if ttag == 'real' : ttext = processnum(ttext,precision)
+
+ if ftag in ("real", "integer", "string") :
+ if ftext != ttext :
+ if field == "openTypeNameLicense" : # Too long to display all
+ addmess = " Old: '" + ttext[0:80] + "...' New: '" + ftext[0:80] + "...'"
+ else: addmess = " Old: '" + ttext + "' New: '" + str(ftext) + "'"
+ telem.text = ftext
+ logger.log(message + addmess, "W")
+ fupdated = True
+ elif ftag in ("true, false") :
+ if ftag != ttag :
+ fti.setelem(field, ET.fromstring("<" + ftag + "/>"))
+ logger.log(message + " Old: '" + ttag + "' New: '" + str(ftag) + "'", "W")
+ fupdated = True
+ elif ftag == "array" : # Assume simple array with just values to compare
+ farray = []
+ for subelem in felem : farray.append(subelem.text)
+ tarray = []
+ for subelem in telem : tarray.append(subelem.text)
+ if farray != tarray :
+ tfi.setelem(field, ET.fromstring(ET.tostring(felem)))
+ logger.log(message + "Some values different Old: " + str(tarray) + " New: " + str(farray), "W")
+ fupdated = True
+ else : logger.log("Non-standard fontinfo field type: "+ ftag + " in " + fontname, "S")
+ else :
+ tfi.addelem(field, ET.fromstring(ET.tostring(felem)))
+ logger.log(message + "is missing from destination font so will be copied from source font", "W")
+ fupdated = True
+ else: # Field not in from font
+ if field in tfi :
+ logger.log( field + " is missing from source font but present in destination font", "E")
+ else :
+ logger.log( field + " is in neither font", "W")
+
+ # Process lib.plist - currently just public.postscriptNames and glyph order fields which are all simple dicts or arrays
+ flib = fromfont.lib
+ tlib = tofont.lib
+ lupdated = False
+ for field in libfields:
+ action = None
+ if field in flib:
+ if field in tlib: # Need to compare values to see if update is needed
+ if flib.getval(field) != tlib.getval(field):
+ action = "Updatefield"
+ else:
+ action = "Copyfield"
+ else:
+ action = "Error" if field == ("public.GlyphOrder", "public.postscriptNames") else "Warn"
+ issue = field + " not in source font lib.plist"
+
+ # Process the actions, create log messages etc
+ if action is None or action == "Ignore":
+ pass
+ elif action == "Warn":
+ logger.log(field + " needs manual correction: " + issue, "W")
+ elif action == "Error":
+ logger.log(field + " needs manual correction: " + issue, "E")
+ elif action in ("Updatefield", "Copyfield"): # Updating actions
+ lupdated = True
+ message = field + updatemessage
+ if action == "Copyfield":
+ message = message + "is missing so will be copied from source font"
+ tlib.addelem(field, ET.fromstring(ET.tostring(flib[field][1])))
+ elif action == "Updatefield":
+ message = message + "Some values different"
+ tlib.setelem(field, ET.fromstring(ET.tostring(flib[field][1])))
+ logger.log(message, "W")
+ else:
+ logger.log("Uncoded action: " + action + " - oops", "X")
+
+ # Now update on disk
+ if not reportonly:
+ if fupdated:
+ logger.log("Writing updated fontinfo.plist", "P")
+ UFO.writeXMLobject(tfi, tofont.outparams, tofont.ufodir, "fontinfo.plist", True, fobject=True)
+ if lupdated:
+ logger.log("Writing updated lib.plist", "P")
+ UFO.writeXMLobject(tlib, tofont.outparams, tofont.ufodir, "lib.plist", True, fobject=True)
+
+ return
+
+
+def processnum(text, precision) : # Apply same processing to real numbers that normalization will
+ if precision is not None:
+ val = round(float(text), precision)
+ if val == int(val) : val = int(val) # Removed trailing decimal .0
+ text = str(val)
+ return text
+
+
+def cmd(): execute("UFO",doit, argspec)
+if __name__ == "__main__": cmd()
diff --git a/lib/silfont/scripts/psfcreateinstances.py b/lib/silfont/scripts/psfcreateinstances.py
new file mode 100644
index 0000000..468435f
--- /dev/null
+++ b/lib/silfont/scripts/psfcreateinstances.py
@@ -0,0 +1,228 @@
+#!/usr/bin/env python
+__doc__ = 'Generate instance UFOs from a designspace document and master UFOs'
+
+# Python 2.7 script to build instance UFOs from a designspace document
+# If a file is given, all instances are built
+# A particular instance to build can be specified using the -i option
+# and the 'name' attribute value for an 'instance' element in the designspace file
+# Or it can be specified using the -a and -v options
+# to specify any attribute and value pair for an 'instance' in the designspace file
+# If more than one instances matches, all will be built
+# A prefix for the output path can be specified (for smith processing)
+# If the location of an instance UFO matches a master's location,
+# glyphs are copied instead of calculated
+# This allows instances to build with glyphs that are not interpolatable
+# An option exists to calculate glyphs instead of copying them
+# If a folder is given using an option, all instances in all designspace files are built
+# Specifying an instance to build or an output path prefix is not supported with a folder
+# Also, all glyphs will be calculated
+
+__url__ = 'http://github.com/silnrsi/pysilfont'
+__copyright__ = 'Copyright (c) 2018 SIL International (http://www.sil.org)'
+__license__ = 'Released under the MIT License (http://opensource.org/licenses/MIT)'
+__author__ = 'Alan Ward'
+
+import os, re
+from mutatorMath.ufo.document import DesignSpaceDocumentReader
+from mutatorMath.ufo.instance import InstanceWriter
+from fontMath.mathGlyph import MathGlyph
+from mutatorMath.ufo import build as build_designspace
+from silfont.core import execute
+
+argspec = [
+ ('designspace_path', {'help': 'Path to designspace document (or folder of them)'}, {}),
+ ('-i', '--instanceName', {'help': 'Font name for instance to build'}, {}),
+ ('-a', '--instanceAttr', {'help': 'Attribute used to specify instance to build'}, {}),
+ ('-v', '--instanceVal', {'help': 'Value of attribute specifying instance to build'}, {}),
+ ('-f', '--folder', {'help': 'Build all designspace files in a folder','action': 'store_true'}, {}),
+ ('-o', '--output', {'help': 'Prepend path to all output paths'}, {}),
+ ('--forceInterpolation', {'help': 'If an instance matches a master, calculate glyphs instead of copying them',
+ 'action': 'store_true'}, {}),
+ ('--roundInstances', {'help': 'Apply integer rounding to all geometry when interpolating',
+ 'action': 'store_true'}, {}),
+ ('-l','--log',{'help': 'Log file (default: *_createinstances.log)'}, {'type': 'outfile', 'def': '_createinstances.log'}),
+ ('-W','--weightfix',{'help': 'Enable RIBBI style weight fixing', 'action': 'store_true'}, {}),
+]
+
+# Class factory to wrap a subclass in a closure to store values not defined in the original class
+# that our method overrides will utilize
+# The class methods will fail unless the class is generated by the factory, which is enforced by scoping
+# Using class attribs or global variables would violate encapsulation even more
+# and would only allow for one instance of the class
+
+weightClasses = {
+ 'bold': 700
+}
+
+def InstanceWriterCF(output_path_prefix, calc_glyphs, fix_weight):
+
+ class LocalInstanceWriter(InstanceWriter):
+ fixWeight = fix_weight
+
+ def __init__(self, path, *args, **kw):
+ if output_path_prefix:
+ path = os.path.join(output_path_prefix, path)
+ return super(LocalInstanceWriter, self).__init__(path, *args, **kw)
+
+ # Override the method used to calculate glyph geometry
+ # If copy_glyphs is true and the glyph being processed is in the same location
+ # (has all the same axes values) as a master UFO,
+ # then extract the glyph geometry directly into the target glyph.
+ # FYI, in the superclass method, m = buildMutator(); m.makeInstance() returns a MathGlyph
+ def _calculateGlyph(self, targetGlyphObject, instanceLocationObject, glyphMasters):
+ # Search for a glyphMaster with the same location as instanceLocationObject
+ found = False
+ if not calc_glyphs: # i.e. if copying glyphs
+ for item in glyphMasters:
+ locationObject = item['location'] # mutatorMath Location
+ if locationObject.sameAs(instanceLocationObject) == 0:
+ found = True
+ fontObject = item['font'] # defcon Font
+ glyphName = item['glyphName'] # string
+ glyphObject = MathGlyph(fontObject[glyphName])
+ glyphObject.extractGlyph(targetGlyphObject, onlyGeometry=True)
+ break
+
+ if not found: # includes case of calc_glyphs == True
+ super(LocalInstanceWriter, self)._calculateGlyph(targetGlyphObject,
+ instanceLocationObject,
+ glyphMasters)
+
+ def _copyFontInfo(self, targetInfo, sourceInfo):
+ super(LocalInstanceWriter, self)._copyFontInfo(targetInfo, sourceInfo)
+
+ if getattr(self, 'fixWeight', False):
+ # fixWeight is True since the --weightfix (or -W) option was specified
+
+ # This mode is used for RIBBI font builds,
+ # therefore the weight class can be determined
+ # by the style name
+ if self.font.info.styleMapStyleName.lower().startswith("bold"):
+ weight_class = 700
+ else:
+ weight_class = 400
+ else:
+ # fixWeight is False (or None)
+
+ # This mode is used for non-RIBBI font builds,
+ # therefore the weight class can be determined
+ # by the weight axis map in the Designspace file
+ foundmap = False
+ weight = int(self.locationObject["weight"])
+ for map_space in self.axes["weight"]["map"]:
+ userspace = int(map_space[0]) # called input in the Designspace file
+ designspace = int(map_space[1]) # called output in the Designspace file
+ if designspace == weight:
+ weight_class = userspace
+ foundmap = True
+ if not foundmap:
+ weight_class = 399 # Dummy value designed to look non-standard
+ logger.log(f'No entry in designspace axis mapping for {weight}; set to 399', 'W')
+ setattr(targetInfo, 'openTypeOS2WeightClass', weight_class)
+
+ localinfo = {}
+ for k in (('openTypeNameManufacturer', None),
+ ('styleMapFamilyName', 'familyName'),
+ ('styleMapStyleName', 'styleName')):
+ localinfo[k[0]] = getattr(targetInfo, k[0], (getattr(targetInfo, k[1]) if k[1] is not None else ""))
+ localinfo['styleMapStyleName'] = localinfo['styleMapStyleName'].title()
+ localinfo['year'] = re.sub(r'^.*?([0-9]+)\s*$', r'\1', getattr(targetInfo, 'openTypeNameUniqueID'))
+ uniqueID = "{openTypeNameManufacturer}: {styleMapFamilyName} {styleMapStyleName} {year}".format(**localinfo)
+ setattr(targetInfo, 'openTypeNameUniqueID', uniqueID)
+
+ return LocalInstanceWriter
+
+logger = None
+severe_error = False
+def progress_func(state="update", action=None, text=None, tick=0):
+ global severe_error
+ if logger:
+ if state == 'error':
+ if str(action) == 'unicodes':
+ logger.log("%s: %s\n%s" % (state, str(action), str(text)), 'W')
+ else:
+ logger.log("%s: %s\n%s" % (state, str(action), str(text)), 'E')
+ severe_error = True
+ else:
+ logger.log("%s: %s\n%s" % (state, str(action), str(text)), 'I')
+
+def doit(args):
+ global logger
+ logger = args.logger
+
+ designspace_path = args.designspace_path
+ instance_font_name = args.instanceName
+ instance_attr = args.instanceAttr
+ instance_val = args.instanceVal
+ output_path_prefix = args.output
+ calc_glyphs = args.forceInterpolation
+ build_folder = args.folder
+ round_instances = args.roundInstances
+
+ if instance_font_name and (instance_attr or instance_val):
+ args.logger.log('--instanceName is mutually exclusive with --instanceAttr or --instanceVal','S')
+ if (instance_attr and not instance_val) or (instance_val and not instance_attr):
+ args.logger.log('--instanceAttr and --instanceVal must be used together', 'S')
+ if (build_folder and (instance_font_name or instance_attr or instance_val
+ or output_path_prefix or calc_glyphs)):
+ args.logger.log('--folder cannot be used with options: -i, -a, -v, -o, --forceInterpolation', 'S')
+
+ args.logger.log('Interpolating master UFOs from designspace', 'P')
+ if not build_folder:
+ if not os.path.isfile(designspace_path):
+ args.logger.log('A designspace file (not a folder) is required', 'S')
+ reader = DesignSpaceDocumentReader(designspace_path, ufoVersion=3,
+ roundGeometry=round_instances,
+ progressFunc=progress_func)
+ # assignment to an internal object variable is a kludge, probably should use subclassing instead
+ reader._instanceWriterClass = InstanceWriterCF(output_path_prefix, calc_glyphs, args.weightfix)
+ if calc_glyphs:
+ args.logger.log('Interpolating glyphs where an instance font location matches a master', 'P')
+ if instance_font_name or instance_attr:
+ key_attr = instance_attr if instance_val else 'name'
+ key_val = instance_val if instance_attr else instance_font_name
+ reader.readInstance((key_attr, key_val))
+ else:
+ reader.readInstances()
+ else:
+ # The below uses a utility function that's part of mutatorMath
+ # It will accept a folder and processes all designspace files there
+ args.logger.log('Interpolating glyphs where an instance font location matches a master', 'P')
+ build_designspace(designspace_path,
+ outputUFOFormatVersion=3, roundGeometry=round_instances,
+ progressFunc=progress_func)
+
+ if not severe_error:
+ args.logger.log('Done', 'P')
+ else:
+ args.logger.log('Done with severe error', 'S')
+
+def cmd(): execute(None, doit, argspec)
+if __name__ == '__main__': cmd()
+
+# Future development might use: fonttools\Lib\fontTools\designspaceLib to read
+# the designspace file (which is the most up-to-date approach)
+# then pass that object to mutatorMath, but there's no way to do that today.
+
+
+# For reference:
+# from mutatorMath/ufo/__init__.py:
+# build() is a convenience function for reading and executing a designspace file.
+# documentPath: filepath to the .designspace document
+# outputUFOFormatVersion: ufo format for output
+# verbose: True / False for lots or no feedback [to log file]
+# logPath: filepath to a log file
+# progressFunc: an optional callback to report progress.
+# see mutatorMath.ufo.tokenProgressFunc
+#
+# class DesignSpaceDocumentReader(object):
+# def __init__(self, documentPath,
+# ufoVersion,
+# roundGeometry=False,
+# verbose=False,
+# logPath=None,
+# progressFunc=None
+# ):
+#
+# def readInstance(self, key, makeGlyphs=True, makeKerning=True, makeInfo=True):
+# def readInstances(self, makeGlyphs=True, makeKerning=True, makeInfo=True):
diff --git a/lib/silfont/scripts/psfcsv2comp.py b/lib/silfont/scripts/psfcsv2comp.py
new file mode 100644
index 0000000..7a4a960
--- /dev/null
+++ b/lib/silfont/scripts/psfcsv2comp.py
@@ -0,0 +1,129 @@
+#!/usr/bin/env python
+__doc__ = '''generate composite definitions from csv file'''
+__url__ = 'http://github.com/silnrsi/pysilfont'
+__copyright__ = 'Copyright (c) 2018 SIL International (http://www.sil.org)'
+__license__ = 'Released under the MIT License (http://opensource.org/licenses/MIT)'
+__author__ = 'Bob Hallissy'
+
+import re
+from silfont.core import execute
+import re
+
+argspec = [
+ ('output',{'help': 'Output file containing composite definitions'}, {'type': 'outfile'}),
+ ('-i','--input',{'help': 'Glyph info csv file'}, {'type': 'incsv', 'def': 'glyph_data.csv'}),
+ ('-f','--fontcode',{'help': 'letter to filter for glyph_data'},{}),
+ ('--gname', {'help': 'Column header for glyph name', 'default': 'glyph_name'}, {}),
+ ('--base', {'help': 'Column header for name of base', 'default': 'base'}, {}),
+ ('--usv', {'help': 'Column header for USV'}, {}),
+ ('--anchors', {'help': 'Column header(s) for APs to compose', 'default': 'above,below'}, {}),
+ ('-r','--report',{'help': 'Set reporting level for log', 'type':str, 'choices':['X','S','E','P','W','I','V']},{}),
+ ('-l','--log',{'help': 'Set log file name'}, {'type': 'outfile', 'def': 'csv2comp.log'}),
+ ]
+
+def doit(args):
+ logger = args.logger
+ if args.report: logger.loglevel = args.report
+ # infont = args.ifont
+ incsv = args.input
+ output = args.output
+
+ def csvWarning(msg, exception = None):
+ m = "glyph_data warning: %s at line %d" % (msg, incsv.line_num)
+ if exception is not None:
+ m += '; ' + exception.message
+ logger.log(m, 'W')
+
+ if args.fontcode is not None:
+ whichfont = args.fontcode.strip().lower()
+ if len(whichfont) != 1:
+ logger.log('-f parameter must be a single letter', 'S')
+ else:
+ whichfont = None
+
+ # Which headers represent APs to use:
+ apList = args.anchors.split(',')
+ if len(apList) == 0:
+ logger.log('--anchors option value "%s" is invalid' % args.anchors, 'S')
+
+ # Get headings from csvfile:
+ fl = incsv.firstline
+ if fl is None: logger.log("Empty input file", "S")
+ # required columns:
+ try:
+ nameCol = fl.index(args.gname)
+ baseCol = fl.index(args.base)
+ apCols = [fl.index(ap) for ap in apList]
+ if args.usv is not None:
+ usvCol = fl.index(args.usv)
+ else:
+ usvCol = None
+ except ValueError as e:
+ logger.log('Missing csv input field: ' + e.message, 'S')
+ except Exception as e:
+ logger.log('Error reading csv input field: ' + e.message, 'S')
+
+ # Now make strip AP names; pair up with columns so easy to iterate:
+ apInfo = list(zip(apCols, [x.strip() for x in apList]))
+
+ # If -f specified, make sure we have the fonts column
+ if whichfont is not None:
+ if 'fonts' not in fl: logger.log('-f requires "fonts" column in glyph_data', 'S')
+ fontsCol = fl.index('fonts')
+
+ # RE that matches names of glyphs we don't care about
+ namesToSkipRE = re.compile('^(?:[._].*|null|cr|nonmarkingreturn|tab|glyph_name)$',re.IGNORECASE)
+
+ # keep track of glyph names we've seen to detect duplicates
+ namesSeen = set()
+
+ # OK, process all records in glyph_data
+ for line in incsv:
+ base = line[baseCol].strip()
+ if len(base) == 0:
+ # No composites specified
+ continue
+
+ gname = line[nameCol].strip()
+ # things to ignore:
+ if namesToSkipRE.match(gname): continue
+ if whichfont is not None and line[fontsCol] != '*' and line[fontsCol].lower().find(whichfont) < 0:
+ continue
+
+ if len(gname) == 0:
+ csvWarning('empty glyph name in glyph_data; ignored')
+ continue
+ if gname.startswith('#'): continue
+ if gname in namesSeen:
+ csvWarning('glyph name %s previously seen in glyph_data; ignored' % gname)
+ continue
+ namesSeen.add(gname)
+
+ # Ok, start building the composite
+ composite = '%s = %s' %(gname, base)
+
+ # The first component must *not* reference the base; all others *must*:
+ seenfirst = False
+ for apCol, apName in apInfo:
+ component = line[apCol].strip()
+ if len(component):
+ if not seenfirst:
+ composite += ' + %s@%s' % (component, apName)
+ seenfirst = True
+ else:
+ composite += ' + %s@%s:%s' % (component, base, apName)
+
+ # Add USV if present
+ if usvCol is not None:
+ usv = line[usvCol].strip()
+ if len(usv):
+ composite += ' | %s' % usv
+
+ # Output this one
+ output.write(composite + '\n')
+
+ output.close()
+
+def cmd() : execute("",doit,argspec)
+if __name__ == "__main__": cmd()
+
diff --git a/lib/silfont/scripts/psfdeflang.py b/lib/silfont/scripts/psfdeflang.py
new file mode 100755
index 0000000..3a1ac26
--- /dev/null
+++ b/lib/silfont/scripts/psfdeflang.py
@@ -0,0 +1,47 @@
+#!/usr/bin/env python
+__doc__ = '''Switch default language in a font'''
+__url__ = 'http://github.com/silnrsi/pysilfont'
+__copyright__ = 'Copyright (c) 2019 SIL International (http://www.sil.org)'
+__license__ = 'Released under the MIT License (http://opensource.org/licenses/MIT)'
+__author__ = 'Martin Hosken'
+
+from silfont.core import execute
+
+argspec = [
+ ('ifont',{'help': 'Input TTF'}, {'type': 'infont'}),
+ ('ofont',{'help': 'Output TTF','nargs': '?' }, {'type': 'outfont'}),
+ ('-L','--lang', {'help': 'Language to switch to'}, {}),
+ ('-l','--log',{'help': 'Optional log file'}, {'type': 'outfile', 'def': '_deflang.log', 'optlog': True}),
+]
+
+def long2tag(x):
+ res = []
+ while x:
+ res.append(chr(x & 0xFF))
+ x >>= 8
+ return "".join(reversed(res))
+
+def doit(args):
+ infont = args.ifont
+ ltag = args.lang.lower()
+ if 'Sill' in infont and 'Feat' in infont:
+ if ltag in infont['Sill'].langs:
+ changes = dict((long2tag(x[0]), x[1]) for x in infont['Sill'].langs[ltag])
+ for g, f in infont['Feat'].features.items():
+ if g in changes:
+ f.default = changes[g]
+ otltag = ltag + (" " * (4 - len(ltag)))
+ for k in ('GSUB', 'GPOS'):
+ try:
+ t = infont[k].table
+ except KeyError:
+ continue
+ for srec in t.ScriptList.ScriptRecord:
+ for lrec in srec.Script.LangSysRecord:
+ if lrec.LangSysTag.lower() == otltag:
+ srec.Script.DefaultLangSys = lrec.LangSys
+ return infont
+
+def cmd() : execute('FT', doit, argspec)
+if __name__ == "__main__" : cmd()
+
diff --git a/lib/silfont/scripts/psfdeleteglyphs.py b/lib/silfont/scripts/psfdeleteglyphs.py
new file mode 100644
index 0000000..94caa36
--- /dev/null
+++ b/lib/silfont/scripts/psfdeleteglyphs.py
@@ -0,0 +1,144 @@
+#!/usr/bin/env python
+__doc__ = '''Deletes glyphs from a UFO based on list. Can instead delete glyphs not in list.'''
+__url__ = 'http://github.com/silnrsi/pysilfont'
+__copyright__ = 'Copyright (c) 2018 SIL International (http://www.sil.org)'
+__license__ = 'Released under the MIT License (http://opensource.org/licenses/MIT)'
+__author__ = 'Victor Gaultney'
+
+from silfont.core import execute
+from xml.etree import ElementTree as ET
+
+argspec = [
+ ('ifont', {'help': 'Input font file'}, {'type': 'infont'}),
+ ('ofont', {'help': 'Output font file', 'nargs': '?'}, {'type': 'outfont'}),
+ ('-i', '--input', {'help': 'Input text file, one glyphname per line'}, {'type': 'infile', 'def': 'glyphlist.txt'}),
+ ('--reverse',{'help': 'Remove glyphs not in list instead', 'action': 'store_true', 'default': False},{}),
+ ('-l','--log',{'help': 'Log file'}, {'type': 'outfile', 'def': 'deletedglyphs.log'})]
+
+def doit(args) :
+ font = args.ifont
+ listinput = args.input
+ logger = args.logger
+
+ glyphlist = []
+ for line in listinput.readlines():
+ glyphlist.append(line.strip())
+
+ deletelist = []
+
+ if args.reverse:
+ for glyphname in font.deflayer:
+ if glyphname not in glyphlist:
+ deletelist.append(glyphname)
+ else:
+ for glyphname in font.deflayer:
+ if glyphname in glyphlist:
+ deletelist.append(glyphname)
+
+ secondarylayers = [x for x in font.layers if x.layername != "public.default"]
+
+ liststocheck = ('public.glyphOrder', 'public.postscriptNames', 'com.schriftgestaltung.glyphOrder')
+ liblists = [[],[],[]]; inliblists = [[],[],[]]
+ if hasattr(font, 'lib'):
+ for (i,listn) in enumerate(liststocheck):
+ if listn in font.lib:
+ liblists[i] = font.lib.getval(listn)
+ else:
+ logger.log("No lib.plist found in font", "W")
+
+ # Now loop round deleting the glyphs etc
+ logger.log("Deleted glyphs:", "I")
+
+ # With groups and kerning, create dicts representing then plists (to make deletion of members easier) and indexes by glyph/member name
+ kgroupprefixes = {"public.kern1.": 1, "public.kern2.": 2}
+ gdict = {}
+ kdict = {}
+ groupsbyglyph = {}
+ ksetsbymember = {}
+
+ groups = font.groups if hasattr(font, "groups") else []
+ kerning = font.kerning if hasattr(font, "kerning") else []
+ if groups:
+ for gname in groups:
+ group = groups.getval(gname)
+ gdict[gname] = group
+ for glyph in group:
+ if glyph in groupsbyglyph:
+ groupsbyglyph[glyph].append(gname)
+ else:
+ groupsbyglyph[glyph] = [gname]
+ if kerning:
+ for setname in kerning:
+ kset = kerning.getval(setname)
+ kdict[setname] = kset
+ for member in kset:
+ if member in ksetsbymember:
+ ksetsbymember[member].append(setname)
+ else:
+ ksetsbymember[member] = [setname]
+
+ # Loop round doing the deleting
+ for glyphn in sorted(deletelist):
+ # Delete from all layers
+ font.deflayer.delGlyph(glyphn)
+ deletedfrom = "Default layer"
+ for layer in secondarylayers:
+ if glyphn in layer:
+ deletedfrom += ", " + layer.layername
+ layer.delGlyph(glyphn)
+ # Check to see if the deleted glyph is in any of liststocheck
+ stillin = None
+ for (i, liblist) in enumerate(liblists):
+ if glyphn in liblist:
+ inliblists[i].append(glyphn)
+ stillin = stillin + ", " + liststocheck[i] if stillin else liststocheck[i]
+
+ logger.log(" " + glyphn + " deleted from: " + deletedfrom, "I")
+ if stillin: logger.log(" " + glyphn + " is still in " + stillin, "I")
+
+ # Process groups.plist and kerning.plist
+
+ tocheck = (glyphn, "public.kern1." + glyphn, "public.kern2." + glyphn)
+ # First delete whole groups and kern pair sets
+ for kerngroup in tocheck[1:]: # Don't check glyphn when deleting groups:
+ if kerngroup in gdict: gdict.pop(kerngroup)
+ for setn in tocheck:
+ if setn in kdict: kdict.pop(setn)
+ # Now delete members within groups and kern pair sets
+ if glyphn in groupsbyglyph:
+ for groupn in groupsbyglyph[glyphn]:
+ if groupn in gdict: # Need to check still there, since whole group may have been deleted above
+ group = gdict[groupn]
+ del group[group.index(glyphn)]
+ for member in tocheck:
+ if member in ksetsbymember:
+ for setn in ksetsbymember[member]:
+ if setn in kdict: del kdict[setn][member]
+ # Now need to recreate groups.plist and kerning.plist
+ if groups:
+ for group in list(groups): groups.remove(group) # Empty existing contents
+ for gname in gdict:
+ elem = ET.Element("array")
+ if gdict[gname]: # Only create if group is not empty
+ for glyph in gdict[gname]:
+ ET.SubElement(elem, "string").text = glyph
+ groups.setelem(gname, elem)
+ if kerning:
+ for kset in list(kerning): kerning.remove(kset) # Empty existing contents
+ for kset in kdict:
+ elem = ET.Element("dict")
+ if kdict[kset]:
+ for member in kdict[kset]:
+ ET.SubElement(elem, "key").text = member
+ ET.SubElement(elem, "integer").text = str(kdict[kset][member])
+ kerning.setelem(kset, elem)
+
+ logger.log(str(len(deletelist)) + " glyphs deleted. Set logging to I to see details", "P")
+ inalist = set(inliblists[0] + inliblists[1] + inliblists[2])
+ if inalist: logger.log(str(len(inalist)) + " of the deleted glyphs are still in some lib.plist entries.", "W")
+
+ return font
+
+def cmd() : execute("UFO",doit,argspec)
+if __name__ == "__main__": cmd()
+
diff --git a/lib/silfont/scripts/psfdupglyphs.py b/lib/silfont/scripts/psfdupglyphs.py
new file mode 100644
index 0000000..1b68bee
--- /dev/null
+++ b/lib/silfont/scripts/psfdupglyphs.py
@@ -0,0 +1,48 @@
+#!/usr/bin/env python3
+'''Duplicates glyphs in a UFO based on a csv definition: source,target.
+Duplicates everything except unicodes.'''
+__url__ = 'http://github.com/silnrsi/pysilfont'
+__copyright__ = 'Copyright (c) 2018 SIL International (http://www.sil.org)'
+__license__ = 'Released under the MIT License (http://opensource.org/licenses/MIT)'
+__author__ = 'Victor Gaultney'
+
+from silfont.core import execute
+
+argspec = [
+ ('ifont', {'help': 'Input font filename'}, {'type': 'infont'}),
+ ('ofont',{'help': 'Output font file','nargs': '?' }, {'type': 'outfont'}),
+ ('-i','--input',{'help': 'Input csv file'}, {'type': 'incsv', 'def': 'duplicates.csv'}),
+ ('-l','--log',{'help': 'Set log file name'}, {'type': 'outfile', 'def': '_duplicates.log'})]
+
+def doit(args) :
+ font = args.ifont
+ logger = args.logger
+
+ # Process duplicates csv file into a dictionary structure
+ args.input.numfields = 2
+ duplicates = {}
+ for line in args.input :
+ duplicates[line[0]] = line[1]
+
+ # Iterate through dictionary (unsorted)
+ for source, target in duplicates.items() :
+ # Check if source glyph is in font
+ if source in font.keys() :
+ # Give warning if target is already in font, but overwrite anyway
+ if target in font.keys() :
+ logger.log("Warning: " + target + " already in font and will be replaced")
+ sourceglyph = font[source]
+ # Make a copy of source into a new glyph object
+ newglyph = sourceglyph.copy()
+ # Modify that glyph object
+ newglyph.unicodes = []
+ # Add the new glyph object to the font with name target
+ font.__setitem__(target,newglyph)
+ logger.log(source + " duplicated to " + target)
+ else :
+ logger.log("Warning: " + source + " not in font")
+
+ return font
+
+def cmd() : execute("FP",doit,argspec)
+if __name__ == "__main__": cmd()
diff --git a/lib/silfont/scripts/psfexportanchors.py b/lib/silfont/scripts/psfexportanchors.py
new file mode 100755
index 0000000..fd27a47
--- /dev/null
+++ b/lib/silfont/scripts/psfexportanchors.py
@@ -0,0 +1,101 @@
+#!/usr/bin/env python
+__doc__ = 'export anchor data from UFO to XML file'
+__url__ = 'http://github.com/silnrsi/pysilfont'
+__copyright__ = 'Copyright (c) 2015,2016 SIL International (http://www.sil.org)'
+__license__ = 'Released under the MIT License (http://opensource.org/licenses/MIT)'
+__author__ = 'David Rowe'
+
+from silfont.core import execute
+from silfont.etutil import ETWriter
+from xml.etree import ElementTree as ET
+
+argspec = [
+ ('ifont',{'help': 'Input UFO'}, {'type': 'infont'}),
+ ('output',{'help': 'Output file exported anchor data in XML format', 'nargs': '?'}, {'type': 'outfile', 'def': '_anc.xml'}),
+ ('-r','--report',{'help': 'Set reporting level for log', 'type':str, 'choices':['X','S','E','P','W','I','V']},{}),
+ ('-l','--log',{'help': 'Set log file name'}, {'type': 'outfile', 'def': '_anc.log'}),
+ ('-g','--gid',{'help': 'Include GID attribute in <glyph> elements', 'action': 'store_true'},{}),
+ ('-s','--sort',{'help': 'Sort by public.glyphOrder in lib.plist', 'action': 'store_true'},{}),
+ ('-u','--Uprefix',{'help': 'Include U+ prefix on UID attribute in <glyph> elements', 'action': 'store_true'},{}),
+ ('-p','--params',{'help': 'XML formatting parameters: indentFirst, indentIncr, attOrder','action': 'append'}, {'type': 'optiondict'})
+ ]
+
+def doit(args) :
+ logfile = args.logger
+ if args.report: logfile.loglevel = args.report
+ infont = args.ifont
+ prefix = "U+" if args.Uprefix else ""
+
+ if hasattr(infont, 'lib') and 'public.glyphOrder' in infont.lib:
+ glyphorderlist = [s.text for s in infont.lib['public.glyphOrder'][1].findall('string')]
+ else:
+ glyphorderlist = []
+ if args.gid:
+ logfile.log("public.glyphOrder is absent; ignoring --gid option", "E")
+ args.gid = False
+ glyphorderset = set(glyphorderlist)
+ if len(glyphorderlist) != len(glyphorderset):
+ logfile.log("At least one duplicate name in public.glyphOrder", "W")
+ # count of duplicate names is len(glyphorderlist) - len(glyphorderset)
+ actualglyphlist = [g for g in infont.deflayer.keys()]
+ actualglyphset = set(actualglyphlist)
+ listorder = []
+ gid = 0
+ for g in glyphorderlist:
+ if g in actualglyphset:
+ listorder.append( (g, gid) )
+ gid += 1
+ actualglyphset.remove(g)
+ glyphorderset.remove(g)
+ else:
+ logfile.log(g + " in public.glyphOrder list but absent from UFO", "W")
+ if args.sort: listorder.sort()
+ for g in sorted(actualglyphset): # if any glyphs remaining
+ listorder.append( (g, None) )
+ logfile.log(g + " in UFO but not in public.glyphOrder list", "W")
+
+ if 'postscriptFontName' in infont.fontinfo:
+ postscriptFontName = infont.fontinfo['postscriptFontName'][1].text
+ else:
+ if 'styleMapFamilyName' in infont.fontinfo:
+ family = infont.fontinfo['styleMapFamilyName'][1].text
+ elif 'familyName' in infont.fontinfo:
+ family = infont.fontinfo['familyName'][1].text
+ else:
+ family = "UnknownFamily"
+ if 'styleMapStyleName' in infont.fontinfo:
+ style = infont.fontinfo['styleMapStyleName'][1].text.capitalize()
+ elif 'styleName' in infont.fontinfo:
+ style = infont.fontinfo['styleName'][1].text
+ else:
+ style = "UnknownStyle"
+
+ postscriptFontName = '-'.join((family,style)).replace(' ','')
+ fontElement= ET.Element('font', upem=infont.fontinfo['unitsPerEm'][1].text, name=postscriptFontName)
+ for g, i in listorder:
+ attrib = {'PSName': g}
+ if args.gid and i != None: attrib['GID'] = str(i)
+ u = infont.deflayer[g]['unicode']
+ if len(u)>0: attrib['UID'] = prefix + u[0].element.get('hex')
+ glyphElement = ET.SubElement(fontElement, 'glyph', attrib)
+ anchorlist = []
+ for a in infont.deflayer[g]['anchor']:
+ anchorlist.append( (a.element.get('name'), int(float(a.element.get('x'))), int(float(a.element.get('y'))) ) )
+ anchorlist.sort()
+ for a, x, y in anchorlist:
+ anchorElement = ET.SubElement(glyphElement, 'point', attrib = {'type': a})
+ locationElement = ET.SubElement(anchorElement, 'location', attrib = {'x': str(x), 'y': str(y)})
+
+# instead of simple serialization with: ofile.write(ET.tostring(fontElement))
+# create ETWriter object and specify indentation and attribute order to get normalized output
+ ofile = args.output
+ indentFirst = args.params.get('indentFirst', "")
+ indentIncr = args.params.get('indentIncr', " ")
+ attOrder = args.params.get('attOrder', "name,upem,PSName,GID,UID,type,x,y")
+ x = attOrder.split(',')
+ attributeOrder = dict(zip(x,range(len(x))))
+ etwobj=ETWriter(fontElement, indentFirst=indentFirst, indentIncr=indentIncr, attributeOrder=attributeOrder)
+ ofile.write(etwobj.serialize_xml())
+
+def cmd() : execute("UFO",doit,argspec)
+if __name__ == "__main__": cmd()
diff --git a/lib/silfont/scripts/psfexportmarkcolors.py b/lib/silfont/scripts/psfexportmarkcolors.py
new file mode 100755
index 0000000..98beae1
--- /dev/null
+++ b/lib/silfont/scripts/psfexportmarkcolors.py
@@ -0,0 +1,55 @@
+#!/usr/bin/env python
+__doc__ = '''Write mapping of glyph name to cell mark color to a csv file
+- csv format glyphname,colordef'''
+__url__ = 'http://github.com/silnrsi/pysilfont'
+__copyright__ = 'Copyright (c) 2019 SIL International (http://www.sil.org)'
+__license__ = 'Released under the MIT License (http://opensource.org/licenses/MIT)'
+__author__ = 'Victor Gaultney'
+
+from silfont.core import execute
+from silfont.util import parsecolors, colortoname
+import datetime
+
+suffix = "_colormap"
+argspec = [
+ ('ifont',{'help': 'Input font file'}, {'type': 'infont'}),
+ ('-o','--output',{'help': 'Output csv file'}, {'type': 'outfile', 'def': suffix+'.csv'}),
+ ('-c','--color',{'help': 'Export list of glyphs that match color'},{}),
+ ('-n','--names',{'help': 'Export colors as names', 'action': 'store_true', 'default': False},{}),
+ ('-l','--log',{'help': 'Log file'}, {'type': 'outfile', 'def': suffix+'.log'}),
+ ('--nocomments',{'help': 'No comments in output files', 'action': 'store_true', 'default': False},{})]
+
+def doit(args) :
+ font = args.ifont
+ outfile = args.output
+ logger = args.logger
+ color = args.color
+
+ # Add initial comments to outfile
+ if not args.nocomments :
+ outfile.write("# " + datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S ") + args.cmdlineargs[0] + "\n")
+ outfile.write("# "+" ".join(args.cmdlineargs[1:])+"\n\n")
+
+ if color :
+ (colorfilter, colorname, logcolor, splitcolor) = parsecolors(color, single=True)
+ if colorfilter is None : logger.log(logcolor, "S") # If color not parsed, parsecolors() puts error in logcolor
+
+ glyphlist = font.deflayer.keys()
+
+ for glyphn in sorted(glyphlist) :
+ glyph = font.deflayer[glyphn]
+ colordefraw = ""
+ colordef = ""
+ if glyph["lib"] :
+ lib = glyph["lib"]
+ if "public.markColor" in lib :
+ colordefraw = lib["public.markColor"][1].text
+ colordef = '"' + colordefraw + '"'
+ if args.names : colordef = colortoname(colordefraw, colordef)
+ if color :
+ if colorfilter == colordefraw : outfile.write(glyphn + "\n")
+ if not color : outfile.write(glyphn + "," + colordef + "\n")
+ return
+
+def cmd() : execute("UFO",doit,argspec)
+if __name__ == "__main__": cmd()
diff --git a/lib/silfont/scripts/psfexportpsnames.py b/lib/silfont/scripts/psfexportpsnames.py
new file mode 100755
index 0000000..5995e14
--- /dev/null
+++ b/lib/silfont/scripts/psfexportpsnames.py
@@ -0,0 +1,47 @@
+#!/usr/bin/env python
+__doc__ = '''Write mapping of glyph name to postscript name to a csv file
+- csv format glyphname,postscriptname'''
+__url__ = 'http://github.com/silnrsi/pysilfont'
+__copyright__ = 'Copyright (c) 2016 SIL International (http://www.sil.org)'
+__license__ = 'Released under the MIT License (http://opensource.org/licenses/MIT)'
+__author__ = 'David Raymond'
+
+from silfont.core import execute
+import datetime
+
+suffix = "_psnamesmap"
+argspec = [
+ ('ifont',{'help': 'Input font file'}, {'type': 'infont'}),
+ ('-o','--output',{'help': 'Ouput csv file'}, {'type': 'outfile', 'def': suffix+'.csv'}),
+ ('-l','--log',{'help': 'Log file'}, {'type': 'outfile', 'def': suffix+'.log'}),
+ ('--nocomments',{'help': 'No comments in output files', 'action': 'store_true', 'default': False},{})]
+
+def doit(args) :
+ font = args.ifont
+ outfile = args.output
+
+ # Add initial comments to outfile
+ if not args.nocomments :
+ outfile.write("# " + datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S ") + args.cmdlineargs[0] + "\n")
+ outfile.write("# "+" ".join(args.cmdlineargs[1:])+"\n\n")
+
+ glyphlist = font.deflayer.keys()
+ missingnames = False
+
+ for glyphn in glyphlist :
+ glyph = font.deflayer[glyphn]
+ # Find PSname if present
+ PSname = None
+ if "lib" in glyph :
+ lib = glyph["lib"]
+ if "public.postscriptname" in lib : PSname = lib["public.postscriptname"][1].text
+ if PSname:
+ outfile.write(glyphn + "," + PSname + "\n")
+ else :
+ font.logger("No psname for " + glyphn, "W")
+ missingnames = True
+ if missingnames : font.logger("Some glyphs had no psnames - see log file","E")
+ return
+
+def cmd() : execute("UFO",doit,argspec)
+if __name__ == "__main__": cmd()
diff --git a/lib/silfont/scripts/psfexportunicodes.py b/lib/silfont/scripts/psfexportunicodes.py
new file mode 100755
index 0000000..c9e1be3
--- /dev/null
+++ b/lib/silfont/scripts/psfexportunicodes.py
@@ -0,0 +1,43 @@
+#!/usr/bin/env python
+__doc__ = '''Export the name and unicode of glyphs that have a defined unicode to a csv file. Does not support double-encoded glyphs.
+- csv format glyphname,unicode'''
+__url__ = 'http://github.com/silnrsi/pysilfont'
+__copyright__ = 'Copyright (c) 2016-2020 SIL International (http://www.sil.org)'
+__license__ = 'Released under the MIT License (http://opensource.org/licenses/MIT)'
+__author__ = 'Victor Gaultney, based on UFOexportPSname.py'
+
+from silfont.core import execute
+import datetime
+
+suffix = "_unicodes"
+argspec = [
+ ('ifont',{'help': 'Input font file'}, {'type': 'infont'}),
+ ('-o','--output',{'help': 'Output csv file'}, {'type': 'outfile', 'def': suffix+'.csv'}),
+ ('-l','--log',{'help': 'Log file'}, {'type': 'outfile', 'def': suffix+'.log'}),
+ ('--nocomments',{'help': 'No comments in output files', 'action': 'store_true', 'default': False},{}),
+ ('--allglyphs',{'help': 'Export names of all glyphs even without', 'action': 'store_true', 'default': False},{})]
+
+def doit(args) :
+ font = args.ifont
+ outfile = args.output
+
+ # Add initial comments to outfile
+ if not args.nocomments :
+ outfile.write("# " + datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S ") + args.cmdlineargs[0] + "\n")
+ outfile.write("# "+" ".join(args.cmdlineargs[1:])+"\n\n")
+
+ glyphlist = sorted(font.deflayer.keys())
+
+ for glyphn in glyphlist :
+ glyph = font.deflayer[glyphn]
+ if len(glyph["unicode"]) == 1 :
+ unival = glyph["unicode"][0].hex
+ outfile.write(glyphn + "," + unival + "\n")
+ else :
+ if args.allglyphs :
+ outfile.write(glyphn + "," + "\n")
+
+ return
+
+def cmd() : execute("UFO",doit,argspec)
+if __name__ == "__main__": cmd()
diff --git a/lib/silfont/scripts/psffixffglifs.py b/lib/silfont/scripts/psffixffglifs.py
new file mode 100755
index 0000000..f496737
--- /dev/null
+++ b/lib/silfont/scripts/psffixffglifs.py
@@ -0,0 +1,48 @@
+#!/usr/bin/env python
+__doc__ = '''Make changes needed to a UFO following processing by FontForge.
+'''
+__url__ = 'http://github.com/silnrsi/pysilfont'
+__copyright__ = 'Copyright (c) 2019 SIL International (http://www.sil.org)'
+__license__ = 'Released under the MIT License (http://opensource.org/licenses/MIT)'
+__author__ = 'David Raymond'
+
+from silfont.core import execute
+
+argspec = [
+ ('ifont',{'help': 'Input font file'}, {'type': 'infont'}),
+ ('ofont',{'help': 'Output font file','nargs': '?' }, {'type': 'outfont'}),
+ ('-l','--log',{'help': 'Log file'}, {'type': 'outfile', 'def': '_postff.log'})]
+
+def doit(args) :
+
+ font = args.ifont
+ logger = args.logger
+
+ advances_removed = 0
+ unicodes_removed = 0
+ for layer in font.layers:
+ if layer.layername == "public.background":
+ for g in layer:
+ glyph = layer[g]
+ # Remove advance and unicode fields from background layer
+ # (FF currently copies some from default layer)
+ if "advance" in glyph:
+ glyph.remove("advance")
+ advances_removed += 1
+ logger.log("Removed <advance> from " + g, "I")
+ uc = glyph["unicode"]
+ if uc != []:
+ while glyph["unicode"] != []: glyph.remove("unicode",0)
+ unicodes_removed += 1
+ logger.log("Removed unicode value(s) from " + g, "I")
+
+ if advances_removed + unicodes_removed > 0 :
+ logger.log("Advance removed from " + str(advances_removed) + " glyphs and unicode values(s) removed from "
+ + str(unicodes_removed) + " glyphs", "P")
+ else:
+ logger.log("No advances or unicodes removed from glyphs", "P")
+
+ return args.ifont
+
+def cmd() : execute("UFO",doit, argspec)
+if __name__ == "__main__": cmd()
diff --git a/lib/silfont/scripts/psffixfontlab.py b/lib/silfont/scripts/psffixfontlab.py
new file mode 100755
index 0000000..c83868f
--- /dev/null
+++ b/lib/silfont/scripts/psffixfontlab.py
@@ -0,0 +1,169 @@
+#!/usr/bin/env python
+__doc__ = '''Make changes needed to a UFO following processing by FontLab 7.
+Various items are reset using the backup of the original font that Fontlab creates
+'''
+__url__ = 'http://github.com/silnrsi/pysilfont'
+__copyright__ = 'Copyright (c) 2021 SIL International (http://www.sil.org)'
+__license__ = 'Released under the MIT License (http://opensource.org/licenses/MIT)'
+__author__ = 'David Raymond'
+
+from silfont.core import execute, splitfn
+from silfont.ufo import Ufont
+import os, shutil, glob
+
+argspec = [
+ ('ifont',{'help': 'Input font file'}, {'type': 'filename'}),
+ ('-l','--log',{'help': 'Log file'}, {'type': 'outfile', 'def': '_fixfontlab.log'})]
+
+def doit(args) :
+
+ fontname = args.ifont
+ logger = args.logger
+ params = args.paramsobj
+
+ # Locate the oldest backup
+ (path, base, ext) = splitfn(fontname)
+ backuppath = os.path.join(path, base + ".*-*" + ext) # Backup has date/time added in format .yymmdd-hhmm
+ backups = glob.glob(backuppath)
+ if len(backups) == 0:
+ logger.log("No backups found matching %s so no changes made to the font" % backuppath, "P")
+ return
+ backupname = sorted(backups)[0] # Choose the oldest backup - date/time format sorts alphabetically
+
+ # Reset groups.plist, kerning.plist and any layerinfo.plist(s) from backup ufo
+ for filename in ["groups.plist", "kerning.plist"]:
+ bufullname = os.path.join(backupname, filename)
+ ufofullname = os.path.join(fontname, filename)
+ if os.path.exists(bufullname):
+ try:
+ shutil.copy(bufullname, fontname)
+ logger.log(filename + " restored from backup", "P")
+ except Exception as e:
+ logger.log("Failed to copy %s to %s: %s" % (bufullname, fontname, str(e)), "S")
+ elif os.path.exists(ufofullname):
+ os.remove(ufofullname)
+ logger.log(filename + " removed from ufo", "P")
+ lifolders = []
+ for ufoname in (fontname, backupname): # Find any layerinfo files in either ufo
+ lis = glob.glob(os.path.join(ufoname, "*/layerinfo.plist"))
+ for li in lis:
+ (lifolder, dummy) = os.path.split(li) # Get full path name for folder
+ (dummy, lifolder) = os.path.split(lifolder) # Now take ufo name off the front
+ if lifolder not in lifolders: lifolders.append(lifolder)
+ for folder in lifolders:
+ filename = os.path.join(folder, "layerinfo.plist")
+ bufullname = os.path.join(backupname, filename)
+ ufofullname = os.path.join(fontname, filename)
+ if os.path.exists(bufullname):
+ try:
+ shutil.copy(bufullname, os.path.join(fontname, folder))
+ logger.log(filename + " restored from backup", "P")
+ except Exception as e:
+ logger.log("Failed to copy %s to %s: %s" % (bufullname, fontname, str(e)), "S")
+ elif os.path.exists(ufofullname):
+ os.remove(ufofullname)
+ logger.log(filename + " removed from ufo", "P")
+
+ # Now open the fonts
+ font = Ufont(fontname, params = params)
+ backupfont = Ufont(backupname, params = params)
+
+ fidel = ("openTypeGaspRangeRecords", "openTypeHeadFlags", "openTypeHheaCaretOffset",
+ "postscriptBlueFuzz", "postscriptBlueScale", "postscriptBlueShift", "postscriptForceBold",
+ "postscriptIsFixedPitch", "postscriptWeightName")
+ libdel = ("com.fontlab.v2.tth", "com.typemytype.robofont.italicSlantOffset")
+ fontinfo = font.fontinfo
+ libplist = font.lib
+ backupfi = backupfont.fontinfo
+ backuplib = backupfont.lib
+
+ # Delete keys that are not needed
+ for key in fidel:
+ if key in fontinfo:
+ old = fontinfo.getval(key)
+ fontinfo.remove(key)
+ logchange(logger, " removed from fontinfo.plist. ", key, old, None)
+ for key in libdel:
+ if key in libplist:
+ old = libplist.getval(key)
+ libplist.remove(key)
+ logchange(logger, " removed from lib.plist. ", key, old, None)
+
+ # Correct other metadata:
+ if "guidelines" in backupfi:
+ fontinfo.setelem("guidelines",backupfi["guidelines"][1])
+ logger.log("fontinfo guidelines copied from backup ufo", "I")
+ elif "guidelines" in fontinfo:
+ fontinfo.remove("guidelines")
+ logger.log("fontinfo guidelines deleted - not in backup ufo", "I")
+ if "italicAngle" in fontinfo and fontinfo.getval("italicAngle") == 0:
+ fontinfo.remove("italicAngle")
+ logger.log("fontinfo italicAngle removed since it was 0", "I")
+ if "openTypeOS2VendorID" in fontinfo:
+ old = fontinfo.getval("openTypeOS2VendorID")
+ if len(old) < 4:
+ new = "%-4s" % (old,)
+ fontinfo.setval("openTypeOS2VendorID", "string", new)
+ logchange(logger, " padded to 4 characters ", "openTypeOS2VendorID", "'%s'" % (old,) , "'%s'" % (new,))
+ if "woffMetadataCredits" in backupfi:
+ fontinfo.setelem("woffMetadataCredits",backupfi["woffMetadataCredits"][1])
+ logger.log("fontinfo woffMetadataCredits copied from backup ufo", "I")
+ elif "woffMetadataCredits" in fontinfo:
+ fontinfo.remove("woffMetadataCredits")
+ logger.log("fontinfo woffMetadataCredits deleted - not in backup ufo", "I")
+ if "woffMetadataDescription" in backupfi:
+ fontinfo.setelem("woffMetadataDescription",backupfi["woffMetadataDescription"][1])
+ logger.log("fontinfo woffMetadataDescription copied from backup ufo", "I")
+ elif "woffMetadataDescription" in fontinfo:
+ fontinfo.remove("woffMetadataDescription")
+ logger.log("fontinfo woffMetadataDescription deleted - not in backup ufo", "I")
+ if "public.glyphOrder" in backuplib:
+ libplist.setelem("public.glyphOrder",backuplib["public.glyphOrder"][1])
+ logger.log("lib.plist public.glyphOrder copied from backup ufo", "I")
+ elif "public.glyphOrder" in libplist:
+ libplist.remove("public.glyphOrder")
+ logger.log("libplist public.glyphOrder deleted - not in backup ufo", "I")
+
+
+
+ # Now process glif level data
+ updates = False
+ for gname in font.deflayer:
+ glyph = font.deflayer[gname]
+ glines = glyph["guideline"]
+ if glines:
+ for gl in list(glines): glines.remove(gl) # Remove any existing glines
+ updates = True
+ buglines = backupfont.deflayer[gname]["guideline"] if gname in backupfont.deflayer else []
+ if buglines:
+ for gl in buglines: glines.append(gl) # Add in those from backup
+ updates = True
+ if updates:
+ logger.log("Some updates to glif guidelines may have been made", "I")
+ updates = False
+ for layer in font.layers:
+ if layer.layername == "public.background":
+ for gname in layer:
+ glyph = layer[gname]
+ if glyph["advance"] is not None:
+ glyph.remove("advance")
+ updates = True
+ if updates: logger.log("Some advance elements removed from public.background glifs", "I")
+ font.write(fontname)
+ return
+
+def logchange(logger, logmess, key, old, new):
+ oldstr = str(old) if len(str(old)) < 22 else str(old)[0:20] + "..."
+ newstr = str(new) if len(str(new)) < 22 else str(new)[0:20] + "..."
+ logmess = key + logmess
+ if old is None:
+ logmess = logmess + " New value: " + newstr
+ else:
+ if new is None:
+ logmess = logmess + " Old value: " + oldstr
+ else:
+ logmess = logmess + " Old value: " + oldstr + ", new value: " + newstr
+ logger.log(logmess, "I")
+
+def cmd() : execute(None,doit, argspec)
+if __name__ == "__main__": cmd()
diff --git a/lib/silfont/scripts/psfftml2TThtml.py b/lib/silfont/scripts/psfftml2TThtml.py
new file mode 100755
index 0000000..e9e1128
--- /dev/null
+++ b/lib/silfont/scripts/psfftml2TThtml.py
@@ -0,0 +1,389 @@
+#! /usr/bin/python3
+'''Build fonts for all combinations of TypeTuner features needed for specific ftml then build html that uses those fonts'''
+__url__ = 'http://github.com/silnrsi/pysilfont'
+__copyright__ = 'Copyright (c) 2019 SIL International (http://www.sil.org)'
+__license__ = 'Released under the MIT License (http://opensource.org/licenses/MIT)'
+__author__ = 'Bob Hallissy'
+
+from silfont.core import execute
+from fontTools import ttLib
+from lxml import etree as ET # using this because it supports xslt and HTML
+from collections import OrderedDict
+from subprocess import check_output, CalledProcessError
+import os, re
+import gzip
+from glob import glob
+
+
+argspec = [
+ ('ttfont', {'help': 'Input Tunable TTF file'}, {'type': 'filename'}),
+ ('map', {'help': 'Feature mapping CSV file'}, {'type': 'incsv'}),
+ ('-o', '--outputdir', {'help': 'Output directory. Default: tests/typetuner', 'default': 'tests/typetuner'}, {}),
+ ('--ftml', {'help': 'ftml file(s) to process. Can be used multiple times and can contain filename patterns.', 'action': 'append'}, {}),
+ ('--xsl', {'help': 'standard xsl file. Default: ../tools/ftml.xsl', 'default': '../tools/ftml.xsl'}, {'type': 'filename'}),
+ ('--norebuild', {'help': 'assume existing fonts are good', 'action': 'store_true'}, {}),
+ ]
+
+# Define globals needed everywhere:
+
+logger = None
+sourcettf = None
+outputdir = None
+fontdir = None
+
+
+# Dictionary of TypeTuner features, derived from 'feat_all.xml', indexed by feature name
+feat_all = dict()
+
+class feat(object):
+ 'TypeTuner feature'
+ def __init__(self, elem, sortkey):
+ self.name = elem.attrib.get('name')
+ self.tag = elem.attrib.get('tag')
+ self.default = elem.attrib.get('value')
+ self.values = OrderedDict()
+ self.sortkey = sortkey
+ for v in elem.findall('value'):
+ # Only add those values which aren't importing line metrics
+ if v.find("./cmd[@name='line_metrics_scaled']") is None:
+ self.values[v.attrib.get('name')] = v.attrib.get('tag')
+
+
+# Dictionaries of mappings from OpenType tags to TypeTuner names, derived from map csv
+feat_maps = dict()
+lang_maps = dict()
+
+class feat_map(object):
+ 'mapping from OpenType feature tag to TypeTuner feature name, default value, and all values'
+ def __init__(self, r):
+ self.ottag, self.ttfeature, self.default = r[0:3]
+ self.ttvalues = r[3:]
+
+class lang_map(object):
+ 'mapping from OpenType language tag to TypeTuner language feature name and value'
+ def __init__(self,r):
+ self.ottag, self.ttfeature, self.ttvalue = r
+
+# About font_tag values
+#
+# In this code, a font_tag uniquely identifies a font we've built.
+#
+# Because different ftml files could use different style names for the same set of features and language, and we
+# want to build only one font for any given combination of features and language, we don't depend on the name of the
+# ftml style for identifying and caching the fonts we build. Rather we build a font_tag which is a the
+# concatenation of the ftml feature/value tags and the ftml lang feature/value tag.
+
+# Font object used to cache information about a tuned font we've created
+
+class font(object):
+ 'Cache of tuned font information'
+
+ def __init__(self, font_tag, feats, lang, fontface):
+ self.font_tag = font_tag
+ self.feats = feats
+ self.lang = lang
+ self.fontface = fontface
+
+
+# Dictionaries for finding font objects
+
+# Finding font from font_tag:
+font_tag2font = dict()
+
+# If an ftml style contains no feats, only the lang tag will show up in the html. Special mapping for those cases:
+lang2font = dict()
+
+# RE to match strings like: # "'cv02' 1"
+feature_settingRE = re.compile(r"^'(\w{4,4})'(?:\s+(\w+))?$")
+# RE to split strings of multiple features around comma (with optional whitespace)
+features_splitRE = re.compile(r"\s*,\s*")
+
+
+def cache_font(feats, lang, norebuild):
+ 'Create (and cache) a TypeTuned font and @fontface for this combination of features and lang'
+
+ # feats is either None or a css font-feature-settings string using single quotes (according to ftml spec), e.g. "'cv02' 1, 'cv60' 1"
+ # lang is either None or bcp47 langtag
+ # norebuild is a debugging aid that causes the code to skip building a .ttf if it is already present thus making the
+ # program run faster but with the risk that the built TTFs don't match the current build.
+
+ # First step is to construct a name for this set of languages and features, something we'll call the "font tag"
+
+ parts = []
+ ttsettings = dict() # place to save TT setting name and value in case we need to build the font
+ fatal_errors = False
+
+ if feats:
+ # Need to split the font-feature-settings around commas and parse each part, mapping css tag and value to
+ # typetuner tag and value
+ for setting in features_splitRE.split(feats):
+ m = feature_settingRE.match(setting)
+ if m is None:
+ logger.log('Invalid CSS feature setting in ftml: {}'.format(setting), 'E')
+ fatal_errors = True
+ continue
+ f,v = m.groups() # Feature tag and value
+ if v in ['normal','off']:
+ v = '0'
+ elif v == 'on':
+ v = '1'
+ try:
+ v = int(v)
+ assert v >= 0
+ except:
+ logger.log('Invalid feature value {} found in map file'.format(setting), 'E')
+ fatal_errors = True
+ continue
+ if not v:
+ continue # No need to include 0/off values
+
+ # we need this one... so translate to TypeTuner feature & value using the map file
+ try:
+ fmap = feat_maps[f]
+ except KeyError:
+ logger.log('Font feature "{}" not found in map file'.format(f), 'E')
+ fatal_errors = True
+ continue
+
+ f = fmap.ttfeature
+
+ try:
+ v = fmap.ttvalues[v - 1]
+ except IndexError:
+ logger.log('TypeTuner feature "{}" doesn\'t have a value index {}'.format(f, v), 'E')
+ fatal_errors = True
+ continue
+
+ # Now translate to TypeTuner tags using feat_all info
+ if f not in feat_all:
+ logger.log('Tunable font doesn\'t contain a feature "{}"'.format(f), 'E')
+ fatal_errors = True
+ elif v not in feat_all[f].values:
+ logger.log('Tunable font feature "{}" doesn\'t have a value {}'.format(f, v), 'E')
+ fatal_errors = True
+ else:
+ ttsettings[f] = v # Save TT setting name and value name in case we need to build the font
+ ttfeat = feat_all[f]
+ f = ttfeat.tag
+ v = ttfeat.values[v]
+ # Finally!
+ parts.append(f+v)
+ if lang:
+ if lang not in lang_maps:
+ logger.log('Language tag "{}" not found in map file'.format(lang), 'E')
+ fatal_errors = True
+ else:
+ # Translate to TypeTuner feature & value using the map file
+ lmap = lang_maps[lang]
+ f = lmap.ttfeature
+ v = lmap.ttvalue
+ # Translate to TypeTuner tags using feat_all info
+ if f not in feat_all:
+ logger.log('Tunable font doesn\'t contain a feature "{}"'.format(f), 'E')
+ fatal_errors = True
+ elif v not in feat_all[f].values:
+ logger.log('Tunable font feature "{}" doesn\'t have a value {}'.format(f, v), 'E')
+ fatal_errors = True
+ else:
+ ttsettings[f] = v # Save TT setting name and value in case we need to build the font
+ ttfeat = feat_all[f]
+ f = ttfeat.tag
+ v = ttfeat.values[v]
+ # Finally!
+ parts.append(f+v)
+ if fatal_errors:
+ return None
+
+ if len(parts) == 0:
+ logger.log('No features or languages found'.format(f), 'E')
+ return None
+
+ # the Font Tag is how we name everything (the ttf, the xml, etc)
+ font_tag = '_'.join(sorted(parts))
+
+ # See if we've had this combination before:
+ if font_tag in font_tag2font:
+ logger.log('Found cached font {}'.format(font_tag), 'I')
+ return font_tag
+
+ # Path to font, which may already exist, and @fontface
+ ttfname = os.path.join(fontdir, font_tag + '.ttf')
+ fontface = '@font-face { font-family: {}; src: url(fonts/{}.ttf); } .{} {font-family: {}; }'.replace('{}',font_tag)
+
+ # Create new font object and remember how to find it:
+ thisfont = font(font_tag, feats, lang, fontface)
+ font_tag2font[font_tag] = thisfont
+ if lang and not feats:
+ lang2font[lang] = thisfont
+
+ # Debugging shortcut: use the existing fonts without rebuilding
+ if norebuild and os.path.isfile(ttfname):
+ logger.log('Blindly using existing font {}'.format(font_tag), 'I')
+ return font_tag
+
+ # Ok, need to build the font
+ logger.log('Building font {}'.format(font_tag), 'I')
+
+ # Create and save the TypeTuner feature settings file
+ sfname = os.path.join(fontdir, font_tag + '.xml')
+ root = ET.XML('''\
+<?xml version = "1.0"?>
+<!DOCTYPE features_set SYSTEM "feat_set.dtd">
+<features_set version = "1.0"/>
+''')
+ # Note: Order of elements in settings file should be same as order in feat_all
+ # (because this is the way TypeTuner does it and some fonts may expect this)
+ for name, ttfeat in sorted(feat_all.items(), key=lambda x: x[1].sortkey):
+ if name in ttsettings:
+ # Output the non-default value for this one:
+ ET.SubElement(root, 'feature',{'name': name, 'value': ttsettings[name]})
+ else:
+ ET.SubElement(root, 'feature', {'name': name, 'value': ttfeat.default})
+ xml = ET.tostring(root,pretty_print = True, encoding='UTF-8', xml_declaration=True)
+ with open(sfname, '+wb')as f:
+ f.write(xml)
+
+ # Now invoke TypeTuner to create the tuned font
+ try:
+ cmd = ['typetuner', '-o', ttfname, '-n', font_tag, sfname, sourcettf]
+ res = check_output(cmd)
+ if len(res):
+ print('\n', res)
+ except CalledProcessError as err:
+ logger.log("couldn't tune font: {}".format(err.output), 'S')
+
+ return font_tag
+
+def doit(args) :
+
+ global logger, sourcettf, outputdir, fontdir
+
+ logger = args.logger
+ sourcettf = args.ttfont
+
+ # Create output directory, including fonts subdirectory, if not present
+ outputdir = args.outputdir
+ os.makedirs(outputdir, exist_ok = True)
+ fontdir = os.path.join(outputdir, 'fonts')
+ os.makedirs(fontdir, exist_ok = True)
+
+ # Read and save feature mapping
+ for r in args.map:
+ # remove empty cells from the end
+ while len(r) and len(r[-1]) == 0:
+ r.pop()
+ if len(r) == 0 or r[0].startswith('#'):
+ continue
+ elif r[0].startswith('lang='):
+ if len(r[0]) < 7 or len(r) != 3:
+ logger.log("Invalid lang mapping: '" + ','.join(r) + "' ignored", "W")
+ else:
+ r[0] = r[0][5:]
+ lang_maps[r[0]] = lang_map(r)
+ else:
+ if len(r) < 4:
+ logger.log("Invalid feature mapping: '" + ','.join(r) + "' ignored", "W")
+ else:
+ feat_maps[r[0]] = feat_map(r)
+
+ # Open and verify input file is a tunable font; extract and parse feat_all from font.
+ font = ttLib.TTFont(sourcettf)
+ raw_data = font.getTableData('Silt')
+ feat_xml = gzip.decompress(raw_data) # .decode('utf-8')
+ root = ET.fromstring(feat_xml)
+ if root.tag != 'all_features':
+ logger.log("Invalid TypeTuner feature file: missing root element", "S")
+ for i, f in enumerate(root.findall('.//feature')):
+ # add to dictionary
+ ttfeat = feat(f,i)
+ feat_all[ttfeat.name] = ttfeat
+
+ # Open and prepare the xslt file to transform the ftml:
+ xslt = ET.parse(args.xsl)
+ xslt_transform = ET.XSLT(xslt)
+
+
+ # Process all ftml files:
+
+ for arg in args.ftml:
+ for infname in glob(arg):
+ # based on input filename, construct output name
+ # find filename and change extension to html:
+ outfname = os.path.join(outputdir, os.path.splitext(os.path.basename(infname))[0] + '.html')
+ logger.log('Processing: {} -> {}'.format(infname, outfname), 'P')
+
+ # Each named style in the FTML ultimately maps to a TypeTuned font that will be added via @fontface.
+ # We need to remember the names of the styles and their associated fonts so we can hack the html.
+ sname2font = dict() # Indexed by ftml stylename; result is a font object
+
+ # Parse the FTML
+ ftml_doc = ET.parse(infname)
+
+ # Adjust <title> to show this is from TypeTuner
+ head = ftml_doc.find('head')
+ title = head.find('title')
+ title.text += " - TypeTuner"
+ # Replace all <fontsrc> elements with two identical from the input font:
+ # One will remain unchanged, the other will eventually be changed to a typetuned font.
+ ET.strip_elements(head, 'fontsrc')
+ fpathname = os.path.relpath(sourcettf, outputdir).replace('\\','/') # for css make sure all slashes are forward!
+ head.append(ET.fromstring('<fontsrc>url({})</fontsrc>'.format(fpathname))) # First font
+ head.append(ET.fromstring('<fontsrc>url({})</fontsrc>'.format(fpathname))) # Second font, same as the first
+
+ # iterate over all the styles in this ftml file, building tuned fonts to match if not already done.
+ for style in head.iter('style'):
+ sname = style.get('name') # e.g. "some_style"
+ feats = style.get('feats') # e.g "'cv02' 1, 'cv60' 1" -- this we'll parse to get need tt features
+ lang = style.get('lang') # e.g., "sd"
+ font_tag = cache_font(feats, lang, args.norebuild)
+ # font_tag could be None due to errors, but messages should already have been logged
+ # If it is valid, remember how to find this font from the ftml stylename
+ if font_tag:
+ sname2font[sname] = font_tag2font[font_tag]
+
+ # convert to html via supplied xslt
+ html_doc = xslt_transform(ftml_doc)
+
+ # Two modifications to make in the html:
+ # 1) add all @fontface specs to the <style> element
+ # 2) Fix up all occurrences of <td> elements referencing font2
+
+ # Add @fontface to <style>
+ style = html_doc.find('//style')
+ style.text = style.text + '\n' + '\n'.join([x.fontface for x in sname2font.values()])
+
+ # Iterate over all <td> elements looking for font2 and a style or lang indicating feature settings
+
+ classRE = re.compile(r'string\s+(?:(\w+)\s+)?font2$')
+
+ for td in html_doc.findall('//td'):
+ tdclass = td.get('class')
+ tdlang = td.get('lang')
+ m = classRE.match(tdclass)
+ if m:
+ sname = m.group(1)
+ if sname:
+ # stylename will get us directly to the font
+ try:
+ td.set('class', 'string {}'.format(sname2font[sname].font_tag))
+ if tdlang: # If there is also a lang attribute, we no longer need it.
+ del td.attrib['lang']
+ except KeyError:
+ logger.log("Style name {} not available.".format(sname), "W")
+ elif tdlang:
+ # Otherwise we'll assume there is only the lang attribute
+ try:
+ td.set('class', 'string {}'.format(lang2font[tdlang].font_tag))
+ del td.attrib['lang'] # lang attribute no longer needed.
+ except KeyError:
+ logger.log("Style for langtag {} not available.".format(tdlang), "W")
+
+
+ # Ok -- write the html out!
+ html = ET.tostring(html_doc, pretty_print=True, method='html', encoding='UTF-8')
+ with open(outfname, '+wb')as f:
+ f.write(html)
+
+
+def cmd() : execute(None,doit,argspec)
+if __name__ == "__main__": cmd()
diff --git a/lib/silfont/scripts/psfftml2odt.py b/lib/silfont/scripts/psfftml2odt.py
new file mode 100755
index 0000000..49777e4
--- /dev/null
+++ b/lib/silfont/scripts/psfftml2odt.py
@@ -0,0 +1,453 @@
+#!/usr/bin/env python
+__doc__ = 'read FTML file and generate LO writer .odt file'
+__url__ = 'http://github.com/silnrsi/pysilfont'
+__copyright__ = 'Copyright (c) 2015, SIL International (http://www.sil.org)'
+__license__ = 'Released under the MIT License (http://opensource.org/licenses/MIT)'
+__author__ = 'David Rowe'
+
+from silfont.core import execute
+from fontTools import ttLib
+from xml.etree import ElementTree as ET ### used to parse input FTML (may not be needed if FTML parser used)
+import re
+import os
+import io
+from odf.opendocument import OpenDocumentText, OpaqueObject
+from odf.config import ConfigItem, ConfigItemSet
+from odf.office import FontFaceDecls
+from odf.style import FontFace, ParagraphProperties, Style, TableCellProperties, TableColumnProperties, TableProperties, TextProperties
+from odf.svg import FontFaceSrc, FontFaceUri, FontFaceFormat
+from odf.table import Table, TableCell, TableColumn, TableRow
+from odf.text import H, P, SequenceDecl, SequenceDecls, Span
+
+# specify two parameters: input file (FTML/XML format), output file (ODT format)
+# preceded by optional log file plus zero or more font strings
+argspec = [
+ ('input',{'help': 'Input file in FTML format'}, {'type': 'infile'}),
+ ('output',{'help': 'Output file (LO writer .odt)', 'nargs': '?'}, {'type': 'filename', 'def': '_out.odt'}),
+ ('-l','--log',{'help': 'Log file', 'required': False},{'type': 'outfile', 'def': '_ftml2odt_log.txt'}),
+ ('-r','--report',{'help': 'Set reporting level for log', 'type':str, 'choices':['X','S','E','P','W','I','V']},{}),
+ ('-f','--font',{'help': 'font specification','action': 'append', 'required': False}, {}),
+ ]
+
+# RegExs for extracting font name from fontsrc element
+findfontnamelocal = re.compile(r"""local\( # begin with local(
+ (["']?) # optional open quote
+ (?P<fontstring>[^)]+) # font name
+ \1 # optional matching close quote
+ \)""", re.VERBOSE) # and end with )
+findfontnameurl = re.compile(r"""url\( # begin with local(
+ (["']?) # optional open quote
+ (?P<fontstring>[^)]+) # font name
+ \1 # optional matching close quote
+ \)""", re.VERBOSE) # and end with )
+fontspec = re.compile(r"""^ # beginning of string
+ (?P<rest>[A-Za-z ]+?) # Font Family Name
+ \s*(?P<bold>Bold)? # Bold
+ \s*(?P<italic>Italic)? # Italic
+ \s*(?P<regular>Regular)? # Regular
+ $""", re.VERBOSE) # end of string
+# RegEx for extracting feature(s) from feats attribute of style element
+onefeat = re.compile(r"""^\s*
+ '(?P<featname>[^']+)'\s* # feature tag
+ (?P<featval>[^', ]+)\s* # feature value
+ ,?\s* # optional comma
+ (?P<remainder>.*) # rest of line (with zero or more tag-value pairs)
+ $""", re.VERBOSE)
+# RegEx for extracting language (and country) from lang attribute of style element
+langcode = re.compile(r"""^
+ (?P<langname>[A-Za-z]+) # language name
+ (- # (optional) hyphen and
+ (?P<countryname>[A-Za-z]+) # country name
+ (-[A-Za-z0-9][-A-Za-z0-9]*)? # (optional) hyphen and other codes
+ )?$""", re.VERBOSE)
+# RegEx to extract hex value from \uxxxxxx and function to generate Unicode character
+# use to change string to newstring:
+# newstring = re.sub(backu, hextounichr, string)
+# or newstring = re.sub(backu, lambda m: unichr(int(m.group(1),16)), string)
+backu = re.compile(r"\\u([0-9a-fA-F]{4,6})")
+def hextounichr(match):
+ return chr(int(match.group(1),16))
+
+def BoldItalic(bold, italic):
+ rs = ""
+ if bold:
+ rs += " Bold"
+ if italic:
+ rs += " Italic"
+ return rs
+
+def parsefeats(inputline):
+ featdic = {}
+ while inputline != "":
+ results = re.match(onefeat, inputline)
+ if results:
+ featdic[results.group('featname')] = results.group('featval')
+ inputline = results.group('remainder')
+ else:
+ break ### warning about unrecognized feature string: inputline
+ return ":" + "&".join( [f + '=' + featdic[f] for f in sorted(featdic)])
+
+def getfonts(fontsourcestrings, logfile, fromcommandline=True):
+ fontlist = []
+ checkfontfamily = []
+ checkembeddedfont = []
+ for fs in fontsourcestrings:
+ if not fromcommandline: # from FTML <fontsrc> either local() or url()
+ installed = True # Assume locally installed font
+ results = re.match(findfontnamelocal, fs)
+ fontstring = results.group('fontstring') if results else None
+ if fontstring == None:
+ installed = False
+ results = re.match(findfontnameurl, fs)
+ fontstring = results.group('fontstring') if results else None
+ if fontstring == None:
+ logfile.log("Invalid font specification: " + fs, "S")
+ else: # from command line
+ fontstring = fs
+ if "." in fs: # must be a filename
+ installed = False
+ else: # must be an installed font
+ installed = True
+ if installed:
+ # get name, bold and italic info from string
+ results = re.match(fontspec, fontstring.strip())
+ if results:
+ fontname = results.group('rest')
+ bold = results.group('bold') != None
+ italic = results.group('italic') != None
+ fontlist.append( (fontname, bold, italic, None) )
+ if (fontname, bold, italic) in checkfontfamily:
+ logfile.log("Duplicate font specification: " + fs, "W") ### or more severe?
+ else:
+ checkfontfamily.append( (fontname, bold, italic) )
+ else:
+ logfile.log("Invalid font specification: " + fontstring.strip(), "E")
+ else:
+ try:
+ # peek inside the font for the name, weight, style
+ f = ttLib.TTFont(fontstring)
+ # take name from name table, NameID 1, platform ID 3, Encoding ID 1 (possible fallback platformID 1, EncodingID =0)
+ n = f['name'] # name table from font
+ fontname = n.getName(1,3,1).toUnicode() # nameID 1 = Font Family name
+ # take bold and italic info from OS/2 table, fsSelection bits 0 and 5
+ o = f['OS/2'] # OS/2 table
+ italic = (o.fsSelection & 1) > 0
+ bold = (o.fsSelection & 32) > 0
+ fontlist.append( (fontname, bold, italic, fontstring) )
+ if (fontname, bold, italic) in checkfontfamily:
+ logfile.log("Duplicate font specification: " + fs + BoldItalic(bold, italic), "W") ### or more severe?
+ else:
+ checkfontfamily.append( (fontname, bold, italic) )
+ if (os.path.basename(fontstring)) in checkembeddedfont:
+ logfile.log("Duplicate embedded font: " + fontstring, "W") ### or more severe?
+ else:
+ checkembeddedfont.append(os.path.basename(fontstring))
+ except IOError:
+ logfile.log("Unable to find font file to embed: " + fontstring, "E")
+ except fontTools.ttLib.TTLibError:
+ logfile.log("File is not a valid font: " + fontstring, "E")
+ except:
+ logfile.log("Error occurred while checking font: " + fontstring, "E") # some other error
+ return fontlist
+
+def init(LOdoc, numfonts=1):
+ totalwid = 6800 #6.8inches
+
+ #compute column widths
+ f = min(numfonts,4)
+ ashare = 4*(6-f)
+ dshare = 2*(6-f)
+ bshare = 100 - 2*ashare - dshare
+ awid = totalwid * ashare // 100
+ dwid = totalwid * dshare // 100
+ bwid = totalwid * bshare // (numfonts * 100)
+
+ # create styles for table, for columns (one style for each column width)
+ # and for one cell (used for everywhere except where background changed)
+ tstyle = Style(name="Table1", family="table")
+ tstyle.addElement(TableProperties(attributes={'width':str(totalwid/1000.)+"in", 'align':"left"}))
+ LOdoc.automaticstyles.addElement(tstyle)
+ tastyle = Style(name="Table1.A", family="table-column")
+ tastyle.addElement(TableColumnProperties(attributes={'columnwidth':str(awid/1000.)+"in"}))
+ LOdoc.automaticstyles.addElement(tastyle)
+ tbstyle = Style(name="Table1.B", family="table-column")
+ tbstyle.addElement(TableColumnProperties(attributes={'columnwidth':str(bwid/1000.)+"in"}))
+ LOdoc.automaticstyles.addElement(tbstyle)
+ tdstyle = Style(name="Table1.D", family="table-column")
+ tdstyle.addElement(TableColumnProperties(attributes={'columnwidth':str(dwid/1000.)+"in"}))
+ LOdoc.automaticstyles.addElement(tdstyle)
+ ta1style = Style(name="Table1.A1", family="table-cell")
+ ta1style.addElement(TableCellProperties(attributes={'padding':"0.035in", 'border':"0.05pt solid #000000"}))
+ LOdoc.automaticstyles.addElement(ta1style)
+ # text style used with non-<em> text
+ t1style = Style(name="T1", family="text")
+ t1style.addElement(TextProperties(attributes={'color':"#999999" }))
+ LOdoc.automaticstyles.addElement(t1style)
+ # create styles for Title, Subtitle
+ tstyle = Style(name="Title", family="paragraph")
+ tstyle.addElement(TextProperties(attributes={'fontfamily':"Arial",'fontsize':"24pt",'fontweight':"bold" }))
+ LOdoc.styles.addElement(tstyle)
+ ststyle = Style(name="Subtitle", family="paragraph")
+ ststyle.addElement(TextProperties(attributes={'fontfamily':"Arial",'fontsize':"18pt",'fontweight':"bold" }))
+ LOdoc.styles.addElement(ststyle)
+
+def doit(args) :
+ logfile = args.logger
+ if args.report: logfile.loglevel = args.report
+
+ try:
+ root = ET.parse(args.input).getroot()
+ except:
+ logfile.log("Error parsing FTML input", "S")
+
+ if args.font: # font(s) specified on command line
+ fontlist = getfonts( args.font, logfile )
+ else: # get font spec from FTML fontsrc element
+ fontlist = getfonts( [root.find("./head/fontsrc").text], logfile, False )
+ #fontlist = getfonts( [fs.text for fs in root.findall("./head/fontsrc")], False ) ### would allow multiple fontsrc elements
+ numfonts = len(fontlist)
+ if numfonts == 0:
+ logfile.log("No font(s) specified", "S")
+ if numfonts > 1:
+ formattedfontnum = ["{0:02d}".format(n) for n in range(numfonts)]
+ else:
+ formattedfontnum = [""]
+ logfile.log("Font(s) specified:", "V")
+ for n, (fontname, bold, italic, embeddedfont) in enumerate(fontlist):
+ logfile.log(" " + formattedfontnum[n] + " " + fontname + BoldItalic(bold, italic) + " " + str(embeddedfont), "V")
+
+ # get optional fontscale; compute pointsize as int(12*fontscale/100). If result xx is not 12, then add "fo:font-size=xxpt" in Px styles
+ pointsize = 12
+ fontscaleel = root.find("./head/fontscale")
+ if fontscaleel != None:
+ fontscale = fontscaleel.text
+ try:
+ pointsize = int(int(fontscale)*12/100)
+ except ValueError:
+ # any problem leaves pointsize 12
+ logfile.log("Problem with fontscale value; defaulting to 12 point", "W")
+
+ # Get FTML styles and generate LO writer styles
+ # P2 is paragraph style for string element when no features specified
+ # each Px (for P3...) corresponds to an FTML style, which specifies lang or feats or both
+ # if numfonts > 1, two-digit font number is appended to make an LO writer style for each FTML style + font combo
+ # When LO writer style is used with attribute rtl="True", "R" appended to style name
+ LOstyles = {}
+ ftmlstyles = {}
+ Pstylenum = 2
+ LOstyles["P2"] = ("", None, None)
+ ftmlstyles[0] = "P2"
+ for s in root.findall("./head/styles/style"):
+ Pstylenum += 1
+ Pnum = "P" + str(Pstylenum)
+ featstring = ""
+ if s.get('feats'):
+ featstring = parsefeats(s.get('feats'))
+ langname = None
+ countryname = None
+ lang = s.get('lang')
+ if lang != None:
+ x = re.match(langcode, lang)
+ langname = x.group('langname')
+ countryname = x.group('countryname')
+ # FTML <test> element @stylename attribute references this <style> element @name attribute
+ ftmlstyles[s.get('name')] = Pnum
+ LOstyles[Pnum] = (featstring, langname, countryname)
+
+ # create LOwriter file and construct styles for tables, column widths, etc.
+ LOdoc = OpenDocumentText()
+ init(LOdoc, numfonts)
+ # Initialize sequence counters
+ sds = SequenceDecls()
+ sd = sds.addElement(SequenceDecl(displayoutlinelevel = '0', name = 'Illustration'))
+ sd = sds.addElement(SequenceDecl(displayoutlinelevel = '0', name = 'Table'))
+ sd = sds.addElement(SequenceDecl(displayoutlinelevel = '0', name = 'Text'))
+ sd = sds.addElement(SequenceDecl(displayoutlinelevel = '0', name = 'Drawing'))
+ LOdoc.text.addElement(sds)
+
+ # Create Px style for each (featstring, langname, countryname) tuple in LOstyles
+ # and for each font (if >1 font, append to Px style name a two-digit number corresponding to the font in fontlist)
+ # and (if at least one rtl attribute) suffix of nothing or "R"
+ # At the same time, collect info for creating FontFace elements (and any embedded fonts)
+ suffixlist = ["", "R"] if root.find(".//test/[@rtl='True']") != None else [""]
+ fontfaces = {}
+ for p in sorted(LOstyles, key = lambda x : int(x[1:])): # key = lambda x : int(x[1:]) corrects sort order
+ featstring, langname, countryname = LOstyles[p]
+ for n, (fontname, bold, italic, embeddedfont) in enumerate(fontlist): # embeddedfont = None if no embedding needed
+ fontnum = formattedfontnum[n]
+ # Collect fontface info: need one for each font family + feature combination
+ # Put embedded font in list only under fontname with empty featstring
+ if (fontname, featstring) not in fontfaces:
+ fontfaces[ (fontname, featstring) ] = []
+ if embeddedfont:
+ if (fontname, "") not in fontfaces:
+ fontfaces[ (fontname, "") ] = []
+ if embeddedfont not in fontfaces[ (fontname, "") ]:
+ fontfaces[ (fontname, "") ].append(embeddedfont)
+ # Generate paragraph styles
+ for s in suffixlist:
+ pstyle = Style(name=p+fontnum+s, family="paragraph")
+ if s == "R":
+ pstyle.addElement(ParagraphProperties(textalign="end", justifysingleword="false", writingmode="rl-tb"))
+ pstyledic = {}
+ pstyledic['fontnamecomplex'] = \
+ pstyledic['fontnameasian'] =\
+ pstyledic['fontname'] = fontname + featstring
+ pstyledic['fontsizecomplex'] = \
+ pstyledic['fontsizeasian'] = \
+ pstyledic['fontsize'] = str(pointsize) + "pt"
+ if bold:
+ pstyledic['fontweightcomplex'] = \
+ pstyledic['fontweightasian'] = \
+ pstyledic['fontweight'] = 'bold'
+ if italic:
+ pstyledic['fontstylecomplex'] = \
+ pstyledic['fontstyleasian'] = \
+ pstyledic['fontstyle'] = 'italic'
+ if langname != None:
+ pstyledic['languagecomplex'] = \
+ pstyledic['languageasian'] = \
+ pstyledic['language'] = langname
+ if countryname != None:
+ pstyledic['countrycomplex'] = \
+ pstyledic['countryasian'] = \
+ pstyledic['country'] = countryname
+ pstyle.addElement(TextProperties(attributes=pstyledic))
+# LOdoc.styles.addElement(pstyle) ### tried this, but when saving the generated odt, LO changed them to automatic styles
+ LOdoc.automaticstyles.addElement(pstyle)
+
+ fontstoembed = []
+ for fontname, featstring in sorted(fontfaces): ### Or find a way to keep order of <style> elements from original FTML?
+ ff = FontFace(name=fontname + featstring, fontfamily=fontname + featstring, fontpitch="variable")
+ LOdoc.fontfacedecls.addElement(ff)
+ if fontfaces[ (fontname, featstring) ]: # embedding needed for this combination
+ for fontfile in fontfaces[ (fontname, featstring) ]:
+ fontstoembed.append(fontfile) # make list for embedding
+ ffsrc = FontFaceSrc()
+ ffuri = FontFaceUri( **{'href': "Fonts/" + os.path.basename(fontfile), 'type': "simple"} )
+ ffformat = FontFaceFormat( **{'string': 'truetype'} )
+ ff.addElement(ffsrc)
+ ffsrc.addElement(ffuri)
+ ffuri.addElement(ffformat)
+
+ basename = "Table1.B"
+ colorcount = 0
+ colordic = {} # record color #rrggbb as key and "Table1.Bx" as stylename (where x is current color count)
+ tablenum = 0
+
+ # get title and comment and use as title and subtitle
+ titleel = root.find("./head/title")
+ if titleel != None:
+ LOdoc.text.addElement(H(outlinelevel=1, stylename="Title", text=titleel.text))
+ commentel = root.find("./head/comment")
+ if commentel != None:
+ LOdoc.text.addElement(P(stylename="Subtitle", text=commentel.text))
+
+ # Each testgroup element begins a new table
+ for tg in root.findall("./testgroup"):
+ # insert label attribute of testgroup element as subtitle
+ tglabel = tg.get('label')
+ if tglabel != None:
+ LOdoc.text.addElement(H(outlinelevel=1, stylename="Subtitle", text=tglabel))
+
+ # insert text from comment subelement of testgroup element
+ tgcommentel = tg.find("./comment")
+ if tgcommentel != None:
+ #print("commentel found")
+ LOdoc.text.addElement(P(text=tgcommentel.text))
+
+ tgbg = tg.get('background') # background attribute of testgroup element
+ tablenum += 1
+ table = Table(name="Table" + str(tablenum), stylename="Table1")
+ table.addElement(TableColumn(stylename="Table1.A"))
+ for n in range(numfonts):
+ table.addElement(TableColumn(stylename="Table1.B"))
+ table.addElement(TableColumn(stylename="Table1.A"))
+ table.addElement(TableColumn(stylename="Table1.D"))
+ for t in tg.findall("./test"): # Each test element begins a new row
+ # stuff to start the row
+ labeltext = t.get('label')
+ stylename = t.get('stylename')
+ stringel = t.find('./string')
+ commentel = t.find('./comment')
+ rtlsuffix = "R" if t.get('rtl') == 'True' else ""
+ comment = commentel.text if commentel != None else None
+ colBstyle = "Table1.A1"
+ tbg = t.get('background') # get background attribute of test group (if one exists)
+ if tbg == None: tbg = tgbg
+ if tbg != None: # if background attribute for test element (or background attribute for testgroup element)
+ if tbg not in colordic: # if color not found in color dic, create new style
+ colorcount += 1
+ newname = basename + str(colorcount)
+ colordic[tbg] = newname
+ tb1style = Style(name=newname, family="table-cell")
+ tb1style.addElement(TableCellProperties(attributes={'padding':"0.0382in", 'border':"0.05pt solid #000000", 'backgroundcolor':tbg}))
+ LOdoc.automaticstyles.addElement(tb1style)
+ colBstyle = colordic[tbg]
+
+ row = TableRow()
+ table.addElement(row)
+ # fill cells
+ # column A (label)
+ cell = TableCell(stylename="Table1.A1", valuetype="string")
+ if labeltext:
+ cell.addElement(P(stylename="Table_20_Contents", text = labeltext))
+ row.addElement(cell)
+
+ # column B (string)
+ for n in range(numfonts):
+ Pnum = ftmlstyles[stylename] if stylename != None else "P2"
+ Pnum = Pnum + formattedfontnum[n] + rtlsuffix
+ ### not clear if any of the following can be moved outside loop and reused
+ cell = TableCell(stylename=colBstyle, valuetype="string")
+ par = P(stylename=Pnum)
+ if len(stringel) == 0: # no <em> subelements
+ par.addText(re.sub(backu, hextounichr, stringel.text))
+ else: # handle <em> subelement(s)
+ if stringel.text != None:
+ par.addElement(Span(stylename="T1", text = re.sub(backu, hextounichr, stringel.text)))
+ for e in stringel.findall("em"):
+ if e.text != None:
+ par.addText(re.sub(backu, hextounichr, e.text))
+ if e.tail != None:
+ par.addElement(Span(stylename="T1", text = re.sub(backu, hextounichr, e.tail)))
+ cell.addElement(par)
+ row.addElement(cell)
+
+ # column C (comment)
+ cell = TableCell(stylename="Table1.A1", valuetype="string")
+ if comment:
+ cell.addElement(P(stylename="Table_20_Contents", text = comment))
+ row.addElement(cell)
+
+ # column D (stylename)
+ cell = TableCell(stylename="Table1.A1", valuetype="string")
+ if comment:
+ cell.addElement(P(stylename="Table_20_Contents", text = stylename))
+ row.addElement(cell)
+ LOdoc.text.addElement(table)
+
+ LOdoc.text.addElement(P(stylename="Subtitle", text="")) # Empty paragraph to end ### necessary?
+
+ try:
+ if fontstoembed: logfile.log("Embedding fonts in document", "V")
+ for f in fontstoembed:
+ LOdoc._extra.append(
+ OpaqueObject(filename = "Fonts/" + os.path.basename(f),
+ mediatype = "application/x-font-ttf", ### should be "application/font-woff" or "/font-woff2" for WOFF fonts, "/font-opentype" for ttf
+ content = io.open(f, "rb").read() ))
+ ci = ConfigItem(**{'name':'EmbedFonts', 'type': 'boolean'}) ### (name = 'EmbedFonts', type = 'boolean')
+ ci.addText('true')
+ cis=ConfigItemSet(**{'name':'ooo:configuration-settings'}) ### (name = 'ooo:configuration-settings')
+ cis.addElement(ci)
+ LOdoc.settings.addElement(cis)
+ except:
+ logfile.log("Error embedding fonts in document", "E")
+ logfile.log("Writing output file: " + args.output, "P")
+ LOdoc.save(args.output)
+ return
+
+def cmd() : execute("",doit, argspec)
+
+if __name__ == "__main__": cmd()
+
diff --git a/lib/silfont/scripts/psfgetglyphnames.py b/lib/silfont/scripts/psfgetglyphnames.py
new file mode 100755
index 0000000..da685ed
--- /dev/null
+++ b/lib/silfont/scripts/psfgetglyphnames.py
@@ -0,0 +1,87 @@
+#!/usr/bin/env python
+__doc__ = '''Create a list of glyphs to import from a list of characters.'''
+__url__ = 'http://github.com/silnrsi/pysilfont'
+__copyright__ = 'Copyright (c) 2019-2020 SIL International (http://www.sil.org)'
+__license__ = 'Released under the MIT License (http://opensource.org/licenses/MIT)'
+__author__ = 'Bobby de Vos'
+
+from silfont.core import execute
+
+suffix = "_psfgetglyphnames"
+argspec = [
+ ('ifont',{'help': 'Font file to copy from'}, {'type': 'infont'}),
+ ('glyphs',{'help': 'List of glyphs for psfcopyglyphs'}, {'type': 'outfile'}),
+ ('-i', '--input', {'help': 'List of characters to import'}, {'type': 'infile', 'def': None}),
+ ('-a','--aglfn',{'help': 'AGLFN list'}, {'type': 'incsv', 'def': None}),
+ ('-u','--uni',{'help': 'Generate uni or u glyph names if not in AGLFN', 'action': 'store_true', 'default': False}, {}),
+ ('-l','--log',{'help': 'Log file'}, {'type': 'outfile', 'def': suffix+'.log'})
+ ]
+
+def doit(args) :
+
+ font = args.ifont
+
+ aglfn = dict()
+ if args.aglfn:
+ # Load Adobe Glyph List For New Fonts (AGLFN)
+ incsv = args.aglfn
+ incsv.numfields = 3
+
+ for line in incsv:
+ usv = line[0]
+ aglfn_name = line[1]
+
+ codepoint = int(usv, 16)
+ aglfn[codepoint] = aglfn_name
+
+ # Gather data from the UFO
+ cmap = dict()
+ for glyph in font:
+ for codepoint in glyph.unicodes:
+ cmap[codepoint] = glyph.name
+
+ # Determine list of glyphs that need to be copied
+ header = ('glyph_name', 'rename', 'usv')
+ glyphs = args.glyphs
+ row = ','.join(header)
+ glyphs.write(row + '\n')
+
+ for line in args.input:
+
+ # Ignore comments
+ line = line.partition('#')[0]
+ line = line.strip()
+
+ # Ignore blank lines
+ if line == '':
+ continue
+
+ # Specify the glyph to copy
+ codepoint = int(line, 16)
+ usv = f'{codepoint:04X}'
+
+ # Specify how to construct default AGLFN name
+ # if codepoint is not listed in the AGLFN file
+ glyph_prefix = 'uni'
+ if codepoint > 0xFFFF:
+ glyph_prefix = 'u'
+
+ if codepoint in cmap:
+ # By default codepoints not listed in the AGLFN file
+ # will be imported with the glyph name of the source UFO
+ default_aglfn = ''
+ if args.uni:
+ # Provide AGLFN compatible names if requested
+ default_aglfn = f'{glyph_prefix}{usv}'
+
+ # Create control file for use with psfcopyglyphs
+ aglfn_name = aglfn.get(codepoint, default_aglfn)
+ glyph_name = cmap[codepoint]
+ if '_' in glyph_name and aglfn_name == '':
+ aglfn_name = glyph_name.replace('_', '')
+ row = ','.join((glyph_name, aglfn_name, usv))
+ glyphs.write(row + '\n')
+
+
+def cmd() : execute("FP",doit, argspec)
+if __name__ == "__main__": cmd()
diff --git a/lib/silfont/scripts/psfglyphs2ufo.py b/lib/silfont/scripts/psfglyphs2ufo.py
new file mode 100644
index 0000000..3af2ddd
--- /dev/null
+++ b/lib/silfont/scripts/psfglyphs2ufo.py
@@ -0,0 +1,275 @@
+#!/usr/bin/env python
+__doc__ = '''Export fonts in a GlyphsApp file to UFOs'''
+__url__ = 'http://github.com/silnrsi/pysilfont'
+__copyright__ = 'Copyright (c) 2017 SIL International (http://www.sil.org)'
+__license__ = 'Released under the MIT License (http://opensource.org/licenses/MIT)'
+__author__ = 'Victor Gaultney'
+
+from silfont.core import execute
+from silfont.ufo import obsoleteLibKeys
+
+import glyphsLib
+import silfont.ufo
+import silfont.etutil
+from io import open
+import os, shutil
+
+argspec = [
+ ('glyphsfont', {'help': 'Input font file'}, {'type': 'filename'}),
+ ('masterdir', {'help': 'Output directory for masters'}, {}),
+ ('--nofixes', {'help': 'Bypass code fixing data', 'action': 'store_true', 'default': False}, {}),
+ ('--nofea', {'help': "Don't output features.fea", 'action': 'store_true', 'default': False}, {}),
+ ('--preservefea', {'help': "Retain the original features.fea in the UFO", 'action': 'store_true', 'default': False}, {}),
+ ('-l', '--log', {'help': 'Log file'}, {'type': 'outfile', 'def': '_glyphs2ufo.log'}),
+ ('-r', '--restore', {'help': 'List of extra keys to restore to fontinfo.plist or lib.plist'}, {})]
+
+def doit(args):
+ logger = args.logger
+ logger.log("Creating UFO objects from GlyphsApp file", "I")
+ with open(args.glyphsfont, 'r', encoding='utf-8') as gfile:
+ gfont = glyphsLib.parser.load(gfile)
+ ufos = glyphsLib.to_ufos(gfont, include_instances=False, family_name=None, propagate_anchors=False, generate_GDEF=False)
+
+ # Extract directory name for use with restores
+ (glyphsdir, filen) = os.path.split(args.glyphsfont)
+
+ keylists = {
+
+ "librestorekeys": ["org.sil.pysilfontparams", "org.sil.altLineMetrics", "org.sil.lcg.toneLetters",
+ "org.sil.lcg.transforms", "public.glyphOrder", "public.postscriptNames",
+ "com.schriftgestaltung.disablesLastChange", "com.schriftgestaltung.disablesAutomaticAlignment",
+ "public.skipExportGlyphs"],
+ "libdeletekeys": ("com.schriftgestaltung.customParameter.GSFont.copyright",
+ "com.schriftgestaltung.customParameter.GSFont.designer",
+ "com.schriftgestaltung.customParameter.GSFont.manufacturer",
+ "com.schriftgestaltung.customParameter.GSFont.note",
+ "com.schriftgestaltung.customParameter.GSFont.Axes",
+ "com.schriftgestaltung.customParameter.GSFont.Axis Mappings",
+ "com.schriftgestaltung.customParameter.GSFontMaster.Master Name"),
+ "libdeleteempty": ("com.schriftgestaltung.DisplayStrings",),
+ "inforestorekeys": ["openTypeHeadCreated", "openTypeNamePreferredFamilyName", "openTypeNamePreferredSubfamilyName",
+ "openTypeNameUniqueID", "openTypeOS2WeightClass", "openTypeOS2WidthClass", "postscriptFontName",
+ "postscriptFullName", "styleMapFamilyName", "styleMapStyleName", "note",
+ "woffMetadataCredits", "woffMetadataDescription"],
+ "integerkeys": ("openTypeOS2WeightClass", "openTypeOS2WidthClass"),
+ "infodeletekeys": ("openTypeVheaVertTypoAscender", "openTypeVheaVertTypoDescender", "openTypeVheaVertTypoLineGap"),
+ # "infodeleteempty": ("openTypeOS2Selection",)
+ }
+
+ if args.restore: # Extra keys to restore. Add to both lists, since should never be duplicated names
+ keylist = args.restore.split(",")
+ keylists["librestorekeys"] += keylist
+ keylists["inforestorekeys"].append(keylist)
+
+ loglists = []
+ obskeysfound={}
+ for ufo in ufos:
+ loglists.append(process_ufo(ufo, keylists, glyphsdir, args, obskeysfound))
+ for loglist in loglists:
+ for logitem in loglist: logger.log(logitem[0], logitem[1])
+ if obskeysfound:
+ logmess = "The following obsolete keys were found. They may have been in the original UFO or you may have an old version of glyphsLib installed\n"
+ for fontname in obskeysfound:
+ keys = obskeysfound[fontname]
+ logmess += " " + fontname + ": "
+ for key in keys:
+ logmess += key + ", "
+ logmess += "\n"
+ logger.log(logmess, "E")
+
+def process_ufo(ufo, keylists, glyphsdir, args, obskeysfound):
+ loglist=[]
+# sn = ufo.info.styleName # )
+# sn = sn.replace("Italic Italic", "Italic") # ) Temp fixes due to glyphLib incorrectly
+# sn = sn.replace("Italic Bold Italic", "Bold Italic") # ) forming styleName
+# sn = sn.replace("Extra Italic Light Italic", "Extra Light Italic") # )
+# ufo.info.styleName = sn # )
+ fontname = ufo.info.familyName.replace(" ", "") + "-" + ufo.info.styleName.replace(" ", "")
+
+ # Fixes to the data
+ if not args.nofixes:
+ loglist.append(("Fixing data in " + fontname, "P"))
+ # lib.plist processing
+ loglist.append(("Checking lib.plist", "P"))
+
+ # Restore values from original UFOs, assuming named as <fontname>.ufo in same directory as input .gylphs file
+
+ ufodir = os.path.join(glyphsdir, fontname + ".ufo")
+ try:
+ origlibplist = silfont.ufo.Uplist(font=None, dirn=ufodir, filen="lib.plist")
+ except Exception as e:
+ loglist.append(("Unable to open lib.plist in " + ufodir + "; values will not be restored", "E"))
+ origlibplist = None
+
+ if origlibplist is not None:
+
+ for key in keylists["librestorekeys"]:
+ current = None if key not in ufo.lib else ufo.lib[key]
+ if key in origlibplist:
+ new = origlibplist.getval(key)
+ if current == new:
+ continue
+ else:
+ ufo.lib[key] = new
+ logchange(loglist, " restored from backup ufo. ", key, current, new)
+ elif current:
+ ufo.lib[key] = None
+ logchange(loglist, " removed since not in backup ufo. ", key, current, None)
+
+ # Delete unneeded keys
+
+ for key in keylists["libdeletekeys"]:
+ if key in ufo.lib:
+ current = ufo.lib[key]
+ del ufo.lib[key]
+ logchange(loglist, " deleted. ", key, current, None)
+
+ for key in keylists["libdeleteempty"]:
+ if key in ufo.lib and (ufo.lib[key] == "" or ufo.lib[key] == []):
+ current = ufo.lib[key]
+ del ufo.lib[key]
+ logchange(loglist, " empty field deleted. ", key, current, None)
+
+ # Check for obsolete keys
+ for key in obsoleteLibKeys:
+ if key in ufo.lib:
+ if fontname not in obskeysfound: obskeysfound[fontname] = []
+ obskeysfound[fontname].append(key)
+
+ # Special processing for Axis Mappings
+ #key = "com.schriftgestaltung.customParameter.GSFont.Axis Mappings"
+ #if key in ufo.lib:
+ # current =ufo.lib[key]
+ # new = dict(current)
+ # for x in current:
+ # val = current[x]
+ # k = list(val.keys())[0]
+ # if k[-2:] == ".0": new[x] = {k[0:-2]: val[k]}
+ # if current != new:
+ # ufo.lib[key] = new
+ # logchange(loglist, " key names set to integers. ", key, current, new)
+
+ # Special processing for ufo2ft filters
+ key = "com.github.googlei18n.ufo2ft.filters"
+ if key in ufo.lib:
+ current = ufo.lib[key]
+ new = list(current)
+ for x in current:
+ if x["name"] == "eraseOpenCorners":
+ new.remove(x)
+
+ if current != new:
+ if new == []:
+ del ufo.lib[key]
+ else:
+ ufo.lib[key] = new
+ logchange(loglist, " eraseOpenCorners filter removed ", key, current, new)
+
+ # fontinfo.plist processing
+
+ loglist.append(("Checking fontinfo.plist", "P"))
+
+ try:
+ origfontinfo = silfont.ufo.Uplist(font=None, dirn=ufodir, filen="fontinfo.plist")
+ except Exception as e:
+ loglist.append(("Unable to open fontinfo.plist in " + ufodir + "; values will not be restored", "E"))
+ origfontinfo = None
+
+ if origfontinfo is not None:
+ for key in keylists["inforestorekeys"]:
+ current = None if not hasattr(ufo.info, key) else getattr(ufo.info, key)
+ if key in origfontinfo:
+ new = origfontinfo.getval(key)
+ if key in keylists["integerkeys"]: new = int(new)
+ if current == new:
+ continue
+ else:
+ setattr(ufo.info, key, new)
+ logchange(loglist, " restored from backup ufo. ", key, current, new)
+ elif current:
+ setattr(ufo.info, key, None)
+ logchange(loglist, " removed since not in backup ufo. ", key, current, None)
+
+ if getattr(ufo.info, "italicAngle") == 0: # Remove italicAngle if 0
+ setattr(ufo.info, "italicAngle", None)
+ logchange(loglist, " removed", "italicAngle", 0, None)
+
+ # Delete unneeded keys
+
+ for key in keylists["infodeletekeys"]:
+ if hasattr(ufo.info, key):
+ current = getattr(ufo.info, key)
+ setattr(ufo.info, key, None)
+ logchange(loglist, " deleted. ", key, current, None)
+
+# for key in keylists["infodeleteempty"]:
+# if hasattr(ufo.info, key) and getattr(ufo.info, key) == "":
+# setattr(ufo.info, key, None)
+# logchange(loglist, " empty field deleted. ", key, current, None)
+ if args.nofea or args.preservefea: ufo.features.text = "" # Suppress output of features.fea
+
+ for layer in ufo.layers:
+ for glyph in layer:
+ lib = glyph.lib
+ if "public.verticalOrigin" in lib: del lib["public.verticalOrigin"]
+
+ # Write ufo out
+ ufopath = os.path.join(args.masterdir, fontname + ".ufo")
+ if args.preservefea: # Move features.fea out of the ufo so that it can be restored afterward
+ origfea = os.path.join(ufopath, "features.fea")
+ hiddenfea = os.path.join(args.masterdir, fontname + "features.tmp")
+ if os.path.exists(origfea):
+ loglist.append((f'Renaming {origfea} to {hiddenfea}', "I"))
+ os.rename(origfea, hiddenfea)
+ else:
+ loglist.append((f"{origfea} does not exists so can't be restored", "E"))
+ origfea = None
+ loglist.append(("Writing out " + ufopath, "P"))
+ if os.path.exists(ufopath): shutil.rmtree(ufopath)
+ ufo.save(ufopath)
+ if args.preservefea and origfea:
+ loglist.append((f'Renaming {hiddenfea} back to {origfea}', "I"))
+ os.rename(hiddenfea, origfea)
+
+ # Now correct the newly-written fontinfo.plist with changes that can't be made via glyphsLib
+ if not args.nofixes:
+ fontinfo = silfont.ufo.Uplist(font=None, dirn=ufopath, filen="fontinfo.plist")
+ changes = False
+ for key in ("guidelines", "postscriptBlueValues", "postscriptFamilyBlues", "postscriptFamilyOtherBlues",
+ "postscriptOtherBlues"):
+ if key in fontinfo and fontinfo.getval(key) == []:
+ fontinfo.remove(key)
+ changes = True
+ logchange(loglist, " empty list deleted", key, None, [])
+ if changes:
+ # Create outparams. Just need any valid values, since font will need normalizing later
+ params = args.paramsobj
+ paramset = params.sets["main"]
+ outparams = {"attribOrders": {}}
+ for parn in params.classes["outparams"]: outparams[parn] = paramset[parn]
+ loglist.append(("Writing updated fontinfo.plist", "I"))
+ silfont.ufo.writeXMLobject(fontinfo, params=outparams, dirn=ufopath, filen="fontinfo.plist", exists=True,
+ fobject=True)
+ return loglist
+
+def logchange(loglist, logmess, key, old, new):
+ oldstr = str(old) if len(str(old)) < 22 else str(old)[0:20] + "..."
+ newstr = str(new) if len(str(new)) < 22 else str(new)[0:20] + "..."
+ logmess = key + logmess
+ if old is None:
+ logmess = logmess + " New value: " + newstr
+ else:
+ if new is None:
+ logmess = logmess + " Old value: " + oldstr
+ else:
+ logmess = logmess + " Old value: " + oldstr + ", new value: " + newstr
+ loglist.append((logmess, "I"))
+ # Extra verbose logging
+ if len(str(old)) > 21 :
+ loglist.append(("Full old value: " + str(old), "V"))
+ if len(str(new)) > 21 :
+ loglist.append(("Full new value: " + str(new), "V"))
+ loglist.append(("Types: Old - " + str(type(old)) + ", New - " + str(type(new)), "V"))
+
+def cmd(): execute(None, doit, argspec)
+if __name__ == "__main__": cmd()
diff --git a/lib/silfont/scripts/psfmakedeprecated.py b/lib/silfont/scripts/psfmakedeprecated.py
new file mode 100644
index 0000000..b86ed4c
--- /dev/null
+++ b/lib/silfont/scripts/psfmakedeprecated.py
@@ -0,0 +1,74 @@
+#!/usr/bin/env python3
+'''Creates deprecated versions of glyphs: takes the specified glyph and creates a
+duplicate with an additional box surrounding it so that it becomes reversed,
+and assigns a new unicode encoding to it.
+Input is a csv with three fields: original,new,unicode'''
+__url__ = 'http://github.com/silnrsi/pysilfont'
+__copyright__ = 'Copyright (c) 2018 SIL International (http://www.sil.org)'
+__license__ = 'Released under the MIT License (http://opensource.org/licenses/MIT)'
+__author__ = 'Victor Gaultney'
+
+from silfont.core import execute
+
+argspec = [
+ ('ifont', {'help': 'Input font filename'}, {'type': 'infont'}),
+ ('ofont',{'help': 'Output font file','nargs': '?' }, {'type': 'outfont'}),
+ ('-i','--input',{'help': 'Input csv file'}, {'type': 'incsv', 'def': 'todeprecate.csv'}),
+ ('-l','--log',{'help': 'Set log file name'}, {'type': 'outfile', 'def': '_deprecated.log'})]
+
+offset = 30
+
+def doit(args) :
+ font = args.ifont
+ logger = args.logger
+
+ # Process csv list into a dictionary structure
+ args.input.numfields = 3
+ deps = {}
+ for line in args.input :
+ deps[line[0]] = {"newname": line[1], "newuni": line[2]}
+
+ # Iterate through dictionary (unsorted)
+ for source, target in deps.items() :
+ # Check if source glyph is in font
+ if source in font.keys() :
+ # Give warning if target is already in font, but overwrite anyway
+ targetname = target["newname"]
+ targetuni = int(target["newuni"], 16)
+ if targetname in font.keys() :
+ logger.log("Warning: " + targetname + " already in font and will be replaced")
+
+ # Make a copy of source into a new glyph object
+ sourceglyph = font[source]
+ newglyph = sourceglyph.copy()
+
+ # Draw box around it
+ xmin, ymin, xmax, ymax = sourceglyph.bounds
+ pen = newglyph.getPen()
+ pen.moveTo((xmax + offset, ymin - offset))
+ pen.lineTo((xmax + offset, ymax + offset))
+ pen.lineTo((xmin - offset, ymax + offset))
+ pen.lineTo((xmin - offset, ymin - offset))
+ pen.closePath()
+
+ # Set unicode
+ newglyph.unicodes = []
+ newglyph.unicode = targetuni
+
+ # Add the new glyph object to the font with name target
+ font.__setitem__(targetname,newglyph)
+
+ # Decompose glyph in case there may be components
+ # It seems you can't decompose a glyph has hasn't yet been added to a font
+ font[targetname].decompose()
+ # Correct path direction
+ font[targetname].correctDirection()
+
+ logger.log(source + " duplicated to " + targetname)
+ else :
+ logger.log("Warning: " + source + " not in font")
+
+ return font
+
+def cmd() : execute("FP",doit,argspec)
+if __name__ == "__main__": cmd()
diff --git a/lib/silfont/scripts/psfmakefea.py b/lib/silfont/scripts/psfmakefea.py
new file mode 100755
index 0000000..6ef0613
--- /dev/null
+++ b/lib/silfont/scripts/psfmakefea.py
@@ -0,0 +1,369 @@
+#!/usr/bin/python3
+__doc__ = 'Make features.fea file'
+# TODO: add conditional compilation, compare to fea, compile to ttf
+__url__ = 'http://github.com/silnrsi/pysilfont'
+__copyright__ = 'Copyright (c) 2017 SIL International (http://www.sil.org)'
+__license__ = 'Released under the MIT License (http://opensource.org/licenses/MIT)'
+__author__ = 'Martin Hosken, Alan Ward'
+
+import silfont.ufo as ufo
+from collections import OrderedDict
+from silfont.feax_parser import feaplus_parser
+from xml.etree import ElementTree as et
+import re
+
+from silfont.core import execute
+
+def getbbox(g):
+ res = (65536, 65536, -65536, -65536)
+ if g['outline'] is None:
+ return (0, 0, 0, 0)
+ for c in g['outline'].contours:
+ for p in c['point']:
+ if 'type' in p.attrib: # any actual point counts
+ x = float(p.get('x', '0'))
+ y = float(p.get('y', '0'))
+ res = (min(x, res[0]), min(y, res[1]), max(x, res[2]), max(y, res[3]))
+ return res
+
+class Glyph(object) :
+ def __init__(self, name, advance=0, bbox=None) :
+ self.name = name
+ self.anchors = {}
+ self.is_mark = False
+ self.advance = int(float(advance))
+ self.bbox = bbox or (0, 0, 0, 0)
+
+ def add_anchor(self, info) :
+ self.anchors[info['name']] = (int(float(info['x'])), int(float(info['y'])))
+
+ def decide_if_mark(self) :
+ for a in self.anchors.keys() :
+ if a.startswith("_") :
+ self.is_mark = True
+ break
+
+def decode_element(e):
+ '''Convert plist element into python structures'''
+ res = None
+ if e.tag == 'string':
+ return e.text
+ elif e.tag == 'integer':
+ return int(e.text)
+ elif e.tag== 'real':
+ return float(e.text)
+ elif e.tag == 'array':
+ res = [decode_element(x) for x in e]
+ elif e.tag == 'dict':
+ res = {}
+ for p in zip(e[::2], e[1::2]):
+ res[p[0].text] = decode_element(p[1])
+ return res
+
+class Font(object) :
+ def __init__(self, defines = None):
+ self.glyphs = OrderedDict()
+ self.classes = OrderedDict()
+ self.all_aps = OrderedDict()
+ self.fontinfo = {}
+ self.kerns = {}
+ self.defines = {} if defines is None else defines
+
+ def readaps(self, filename, omitaps='', params = None) :
+ omittedaps = set(omitaps.replace(',',' ').split()) # allow comma- and/or space-separated list
+ if filename.endswith('.ufo') :
+ f = ufo.Ufont(filename, params = params)
+ self.fontinfo = {}
+ for k, v in f.fontinfo._contents.items():
+ self.fontinfo[k] = decode_element(v[1])
+ skipglyphs = set(f.lib.getval('public.skipExportGlyphs', []))
+ for g in f.deflayer :
+ if g in skipglyphs:
+ continue
+ ufo_g = f.deflayer[g]
+ advb = ufo_g['advance']
+ adv = advb.width if advb is not None else 0
+ bbox = getbbox(ufo_g)
+ glyph = Glyph(g, advance=adv, bbox=bbox)
+ self.glyphs[g] = glyph
+ if 'anchor' in ufo_g._contents :
+ for a in ufo_g._contents['anchor'] :
+ if a.element.attrib['name'] not in omittedaps:
+ glyph.add_anchor(a.element.attrib)
+ self.all_aps.setdefault(a.element.attrib['name'], []).append(glyph)
+ if hasattr(f, 'groups'):
+ for k, v in f.groups._contents.items():
+ self.classes[k.lstrip('@')] = decode_element(v[1])
+ if hasattr(f, 'kerning'):
+ for k, v in f.kerning._contents.items():
+ key = k.lstrip('@')
+ if key in self.classes:
+ key = "@" + key
+ subelements = decode_element(v[1])
+ kerndict = {}
+ for s, n in subelements.items():
+ skey = s.lstrip('@')
+ if skey in self.classes:
+ skey = "@" + skey
+ kerndict[skey] = n
+ self.kerns[key] = kerndict
+ elif filename.endswith('.xml') :
+ currGlyph = None
+ currPoint = None
+ self.fontinfo = {}
+ for event, elem in et.iterparse(filename, events=('start', 'end')):
+ if event == 'start':
+ if elem.tag == 'glyph':
+ name = elem.get('PSName', '')
+ if name:
+ currGlyph = Glyph(name)
+ self.glyphs[name] = currGlyph
+ currPoint = None
+ elif elem.tag == 'point':
+ currPoint = {'name' : elem.get('type', '')}
+ elif elem.tag == 'location' and currPoint is not None:
+ currPoint['x'] = int(elem.get('x', 0))
+ currPoint['y'] = int(elem.get('y', 0))
+ elif elem.tag == 'font':
+ n = elem.get('name', '')
+ x = n.split('-')
+ if len(x) == 2:
+ self.fontinfo['familyName'] = x[0]
+ self.fontinfo['openTypeNamePreferredFamilyName'] = x[0]
+ self.fontinfo['styleMapFamilyName'] = x[0]
+ self.fontinfo['styleName'] = x[1]
+ self.fontinfo['openTypeNamePreferredSubfamilyName'] = x[1]
+ self.fontinfo['postscriptFullName'] = "{0} {1}".format(*x)
+ self.fontinfo['postscriptFontName'] = n
+ elif event == 'end':
+ if elem.tag == 'point':
+ if currGlyph and currPoint['name'] not in omittedaps:
+ currGlyph.add_anchor(currPoint)
+ self.all_aps.setdefault(currPoint['name'], []).append(currGlyph)
+ currPoint = None
+ elif elem.tag == 'glyph':
+ currGlyph = None
+
+ def read_classes(self, fname, classproperties=False):
+ doc = et.parse(fname)
+ for c in doc.findall('.//class'):
+ class_name = c.get('name')
+ m = re.search('\[(\d+)\]$', class_name)
+ # support fixedclasses like make_gdl.pl via AP.pm
+ if m:
+ class_nm = class_name[0:m.start()]
+ ix = int(m.group(1))
+ else:
+ class_nm = class_name
+ ix = None
+ cl = self.classes.setdefault(class_nm, [])
+ for e in c.get('exts', '').split() + [""]:
+ for g in c.text.split():
+ if g+e in self.glyphs or (e == '' and g.startswith('@')):
+ if ix:
+ cl.insert(ix, g+e)
+ else:
+ cl.append(g+e)
+ if not classproperties:
+ return
+ for c in doc.findall('.//property'):
+ for e in c.get('exts', '').split() + [""]:
+ for g in c.text.split():
+ if g+e in self.glyphs:
+ cname = c.get('name') + "_" + c.get('value')
+ self.classes.setdefault(cname, []).append(g+e)
+
+ def make_classes(self, ligmode) :
+ for name, g in self.glyphs.items() :
+ # pull off suffix and make classes
+ # TODO: handle ligatures
+ base = name
+ if ligmode is None or 'comp' not in ligmode or "_" not in name:
+ pos = base.rfind('.')
+ while pos > 0 :
+ old_base = base
+ ext = base[pos+1:]
+ base = base[:pos]
+ ext_class_nm = "c_" + ext
+ if base in self.glyphs and old_base in self.glyphs:
+ glyph_lst = self.classes.setdefault(ext_class_nm, [])
+ if not old_base in glyph_lst:
+ glyph_lst.append(old_base)
+ self.classes.setdefault("cno_" + ext, []).append(base)
+ pos = base.rfind('.')
+ if ligmode is not None and "_" in name:
+ comps = name.split("_")
+ if "comp" in ligmode or "." not in comps[-1]:
+ base = comps.pop(-1 if "last" in ligmode else 0)
+ cname = base.replace(".", "_")
+ noname = "_".join(comps)
+ if base in self.glyphs and noname in self.glyphs:
+ glyph_lst = self.classes.setdefault("clig_"+cname, [])
+ if name not in glyph_lst:
+ glyph_lst.append(name)
+ self.classes.setdefault("cligno_"+cname, []).append(noname)
+ if g.is_mark :
+ self.classes.setdefault('GDEF_marks', []).append(name)
+ else :
+ self.classes.setdefault('GDEF_bases', []).append(name)
+
+ def make_marks(self) :
+ for name, g in self.glyphs.items() :
+ g.decide_if_mark()
+
+ def order_classes(self):
+ # return ordered list of classnames as desired for FEA
+
+ # Start with alphabetical then correct:
+ # 1. Put classes like "cno_whatever" adjacent to "c_whatever"
+ # 2. Classes can be defined in terms of other classes but FEA requires that
+ # classes be defined before they can be referenced.
+
+ def sortkey(x):
+ key1 = 'c_' + x[4:] if x.startswith('cno_') else x
+ return (key1, x)
+
+ classes = sorted(self.classes.keys(), key=sortkey)
+ links = {} # key = classname; value = list of other classes that include this one
+ counts = {} # key = classname; value = count of un-output classes that this class includes
+ for name in classes:
+ y = [c[1:] for c in self.classes[name] if c.startswith('@')] #list of included classes
+ counts[name] = len(y)
+ for c in y:
+ links.setdefault(c, []).append(name)
+
+ outclasses = []
+ while len(classes) > 0:
+ foundone = False
+ for name in classes:
+ if counts[name] == 0:
+ foundone = True
+ # output this class
+ outclasses.append(name)
+ classes.remove(name)
+ # adjust counts of classes that include this one
+ if name in links:
+ for n in links[name]:
+ counts[n] -= 1
+ # It may now be possible to output some we skipped earlier,
+ # so start over from the beginning of the list
+ break
+ if not foundone:
+ # all remaining classes include un-output classes and thus there is a loop somewhere
+ raise ValueError("Class reference loop(s) found: " + ", ".join(classes))
+ return outclasses
+
+ def addComment(self, parser, text):
+ cmt = parser.ast.Comment("# " + text, location=None)
+ cmt.pretext = "\n"
+ parser.add_statement(cmt)
+
+ def append_classes(self, parser) :
+ # normal glyph classes
+ self.addComment(parser, "Main Classes")
+ for name in self.order_classes():
+ gc = parser.ast.GlyphClass(None, location=None)
+ for g in self.classes[name] :
+ gc.append(g)
+ gcd = parser.ast.GlyphClassDefinition(name, gc, location=None)
+ parser.add_statement(gcd)
+ parser.define_glyphclass(name, gcd)
+
+ def _addGlyphsToClass(self, parser, glyphs, gc, anchor, definer):
+ if len(glyphs) > 1 :
+ val = parser.ast.GlyphClass(glyphs, location=None)
+ else :
+ val = parser.ast.GlyphName(glyphs[0], location=None)
+ classdef = definer(gc, anchor, val, location=None)
+ gc.addDefinition(classdef)
+ parser.add_statement(classdef)
+
+ def append_positions(self, parser):
+ # create base and mark classes, add to fea file dicts and parser symbol table
+ bclassdef_lst = []
+ mclassdef_lst = []
+ self.addComment(parser, "Positioning classes and statements")
+ for ap_nm, glyphs_w_ap in self.all_aps.items() :
+ self.addComment(parser, "AP: " + ap_nm)
+ # e.g. all glyphs with U AP
+ if not ap_nm.startswith("_"):
+ if any(not x.is_mark for x in glyphs_w_ap):
+ gcb = parser.set_baseclass(ap_nm)
+ parser.add_statement(gcb)
+ if any(x.is_mark for x in glyphs_w_ap):
+ gcm = parser.set_baseclass(ap_nm + "_MarkBase")
+ parser.add_statement(gcm)
+ else:
+ gc = parser.set_markclass(ap_nm)
+
+ # create lists of glyphs that use the same point (name and coordinates)
+ # that can share a class definition
+ anchor_cache = OrderedDict()
+ markanchor_cache = OrderedDict()
+ for g in glyphs_w_ap :
+ p = g.anchors[ap_nm]
+ if g.is_mark and not ap_nm.startswith("_"):
+ markanchor_cache.setdefault(p, []).append(g.name)
+ else:
+ anchor_cache.setdefault(p, []).append(g.name)
+
+ if ap_nm.startswith("_"):
+ for p, glyphs_w_pt in anchor_cache.items():
+ anchor = parser.ast.Anchor(p[0], p[1], location=None)
+ self._addGlyphsToClass(parser, glyphs_w_pt, gc, anchor, parser.ast.MarkClassDefinition)
+ else:
+ for p, glyphs_w_pt in anchor_cache.items():
+ anchor = parser.ast.Anchor(p[0], p[1], location=None)
+ self._addGlyphsToClass(parser, glyphs_w_pt, gcb, anchor, parser.ast.BaseClassDefinition)
+ for p, glyphs_w_pt in markanchor_cache.items():
+ anchor = parser.ast.Anchor(p[0], p[1], location=None)
+ self._addGlyphsToClass(parser, glyphs_w_pt, gcm, anchor, parser.ast.BaseClassDefinition)
+
+#TODO: provide more argument info
+argspec = [
+ ('infile', {'nargs': '?', 'help': 'Input UFO or file'}, {'def': None, 'type': 'filename'}),
+ ('-i', '--input', {'required': 'True', 'help': 'Fea file to merge'}, {}),
+ ('-o', '--output', {'help': 'Output fea file'}, {}),
+ ('-c', '--classfile', {'help': 'Classes file'}, {}),
+ ('-L', '--ligmode', {'help': 'Parse ligatures: last - use last element as class name, first - use first element as class name, lastcomp, firstcomp - final variants are part of the component not the whole ligature'}, {}),
+ ('-D', '--define', {'action': 'append', 'help': 'Add option definition to pass to fea code --define=var=val'}, {}),
+ # ('--debug', {'help': 'Drop into pdb', 'action': 'store_true'}, {}),
+ ('--classprops', {'help': 'Include property elements from classes file', 'action': 'store_true'}, {}),
+ ('--omitaps', {'help': 'names of attachment points to omit (comma- or space-separated)', 'default': '', 'action': 'store'}, {})
+]
+
+def doit(args) :
+ defines = dict(x.split('=') for x in args.define) if args.define else {}
+ font = Font(defines)
+ # if args.debug:
+ # import pdb; pdb.set_trace()
+ if "checkfix" not in args.params:
+ args.paramsobj.sets["main"]["checkfix"] = "None"
+ if args.infile is not None:
+ font.readaps(args.infile, args.omitaps, args.paramsobj)
+
+ font.make_marks()
+ font.make_classes(args.ligmode)
+ if args.classfile:
+ font.read_classes(args.classfile, classproperties = args.classprops)
+
+ p = feaplus_parser(None, font.glyphs, font.fontinfo, font.kerns, font.defines)
+ doc_ufo = p.parse() # returns an empty ast.FeatureFile
+
+ # Add goodies from the font
+ font.append_classes(p)
+ font.append_positions(p)
+
+ # parse the input fea file
+ if args.input :
+ doc_fea = p.parse(args.input)
+ else:
+ doc_fea = doc_ufo
+
+ # output as doc.asFea()
+ if args.output :
+ with open(args.output, "w") as of :
+ of.write(doc_fea.asFea())
+
+def cmd(): execute(None, doit, argspec)
+if __name__ == '__main__': cmd()
diff --git a/lib/silfont/scripts/psfmakescaledshifted.py b/lib/silfont/scripts/psfmakescaledshifted.py
new file mode 100644
index 0000000..69bbbb9
--- /dev/null
+++ b/lib/silfont/scripts/psfmakescaledshifted.py
@@ -0,0 +1,117 @@
+#!/usr/bin/env python3
+'''Creates duplicate versions of glyphs that are scaled and shifted.
+Input is a csv with three fields: original,new,unicode'''
+__url__ = 'http://github.com/silnrsi/pysilfont'
+__copyright__ = 'Copyright (c) 2019 SIL International (http://www.sil.org)'
+__license__ = 'Released under the MIT License (http://opensource.org/licenses/MIT)'
+__author__ = 'Victor Gaultney'
+
+from silfont.core import execute
+from silfont.util import parsecolors
+from ast import literal_eval as make_tuple
+
+argspec = [
+ ('ifont', {'help': 'Input font filename'}, {'type': 'infont'}),
+ ('ofont',{'help': 'Output font file','nargs': '?' }, {'type': 'outfont'}),
+ ('-i','--input',{'help': 'Input csv file', 'required': True}, {'type': 'incsv', 'def': 'scaledshifted.csv'}),
+ ('-c', '--colorcells', {'help': 'Color cells of generated glyphs', 'action': 'store_true'}, {}),
+ ('--color', {'help': 'Color to use when marking generated glyphs'},{}),
+ ('-t','--transform',{'help': 'Transform matrix or type', 'required': True}, {}),
+ ('-l','--log',{'help': 'Set log file name'}, {'type': 'outfile', 'def': '_scaledshifted.log'})]
+
+def doit(args) :
+ font = args.ifont
+ logger = args.logger
+ transform = args.transform
+
+ if transform[1] == "(":
+ # Set transform from matrix - example: "(0.72, 0, 0, 0.6, 10, 806)"
+ # (xx, xy, yx, yy, x, y)
+ trans = make_tuple(args.transform)
+ else:
+ # Set transformation specs from UFO lib.plist org.sil.lcg.transforms
+ # Will need to be enhanced to support adjustMetrics, boldX, boldY parameters for smallcaps
+ try:
+ trns = font.lib["org.sil.lcg.transforms"][transform]
+ except KeyError:
+ logger.log("Error: transform type not found in lib.plist org.sil.lcg.transforms", "S")
+ else:
+ try:
+ adjM = trns["adjustMetrics"]
+ except KeyError:
+ adjM = 0
+ try:
+ skew = trns["skew"]
+ except KeyError:
+ skew = 0
+ try:
+ shiftX = trns["shiftX"]
+ except KeyError:
+ shiftX = 0
+ try:
+ shiftY = trns["shiftY"]
+ except KeyError:
+ shiftY = 0
+ trans = (trns["scaleX"], 0, skew, trns["scaleY"], shiftX+adjM, shiftY)
+
+
+ # Process csv list into a dictionary structure
+ args.input.numfields = 3
+ deps = {}
+ for (source, newname, newuni) in args.input :
+ if source in deps:
+ deps[source].append({"newname": newname, "newuni": newuni})
+ else:
+ deps[source] = [({"newname": newname, "newuni": newuni})]
+
+ # Iterate through dictionary (unsorted)
+ for source in deps:
+ # Check if source glyph is in font
+ if source in font.keys() :
+ for target in deps[source]:
+ # Give warning if target is already in font, but overwrite anyway
+ targetname = target["newname"]
+ if targetname in font.keys() :
+ logger.log("Warning: " + targetname + " already in font and will be replaced")
+
+ # Make a copy of source into a new glyph object
+ sourceglyph = font[source]
+ newglyph = sourceglyph.copy()
+
+ newglyph.transformBy(trans)
+ # Set width because transformBy does not seems to properly adjust width
+ newglyph.width = (int(newglyph.width * trans[0])) + (adjM * 2)
+
+ # Set unicode
+ newglyph.unicodes = []
+ if target["newuni"]:
+ newglyph.unicode = int(target["newuni"], 16)
+
+ # mark glyphs as being generated by setting cell mark color (defaults to blue if args.color not set)
+ if args.colorcells or args.color:
+ if args.color:
+ (color, name, logcolor, splitcolor) = parsecolors(args.color, single=True)
+ if color is None: logger.log(logcolor, "S") # If color not parsed, parsecolors() puts error in logcolor
+ color = color.split(",") # Need to convert string to tuple
+ color = (float(color[0]), float(color[1]), float(color[2]), float(color[3]))
+ else:
+ color = (0.18, 0.16, 0.78, 1)
+ newglyph.markColor = color
+
+ # Add the new glyph object to the font with name target
+ font.__setitem__(targetname, newglyph)
+
+ # Decompose glyph in case there may be components
+ # It seems you can't decompose a glyph has hasn't yet been added to a font
+ font[targetname].decompose()
+ # Correct path direction
+ font[targetname].correctDirection()
+
+ logger.log(source + " duplicated to " + targetname)
+ else :
+ logger.log("Warning: " + source + " not in font")
+
+ return font
+
+def cmd() : execute("FP",doit,argspec)
+if __name__ == "__main__": cmd()
diff --git a/lib/silfont/scripts/psfmakewoffmetadata.py b/lib/silfont/scripts/psfmakewoffmetadata.py
new file mode 100755
index 0000000..c7d8128
--- /dev/null
+++ b/lib/silfont/scripts/psfmakewoffmetadata.py
@@ -0,0 +1,225 @@
+#!/usr/bin/env python
+__doc__ = 'Make the WOFF metadata xml file based on input UFO (and optionally FONTLOG.txt)'
+__url__ = 'http://github.com/silnrsi/pysilfont'
+__copyright__ = 'Copyright (c) 2017 SIL International (http://www.sil.org)'
+__license__ = 'Released under the MIT License (http://opensource.org/licenses/MIT)'
+__author__ = 'David Raymond'
+
+from silfont.core import execute
+import silfont.ufo as UFO
+
+import re, os, datetime
+from xml.etree import ElementTree as ET
+
+argspec = [
+ ('font', {'help': 'Source font file'}, {'type': 'infont'}),
+ ('-n', '--primaryname', {'help': 'Primary Font Name', 'required': True}, {}),
+ ('-i', '--orgid', {'help': 'orgId', 'required': True}, {}),
+ ('-f', '--fontlog', {'help': 'FONTLOG.txt file', 'default': 'FONTLOG.txt'}, {'type': 'filename'}),
+ ('-o', '--output', {'help': 'Override output file'}, {'type': 'filename', 'def': None}),
+ ('--populateufowoff', {'help': 'Copy info from FONTLOG.txt to UFO', 'action': 'store_true', 'default': False},{}),
+ ('-l', '--log', {'help': 'Log file'}, {'type': 'outfile', 'def': '_makewoff.log'})]
+
+def doit(args):
+ font = args.font
+ pfn = args.primaryname
+ orgid = args.orgid
+ logger = args.logger
+ ofn = args.output
+
+ # Find & process info required in the UFO
+
+ fi = font.fontinfo
+
+ ufofields = {}
+ missing = None
+ for field in ("versionMajor", "versionMinor", "openTypeNameManufacturer", "openTypeNameManufacturerURL",
+ "openTypeNameLicense", "copyright", "trademark"):
+ if field in fi:
+ ufofields[field] = fi[field][1].text
+ elif field != 'trademark': # trademark is no longer required
+ missing = field if missing is None else missing + ", " + field
+ if missing is not None: logger.log("Field(s) missing from fontinfo.plist: " + missing, "S")
+
+ version = ufofields["versionMajor"] + "." + ufofields["versionMinor"].zfill(3)
+
+ # Find & process WOFF fields if present in the UFO
+
+ missing = None
+ ufofields["woffMetadataDescriptionurl"] = None
+ ufowoff = {"woffMetadataCredits": "credits", "woffMetadataDescription": "text"} # Field, dict name
+ for field in ufowoff:
+ fival = fi.getval(field) if field in fi else None
+ if fival is None:
+ missing = field if missing is None else missing + ", " + field
+ ufofields[field] = None
+ else:
+ ufofields[field] = fival[ufowoff[field]]
+ if field == "woffMetadataDescription" and "url" in fival:
+ ufofields["woffMetadataDescriptionurl"] = fival["url"]
+
+ # Process --populateufowoff setting, if present
+ if args.populateufowoff:
+ if missing != "woffMetadataCredits, woffMetadataDescription":
+ logger.log("Data exists in the UFO for woffMetadata - remove manually to reuse --populateufowoff", "S")
+
+ if args.populateufowoff or missing is not None:
+ if missing: logger.log("WOFF field(s) missing from fontinfo.plist will be generated from FONTLOG.txt: " + missing, "W")
+ # Open the fontlog file
+ try:
+ fontlog = open(args.fontlog)
+ except Exception as e:
+ logger.log(f"Unable to open {args.fontlog}: {str(e)}", "S")
+ # Parse the fontlog file
+ (section, match) = readuntil(fontlog, ("Basic Font Information",)) # Skip until start of "Basic Font Information" section
+ if match is None: logger.log("No 'Basic Font Information' section in fontlog", "S")
+ (fldescription, match) = readuntil(fontlog, ("Information for C", "Acknowledgements")) # Description ends when first of these sections is found
+ fldescription = [{"text": fldescription}]
+ if match == "Information for C": (section, match) = readuntil(fontlog, ("Acknowledgements",)) # If Info... section present then skip on to Acknowledgements
+ if match is None: logger.log("No 'Acknowledgements' section in fontlog", "S")
+ (acksection, match) = readuntil(fontlog, ("No match needed!!",))
+
+ flcredits = []
+ credit = {}
+ acktype = ""
+ flog2woff = {"N": "name", "E": "Not used", "W": "url", "D": "role"}
+ for line in acksection.splitlines():
+ if line == "":
+ if acktype != "": # Must be at the end of a credit section
+ if "name" in credit:
+ flcredits.append(credit)
+ else:
+ logger.log("Credit section found with no N: entry", "E")
+ credit = {}
+ acktype = ""
+ else:
+ match = re.match("^([NEWD]): (.*)", line)
+ if match is None:
+ if acktype == "N": credit["name"] = credit["name"] + line # Name entries can be multiple lines
+ else:
+ acktype = match.group(1)
+ if acktype in credit:
+ logger.log("Multiple " + acktype + " entries found in a credit section", "E")
+ else:
+ credit[flog2woff[acktype]] = match.group(2)
+ if flcredits == []: logger.log("No credits found in fontlog", "S")
+ if args.populateufowoff:
+ ufofields["woffMetadataDescription"] = fldescription # Force fontlog values to be used writing metadata.xml later
+ ufofields["woffMetadataCredits"] = flcredits
+ # Create xml strings and update fontinfo
+ xmlstring = "<dict>" + \
+ "<key>text</key><array><dict>" + \
+ "<key>text</key><string>" + textprotect(fldescription[0]["text"]) + "</string>" + \
+ "</dict></array>" + \
+ "<key>url</key><string>https://software.sil.org/</string>"\
+ "</dict>"
+ fi.setelem("woffMetadataDescription", ET.fromstring(xmlstring))
+
+ xmlstring = "<dict><key>credits</key><array>"
+ for credit in flcredits:
+ xmlstring += '<dict><key>name</key><string>' + textprotect(credit["name"]) + '</string>'
+ if "url" in credit: xmlstring += '<key>url</key><string>' + textprotect(credit["url"]) + '</string>'
+ if "role" in credit: xmlstring += '<key>role</key><string>' + textprotect(credit["role"]) + '</string>'
+ xmlstring += '</dict>'
+ xmlstring += '</array></dict>'
+ fi.setelem("woffMetadataCredits", ET.fromstring(xmlstring))
+
+ fi.setval("openTypeHeadCreated", "string", datetime.datetime.now().strftime("%Y/%m/%d %H:%M:%S"))
+ logger.log("Writing updated fontinfo.plist with values from FONTLOG.txt", "P")
+ exists = True if os.path.isfile(os.path.join(font.ufodir, "fontinfo.plist")) else False
+ UFO.writeXMLobject(fi, font.outparams, font.ufodir, "fontinfo.plist", exists, fobject=True)
+
+ description = ufofields["woffMetadataDescription"]
+ if description == None: description = fldescription
+ credits = ufofields["woffMetadataCredits"]
+ if credits == None : credits = flcredits
+
+ # Construct output file name
+ (folder, ufoname) = os.path.split(font.ufodir)
+ filename = os.path.join(folder, pfn + "-WOFF-metadata.xml") if ofn is None else ofn
+ try:
+ file = open(filename, "w")
+ except Exception as e:
+ logger.log("Unable to open " + filename + " for writing:\n" + str(e), "S")
+ logger.log("Writing to : " + filename, "P")
+
+ file.write('<?xml version="1.0" encoding="UTF-8"?>\n')
+ file.write('<metadata version="1.0">\n')
+ file.write(' <uniqueid id="' + orgid + '.' + pfn + '.' + version + '" />\n')
+ file.write(' <vendor name="' + attrprotect(ufofields["openTypeNameManufacturer"]) + '" url="'
+ + attrprotect(ufofields["openTypeNameManufacturerURL"]) + '" />\n')
+ file.write(' <credits>\n')
+ for credit in credits:
+ file.write(' <credit\n')
+ file.write(' name="' + attrprotect(credit["name"]) + '"\n')
+ if "url" in credit: file.write(' url="' + attrprotect(credit["url"]) + '"\n')
+ if "role" in credit: file.write(' role="' + attrprotect(credit["role"]) + '"\n')
+ file.write(' />\n')
+ file.write(' </credits>\n')
+
+ if ufofields["woffMetadataDescriptionurl"]:
+ file.write(f' <description url="{ufofields["woffMetadataDescriptionurl"]}">\n')
+ else:
+ file.write(' <description>\n')
+ file.write(' <text lang="en">\n')
+ for entry in description:
+ for line in entry["text"].splitlines():
+ file.write(' ' + textprotect(line) + '\n')
+ file.write(' </text>\n')
+ file.write(' </description>\n')
+
+ file.write(' <license url="http://scripts.sil.org/OFL" id="org.sil.ofl.1.1">\n')
+ file.write(' <text lang="en">\n')
+ for line in ufofields["openTypeNameLicense"].splitlines(): file.write(' ' + textprotect(line) + '\n')
+ file.write(' </text>\n')
+ file.write(' </license>\n')
+
+ file.write(' <copyright>\n')
+ file.write(' <text lang="en">\n')
+ for line in ufofields["copyright"].splitlines(): file.write(' ' + textprotect(line) + '\n')
+ file.write(' </text>\n')
+ file.write(' </copyright>\n')
+
+ if 'trademark' in ufofields:
+ file.write(' <trademark>\n')
+ file.write(' <text lang="en">' + textprotect(ufofields["trademark"]) + '</text>\n')
+ file.write(' </trademark>\n')
+
+ file.write('</metadata>')
+
+ file.close()
+
+def readuntil(file, texts): # Read through file until line is in texts. Return section up to there and the text matched
+ skip = True
+ match = None
+ for line in file:
+ line = line.strip()
+ if skip: # Skip underlines and blank lines at start of section
+ if line == "" or line[0:5] == "-----":
+ pass
+ else:
+ section = line
+ skip = False
+ else:
+ for text in texts:
+ if line[0:len(text)] == text: match = text
+ if match: break
+ section = section + "\n" + line
+ while section[-1] == "\n": section = section[:-1] # Strip blank lines at end
+ return (section, match)
+
+def textprotect(txt): # Switch special characters in text to use &...; format
+ txt = re.sub(r'&', '&amp;', txt)
+ txt = re.sub(r'<', '&lt;', txt)
+ txt = re.sub(r'>', '&gt;', txt)
+ return txt
+
+def attrprotect(txt): # Switch special characters in text to use &...; format
+ txt = re.sub(r'&', '&amp;', txt)
+ txt = re.sub(r'<', '&lt;', txt)
+ txt = re.sub(r'>', '&gt;', txt)
+ txt = re.sub(r'"', '&quot;', txt)
+ return txt
+
+def cmd(): execute("UFO", doit, argspec)
+if __name__ == "__main__": cmd()
diff --git a/lib/silfont/scripts/psfnormalize.py b/lib/silfont/scripts/psfnormalize.py
new file mode 100755
index 0000000..82b132e
--- /dev/null
+++ b/lib/silfont/scripts/psfnormalize.py
@@ -0,0 +1,31 @@
+#!/usr/bin/env python
+__doc__ = '''Normalize a UFO and optionally convert between UFO2 and UFO3'''
+__url__ = 'http://github.com/silnrsi/pysilfont'
+__copyright__ = 'Copyright (c) 2015 SIL International (http://www.sil.org)'
+__license__ = 'Released under the MIT License (http://opensource.org/licenses/MIT)'
+__author__ = 'David Raymond'
+
+from silfont.core import execute
+
+argspec = [
+ ('ifont',{'help': 'Input font file'}, {'type': 'infont'}),
+ ('ofont',{'help': 'Output font file','nargs': '?' }, {'type': 'outfont'}),
+ ('-l','--log',{'help': 'Log file'}, {'type': 'outfile', 'def': '_normalize.log'}),
+ ('-v','--version',{'help': 'UFO version to convert to (2, 3 or 3ff)'},{})]
+
+def doit(args) :
+
+ if args.version is not None :
+ v = args.version.lower()
+ if v in ("2","3","3ff") :
+ if v == "3ff": # Special action for testing with FontForge import
+ v = "3"
+ args.ifont.outparams['format1Glifs'] = True
+ args.ifont.outparams['UFOversion'] = v
+ else:
+ args.logger.log("-v, --version must be one of 2,3 or 3ff", "S")
+
+ return args.ifont
+
+def cmd() : execute("UFO",doit, argspec)
+if __name__ == "__main__": cmd()
diff --git a/lib/silfont/scripts/psfremovegliflibkeys.py b/lib/silfont/scripts/psfremovegliflibkeys.py
new file mode 100644
index 0000000..5d59ad7
--- /dev/null
+++ b/lib/silfont/scripts/psfremovegliflibkeys.py
@@ -0,0 +1,71 @@
+#!/usr/bin/env python
+__doc__ = '''Remove the specified key(s) from glif libs'''
+__url__ = 'http://github.com/silnrsi/pysilfont'
+__copyright__ = 'Copyright (c) 2017 SIL International (http://www.sil.org)'
+__license__ = 'Released under the MIT License (http://opensource.org/licenses/MIT)'
+__author__ = 'David Raymond'
+
+from silfont.core import execute
+
+argspec = [
+ ('ifont',{'help': 'Input font file'}, {'type': 'infont'}),
+ ('key',{'help': 'Key(s) to remove','nargs': '*' }, {}),
+ ('-b', '--begins', {'help': 'Remove keys beginning with','nargs': '*' }, {}),
+ ('-o', '--ofont',{'help': 'Output font file' }, {'type': 'outfont'}),
+ ('-l','--log',{'help': 'Log file'}, {'type': 'outfile', 'def': '_removegliflibkeys.log'})]
+
+def doit(args) :
+ font = args.ifont
+ logger = args.logger
+ keys = args.key
+ bkeys=args.begins if args.begins is not None else []
+ keycounts = {}
+ bkeycounts = {}
+ for key in keys : keycounts[key] = 0
+ for key in bkeys:
+ if key in keycounts: logger.log("--begins key can't be the same as a standard key", "S")
+ bkeycounts[key] = 0
+
+ for glyphn in font.deflayer :
+ glyph = font.deflayer[glyphn]
+ if glyph["lib"] :
+ for key in keys :
+ if key in glyph["lib"] :
+ val = str( glyph["lib"].getval(key))
+ glyph["lib"].remove(key)
+ keycounts[key] += 1
+ logger.log(key + " removed from " + glyphn + ". Value was " + val, "I" )
+ if key == "com.schriftgestaltung.Glyphs.originalWidth": # Special fix re glyphLib bug
+ if glyph["advance"] is None: glyph.add("advance")
+ adv = (glyph["advance"])
+ if adv.width is None:
+ adv.width = int(float(val))
+ logger.log("Advance width for " + glyphn + " set to " + val, "I")
+ else:
+ logger.log("Advance width for " + glyphn + " is already set to " + str(adv.width) + " so originalWidth not copied", "E")
+ for key in bkeys:
+ gkeys = list(glyph["lib"])
+ for gkey in gkeys:
+ if gkey[:len(key)] == key:
+ val = str(glyph["lib"].getval(gkey))
+ glyph["lib"].remove(gkey)
+ if gkey in keycounts:
+ keycounts[gkey] += 1
+ else:
+ keycounts[gkey] = 1
+ bkeycounts[key] += 1
+ logger.log(gkey + " removed from " + glyphn + ". Value was " + val, "I")
+
+ for key in keycounts :
+ count = keycounts[key]
+ if count > 0 :
+ logger.log(key + " removed from " + str(count) + " glyphs", "P")
+ else :
+ logger.log("No lib entries found for " + key, "E")
+ for key in bkeycounts:
+ if bkeycounts[key] == 0: logger.log("No lib entries found for beginning with " + key, "E")
+
+ return font
+
+def cmd() : execute("UFO",doit,argspec)
+if __name__ == "__main__": cmd()
diff --git a/lib/silfont/scripts/psfrenameglyphs.py b/lib/silfont/scripts/psfrenameglyphs.py
new file mode 100644
index 0000000..ff8ef73
--- /dev/null
+++ b/lib/silfont/scripts/psfrenameglyphs.py
@@ -0,0 +1,587 @@
+#!/usr/bin/env python
+__doc__ = '''Assign new working names to glyphs based on csv input file
+- csv format oldname,newname'''
+__url__ = 'http://github.com/silnrsi/pysilfont'
+__copyright__ = 'Copyright (c) 2017 SIL International (http://www.sil.org)'
+__license__ = 'Released under the MIT License (http://opensource.org/licenses/MIT)'
+__author__ = 'Bob Hallissy'
+
+from silfont.core import execute
+from xml.etree import ElementTree as ET
+import re
+import os
+from glob import glob
+
+argspec = [
+ ('ifont',{'help': 'Input font file'}, {'type': 'infont'}),
+ ('ofont',{'help': 'Output font file','nargs': '?' }, {'type': 'outfont'}),
+ ('-c', '--classfile', {'help': 'Classes file'}, {}),
+ ('-i','--input',{'help': 'Input csv file'}, {'type': 'incsv', 'def': 'namemap.csv'}),
+ ('--mergecomps',{'help': 'turn on component merge', 'action': 'store_true', 'default': False},{}),
+ ('-l','--log',{'help': 'Log file'}, {'type': 'outfile', 'def': '_renameglyphs.log'})]
+
+csvmap = "" # Variable used globally
+
+def doit(args) :
+ global csvmap, ksetsbymember
+ font = args.ifont
+ incsv = args.input
+ logger = args.logger
+ mergemode = args.mergecomps
+
+ failerrors = 0 # Keep count of errors that should cause the script to fail
+ csvmap = {} # List of all real maps in incsv, so excluding headers, blank lines, comments and identity maps
+ nameMap = {} # remember all glyphs actually renamed
+ kerngroupsrenamed = {} # List of all kern groups actually renamed
+
+ # List of secondary layers (ie layers other than the default)
+ secondarylayers = [x for x in font.layers if x.layername != "public.default"]
+
+ # Obtain lib.plist glyph order(s) and psnames if they exist:
+ publicGlyphOrder = csGlyphOrder = psnames = displayStrings = None
+ if hasattr(font, 'lib'):
+ if 'public.glyphOrder' in font.lib:
+ publicGlyphOrder = font.lib.getval('public.glyphOrder') # This is an array
+ if 'com.schriftgestaltung.glyphOrder' in font.lib:
+ csGlyphOrder = font.lib.getval('com.schriftgestaltung.glyphOrder') # This is an array
+ if 'public.postscriptNames' in font.lib:
+ psnames = font.lib.getval('public.postscriptNames') # This is a dict keyed by glyphnames
+ if 'com.schriftgestaltung.customParameter.GSFont.DisplayStrings' in font.lib:
+ displayStrings = font.lib.getval('com.schriftgestaltung.customParameter.GSFont.DisplayStrings')
+ else:
+ logger.log("no lib.plist found in font", "W")
+
+ # Renaming within the UFO is done in two passes to make sure we can handle circular renames such as:
+ # someglyph.alt = someglyph
+ # someglyph = someglyph.alt
+
+ # Note that the various objects with glyph names are all done independently since
+ # the same glyph names are not necessarily in all structures.
+
+ # First pass: process all records of csv, and for each glyph that is to be renamed:
+ # If the new glyphname is not already present, go ahead and rename it now.
+ # If the new glyph name already exists, rename the glyph to a temporary name
+ # and put relevant details in saveforlater[]
+
+ saveforlaterFont = [] # For the font itself
+ saveforlaterPGO = [] # For public.GlyphOrder
+ saveforlaterCSGO = [] # For GlyphsApp GlyphOrder (com.schriftgestaltung.glyphOrder)
+ saveforlaterPSN = [] # For public.postscriptNames
+ deletelater = [] # Glyphs we'll delete after merging
+
+ for r in incsv:
+ oldname = r[0].strip()
+ newname = r[1].strip()
+ # ignore header row and rows where the newname is blank or a comment marker
+ if oldname == "Name" or oldname.startswith('#') or newname == "" or oldname == newname:
+ continue
+ if len(oldname)==0:
+ logger.log('empty glyph oldname in glyph_data; ignored (newname: %s)' % newname, 'W')
+ continue
+ csvmap[oldname]=newname
+
+ # Handle font first:
+ if oldname not in font.deflayer:
+ logger.log("glyph name not in font: " + oldname , "I")
+ elif newname not in font.deflayer:
+ inseclayers = False
+ for layer in secondarylayers:
+ if newname in layer:
+ logger.log("Glyph %s is already in non-default layers; can't rename %s" % (newname, oldname), "E")
+ failerrors += 1
+ inseclayers = True
+ continue
+ if not inseclayers:
+ # Ok, this case is easy: just rename the glyph in all layers
+ for layer in font.layers:
+ if oldname in layer: layer[oldname].name = newname
+ nameMap[oldname] = newname
+ logger.log("Pass 1 (Font): Renamed %s to %s" % (oldname, newname), "I")
+ elif mergemode:
+ mergeglyphs(font.deflayer[oldname], font.deflayer[newname])
+ for layer in secondarylayers:
+ if oldname in layer:
+ if newname in layer:
+ mergeglyphs(layer[oldname], layer[newname])
+ else:
+ layer[oldname].name = newname
+
+ nameMap[oldname] = newname
+ deletelater.append(oldname)
+ logger.log("Pass 1 (Font): merged %s to %s" % (oldname, newname), "I")
+ else:
+ # newname already in font -- but it might get renamed later in which case this isn't actually a problem.
+ # For now, then, rename glyph to a temporary name and remember it for second pass
+ tempname = gettempname(lambda n : n not in font.deflayer)
+ for layer in font.layers:
+ if oldname in layer:
+ layer[oldname].name = tempname
+ saveforlaterFont.append( (tempname, oldname, newname) )
+
+ # Similar algorithm for public.glyphOrder, if present:
+ if publicGlyphOrder:
+ if oldname not in publicGlyphOrder:
+ logger.log("glyph name not in publicGlyphorder: " + oldname , "I")
+ else:
+ x = publicGlyphOrder.index(oldname)
+ if newname not in publicGlyphOrder:
+ publicGlyphOrder[x] = newname
+ nameMap[oldname] = newname
+ logger.log("Pass 1 (PGO): Renamed %s to %s" % (oldname, newname), "I")
+ elif mergemode:
+ del publicGlyphOrder[x]
+ nameMap[oldname] = newname
+ logger.log("Pass 1 (PGO): Removed %s (now using %s)" % (oldname, newname), "I")
+ else:
+ tempname = gettempname(lambda n : n not in publicGlyphOrder)
+ publicGlyphOrder[x] = tempname
+ saveforlaterPGO.append( (x, oldname, newname) )
+
+ # And for GlyphsApp glyph order, if present:
+ if csGlyphOrder:
+ if oldname not in csGlyphOrder:
+ logger.log("glyph name not in csGlyphorder: " + oldname , "I")
+ else:
+ x = csGlyphOrder.index(oldname)
+ if newname not in csGlyphOrder:
+ csGlyphOrder[x] = newname
+ nameMap[oldname] = newname
+ logger.log("Pass 1 (csGO): Renamed %s to %s" % (oldname, newname), "I")
+ elif mergemode:
+ del csGlyphOrder[x]
+ nameMap[oldname] = newname
+ logger.log("Pass 1 (csGO): Removed %s (now using %s)" % (oldname, newname), "I")
+ else:
+ tempname = gettempname(lambda n : n not in csGlyphOrder)
+ csGlyphOrder[x] = tempname
+ saveforlaterCSGO.append( (x, oldname, newname) )
+
+ # And for psnames
+ if psnames:
+ if oldname not in psnames:
+ logger.log("glyph name not in psnames: " + oldname , "I")
+ elif newname not in psnames:
+ psnames[newname] = psnames.pop(oldname)
+ nameMap[oldname] = newname
+ logger.log("Pass 1 (psn): Renamed %s to %s" % (oldname, newname), "I")
+ elif mergemode:
+ del psnames[oldname]
+ nameMap[oldname] = newname
+ logger.log("Pass 1 (psn): Removed %s (now using %s)" % (oldname, newname), "I")
+ else:
+ tempname = gettempname(lambda n: n not in psnames)
+ psnames[tempname] = psnames.pop(oldname)
+ saveforlaterPSN.append( (tempname, oldname, newname))
+
+ # Second pass: now we can reprocess those things we saved for later:
+ # If the new glyphname is no longer present, we can complete the renaming
+ # Otherwise we've got a fatal error
+
+ for j in saveforlaterFont:
+ tempname, oldname, newname = j
+ if newname in font.deflayer: # Only need to check deflayer, since (if present) it would have been renamed in all
+ # Ok, this really is a problem
+ logger.log("Glyph %s already in font; can't rename %s" % (newname, oldname), "E")
+ failerrors += 1
+ else:
+ for layer in font.layers:
+ if tempname in layer:
+ layer[tempname].name = newname
+ nameMap[oldname] = newname
+ logger.log("Pass 2 (Font): Renamed %s to %s" % (oldname, newname), "I")
+
+ for j in saveforlaterPGO:
+ x, oldname, newname = j
+ if newname in publicGlyphOrder:
+ # Ok, this really is a problem
+ logger.log("Glyph %s already in public.GlyphOrder; can't rename %s" % (newname, oldname), "E")
+ failerrors += 1
+ else:
+ publicGlyphOrder[x] = newname
+ nameMap[oldname] = newname
+ logger.log("Pass 2 (PGO): Renamed %s to %s" % (oldname, newname), "I")
+
+ for j in saveforlaterCSGO:
+ x, oldname, newname = j
+ if newname in csGlyphOrder:
+ # Ok, this really is a problem
+ logger.log("Glyph %s already in com.schriftgestaltung.glyphOrder; can't rename %s" % (newname, oldname), "E")
+ failerrors += 1
+ else:
+ csGlyphOrder[x] = newname
+ nameMap[oldname] = newname
+ logger.log("Pass 2 (csGO): Renamed %s to %s" % (oldname, newname), "I")
+
+ for tempname, oldname, newname in saveforlaterPSN:
+ if newname in psnames:
+ # Ok, this really is a problem
+ logger.log("Glyph %s already in public.postscriptNames; can't rename %s" % (newname, oldname), "E")
+ failerrors += 1
+ else:
+ psnames[newname] = psnames.pop(tempname)
+ nameMap[oldname] = newname
+ logger.log("Pass 2 (psn): Renamed %s to %s" % (oldname, newname), "I")
+
+ # Rebuild font structures from the modified lists we have:
+
+ # Rebuild glyph order elements:
+ if publicGlyphOrder:
+ array = ET.Element("array")
+ for name in publicGlyphOrder:
+ ET.SubElement(array, "string").text = name
+ font.lib.setelem("public.glyphOrder", array)
+
+ if csGlyphOrder:
+ array = ET.Element("array")
+ for name in csGlyphOrder:
+ ET.SubElement(array, "string").text = name
+ font.lib.setelem("com.schriftgestaltung.glyphOrder", array)
+
+ # Rebuild postscriptNames:
+ if psnames:
+ dict = ET.Element("dict")
+ for n in psnames:
+ ET.SubElement(dict, "key").text = n
+ ET.SubElement(dict, "string").text = psnames[n]
+ font.lib.setelem("public.postscriptNames", dict)
+
+ # Iterate over all glyphs, and fix up any components that reference renamed glyphs
+ for layer in font.layers:
+ for name in layer:
+ glyph = layer[name]
+ for component in glyph.etree.findall('./outline/component[@base]'):
+ oldname = component.get('base')
+ if oldname in nameMap:
+ component.set('base', nameMap[oldname])
+ logger.log(f'renamed component base {oldname} to {component.get("base")} in glyph {name} layer {layer.layername}', 'I')
+ lib = glyph['lib']
+ if lib:
+ if 'com.schriftgestaltung.Glyphs.ComponentInfo' in lib:
+ cielem = lib['com.schriftgestaltung.Glyphs.ComponentInfo'][1]
+ for component in cielem:
+ for i in range(0,len(component),2):
+ if component[i].text == 'name':
+ oldname = component[i+1].text
+ if oldname in nameMap:
+ component[i+1].text = nameMap[oldname]
+ logger.log(f'renamed component info {oldname} to {nameMap[oldname]} in glyph {name} layer {layer.layername}', 'I')
+
+ # Delete anything we no longer need:
+ for name in deletelater:
+ for layer in font.layers:
+ if name in layer: layer.delGlyph(name)
+ logger.log("glyph %s removed" % name, "I")
+
+ # Other structures with glyphs in are handled by looping round the structures replacing glyphs rather than
+ # looping round incsv
+
+ # Update Display Strings
+
+ if displayStrings:
+ changed = False
+ glyphRE = re.compile(r'/([a-zA-Z0-9_.-]+)') # regex to match / followed by a glyph name
+ for i, dispstr in enumerate(displayStrings): # Passing the glyphSub function to .sub() causes it to
+ displayStrings[i] = glyphRE.sub(glyphsub, dispstr) # every non-overlapping occurrence of pattern
+ if displayStrings[i] != dispstr:
+ changed = True
+ if changed:
+ array = ET.Element("array")
+ for dispstr in displayStrings:
+ ET.SubElement(array, "string").text = dispstr
+ font.lib.setelem('com.schriftgestaltung.customParameter.GSFont.DisplayStrings', array)
+ logger.log("com.schriftgestaltung.customParameter.GSFont.DisplayStrings updated", "I")
+
+ # Process groups.plist and kerning.plist
+ # group names in the form public.kern[1|2].<glyph name> will automatically be renamed if the glyph name is in the csvmap
+ #
+ groups = kerning = None
+ kgroupprefixes = {"public.kern1.": 1, "public.kern2.": 2}
+
+ if "groups" in font.__dict__: groups = font.groups
+ if "kerning" in font.__dict__: kerning = font.kerning
+
+ if (groups or kerning) and mergemode:
+ logger.log("Note - Kerning and group data not processed when using mergecomps", "P")
+ elif groups or kerning:
+
+ kgroupsmap = ["", {}, {}] # Dicts of kern1/kern2 group renames. Outside the groups if statement, since also used with kerning.plist
+ if groups:
+ # Analyse existing data, building dict from existing data and building some indexes
+ gdict = {}
+ kgroupsbyglyph = ["", {}, {}] # First entry dummy, so index is 1 or 2 for kern1 and kern2
+ kgroupduplicates = ["", [], []] #
+ for gname in groups:
+ group = groups.getval(gname)
+ gdict[gname] = group
+ kprefix = gname[0:13]
+ if kprefix in kgroupprefixes:
+ ktype = kgroupprefixes[kprefix]
+ for glyph in group:
+ if glyph in kgroupsbyglyph[ktype]:
+ kgroupduplicates[ktype].append(glyph)
+ logger.log("In existing kern groups, %s is in more than one kern%s group" % (glyph, str(ktype)), "E")
+ failerrors += 1
+ else:
+ kgroupsbyglyph[ktype][glyph] = gname
+ # Now process the group data
+ glyphsrenamed = []
+ saveforlaterKgroups = []
+ for gname in list(gdict): # Loop round groups renaming glyphs within groups and kern group names
+ group = gdict[gname]
+
+ # Rename group if kern1 or kern2 group
+ kprefix = gname[:13]
+ if kprefix in kgroupprefixes:
+ ktype = kgroupprefixes[kprefix]
+ ksuffix = gname[13:]
+ if ksuffix in csvmap: # This is a kern group that we should rename
+ newgname = kprefix + csvmap[ksuffix]
+ if newgname in gdict: # Will need to be renamed in second pass
+ tempname = gettempname(lambda n : n not in gdict)
+ gdict[tempname] = gdict.pop(gname)
+ saveforlaterKgroups.append((tempname, gname, newgname))
+ else:
+ gdict[newgname] = gdict.pop(gname)
+ kerngroupsrenamed[gname] = newgname
+ logger.log("Pass 1 (Kern groups): Renamed %s to %s" % (gname, newgname), "I")
+ kgroupsmap[ktype][gname] = newgname
+
+ # Now rename glyphs within the group
+ # - This could lead to duplicate names, but that might be valid for arbitrary groups so not checked
+ # - kern group validity will be checked after all renaming is done
+
+ for (i, glyph) in enumerate(group):
+ if glyph in csvmap:
+ group[i] = csvmap[glyph]
+ if glyph not in glyphsrenamed: glyphsrenamed.append(glyph)
+
+ # Need to report glyphs renamed after the loop, since otherwise could report multiple times
+ for oldname in glyphsrenamed:
+ nameMap[oldname] = csvmap[oldname]
+ logger.log("Glyphs in groups: Renamed %s to %s" % (oldname, csvmap[oldname]), "I")
+
+ # Second pass for renaming kern groups. (All glyph renaming is done in first pass)
+
+ for (tempname, oldgname, newgname) in saveforlaterKgroups:
+ if newgname in gdict: # Can't rename
+ logger.log("Kern group %s already in groups.plist; can't rename %s" % (newgname, oldgname), "E")
+ failerrors += 1
+ else:
+ gdict[newgname] = gdict.pop(tempname)
+ kerngroupsrenamed[oldgname] = newgname
+ logger.log("Pass 2 (Kern groups): Renamed %s to %s" % (oldgname, newgname), "I")
+
+ # Finally check kern groups follow the UFO rules!
+ kgroupsbyglyph = ["", {}, {}] # Reset for new analysis
+ for gname in gdict:
+ group = gdict[gname]
+ kprefix = gname[:13]
+ if kprefix in kgroupprefixes:
+ ktype = kgroupprefixes[kprefix]
+ for glyph in group:
+ if glyph in kgroupsbyglyph[ktype]: # Glyph already in a kern group so we have a duplicate
+ if glyph not in kgroupduplicates[ktype]: # This is a newly-created duplicate so report
+ logger.log("After renaming, %s is in more than one kern%s group" % (glyph, str(ktype)), "E")
+ failerrors += 1
+ kgroupduplicates[ktype].append(glyph)
+ else:
+ kgroupsbyglyph[ktype][glyph] = gname
+
+ # Now need to recreate groups.plist from gdict
+
+ for group in list(groups): groups.remove(group) # Empty existing contents
+ for gname in gdict:
+ elem = ET.Element("array")
+ for glyph in gdict[gname]:
+ ET.SubElement(elem, "string").text = glyph
+ groups.setelem(gname, elem)
+
+ # Now process kerning data
+ if kerning:
+ k1map = kgroupsmap[1]
+ k2map = kgroupsmap[2]
+ kdict = {}
+ for setname in kerning: kdict[setname] = kerning.getval(setname) # Create a working dict from plist
+ saveforlaterKsets = []
+ # First pass on set names
+ for setname in list(kdict): # setname could be a glyph in csvmap or a kern1 group name in k1map
+ if setname in csvmap or setname in k1map:
+ newname = csvmap[setname] if setname in csvmap else k1map[setname]
+ if newname in kdict:
+ tempname = gettempname(lambda n : n not in kdict)
+ kdict[tempname] = kdict.pop(setname)
+ saveforlaterKsets.append((tempname, setname, newname))
+ else:
+ kdict[newname] = kdict.pop(setname)
+ if setname in csvmap: nameMap[setname] = newname # Change to kern set name will have been logged previously
+ logger.log("Pass 1 (Kern sets): Renamed %s to %s" % (setname, newname), "I")
+
+ # Now do second pass for set names
+ for (tempname, oldname, newname) in saveforlaterKsets:
+ if newname in kdict: # Can't rename
+ logger.log("Kern set %s already in kerning.plist; can't rename %s" % (newname, oldname), "E")
+ failerrors += 1
+ else:
+ kdict[newname] = kdict.pop(tempname)
+ if oldname in csvmap: nameMap[oldname] = newname
+ logger.log("Pass 1 (Kern sets): Renamed %s to %s" % (oldname, newname), "I")
+
+ # Rename kern set members next.
+
+ # Here, since a member could be in more than one set, take different approach to two passes.
+ # - In first pass, rename to a temp (and invalid) name so duplicates are not possible. Name to include
+ # old name for reporting purposes
+ # - In second pass, set to correct new name after checking for duplicates
+
+ # Do first pass for set names
+ tempnames = []
+ for setname in list(kdict):
+ kset = kdict[setname]
+
+ for mname in list(kset): # mname could be a glyph in csvmap or a kern2 group name in k2map
+ if mname in csvmap or mname in k2map:
+ newname = csvmap[mname] if mname in csvmap else k2map[mname]
+ newname = "^" + newname + "^" + mname
+ if newname not in tempnames: tempnames.append(newname)
+ kset[newname] = kset.pop(mname)
+
+ # Second pass to change temp names to correct final names
+ # We need an index of which sets each member is in
+ ksetsbymember = {}
+ for setname in kdict:
+ kset = kdict[setname]
+ for member in kset:
+ if member not in ksetsbymember:
+ ksetsbymember[member] = [setname]
+ else:
+ ksetsbymember[member].append(setname)
+ # Now do the renaming
+ for tname in tempnames:
+ (newname, oldname) = tname[1:].split("^")
+ if newname in ksetsbymember: # Can't rename
+ logger.log("Kern set %s already in kerning.plist; can't rename %s" % (newname, oldname), "E")
+ failerrors += 1
+ else:
+ for ksetname in ksetsbymember[tname]:
+ kset = kdict[ksetname]
+ kset[newname] = kset.pop(tname)
+ ksetsbymember[newname] = ksetsbymember.pop(tname)
+ if tname in csvmap: nameMap[oldname] = newname
+ logger.log("Kern set members: Renamed %s to %s" % (oldname, newname), "I")
+
+ # Now need to recreate kerning.plist from kdict
+ for kset in list(kerning): kerning.remove(kset) # Empty existing contents
+ for kset in kdict:
+ elem = ET.Element("dict")
+ for member in kdict[kset]:
+ ET.SubElement(elem, "key").text = member
+ ET.SubElement(elem, "integer").text = str(kdict[kset][member])
+ kerning.setelem(kset, elem)
+
+ if failerrors:
+ logger.log(str(failerrors) + " issues detected - see errors reported above", "S")
+
+ logger.log("%d glyphs renamed in UFO" % (len(nameMap)), "P")
+ if kerngroupsrenamed: logger.log("%d kern groups renamed in UFO" % (len(kerngroupsrenamed)), "P")
+
+ # If a classfile was provided, change names within it also
+ #
+ if args.classfile:
+
+ logger.log("Processing classfile {}".format(args.classfile), "P")
+
+ # In order to preserve comments we use our own TreeBuilder
+ class MyTreeBuilder(ET.TreeBuilder):
+ def comment(self, data):
+ self.start(ET.Comment, {})
+ self.data(data)
+ self.end(ET.Comment)
+
+ # RE to match separators between glyph names (whitespace):
+ notGlyphnameRE = re.compile(r'(\s+)')
+
+ # Keep a list of glyphnames that were / were not changed
+ changed = set()
+ notChanged = set()
+
+ # Process one token (might be whitespace separator, glyph name, or embedded classname starting with @):
+ def dochange(gname, logErrors = True):
+ if len(gname) == 0 or gname.isspace() or gname not in csvmap or gname.startswith('@'):
+ # No change
+ return gname
+ try:
+ newgname = csvmap[gname]
+ changed.add(gname)
+ return newgname
+ except KeyError:
+ if logErrors: notChanged.add(gname)
+ return gname
+
+ doc = ET.parse(args.classfile, parser=ET.XMLParser(target=MyTreeBuilder()))
+ for e in doc.iter(None):
+ if e.tag in ('class', 'property'):
+ if 'exts' in e.attrib:
+ logger.log("{} '{}' has 'exts' attribute which may need editing".format(e.tag.title(), e.get('name')), "W")
+ # Rather than just split() the text, we'll use re and thus try to preserve whitespace
+ e.text = ''.join([dochange(x) for x in notGlyphnameRE.split(e.text)])
+ elif e.tag is ET.Comment:
+ # Go ahead and look for glyph names in comment text but don't flag as error
+ e.text = ''.join([dochange(x, False) for x in notGlyphnameRE.split(e.text)])
+ # and process the tail as this might be valid part of class or property
+ e.tail = ''.join([dochange(x) for x in notGlyphnameRE.split(e.tail)])
+
+
+ if len(changed):
+ # Something in classes changed so rewrite it... saving backup
+ (dn,fn) = os.path.split(args.classfile)
+ dn = os.path.join(dn, args.paramsobj.sets['main']['backupdir'])
+ if not os.path.isdir(dn):
+ os.makedirs(dn)
+ # Work out backup name based on existing backups
+ backupname = os.path.join(dn,fn)
+ nums = [int(re.search(r'\.(\d+)~$',n).group(1)) for n in glob(backupname + ".*~")]
+ backupname += ".{}~".format(max(nums) + 1 if nums else 1)
+ logger.log("Backing up input classfile to {}".format(backupname), "P")
+ # Move the original file to backupname
+ os.rename(args.classfile, backupname)
+ # Write the output file
+ doc.write(args.classfile)
+
+ if len(notChanged):
+ logger.log("{} glyphs renamed, {} NOT renamed in {}: {}".format(len(changed), len(notChanged), args.classfile, ' '.join(notChanged)), "W")
+ else:
+ logger.log("All {} glyphs renamed in {}".format(len(changed), args.classfile), "P")
+
+ return font
+
+def mergeglyphs(mergefrom, mergeto): # Merge any "moving" anchors (i.e., those starting with '_') into the glyph we're keeping
+ # Assumption: we are merging one or more component references to just one component; deleting the others
+ for a in mergefrom['anchor']:
+ aname = a.element.get('name')
+ if aname.startswith('_'):
+ # We want to copy this anchor to the glyph being kept:
+ for i, a2 in enumerate(mergeto['anchor']):
+ if a2.element.get('name') == aname:
+ # Overwrite existing anchor of same name
+ mergeto['anchor'][i] = a
+ break
+ else:
+ # Append anchor to glyph
+ mergeto['anchor'].append(a)
+
+def gettempname(f):
+ ''' return a temporary glyph name that, when passed to function f(), returns true'''
+ # Initialize function attribute for use as counter
+ if not hasattr(gettempname, "counter"): gettempname.counter = 0
+ while True:
+ name = "tempglyph%d" % gettempname.counter
+ gettempname.counter += 1
+ if f(name): return name
+
+def glyphsub(m): # Function passed to re.sub() when updating display strings
+ global csvmap
+ gname = m.group(1)
+ return '/' + csvmap[gname] if gname in csvmap else m.group(0)
+
+def cmd() : execute("UFO",doit,argspec)
+if __name__ == "__main__": cmd()
diff --git a/lib/silfont/scripts/psfrunfbchecks.py b/lib/silfont/scripts/psfrunfbchecks.py
new file mode 100755
index 0000000..eddf8bc
--- /dev/null
+++ b/lib/silfont/scripts/psfrunfbchecks.py
@@ -0,0 +1,249 @@
+#!/usr/bin/env python
+'''Run Font Bakery tests using a standard profile with option to specify an alternative profile
+It defaults to ttfchecks.py - ufo checks are not supported yet'''
+__url__ = 'http://github.com/silnrsi/pysilfont'
+__copyright__ = 'Copyright (c) 2020 SIL International (http://www.sil.org)'
+__license__ = 'Released under the MIT License (http://opensource.org/licenses/MIT)'
+__author__ = 'David Raymond'
+
+import glob, os, csv
+
+from textwrap import TextWrapper
+
+from fontbakery.reporters.serialize import SerializeReporter
+from fontbakery.reporters.html import HTMLReporter
+from fontbakery.checkrunner import distribute_generator, CheckRunner, get_module_profile, SKIP, INFO
+from fontbakery.configuration import Configuration
+from fontbakery.commands.check_profile import get_module
+from fontbakery import __version__ as version
+
+from silfont.core import execute
+
+argspec = [
+ ('fonts',{'help': 'font(s) to run checks against; wildcards allowed', 'nargs': "+"}, {'type': 'filename'}),
+ ('--profile', {'help': 'profile to use instead of Pysilfont default'}, {}),
+ ('--html', {'help': 'Write html report to htmlfile', 'metavar': "HTMLFILE"}, {}),
+ ('--csv',{'help': 'Write results to csv file'}, {'type': 'filename', 'def': None}),
+ ('-F', '--full-lists',{'help': "Don't truncate lists of items" ,'action': 'store_true', 'default': False}, {}),
+ ('--ttfaudit', {'help': 'Compare the list of ttf checks in pysilfont with those in Font Bakery and output a csv to "fonts". No checks are actually run',
+ 'action': 'store_true', 'default': False}, {}),
+ ('-l', '--log', {'help': 'Log file'}, {'type': 'outfile', 'def': '_runfbchecks.log'})]
+
+def doit(args):
+ global version
+ v = version.split(".")
+ version = f'{v[0]}.{v[1]}.{v[2]}' # Set version to just the number part - ie without .dev...
+
+ logger = args.logger
+ htmlfile = args.html
+
+ if args.ttfaudit: # Special action to compare checks in profile against check_list values
+ audit(args.fonts, logger) # args.fonts used as output file name for audit
+ return
+
+ if args.csv:
+ try:
+ csvfile = open(args.csv, 'w')
+ csvwriter = csv.writer(csvfile)
+ csvlines = []
+ except Exception as e:
+ logger.log("Failed to open " + args.csv + ": " + str(e), "S")
+ else:
+ csvfile = None
+
+ # Process list of fonts supplied, expanding wildcards using glob if needed
+ fonts = []
+ fontstype = None
+ for pattern in args.fonts:
+ for fullpath in glob.glob(pattern):
+ ftype = fullpath.lower().rsplit(".", 1)[-1]
+ if ftype == "otf": ftype = "ttf"
+ if ftype not in ("ttf", "ufo"):
+ logger.log("Fonts must be OpenType or UFO - " + fullpath + " invalid", "S")
+ if fontstype is None:
+ fontstype = ftype
+ else:
+ if ftype != fontstype:
+ logger.log("All fonts must be of the same type - both UFO and ttf/otf fonts supplied", "S")
+ fonts.append(fullpath)
+
+ if fonts == [] : logger.log("No files match the filespec provided for fonts: " + str(args.fonts), "S")
+
+ # Find the main folder name for ttf files - strips "results" if present
+ (path, ttfdir) = os.path.split(os.path.dirname(fonts[0]))
+ if ttfdir == ("results"): ttfdir = os.path.basename(path)
+
+ # Create the profile object
+ if args.profile:
+ proname = args.profile
+ else:
+ if fontstype == "ttf":
+ proname = "silfont.fbtests.ttfchecks"
+ else:
+ logger.log("UFO fonts not yet supported", "S")
+
+ try:
+ module = get_module(proname)
+ except Exception as e:
+ logger.log("Failed to import profile: " + proname + "\n" + str(e), "S")
+
+ profile = get_module_profile(module)
+ profile.configuration_defaults = {
+ "com.google.fonts/check/file_size": {
+ "WARN_SIZE": 1 * 1024 * 1024,
+ "FAIL_SIZE": 9 * 1024 * 1024
+ }
+ }
+
+ psfcheck_list = module.psfcheck_list
+
+ # Create the runner and reporter objects, then run the tests
+ configuration = Configuration(full_lists = args.full_lists)
+ runner = CheckRunner(profile, values={
+ "fonts": fonts, 'ufos': [], 'designspaces': [], 'glyphs_files': [], 'readme_md': [], 'metadata_pb': []}
+ , config=configuration)
+
+ if version == "0.8.6":
+ sr = SerializeReporter(runner=runner) # This produces results from all the tests in sr.getdoc for later analysis
+ else:
+ sr = SerializeReporter(runner=runner, loglevels = [INFO]) # loglevels was added with 0.8.7
+ reporters = [sr.receive]
+
+ if htmlfile:
+ hr = HTMLReporter(runner=runner, loglevels = [SKIP])
+ reporters.append(hr.receive)
+
+ distribute_generator(runner.run(), reporters)
+
+ # Process the results
+ results = sr.getdoc()
+ sections = results["sections"]
+
+ checks = {}
+ maxname = 11
+ somedebug = False
+ overrides = {}
+ tempoverrides = False
+
+ for section in sections:
+ secchecks = section["checks"]
+ for check in secchecks:
+ checkid = check["key"][1][17:-1]
+ fontfile = check["filename"] if "filename" in check else "Family-wide"
+ path, fontname = os.path.split(fontfile)
+ if fontname not in checks:
+ checks[fontname] = {"ERROR": [], "FAIL": [], "WARN": [], "INFO": [], "SKIP": [], "PASS": [], "DEBUG": []}
+ if len(fontname) > maxname: maxname = len(fontname)
+ status = check["result"]
+ if checkid in psfcheck_list:
+ # Look for status overrides
+ (changetype, temp) = ("temp_change_status", True) if "temp_change_status" in psfcheck_list[checkid]\
+ else ("change_status", False)
+ if changetype in psfcheck_list[checkid]:
+ change_status = psfcheck_list[checkid][changetype]
+ if status in change_status:
+ reason = change_status["reason"] if "reason" in change_status else None
+ overrides[fontname + ", " + checkid] = (status + " to " + change_status[status], temp, reason)
+ if temp: tempoverrides = True
+ status = change_status[status] ## Should validate new status is one of FAIL, WARN or PASS
+ checks[fontname][status].append(check)
+ if status == "DEBUG": somedebug = True
+
+ if htmlfile:
+ logger.log("Writing results to " + htmlfile, "P")
+ with open(htmlfile, 'w') as hfile:
+ hfile.write(hr.get_html())
+
+ fbstats = ["ERROR", "FAIL", "WARN", "INFO", "SKIP", "PASS"]
+ psflevels = ["E", "E", "W", "I", "I", "V"]
+ if somedebug: # Only have debug column if some debug statuses are present
+ fbstats.append("DEBUG")
+ psflevels.append("W")
+ wrapper = TextWrapper(width=120, initial_indent=" ", subsequent_indent=" ")
+ errorcnt = 0
+ failcnt = 0
+ summarymess = "Check status summary:\n"
+ summarymess += "{:{pad}}ERROR FAIL WARN INFO SKIP PASS".format("", pad=maxname+4)
+ if somedebug: summarymess += " DEBUG"
+ fontlist = list(sorted(x for x in checks if x != "Family-wide")) # Alphabetic list of fonts
+ if "Family-wide" in checks: fontlist.append("Family-wide") # Add Family-wide last
+ for fontname in fontlist:
+ summarymess += "\n {:{pad}}".format(fontname, pad=maxname)
+ for i, status in enumerate(fbstats):
+ psflevel = psflevels[i]
+ checklist = checks[fontname][status]
+ cnt = len(checklist)
+ if cnt > 0 or status != "DEBUG": summarymess += "{:6d}".format(cnt) # Suppress 0 for DEBUG
+ if cnt:
+ if status == "ERROR": errorcnt += cnt
+ if status == "FAIL": failcnt += cnt
+ messparts = ["Checks with status {} for {}".format(status, fontname)]
+ for check in checklist:
+ checkid = check["key"][1][17:-1]
+ csvline = [ttfdir, fontname, check["key"][1][17:-1], status, check["description"]]
+ messparts.append(" > {}".format(checkid))
+ for record in check["logs"]:
+ message = record["message"]
+ if record["status"] != status: message = record["status"] + " " + message
+ messparts += wrapper.wrap(message)
+ csvline.append(message)
+ if csvfile: csvlines.append(csvline)
+ logger.log("\n".join(messparts) , psflevel)
+ if csvfile: # Output to csv file, worted by font then checkID
+ for line in sorted(csvlines, key = lambda x: (x[1],x[2])): csvwriter.writerow(line)
+ if overrides != {}:
+ summarymess += "\n Note: " + str(len(overrides)) + " Fontbakery statuses were overridden - see log file for details"
+ if tempoverrides: summarymess += "\n ******** Some of the overrides were temporary overrides ********"
+ logger.log(summarymess, "P")
+
+ if overrides != {}:
+ for oname in overrides:
+ override = overrides[oname]
+ mess = "Status override for " + oname + ": " + override[0]
+ if override[1]: mess += " (Temporary override)"
+ logger.log(mess, "W")
+ if override[2] is not None: logger.log("Override reason: " + override[2], "I")
+
+ if errorcnt + failcnt > 0:
+ mess = str(failcnt) + " test(s) gave a status of FAIL" if failcnt > 0 else ""
+ if errorcnt > 0:
+ if failcnt > 0: mess += "\n "
+ mess += str(errorcnt) + " test(s) gave a status of ERROR which means they failed to execute properly." \
+ "\n " \
+ " ERROR probably indicates a software issue rather than font issue"
+ logger.log(mess, "E")
+
+def audit(fonts, logger):
+ if len(fonts) != 1: logger.log("For audit, specify output csv file instead of list of fonts", "S")
+ csvname = fonts[0]
+ from silfont.fbtests.ttfchecks import all_checks_dict
+ missingfromprofile=[]
+ missingfromchecklist=[]
+ checks = all_checks_dict()
+ logger.log("Opening " + csvname + " for audit output csv", "P")
+ with open(csvname, 'w', newline='') as csvfile:
+ csvwriter = csv.writer(csvfile, dialect='excel')
+ fields = ["id", "psfaction", "section", "description", "rationale", "conditions"]
+ csvwriter.writerow(fields)
+
+ for checkid in checks:
+ check = checks[checkid]
+ row = [checkid]
+ for field in fields:
+ if field != "id": row.append(check[field])
+ if check["section"] == "Missing": missingfromprofile.append(checkid)
+ if check["psfaction"] == "Not in psfcheck_list": missingfromchecklist.append(checkid)
+ csvwriter.writerow(row)
+ if missingfromprofile != []:
+ mess = "The following checks are in psfcheck_list but not in the ttfchecks.py profile:"
+ for checkid in missingfromprofile: mess += "\n " + checkid
+ logger.log(mess, "E")
+ if missingfromchecklist != []:
+ mess = "The following checks are in the ttfchecks.py profile but not in psfcheck_list:"
+ for checkid in missingfromchecklist: mess += "\n " + checkid
+ logger.log(mess, "E")
+
+ return
+
+def cmd(): execute(None, doit, argspec)
+if __name__ == "__main__": cmd()
diff --git a/lib/silfont/scripts/psfsetassocfeat.py b/lib/silfont/scripts/psfsetassocfeat.py
new file mode 100755
index 0000000..da33bb4
--- /dev/null
+++ b/lib/silfont/scripts/psfsetassocfeat.py
@@ -0,0 +1,54 @@
+#!/usr/bin/env python
+__doc__ = '''Add associate feature info to glif lib based on a csv file
+csv format glyphname,featurename[,featurevalue]'''
+__url__ = 'http://github.com/silnrsi/pysilfont'
+__copyright__ = 'Copyright (c) 2015 SIL International (http://www.sil.org)'
+__license__ = 'Released under the MIT License (http://opensource.org/licenses/MIT)'
+__author__ = 'David Raymond'
+
+from silfont.core import execute
+
+suffix = "_AssocFeat"
+argspec = [
+ ('ifont',{'help': 'Input font file'}, {'type': 'infont'}),
+ ('ofont',{'help': 'Output font file','nargs': '?' }, {'type': 'outfont'}),
+ ('-i','--input',{'help': 'Input csv file'}, {'type': 'incsv', 'def': suffix+'.csv'}),
+ ('-l','--log',{'help': 'Log file'}, {'type': 'outfile', 'def': suffix+'.log'})]
+
+def doit(args) :
+ font = args.ifont
+ incsv = args.input
+ incsv.minfields = 2
+ incsv.maxfields = 3
+ incsv.logger = font.logger
+ glyphlist = list(font.deflayer.keys()) # Identify which glifs have not got an AssocFeat set
+
+ for line in incsv :
+ glyphn = line[0]
+ feature = line[1]
+ value = line[2] if len(line) == 3 else ""
+
+ if glyphn in glyphlist :
+ glyph = font.deflayer[glyphn]
+ if glyph["lib"] is None : glyph.add("lib")
+ glyph["lib"].setval("org.sil.assocFeature","string",feature)
+ if value != "" :
+ glyph["lib"].setval("org.sil.assocFeatureValue","integer",value)
+ else :
+ if "org.sil.assocFeatureValue" in glyph["lib"] : glyph["lib"].remove("org.sil.assocFeatureValue")
+ glyphlist.remove(glyphn)
+ else :
+ font.logger.log("No glyph in font for " + glyphn + " on line " + str(incsv.line_num),"E")
+
+ for glyphn in glyphlist : # Remove any values from remaining glyphs
+ glyph = font.deflayer[glyphn]
+ if glyph["lib"] :
+ if "org.sil.assocFeatureValue" in glyph["lib"] : glyph["lib"].remove("org.sil.assocFeatureValue")
+ if "org.sil.assocFeature" in glyph["lib"] :
+ glyph["lib"].remove("org.sil.assocFeature")
+ font.logger.log("Feature info removed for " + glyphn,"I")
+
+ return font
+
+def cmd() : execute("UFO",doit,argspec)
+if __name__ == "__main__": cmd()
diff --git a/lib/silfont/scripts/psfsetassocuids.py b/lib/silfont/scripts/psfsetassocuids.py
new file mode 100755
index 0000000..e8be848
--- /dev/null
+++ b/lib/silfont/scripts/psfsetassocuids.py
@@ -0,0 +1,51 @@
+#!/usr/bin/env python
+__doc__ = '''Add associate UID info to glif lib based on a csv file
+- Could be one value for variant UIDs and multiple for ligatures'''
+__url__ = 'http://github.com/silnrsi/pysilfont'
+__copyright__ = 'Copyright (c) 2015 SIL International (http://www.sil.org)'
+__license__ = 'Released under the MIT License (http://opensource.org/licenses/MIT)'
+__author__ = 'David Raymond'
+
+from silfont.core import execute
+from xml.etree import ElementTree as ET
+
+suffix = "_AssocUIDs"
+argspec = [
+ ('ifont',{'help': 'Input font file'}, {'type': 'infont'}),
+ ('ofont',{'help': 'Output font file','nargs': '?' }, {'type': 'outfont'}),
+ ('-i','--input',{'help': 'Input csv file'}, {'type': 'incsv', 'def': suffix+'.csv'}),
+ ('-l','--log',{'help': 'Log file'}, {'type': 'outfile', 'def': suffix+'.log'})]
+
+def doit(args) :
+ font = args.ifont
+ incsv = args.input
+ incsv.minfields = 2
+ incsv.logger = font.logger
+ glyphlist = list(font.deflayer.keys()) # Identify which glifs have not got AssocUIDs set
+
+ for line in incsv :
+ glyphn = line.pop(0)
+ if glyphn in glyphlist :
+ glyph = font.deflayer[glyphn]
+ if glyph["lib"] is None : glyph.add("lib")
+ # Create an array element for the UID value(s)
+ array = ET.Element("array")
+ for UID in line:
+ sub = ET.SubElement(array,"string")
+ sub.text = UID
+ glyph["lib"].setelem("org.sil.assocUIDs",array)
+ glyphlist.remove(glyphn)
+ else :
+ font.logger.log("No glyph in font for " + glyphn + " on line " + str(incsv.line_num),"E")
+
+ for glyphn in glyphlist : # Remove any values from remaining glyphs
+ glyph = font.deflayer[glyphn]
+ if glyph["lib"] :
+ if "org.sil.assocUIDs" in glyph["lib"] :
+ glyph["lib"].remove("org.sil.assocUIDs")
+ font.logger.log("UID info removed for " + glyphn,"I")
+
+ return font
+
+def cmd() : execute("UFO",doit,argspec)
+if __name__ == "__main__": cmd()
diff --git a/lib/silfont/scripts/psfsetdummydsig.py b/lib/silfont/scripts/psfsetdummydsig.py
new file mode 100644
index 0000000..02896a0
--- /dev/null
+++ b/lib/silfont/scripts/psfsetdummydsig.py
@@ -0,0 +1,36 @@
+#!/usr/bin/python3
+
+__doc__ = 'Put a dummy DSIG table into a ttf font'
+__url__ = 'http://github.com/silnrsi/pysilfont'
+__copyright__ = 'Copyright (c) 2019 SIL International (http://www.sil.org)'
+__license__ = 'Released under the MIT License (http://opensource.org/licenses/MIT)'
+__author__ = 'Nicolas Spalinger'
+
+from silfont.core import execute
+from fontTools import ttLib
+
+argspec = [
+ ('-i', '--ifont', {'help': 'Input ttf font file'}, {}),
+ ('-o', '--ofont', {'help': 'Output font file'}, {}),
+ ('-l', '--log', {'help': 'Optional log file'}, {'type': 'outfile', 'def': 'dummydsig.log', 'optlog': True})]
+
+
+def doit(args):
+
+ ttf = ttLib.TTFont(args.ifont)
+
+ newDSIG = ttLib.newTable("DSIG")
+ newDSIG.ulVersion = 1
+ newDSIG.usFlag = 0
+ newDSIG.usNumSigs = 0
+ newDSIG.signatureRecords = []
+ ttf.tables["DSIG"] = newDSIG
+
+ args.logger.log('Saving the output ttf file with dummy DSIG table', 'P')
+ ttf.save(args.ofont)
+
+ args.logger.log('Done', 'P')
+
+
+def cmd(): execute("FT", doit, argspec)
+if __name__ == '__main__': cmd()
diff --git a/lib/silfont/scripts/psfsetglyphdata.py b/lib/silfont/scripts/psfsetglyphdata.py
new file mode 100644
index 0000000..9aa2162
--- /dev/null
+++ b/lib/silfont/scripts/psfsetglyphdata.py
@@ -0,0 +1,143 @@
+#!/usr/bin/env python
+__doc__ = '''Update and/or sort glyph_data.csv based on input file(s)'''
+__url__ = 'http://github.com/silnrsi/pysilfont'
+__copyright__ = 'Copyright (c) 2021 SIL International (http://www.sil.org)'
+__license__ = 'Released under the MIT License (http://opensource.org/licenses/MIT)'
+__author__ = 'David Raymond'
+
+from silfont.core import execute
+import csv
+
+argspec = [
+ ('glyphdata', {'help': 'glyph_data csv file to update'}, {'type': 'incsv', 'def': 'glyph_data.csv'}),
+ ('outglyphdata', {'help': 'Alternative output file name', 'nargs': '?'}, {'type': 'filename', 'def': None}),
+ ('-a','--addcsv',{'help': 'Records to add to glyphdata'}, {'type': 'incsv', 'def': None}),
+ ('-d', '--deletions', {'help': 'Records to delete from glyphdata'}, {'type': 'incsv', 'def': None}),
+ ('-s', '--sortheader', {'help': 'Column header to sort by'}, {}),
+ ('--sortalpha', {'help': 'Use with sortheader to sort alphabetically not numerically', 'action': 'store_true', 'default': False}, {}),
+ ('-f', '--force', {'help': 'When adding, if glyph exists, overwrite existing data', 'action': 'store_true', 'default': False}, {}),
+ ('-l','--log',{'help': 'Log file name'}, {'type': 'outfile', 'def': 'setglyphdata.log'}),
+ ]
+
+def doit(args):
+ logger = args.logger
+ gdcsv = args.glyphdata
+ addcsv = args.addcsv
+ dellist = args.deletions
+ sortheader = args.sortheader
+ force = args.force
+
+ # Check arguments are valid
+ if not(addcsv or dellist or sortheader): logger.log("At least one of -a, -d or -s must be specified", "S")
+ if force and not addcsv: logger.log("-f should only be used with -a", "S")
+
+ #
+ # Process the glyph_data.csv
+ #
+
+ # Process the headers line
+ gdheaders = gdcsv.firstline
+ if 'glyph_name' not in gdheaders: logger.log("No glyph_name header in glyph data csv", "S")
+ gdcsv.numfields = len(gdheaders)
+ gdheaders = {header: col for col, header in enumerate(gdheaders)} # Turn into dict of form header: column
+ gdnamecol = gdheaders["glyph_name"]
+ if sortheader and sortheader not in gdheaders:
+ logger.log(sortheader + " not in glyph data headers", "S")
+ next(gdcsv.reader, None) # Skip first line with headers in
+
+ # Read the data in
+ logger.log("Reading in exisitng glyph data file", "P")
+ gddata = {}
+ gdorder = []
+ for line in gdcsv:
+ gname = line[gdnamecol]
+ gddata[gname] = line
+ gdorder.append(gname)
+
+ # Delete records from dellist
+
+ if dellist:
+ logger.log("Deleting items from glyph data based on deletions file", "P")
+ dellist.numfields = 1
+ for line in dellist:
+ gname = line[0]
+ if gname in gdorder:
+ del gddata[gname]
+ gdorder.remove(gname)
+ logger.log(gname + " deleted from glyph data", "I")
+ else:
+ logger.log(gname + "not in glyph data", "W")
+
+ #
+ # Process the addcsv, if present
+ #
+
+ if addcsv:
+ # Check if addcsv has headers; if not use gdheaders
+ addheaders = addcsv.firstline
+ headerssame = True
+ if 'glyph_name' in addheaders:
+ if addheaders != gdcsv.firstline: headerssame = False
+ next(addcsv.reader)
+ else:
+ addheaders = gdheaders
+
+ addcsv.numfields = len(addheaders)
+ addheaders = {header: col for col, header in enumerate(addheaders)} # Turn into dict of form header: column
+ addnamecol = addheaders["glyph_name"]
+
+ logger.log("Adding new records from add csv file", "P")
+ for line in addcsv:
+ gname = line[addnamecol]
+ logtype = "added to"
+ if gname in gdorder:
+ if force: # Remove existing line
+ logtype = "replaced in"
+ del gddata[gname]
+ gdorder.remove(gname)
+ else:
+ logger.log(gname + " already in glyphdata so new data not added", "W")
+ continue
+ logger.log(f'{gname} {logtype} glyphdata', "I")
+
+ if not headerssame: # need to construct new line based on addheaders
+ newline = []
+ for header in gdheaders:
+ val = line[addheaders[header]] if header in addheaders else ""
+ newline.append(val)
+ line = newline
+
+ gddata[gname] = line
+ gdorder.append(gname)
+
+ # Finally sort the data if sortheader supplied
+ def numeric(x):
+ try:
+ numx = float(x)
+ except ValueError:
+ logger.log(f'Non-numeric value "{x}" in sort column; 0 used for sorting', "E")
+ numx = 0
+ return numx
+
+ if sortheader:
+ sortheaderpos = gdheaders[sortheader]
+ if args.sortalpha:
+ gdorder = sorted(gdorder, key=lambda x: gddata[x][sortheaderpos])
+ else:
+ gdorder = sorted(gdorder, key=lambda x: numeric(gddata[x][sortheaderpos]))
+
+ # Now write the data out
+ outfile = args.outglyphdata
+ if not outfile:
+ gdcsv.file.close()
+ outfile = gdcsv.filename
+ logger.log(f'Writing glyph data out to {outfile}', "P")
+ with open(outfile, "w", newline="") as f:
+ writer = csv.writer(f)
+ writer.writerow(gdcsv.firstline)
+ for glyphn in gdorder:
+ writer.writerow(gddata[glyphn])
+
+def cmd() : execute("",doit,argspec)
+if __name__ == "__main__": cmd()
+
diff --git a/lib/silfont/scripts/psfsetglyphorder.py b/lib/silfont/scripts/psfsetglyphorder.py
new file mode 100755
index 0000000..e2448e7
--- /dev/null
+++ b/lib/silfont/scripts/psfsetglyphorder.py
@@ -0,0 +1,91 @@
+#!/usr/bin/env python
+__doc__ = '''Load glyph order data into public.glyphOrder in lib.plist based on based on a text file in one of two formats:
+ - simple text file with one glyph name per line
+ - csv file with headers, using headers "glyph_name" and "sort_final" where the latter contains
+ numeric values used to sort the glyph names by'''
+__url__ = 'http://github.com/silnrsi/pysilfont'
+__copyright__ = 'Copyright (c) 2015 SIL International (http://www.sil.org)'
+__license__ = 'Released under the MIT License (http://opensource.org/licenses/MIT)'
+__author__ = 'David Raymond'
+
+from silfont.core import execute
+from xml.etree import ElementTree as ET
+
+argspec = [
+ ('ifont', {'help': 'Input font file'}, {'type': 'infont'}),
+ ('ofont', {'help': 'Output font file', 'nargs': '?'}, {'type': 'outfont'}),
+ ('--gname', {'help': 'Column header for glyph name', 'default': 'glyph_name'}, {}),
+ ('--header', {'help': 'Column header(s) for sort order', 'default': 'sort_final'}, {}),
+ ('--field', {'help': 'Field(s) in lib.plist to update', 'default': 'public.glyphOrder'}, {}),
+ ('-i', '--input', {'help': 'Input text file, one glyphname per line'}, {'type': 'incsv', 'def': 'glyph_data.csv'}),
+ ('-x', '--removemissing', {'help': 'Remove from list if glyph not in font', 'action': 'store_true', 'default': False}, {}),
+ ('-l', '--log', {'help': 'Log file'}, {'type': 'outfile', 'def': '_gorder.log'})]
+
+
+def doit(args):
+ font = args.ifont
+ incsv = args.input
+ logger = args.logger
+ removemissing = args.removemissing
+
+ fields = args.field.split(",")
+ fieldcount = len(fields)
+ headers = args.header.split(",")
+ if fieldcount != len(headers): logger.log("Must specify same number of values in --field and --header", "S")
+ gname = args.gname
+
+ # Identify file format from first line then create glyphdata[] with glyph name then one column per header
+ glyphdata = {}
+ fl = incsv.firstline
+ if fl is None: logger.log("Empty input file", "S")
+ numfields = len(fl)
+ incsv.numfields = numfields
+ fieldpos = []
+ if numfields > 1: # More than 1 column, so must have headers
+ if gname in fl:
+ glyphnpos = fl.index(gname)
+ else:
+ logger.log("No" + gname + "field in csv headers", "S")
+ for header in headers:
+ if header in fl:
+ pos = fl.index(header)
+ fieldpos.append(pos)
+ else:
+ logger.log('No "' + header + '" heading in csv headers"', "S")
+ next(incsv.reader, None) # Skip first line with headers in
+ for line in incsv:
+ glyphn = line[glyphnpos]
+ if len(glyphn) == 0:
+ continue # No need to include cases where name is blank
+ glyphdata[glyphn]=[]
+ for pos in fieldpos: glyphdata[glyphn].append(float(line[pos]))
+ elif numfields == 1: # Simple text file. Create glyphdata in same format as for csv files
+ for i, line in enumerate(incsv): glyphdata[line[0]]=(i,)
+ else:
+ logger.log("Invalid csv file", "S")
+
+ # Now process the data
+ if "lib" not in font.__dict__: font.addfile("lib")
+ glyphlist = list(font.deflayer.keys())
+
+ for i in range(0,fieldcount):
+ array = ET.Element("array")
+ for glyphn, vals in sorted(glyphdata.items(), key=lambda item: item[1][i]):
+ if glyphn in glyphlist:
+ sub = ET.SubElement(array, "string")
+ sub.text = glyphn
+ else:
+ font.logger.log("No glyph in font for " + glyphn, "I")
+ if not removemissing:
+ sub = ET.SubElement(array, "string")
+ sub.text = glyphn
+ font.lib.setelem(fields[i-1],array)
+
+ for glyphn in sorted(glyphlist): # Remaining glyphs were not in the input file
+ if glyphn not in glyphdata: font.logger.log("No entry in input file for font glyph " + glyphn, "I")
+
+ return font
+
+
+def cmd(): execute("UFO", doit, argspec)
+if __name__ == "__main__": cmd()
diff --git a/lib/silfont/scripts/psfsetkeys.py b/lib/silfont/scripts/psfsetkeys.py
new file mode 100755
index 0000000..2cee4ab
--- /dev/null
+++ b/lib/silfont/scripts/psfsetkeys.py
@@ -0,0 +1,100 @@
+#!/usr/bin/env python
+__doc__ = '''Set keys with given values in a UFO plist file.'''
+__url__ = 'http://github.com/silnrsi/pysilfont'
+__copyright__ = 'Copyright (c) 2018 SIL International (http://www.sil.org)'
+__license__ = 'Released under the MIT License (http://opensource.org/licenses/MIT)'
+__author__ = 'Bobby de Vos'
+
+from silfont.core import execute
+from xml.etree import ElementTree as ET
+import codecs
+
+suffix = "_setkeys"
+argspec = [
+ ('ifont',{'help': 'Input font file'}, {'type': 'infont'}),
+ ('ofont',{'help': 'Output font file','nargs': '?' }, {'type': 'outfont'}),
+ ('--plist',{'help': 'Select plist to modify'}, {'def': 'fontinfo'}),
+ ('-i','--input',{'help': 'Input csv file'}, {'type': 'incsv', 'def': None}),
+ ('-k','--key',{'help': 'Name of key to set'},{}),
+ ('-v','--value',{'help': 'Value to set key to'},{}),
+ ('--file',{'help': 'Use contents of file to set key to'},{}),
+ ('--filepart',{'help': 'Use contents of part of the file to set key to'},{}),
+ ('-l','--log',{'help': 'Log file'}, {'type': 'outfile', 'def': suffix+'.log'})
+ ]
+
+def doit(args) :
+
+ font = args.ifont
+ logger = args.logger
+ plist = args.plist
+ if plist is None: plist = "fontinfo"
+ if plist not in ("lib", "fontinfo"):
+ logger.log("--plist must be either fontinfo or lib", "S")
+ else:
+ if plist not in font.__dict__: font.addfile(plist)
+ logger.log("Adding keys to " + plist, "I")
+ font_plist = getattr(font, plist)
+
+ # Ensure enough options were specified
+ value = args.value or args.file or args.filepart
+ if args.key and not value:
+ logger.log('Value needs to be specified', "S")
+ if not args.key and value:
+ logger.log('Key needs to be specified', "S")
+
+ # Use a one line string to set the key
+ if args.key and args.value:
+ set_key_value(font_plist, args.key, args.value)
+
+ # Use entire file contents to set the key
+ if args.key and args.file:
+ fh = codecs.open(args.file, 'r', 'utf-8')
+ contents = ''.join(fh.readlines())
+ set_key_value(font_plist, args.key, contents)
+ fh.close()
+
+ # Use some of the file contents to set the key
+ if args.key and args.filepart:
+ fh = codecs.open(args.filepart, 'r', 'utf-8')
+ lines = list()
+ for line in fh:
+ if line == '\n':
+ break
+ lines.append(line)
+ contents = ''.join(lines)
+ set_key_value(font_plist, args.key, contents)
+ fh.close()
+
+ # Set many keys
+ if args.input:
+ incsv = args.input
+ incsv.numfields = 2
+
+ for line in incsv:
+ key = line[0]
+ value = line[1]
+ set_key_value(font_plist, key, value)
+
+ return font
+
+def set_key_value(font_plist, key, value):
+ """Set key to value in font."""
+
+ # Currently setval() only works for integer, real or string.
+ # For other items you need to construct an elementtree element and use setelem()
+
+ if value == 'true' or value == 'false':
+ # Handle boolean values
+ font_plist.setelem(key, ET.Element(value))
+ else:
+ try:
+ # Handle integers values
+ number = int(value)
+ font_plist.setval(key, 'integer', number)
+ except ValueError:
+ # Handle string (including multi-line strings) values
+ font_plist.setval(key, 'string', value)
+ font_plist.font.logger.log(key + " added, value: " + str(value), "I")
+
+def cmd() : execute("UFO",doit, argspec)
+if __name__ == "__main__": cmd()
diff --git a/lib/silfont/scripts/psfsetmarkcolors.py b/lib/silfont/scripts/psfsetmarkcolors.py
new file mode 100755
index 0000000..c436f4c
--- /dev/null
+++ b/lib/silfont/scripts/psfsetmarkcolors.py
@@ -0,0 +1,106 @@
+#!/usr/bin/env python
+__doc__ = ''' Sets the cell mark color of glyphs in a UFO
+- Input file is a list of glyph names (or unicode values if -u is specified
+- Color can be numeric or certain names, eg "0.85,0.26,0.06,1" or "g_red"
+'''
+__url__ = 'http://github.com/silnrsi/pysilfont'
+__copyright__ = 'Copyright (c) 2019 SIL International (http://www.sil.org)'
+__license__ = 'Released under the MIT License (http://opensource.org/licenses/MIT)'
+__author__ = 'David Raymond'
+
+from silfont.core import execute, splitfn
+from silfont.util import parsecolors
+import io
+
+argspec = [
+ ('ifont',{'help': 'Input font file'}, {'type': 'infont'}),
+ ('ofont',{'help': 'Output font file','nargs': '?' }, {'type': 'outfont'}),
+ ('-i','--input',{'help': 'input file'}, {'type': 'filename', 'def': 'nodefault.txt'}),
+ ('-c','--color',{'help': 'Color to set'},{}),
+ ('-u','--unicodes',{'help': 'Use unicode values in input file', 'action': 'store_true', 'default': False},{}),
+ ('-x','--deletecolors',{'help': 'Delete existing mark colors', 'action': 'store_true', 'default': False},{}),
+ ('-l','--log',{'help': 'Log file'}, {'type': 'outfile', 'def': '_setmarkcolors.log'})]
+
+def doit(args) :
+ font = args.ifont
+ logger = args.logger
+ infile = args.input
+ color = args.color
+ unicodes = args.unicodes
+ deletecolors = args.deletecolors
+
+ if not ((color is not None) ^ deletecolors): logger.log("Must specify one and only one of -c and -x", "S")
+
+ if color is not None:
+ (color, colorname, logcolor, splitcolor) = parsecolors(color, single=True)
+ if color is None: logger.log(logcolor, "S") # If color not parsed, parsecolors() puts error in logcolor
+
+ # Process the input file. It needs to be done in script rather than by execute() since, if -x is used, there might not be one
+ (ibase, iname, iext) = splitfn(infile)
+ if iname == "nodefault": # Indicates no file was specified
+ infile = None
+ if (color is not None) or unicodes or (not deletecolors): logger.log("If no input file, -x must be used and neither -c or -u can be used", "S")
+ else:
+ logger.log('Opening file for input: ' + infile, "P")
+ try:
+ infile = io.open(infile, "r", encoding="utf-8")
+ except Exception as e:
+ logger.log("Failed to open file: " + str(e), "S")
+
+ # Create list of glyphs to process
+ if deletecolors and infile is None: # Need to delete colors from all glyphs
+ glyphlist = sorted(font.deflayer.keys())
+ else:
+ inlist = [x.strip() for x in infile.readlines()]
+ glyphlist = []
+ if unicodes:
+ unicodesfound = []
+ for glyphn in sorted(font.deflayer.keys()):
+ glyph = font.deflayer[glyphn]
+ for unicode in [x.hex for x in glyph["unicode"]]:
+ if unicode in inlist:
+ glyphlist.append(glyphn)
+ unicodesfound.append(unicode)
+ for unicode in inlist:
+ if unicode not in unicodesfound: logger.log("No gylphs with unicode '" + unicode + "' in the font", "I")
+ else:
+ for glyphn in inlist:
+ if glyphn in font.deflayer:
+ glyphlist.append(glyphn)
+ else:
+ logger.log(glyphn + " is not in the font", "I")
+
+ changecnt = 0
+ for glyphn in glyphlist:
+ glyph = font.deflayer[glyphn]
+ oldcolor = None
+ lib = glyph["lib"]
+ if lib:
+ if "public.markColor" in lib: oldcolor = str(glyph["lib"].getval("public.markColor"))
+ if oldcolor != color:
+ if oldcolor is not None:
+ (temp, oldname, oldlogcolor, splitcolor) = parsecolors(oldcolor, single=True)
+ if temp is None: oldlogcolor = oldcolor # Failed to parse old color, so just report what is was
+
+ changecnt += 1
+ if deletecolors:
+ glyph["lib"].remove("public.markColor")
+ logger.log(glyphn + ": " + oldlogcolor + " removed", "I")
+ else:
+ if oldcolor is None:
+ if lib is None: glyph.add("lib")
+ glyph["lib"].setval("public.markColor","string",color)
+ logger.log(glyphn+ ": " + logcolor + " added", "I")
+ else:
+ glyph["lib"].setval("public.markColor", "string", color)
+ logger.log(glyphn + ": " + oldlogcolor + " changed to " + logcolor, "I")
+
+ if deletecolors:
+ logger.log(str(changecnt) + " colors removed", "P")
+ else:
+ logger.log(str(changecnt) + " colors changed or added", "P")
+
+ return font
+
+def cmd() : execute("UFO",doit,argspec)
+if __name__ == "__main__": cmd()
diff --git a/lib/silfont/scripts/psfsetpsnames.py b/lib/silfont/scripts/psfsetpsnames.py
new file mode 100755
index 0000000..55528c7
--- /dev/null
+++ b/lib/silfont/scripts/psfsetpsnames.py
@@ -0,0 +1,86 @@
+#!/usr/bin/env python
+__doc__ = '''Add public.postscriptNames to lib.plist based on a csv file in one of two formats:
+ - simple glyphname, postscriptname with no headers
+ - with headers, where the headers for glyph name and postscript name "glyph_name" and "ps_name"'''
+__url__ = 'http://github.com/silnrsi/pysilfont'
+__copyright__ = 'Copyright (c) 2015 SIL International (http://www.sil.org)'
+__license__ = 'Released under the MIT License (http://opensource.org/licenses/MIT)'
+__author__ = 'David Raymond'
+
+from silfont.core import execute
+from xml.etree import ElementTree as ET
+
+argspec = [
+ ('ifont', {'help': 'Input font file'}, {'type': 'infont'}),
+ ('ofont', {'help': 'Output font file', 'nargs': '?'}, {'type': 'outfont'}),
+ ('--gname', {'help': 'Column header for glyph name', 'default': 'glyph_name'}, {}),
+ ('-i', '--input', {'help': 'Input csv file'}, {'type': 'incsv', 'def': 'glyph_data.csv'}),
+ ('-x', '--removemissing', {'help': 'Remove from list if glyph not in font', 'action': 'store_true', 'default': False}, {}),
+ ('-l', '--log', {'help': 'Log file'}, {'type': 'outfile', 'def': 'setpsnames.log'})]
+
+
+def doit(args):
+ font = args.ifont
+ logger = args.logger
+ incsv = args.input
+ gname = args.gname
+ removemissing = args.removemissing
+
+ glyphlist = list(font.deflayer.keys()) # List to check every glyph has a psname supplied
+
+ # Identify file format from first line
+ fl = incsv.firstline
+ if fl is None: logger.log("Empty input file", "S")
+ numfields = len(fl)
+ incsv.numfields = numfields
+ if numfields == 2:
+ glyphnpos = 0
+ psnamepos = 1 # Default for plain csv
+ elif numfields > 2: # More than 2 columns, so must have standard headers
+ if gname in fl:
+ glyphnpos = fl.index(gname)
+ else:
+ logger.log("No " + gname + " field in csv headers", "S")
+ if "ps_name" in fl:
+ psnamepos = fl.index("ps_name")
+ else:
+ logger.log("No ps_name field in csv headers", "S")
+ next(incsv.reader, None) # Skip first line with headers in
+ else:
+ logger.log("Invalid csv file", "S")
+
+ # Now process the data
+ dict = ET.Element("dict")
+ for line in incsv:
+ glyphn = line[glyphnpos]
+ psname = line[psnamepos]
+ if len(psname) == 0 or glyphn == psname:
+ continue # No need to include cases where production name is blank or same as working name
+ # Check if in font
+ infont = False
+ if glyphn in glyphlist:
+ glyphlist.remove(glyphn)
+ infont = True
+ else:
+ if not removemissing: logger.log("No glyph in font for " + glyphn + " on line " + str(incsv.line_num), "I")
+ if not removemissing or infont:
+ # Add to dict
+ sub = ET.SubElement(dict, "key")
+ sub.text = glyphn
+ sub = ET.SubElement(dict, "string")
+ sub.text = psname
+ # Add to lib.plist
+ if len(dict) > 0:
+ if "lib" not in font.__dict__: font.addfile("lib")
+ font.lib.setelem("public.postscriptNames", dict)
+ else:
+ if "lib" in font.__dict__ and "public.postscriptNames" in font.lib:
+ font.lib.remove("public.postscriptNames")
+
+ for glyphn in sorted(glyphlist): logger.log("No PS name in input file for font glyph " + glyphn, "I")
+
+ return font
+
+
+def cmd(): execute("UFO", doit, argspec)
+if __name__ == "__main__": cmd()
diff --git a/lib/silfont/scripts/psfsetunicodes.py b/lib/silfont/scripts/psfsetunicodes.py
new file mode 100755
index 0000000..aac1778
--- /dev/null
+++ b/lib/silfont/scripts/psfsetunicodes.py
@@ -0,0 +1,79 @@
+#!/usr/bin/env python
+__doc__ = '''Set the unicodes of glyphs in a font based on an external csv file.
+- csv format glyphname,unicode, [unicode2, [,unicode3]]'''
+__url__ = 'http://github.com/silnrsi/pysilfont'
+__copyright__ = 'Copyright (c) 2016 SIL International (http://www.sil.org)'
+__license__ = 'Released under the MIT License (http://opensource.org/licenses/MIT)'
+__author__ = 'Victor Gaultney, based on UFOsetPSnames.py'
+
+from silfont.core import execute
+
+suffix = "_setunicodes"
+argspec = [
+ ('ifont',{'help': 'Input font file'}, {'type': 'infont'}),
+ ('ofont',{'help': 'Output font file','nargs': '?' }, {'type': 'outfont'}),
+ ('-i','--input',{'help': 'Input csv file'}, {'type': 'incsv', 'def': suffix+'.csv'}),
+ ('-l','--log',{'help': 'Log file'}, {'type': 'outfile', 'def': suffix+'.log'})]
+
+def doit(args) :
+ font = args.ifont
+ incsv = args.input
+ logger = args.logger
+ # Allow for up to 3 unicode values per glyph
+ incsv.minfields = 2
+ incsv.maxfields = 4
+
+ # List of glyphnames actually in the font:
+ glyphlist = list(font.deflayer.keys())
+
+ # Create mapping to find glyph name from decimal usv:
+ dusv2gname = {int(unicode.hex, 16): gname for gname in glyphlist for unicode in font.deflayer[gname]['unicode']}
+
+ # Remember what glyphnames we've processed:
+ processed = set()
+
+ for line in incsv :
+ glyphn = line[0]
+ # Allow for up to 3 unicode values
+ dusvs = []
+ for col in range(1,len(line)):
+ try:
+ dusv = int(line[col],16) # sanity check and convert to decimal
+ except ValueError:
+ logger.log("Invalid USV '%s'; line %d ignored." % (line[col], incsv.line_num), "W")
+ continue
+ dusvs.append(dusv)
+
+ if glyphn in glyphlist :
+
+ if glyphn in processed:
+ logger.log(f"Glyph {glyphn} in csv more than once; line {incsv.line_num} ignored.", "W")
+
+ glyph = font.deflayer[glyphn]
+ # Remove existing unicodes
+ for unicode in list(glyph["unicode"]):
+ del dusv2gname[int(unicode.hex, 16)]
+ glyph.remove("unicode",index = 0)
+
+ # Add the new unicode(s) in
+ for dusv in dusvs:
+ # See if any glyph already encodes this unicode value:
+ if dusv in dusv2gname:
+ # Remove this encoding from the other glyph:
+ oglyph = font.deflayer[dusv2gname[dusv]]
+ for unicode in oglyph["unicode"]:
+ if int(unicode.hex,16) == dusv:
+ oglyph.remove("unicode", object=unicode)
+ break
+ # Add this unicode value and update dusv2gname
+ dusv2gname[dusv] = glyphn
+ glyph.add("unicode",{"hex": ("%04X" % dusv)}) # Standardize to 4 (or more) digits and caps
+ # Record that we processed this glyphname,
+ processed.add(glyphn)
+ else :
+ logger.log("Glyph '%s' not in font; line %d ignored." % (glyphn, incsv.line_num), "I")
+
+ return font
+
+def cmd() : execute("UFO",doit,argspec)
+if __name__ == "__main__": cmd()
diff --git a/lib/silfont/scripts/psfsetversion.py b/lib/silfont/scripts/psfsetversion.py
new file mode 100755
index 0000000..764271e
--- /dev/null
+++ b/lib/silfont/scripts/psfsetversion.py
@@ -0,0 +1,85 @@
+#!/usr/bin/env python
+__doc__ = '''Update the various font version fields'''
+__url__ = 'http://github.com/silnrsi/pysilfont'
+__copyright__ = 'Copyright (c) 2017 SIL International (http://www.sil.org)'
+__license__ = 'Released under the MIT License (http://opensource.org/licenses/MIT)'
+__author__ = 'David Raymond'
+
+from silfont.core import execute
+import silfont.ufo as UFO
+import re
+
+argspec = [
+ ('font',{'help': 'From font file'}, {'type': 'infont'}),
+ ('newversion',{'help': 'Version string or increment', 'nargs': '?'}, {}),
+ ('-l','--log',{'help': 'Log file'}, {'type': 'outfile', 'def': '_setversion.log'})
+ ]
+
+otnvre = re.compile('Version (\d)\.(\d\d\d)( .+)?$')
+
+def doit(args) :
+
+ font = args.font
+ logger = args.logger
+ newversion = args.newversion
+
+
+ fi = font.fontinfo
+ otelem = fi["openTypeNameVersion"][1] if "openTypeNameVersion" in fi else None
+ majelem = fi["versionMajor"][1] if "versionMajor" in fi else None
+ minelem = fi["versionMinor"][1] if "versionMinor" in fi else None
+ otnv = None if otelem is None else otelem.text
+ vmaj = None if majelem is None else majelem.text
+ vmin = None if minelem is None else minelem.text
+
+ if otnv is None or vmaj is None or vmin is None : logger.log("At least one of openTypeNameVersion, versionMajor or versionMinor missing from fontinfo.plist", "S")
+
+ if newversion is None:
+ if otnvre.match(otnv) is None:
+ logger.log("Current version is '" + otnv + "' which is non-standard", "E")
+ else :
+ logger.log("Current version is '" + otnv + "'", "P")
+ (otmaj,otmin,otextrainfo) = parseotnv(otnv)
+ if (otmaj, int(otmin)) != (vmaj,int(vmin)) :
+ logger.log("openTypeNameVersion values don't match versionMajor (" + vmaj + ") and versionMinor (" + vmin + ")", "E")
+ else:
+ if newversion[0:1] == "+" :
+ if otnvre.match(otnv) is None:
+ logger.log("Current openTypeNameVersion is non-standard so can't be incremented: " + otnv , "S")
+ else :
+ (otmaj,otmin,otextrainfo) = parseotnv(otnv)
+ if (otmaj, int(otmin)) != (vmaj,int(vmin)) :
+ logger.log("openTypeNameVersion (" + otnv + ") doesn't match versionMajor (" + vmaj + ") and versionMinor (" + vmin + ")", "S")
+ # Process increment to versionMinor. Note vmin is treated as 3 digit mpp where m and pp are minor and patch versions respectively
+ increment = newversion[1:]
+ if increment not in ("1", "0.001", ".001", "0.1", ".1") :
+ logger.log("Invalid increment value - must be one of 1, 0.001, .001, 0.1 or .1", "S")
+ increment = 100 if increment in ("0.1", ".1") else 1
+ if (increment == 100 and vmin[0:1] == "9") or (increment == 1 and vmin[1:2] == "99") :
+ logger.log("Version already at maximum so can't be incremented", "S")
+ otmin = str(int(otmin) + increment).zfill(3)
+ else :
+ newversion = "Version " + newversion
+ if otnvre.match(newversion) is None:
+ logger.log("newversion format invalid - should be 'M.mpp' or 'M.mpp extrainfo'", "S")
+ else :
+ (otmaj,otmin,otextrainfo) = parseotnv(newversion)
+ newotnv = "Version " + otmaj + "." + otmin + otextrainfo # Extrainfo already as leading space
+ logger.log("Updating version from '" + otnv + "' to '" + newotnv + "'","P")
+
+ # Update and write to disk
+ otelem.text = newotnv
+ majelem.text = otmaj
+ minelem.text = otmin
+ UFO.writeXMLobject(fi,font.outparams,font.ufodir, "fontinfo.plist" , True, fobject = True)
+
+ return
+
+def parseotnv(string) : # Returns maj, min and extrainfo
+ m = otnvre.match(string) # Assumes string has already been tested for a match
+ extrainfo = "" if m.group(3) is None else m.group(3)
+ return (m.group(1), m.group(2), extrainfo)
+
+
+def cmd() : execute("UFO",doit, argspec)
+if __name__ == "__main__": cmd()
diff --git a/lib/silfont/scripts/psfshownames.py b/lib/silfont/scripts/psfshownames.py
new file mode 100755
index 0000000..191e0f8
--- /dev/null
+++ b/lib/silfont/scripts/psfshownames.py
@@ -0,0 +1,235 @@
+#!/usr/bin/python3
+__doc__ = 'Display name fields and other bits for linking fonts into families'
+__url__ = 'http://github.com/silnrsi/pysilfont'
+__copyright__ = 'Copyright (c) 2021 SIL International (http://www.sil.org)'
+__license__ = 'Released under the MIT License (http://opensource.org/licenses/MIT)'
+__author__ = 'Bobby de Vos'
+
+from silfont.core import execute, splitfn
+from fontTools.ttLib import TTFont
+import glob
+from operator import attrgetter, methodcaller
+import tabulate
+
+WINDOWS_ENGLISH_IDS = 3, 1, 0x409
+
+FAMILY_RELATED_IDS = {
+ 1: 'Family',
+ 2: 'Subfamily',
+ 4: 'Full name',
+ 6: 'PostScript name',
+ 16: 'Typographic/Preferred family',
+ 17: 'Typographic/Preferred subfamily',
+ 21: 'WWS family',
+ 22: 'WWS subfamily',
+ 25: 'Variations PostScript Name Prefix',
+}
+
+
+class FontInfo:
+ def __init__(self):
+ self.filename = ''
+ self.name_table = dict()
+ self.weight_class = 0
+ self.regular = ''
+ self.bold = ''
+ self.italic = ''
+ self.width = ''
+ self.width_name = ''
+ self.width_class = 0
+ self.wws = ''
+
+ def sort_fullname(self):
+ return self.name_table[4]
+
+
+argspec = [
+ ('font', {'help': 'ttf font(s) to run report against; wildcards allowed', 'nargs': "+"}, {'type': 'filename'}),
+ ('-b', '--bits', {'help': 'Show bits', 'action': 'store_true'}, {}),
+ ('-m', '--multiline', {'help': 'Output multi-line key:values instead of a table', 'action': 'store_true'}, {}),
+]
+
+
+def doit(args):
+ logger = args.logger
+
+ font_infos = []
+ for pattern in args.font:
+ for fullpath in glob.glob(pattern):
+ logger.log(f'Processing {fullpath}', 'P')
+ try:
+ font = TTFont(fullpath)
+ except Exception as e:
+ logger.log(f'Error opening {fullpath}: {e}', 'E')
+ break
+
+ font_info = FontInfo()
+ font_info.filename = fullpath
+ get_names(font, font_info)
+ get_bits(font, font_info)
+ font_infos.append(font_info)
+
+ if not font_infos:
+ logger.log("No files match the filespec provided for fonts: " + str(args.fonts), "S")
+
+ font_infos.sort(key=methodcaller('sort_fullname'))
+ font_infos.sort(key=attrgetter('width_class'), reverse=True)
+ font_infos.sort(key=attrgetter('weight_class'))
+
+ rows = list()
+ if args.multiline:
+ # Multi-line mode
+ for font_info in font_infos:
+ for line in multiline_names(font_info):
+ rows.append(line)
+ if args.bits:
+ for line in multiline_bits(font_info):
+ rows.append(line)
+ align = ['left', 'right']
+ if len(font_infos) == 1:
+ del align[0]
+ for row in rows:
+ del row[0]
+ output = tabulate.tabulate(rows, tablefmt='plain', colalign=align)
+ output = output.replace(': ', ':')
+ output = output.replace('#', '')
+ else:
+ # Table mode
+
+ # Record information for headers
+ headers = table_headers(args.bits)
+
+ # Record information for each instance.
+ for font_info in font_infos:
+ record = table_records(font_info, args.bits)
+ rows.append(record)
+
+ # Not all fonts in a family with have the same name ids present,
+ # for instance 16: Typographic/Preferred family is only needed in
+ # non-RIBBI familes, and even then only for the non-RIBBI instances.
+ # Also, not all the bit fields are present in each instance.
+ # Therefore, columns with no data in any instance are removed.
+ indices = list(range(len(headers)))
+ indices.reverse()
+ for index in indices:
+ empty = True
+ for row in rows:
+ data = row[index]
+ if data:
+ empty = False
+ if empty:
+ for row in rows + [headers]:
+ del row[index]
+
+ # Format 'pipe' is nicer for GitHub, but is wider on a command line
+ output = tabulate.tabulate(rows, headers, tablefmt='simple')
+
+ # Print output from either mode
+ if args.quiet:
+ print(output)
+ else:
+ logger.log('The following family-related values were found in the name, head, and OS/2 tables\n' + output, 'P')
+
+
+def get_names(font, font_info):
+ table = font['name']
+ (platform_id, encoding_id, language_id) = WINDOWS_ENGLISH_IDS
+
+ for name_id in FAMILY_RELATED_IDS:
+ record = table.getName(
+ nameID=name_id,
+ platformID=platform_id,
+ platEncID=encoding_id,
+ langID=language_id
+ )
+ if record:
+ font_info.name_table[name_id] = str(record)
+
+
+def get_bits(font, font_info):
+ os2 = font['OS/2']
+ head = font['head']
+ font_info.weight_class = os2.usWeightClass
+ font_info.regular = bit2code(os2.fsSelection, 6, 'W-')
+ font_info.bold = bit2code(os2.fsSelection, 5, 'W')
+ font_info.bold += bit2code(head.macStyle, 0, 'M')
+ font_info.italic = bit2code(os2.fsSelection, 0, 'W')
+ font_info.italic += bit2code(head.macStyle, 1, 'M')
+ font_info.width_class = os2.usWidthClass
+ font_info.width = str(font_info.width_class)
+ if font_info.width_class == 5:
+ font_info.width_name = 'Width-Normal'
+ if font_info.width_class < 5:
+ font_info.width_name = 'Width-Condensed'
+ font_info.width += bit2code(head.macStyle, 5, 'M')
+ if font_info.width_class > 5:
+ font_info.width_name = 'Width-Extended'
+ font_info.width += bit2code(head.macStyle, 6, 'M')
+ font_info.wws = bit2code(os2.fsSelection, 8, '8')
+
+
+def bit2code(bit_field, bit, code_letter):
+ code = ''
+ if bit_field & 1 << bit:
+ code = code_letter
+ return code
+
+
+def multiline_names(font_info):
+ for name_id in sorted(font_info.name_table):
+ line = [font_info.filename + ':',
+ str(name_id) + ':',
+ FAMILY_RELATED_IDS[name_id] + ':',
+ font_info.name_table[name_id]
+ ]
+ yield line
+
+
+def multiline_bits(font_info):
+ labels = ('usWeightClass', 'Regular', 'Bold', 'Italic', font_info.width_name, 'WWS')
+ values = (font_info.weight_class, font_info.regular, font_info.bold, font_info.italic, font_info.width, font_info.wws)
+ for label, value in zip(labels, values):
+ if not value:
+ continue
+ line = [font_info.filename + ':',
+ '#',
+ str(label) + ':',
+ value
+ ]
+ yield line
+
+
+def table_headers(bits):
+ headers = ['filename']
+ for name_id in sorted(FAMILY_RELATED_IDS):
+ name_id_key = FAMILY_RELATED_IDS[name_id]
+ header = f'{name_id}: {name_id_key}'
+ if len(header) > 20:
+ header = header.replace(' ', '\n')
+ header = header.replace('/', '\n')
+ headers.append(header)
+ if bits:
+ headers.extend(['wght', 'R', 'B', 'I', 'wdth', 'WWS'])
+ return headers
+
+
+def table_records(font_info, bits):
+ record = [font_info.filename]
+ for name_id in sorted(FAMILY_RELATED_IDS):
+ name_id_value = font_info.name_table.get(name_id, '')
+ record.append(name_id_value)
+ if bits:
+ record.append(font_info.weight_class)
+ record.append(font_info.regular)
+ record.append(font_info.bold)
+ record.append(font_info.italic)
+ record.append(font_info.width)
+ record.append(font_info.wws)
+ return record
+
+
+def cmd(): execute('FT', doit, argspec)
+
+
+if __name__ == '__main__':
+ cmd()
diff --git a/lib/silfont/scripts/psfsubset.py b/lib/silfont/scripts/psfsubset.py
new file mode 100644
index 0000000..b207c3b
--- /dev/null
+++ b/lib/silfont/scripts/psfsubset.py
@@ -0,0 +1,112 @@
+#!/usr/bin/env python
+__doc__ = '''Subset an existing UFO based on a csv or text list of glyph names or USVs to keep.
+'''
+__url__ = 'http://github.com/silnrsi/pysilfont'
+__copyright__ = 'Copyright (c) 2018 SIL International (http://www.sil.org)'
+__license__ = 'Released under the MIT License (http://opensource.org/licenses/MIT)'
+__author__ = 'Bob Hallissy'
+
+from silfont.core import execute
+from xml.etree import ElementTree as ET
+import re
+
+argspec = [
+ ('ifont',{'help': 'Input font file'}, {'type': 'infont'}),
+ ('ofont',{'help': 'Output font file','nargs': '?' }, {'type': 'outfont'}),
+ ('-i','--input',{'help': 'Input csv file'}, {'type': 'incsv'}),
+ ('--header', {'help': 'Column header for glyphlist', 'default': 'glyph_name'}, {}),
+ ('-l','--log',{'help': 'Log file'}, {'type': 'outfile', 'def': '_subset.log'})]
+
+def doit(args) :
+ font = args.ifont
+ incsv = args.input
+ logger = args.logger
+ deflayer = font.deflayer
+
+ # Create mappings to find glyph name from decimal usv:
+ dusv2gname = {int(ucode.hex, 16): gname for gname in deflayer for ucode in deflayer[gname]['unicode']}
+
+ # check for headers in the csv
+ fl = incsv.firstline
+ if fl is None: logger.log("Empty input file", "S")
+ numfields = len(fl)
+ if numfields == 1 and args.header not in fl:
+ dataCol = 0 # Default for plain csv
+ elif numfields >= 1: # Must have headers
+ try:
+ dataCol = fl.index(args.header)
+ except ValueError as e:
+ logger.log('Missing csv input field: ' + e.message, 'S')
+ except Exception as e:
+ logger.log('Error reading csv input field: ' + e.message, 'S')
+ next(incsv.reader, None) # Skip first line with headers in
+ else:
+ logger.log("Invalid csv file", "S")
+
+ # From the csv, assemble a list of glyphs to process:
+ toProcess = set()
+ usvRE = re.compile('[0-9a-f]{4,6}',re.IGNORECASE) # matches 4-6 digit hex
+ for r in incsv:
+ gname = r[dataCol].strip()
+ if usvRE.match(gname):
+ # data is USV, not glyph name
+ dusv = int(gname,16)
+ if dusv in dusv2gname:
+ toProcess.add(dusv2gname[dusv])
+ continue
+ # The USV wasn't in the font... try it as a glyph name
+ if gname not in deflayer:
+ logger.log("Glyph '%s' not in font; line %d ignored" % (gname, incsv.line_num), 'W')
+ continue
+ toProcess.add(gname)
+
+ # Generate a complete list of glyphs to keep:
+ toKeep = set()
+ while len(toProcess):
+ gname = toProcess.pop() # retrieves a random item from the set
+ if gname in toKeep:
+ continue # Already processed this one
+ toKeep.add(gname)
+
+ # If it has any components we haven't already processed, add them to the toProcess list
+ for component in deflayer[gname].etree.findall('./outline/component[@base]'):
+ cname = component.get('base')
+ if cname not in toKeep:
+ toProcess.add(cname)
+
+ # Generate a complete list of glyphs to delete:
+ toDelete = set(deflayer).difference(toKeep)
+
+ # Remove any glyphs not in the toKeep set
+ for gname in toDelete:
+ logger.log("Deleting " + gname, "V")
+ deflayer.delGlyph(gname)
+ assert len(deflayer) == len(toKeep), "len(deflayer) != len(toKeep)"
+ logger.log("Retained %d glyphs, deleted %d glyphs." % (len(toKeep), len(toDelete)), "P")
+
+ # Clean up and rebuild sort orders
+ libexists = True if "lib" in font.__dict__ else False
+ for orderName in ('public.glyphOrder', 'com.schriftgestaltung.glyphOrder'):
+ if libexists and orderName in font.lib:
+ glyphOrder = font.lib.getval(orderName) # This is an array
+ array = ET.Element("array")
+ for gname in glyphOrder:
+ if gname in toKeep:
+ ET.SubElement(array, "string").text = gname
+ font.lib.setelem(orderName, array)
+
+ # Clean up and rebuild psnames
+ if libexists and 'public.postscriptNames' in font.lib:
+ psnames = font.lib.getval('public.postscriptNames') # This is a dict keyed by glyphnames
+ dict = ET.Element("dict")
+ for gname in psnames:
+ if gname in toKeep:
+ ET.SubElement(dict, "key").text = gname
+ ET.SubElement(dict, "string").text = psnames[gname]
+ font.lib.setelem("public.postscriptNames", dict)
+
+ return font
+
+def cmd() : execute("UFO",doit,argspec)
+
+if __name__ == "__main__": cmd()
diff --git a/lib/silfont/scripts/psfsyncmasters.py b/lib/silfont/scripts/psfsyncmasters.py
new file mode 100644
index 0000000..4302d50
--- /dev/null
+++ b/lib/silfont/scripts/psfsyncmasters.py
@@ -0,0 +1,293 @@
+#!/usr/bin/env python
+__doc__ = '''Sync metadata across a family of fonts based on designspace files'''
+__url__ = 'http://github.com/silnrsi/pysilfont'
+__copyright__ = 'Copyright (c) 2018 SIL International (http://www.sil.org)'
+__license__ = 'Released under the MIT License (http://opensource.org/licenses/MIT)'
+__author__ = 'David Raymond'
+
+from silfont.core import execute
+import silfont.ufo as UFO
+import silfont.etutil as ETU
+import os, datetime
+import fontTools.designspaceLib as DSD
+from xml.etree import ElementTree as ET
+
+argspec = [
+ ('primaryds', {'help': 'Primary design space file'}, {'type': 'filename'}),
+ ('secondds', {'help': 'Second design space file', 'nargs': '?', 'default': None}, {'type': 'filename', 'def': None}),
+ ('--complex', {'help': 'Indicates complex set of fonts rather than RIBBI', 'action': 'store_true', 'default': False},{}),
+ ('-l','--log', {'help': 'Log file'}, {'type': 'outfile', 'def': '_sync.log'}),
+ ('-n','--new', {'help': 'append "_new" to file names', 'action': 'store_true', 'default': False},{}) # For testing/debugging
+ ]
+
+def doit(args) :
+ ficopyreq = ("ascender", "copyright", "descender", "familyName", "openTypeHheaAscender",
+ "openTypeHheaDescender", "openTypeHheaLineGap", "openTypeNameDescription", "openTypeNameDesigner",
+ "openTypeNameDesignerURL", "openTypeNameLicense", "openTypeNameLicenseURL",
+ "openTypeNameManufacturer", "openTypeNameManufacturerURL", "openTypeNamePreferredFamilyName",
+ "openTypeNameVersion", "openTypeOS2CodePageRanges", "openTypeOS2TypoAscender",
+ "openTypeOS2TypoDescender", "openTypeOS2TypoLineGap", "openTypeOS2UnicodeRanges",
+ "openTypeOS2VendorID", "openTypeOS2WinAscent", "openTypeOS2WinDescent", "versionMajor",
+ "versionMinor")
+ ficopyopt = ("openTypeNameSampleText", "postscriptFamilyBlues", "postscriptFamilyOtherBlues", "trademark",
+ "woffMetadataCredits", "woffMetadataDescription")
+ fispecial = ("italicAngle", "openTypeOS2WeightClass", "openTypeNamePreferredSubfamilyName", "openTypeNameUniqueID",
+ "styleMapFamilyName", "styleMapStyleName", "styleName", "unitsPerEm")
+ fiall = sorted(set(ficopyreq) | set(ficopyopt) | set(fispecial))
+ required = ficopyreq + ("openTypeOS2WeightClass", "styleName", "unitsPerEm")
+ libcopy = ("com.schriftgestaltung.glyphOrder", "public.glyphOrder", "public.postscriptNames")
+ logger = args.logger
+ complex = args.complex
+
+ pds = DSD.DesignSpaceDocument()
+ pds.read(args.primaryds)
+ if args.secondds is not None:
+ sds = DSD.DesignSpaceDocument()
+ sds.read(args.secondds)
+ else:
+ sds = None
+
+ # Process all the sources
+ psource = None
+ dsources = []
+ for source in pds.sources:
+ if source.copyInfo:
+ if psource: logger.log('Multiple fonts with <info copy="1" />', "S")
+ psource = Dsource(pds, source, logger, frompds=True, psource = True, args = args)
+ else:
+ dsources.append(Dsource(pds, source, logger, frompds=True, psource = False, args = args))
+ if sds is not None:
+ for source in sds.sources:
+ dsources.append(Dsource(sds, source, logger, frompds=False, psource = False, args=args))
+
+ # Process values in psource
+ fipval = {}
+ libpval = {}
+ changes = False
+ reqmissing = False
+
+ for field in fiall:
+ pval = psource.fontinfo.getval(field) if field in psource.fontinfo else None
+ oval = pval
+ # Set values or do other checks for special cases
+ if field == "italicAngle":
+ if "italic" in psource.source.filename.lower():
+ if pval is None or pval == 0 :
+ logger.log("Primary font: Italic angle must be non-zero for italic fonts", "E")
+ else:
+ if pval is not None and pval != 0 :
+ logger.log("Primary font: Italic angle must be zero for non-italic fonts", "E")
+ pval = None
+ elif field == "openTypeOS2WeightClass":
+ pval = int(psource.source.location["weight"])
+ elif field == "styleMapFamilyName":
+ if not complex and pval is None: logger.log("styleMapFamilyName missing from primary font", "E")
+ elif field == "styleMapStyleName":
+ if not complex and pval not in ('regular', 'bold', 'italic', 'bold italic'):
+ logger.log("styleMapStyleName must be 'regular', 'bold', 'italic', 'bold italic'", "E")
+ elif field in ("styleName", "openTypeNamePreferredSubfamilyName"):
+ pval = psource.source.styleName
+ elif field == "openTypeNameUniqueID":
+ nm = str(fipval["openTypeNameManufacturer"]) # Need to wrap with str() just in case missing from
+ fn = str(fipval["familyName"]) # fontinfo so would have been set to None
+ sn = psource.source.styleName
+ pval = nm + ": " + fn + " " + sn + ": " + datetime.datetime.now().strftime("%Y")
+ elif field == "unitsperem":
+ if pval is None or pval <= 0: logger.log("unitsperem must be non-zero", "S")
+ # After processing special cases, all required fields should have values
+ if pval is None and field in required:
+ reqmissing = True
+ logger.log("Required fontinfo field " + field + " missing from " + psource.source.filename, "E")
+ elif oval != pval:
+ changes = True
+ if pval is None:
+ if field in psource.fontinfo: psource.fontinfo.remove(field)
+ else:
+ psource.fontinfo[field][1].text = str(pval)
+ logchange(logger, "Primary font: " + field + " updated:", oval, pval)
+ fipval[field] = pval
+ if reqmissing: logger.log("Required fontinfo fields missing from " + psource.source.filename, "S")
+ if changes:
+ psource.fontinfo.setval("openTypeHeadCreated", "string",
+ datetime.datetime.now().strftime("%Y/%m/%d %H:%M:%S"))
+ psource.write("fontinfo")
+
+ for field in libcopy:
+ pval = psource.lib.getval(field) if field in psource.lib else None
+ if pval is None:
+ logtype = "W" if field[0:7] == "public." else "I"
+ logger.log("lib.plist field " + field + " missing from " + psource.source.filename, logtype)
+ libpval[field] = pval
+
+ # Now update values in other source fonts
+
+ for dsource in dsources:
+ logger.log("Processing " + dsource.ufodir, "I")
+ fchanges = False
+ for field in fiall:
+ sval = dsource.fontinfo.getval(field) if field in dsource.fontinfo else None
+ oval = sval
+ pval = fipval[field]
+ # Set values or do other checks for special cases
+ if field == "italicAngle":
+ if "italic" in dsource.source.filename.lower():
+ if sval is None or sval == 0:
+ logger.log(dsource.source.filename + ": Italic angle must be non-zero for italic fonts", "E")
+ else:
+ if sval is not None and sval != 0:
+ logger.log(dsource.source.filename + ": Italic angle must be zero for non-italic fonts", "E")
+ sval = None
+ elif field == "openTypeOS2WeightClass":
+ sval = int(dsource.source.location["weight"])
+ elif field == "styleMapStyleName":
+ if not complex and sval not in ('regular', 'bold', 'italic', 'bold italic'):
+ logger.log(dsource.source.filename + ": styleMapStyleName must be 'regular', 'bold', 'italic', 'bold italic'", "E")
+ elif field in ("styleName", "openTypeNamePreferredSubfamilyName"):
+ sval = dsource.source.styleName
+ elif field == "openTypeNameUniqueID":
+ sn = dsource.source.styleName
+ sval = nm + ": " + fn + " " + sn + ": " + datetime.datetime.now().strftime("%Y")
+ else:
+ sval = pval
+ if oval != sval:
+ if field == "unitsPerEm": logger.log("unitsPerEm inconsistent across fonts", "S")
+ fchanges = True
+ if sval is None:
+ dsource.fontinfo.remove(field)
+ logmess = " removed: "
+ else:
+ logmess = " added: " if oval is None else " updated: "
+ # Copy value from primary. This will add if missing.
+ dsource.fontinfo.setelem(field, ET.fromstring(ET.tostring(psource.fontinfo[field][1])))
+ # For fields where it is not a copy from primary...
+ if field in ("italicAngle", "openTypeNamePreferredSubfamilyName", "openTypeNameUniqueID",
+ "openTypeOS2WeightClass", "styleName"):
+ dsource.fontinfo[field][1].text = str(sval)
+
+ logchange(logger, dsource.source.filename + " " + field + logmess, oval, sval)
+
+ lchanges = False
+ for field in libcopy:
+ oval = dsource.lib.getval(field) if field in dsource.lib else None
+ pval = libpval[field]
+ if oval != pval:
+ lchanges = True
+ if pval is None:
+ dsource.lib.remove(field)
+ logmess = " removed: "
+ else:
+ dsource.lib.setelem(field, ET.fromstring(ET.tostring(psource.lib[field][1])))
+ logmess = " updated: "
+ logchange(logger, dsource.source.filename + " " + field + logmess, oval, pval)
+
+ if lchanges:
+ dsource.write("lib")
+ fchanges = True # Force fontinfo to update so openTypeHeadCreated is set
+ if fchanges:
+ dsource.fontinfo.setval("openTypeHeadCreated", "string",
+ datetime.datetime.now().strftime("%Y/%m/%d %H:%M:%S"))
+ dsource.write("fontinfo")
+
+ logger.log("psfsyncmasters completed", "P")
+
+class Dsource(object):
+ def __init__(self, ds, source, logger, frompds, psource, args):
+ self.ds = ds
+ self.source = source
+ self.logger = logger
+ self.frompds = frompds # Boolean to say if came from pds
+ self.newfile = "_new" if args.new else ""
+ self.ufodir = source.path
+ if not os.path.isdir(self.ufodir): logger.log(self.ufodir + " in designspace doc does not exist", "S")
+ try:
+ self.fontinfo = UFO.Uplist(font=None, dirn=self.ufodir, filen="fontinfo.plist")
+ except Exception as e:
+ logger.log("Unable to open fontinfo.plist in " + self.ufodir, "S")
+ try:
+ self.lib = UFO.Uplist(font=None, dirn=self.ufodir, filen="lib.plist")
+ except Exception as e:
+ if psource:
+ logger.log("Unable to open lib.plist in " + self.ufodir, "E")
+ self.lib = {} # Just need empty dict, so all vals will be set to None
+ else:
+ logger.log("Unable to open lib.plist in " + self.ufodir + "; creating empty one", "E")
+ self.lib = UFO.Uplist()
+ self.lib.logger=logger
+ self.lib.etree = ET.fromstring("<plist>\n<dict/>\n</plist>")
+ self.lib.populate_dict()
+ self.lib.dirn = self.ufodir
+ self.lib.filen = "lib.plist"
+
+ # Process parameters with similar logic to that in ufo.py. primarily to create outparams for writeXMLobject
+ libparams = {}
+ params = args.paramsobj
+ if "org.sil.pysilfontparams" in self.lib:
+ elem = self.lib["org.sil.pysilfontparams"][1]
+ if elem.tag != "array":
+ logger.log("Invalid parameter XML lib.plist - org.sil.pysilfontparams must be an array", "S")
+ for param in elem:
+ parn = param.tag
+ if not (parn in params.paramclass) or params.paramclass[parn] not in ("outparams", "ufometadata"):
+ logger.log(
+ "lib.plist org.sil.pysilfontparams must only contain outparams or ufometadata values: " + parn + " invalid",
+ "S")
+ libparams[parn] = param.text
+ # Create font-specific parameter set (with updates from lib.plist) Prepend names with ufodir to ensure uniqueness if multiple fonts open
+ params.addset(self.ufodir + "lib", "lib.plist in " + self.ufodir, inputdict=libparams)
+ if "command line" in params.sets:
+ params.sets[self.ufodir + "lib"].updatewith("command line", log=False) # Command line parameters override lib.plist ones
+ copyset = "main" if "main" in params.sets else "default"
+ params.addset(self.ufodir, copyset=copyset)
+ params.sets[self.ufodir].updatewith(self.ufodir + "lib", sourcedesc="lib.plist")
+ self.paramset = params.sets[self.ufodir]
+ # Validate specific parameters
+ if sorted(self.paramset["glifElemOrder"]) != sorted(params.sets["default"]["glifElemOrder"]):
+ logger.log("Invalid values for glifElemOrder", "S")
+ # Create outparams based on values in paramset, building attriborders from separate attriborders.<type> parameters.
+ self.outparams = {"attribOrders": {}}
+ for parn in params.classes["outparams"]:
+ value = self.paramset[parn]
+ if parn[0:12] == 'attribOrders':
+ elemname = parn.split(".")[1]
+ self.outparams["attribOrders"][elemname] = ETU.makeAttribOrder(value)
+ else:
+ self.outparams[parn] = value
+ self.outparams["UFOversion"] = 9 # Dummy value since not currently needed
+
+ def write(self, plistn):
+ filen = plistn + self.newfile + ".plist"
+ self.logger.log("Writing updated " + plistn + ".plist to " + filen, "P")
+ exists = True if os.path.isfile(os.path.join(self.ufodir, filen)) else False
+ plist = getattr(self, plistn)
+ UFO.writeXMLobject(plist, self.outparams, self.ufodir, filen, exists, fobject=True)
+
+
+def logchange(logger, logmess, old, new):
+ oldstr = str(old) if len(str(old)) < 22 else str(old)[0:20] + "..."
+ newstr = str(new) if len(str(new)) < 22 else str(new)[0:20] + "..."
+ if old is None:
+ logmess = logmess + " New value: " + newstr
+ else:
+ if new is None:
+ logmess = logmess + " Old value: " + oldstr
+ else:
+ logmess = logmess + " Old value: " + oldstr + ", new value: " + newstr
+ logger.log(logmess, "W")
+ # Extra verbose logging
+ if len(str(old)) > 21 :
+ logger.log("Full old value: " + str(old), "V")
+ if len(str(new)) > 21 :
+ logger.log("Full new value: " + str(new), "V")
+ logger.log("Types: Old - " + str(type(old)) + ", New - " + str(type(new)), "V")
+
+
+def cmd() : execute(None,doit, argspec)
+if __name__ == "__main__": cmd()
+
+
+''' *** Code notes ***
+
+Does not check precision for float, since no float values are currently processed
+ - see processnum in psfsyncmeta if needed later
+
+'''
diff --git a/lib/silfont/scripts/psfsyncmeta.py b/lib/silfont/scripts/psfsyncmeta.py
new file mode 100755
index 0000000..e925fde
--- /dev/null
+++ b/lib/silfont/scripts/psfsyncmeta.py
@@ -0,0 +1,303 @@
+#!/usr/bin/env python
+__doc__ = '''Sync metadata across a family of fonts assuming standard UFO file naming'''
+__url__ = 'http://github.com/silnrsi/pysilfont'
+__copyright__ = 'Copyright (c) 2017 SIL International (http://www.sil.org)'
+__license__ = 'Released under the MIT License (http://opensource.org/licenses/MIT)'
+__author__ = 'David Raymond'
+
+from silfont.core import execute
+from datetime import datetime
+import silfont.ufo as UFO
+import os
+from xml.etree import ElementTree as ET
+
+argspec = [
+ ('ifont',{'help': 'Input font file'}, {'type': 'infont'}),
+ ('-l','--log',{'help': 'Log file'}, {'type': 'outfile', 'def': '_sync.log'}),
+ ('-s','--single', {'help': 'Sync single UFO against master', 'action': 'store_true', 'default': False},{}),
+ ('-m','--master', {'help': 'Master UFO to sync single UFO against', 'nargs': '?' },{'type': 'infont', 'def': None}),
+ ('-r','--reportonly', {'help': 'Report issues but no updating', 'action': 'store_true', 'default': False},{}),
+ ('-n','--new', {'help': 'append "_new" to file/ufo names', 'action': 'store_true', 'default': False},{}),
+ ('--normalize', {'help': 'output all the fonts to normalize them', 'action': 'store_true', 'default': False},{}),
+ ]
+
+def doit(args) :
+ standardstyles = ["Regular", "Italic", "Bold", "BoldItalic"]
+ finfoignore = ["openTypeHeadCreated", "openTypeOS2Panose", "postscriptBlueScale", "postscriptBlueShift",
+ "postscriptBlueValues", "postscriptOtherBlues", "postscriptStemSnapH", "postscriptStemSnapV", "postscriptForceBold"]
+ libfields = ["public.postscriptNames", "public.glyphOrder", "com.schriftgestaltung.glyphOrder"]
+
+ font = args.ifont
+ logger = args.logger
+ singlefont = args.single
+ mfont = args.master
+ newfile = "_new" if args.new else ""
+ reportonly = args.reportonly
+ updatemessage = " to be updated: " if reportonly else " updated: "
+ params = args.paramsobj
+ precision = font.paramset["precision"]
+
+ # Increase screen logging level to W unless specific level supplied on command-line
+ if not(args.quiet or "scrlevel" in params.sets["command line"]) : logger.scrlevel = "W"
+
+ # Process UFO name
+ (path,base) = os.path.split(font.ufodir)
+ (base,ext) = os.path.splitext(base)
+ if '-' not in base : logger.log("Non-standard UFO name - must be <family>-<style>", "S")
+ (family,style) = base.split('-')
+
+ styles = [style]
+ fonts = {}
+ fonts[style] = font
+
+ # Process single and master settings
+ if singlefont :
+ if mfont :
+ mastertext = "Master" # Used in log messages
+ else : # Check against Regular font from same family
+ mfont = openfont(params, path, family, "Regular")
+ if mfont is None : logger.log("No regular font to check against - use -m to specify master font", "S")
+ mastertext = "Regular"
+ fonts["Regular"] =mfont
+ else : # Supplied font must be Regular
+ if mfont : logger.log("-m --master must only be used with -s --single", "S")
+ if style != "Regular" : logger.log("Must specify a Regular font unless -s is used", "S")
+ mastertext = "Regular"
+ mfont = font
+
+ # Check for required fields in master font
+ mfinfo = mfont.fontinfo
+ if "familyName" in mfinfo :
+ spacedfamily = mfinfo["familyName"][1].text
+ else:
+ logger.log("No familyName field in " + mastertext, "S")
+ if "openTypeNameManufacturer" in mfinfo :
+ manufacturer = mfinfo["openTypeNameManufacturer"][1].text
+ else:
+ logger.log("No openTypeNameManufacturer field in " + mastertext, "S")
+ mlib = mfont.lib
+
+ # Open the remaining fonts in the family
+ if not singlefont :
+ for style in standardstyles :
+ if not style in fonts :
+ fonts[style] = openfont(params, path, family, style) # Will return None if font does not exist
+ if fonts[style] is not None : styles.append(style)
+
+ # Process fonts
+ psuniqueidlist = []
+ fieldscopied = False
+ for style in styles :
+ font = fonts[style]
+ if font.UFOversion != "2" : logger.log("This script only works with UFO 2 format fonts","S")
+
+ fontname = family + "-" + style
+ spacedstyle = "Bold Italic" if style == "BoldItalic" else style
+ spacedname = spacedfamily + " " + spacedstyle
+ logger.log("************ Processing " + fontname, "P")
+
+ ital = True if "Italic" in style else False
+ bold = True if "Bold" in style else False
+
+ # Process fontinfo.plist
+ finfo=font.fontinfo
+ fieldlist = list(set(finfo) | set(mfinfo)) # Need all fields from both to detect missing fields
+ fchanged = False
+
+ for field in fieldlist:
+ action = None; issue = ""; newval = ""
+ if field in finfo :
+ elem = finfo[field][1]
+ tag = elem.tag
+ text = elem.text
+ if text is None : text = ""
+ if tag == "real" : text = processnum(text,precision)
+ # Field-specific actions
+
+ if field not in finfo :
+ if field not in finfoignore : action = "Copyfield"
+ elif field == "italicAngle" :
+ if ital and text == "0" :
+ issue = "is zero"
+ action = "Warn"
+ if not ital and text != "0" :
+ issue = "is non-zero"
+ newval = 0
+ action = "Update"
+ elif field == "openTypeNameUniqueID" :
+ newval = manufacturer + ": " + spacedname + ": " + datetime.now().strftime("%Y")
+ if text != newval :
+ issue = "Incorrect value"
+ action = "Update"
+ elif field == "openTypeOS2WeightClass" :
+ if bold and text != "700" :
+ issue = "is not 700"
+ newval = 700
+ action = "Update"
+ if not bold and text != "400" :
+ issue = "is not 400"
+ newval = 400
+ action = "Update"
+ elif field == "postscriptFontName" :
+ if text != fontname :
+ newval = fontname
+ issue = "Incorrect value"
+ action = "Update"
+ elif field == "postscriptFullName" :
+ if text != spacedname :
+ newval = spacedname
+ issue = "Incorrect value"
+ action = "Update"
+ elif field == "postscriptUniqueID" :
+ if text in psuniqueidlist :
+ issue = "has same value as another font: " + text
+ action = "Warn"
+ else :
+ psuniqueidlist.append(text)
+ elif field == "postscriptWeightName" :
+ newval = 'bold' if bold else 'regular'
+ if text != newval :
+ issue = "Incorrect value"
+ action = 'Update'
+ elif field == "styleMapStyleName" :
+ if text != spacedstyle.lower() :
+ newval = spacedstyle.lower()
+ issue = "Incorrect value"
+ action = "Update"
+ elif field in ("styleName", "openTypeNamePreferredSubfamilyName") :
+ if text != spacedstyle :
+ newval = spacedstyle
+ issue = "Incorrect value"
+ action = "Update"
+ elif field in finfoignore :
+ action = "Ignore"
+ # Warn for fields in this font but not master
+ elif field not in mfinfo :
+ issue = "is in " + spacedstyle + " but not in " + mastertext
+ action = "Warn"
+ # for all other fields, sync values from master
+ else :
+ melem = mfinfo[field][1]
+ mtag = melem.tag
+ mtext = melem.text
+ if mtext is None : mtext = ""
+ if mtag == 'real' : mtext = processnum(mtext,precision)
+ if tag in ("real", "integer", "string") :
+ if mtext != text :
+ issue = "does not match " + mastertext + " value"
+ newval = mtext
+ action = "Update"
+ elif tag in ("true, false") :
+ if tag != mtag :
+ issue = "does not match " + mastertext + " value"
+ action = "FlipBoolean"
+ elif tag == "array" : # Assume simple array with just values to compare
+ marray = mfinfo.getval(field)
+ array = finfo.getval(field)
+ if array != marray: action = "CopyArray"
+ else : logger.log("Non-standard fontinfo field type in " + fontname, "X")
+
+ # Now process the actions, create log messages etc
+ if action is None or action == "Ignore" :
+ pass
+ elif action == "Warn" :
+ logger.log(field + " needs manual correction: " + issue, "W")
+ elif action == "Error" :
+ logger.log(field + " needs manual correction: " + issue, "E")
+ elif action in ("Update", "FlipBoolean", "Copyfield", "CopyArray") : # Updating actions
+ fchanged = True
+ message = field + updatemessage
+ if action == "Update" :
+ message = message + issue + " Old: '" + text + "' New: '" + str(newval) + "'"
+ elem.text = newval
+ elif action == "FlipBoolean" :
+ newval = "true" if tag == "false" else "false"
+ message = message + issue + " Old: '" + tag + "' New: '" + newval + "'"
+ finfo.setelem(field, ET.fromstring("<" + newval + "/>"))
+ elif action == "Copyfield" :
+ message = message + "is missing so will be copied from " + mastertext
+ fieldscopied = True
+ finfo.addelem(field, ET.fromstring(ET.tostring(mfinfo[field][1])))
+ elif action == "CopyArray" :
+ message = message + "Some values different Old: " + str(array) + " New: " + str(marray)
+ finfo.setelem(field, ET.fromstring(ET.tostring(melem)))
+ logger.log(message, "W")
+ else:
+ logger.log("Uncoded action: " + action + " - oops", "X")
+
+ # Process lib.plist - currently just public.postscriptNames and glyph order fields which are all simple dicts or arrays
+ lib = font.lib
+ lchanged = False
+
+ for field in libfields:
+ # Check the values
+ action = None; issue = ""; newval = ""
+ if field in mlib:
+ if field in lib:
+ if lib.getval(field) != mlib.getval(field): # will only work for arrays or dicts with simple values
+ action = "Updatefield"
+ else:
+ action = "Copyfield"
+ else:
+ action = "Error" if field == ("public.GlyphOrder", "public.postscriptNames") else "Warn"
+ issue = field + " not in " + mastertext + " lib.plist"
+
+ # Process the actions, create log messages etc
+ if action is None or action == "Ignore":
+ pass
+ elif action == "Warn":
+ logger.log(field + " needs manual correction: " + issue, "W")
+ elif action == "Error":
+ logger.log(field + " needs manual correction: " + issue, "E")
+ elif action in ("Updatefield", "Copyfield"): # Updating actions
+ lchanged = True
+ message = field + updatemessage
+ if action == "Copyfield":
+ message = message + "is missing so will be copied from " + mastertext
+ lib.addelem(field, ET.fromstring(ET.tostring(mlib[field][1])))
+ elif action == "Updatefield":
+ message = message + "Some values different"
+ lib.setelem(field, ET.fromstring(ET.tostring(mlib[field][1])))
+ logger.log(message, "W")
+ else:
+ logger.log("Uncoded action: " + action + " - oops", "X")
+
+ # Now update on disk
+ if not reportonly:
+ if args.normalize:
+ font.write(os.path.join(path, family + "-" + style + newfile + ".ufo"))
+ else: # Just update fontinfo and lib
+ if fchanged:
+ filen = "fontinfo" + newfile + ".plist"
+ logger.log("Writing updated fontinfo to " + filen, "P")
+ exists = True if os.path.isfile(os.path.join(font.ufodir, filen)) else False
+ UFO.writeXMLobject(finfo, font.outparams, font.ufodir, filen, exists, fobject=True)
+ if lchanged:
+ filen = "lib" + newfile + ".plist"
+ logger.log("Writing updated lib.plist to " + filen, "P")
+ exists = True if os.path.isfile(os.path.join(font.ufodir, filen)) else False
+ UFO.writeXMLobject(lib, font.outparams, font.ufodir, filen, exists, fobject=True)
+
+ if fieldscopied :
+ message = "After updating, UFOsyncMeta will need to be re-run to validate these fields" if reportonly else "Re-run UFOsyncMeta to validate these fields"
+ logger.log("*** Some fields were missing and so copied from " + mastertext + ". " + message, "P")
+
+ return
+
+
+def openfont(params, path, family, style) : # Only try if directory exists
+ ufodir = os.path.join(path,family+"-"+style+".ufo")
+ font = UFO.Ufont(ufodir, params=params) if os.path.isdir(ufodir) else None
+ return font
+
+
+def processnum(text, precision) : # Apply same processing to numbers that normalization will
+ if precision is not None:
+ val = round(float(text), precision)
+ if val == int(val) : val = int(val) # Removed trailing decimal .0
+ text = str(val)
+ return text
+
+
+def cmd() : execute("UFO",doit, argspec)
+if __name__ == "__main__": cmd()
diff --git a/lib/silfont/scripts/psftuneraliases.py b/lib/silfont/scripts/psftuneraliases.py
new file mode 100644
index 0000000..f71d097
--- /dev/null
+++ b/lib/silfont/scripts/psftuneraliases.py
@@ -0,0 +1,121 @@
+#!/usr/bin/env python
+__doc__ = '''Merge lookup and feature aliases into TypeTuner feature file'''
+__url__ = 'http://github.com/silnrsi/pysilfont'
+__copyright__ = 'Copyright (c) 2019 SIL International (http://www.sil.org)'
+__license__ = 'Released under the MIT License (http://opensource.org/licenses/MIT)'
+__author__ = 'Bob Hallissy'
+
+from silfont.core import execute
+from xml.etree import ElementTree as ET
+from fontTools import ttLib
+import csv
+import struct
+
+argspec = [
+ ('input', {'help': 'Input TypeTuner feature file'}, {'type': 'infile'}),
+ ('output', {'help': 'Output TypeTuner feature file'}, {}),
+ ('-m','--mapping', {'help': 'Input csv mapping file'}, {'type': 'incsv'}),
+ ('-f','--ttf', {'help': 'Compiled TTF file'}, {}),
+ ('-l','--log',{'help': 'Optional log file'}, {'type': 'outfile', 'def': '_tuneraliases.log', 'optlog': True}),
+ ]
+
+def doit(args) :
+ logger = args.logger
+
+ if args.mapping is None and args.ttf is None:
+ logger.log("One or both of -m and -f must be provided", "S")
+ featdoc = ET.parse(args.input)
+ root = featdoc.getroot()
+ if root.tag != 'all_features':
+ logger.log("Invalid TypeTuner feature file: missing root element", "S")
+
+ # Whitespace to add after each new alias:
+ tail = '\n\t\t'
+
+ # Find or add alliaes element
+ aliases = root.find('aliases')
+ if aliases is None:
+ aliases = ET.SubElement(root,'aliases')
+ aliases.tail = '\n'
+
+ added = set()
+ duplicates = set()
+ def setalias(name, value):
+ # detect duplicate names in input
+ if name in added:
+ duplicates.add(name)
+ else:
+ added.add(name)
+ # modify existing or add new alias
+ alias = aliases.find('alias[@name="{}"]'.format(name))
+ if alias is None:
+ alias = ET.SubElement(aliases, 'alias', {'name': name, 'value': value})
+ alias.tail = tail
+ else:
+ alias.set('value', value)
+
+ # Process mapping file if present:
+ if args.mapping:
+ # Mapping file is assumed to come from psfbuildfea, and should look like:
+ # lookupname,table,index
+ # e.g. DigitAlternates,GSUB,51
+ for (name,table,value) in args.mapping:
+ setalias(name, value)
+
+ # Process the ttf file if present
+ if args.ttf:
+ # Generate aliases for features.
+ # In this code featureID means the key used in FontUtils for finding the feature, e.g., "calt _2"
+ def dotable(t): # Common routine for GPOS and GSUB
+ currtag = None
+ currtagindex = None
+ flist = [] # list, in order, of (featureTag, featureID), per Font::TTF
+ for i in range(0,t.FeatureList.FeatureCount):
+ newtag = str(t.FeatureList.FeatureRecord[i].FeatureTag)
+ if currtag is None or currtag != newtag:
+ flist.append((newtag, newtag))
+ currtag = newtag
+ currtagindex = 0
+ else:
+ flist.append( (currtag, '{} _{}'.format(currtag, currtagindex)))
+ currtagindex += 1
+ fslList = {} # dictionary keyed by feature_script_lang values returning featureID
+ for s in t.ScriptList.ScriptRecord:
+ currtag = str(s.ScriptTag)
+ # At present only looking at the dflt lang entries
+ for findex in s.Script.DefaultLangSys.FeatureIndex:
+ fslList['{}_{}_dflt'.format(flist[findex][0],currtag)] = flist[findex][1]
+ # Now that we have them all, add them in sorted order.
+ for name, value in sorted(fslList.items()):
+ setalias(name,value)
+
+ # Open the TTF for processing
+ try:
+ f = ttLib.TTFont(args.ttf)
+ except Exception as e:
+ logger.log("Couldn't open font '{}' for reading : {}".format(args.ttf, str(e)),"S")
+ # Grab features from GSUB and GPOS
+ for tag in ('GSUB', 'GPOS'):
+ try:
+ dotable(f[tag].table)
+ except Exception as e:
+ logger.log("Failed to process {} table: {}".format(tag, str(e)), "W")
+ # Grab features from Graphite:
+ try:
+ for tag in sorted(f['Feat'].features.keys()):
+ if tag == '1':
+ continue
+ name = 'gr_' + tag
+ value = str(struct.unpack('>L', tag.encode())[0])
+ setalias(name,value)
+ except Exception as e:
+ logger.log("Failed to process Feat table: {}".format(str(e)), "W")
+
+ if len(duplicates):
+ logger.log("The following aliases defined more than once in input: {}".format(", ".join(sorted(duplicates))), "S")
+
+ # Success. Write the result
+ featdoc.write(args.output, encoding='UTF-8', xml_declaration=True)
+
+def cmd() : execute(None,doit,argspec)
+if __name__ == "__main__": cmd()
diff --git a/lib/silfont/scripts/psfufo2glyphs.py b/lib/silfont/scripts/psfufo2glyphs.py
new file mode 100644
index 0000000..b40afcc
--- /dev/null
+++ b/lib/silfont/scripts/psfufo2glyphs.py
@@ -0,0 +1,69 @@
+#!/usr/bin/env python
+__doc__ = '''Reads a designSpace file and create a Glyphs file from its linked ufos'''
+__url__ = 'http://github.com/silnrsi/pysilfont'
+__copyright__ = 'Copyright (c) 2018 SIL International (http://www.sil.org)'
+__license__ = 'Released under the MIT License (http://opensource.org/licenses/MIT)'
+__author__ = 'David Raymond'
+
+from silfont.core import execute, splitfn
+
+from glyphsLib import to_glyphs
+from fontTools.designspaceLib import DesignSpaceDocument
+import os
+
+argspec = [
+ ('designspace', {'help': 'Input designSpace file'}, {'type': 'filename'}),
+ ('glyphsfile', {'help': 'Output glyphs file name', 'nargs': '?' }, {'type': 'filename', 'def': None}),
+ ('--glyphsformat', {'help': "Format for glyphs file (2 or 3)", 'default': "2"}, {}),
+ ('--nofea', {'help': 'Do not process features.fea', 'action': 'store_true', 'default': False}, {}),
+ # ('--nofixes', {'help': 'Bypass code fixing data', 'action': 'store_true', 'default': False}, {}),
+ ('-l', '--log', {'help': 'Log file'}, {'type': 'outfile', 'def': '_ufo2glyphs.log'})]
+
+# This is just bare-bones code at present so does the same as glyphsLib's ufo2glyphs!
+# It is designed so that data could be massaged, if necessary, on the way. No such need has been found so far
+
+def doit(args):
+ glyphsfile = args.glyphsfile
+ logger = args.logger
+ gformat = args.glyphsformat
+ if gformat in ("2","3"):
+ gformat = int(gformat)
+ else:
+ logger.log("--glyphsformat must be 2 or 3", 'S')
+ if glyphsfile is None:
+ (path,base,ext) = splitfn(args.designspace)
+ glyphsfile = os.path.join(path, base + ".glyphs" )
+ else:
+ (path, base, ext) = splitfn(glyphsfile)
+ backupname = os.path.join(path, base + "-backup.glyphs" )
+ logger.log("Opening designSpace file", "I")
+ ds = DesignSpaceDocument()
+ ds.read(args.designspace)
+ if args.nofea: # Need to rename the features.fea files so they are not processed
+ origfeas = []; hiddenfeas = []
+ for source in ds.sources:
+ origfea = os.path.join(source.path, "features.fea")
+ hiddenfea = os.path.join(source.path, "features.tmp")
+ if os.path.exists(origfea):
+ logger.log(f'Renaming {origfea} to {hiddenfea}', "I")
+ os.rename(origfea, hiddenfea)
+ origfeas.append(origfea)
+ hiddenfeas.append(hiddenfea)
+ else:
+ logger.log(f'No features.fea found in {source.path}')
+ logger.log("Now creating glyphs object", "I")
+ glyphsfont = to_glyphs(ds)
+ if args.nofea: # Now need to reverse renamimg of features.fea files
+ for i, origfea in enumerate(origfeas):
+ logger.log(f'Renaming {hiddenfeas[i]} back to {origfea}', "I")
+ os.rename(hiddenfeas[i], origfea)
+ glyphsfont.format_version = gformat
+
+ if os.path.exists(glyphsfile): # Create a backup
+ logger.log("Renaming existing glyphs file to " + backupname, "I")
+ os.renames(glyphsfile, backupname)
+ logger.log("Writing glyphs file: " + glyphsfile, "I")
+ glyphsfont.save(glyphsfile)
+
+def cmd(): execute(None, doit, argspec)
+if __name__ == "__main__": cmd()
diff --git a/lib/silfont/scripts/psfufo2ttf.py b/lib/silfont/scripts/psfufo2ttf.py
new file mode 100644
index 0000000..832ef88
--- /dev/null
+++ b/lib/silfont/scripts/psfufo2ttf.py
@@ -0,0 +1,108 @@
+#!/usr/bin/env python
+__doc__ = 'Generate a ttf file without OpenType tables from a UFO'
+__url__ = 'http://github.com/silnrsi/pysilfont'
+__copyright__ = 'Copyright (c) 2017 SIL International (http://www.sil.org)'
+__license__ = 'Released under the MIT License (http://opensource.org/licenses/MIT)'
+__author__ = 'Alan Ward'
+
+# Compared to fontmake it does not decompose glyphs or remove overlaps
+# and curve conversion seems to happen in a different way.
+
+from silfont.core import execute
+import defcon, ufo2ft.outlineCompiler, ufo2ft.preProcessor, ufo2ft.filters
+
+argspec = [
+ ('iufo', {'help': 'Input UFO folder'}, {}),
+ ('ottf', {'help': 'Output ttf file name'}, {}),
+ ('--removeOverlaps', {'help': 'Merge overlapping contours', 'action': 'store_true'}, {}),
+ ('--decomposeComponents', {'help': 'Decompose componenets', 'action': 'store_true'}, {}),
+ ('-l', '--log', {'help': 'Optional log file'}, {'type': 'outfile', 'def': '_ufo2ttf.log', 'optlog': True})]
+
+PUBLIC_PREFIX = 'public.'
+
+def doit(args):
+ ufo = defcon.Font(args.iufo)
+
+ # if style is Regular and there are no openTypeNameRecords defining the full name (ID=4), then
+ # add one so that "Regular" is omitted from the fullname
+ if ufo.info.styleName == 'Regular':
+ if ufo.info.openTypeNameRecords is None:
+ ufo.info.openTypeNameRecords = []
+ fullNameRecords = [ nr for nr in ufo.info.openTypeNameRecords if nr['nameID'] == 4]
+ if not len(fullNameRecords):
+ ufo.info.openTypeNameRecords.append( { 'nameID': 4, 'platformID': 3, 'encodingID': 1, 'languageID': 1033, 'string': ufo.info.familyName } )
+
+# args.logger.log('Converting UFO to ttf and compiling fea')
+# font = ufo2ft.compileTTF(ufo,
+# glyphOrder = ufo.lib.get(PUBLIC_PREFIX + 'glyphOrder'),
+# useProductionNames = False)
+
+ args.logger.log('Converting UFO to ttf without OT', 'P')
+
+ # default arg value for TTFPreProcessor class: removeOverlaps = False, convertCubics = True
+ preProcessor = ufo2ft.preProcessor.TTFPreProcessor(ufo, removeOverlaps = args.removeOverlaps, convertCubics=True,
+ flattenComponents = True,
+ skipExportGlyphs = ufo.lib.get("public.skipExportGlyphs", []))
+
+ # Need to handle cases if filters that are used are set in com.github.googlei18n.ufo2ft.filters with lib.plist
+ dc = dtc = ftpos = None
+ for (i,filter) in enumerate(preProcessor.preFilters):
+ if isinstance(filter, ufo2ft.filters.decomposeComponents.DecomposeComponentsFilter):
+ dc = True
+ if isinstance(filter, ufo2ft.filters.decomposeTransformedComponents.DecomposeTransformedComponentsFilter):
+ dtc = True
+ if isinstance(filter, ufo2ft.filters.flattenComponents.FlattenComponentsFilter):
+ ftpos = i
+ # Add decomposeComponents if --decomposeComponents is used
+ if args.decomposeComponents and not dc: preProcessor.preFilters.append(
+ ufo2ft.filters.decomposeComponents.DecomposeComponentsFilter())
+ # Add decomposeTransformedComponents if not already set via lib.plist
+ if not dtc: preProcessor.preFilters.append(ufo2ft.filters.decomposeTransformedComponents.DecomposeTransformedComponentsFilter())
+ # Remove flattenComponents if set via lib.plist since we set it via flattenComponents = True when setting up the preprocessor
+ if ftpos: preProcessor.preFilters.pop(ftpos)
+
+ glyphSet = preProcessor.process()
+ outlineCompiler = ufo2ft.outlineCompiler.OutlineTTFCompiler(ufo,
+ glyphSet=glyphSet,
+ glyphOrder=ufo.lib.get(PUBLIC_PREFIX + 'glyphOrder'))
+ font = outlineCompiler.compile()
+
+ # handle uvs glyphs until ufo2ft does it for us.
+ uvsdict = getuvss(ufo)
+ if len(uvsdict):
+ from fontTools.ttLib.tables._c_m_a_p import cmap_format_14
+ cmap_uvs = cmap_format_14(14)
+ cmap_uvs.platformID = 0
+ cmap_uvs.platEncID = 5
+ cmap_uvs.cmap = {}
+ cmap_uvs.uvsDict = uvsdict
+ font['cmap'].tables.append(cmap_uvs)
+
+ args.logger.log('Saving ttf file', 'P')
+ font.save(args.ottf)
+
+ args.logger.log('Done', 'P')
+
+def getuvss(ufo):
+ uvsdict = {}
+ uvs = ufo.lib.get('org.sil.variationSequences', None)
+ if uvs is not None:
+ for usv, dat in uvs.items():
+ usvc = int(usv, 16)
+ pairs = []
+ uvsdict[usvc] = pairs
+ for k, v in dat.items():
+ pairs.append((int(k, 16), v))
+ return uvsdict
+ for g in ufo:
+ uvs = getattr(g, 'lib', {}).get("org.sil.uvs", None)
+ if uvs is None:
+ continue
+ codes = [int(x, 16) for x in uvs.split()]
+ if codes[1] not in uvsdict:
+ uvsdict[codes[1]] = []
+ uvsdict[codes[1]].append((codes[0], (g.name if codes[0] not in g.unicodes else None)))
+ return uvsdict
+
+def cmd(): execute(None, doit, argspec)
+if __name__ == '__main__': cmd()
diff --git a/lib/silfont/scripts/psfversion.py b/lib/silfont/scripts/psfversion.py
new file mode 100755
index 0000000..12cdae9
--- /dev/null
+++ b/lib/silfont/scripts/psfversion.py
@@ -0,0 +1,64 @@
+#!/usr/bin/env python
+__doc__ = 'Display version info for pysilfont and dependencies'
+__url__ = 'http://github.com/silnrsi/pysilfont'
+__copyright__ = 'Copyright (c) 2018 SIL International (http://www.sil.org)'
+__license__ = 'Released under the MIT License (http://opensource.org/licenses/MIT)'
+__author__ = 'David Raymond'
+
+import sys, importlib
+import silfont
+
+def cmd() :
+
+ deps = ( # (module, used by, min recommended version)
+ ('defcon', '?', ''),
+ ('fontbakery', '?', ''),
+ ('fontMath', '?', ''),
+ ('fontParts', '?', ''),
+ ('fontTools', '?', ''),
+ ('glyphConstruction', '?', ''),
+ ('glyphsLib', '?', ''),
+ ('lxml','?', ''),
+ ('lz4', '?', ''),
+ ('mutatorMath', '?', ''),
+ ('odf', '?', ''),
+ ('palaso', '?', ''),
+ ('tabulate', '?', ''),
+ ('ufo2ft', '?', ''),
+ ('ufoLib2', '?', ''),
+ )
+
+ # Pysilfont info
+ print("Pysilfont " + silfont.__copyright__ + "\n")
+ print(" Version: " + silfont.__version__)
+ print(" Commands in: " + sys.argv[0][:-10])
+ print(" Code running from: " + silfont.__file__[:-12])
+ print(" using: Python " + sys.version.split(" \n")[0] + "\n")
+
+ for dep in deps:
+ name = dep[0]
+
+ try:
+ module = importlib.import_module(name)
+ path = module.__file__
+ # Remove .py file name from end
+ pyname = path.split("/")[-1]
+ path = path[:-len(pyname)-1]
+ version = "No version info"
+ for attr in ("__version__", "version", "VERSION"):
+ if hasattr(module, attr):
+ version = getattr(module, attr)
+ break
+ except Exception as e:
+ etext = str(e)
+ if etext == "No module named '" + name + "'":
+ version = "Module is not installed"
+ else:
+ version = "Module import failed with " + etext
+ path = ""
+
+ print('{:20} {:15} {}'.format(name + ":", version, path))
+
+ return
+
+if __name__ == "__main__": cmd()
diff --git a/lib/silfont/scripts/psfwoffit.py b/lib/silfont/scripts/psfwoffit.py
new file mode 100644
index 0000000..678cb19
--- /dev/null
+++ b/lib/silfont/scripts/psfwoffit.py
@@ -0,0 +1,99 @@
+#!/usr/bin/env python
+__doc__ = 'Convert font between ttf, woff, woff2'
+__url__ = 'http://github.com/silnrsi/pysilfont'
+__copyright__ = 'Copyright (c) 2021 SIL International (http://www.sil.org)'
+__license__ = 'Released under the MIT License (http://opensource.org/licenses/MIT)'
+__author__ = 'Bob Hallissy'
+
+from silfont.core import execute
+from fontTools.ttLib import TTFont
+from fontTools.ttLib.sfnt import WOFFFlavorData
+from fontTools.ttLib.woff2 import WOFF2FlavorData
+import os.path
+
+argspec = [
+ ('infont', {'help': 'Source font file (can be ttf, woff, or woff2)'}, {}),
+ ('-m', '--metadata', {'help': 'file containing XML WOFF metadata', 'default': None}, {}),
+ ('--privatedata', {'help': 'file containing WOFF privatedata', 'default': None}, {}),
+ ('-v', '--version', {'help': 'woff font version number in major.minor', 'default': None}, {}),
+ ('--ttf', {'help': 'name of ttf file to be written', 'nargs': '?', 'default': None, 'const': '-'}, {}),
+ ('--woff', {'help': 'name of woff file to be written', 'nargs': '?', 'default': None, 'const': '-'}, {}),
+ ('--woff2', {'help': 'name of woff2 file to be written', 'nargs': '?', 'default': None, 'const': '-'}, {}),
+ ('-l', '--log', {'help': 'Log file'}, {'type': 'outfile', 'def': '_woffit.log'})]
+
+def doit(args):
+ logger = args.logger
+ infont = args.infont
+ font = TTFont(args.infont)
+ defaultpath = os.path.splitext(infont)[0]
+ inFlavor = font.flavor or 'ttf'
+ logger.log(f'input font {infont} is a {inFlavor}', 'I')
+
+ # Read & parse version, if provided
+ flavorData = WOFFFlavorData() # Initializes all fields to None
+
+ if args.version:
+ try:
+ version = float(args.version)
+ if version < 0:
+ raise ValueError('version cannot be negative')
+ flavorData.majorVersion, flavorData.minorVersion = map(int, format(version, '.3f').split('.'))
+ except:
+ logger.log(f'invalid version syntax "{args.version}": should be MM.mmm', 'S')
+ else:
+ try:
+ flavorData.majorVersion = font.flavorData.majorVersion
+ flavorData.minorVersion = font.flavorData.minorVersion
+ except:
+ # Pull version from head table
+ head = font['head']
+ flavorData.majorVersion, flavorData.minorVersion =map(int, format(head.fontRevision, '.3f').split('.'))
+
+ # Read metadata if provided, else get value from input font
+ if args.metadata:
+ try:
+ with open(args.metadata, 'rb') as f:
+ flavorData.metaData = f.read()
+ except:
+ logger.log(f'Unable to read file "{args.metadata}"', 'S')
+ elif inFlavor != 'ttf':
+ flavorData.metaData = font.flavorData.metaData
+
+ # Same process for private data
+ if args.privatedata:
+ try:
+ with open(args.privatedata, 'rb') as f:
+ flavorData.privateData = f.read()
+ except:
+ logger.log(f'Unable to read file "{args.privatedata}"', 'S')
+ elif inFlavor != 'ttf':
+ flavorData.privData = font.flavorData.privData
+
+ if args.woff:
+ font.flavor = 'woff'
+ font.flavorData = flavorData
+ fname = f'{defaultpath}.{font.flavor}' if args.woff2 == '-' else args.woff
+ logger.log(f'Writing {font.flavor} font to "{fname}"', 'P')
+ font.save(fname)
+
+ if args.woff2:
+ font.flavor = 'woff2'
+ font.flavorData = WOFF2FlavorData(data=flavorData)
+ fname = f'{defaultpath}.{font.flavor}' if args.woff2 == '-' else args.woff2
+ logger.log(f'Writing {font.flavor} font to "{fname}"', 'P')
+ font.save(fname)
+
+ if args.ttf:
+ font.flavor = None
+ font.flavorData = None
+ fname = f'{defaultpath}.ttf' if args.ttf == '-' else args.ttf
+ logger.log(f'Writing ttf font to "{fname}"', 'P')
+ font.save(fname)
+
+ font.close()
+
+def cmd() : execute('FT',doit, argspec)
+if __name__ == "__main__": cmd()
+
+
+
diff --git a/lib/silfont/scripts/psfxml2compdef.py b/lib/silfont/scripts/psfxml2compdef.py
new file mode 100755
index 0000000..f5b5b35
--- /dev/null
+++ b/lib/silfont/scripts/psfxml2compdef.py
@@ -0,0 +1,33 @@
+#!/usr/bin/env python
+__doc__ = 'convert composite definition file from XML format'
+__url__ = 'http://github.com/silnrsi/pysilfont'
+__copyright__ = 'Copyright (c) 2015 SIL International (http://www.sil.org)'
+__license__ = 'Released under the MIT License (http://opensource.org/licenses/MIT)'
+__author__ = 'David Rowe'
+
+from silfont.core import execute
+from silfont.comp import CompGlyph
+from xml.etree import ElementTree as ET
+
+# specify two parameters: input file (XML format), output file (single line format).
+argspec = [
+ ('input',{'help': 'Input file of CD in XML format'}, {'type': 'infile'}),
+ ('output',{'help': 'Output file of CD in single line format'}, {'type': 'outfile'}),
+ ('-l', '--log', {'help': 'Optional log file'}, {'type': 'outfile', 'def': '_xml2compdef.log', 'optlog': True})]
+
+def doit(args) :
+ cgobj = CompGlyph()
+ glyphcount = 0
+ for g in ET.parse(args.input).getroot().findall('glyph'):
+ glyphcount += 1
+ cgobj.CDelement = g
+ cgobj.CDline = None
+ cgobj.parsefromCDelement()
+ if cgobj.CDline != None:
+ args.output.write(cgobj.CDline+'\n')
+ else:
+ pass # error in glyph number glyphcount message
+ return
+
+def cmd() : execute(None,doit,argspec)
+if __name__ == "__main__": cmd()
diff --git a/lib/silfont/ufo.py b/lib/silfont/ufo.py
new file mode 100755
index 0000000..e6917c8
--- /dev/null
+++ b/lib/silfont/ufo.py
@@ -0,0 +1,1386 @@
+#!/usr/bin/env python
+'Classes and functions for use handling Ufont UFO font objects in pysilfont scripts'
+__url__ = 'http://github.com/silnrsi/pysilfont'
+__copyright__ = 'Copyright (c) 2015 SIL International (http://www.sil.org)'
+__license__ = 'Released under the MIT License (http://opensource.org/licenses/MIT)'
+__author__ = 'David Raymond'
+
+from xml.etree import ElementTree as ET
+import sys, os, shutil, filecmp, io, re
+import warnings
+import collections
+import datetime
+import silfont.core
+import silfont.util as UT
+import silfont.etutil as ETU
+
+_glifElemMulti = ('unicode', 'guideline', 'anchor') # glif elements that can occur multiple times
+_glifElemF1 = ('advance', 'unicode', 'outline', 'lib') # glif elements valid in format 1 glifs (ie UFO2 glfis)
+
+# Define illegal characters and reserved names for makeFileName
+_illegalChars = "\"*+/:><?[\]|" + chr(0x7F)
+for i in range(0, 32): _illegalChars += chr(i)
+_illegalChars = list(_illegalChars)
+_reservedNames = "CON PRN AUX CLOCK$ NUL COM1 COM2 COM3 COM4 PT1 LPT2 LPT3".lower().split(" ")
+
+obsoleteLibKeys = [ # Used by "check and fix" + some scripts
+ "com.schriftgestaltung.blueFuzz",
+ "com.schriftgestaltung.blueScale",
+ "com.schriftgestaltung.blueShift",
+ "com.schriftgestaltung.customValue",
+ "com.schriftgestaltung.Disable Last Change",
+ "com.schriftgestaltung.disablesAutomaticAlignment",
+ "com.schriftgestaltung.disablesLastChange",
+ "com.schriftgestaltung.DisplayStrings",
+ "com.schriftgestaltung.font.Disable Last Change",
+ "com.schriftgestaltung.font.glyphOrder",
+ "com.schriftgestaltung.font.license",
+ "com.schriftgestaltung.useNiceNames",
+ "org.sil.glyphsappversion",
+ "UFOFormat"]
+
+class _Ucontainer(object):
+ # Parent class for other objects (eg Ulayer)
+ def __init__(self):
+ self._contents = {}
+
+ # Define methods so it acts like an immutable container
+ # (changes should be made via object functions etc)
+ def __len__(self):
+ return len(self._contents)
+
+ def __getitem__(self, key):
+ return self._contents[key]
+
+ def __iter__(self):
+ return iter(self._contents)
+
+ def get(self, key, default=None):
+ return self._contents.get(key, default=default)
+
+ def keys(self):
+ return self._contents.keys()
+
+
+class _plist(object):
+ # Used for common plist methods inherited by Uplist and Ulib classes
+
+ def addval(self, key, valuetype, value): # For simple single-value elements - use addelem for dicts or arrays
+ if valuetype not in ("integer", "real", "string"):
+ self.font.logger.log("addval() can only be used with simple elements", "X")
+ if key in self._contents: self.font.logger.log("Attempt to add duplicate key " + key + " to plist", "X")
+ dict = self.etree[0]
+
+ keyelem = ET.Element("key")
+ keyelem.text = key
+ dict.append(keyelem)
+
+ valelem = ET.Element(valuetype)
+ valelem.text = str(value)
+ dict.append(valelem)
+
+ self._contents[key] = [keyelem, valelem]
+
+ def setval(self, key, valuetype, value): # For simple single-value elements - use setelem for dicts or arrays
+ if valuetype not in ("integer", "real", "string"):
+ self.font.logger.log("setval() can only be used with simple elements", "X")
+ if key in self._contents:
+ self._contents[key][1].text = str(value)
+ else:
+ self.addval(key, valuetype, value)
+
+ def getval(self, key, default=None): # Returns a value for integer, real, string, true, false, dict or array keys or None for other keys
+ elem = self._contents.get(key, [None, None])[1]
+ if elem is None:
+ return default
+ return self._valelem(elem)
+
+ def _valelem(self, elem): # Used by getval to recursively process dict and array elements
+ if elem.tag == "integer": return int(elem.text)
+ elif elem.tag == "real": return float(elem.text)
+ elif elem.tag == "string": return elem.text
+ elif elem.tag == "true": return True
+ elif elem.tag == "false": return False
+ elif elem.tag == "array":
+ array = []
+ for subelem in elem: array.append(self._valelem(subelem))
+ return array
+ elif elem.tag == "dict":
+ dict = {}
+ for i in range(0, len(elem), 2): dict[elem[i].text] = self._valelem(elem[i + 1])
+ return dict
+ else:
+ return None
+
+ def remove(self, key):
+ item = self._contents[key]
+ self.etree[0].remove(item[0])
+ self.etree[0].remove(item[1])
+ del self._contents[key]
+
+ def addelem(self, key, element): # For non-simple elements (eg arrays) the calling script needs to build the etree element
+ if key in self._contents: self.font.logger.log("Attempt to add duplicate key " + key + " to plist", "X")
+ dict = self.etree[0]
+
+ keyelem = ET.Element("key")
+ keyelem.text = key
+ dict.append(keyelem)
+ dict.append(element)
+
+ self._contents[key] = [keyelem, element]
+
+ def setelem(self, key, element):
+ if key in self._contents: self.remove(key)
+ self.addelem(key, element)
+
+
+class Uelement(_Ucontainer):
+ # Class for an etree element. Mainly used as a parent class
+ # For each tag in the element, returns list of sub-elements with that tag
+ def __init__(self, element):
+ self.element = element
+ self.reindex()
+
+ def reindex(self):
+ self._contents = collections.defaultdict(list)
+ for e in self.element:
+ self._contents[e.tag].append(e)
+
+ def remove(self, subelement):
+ self._contents[subelement.tag].remove(subelement)
+ self.element.remove(subelement)
+
+ def append(self, subelement):
+ self._contents[subelement.tag].append(subelement)
+ self.element.append(subelement)
+
+ def insert(self, index, subelement):
+ self._contents[subelement.tag].insert(index, subelement)
+ self.element.insert(index, subelement)
+
+ def replace(self, index, subelement):
+ self._contents[subelement.tag][index] = subelement
+ self.element[index] = subelement
+
+
+class UtextFile(object):
+ # Generic object for handling non-xml text files
+ def __init__(self, font, dirn, filen):
+ self.type = "textfile"
+ self.font = font
+ self.filen = filen
+ self.dirn = dirn
+ if dirn == font.ufodir:
+ dtree = font.dtree
+ else:
+ dtree = font.dtree.subtree(dirn)
+ if not dtree: font.logger.log("Missing directory " + dirn, "X")
+ if filen not in dtree:
+ dtree[filen] = UT.dirTreeItem(added=True)
+ dtree[filen].setinfo(read=True)
+ dtree[filen].fileObject = self
+ dtree[filen].fileType = "text"
+
+ def write(self, dtreeitem, dir, ofilen, exists):
+ # For now just copies source to destination if changed
+ inpath = os.path.join(self.dirn, self.filen)
+ changed = True
+ if exists: changed = not (filecmp.cmp(inpath, os.path.join(dir, self.filen)))
+ if changed:
+ try:
+ shutil.copy2(inpath, dir)
+ except Exception as e:
+ print(e)
+ sys.exit(1)
+ dtreeitem.written = True
+
+class Udirectory(object):
+ # Generic object for handling directories - used for data and images
+ def __init__(self, font, parentdir, dirn):
+ self.type = "directory"
+ self.font = font
+ self.parentdir = parentdir
+ self.dirn = dirn
+ if parentdir != font.ufodir:
+ self.font.logger.log("Currently Udir only supports top-level directories", "X")
+ dtree = font.dtree
+ if dirn not in dtree:
+ self.font.logger.log("Udir directory " + dirn + " does not exist", "X")
+ dtree[dirn].setinfo(read=True)
+ dtree[dirn].fileObject = self
+ dtree[dirn].fileType = "directory"
+
+ def write(self, dtreeitem, oparentdir):
+ # For now just copies source to destination
+ if self.parentdir == oparentdir: return # No action needed
+ inpath = os.path.join(self.parentdir, self.dirn)
+ outpath = os.path.join(oparentdir, self.dirn)
+ try:
+ if os.path.isdir(outpath):
+ shutil.rmtree(outpath)
+ shutil.copytree(inpath, outpath)
+ except Exception as e:
+ print(e)
+ sys.exit(1)
+ dtreeitem.written = True
+
+class Ufont(object):
+ """ Object to hold all the data from a UFO"""
+
+ def __init__(self, ufodir, logger=None, params=None):
+ if logger is not None and params is not None:
+ params.logger.log("Only supply a logger if params not set (since that has one)", "X")
+ if params is None:
+ params = silfont.core.parameters()
+ if logger is not None: params.logger = logger
+ self.params = params
+ self.logger = params.logger
+ logger = self.logger
+ self.ufodir = ufodir
+ logger.log('Reading UFO: ' + ufodir, 'P')
+ if not os.path.isdir(ufodir):
+ logger.log(ufodir + " is not a directory", "S")
+ # Read list of files and folders
+ self.dtree = UT.dirTree(ufodir)
+ # Read metainfo (which must exist)
+ self.metainfo = self._readPlist("metainfo.plist")
+ self.UFOversion = self.metainfo["formatVersion"][1].text
+ # Read lib.plist then process pysilfont parameters if present
+ libparams = {}
+ if "lib.plist" in self.dtree:
+ self.lib = self._readPlist("lib.plist")
+ if "org.sil.pysilfontparams" in self.lib:
+ elem = self.lib["org.sil.pysilfontparams"][1]
+ if elem.tag != "array":
+ logger.log("Invalid parameter XML lib.plist - org.sil.pysilfontparams must be an array", "S")
+ for param in elem:
+ parn = param.tag
+ if not (parn in params.paramclass) or params.paramclass[parn] not in ("outparams", "ufometadata"):
+ logger.log("lib.plist org.sil.pysilfontparams must only contain outparams or ufometadata values: " + parn + " invalid", "S")
+ libparams[parn] = param.text
+ # Create font-specific parameter set (with updates from lib.plist) Prepend names with ufodir to ensure uniqueness if multiple fonts open
+ params.addset(ufodir + "lib", "lib.plist in " + ufodir, inputdict=libparams)
+ if "command line" in params.sets:
+ params.sets[ufodir + "lib"].updatewith("command line", log=False) # Command line parameters override lib.plist ones
+ copyset = "main" if "main" in params.sets else "default"
+ params.addset(ufodir, copyset=copyset)
+ params.sets[ufodir].updatewith(ufodir + "lib", sourcedesc="lib.plist")
+ self.paramset = params.sets[ufodir]
+ # Validate specific parameters
+ if self.paramset["UFOversion"] not in ("", "2", "3"): logger.log("UFO version must be 2 or 3", "S")
+ if sorted(self.paramset["glifElemOrder"]) != sorted(self.params.sets["default"]["glifElemOrder"]):
+ logger.log("Invalid values for glifElemOrder", "S")
+
+ # Create outparams based on values in paramset, building attriborders from separate attriborders.<type> parameters.
+ self.outparams = {"attribOrders": {}}
+ for parn in params.classes["outparams"]:
+ value = self.paramset[parn]
+ if parn[0:12] == 'attribOrders':
+ elemname = parn.split(".")[1]
+ self.outparams["attribOrders"][elemname] = ETU.makeAttribOrder(value)
+ else:
+ self.outparams[parn] = value
+ if self.outparams["UFOversion"] == "": self.outparams["UFOversion"] = self.UFOversion
+
+ # Set flags for checking and fixing metadata
+ cf = self.paramset["checkfix"].lower()
+ if cf not in ("check", "fix", "none", ""): logger.log("Invalid value '" + cf + "' for checkfix parameter", "S")
+
+ self.metacheck = True if cf in ("check", "fix") else False
+ self.metafix = True if cf == "fix" else False
+ if "fontinfo.plist" not in self.dtree:
+ logger.log("fontinfo.plist missing so checkfix routines can't be run", "E")
+ self.metacheck = False
+ self.metafix = False
+
+ # Read other top-level plists
+ if "fontinfo.plist" in self.dtree: self.fontinfo = self._readPlist("fontinfo.plist")
+ if "groups.plist" in self.dtree: self.groups = self._readPlist("groups.plist")
+ if "kerning.plist" in self.dtree: self.kerning = self._readPlist("kerning.plist")
+ createlayercontents = False
+ if self.UFOversion == "2": # Create a dummy layer contents so 2 & 3 can be handled the same
+ createlayercontents = True
+ else:
+ if "layercontents.plist" in self.dtree:
+ self.layercontents = self._readPlist("layercontents.plist")
+ else:
+ logger.log("layercontents.plist missing - one will be created", "W")
+ createlayercontents = True
+ if createlayercontents:
+ if "glyphs" not in self.dtree: logger.log('No glyphs directory in font', "S")
+ self.layercontents = Uplist(font=self)
+ self.dtree['layercontents.plist'] = UT.dirTreeItem(read=True, added=True, fileObject=self.layercontents,
+ fileType="xml")
+ dummylc = "<plist>\n<array>\n<array>\n<string>public.default</string>\n<string>glyphs</string>\n</array>\n</array>\n</plist>"
+ self.layercontents.etree = ET.fromstring(dummylc)
+ self.layercontents.populate_dict()
+
+ # Process features.fea
+ if "features.fea" in self.dtree:
+ self.features = UfeatureFile(self, ufodir, "features.fea")
+ # Process the glyphs directories)
+ self.layers = []
+ self.deflayer = None
+ for i in sorted(self.layercontents.keys()):
+ layername = self.layercontents[i][0].text
+ layerdir = self.layercontents[i][1].text
+ logger.log("Processing Glyph Layer " + str(i) + ": " + layername + layerdir, "I")
+ layer = Ulayer(layername, layerdir, self)
+ if layer:
+ self.layers.append(layer)
+ if layername == "public.default": self.deflayer = layer
+ else:
+ logger.log("Glyph directory " + layerdir + " missing", "S")
+ if self.deflayer is None: logger.log("No public.default layer", "S")
+ # Process other directories
+ if "images" in self.dtree:
+ self.images = Udirectory(self,ufodir, "images")
+ if "data" in self.dtree:
+ self.data = Udirectory(self, ufodir, "data")
+
+ # Run best practices check and fix routines
+ if self.metacheck:
+ initwarnings = logger.warningcount
+ initerrors = logger.errorcount
+
+ fireq = ("ascender", "copyright", "descender", "familyName", "openTypeNameManufacturer",
+ "styleName", "unitsPerEm", "versionMajor", "versionMinor")
+ fiwarnifmiss = ("capHeight", "copyright", "openTypeNameDescription", "openTypeNameDesigner",
+ "openTypeNameDesignerURL", "openTypeNameLicense", "openTypeNameLicenseURL",
+ "openTypeNameManufacturerURL", "openTypeOS2CodePageRanges",
+ "openTypeOS2UnicodeRanges", "openTypeOS2VendorID","styleMapFamilyName", "styleMapStyleName",
+ "openTypeOS2WeightClass", "openTypeOS2WinAscent", "openTypeOS2WinDescent")
+ fiwarnifnot = {"unitsPerEm": (1000, 2048),
+ "styleMapStyleName": ("regular", "bold", "italic", "bold italic")},
+ fiwarnifpresent = ("note",)
+ fidel = ("macintoshFONDFamilyID", "macintoshFONDName", "openTypeNameCompatibleFullName",
+ "openTypeGaspRangeRecords", "openTypeHeadFlags", "openTypeHheaCaretOffset",
+ "openTypeOS2FamilyClass", "postscriptForceBold", "postscriptIsFixedPitch",
+ "postscriptBlueFuzz", "postscriptBlueScale", "postscriptBlueShift", "postscriptWeightName",
+ "year")
+ fidelifempty = ("guidelines", "postscriptBlueValues", "postscriptFamilyBlues", "postscriptFamilyOtherBlues",
+ "postscriptOtherBlues")
+ fiint = ("ascender", "capHeight", "descender", "postscriptUnderlinePosition",
+ "postscriptUnderlineThickness", "unitsPerEm", "xHeight")
+ ficapitalize = ("styleMapFamilyName", "styleName")
+ fisetifmissing = {}
+ fisettoother = {"openTypeHheaAscender": "ascender", "openTypeHheaDescender": "descender",
+ "openTypeNamePreferredFamilyName": "familyName",
+ "openTypeNamePreferredSubfamilyName": "styleName", "openTypeOS2TypoAscender": "ascender",
+ "openTypeOS2TypoDescender": "descender"}
+ fisetto = {"openTypeHheaLineGap": 0, "openTypeOS2TypoLineGap": 0, "openTypeOS2WidthClass": 5,
+ "openTypeOS2Selection": [7], "openTypeOS2Type": []} # Other values are added below
+
+ libdel = ("com.fontlab.v2.tth", "com.typemytype.robofont.italicSlantOffset")
+ libsetto = {"com.schriftgestaltung.customParameter.GSFont.disablesAutomaticAlignment": True,
+ "com.schriftgestaltung.customParameter.GSFont.disablesLastChange": True}
+ libwarnifnot = {"com.schriftgestaltung.customParameter.GSFont.useNiceNames": False}
+ libwarnifmissing = ("public.glyphOrder",)
+
+ # fontinfo.plist checks
+ logger.log("Checking fontinfo.plist metadata", "P")
+
+ # Check required fields, some of which are needed for remaining checks
+ missing = []
+ for key in fireq:
+ if key not in self.fontinfo or self.fontinfo.getval(key) is None: missing.append(key)
+ # Collect values for constructing other fields, setting dummy values when missing and in check-only mode
+ dummies = False
+ storedvals = {}
+ for key in ("ascender", "copyright", "descender", "familyName", "styleName", "openTypeNameManufacturer", "versionMajor", "versionMinor"):
+ if key in self.fontinfo and self.fontinfo.getval(key) is not None:
+ storedvals[key] = self.fontinfo.getval(key)
+ if key == "styleName":
+ sn = storedvals[key]
+ sn = re.sub(r"(\w)(Italic)", r"\1 \2", sn) # Add a space before Italic if missing
+ # Capitalise first letter of words
+ sep = b' ' if type(sn) is bytes else ' '
+ sn = sep.join(s[:1].upper() + s[1:] for s in sn.split(sep))
+ if sn != storedvals[key]:
+ if self.metafix:
+ self.fontinfo.setval(key, "string", sn)
+ logmess = " updated "
+ else:
+ logmess = " would be updated "
+ self.logchange(logmess, key, storedvals[key], sn)
+ storedvals[key] = sn
+ if key in ("ascender", "descender"):
+ storedvals[key] = int(storedvals[key])
+ else:
+ dummies = True
+ if key in ("ascender", "descender", "versionMajor", "versionMinor"):
+ storedvals[key] = 999
+ else:
+ storedvals[key] = "Dummy"
+ if missing:
+ logtype = "S" if self.metafix else "W"
+ logger.log("Required fields missing from fontinfo.plist: " + str(missing), logtype)
+ if dummies:
+ logger.log("Checking will continue with values of 'Dummy' or 999 for missing fields", "W")
+ # Construct values for certain fields
+ value = storedvals["openTypeNameManufacturer"] + ": " + storedvals["familyName"] + " "
+ value = value + storedvals["styleName"] + ": " + datetime.datetime.now().strftime("%Y")
+ fisetto["openTypeNameUniqueID"] = value
+# fisetto["openTypeOS2WinDescent"] = -storedvals["descender"]
+ if "openTypeNameVersion" not in self.fontinfo:
+ fisetto["openTypeNameVersion"] = "Version " + str(storedvals["versionMajor"]) + "."\
+ + str(storedvals["versionMinor"])
+ if "openTypeOS2WeightClass" not in self.fontinfo:
+ sn = storedvals["styleName"]
+ sn2wc = {"Regular": 400, "Italic": 400, "Bold": 700, "BoldItalic": 700}
+ if sn in sn2wc: fisetto["openTypeOS2WeightClass"] = sn2wc[sn]
+ if "xHeight" not in self.fontinfo:
+ fisetto["xHeight"] = int(storedvals["ascender"] * 0.6)
+ if "openTypeOS2Selection" in self.fontinfo: # If already present, need to ensure bit 7 is set
+ fisetto["openTypeOS2Selection"] = sorted(list(set(self.fontinfo.getval("openTypeOS2Selection") + [7])))
+
+ for key in fisetifmissing:
+ if key not in self.fontinfo:
+ fisetto[key] = fisetifmissing[key]
+
+ changes = 0
+ # Warn about missing fields
+ for key in fiwarnifmiss:
+ if key not in self.fontinfo:
+ logmess = key + " is missing from fontinfo.plist"
+ if key in ("styleMapFamilyName", "styleMapStyleName") :
+ logmess = logmess + " (not needed for complex masters)"
+ logger.log(logmess, "W")
+ # Warn about bad values
+ for key in fiwarnifnot:
+ if key in self.fontinfo:
+ value = self.fontinfo.getval(key)
+ if value not in fiwarnifnot[key]:
+ logger.log(key + " should be one of " + str(fiwarnifnot[key]), "W")
+ # Warn about keys where use of discouraged
+ for key in fiwarnifpresent:
+ if key in self.fontinfo:
+ logger.log(key + " is present - it's use is discouraged")
+
+ # Now do all remaining checks - which will lead to values being changed
+ for key in fidel + fidelifempty:
+ if key in self.fontinfo:
+ old = self.fontinfo.getval(key)
+ if not(key in fidelifempty and old != []): # Delete except for non-empty fidelifempty
+ if self.metafix:
+ self.fontinfo.remove(key)
+ logmess = " removed from fontinfo. "
+ else:
+ logmess = " would be removed from fontinfo "
+ self.logchange(logmess, key, old, None)
+ changes += 1
+
+ # Set to integer values
+ for key in fiint:
+ if key in self.fontinfo:
+ old = self.fontinfo.getval(key)
+ if old != int(old):
+ new = int(old)
+ if self.metafix:
+ self.fontinfo.setval(key, "integer", new)
+ logmess = " updated "
+ else:
+ logmess = " would be updated "
+ self.logchange(logmess, key, old, new)
+ changes += 1
+ # Capitalize words
+ for key in ficapitalize:
+ if key in self.fontinfo:
+ old = self.fontinfo.getval(key)
+ sep = b' ' if type(old) is bytes else ' '
+ new = sep.join(s[:1].upper() + s[1:] for s in old.split(sep)) # Capitalise words
+ if new != old:
+ if self.metafix:
+ self.fontinfo.setval(key, "string", new)
+ logmess = " uppdated "
+ else:
+ logmess = " would be uppdated "
+ self.logchange(logmess, key, old, new)
+ changes += 1
+ # Set to specific values
+ for key in list(fisetto.keys()) + list(fisettoother.keys()):
+ if key in self.fontinfo:
+ old = self.fontinfo.getval(key)
+ logmess = " updated "
+ else:
+ old = None
+ logmess = " added "
+ if key in fisetto:
+ new = fisetto[key]
+ else:
+ new = storedvals[fisettoother[key]]
+ if new != old:
+ if self.metafix:
+ if isinstance(new, list): # Currently only integer arrays
+ array = ET.Element("array")
+ for val in new: # Only covers integer at present for openTypeOS2Selection
+ ET.SubElement(array, "integer").text = val
+ self.fontinfo.setelem(key, array)
+ else: # Does not cover real at present
+ valtype = "integer" if isinstance(new, int) else "string"
+ self.fontinfo.setval(key, valtype, new)
+ else:
+ logmess = " would be" + logmess
+ self.logchange(logmess, key, old, new)
+ changes += 1
+ # Specific checks
+ if "italicAngle" in self.fontinfo:
+ old = self.fontinfo.getval("italicAngle")
+ if old == 0: # Should be deleted if 0
+ logmess = " removed since it is 0 "
+ if self.metafix:
+ self.fontinfo.remove("italicAngle")
+ else:
+ logmess = " would be" + logmess
+ self.logchange(logmess, "italicAngle", old, None)
+ changes += 1
+ if "versionMajor" in self.fontinfo: # If missing, an error will already have been reported...
+ vm = self.fontinfo.getval("versionMajor")
+ if vm == 0: logger.log("versionMajor is 0", "W")
+
+ # lib.plist checks
+ if "lib" not in self.__dict__:
+ logger.log("lib.plist missing so not checked by check & fix routines", "E")
+ else:
+ logger.log("Checking lib.plist metadata", "P")
+
+ for key in libdel:
+ if key in self.lib:
+ old = self.lib.getval(key)
+ if self.metafix:
+ self.lib.remove(key)
+ logmess = " removed from lib.plist. "
+ else:
+ logmess = " would be removed from lib.plist "
+ self.logchange(logmess, key, old, None)
+ changes += 1
+
+ for key in libsetto:
+ if key in self.lib:
+ old = self.lib.getval(key)
+ logmess = " updated "
+ else:
+ old = None
+ logmess = " added "
+ new = libsetto[key]
+ if new != old:
+ if self.metafix:
+ # Currently just supports True. See fisetto for adding other types
+ if new == True:
+ self.lib.setelem(key, ET.fromstring("<true/>"))
+ else: # Does not cover real at present
+ logger.log("Invalid value type for libsetto", "X")
+ else:
+ logmess = " would be" + logmess
+ self.logchange(logmess, key, old, new)
+ changes += 1
+ for key in libwarnifnot:
+ value = self.lib.getval(key) if key in self.lib else None
+ if value != libwarnifnot[key]:
+ addmess = "; currently missing" if value is None else "; currently set to " + str(value)
+ logger.log(key + " should normally be " + str(libwarnifnot[key]) + addmess, "W")
+
+ for key in libwarnifmissing:
+ if key not in self.lib:
+ logger.log(key + " is missing from lib.plist", "W")
+
+ logmess = " deleted - obsolete key" if self.metafix else " would be deleted - obsolete key"
+ for key in obsoleteLibKeys: # For obsolete keys that have been added historically by some tools
+ if key in self.lib:
+ old = self.lib.getval(key)
+ if self.metafix: self.lib.remove(key)
+ self.logchange(logmess,key,old,None)
+ changes += 1
+
+ # Show check&fix summary
+ warnings = logger.warningcount - initwarnings - changes
+ errors = logger.errorcount - initerrors
+ if errors or warnings or changes:
+ changemess = ", Changes made: " if self.metafix else ", Changes to make: "
+ logger.log("Check & fix results:- Errors: " + str(errors) + changemess + str(changes) +
+ ", Other warnings: " + str(warnings), "P")
+ if logger.scrlevel not in "WIV": logger.log("See log file for details", "P")
+ if missing and not self.metafix:
+ logger.log("**** Since some required fields were missing, checkfix=fix would fail", "P")
+ else:
+ logger.log("Check & Fix ran cleanly", "P")
+
+ def _readPlist(self, filen):
+ if filen in self.dtree:
+ plist = Uplist(font=self, filen=filen)
+ self.dtree[filen].setinfo(read=True, fileObject=plist, fileType="xml")
+ return plist
+ else:
+ self.logger.log(filen + " does not exist", "S")
+
+ def write(self, outdir):
+ # Write UFO out to disk, based on values set in self.outparams
+ self.logger.log("Processing font for output", "P")
+ if not os.path.exists(outdir):
+ try:
+ os.mkdir(outdir)
+ except Exception as e:
+ print(e)
+ sys.exit(1)
+ if not os.path.isdir(outdir):
+ self.logger.log(outdir + " not a directory", "S")
+
+ # If output UFO already exists, need to open so only changed files are updated and redundant files deleted
+ if outdir == self.ufodir: # In special case of output and input being the same, simply copy the input font
+ odtree = UT.dirTree(outdir)
+ else:
+ if not os.path.exists(outdir): # If outdir does not exist, create it
+ try:
+ os.mkdir(outdir)
+ except Exception as e:
+ print(e)
+ sys.exit(1)
+ odtree = {}
+ else:
+ if not os.path.isdir(outdir): self.logger.log(outdir + " not a directory", "S")
+ dirlist = os.listdir(outdir)
+ if dirlist == []: # Outdir is empty
+ odtree = {}
+ else:
+ self.logger.log("Output UFO already exists - reading for comparison", "P")
+ odtree = UT.dirTree(outdir)
+ # Update version info etc
+ UFOversion = self.outparams["UFOversion"]
+ self.metainfo["formatVersion"][1].text = str(UFOversion)
+ self.metainfo["creator"][1].text = "org.sil.scripts.pysilfont"
+
+ # Set standard UFO files for output
+ dtree = self.dtree
+ setFileForOutput(dtree, "metainfo.plist", self.metainfo, "xml")
+ if "fontinfo" in self.__dict__: setFileForOutput(dtree, "fontinfo.plist", self.fontinfo, "xml")
+ if "groups" in self.__dict__: # With groups, sort by glyph name
+ for gname in list(self.groups):
+ group = self.groups.getval(gname)
+ elem = ET.Element("array")
+ for glyph in sorted(group):
+ ET.SubElement(elem, "string").text = glyph
+ self.groups.setelem(gname, elem)
+ setFileForOutput(dtree, "groups.plist", self.groups, "xml")
+ if "kerning" in self.__dict__: setFileForOutput(dtree, "kerning.plist", self.kerning, "xml")
+ if "lib" in self.__dict__: setFileForOutput(dtree, "lib.plist", self.lib, "xml")
+ if UFOversion == "3":
+ # Sort layer contents by layer name
+ lc = self.layercontents
+ lcindex = {lc[x][0].text: lc[x] for x in lc} # index on layer name
+ for (x, name) in enumerate(sorted(lcindex)):
+ lc.etree[0][x] = lcindex[name] # Replace array elements in new order
+ setFileForOutput(dtree, "layercontents.plist", self.layercontents, "xml")
+ if "features" in self.__dict__: setFileForOutput(dtree, "features.fea", self.features, "text")
+ # Set glyph layers for output
+ for layer in self.layers: layer.setForOutput()
+
+ # Write files to disk
+
+ self.logger.log("Writing font to " + outdir, "P")
+
+ changes = writeToDisk(dtree, outdir, self, odtree)
+ if changes: # Need to update openTypeHeadCreated if there have been any changes to the font
+ if "fontinfo" in self.__dict__:
+ self.fontinfo.setval("openTypeHeadCreated", "string",
+ datetime.datetime.now().strftime("%Y/%m/%d %H:%M:%S"))
+ self.fontinfo.outxmlstr="" # Need to reset since writeXMLobject has already run once
+ writeXMLobject(self.fontinfo, self.outparams, outdir, "fontinfo.plist", True, fobject=True)
+
+ def addfile(self, filetype): # Add empty plist file for optional files
+ if filetype not in ("fontinfo", "groups", "kerning", "lib"): self.logger.log("Invalid file type to add", "X")
+ if filetype in self.__dict__: self.logger.log("File already in font", "X")
+ obj = Uplist(font=self)
+ setattr(self, filetype, obj)
+ self.dtree[filetype + '.plist'] = UT.dirTreeItem(read=True, added=True, fileObject=obj, fileType="xml")
+ obj.etree = ET.fromstring("<plist>\n<dict/>\n</plist>")
+
+ def logchange(self, logmess, key, old, new):
+ oldstr = str(old) if len(str(old)) < 22 else str(old)[0:20] + "..."
+ newstr = str(new) if len(str(new)) < 22 else str(new)[0:20] + "..."
+ logmess = key + logmess
+ if old is None:
+ logmess = logmess + " New value: " + newstr
+ else:
+ if new is None:
+ logmess = logmess + " Old value: " + oldstr
+ else:
+ logmess = logmess + " Old value: " + oldstr + ", new value: " + newstr
+ self.logger.log(logmess, "W")
+ # Extra verbose logging
+ if len(str(old)) > 21:
+ self.logger.log("Full old value: " + str(old), "I")
+ if len(str(new)) > 21:
+ self.logger.log("Full new value: " + str(new), "I")
+ otype = "string" if isinstance(old, (bytes, str)) else type(old).__name__ # To produce consistent reporting
+ ntype = "string" if isinstance(new, (bytes, str)) else type(new).__name__ # with Python 2 & 3
+ self.logger.log("Types: Old - " + otype + ", New - " + ntype, "I")
+
+class Ulayer(_Ucontainer):
+ def __init__(self, layername, layerdir, font):
+ self._contents = collections.OrderedDict()
+ self.dtree = font.dtree.subTree(layerdir)
+ font.dtree[layerdir].read = True
+ self.layername = layername
+ self.layerdir = layerdir
+ self.font = font
+ fulldir = os.path.join(font.ufodir, layerdir)
+ self.contents = Uplist(font=font, dirn=fulldir, filen="contents.plist")
+ self.dtree["contents.plist"].setinfo(read=True, fileObject=self.contents, fileType="xml")
+
+ if font.UFOversion == "3":
+ if 'layerinfo.plist' in self.dtree:
+ self.layerinfo = Uplist(font=font, dirn=fulldir, filen="layerinfo.plist")
+ self.dtree["layerinfo.plist"].setinfo(read=True, fileObject=self.layerinfo, fileType="xml")
+
+ for glyphn in sorted(self.contents.keys()):
+ glifn = self.contents[glyphn][1].text
+ if glifn in self.dtree:
+ glyph = Uglif(layer=self, filen=glifn)
+ self._contents[glyphn] = glyph
+ self.dtree[glifn].setinfo(read=True, fileObject=glyph, fileType="xml")
+ if glyph.name != glyphn:
+ super(Uglif, glyph).__setattr__("name", glyphn) # Need to use super to bypass normal glyph renaming logic
+ self.font.logger.log("Glyph names in glif and contents.plist did not match for " + glyphn + "; corrected", "W")
+ else:
+ self.font.logger.log("Missing glif " + glifn + " in " + fulldir, "S")
+
+ def setForOutput(self):
+
+ UFOversion = self.font.outparams["UFOversion"]
+ convertg2f1 = True if UFOversion == "2" or self.font.outparams["format1Glifs"] else False
+ dtree = self.font.dtree.subTree(self.layerdir)
+ if self.font.outparams["renameGlifs"]: self.renameGlifs()
+
+ setFileForOutput(dtree, "contents.plist", self.contents, "xml")
+ if "layerinfo" in self.__dict__ and UFOversion == "3":
+ setFileForOutput(dtree, "layerinfo.plist", self.layerinfo, "xml")
+
+ for glyphn in self:
+ glyph = self._contents[glyphn]
+ if convertg2f1: glyph.convertToFormat1()
+ if glyph["advance"] is not None:
+ if glyph["advance"].width is None and glyph["advance"].height is None: glyph.remove("advance")
+ # Normalize so that, when both exist, components come before contour
+ outline = glyph["outline"]
+ if len(outline.components) > 0 and list(outline)[0] == "contour":
+ # Need to move components to the front...
+ contours = outline.contours
+ components = outline.components
+ oldcontours = list(contours) # Easiest way to 'move' components is to delete contours then append back at the end
+ for contour in oldcontours: outline.removeobject(contour, "contour")
+ for contour in oldcontours: outline.appendobject(contour, "contour")
+
+ setFileForOutput(dtree, glyph.filen, glyph, "xml")
+
+ def renameGlifs(self):
+ namelist = []
+ for glyphn in sorted(self.keys()):
+ glyph = self._contents[glyphn]
+ filename = makeFileName(glyphn, namelist)
+ namelist.append(filename.lower())
+ filename += ".glif"
+ if filename != glyph.filen:
+ self.renameGlif(glyphn, glyph, filename)
+
+ def renameGlif(self, glyphn, glyph, newname):
+ self.font.logger.log("Renaming glif for " + glyphn + " from " + glyph.filen + " to " + newname, "I")
+ self.dtree.removedfiles[glyph.filen] = newname # Track so original glif does not get reported as invalid
+ glyph.filen = newname
+ self.contents[glyphn][1].text = newname
+
+ def addGlyph(self, glyph):
+ glyphn = glyph.name
+ if glyphn in self._contents: self.font.logger.log(glyphn + " already in font", "X")
+ self._contents[glyphn] = glyph
+ # Set glif name
+ glifn = makeFileName(glyphn)
+ names = []
+ while glifn in self.contents: # need to check for duplicate glif names
+ names.append(glifn)
+ glifn = makeFileName(glyphn, names)
+ glifn += ".glif"
+ glyph.filen = glifn
+ # Add to contents.plist and dtree
+ self.contents.addval(glyphn, "string", glifn)
+ self.dtree[glifn] = UT.dirTreeItem(read=False, added=True, fileObject=glyph, fileType="xml")
+
+ def delGlyph(self, glyphn):
+ self.dtree.removedfiles[self[glyphn].filen] = "deleted" # Track so original glif does not get reported as invalid
+ del self._contents[glyphn]
+ self.contents.remove(glyphn)
+
+
+class Uplist(ETU.xmlitem, _plist):
+ def __init__(self, font=None, dirn=None, filen=None, parse=True):
+ if dirn is None and font: dirn = font.ufodir
+ logger = font.logger if font else silfont.core.loggerobj()
+ ETU.xmlitem.__init__(self, dirn, filen, parse, logger)
+ self.type = "plist"
+ self.font = font
+ self.outparams = None
+ if filen and dirn: self.populate_dict()
+
+ def populate_dict(self):
+ self._contents.clear() # Clear existing contents, if any
+ pl = self.etree[0]
+ if pl.tag == "dict":
+ for i in range(0, len(pl), 2):
+ key = pl[i].text
+ self._contents[key] = [pl[i], pl[i + 1]] # The two elements for the item
+ else: # Assume array of 2 element arrays (eg layercontents.plist)
+ for i in range(len(pl)):
+ self._contents[i] = pl[i]
+
+
+class Uglif(ETU.xmlitem):
+ # Unlike plists, glifs can have multiples of some sub-elements (eg anchors) so create lists for those
+
+ def __init__(self, layer, filen=None, parse=True, name=None, format=None):
+ dirn = os.path.join(layer.font.ufodir, layer.layerdir)
+ ETU.xmlitem.__init__(self, dirn, filen, parse, layer.font.logger) # Will read item from file if dirn and filen both present
+ self.type = "glif"
+ self.layer = layer
+ self.format = format if format else '2'
+ self.name = name
+ self.outparams = None
+ self.glifElemOrder = self.layer.font.outparams["glifElemOrder"]
+ # Set initial values for sub-objects
+ for elem in self.glifElemOrder:
+ if elem in _glifElemMulti:
+ self._contents[elem] = []
+ else:
+ self._contents[elem] = None
+ if self.etree is not None: self.process_etree()
+
+ def __setattr__(self, name, value):
+ if name == "name" and getattr(self, "name", None): # Existing glyph name is being changed
+ oname = self.name
+ if value in self.layer._contents: self.layer.font.logger.log(name + " already in font", "X")
+ # Update the _contents dictionary
+ del self.layer._contents[oname]
+ self.layer._contents[value] = self
+ # Set glif name
+ glifn = makeFileName(value)
+ names = []
+ while glifn in self.layer.contents: # need to check for duplicate glif names
+ names.append(glifn)
+ glifn = makeFileName(value, names)
+ glifn += ".glif"
+
+ # Update to contents.plist, filen and dtree
+ self.layer.contents.remove(oname)
+ self.layer.contents.addval(value, "string", glifn)
+ self.layer.dtree.removedfiles[self.filen] = glifn # Track so original glif does not get reported as invalid
+ self.filen = glifn
+ self.layer.dtree[glifn] = UT.dirTreeItem(read=False, added=True, fileObject=self, fileType="xml")
+ super(Uglif, self).__setattr__(name, value)
+
+ def process_etree(self):
+ et = self.etree
+ self.name = getattrib(et, "name")
+ self.format = getattrib(et, "format")
+ if self.format is None:
+ if self.layer.font.UFOversion == "3":
+ self.format = '2'
+ else:
+ self.format = '1'
+ for i in range(len(et)):
+ element = et[i]
+ tag = element.tag
+ if not tag in self.glifElemOrder: self.layer.font.logger.log(
+ "Invalid element " + tag + " in glif " + self.name, "E")
+ if tag in _glifElemF1 or self.format == '2':
+ if tag in _glifElemMulti:
+ self._contents[tag].append(self.makeObject(tag, element))
+ else:
+ self._contents[tag] = self.makeObject(tag, element)
+
+ # Convert UFO2 style anchors to UFO3 anchors
+ if self._contents['outline'] is not None and self.format == "1":
+ for contour in self._contents['outline'].contours[:]:
+ if contour.UFO2anchor:
+ del contour.UFO2anchor["type"] # remove type="move"
+ self.add('anchor', contour.UFO2anchor)
+ self._contents['outline'].removeobject(contour, "contour")
+ if self._contents['outline'] is None: self.add('outline')
+
+ self.format = "2"
+
+ def rebuildET(self):
+ self.etree = ET.Element("glyph")
+ et = self.etree
+ et.attrib["name"] = self.name
+ et.attrib["format"] = self.format
+ # Insert sub-elements
+ for elem in self.glifElemOrder:
+ if elem in _glifElemF1 or self.format == "2": # Check element is valid for glif format
+ item = self._contents[elem]
+ if item is not None:
+ if elem in _glifElemMulti:
+ for object in item:
+ et.append(object.element)
+ else:
+ et.append(item.element)
+
+ def add(self, ename, attrib=None):
+ # Add an element and corresponding object to a glif
+ element = ET.Element(ename)
+ if attrib: element.attrib = attrib
+ if ename == "lib": ET.SubElement(element, "dict")
+ multi = True if ename in _glifElemMulti else False
+
+ if multi and ename not in self._contents:
+ self._contents[ename] = []
+
+ # Check element does not already exist for single elements
+ if ename in self._contents and not multi:
+ if self._contents[ename] is not None: self.layer.font.logger.log("Already an " + ename + " in glif", "X")
+
+ # Add new object
+ if multi:
+ self._contents[ename].append(self.makeObject(ename, element))
+ else:
+ self._contents[ename] = self.makeObject(ename, element)
+
+ def remove(self, ename, index=None, object=None):
+ # Remove object from a glif
+ # For multi objects, an index or object must be supplied to identify which
+ # to delete
+ if ename in _glifElemMulti:
+ item = self._contents[ename]
+ if index is None: index = item.index(object)
+ del item[index]
+ else:
+ self._contents[ename] = None
+
+ def convertToFormat1(self):
+ # Convert to a glif format of 1 (for UFO2) prior to writing out
+ self.format = "1"
+ # Change anchors to UFO2 style anchors. Sort anchors by anchor name first
+ anchororder = sorted(self._contents['anchor'], key=lambda x: x.element.attrib['name'])
+ for anchor in anchororder:
+ element = anchor.element
+ for attrn in ('colour', 'indentifier'): # Remove format 2 attributes
+ if attrn in element.attrib: del element.attrib[attrn]
+ element.attrib['type'] = 'move'
+ contelement = ET.Element("contour")
+ contelement.append(ET.Element("point", element.attrib))
+ self._contents['outline'].appendobject(Ucontour(self._contents['outline'], contelement), "contour")
+ self.remove('anchor', object=anchor)
+
+ def makeObject(self, type, element):
+ if type == 'advance': return Uadvance(self, element)
+ if type == 'unicode': return Uunicode(self, element)
+ if type == 'outline': return Uoutline(self, element)
+ if type == 'lib': return Ulib(self, element)
+ if type == 'note': return Unote(self, element)
+ if type == 'image': return Uimage(self, element)
+ if type == 'guideline': return Uguideline(self, element)
+ if type == 'anchor': return Uanchor(self, element)
+
+
+class Uadvance(Uelement):
+ def __init__(self, glif, element):
+ super(Uadvance, self).__init__(element)
+ self.glif = glif
+ if 'width' in element.attrib:
+ self.width = element.attrib[str('width')]
+ else:
+ self.width = None
+ if 'height' in element.attrib:
+ self.height = element.attrib[str('height')]
+ else:
+ self.height = None
+
+ def __setattr__(self, name, value):
+ if name in ('width', 'height'):
+ if value == "0" : value = None
+ if value is None:
+ if name in self.element.attrib: del self.element.attrib[name]
+ else:
+ value = str(value)
+ self.element.attrib[name] = value
+ super(Uadvance, self).__setattr__(name, value)
+
+class Uunicode(Uelement):
+ def __init__(self, glif, element):
+ super(Uunicode, self).__init__(element)
+ self.glif = glif
+ if 'hex' in element.attrib:
+ self.hex = element.attrib['hex']
+ else:
+ self.hex = ""
+ self.glif.logger.log("No unicode hex attribute for " + glif.name, "E")
+
+ def __setattr__(self, name, value):
+ if name == "hex": self.element.attrib['hex'] = value
+ super(Uunicode, self).__setattr__(name, value)
+
+
+class Unote(Uelement):
+ def __init__(self, glif, element):
+ self.glif = glif
+ super(Unote, self).__init__(element)
+
+
+class Uimage(Uelement):
+ def __init__(self, glif, element):
+ self.glif = glif
+ super(Uimage, self).__init__(element)
+
+
+class Uguideline(Uelement):
+ def __init__(self, glif, element):
+ self.glif = glif
+ super(Uguideline, self).__init__(element)
+
+
+class Uanchor(Uelement):
+ def __init__(self, glif, element):
+ self.glif = glif
+ super(Uanchor, self).__init__(element)
+
+
+class Uoutline(Uelement):
+ def __init__(self, glif, element):
+ super(Uoutline, self).__init__(element)
+ self.glif = glif
+ self.components = []
+ self.contours = []
+ for tag in self._contents:
+ if tag == "component":
+ for component in self._contents[tag]:
+ self.components.append(Ucomponent(self, component))
+ if tag == "contour":
+ for contour in self._contents[tag]:
+ self.contours.append(Ucontour(self, contour))
+
+ def removeobject(self, obj, typ):
+ super(Uoutline, self).remove(obj.element)
+ if typ == "component": self.components.remove(obj)
+ if typ == "contour": self.contours.remove(obj)
+
+ def replaceobject(self, oldobj, newobj, typ):
+ eindex = list(self.element).index(oldobj.element)
+ super(Uoutline, self).replace(eindex, newobj.element)
+ if typ == "component":
+ cindex = self.components.index(oldobj)
+ self.components[cindex]= newobj
+ if typ == "contour":
+ cindex = self.contours.index(oldobj)
+ self.contours[cindex]= newobj
+
+ def appendobject(self, item, typ): # Item can be an contour/component object, element or attribute list
+ if isinstance(item, (Ucontour, Ucomponent)):
+ obj = item
+ else:
+ if isinstance(item, dict):
+ elem = ET.Element(typ)
+ elem.attrib = item
+ elif isinstance(item, ET.Element):
+ elem = item
+ else:
+ self.glif.logger.log("item should be dict, element, Ucontour or Ucomponent", "S")
+ if typ == 'component':
+ obj = Ucomponent(self,elem)
+ else:
+ obj = Ucontour(self,elem)
+ super(Uoutline, self).append(obj.element)
+ if typ == "component": self.components.append(obj)
+ if typ == "contour": self.contours.append(obj)
+
+ def insertobject(self, index, item, typ): # Needs updating to match appendobject
+ self.glif.logger.log("insertobject currently buggy so don't use!", "X")
+ # Bug is that index for super... should be different than components/contours.
+ # need to think through logic to sort this out...
+ # May need to take some logic from appendobject and some from replaceobj
+
+ #super(Uoutline, self).insert(index, obj.element)
+ #if typ == "component": self.components.insert(index, obj)
+ #if typ == "contour": self.contours.insert(index, obj)
+
+
+class Ucomponent(Uelement):
+ def __init__(self, outline, element):
+ super(Ucomponent, self).__init__(element)
+ self.outline = outline
+
+
+class Ucontour(Uelement):
+ def __init__(self, outline, element):
+ super(Ucontour, self).__init__(element)
+ self.outline = outline
+ self.UFO2anchor = None
+ points = self._contents['point']
+ # Identify UFO2-style anchor points
+ if len(points) == 1 and "type" in points[0].attrib:
+ if points[0].attrib["type"] == "move":
+ if "name" in points[0].attrib:
+ self.UFO2anchor = points[0].attrib
+ else:
+ self.outline.glif.layer.font.logger.log(
+ "Glyph " + self.outline.glif.name + " contains a single-point contour with no anchor name", "E")
+
+
+class Ulib(_Ucontainer, _plist):
+ # For glif lib elements; top-level lib files use Uplist
+ def __init__(self, glif, element):
+ self.glif = glif
+ self.element = element # needs both element and etree for compatibility
+ self.etree = element # with other glif components and _plist methods
+ self._contents = {}
+ self.reindex()
+
+ def reindex(self):
+ self._contents.clear() # Clear existing contents, if any
+ pl = self.element[0]
+ if pl.tag == "dict":
+ for i in range(0, len(pl), 2):
+ key = pl[i].text
+ self._contents[key] = [pl[i], pl[i + 1]] # The two elements for the item
+
+
+class UfeatureFile(UtextFile):
+ def __init__(self, font, dirn, filen):
+ super(UfeatureFile, self).__init__(font, dirn, filen)
+
+
+def writeXMLobject(dtreeitem, params, dirn, filen, exists, fobject=False):
+ object = dtreeitem if fobject else dtreeitem.fileObject # Set fobject to True if a file object is passed ratehr than dtreeitem
+ if object.outparams: params = object.outparams # override default params with object-specific ones
+ indentFirst = params["indentFirst"]
+ attribOrder = {}
+ if object.type in params['attribOrders']: attribOrder = params['attribOrders'][object.type]
+ if object.type == "plist":
+ indentFirst = params["plistIndentFirst"]
+ object.etree.attrib[".doctype"] = 'plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"'
+
+ # Format ET data if any data parameters are set
+ if params["sortDicts"] or params["precision"] is not None: normETdata(object.etree, params, type=object.type)
+
+ etw = ETU.ETWriter(object.etree, attributeOrder=attribOrder, indentIncr=params["indentIncr"],
+ indentFirst=indentFirst, indentML=params["indentML"], precision=params["precision"],
+ floatAttribs=params["floatAttribs"], intAttribs=params["intAttribs"])
+ object.outxmlstr=etw.serialize_xml()
+ # Now we have the output xml, need to compare with existing item's xml, if present
+ changed = True
+
+ if exists: # File already on disk
+ if exists == "same": # Output and input locations the same
+ oxmlstr = object.inxmlstr
+ else: # Read existing XML from disk
+ oxmlstr = ""
+ try:
+ oxml = io.open(os.path.join(dirn, filen), "r", encoding="utf-8")
+ except Exception as e:
+ print(e)
+ sys.exit(1)
+ for line in oxml.readlines():
+ oxmlstr += line
+ oxml.close()
+ with warnings.catch_warnings():
+ warnings.simplefilter("ignore", UnicodeWarning)
+ if oxmlstr == object.outxmlstr: changed = False
+
+ if changed: object.write_to_file(dirn, filen)
+ if not fobject: dtreeitem.written = True # Mark as True, even if not changed - the file should still be there!
+ return changed # Boolean to indicate file updated on disk
+
+
+def setFileForOutput(dtree, filen, fileObject, fileType): # Put details in dtree, creating item if needed
+ if filen not in dtree:
+ dtree[filen] = UT.dirTreeItem()
+ dtree[filen].added = True
+ dtree[filen].setinfo(fileObject=fileObject, fileType=fileType, towrite=True)
+
+
+def writeToDisk(dtree, outdir, font, odtree=None, logindent="", changes = False):
+ if odtree is None: odtree = {}
+ # Make lists of items in dtree and odtree with type prepended for sorting and comparison purposes
+ dtreelist = []
+ for filen in dtree: dtreelist.append(dtree[filen].type + filen)
+ dtreelist.sort()
+ odtreelist = []
+ if odtree == {}:
+ locationtype = "Empty"
+ else:
+ if outdir == font.ufodir:
+ locationtype = "Same"
+ else:
+ locationtype = "Different"
+ for filen in odtree: odtreelist.append(odtree[filen].type + filen)
+ odtreelist.sort()
+
+ okey = odtreelist.pop(0) if odtreelist != [] else None
+
+ for key in dtreelist:
+ type = key[0:1]
+ filen = key[1:]
+ dtreeitem = dtree[filen]
+
+ while okey and okey < key: # Item in output UFO no longer needed
+ ofilen = okey[1:]
+ if okey[0:1] == "f":
+ logmess = 'Deleting ' + ofilen + ' from existing output UFO'
+ os.remove(os.path.join(outdir, ofilen))
+ else:
+ logmess = 'Deleting directory ' + ofilen + ' from existing output UFO'
+ shutil.rmtree(os.path.join(outdir, ofilen))
+ if ofilen not in dtree.removedfiles: font.logger.log(logmess, "W") # No need to log for remaned files
+ okey = odtreelist.pop(0) if odtreelist != [] else None
+
+ if key == okey:
+ exists = locationtype
+ okey = odtreelist.pop(0) if odtreelist != [] else None # Ready for next loop
+ else:
+ exists = False
+
+ if dtreeitem.type == "f":
+ if dtreeitem.towrite:
+ font.logger.log(logindent + filen, "V")
+ if dtreeitem.fileType == "xml":
+ if dtreeitem.fileObject: # Only write if object has items
+ if dtreeitem.fileObject.type == "glif":
+ glif = dtreeitem.fileObject
+ if glif["lib"] is not None: # Delete lib if no items in it
+ if glif["lib"].__len__() == 0:
+ glif.remove("lib")
+ # Sort UFO3 anchors by name (UFO2 anchors will have been sorted on conversion)
+ glif["anchor"].sort(key=lambda anchor: anchor.element.get("name"))
+ glif.rebuildET()
+ result = writeXMLobject(dtreeitem, font.outparams, outdir, filen, exists)
+ if result: changes = True
+ else: # Delete existing item if the current object is empty
+ if exists:
+ font.logger.log('Deleting empty item ' + filen + ' from existing output UFO', "I")
+ os.remove(os.path.join(outdir, filen))
+ changes = True
+ elif dtreeitem.fileType == "text":
+ dtreeitem.fileObject.write(dtreeitem, outdir, filen, exists)
+ ## Need to add code for other file types
+ else:
+ if filen in dtree.removedfiles:
+ if exists:
+ os.remove(os.path.join(outdir, filen)) # Silently remove old file for renamed files
+ changes = True
+ exists = False
+ else: # File should not have been in original UFO
+ if exists == "same":
+ font.logger.log('Deleting ' + filen + ' from existing UFO', "W")
+ os.remove(os.path.join(outdir, filen))
+ changes = True
+ exists = False
+ else:
+ if not dtreeitem.added:
+ font.logger.log('Skipping invalid file ' + filen + ' from input UFO', "W")
+ if exists:
+ font.logger.log('Deleting ' + filen + ' from existing output UFO', "W")
+ os.remove(os.path.join(outdir, filen))
+ changes = True
+
+ else: # Must be directory
+ if not dtreeitem.read:
+ font.logger.log(logindent + "Skipping invalid input directory " + filen, "W")
+ if exists:
+ font.logger.log('Deleting directory ' + filen + ' from existing output UFO', "W")
+ shutil.rmtree(os.path.join(outdir, filen))
+ changes = True
+ continue
+ font.logger.log(logindent + "Processing " + filen + " directory", "I")
+ subdir = os.path.join(outdir, filen)
+ if isinstance(dtreeitem.fileObject, Udirectory):
+ dtreeitem.fileObject.write(dtreeitem, outdir)
+ else:
+ if not os.path.exists(subdir): # If outdir does not exist, create it
+ try:
+ os.mkdir(subdir)
+ except Exception as e:
+ print(e)
+ sys.exit(1)
+ changes = True
+
+ if exists:
+ subodtree = odtree[filen].dirtree
+ else:
+ subodtree = {}
+ subindent = logindent + " "
+ changes = writeToDisk(dtreeitem.dirtree, subdir, font, subodtree, subindent, changes)
+ if os.listdir(subdir) == []:
+ os.rmdir(subdir) # Delete directory if empty
+ changes = True
+
+ while okey: # Any remaining items in odree list are no longer needed
+ ofilen = okey[1:]
+ if okey[0:1] == "f":
+ logmess = 'Deleting ' + ofilen + ' from existing output UFO'
+ os.remove(os.path.join(outdir, ofilen))
+ changes = True
+ else:
+ logmess = 'Deleting directory ' + ofilen + ' from existing output UFO', "W"
+ shutil.rmtree(os.path.join(outdir, ofilen))
+ changes = True
+ if ofilen not in dtree.removedfiles: font.logger.log(logmess, "W") # No need to log warning for removed files
+ okey = odtreelist.pop(0) if odtreelist != [] else None
+ return changes
+
+def normETdata(element, params, type):
+ # Recursively normalise the data an an ElementTree element
+ for subelem in element:
+ normETdata(subelem, params, type)
+
+ precision = params["precision"]
+ if precision is not None:
+ if element.tag in ("integer", "real"):
+ num = round(float(element.text), precision)
+ if num == int(num):
+ element.tag = "integer"
+ element.text = "{}".format(int(num))
+ else:
+ element.tag = "real"
+ element.text = "{}".format(num)
+
+ if params["sortDicts"] and element.tag == "dict":
+ edict = {}
+ elist = []
+ for i in range(0, len(element), 2):
+ edict[element[i].text] = [element[i], element[i + 1]]
+ elist.append(element[i].text)
+ keylist = sorted(edict.keys())
+ if elist != keylist:
+ i = 0
+ for key in keylist:
+ element[i] = edict[key][0]
+ element[i + 1] = edict[key][1]
+ i = i + 2
+
+
+def getattrib(element, attrib): return element.attrib[attrib] if attrib in element.attrib else None
+
+
+def makeFileName(name, namelist=None):
+ if namelist is None: namelist = []
+ # Replace illegal characters and add _ after UC letters
+ newname = ""
+ for x in name:
+ if x in _illegalChars:
+ x = "_"
+ else:
+ if x != x.lower(): x += "_"
+ newname += x
+ # Replace initial . if present
+ if newname[0] == ".": newname = "_" + newname[1:]
+ parts = []
+ for part in newname.split("."):
+ if part in _reservedNames:
+ part = "_" + part
+ parts.append(part)
+ name = ".".join(parts)
+ if name.lower() in namelist: # case-insensitive name already used, so add a suffix
+ newname = None
+ i = 1
+ while newname is None:
+ test = name + '{0:015d}'.format(i)
+ if not (test.lower() in namelist): newname = test
+ i += 1
+ name = newname
+ return name
diff --git a/lib/silfont/util.py b/lib/silfont/util.py
new file mode 100755
index 0000000..e8b020d
--- /dev/null
+++ b/lib/silfont/util.py
@@ -0,0 +1,374 @@
+#!/usr/bin/env python
+'General classes and functions for use in pysilfont scripts'
+__url__ = 'http://github.com/silnrsi/pysilfont'
+__copyright__ = 'Copyright (c) 2014 SIL International (http://www.sil.org)'
+__license__ = 'Released under the MIT License (http://opensource.org/licenses/MIT)'
+__author__ = 'David Raymond'
+
+import os, subprocess, difflib, sys, io
+from silfont.core import execute
+from pkg_resources import resource_filename
+from csv import reader as csvreader
+
+try:
+ from fontTools.ttLib import TTFont
+except Exception as e:
+ TTFont = None
+
+class dirTree(dict) :
+ """ An object to hold list of all files and directories in a directory
+ with option to read sub-directory contents into dirTree objects.
+ Iterates through readSub levels of subfolders
+ Flags to keep track of changes to files etc"""
+ def __init__(self,dirn,readSub = 9999) :
+ self.removedfiles = {} # List of files that have been renamed or deleted since reading from disk
+ for name in os.listdir(dirn) :
+ if name[-1:] == "~" : continue
+ item=dirTreeItem()
+ if os.path.isdir(os.path.join(dirn, name)) :
+ item.type = "d"
+ if readSub :
+ item.dirtree = dirTree(os.path.join(dirn,name),readSub-1)
+ self[name] = item
+
+ def subTree(self,path) : # Returns dirTree object for a subtree based on subfolder name(s)
+ # 'path' can be supplied as either a relative path (eg "subf/subsubf") or array (eg ['subf','subsubf']
+ if type(path) in (bytes, str): path = self._split(path)
+ subf=path[0]
+ if subf in self:
+ dtree = self[subf].dirtree
+ else : return None
+
+ if len(path) == 1 :
+ return dtree
+ else :
+ path.pop(0)
+ return dtree.subTree(path)
+
+ def _split(self,path) : # Turn a relative path into an array of subfolders
+ npath = [os.path.split(path)[1]]
+ while os.path.split(path)[0] :
+ path = os.path.split(path)[0]
+ npath.insert(0,os.path.split(path)[1])
+ return npath
+
+class dirTreeItem(object) :
+
+ def __init__(self, type = "f", dirtree = None, read = False, added = False, changed = False, towrite = False, written = False, fileObject = None, fileType = None, flags = {}) :
+ self.type = type # "d" or "f"
+ self.dirtree = dirtree # dirtree for a sub-directory
+ # Remaining properties are for calling scripts to use as they choose to track actions etc
+ self.read = read # Item has been read by the script
+ self.added = added # Item has been added to dirtree, so does not exist on disk
+ self.changed = changed # Item has been changed, so may need updating on disk
+ self.towrite = towrite # Item should be written out to disk
+ self.written = written # Item has been written to disk
+ self.fileObject = fileObject # An object representing the file
+ self.fileType = fileType # The type of the file object
+ self.flags = {} # Any other flags a script might need
+
+ def setinfo(self, read = None, added = None, changed = None, towrite = None, written = None, fileObject = None, fileType = None, flags = None) :
+ pass
+ if read : self.read = read
+ if added : self.added = added
+ if changed : self.changed = changed
+ if towrite: self.towrite = towrite
+ if written : self.written = written
+ if fileObject is not None : self.fileObject = fileObject
+ if fileType : self.fileType = fileType
+ if flags : self.flags = flags
+
+class ufo_diff(object): # For diffing 2 ufos as part of testing
+ # returncodes:
+ # 0 - ufos are the same
+ # 1 - Differences were found
+ # 2 - Errors running the difference (eg can't open file)
+ # diff - text of the differences
+ # errors - text of the errors
+
+ def __init__(self, ufo1, ufo2, ignoreOHCtime=True):
+
+ diffcommand = ["diff", "-r", "-c1", ufo1, ufo2]
+
+ # By default, if only difference in fontinfo is the openTypeHeadCreated timestamp ignore that
+
+ if ignoreOHCtime: # Exclude fontinfo if only diff is openTypeHeadCreated
+ # Otherwise leave it in so differences are reported by main diff
+ fi1 = os.path.join(ufo1,"fontinfo.plist")
+ fi2 = os.path.join(ufo2, "fontinfo.plist")
+ fitest = subprocess.Popen(["diff", fi1, fi2, "-c1"], stdout=subprocess.PIPE, stderr=subprocess.PIPE)
+ text = fitest.communicate()
+ if fitest.returncode == 1:
+ difftext = text[0].decode("utf-8").split("\n")
+ if difftext[4].strip() == "<key>openTypeHeadCreated</key>" and len(difftext) == 12:
+ diffcommand.append("--exclude=fontinfo.plist")
+
+ # Now do the main diff
+ test = subprocess.Popen(diffcommand, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
+ text = test.communicate()
+ self.returncode = test.returncode
+ self.diff = text[0].decode("utf-8")
+ self.errors = text[1]
+
+ def print_text(self): # Print diff info or errors from the diffcommand
+ if self.returncode == 0:
+ print("UFOs are the same")
+ elif self.returncode == 1:
+ print("UFOs are different")
+ print(self.diff)
+ elif self.returncode == 2:
+ print("Failed to compare UFOs")
+ print(self.errors)
+
+class text_diff(object): # For diffing 2 text files with option to ignore common timestamps
+ # See ufo_diff for class attribute details
+
+ def __init__(self, file1, file2, ignore_chars=0, ignore_firstlinechars = 0):
+ # ignore_chars - characters to ignore from left of each line; typically 20 for timestamps
+ # ignore_firstlinechars - as above, but just for first line, eg for initial comment in csv files, typically 22
+ errors = []
+ try:
+ f1 = [x[ignore_chars:-1].replace('\\','/') for x in io.open(file1, "r", encoding="utf-8").readlines()]
+ except IOError:
+ errors.append("Can't open " + file1)
+ try:
+ f2 = [x[ignore_chars:-1].replace('\\','/') for x in io.open(file2, "r", encoding="utf-8").readlines()]
+ except IOError:
+ errors.append("Can't open " + file2)
+ if errors == []: # Indicates both files were opened OK
+ if ignore_firstlinechars: # Ignore first line for files with first line comment with timestamp
+ f1[0] = f1[0][ignore_firstlinechars:-1]
+ f2[0] = f2[0][ignore_firstlinechars:-1]
+ self.errors = ""
+ self.diff = "\n".join([x for x in difflib.unified_diff(f1, f2, file1, file2, n=0)])
+ self.returncode = 0 if self.diff == "" else 1
+ else:
+ self.diff = ""
+ self.errors = "\n".join(errors)
+ self.returncode = 2
+
+ def print_text(self): # Print diff info or errors the unified_diff command
+ if self.returncode == 0:
+ print("Files are the same")
+ elif self.returncode == 1:
+ print("Files are different")
+ print(self.diff)
+ elif self.returncode == 2:
+ print("Failed to compare Files")
+ print(self.errors)
+
+class ttf_diff(object): # For diffing 2 ttf files. Differences are not listed
+ # See ufo_diff for class attribute details
+
+ def __init__(self, file1, file2):
+ errors=[]
+ if TTFont is None:
+ self.diff=""
+ self.errors="Testing failed - class ttf_diff requires fontTools to be installed"
+ self.returncode = 2
+ return
+
+ # Open the ttf files
+ try:
+ font1 = TTFont(file1)
+ except Exception as e:
+ errors.append("Can't open " + file1)
+ errors.append(e.__str__())
+ try:
+ font2 = TTFont(file2)
+ except Exception as e:
+ errors.append("Can't open " + file2)
+ errors.append(e.__str__())
+ if errors:
+ self.diff = ""
+ self.errors = "\n".join(errors)
+ self.returncode = 2
+ return
+
+ # Create ttx xml strings from each font
+ ttx1 = _ttx()
+ ttx2 = _ttx()
+ font1.saveXML(ttx1)
+ font2.saveXML(ttx2)
+
+ if ttx1.txt() == ttx2.txt():
+ self.diff = ""
+ self.errors = ""
+ self.returncode = 0
+ else:
+ self.diff = file1 + " and " + file2 + " are different - compare with external tools"
+ self.errors = ""
+ self.returncode = 1
+
+ def print_text(self): # Print diff info or errors the unified_diff command
+ if self.returncode == 0:
+ print("Files are the same")
+ elif self.returncode == 1:
+ print("Files are different")
+ print(self.diff)
+ elif self.returncode == 2:
+ print("Failed to compare Files")
+ print(self.errors)
+
+def test_run(tool, commandline, testcommand, outfont, exp_errors, exp_warnings): # Used by tests to run commands
+ sys.argv = commandline.split(" ")
+ (args, font) = execute(tool, testcommand.doit, testcommand.argspec, chain="first")
+ if outfont:
+ if tool in ("FT", "FP"):
+ font.save(outfont)
+ else: # Must be Pyslifont Ufont
+ font.write(outfont)
+ args.logger.logfile.close() # Need to close the log so that the diff test can be run
+ exp_counts = (exp_errors, exp_warnings)
+ actual_counts = (args.logger.errorcount, args.logger.warningcount)
+ result = exp_counts == actual_counts
+ if not result: print("Mis-match of logger errors/warnings: " + str(exp_counts) + " vs " + str(actual_counts))
+ return result
+
+def test_diffs(dirname, testname, extensions): # Used by test to run diffs on results files based on extensions
+ result = True
+ for ext in extensions:
+ resultfile = os.path.join("local/testresults", dirname, testname + ext)
+ referencefile = os.path.join("tests/reference", dirname, testname + ext)
+ if ext == ".ufo":
+ diff = ufo_diff(resultfile, referencefile)
+ elif ext == ".csv":
+ diff = text_diff(resultfile, referencefile, ignore_firstlinechars=22)
+ elif ext in (".log", ".lg"):
+ diff = text_diff(resultfile, referencefile, ignore_chars=20)
+ elif ext == ".ttf":
+ diff = ttf_diff(resultfile, referencefile)
+ else:
+ diff = text_diff(resultfile, referencefile)
+
+ if diff.returncode:
+ diff.print_text()
+ result = False
+ return result
+
+class _ttx(object): # Used by ttf_diff()
+
+ def __init__(self):
+ self.lines = []
+
+ def write(self, line):
+ if not("<checkSumAdjustment value=" in line or "<modified value=" in line) :
+ self.lines.append(line)
+
+ def txt(self):
+ return "".join(self.lines)
+
+# Functions for mapping color def to names based on the colors provided by app UIs
+namestocolorslist = {
+ 'g_red': '0.85,0.26,0.06,1', # g_ names refers to colors definable using the Glyphs UI
+ 'g_orange': '0.99,0.62,0.11,1',
+ 'g_brown': '0.65,0.48,0.2,1',
+ 'g_yellow': '0.97,1,0,1',
+ 'g_light_green': '0.67,0.95,0.38,1',
+ 'g_dark_green': '0.04,0.57,0.04,1',
+ 'g_cyan': '0,0.67,0.91,1',
+ 'g_blue': '0.18,0.16,0.78,1',
+ 'g_purple': '0.5,0.09,0.79,1',
+ 'g_pink': '0.98,0.36,0.67,1',
+ 'g_light_gray': '0.75,0.75,0.75,1',
+ 'g_dark_gray': '0.25,0.25,0.25,1'
+}
+colorstonameslist = {v: k for k, v in namestocolorslist.items()}
+
+def nametocolor(color, default=None):
+ global namestocolorslist
+ if default is not None:
+ return namestocolorslist.get(color,default)
+ else:
+ return namestocolorslist.get(color)
+
+def colortoname(color, default=None):
+ global colorstonameslist
+ if default:
+ return colorstonameslist.get(color,default)
+ else:
+ return colorstonameslist.get(color)
+
+def parsecolors(colors, single = False, allowspecial = False): # Process a list of colors - designed for handling command-line input
+ # Colors can be in RBGA format (eg (0.25,0.25,0.25,1)) or text name (eg g_dark_grey), spearated by commas.
+ # Function returns a list of tuples, one per color, (RGBA, name, logcolor, original color after splitting)
+ # If the color can't be parsed, RGBA will be None and logocolor contain an error message
+ # If single is set, just return one tuple rather than a list of tuples
+ # Also can allow for special values of 'none' and 'leave' if allowspecial set
+
+ # First tidy up the input string
+ cols = colors.lower().replace(" ", "")
+
+ if single: # If just one color, don't need to split the string and can allow for RGBA without brackets
+ splitcols = ["(" + cols + ")"] if cols[0] in ("0", "1") else [cols]
+ else:
+ # Since RGBA colors which have parentheses and then commas within them, so can't just split on commas so add @ signs for first split
+ cols = cols.replace(",(", "@(").replace("),", ")@").split("@")
+ splitcols = []
+ for color in cols:
+ if color[0] == "(":
+ splitcols.append(color)
+ else:
+ splitcols = splitcols + color.split(',')
+ parsed = []
+ for splitcol in splitcols:
+ if allowspecial and splitcol in ("none", "leave"):
+ RGBA = ""
+ name = splitcol
+ logcolor = splitcol
+ else:
+ errormess = ""
+ name = ""
+ RGBA = ""
+ if splitcol[0] == '(':
+ values = splitcol[1:-1].split(',') # Remove parentheses then split on commas
+ if len(values) != 4:
+ errormess = "RGBA colours must have 4 values"
+ else:
+ for i in (0, 1, 2, 3):
+ values[i] = float(values[i])
+ if values[i] < 0 or values[i] > 1: errormess = "RGBA values must be between 0 and 1"
+ if values[0] + values[1] + values[2] == 0: errormess = "At lease one RGB value must be non-zero"
+ if values[3] == 0: errormess = "With RGBA, A must not be zero"
+ if errormess == "":
+ for i in (0, 1, 2, 3):
+ v = values[i]
+ if v == int(v): v = int(v) # Convert integers to int type for correct formatting with str()
+ RGBA += str(v) + ","
+ RGBA = RGBA[0:-1] # Strip trialing comma
+ name = colortoname(RGBA, "")
+ else:
+ name = splitcol
+ RGBA = nametocolor(name)
+ if RGBA is None: errormess = "Invalid color name"
+ if errormess:
+ logcolor = "Invalid color: " + splitcol + " - " + errormess
+ RGBA = None
+ name = None
+ else:
+ logcolor = RGBA
+ if name: logcolor += " (" + name + ")"
+ parsed.append((RGBA, name, logcolor,splitcol))
+ if single: parsed = parsed[0]
+
+ return parsed
+
+# Provide dict of required characters which match the supplied list of sets - sets can be basic, rtl or sil
+def required_chars(sets="basic"):
+ if type(sets) == str: sets = (sets,) # Convert single string to a tuple
+ rcfile = open(resource_filename('silfont','data/required_chars.csv'))
+ rcreader = csvreader(rcfile)
+ next(rcreader) # Read fist line which is headers
+ rcdict = {}
+ for line in rcreader:
+ unicode = line[0][2:]
+ item = {
+ "ps_name": line[1],
+ "glyph_name": line[2],
+ "sil_set": line[3],
+ "rationale": line[4],
+ "notes": line[5]
+ }
+ if item["sil_set"] in sets: rcdict[unicode] = item
+ return rcdict
+
diff --git a/preflight/update-preflight-libs.sh b/preflight/update-preflight-libs.sh
new file mode 100755
index 0000000..80c7f91
--- /dev/null
+++ b/preflight/update-preflight-libs.sh
@@ -0,0 +1,28 @@
+#!/bin/sh
+# Update preflight libs
+
+# Copyright (c) 2022, SIL International (http://www.sil.org)
+# Released under the MIT License (http://opensource.org/licenses/MIT)
+# maintained by Nicolas Spalinger
+
+echo "Which python are we using? and from where?"
+type python3
+python3 --version
+
+echo "Installing/Updating pip"
+python3 -m pip install --upgrade pip
+
+echo "Populating/updating the preflight dependencies in user mode"
+
+python3 -m pip install -e git+https://github.com/silnrsi/pysilfont.git@master#egg=pysilfont git+https://github.com/googlefonts/GlyphsLib.git@main#egg=glyphsLib git+https://github.com/fonttools/ufoLib2.git@master#egg=ufoLib2 git+https://github.com/fonttools/fonttools.git@main#egg=fontTools git+https://github.com/typemytype/glyphConstruction.git@master#egg=glyphConstruction fs mutatorMath defcon fontMath --user
+
+echo ""
+echo "Please check these dependencies have been installed correctly: defcon, fontMath, fontTools, glyphConstruction, glyphsLib, MutatorMath, pysilfont and ufoLib2. Only these are currently needed for preflight."
+echo "make sure your PATH includes ~/Library/Python/3.10/bin where the scripts are installed"
+echo "add export PATH=\"\$PATH:\$HOME/Library/Python/3.10/bin\" to ~/.bash_profile or ~/.zshrc"
+
+echo ""
+type psfversion
+echo ""
+psfversion
+
diff --git a/pytest.ini b/pytest.ini
new file mode 100644
index 0000000..202c7c1
--- /dev/null
+++ b/pytest.ini
@@ -0,0 +1,3 @@
+[pytest]
+testpaths = tests
+filterwarnings = ignore::DeprecationWarning
diff --git a/setup.py b/setup.py
new file mode 100755
index 0000000..857853b
--- /dev/null
+++ b/setup.py
@@ -0,0 +1,69 @@
+#!/usr/bin/env python
+from __future__ import print_function
+'Setuptools installation file'
+__url__ = 'http://github.com/silnrsi/pysilfont'
+__copyright__ = 'Copyright (c) 2014 SIL International (http://www.sil.org)'
+__license__ = 'Released under the MIT License (http://opensource.org/licenses/MIT)'
+
+import sys, os, importlib
+
+try:
+ from setuptools import setup
+except ImportError :
+ print("pysilfont requires setuptools - see installation notes in README.md")
+ sys.exit(1)
+
+# Read version from __init__.py
+version = None
+here = os.path.abspath(os.path.dirname(__file__))
+init = open(os.path.join(here, "lib", "silfont", "__init__.py"), 'r')
+for line in init:
+ if line.startswith('__version__'):
+ version = line.split("'")[1]
+if version is None: sys.exit("Failed to read __version__ from init.py")
+
+if sys.version_info < (3,6): sys.exit('Sorry, Python < 3.6 is not supported')
+
+warnings = []
+if sys.argv[1] in ('develop', 'install') :
+ for m in ('Brotli', 'defcon', 'fontbakery','fontMath', 'fontParts', 'fontTools', 'glyphConstruction', 'glyphsLib', 'lxml', 'lz4', 'mutatorMath', 'palaso', 'odf', 'tabulate', 'ufo2ft', 'ufoLib2'):
+ try:
+ module = importlib.import_module(m)
+ except ImportError : warnings.append("- Some modules/scripts require the python %s package which is not currently installed" % m)
+
+long_description = "A growing collection of font utilities mainly written in Python designed to help with various aspects of font design and production.\n"
+long_description += "Developed and maintained by SIL International's by SIL International's WSTech department (formerly NRSI)."
+
+# Create entry_points console scripts entry
+cscripts = []
+for file in os.listdir("lib/silfont/scripts/") :
+ (base,ext) = os.path.splitext(file)
+ if ext == ".py" and base != "__init__" : cscripts.append(base + " = silfont.scripts." + base + ":cmd")
+
+setup(
+ name = 'pysilfont',
+ version = version,
+ description = 'Python-based font utilities collection',
+ long_description = long_description,
+ maintainer = 'SIL International',
+ maintainer_email = 'fonts@sil.org',
+ url = 'http://github.com/silnrsi/pysilfont',
+ packages = ["silfont", "silfont.scripts", "silfont.fbtests"],
+ package_dir = {'':'lib'},
+ package_data = {"silfont": ["data/*.*"]},
+ entry_points={'console_scripts': cscripts},
+ license = 'MIT',
+ platforms = ['Linux','Win32','Mac OS X'],
+ classifiers = [
+ "Environment :: Console",
+ "Programming Language :: Python :: 3.6",
+ "Intended Audience :: Developers",
+ "License :: OSI Approved :: MIT License",
+ "Topic :: Text Processing :: Fonts"
+ ],
+)
+
+if warnings :
+ print ("\n***** Warnings *****")
+ for warning in warnings : print(warning)
+
diff --git a/tests/fontparts/test_10_psfbuildcompgc.py b/tests/fontparts/test_10_psfbuildcompgc.py
new file mode 100644
index 0000000..ef8b17d
--- /dev/null
+++ b/tests/fontparts/test_10_psfbuildcompgc.py
@@ -0,0 +1,37 @@
+#!/usr/bin/env python
+''' Test of script named in testname below
+'''
+__url__ = 'http://github.com/silnrsi/pysilfont'
+__copyright__ = 'Copyright (c) 2018 SIL International (http://www.sil.org)'
+__license__ = 'Released under the MIT License (http://opensource.org/licenses/MIT)'
+__author__ = 'David Raymond'
+
+import silfont.util
+
+# Next 7 lines of code may be test-specific
+import silfont.scripts.psfbuildcompgc as testcommand
+testname = "psfbuildcompgc"
+cl = "psfbuildcompgc tests/input/font-psf-test/source/PsfTest-Regular.ufo -i tests/input/psfbuildcomp.txt -l local/testresults/fontparts/psfbuildcompgc.log"
+outfont = "local/testresults/fontparts/psfbuildcompgc.ufo" # Set to None for commands which don't output a font
+diffexts = [".ufo", ".log"] # List of extensions of all output files
+exp_errors = 0 # These may need updating if the test ufo is updated
+exp_warnings = 0 # The test ufo should have some errors/warnings to test the code!
+
+# Code after this can be the same for most/all tests; if needed to be different for a test remove this comment!
+
+def test_run():
+ result = silfont.util.test_run("FP", cl, testcommand, outfont, exp_errors, exp_warnings)
+ assert result
+
+def test_diffs(): # Do a diff on all output files
+ result = silfont.util.test_diffs("fontparts", testname, diffexts)
+ assert result
+
+if __name__ == "__main__":
+ test_run()
+ test_diffs()
+
+
+
+
+
diff --git a/tests/input/PsfTest-R.ttf b/tests/input/PsfTest-R.ttf
new file mode 100644
index 0000000..547fcd2
--- /dev/null
+++ b/tests/input/PsfTest-R.ttf
Binary files differ
diff --git a/tests/input/font-psf-test/FONTLOG.txt b/tests/input/font-psf-test/FONTLOG.txt
new file mode 100644
index 0000000..01ffd97
--- /dev/null
+++ b/tests/input/font-psf-test/FONTLOG.txt
@@ -0,0 +1,174 @@
+FONTLOG
+Psf Test
+==========================
+
+
+This file provides detailed information on the Psf Test family
+of fonts. This information should be distributed along with the Andika
+Mtihani fonts and any derivative works.
+
+Psf Test is a font family used only for testing the pysilfont framework.
+It is not intended to be an installable font family and doesn't even
+contain a complete Latin alphabet (Z and z are missing). The contents of
+these fonts are taken from Andika New Basic (https://scripts.sil.org/andika).
+
+For copyright and licensing information - including any Reserved Font
+Names - see OFL.txt.
+
+For practical information about using, modifying and redistributing this
+font see OFL-FAQ.txt.
+
+
+ChangeLog
+----------
+(This should list both major and minor changes, most recent first.)
+
+9 Aug 2018 (SIL NRSI team) Psf Test version 5.500
+- Reduced character set to only a useful subset and missing a few characters
+- Intended only as a test font for pysilfont
+
+20 Apr 2015 (SIL NRSI team) Andika New Basic version 5.500
+- Reduced character set to a "Basic" number of characters
+- Added Bold, Italic, and Bold-Italic faces
+- Improved design of U+0254/U+0186 and their .TopSerif alternates
+- Metrics of these alternates are now same as those of default glyphs
+- Added Capital J alternate for U+004A
+
+27 Oct 2014 (SIL NRSI team) Andika Regular version 5.000
+- Added Stylistic Sets to the font for OpenType support
+ of previously Graphite-only features
+- Added Character Variants to the font for OpenType support
+ of previously Graphite-only features
+- Added Serbian feature when Serbian language is turned on
+- Added hook D variant feature (for U+018A/U+0257)
+- Removed "Show deprecated PUA" feature
+- Removed "Romanian-style diacritics" feature
+ (because glyphs are now encoded)
+- Removed "Diacritic selection" feature
+- Added U+039E, U+03BC, U+03C6 and U+03C9 in the Greek and Coptic block
+- Added U+0528..U+052F in the Cyrillic Supplement block
+- Added U+2041 in the General Punctuation block
+- Added U+2095..U+209C in the Superscripts and Subscripts block
+- Added U+20B6..U+20BD in the Currency Symbols block
+- Added U+210C, U+2113, U+2117, U+212D, U+2135, U+214F in the
+ Letterlike Symbols block
+- Added U+2150..U+2152 and U+2189 in the Number Forms block
+- Added U+2226, U+2234..U+2235, U+2262, U+2282..U+2287 in the
+ Mathematical Operators block
+- Added U+2640, U+2642, U+266D, U+266F in the Miscellaneous Symbols block
+- Added U+27E8..U+27E9 in the Miscellaneous Mathematical Symbols-A block
+- Added U+2C7E..U+2C7F in the Latin Extended-C block
+- Added U+2C88 in the Coptic block
+- Added U+2E00..U+2E0D, U+2E3A..U+2E3B in the Supplemental
+ Punctuation block
+- Added U+A736..U+A73F, U+A742..U+A74D, U+A750..U+A787, U+A790..U+A7AD,
+ U+A7B0..U+A7B1, U+A7F7..U+A7FA in the Latin Extended-D block.
+ These were also added to relevant features.
+- Added U+A92E in the Kayah Li block (to support the Kayah Li language
+ when using the Roman script)
+- Added U+AB64..U+AB65 in the Latin Extended-E block
+- Added U+1D40C, U+1D504..U+1D505, U+1D50A, U+1D50E..U+1D50F, U+1D514,
+ U+1D516..U+1D517, U+1D519 in the Mathematical Alphanumeric Symbols block
+- Added PUA characters U+F26C (curl J) and U+F26D (left-hook b)
+- Characters in our PUA that were added to Unicode have had their
+ codepoints updated:
+ F1AD>A7F9, F266>A78E, F26B>A78D, F32C>0526, F32D>0527, F17B>1DFD, F209>2C70
+- These PUA characters were deprecated (now white on black glyphs):
+ U+F17B, U+F1AD, U+F209, U+F247, U+F248, U+F266, U+F26B, U+F32C, U+F32D
+- Deleted U+0149 as it is officially deprecated in Unicode
+- Added support for shorter macrons under narrow letters (i,l,r,t).
+ (This only works for Graphite or using precomposed characters in OpenType.)
+- Made it possible for saltillo characters (U+A78B and U+A78C) to "carry"
+ diacritics
+- Improved design of U+A722..U+A725 and U+A78D
+- Refactored all cedilla positioning
+- Removal of unneeded duplicate glyphs (because of improvements in smart
+ font code)
+- Bug fix in Graphite code to allow for simultaneous selection of Vietnamese
+ alternates and Small Caps
+- Bug fix in Graphite code to allow for simultaneous selection of Ogonek
+ alternates and Small Caps
+- Version number bumped up to match other SIL Roman fonts
+- Optimized Graphite code for faster processing of plain ASCII text
+- Subscript and Superscript parentheses, minus, plus and equals were raised.
+ Metrics were not changed.
+- Modified U+0452 to have a descender
+- Changed postscript names for U+0218 and U+0219
+- Changed postscript names for U+2203, U+232A and U+2329
+- Changed design of U+A728 to use lowercase ezh form
+- Added space to right of U+201E to make it equal to that of U+201A
+- Made U+005C Reverse Solidus an actual reverse of U+002F Solidus
+- "Hide tone contour staves" feature now works with single tonebar
+- Changed U+1D44 and U+0250 to be double-story rather than single-story
+- Allowed combining marks to render properly with U+02D0
+
+1 Aug 2012 (SIL NRSI team) Andika Regular version 1.004
+- Changed Graphite feature identifiers from integers to 4-character
+ alphanumeric tags (no other changes)
+
+12 Sep 2011 (SIL NRSI team) Andika Regular version 1.002
+- Removed the VDMX table and changed the version number.
+
+8 Jul 2011 (SIL NRSI team) Andika Regular version 1.000
+- Released under SIL Open Font License.
+
+2 May 2008 (SIL NRSI team) Andika Basic Regular version 1.0
+- Released under SIL Open Font License.
+
+19 Jan 2007 (SIL NRSI team) Andika Design Review version 0.001
+- Released under Open Font License. Five new fonts containing
+ revisions of some glyphs and different combinations of others.
+
+7 Aug 2006 (SIL NRSI team) Andika Design Review version 0.001
+- Released under Open Font License.
+
+
+Acknowledgements
+-----------------
+(Here is where contributors can be acknowledged. If you make modifications
+be sure to add your name (N), email (E), web-address (W) and description (D).
+This list is sorted by last name in alphabetical order.)
+
+N: Don Collingsworth
+E: http://scripts.sil.org/support
+W: http://scripts.sil.org/
+D: Contributed some extended Latin glyphs
+
+N: Victor Gaultney
+E: http://scripts.sil.org/support
+W: http://www.sil.org/~gaultney/
+D: Original Designer
+
+N: Eric Hays
+E: http://scripts.sil.org/support
+W: http://scripts.sil.org/
+D: Contributed some extended Latin glyphs
+
+N: Annie Olsen
+E: http://scripts.sil.org/support
+W: http://scripts.sil.org/
+D: Lead Designer
+
+N: Julie Remington
+E: http://scripts.sil.org/support
+W: http://scripts.sil.org/
+D: Contributed some extended Latin glyphs
+
+N: Pablo Ugerman
+W: http://www.ugrdesign.com.ar/
+D: Volunteer designer for much of Bold face
+
+N: SIL font engineers
+E: http://scripts.sil.org/support
+W: http://scripts.sil.org/
+D: Graphite, OpenType, and TypeTuner code, and build support
+
+
+The Andika, Andika Basic and Andika New Basic fonts are maintained by
+SIL International.
+
+For more information please visit the Andika page on SIL
+International's Computers and Writing Systems website:
+http://scripts.sil.org/andika
+
+Support through the website: http://scripts.sil.org/Support
diff --git a/tests/input/font-psf-test/OFL-FAQ.txt b/tests/input/font-psf-test/OFL-FAQ.txt
new file mode 100644
index 0000000..b7caf2b
--- /dev/null
+++ b/tests/input/font-psf-test/OFL-FAQ.txt
@@ -0,0 +1,427 @@
+OFL FAQ - Frequently Asked Questions about the SIL Open Font License (OFL)
+Version 1.1-update4 - Sept 2014
+(See http://scripts.sil.org/OFL for updates)
+
+
+CONTENTS OF THIS FAQ
+1 USING AND DISTRIBUTING FONTS LICENSED UNDER THE OFL
+2 USING OFL FONTS FOR WEB PAGES AND ONLINE WEB FONT SERVICES
+3 MODIFYING OFL-LICENSED FONTS
+4 LICENSING YOUR ORIGINAL FONTS UNDER THE OFL
+5 CHOOSING RESERVED FONT NAMES
+6 ABOUT THE FONTLOG
+7 MAKING CONTRIBUTIONS TO OFL PROJECTS
+8 ABOUT THE LICENSE ITSELF
+9 ABOUT SIL INTERNATIONAL
+APPENDIX A - FONTLOG EXAMPLE
+
+1 USING AND DISTRIBUTING FONTS LICENSED UNDER THE OFL
+
+1.1 Can I use the fonts for a book or other print publication, to create logos or other graphics or even to manufacture objects based on their outlines?
+Yes. You are very welcome to do so. Authors of fonts released under the OFL allow you to use their font software as such for any kind of design work. No additional license or permission is required, unlike with some other licenses. Some examples of these uses are: logos, posters, business cards, stationery, video titling, signage, t-shirts, personalised fabric, 3D-printed/laser-cut shapes, sculptures, rubber stamps, cookie cutters and lead type.
+
+1.1.1 Does that restrict the license or distribution of that artwork?
+No. You remain the author and copyright holder of that newly derived graphic or object. You are simply using an open font in the design process. It is only when you redistribute, bundle or modify the font itself that other conditions of the license have to be respected (see below for more details).
+
+1.1.2 Is any kind of acknowledgement required?
+No. Font authors may appreciate being mentioned in your artwork's acknowledgements alongside the name of the font, possibly with a link to their website, but that is not required.
+
+1.2 Can the fonts be included with Free/Libre and Open Source Software collections such as GNU/Linux and BSD distributions and repositories?
+Yes! Fonts licensed under the OFL can be freely included alongside other software under FLOSS (Free/Libre and Open Source Software) licenses. Since fonts are typically aggregated with, not merged into, existing software, there is little need to be concerned about incompatibility with existing software licenses. You may also repackage the fonts and the accompanying components in a .rpm or .deb package (or other similar package formats or installers) and include them in distribution CD/DVDs and online repositories. (Also see section 5.9 about rebuilding from source.)
+
+1.3 I want to distribute the fonts with my program. Does this mean my program also has to be Free/Libre and Open Source Software?
+No. Only the portions based on the Font Software are required to be released under the OFL. The intent of the license is to allow aggregation or bundling with software under restricted licensing as well.
+
+1.4 Can I sell a software package that includes these fonts?
+Yes, you can do this with both the Original Version and a Modified Version of the fonts. Examples of bundling made possible by the OFL would include: word processors, design and publishing applications, training and educational software, games and entertainment software, mobile device applications, etc.
+
+1.5 Can I include the fonts on a CD of freeware or commercial fonts?
+Yes, as long some other font or software is also on the disk, so the OFL font is not sold by itself.
+
+1.6 Why won't the OFL let me sell the fonts alone?
+The intent is to keep people from making money by simply redistributing the fonts. The only people who ought to profit directly from the fonts should be the original authors, and those authors have kindly given up potential direct income to distribute their fonts under the OFL. Please honour and respect their contribution!
+
+1.7 What about sharing OFL fonts with friends on a CD, DVD or USB stick?
+You are very welcome to share open fonts with friends, family and colleagues through removable media. Just remember to include the full font package, including any copyright notices and licensing information as available in OFL.txt. In the case where you sell the font, it has to come bundled with software.
+
+1.8 Can I host the fonts on a web site for others to use?
+Yes, as long as you make the full font package available. In most cases it may be best to point users to the main site that distributes the Original Version so they always get the most recent stable and complete version. See also discussion of web fonts in Section 2.
+
+1.9 Can I host the fonts on a server for use over our internal network?
+Yes. If the fonts are transferred from the server to the client computer by means that allow them to be used even if the computer is no longer attached to the network, the full package (copyright notices, licensing information, etc.) should be included.
+
+1.10 Does the full OFL license text always need to accompany the font?
+The only situation in which an OFL font can be distributed without the text of the OFL (either in a separate file or in font metadata), is when a font is embedded in a document or bundled within a program. In the case of metadata included within a font, it is legally sufficient to include only a link to the text of the OFL on http://scripts.sil.org/OFL, but we strongly recommend against this. Most modern font formats include metadata fields that will accept the full OFL text, and full inclusion increases the likelihood that users will understand and properly apply the license.
+
+1.11 What do you mean by 'embedding'? How does that differ from other means of distribution?
+By 'embedding' we mean inclusion of the font in a document or file in a way that makes extraction (and redistribution) difficult or clearly discouraged. In many cases the names of embedded fonts might also not be obvious to those reading the document, the font data format might be altered, and only a subset of the font - only the glyphs required for the text - might be included. Any other means of delivering a font to another person is considered 'distribution', and needs to be accompanied by any copyright notices and licensing information available in OFL.txt.
+
+1.12 So can I embed OFL fonts in my document?
+Yes, either in full or a subset. The restrictions regarding font modification and redistribution do not apply, as the font is not intended for use outside the document.
+
+1.13 Does embedding alter the license of the document itself?
+No. Referencing or embedding an OFL font in any document does not change the license of the document itself. The requirement for fonts to remain under the OFL does not apply to any document created using the fonts and their derivatives. Similarly, creating any kind of graphic using a font under OFL does not make the resulting artwork subject to the OFL.
+
+1.14 If OFL fonts are extracted from a document in which they are embedded (such as a PDF file), what can be done with them? Is this a risk to author(s)?
+The few utilities that can extract fonts embedded in a PDF will typically output limited amounts of outlines - not a complete font. To create a working font from this method is much more difficult and time consuming than finding the source of the original OFL font. So there is little chance that an OFL font would be extracted and redistributed inappropriately through this method. Even so, copyright laws address any misrepresentation of authorship. All Font Software released under the OFL and marked as such by the author(s) is intended to remain under this license regardless of the distribution method, and cannot be redistributed under any other license. We strongly discourage any font extraction - we recommend directly using the font sources instead - but if you extract font outlines from a document, please be considerate: respect the work of the author(s) and the licensing model.
+
+1.15 What about distributing fonts with a document? Within a compressed folder structure? Is it distribution, bundling or embedding?
+Certain document formats may allow the inclusion of an unmodified font within their file structure which may consist of a compressed folder containing the various resources forming the document (such as pictures and thumbnails). Including fonts within such a structure is understood as being different from embedding but rather similar to bundling (or mere aggregation) which the license explicitly allows. In this case the font is conveyed unchanged whereas embedding a font usually transforms it from the original format. The OFL does not allow anyone to extract the font from such a structure to then redistribute it under another license. The explicit permission to redistribute and embed does not cancel the requirement for the Font Software to remain under the license chosen by its author(s). Even if the font travels inside the document as one of its assets, it should not lose its authorship information and licensing.
+
+1.16 What about ebooks shipping with open fonts?
+The requirements differ depending on whether the fonts are linked, embedded or distributed (bundled or aggregated). Some ebook formats use web technologies to do font linking via @font-face, others are designed for font embedding, some use fonts distributed with the document or reading software, and a few rely solely on the fonts already present on the target system. The license requirements depend on the type of inclusion as discussed in 1.15.
+
+1.17 Can Font Software released under the OFL be subject to URL-based access restrictions methods or DRM (Digital Rights Management) mechanisms?
+Yes, but these issues are out-of-scope for the OFL. The license itself neither encourages their use nor prohibits them since such mechanisms are not implemented in the components of the Font Software but through external software. Such restrictions are put in place for many different purposes corresponding to various usage scenarios. One common example is to limit potentially dangerous cross-site scripting attacks. However, in the spirit of libre/open fonts and unrestricted writing systems, we strongly encourage open sharing and reuse of OFL fonts, and the establishment of an environment where such restrictions are unnecessary. Note that whether you wish to use such mechanisms or you prefer not to, you must still abide by the rules set forth by the OFL when using fonts released by their authors under this license. Derivative fonts must be licensed under the OFL, even if they are part of a service for which you charge fees and/or for which access to source code is restricted. You may not sell the fonts on their own - they must be part of a larger software package, bundle or subscription plan. For example, even if the OFL font is distributed in a software package or via an online service using a DRM mechanism, the user would still have the right to extract that font, use, study, modify and redistribute it under the OFL.
+
+1.18 I've come across a font released under the OFL. How can I easily get more information about the Original Version? How can I know where it stands compared to the Original Version or other Modified Versions?
+Consult the copyright statement(s) in the license for ways to contact the original authors. Consult the FONTLOG (see section 6 for more details and examples) for information on how the font differs from the Original Version, and get in touch with the various contributors via the information in the acknowledgement section. Please consider using the Original Versions of the fonts whenever possible.
+
+1.19 What do you mean in condition 4 of the OFL's permissions and conditions? Can you provide examples of abusive promotion / endorsement / advertisement vs. normal acknowledgement?
+The intent is that the goodwill and reputation of the author(s) should not be used in a way that makes it sound like the original author(s) endorse or approve of a specific Modified Version or software bundle. For example, it would not be right to advertise a word processor by naming the author(s) in a listing of software features, or to promote a Modified Version on a web site by saying "designed by ...". However, it would be appropriate to acknowledge the author(s) if your software package has a list of people who deserve thanks. We realize that this can seem to be a grey area, but the standard used to judge an acknowledgement is that if the acknowledgement benefits the author(s) it is allowed, but if it primarily benefits other parties, or could reflect poorly on the author(s), then it is not.
+
+1.20 I'm writing a small app for mobile platforms, do I need to include the whole package?
+If you bundle a font under the OFL with your mobile app you must comply with the terms of the license. At a minimum you must include the copyright statement, the license notice and the license text. A mention of this information in your About box or Changelog, with a link to where the font package is from, is good practice, and the extra space needed to carry these items is very small. You do not, however, need to include the full contents of the font package - only the fonts you use and the copyright and license that apply to them. For example, if you only use the regular weight in your app, you do not need to include the italic and bold versions.
+
+1.21 What about including OFL fonts by default in my firmware or dedicated operating system?
+Many such systems are restricted and turned into appliances so that users cannot study or modify them. Using open fonts to increase quality and language coverage is a great idea, but you need to be aware that if there is a way for users to extract fonts you cannot legally prevent them from doing that. The fonts themselves, including any changes you make to them, must be distributed under the OFL even if your firmware has a more restrictive license. If you do transform the fonts and change their formats when you include them in your firmware you must respect any names reserved by the font authors via the RFN mechanism and pick your own font name. Alternatively if you directly add a font under the OFL to the font folder of your firmware without modifying or optimizing it you are simply bundling the font like with any other software collection, and do not need to make any further changes.
+
+1.22 Can I make and publish CMS themes or templates that use OFL fonts? Can I include the fonts themselves in the themes or templates? Can I sell the whole package?
+Yes, you are very welcome to integrate open fonts into themes and templates for your preferred CMS and make them more widely available. Remember that you can only sell the fonts and your CMS add-on as part of a software bundle. (See 1.4 for details and examples about selling bundles).
+
+1.23 Can OFL fonts be included in services that deliver fonts to the desktop from remote repositories? Even if they contain both OFL and non-OFL fonts?
+Yes. Some foundries have set up services to deliver fonts to subscribers directly to desktops from their online repositories; similarly, plugins are available to preview and use fonts directly in your design tool or publishing suite. These services may mix open and restricted fonts in the same channel, however they should make a clear distinction between them to users. These services should also not hinder users (such as through DRM or obfuscation mechanisms) from extracting and using the OFL fonts in other environments, or continuing to use OFL fonts after subscription terms have ended, as those uses are specifically allowed by the OFL.
+
+1.24 Can services that provide or distribute OFL fonts restrict my use of them?
+No. The terms of use of such services cannot replace or restrict the terms of the OFL, as that would be the same as distributing the fonts under a different license, which is not allowed. You are still entitled to use, modify and redistribute them as the original authors have intended outside of the sole control of that particular distribution channel. Note, however, that the fonts provided by these services may differ from the Original Versions.
+
+
+2 USING OFL FONTS FOR WEBPAGES AND ONLINE WEB FONT SERVICES
+
+NOTE: This section often refers to a separate paper on 'Web Fonts & RFNs'. This is available at http://scripts.sil.org/OFL_web_fonts_and_RFNs
+
+2.1 Can I make webpages using these fonts?
+Yes! Go ahead! Using CSS (Cascading Style Sheets) is recommended. Your three best options are:
+- referring directly in your stylesheet to open fonts which may be available on the user's system
+- providing links to download the full package of the font - either from your own website or from elsewhere - so users can install it themselves
+- using @font-face to distribute the font directly to browsers. This is recommended and explicitly allowed by the licensing model because it is distribution. The font file itself is distributed with other components of the webpage. It is not embedded in the webpage but referenced through a web address which will cause the browser to retrieve and use the corresponding font to render the webpage (see 1.11 and 1.15 for details related to embedding fonts into documents). As you take advantage of the @font-face cross-platform standard, be aware that web fonts are often tuned for a web environment and not intended for installation and use outside a browser. The reasons in favour of using web fonts are to allow design of dynamic text elements instead of static graphics, to make it easier for content to be localized and translated, indexed and searched, and all this with cross-platform open standards without depending on restricted extensions or plugins. You should check the CSS cascade (the order in which fonts are being called or delivered to your users) when testing.
+
+2.2 Can I make and use WOFF (Web Open Font Format) versions of OFL fonts?
+Yes, but you need to be careful. A change in font format normally is considered modification, and Reserved Font Names (RFNs) cannot be used. Because of the design of the WOFF format, however, it is possible to create a WOFF version that is not considered modification, and so would not require a name change. You are allowed to create, use and distribute a WOFF version of an OFL font without changing the font name, but only if:
+
+- the original font data remains unchanged except for WOFF compression, and
+- WOFF-specific metadata is either omitted altogether or present and includes, unaltered, the contents of all equivalent metadata in the original font.
+
+If the original font data or metadata is changed, or the WOFF-specific metadata is incomplete, the font must be considered a Modified Version, the OFL restrictions would apply and the name of the font must be changed: any RFNs cannot be used and copyright notices and licensing information must be included and cannot be deleted or modified. You must come up with a unique name - we recommend one corresponding to your domain or your particular web application. Be aware that only the original author(s) can use RFNs. This is to prevent collisions between a derivative tuned to your audience and the original upstream version and so to reduce confusion.
+
+Please note that most WOFF conversion tools and online services do not meet the two requirements listed above, and so their output must be considered a Modified Version. So be very careful and check to be sure that the tool or service you're using is compressing unchanged data and completely and accurately reflecting the original font metadata.
+
+2.3 What about other web font formats such as EOT/EOTLite/CWT/etc.?
+In most cases these formats alter the original font data more than WOFF, and do not completely support appropriate metadata, so their use must be considered modification and RFNs may not be used. However, there may be certain formats or usage scenarios that may allow the use of RFNs. See http://scripts.sil.org/OFL_web_fonts_and_RFNs
+
+2.4 Can I make OFL fonts available through web font online services?
+Yes, you are welcome to include OFL fonts in online web font services as long as you properly meet all the conditions of the license. The origin and open status of the font should be clear among the other fonts you are hosting. Authorship, copyright notices and license information must be sufficiently visible to your users or subscribers so they know where the font comes from and the rights granted by the author(s). Make sure the font file contains the needed copyright notice(s) and licensing information in its metadata. Please double-check the accuracy of every field to prevent contradictory information. Other font formats, including EOT/EOTLite/CWT and superior alternatives like WOFF, already provide fields for this information. Remember that if you modify the font within your library or convert it to another format for any reason the OFL restrictions apply and you need to change the names accordingly. Please respect the author's wishes as expressed in the OFL and do not misrepresent original designers and their work. Don't lump quality open fonts together with dubious freeware or public domain fonts. Consider how you can best work with the original designers and foundries, support their efforts and generate goodwill that will benefit your service. (See 1.17 for details related to URL-based access restrictions methods or DRM mechanisms).
+
+2.5 Some web font formats and services provide ways of "optimizing" the font for a particular website or web application; is that allowed?
+Yes, it is permitted, but remember that these optimized versions are Modified Versions and so must follow OFL requirements like appropriate renaming. Also you need to bear in mind the other important parameters beyond compression, speed and responsiveness: you need to consider the audience of your particular website or web application, as choosing some optimization parameters may turn out to be less than ideal for them. Subsetting by removing certain glyphs or features may seriously limit functionality of the font in various languages that your users expect. It may also introduce degradation of quality in the rendering or specific bugs on the various target platforms compared to the original font from upstream. In other words, remember that one person's optimized font may be another person's missing feature. Various advanced typographic features (OpenType, Graphite or AAT) are also available through CSS and may provide the desired effects without the need to modify the font.
+
+2.6 Is subsetting a web font considered modification?
+Yes. Removing any parts of the font when delivering a web font to a browser, including unused glyphs and smart font code, is considered modification. This is permitted by the OFL but would not normally allow the use of RFNs. Some newer subsetting technologies may be able to subset in a way that allows users to effectively have access to the complete font, including smart font behaviour. See 2.8 and http://scripts.sil.org/OFL_web_fonts_and_RFNs
+
+2.7 Are there any situations in which a modified web font could use RFNs?
+Yes. If a web font is optimized only in ways that preserve Functional Equivalence (see 2.8), then it may use RFNs, as it reasonably represents the Original Version and respects the intentions of the author(s) and the main purposes of the RFN mechanism (avoids collisions, protects authors, minimizes support, encourages derivatives). However this is technically very difficult and often impractical, so a much better scenario is for the web font service or provider to sign a separate agreement with the author(s) that allows the use of RFNs for Modified Versions.
+
+2.8 How do you know if an optimization to a web font preserves Functional Equivalence?
+Functional Equivalence is described in full in the 'Web fonts and RFNs' paper at http://scripts.sil.org/OFL_web_fonts_and_RFNs, in general, an optimized font is deemed to be Functionally Equivalent (FE) to the Original Version if it:
+
+- Supports the same full character inventory. If a character can be properly displayed using the Original Version, then that same character, encoded correctly on a web page, will display properly.
+- Provides the same smart font behavior. Any dynamic shaping behavior that works with the Original Version should work when optimized, unless the browser or environment does not support it. There does not need to be guaranteed support in the client, but there should be no forced degradation of smart font or shaping behavior, such as the removal or obfuscation of OpenType, Graphite or AAT tables.
+- Presents text with no obvious degradation in visual quality. The lettershapes should be equally (or more) readable, within limits of the rendering platform.
+- Preserves original author, project and license metadata. At a minimum, this should include: Copyright and authorship; The license as stated in the Original Version, whether that is the full text of the OFL or a link to the web version; Any RFN declarations; Information already present in the font or documentation that points back to the Original Version, such as a link to the project or the author's website.
+
+If an optimized font meets these requirements, and so is considered to be FE, then it's very likely that the original author would feel that the optimized font is a good and reasonable equivalent. If it falls short of any of these requirements, the optimized font does not reasonably represent the Original Version, and so should be considered to be a Modified Version. Like other Modified Versions, it would not be allowed to use any RFNs and you simply need to pick your own font name.
+
+2.9 Isn't use of web fonts another form of embedding?
+No. Unlike embedded fonts in a PDF, web fonts are not an integrated part of the document itself. They are not specific to a single document and are often applied to thousands of documents around the world. The font data is not stored alongside the document data and often originates from a different location. The ease by which the web fonts used by a document may be identified and downloaded for desktop use demonstrates that they are philosophically and technically separate from the web pages that specify them. See http://scripts.sil.org/OFL_web_fonts_and_RFNs
+
+2.10 So would it be better to not use RFNs at all if you want your font to be distributed by a web fonts service?
+No. Although the OFL does not require authors to use RFNs, the RFN mechanism is an important part of the OFL model and completely compatible with web font services. If that web font service modifies the fonts, then the best solution is to sign a separate agreement for the use of any RFNs. It is perfectly valid for an author to not declare any RFNs, but before they do so they need to fully understand the benefits they are giving up, and the overall negative effect of allowing many different versions bearing the same name to be widely distributed. As a result, we don't generally recommend it.
+
+2.11 What should an agreement for the use of RFNs say? Are there any examples?
+There is no prescribed format for this agreement, as legal systems vary, and no recommended examples. Authors may wish to add specific clauses to further restrict use, require author review of Modified Versions, establish user support mechanisms or provide terms for ending the agreement. Such agreements are usually not public, and apply only to the main parties. However, it would be very beneficial for web font services to clearly state when they have established such agreements, so that the public understands clearly that their service is operating appropriately.
+
+See the separate paper on 'Web Fonts & RFNs' for in-depth discussion of issues related to the use of RFNs for web fonts. This is available at http://scripts.sil.org/OFL_web_fonts_and_RFNs
+
+
+3 MODIFYING OFL-LICENSED FONTS
+
+3.1 Can I change the fonts? Are there any limitations to what things I can and cannot change?
+You are allowed to change anything, as long as such changes do not violate the terms of the license. In other words, you are not allowed to remove the copyright statement(s) from the font, but you could put additional information into it that covers your contribution. See the placeholders in the OFL header template for recommendations on where to add your own statements. (Remember that, when authors have reserved names via the RFN mechanism, you need to change the internal names of the font to your own font name when making your modified version even if it is just a small change.)
+
+3.2 I have a font that needs a few extra glyphs - can I take them from an OFL licensed font and copy them into mine?
+Yes, but if you distribute that font to others it must be under the OFL, and include the information mentioned in condition 2 of the license.
+
+3.3 Can I charge people for my additional work? In other words, if I add a bunch of special glyphs or OpenType/Graphite/AAT code, can I sell the enhanced font?
+Not by itself. Derivative fonts must be released under the OFL and cannot be sold by themselves. It is permitted, however, to include them in a larger software package (such as text editors, office suites or operating systems), even if the larger package is sold. In that case, you are strongly encouraged, but not required, to also make that derived font easily and freely available outside of the larger package.
+
+3.4 Can I pay someone to enhance the fonts for my use and distribution?
+Yes. This is a good way to fund the further development of the fonts. Keep in mind, however, that if the font is distributed to others it must be under the OFL. You won't be able to recover your investment by exclusively selling the font, but you will be making a valuable contribution to the community. Please remember how you have benefited from the contributions of others.
+
+3.5 I need to make substantial revisions to the font to make it work with my program. It will be a lot of work, and a big investment, and I want to be sure that it can only be distributed with my program. Can I restrict its use?
+No. If you redistribute a Modified Version of the font it must be under the OFL. You may not restrict it in any way beyond what the OFL permits and requires. This is intended to ensure that all released improvements to the fonts become available to everyone. But you will likely get an edge over competitors by being the first to distribute a bundle with the enhancements. Again, please remember how you have benefited from the contributions of others.
+
+3.6 Do I have to make any derivative fonts (including extended source files, build scripts, documentation, etc.) publicly available?
+No, but please consider sharing your improvements with others. You may find that you receive in return more than what you gave.
+
+3.7 If a trademark is claimed in the OFL font, does that trademark need to remain in modified fonts?
+Yes. Any trademark notices must remain in any derivative fonts to respect trademark laws, but you may add any additional trademarks you claim, officially registered or not. For example if an OFL font called "Foo" contains a notice that "Foo is a trademark of Acme", then if you rename the font to "Bar" when creating a Modified Version, the new trademark notice could say "Foo is a trademark of Acme Inc. - Bar is a trademark of Roadrunner Technologies Ltd.". Trademarks work alongside the OFL and are not subject to the terms of the licensing agreement. The OFL does not grant any rights under trademark law. Bear in mind that trademark law varies from country to country and that there are no international trademark conventions as there are for copyright. You may need to significantly invest in registering and defending a trademark for it to remain valid in the countries you are interested in. This may be costly for an individual independent designer.
+
+3.8 If I commit changes to a font (or publish a branch in a DVCS) as part of a public open source software project, do I have to change the internal font names?
+Only if there are declared RFNs. Making a public commit or publishing a public branch is effectively redistributing your modifications, so any change to the font will require that you do not use the RFNs. Even if there are no RFNs, it may be useful to change the name or add a suffix indicating that a particular version of the font is still in development and not released yet. This will clearly indicate to users and fellow designers that this particular font is not ready for release yet. See section 5 for more details.
+
+
+4 LICENSING YOUR ORIGINAL FONTS UNDER THE OFL
+
+4.1 Can I use the SIL OFL for my own fonts?
+Yes! We heartily encourage everyone to use the OFL to distribute their own original fonts. It is a carefully constructed license that allows great freedom along with enough artistic integrity protection for the work of the authors as well as clear rules for other contributors and those who redistribute the fonts. The licensing model is used successfully by various organisations, both for-profit and not-for-profit, to release fonts of varying levels of scope and complexity.
+
+4.2 What do I have to do to apply the OFL to my font?
+If you want to release your fonts under the OFL, we recommend you do the following:
+
+4.2.1 Put your copyright and Reserved Font Names information at the beginning of the main OFL.txt file in place of the dedicated placeholders (marked with the <> characters). Include this file in your release package.
+
+4.2.2 Put your copyright and the OFL text with your chosen Reserved Font Name(s) into your font files (the copyright and license fields). A link to the OFL text on the OFL web site is an acceptable (but not recommended) alternative. Also add this information to any other components (build scripts, glyph databases, documentation, test files, etc). Accurate metadata in your font files is beneficial to you as an increasing number of applications are exposing this information to the user. For example, clickable links can bring users back to your website and let them know about other work you have done or services you provide. Depending on the format of your fonts and sources, you can use template human-readable headers or machine-readable metadata. You should also double-check that there is no conflicting metadata in the font itself contradicting the license, such as the fstype bits in the os2 table or fields in the name table.
+
+4.2.3 Write an initial FONTLOG.txt for your font and include it in the release package (see Section 6 and Appendix A for details including a template).
+
+4.2.4 Include the relevant practical documentation on the license by adding the current OFL-FAQ.txt file in your package.
+
+4.2.5 If you wish you can use the OFL graphics (http://scripts.sil.org/OFL_logo) on your website.
+
+4.3 Will you make my font OFL for me?
+We won't do the work for you. We can, however, try to answer your questions, unfortunately we do not have the resources to review and check your font packages for correct use of the OFL. We recommend you turn to designers, foundries or consulting companies with experience in doing open font design to provide this service to you.
+
+4.4 Will you distribute my OFL font for me?
+No, although if the font is of sufficient quality and general interest we may include a link to it on our partial list of OFL fonts on the OFL web site. You may wish to consider other open font catalogs or hosting services, such as the Unifont Font Guide (http://unifont.org/fontguide), The League of Movable Type (http://theleagueofmovabletype.com) or the Open Font Library (http://openfontlibrary.org/), which despite the name has no direct relationship to the OFL or SIL. We do not endorse any particular catalog or hosting service - it is your responsibility to determine if the service is right for you and if it treats authors with fairness.
+
+4.5 Why should I use the OFL for my fonts?
+- to meet needs for fonts that can be modified to support lesser-known languages
+- to provide a legal and clear way for people to respect your work but still use it (and reduce piracy)
+- to involve others in your font project
+- to enable your fonts to be expanded with new weights and improved writing system/language support
+- to allow more technical font developers to add features to your design (such as OpenType, Graphite or AAT support)
+- to renew the life of an old font lying on your hard drive with no business model
+- to allow your font to be included in Libre Software operating systems like Ubuntu
+- to give your font world status and wide, unrestricted distribution
+- to educate students about quality typeface and font design
+- to expand your test base and get more useful feedback
+- to extend your reach to new markets when users see your metadata and go to your website
+- to get your font more easily into one of the web font online services
+- to attract attention for your commercial fonts
+- to make money through web font services
+- to make money by bundling fonts with applications
+- to make money adjusting and extending existing open fonts
+- to get a better chance that foundations/NGOs/charities/companies who commission fonts will pick you
+- to be part of a sharing design and development community
+- to give back and contribute to a growing body of font sources
+
+
+5 CHOOSING RESERVED FONT NAMES
+
+5.1 What are Reserved Font Names?
+These are font names, or portions of font names, that the author has chosen to reserve for use only with the Original Version of the font, or for Modified Version(s) created by the original author.
+
+5.2 Why can't I use the Reserved Font Names in my derivative font names? I'd like people to know where the design came from.
+The best way to acknowledge the source of the design is to thank the original authors and any other contributors in the files that are distributed with your revised font (although no acknowledgement is required). The FONTLOG is a natural place to do this. Reserved Font Names ensure that the only fonts that have the original names are the unmodified Original Versions. This allows designers to maintain artistic integrity while allowing collaboration to happen. It eliminates potential confusion and name conflicts. When choosing a name, be creative and avoid names that reuse almost all the same letters in the same order or sound like the original. It will help everyone if Original Versions and Modified Versions can easily be distinguished from one another and from other derivatives. Any substitution and matching mechanism is outside the scope of the license.
+
+5.3 What do you mean by "primary name as presented to the user"? Are you referring to the font menu name?
+Yes, this applies to the font menu name and other mechanisms that specify a font in a document. It would be fine, however, to keep a text reference to the original fonts in the description field, in your modified source file or in documentation provided alongside your derivative as long as no one could be confused that your modified source is the original. But you cannot use the Reserved Font Names in any way to identify the font to the user (unless the Copyright Holder(s) allow(s) it through a separate agreement). Users who install derivatives (Modified Versions) on their systems should not see any of the original Reserved Font Names in their font menus, for example. Again, this is to ensure that users are not confused and do not mistake one font for another and so expect features only another derivative or the Original Version can actually offer.
+
+5.4 Am I not allowed to use any part of the Reserved Font Names?
+You may not use individual words from the Reserved Font Names, but you would be allowed to use parts of words, as long as you do not use any word from the Reserved Font Names entirely. We do not recommend using parts of words because of potential confusion, but it is allowed. For example, if "Foobar" was a Reserved Font Name, you would be allowed to use "Foo" or "bar", although we would not recommend it. Such an unfortunate choice would confuse the users of your fonts as well as make it harder for other designers to contribute.
+
+5.5 So what should I, as an author, identify as Reserved Font Names?
+Original authors are encouraged to name their fonts using clear, distinct names, and only declare the unique parts of the name as Reserved Font Names. For example, the author of a font called "Foobar Sans" would declare "Foobar" as a Reserved Font Name, but not "Sans", as that is a common typographical term, and may be a useful word to use in a derivative font name. Reserved Font Names should also be single words for simplicity and legibility. A font called "Flowing River" should have Reserved Font Names "Flowing" and "River", not "Flowing River". You also need to be very careful about reserving font names which are already linked to trademarks (whether registered or not) which you do not own.
+
+5.6 Do I, as an author, have to identify any Reserved Font Names?
+No. RFNs are optional and not required, but we encourage you to use them. This is primarily to avoid confusion between your work and Modified Versions. As an author you can release a font under the OFL and not declare any Reserved Font Names. There may be situations where you find that using no RFNs and letting your font be changed and modified - including any kind of modification - without having to change the original name is desirable. However you need to be fully aware of the consequences. There will be no direct way for end-users and other designers to distinguish your Original Version from many Modified Versions that may be created. You have to trust whoever is making the changes and the optimizations to not introduce problematic changes. The RFNs you choose for your own creation have value to you as an author because they allow you to maintain artistic integrity and keep some control over the distribution channel to your end-users. For discussion of RFNs and web fonts see section 2.
+
+5.7 Are any names (such as the main font name) reserved by default?
+No. That is a change to the license as of version 1.1. If you want any names to be Reserved Font Names, they must be specified after the copyright statement(s).
+
+5.8 Is there any situation in which I can use Reserved Font Names for a Modified Version?
+The Copyright Holder(s) can give certain trusted parties the right to use any of the Reserved Font Names through separate written agreements. For example, even if "Foobar" is a RFN, you could write up an agreement to give company "XYZ" the right to distribute a modified version with a name that includes "Foobar". This allows for freedom without confusion. The existence of such an agreement should be made as clear as possible to downstream users and designers in the distribution package and the relevant documentation. They need to know if they are a party to the agreement or not and what they are practically allowed to do or not even if all the details of the agreement are not public.
+
+5.9 Do font rebuilds require a name change? Do I have to change the name of the font when my packaging workflow includes a full rebuild from source?
+Yes, all rebuilds which change the font data and the smart code are Modified Versions and the requirements of the OFL apply: you need to respect what the Author(s) have chosen in terms of Reserved Font Names. However if a package (or installer) is simply a wrapper or a compressed structure around the final font - leaving them intact on the inside - then no name change is required. Please get in touch with the author(s) and copyright holder(s) to inquire about the presence of font sources beyond the final font file(s) and the recommended build path. That build path may very well be non-trivial and hard to reproduce accurately by the maintainer. If a full font build path is made available by the upstream author(s) please be aware that any regressions and changes you may introduce when doing a rebuild for packaging purposes is your own responsibility as a package maintainer since you are effectively creating a separate branch. You should make it very clear to your users that your rebuilt version is not the canonical one from upstream.
+
+5.10 Can I add other Reserved Font Names when making a derivative font?
+Yes. List your additional Reserved Font Names after your additional copyright statement, as indicated with example placeholders at the top of the OFL.txt file. Be sure you do not remove any existing RFNs but only add your own. RFN statements should be placed next to the copyright statement of the relevant author as indicated in the OFL.txt template to make them visible to designers wishing to make their separate version.
+
+
+6 ABOUT THE FONTLOG
+
+6.1 What is this FONTLOG thing exactly?
+It has three purposes: 1) to provide basic information on the font to users and other designers and developers, 2) to document changes that have been made to the font or accompanying files, either by the original authors or others, and 3) to provide a place to acknowledge authors and other contributors. Please use it!
+
+6.2 Is the FONTLOG required?
+It is not a requirement of the license, but we strongly recommend you have one.
+
+6.3 Am I required to update the FONTLOG when making Modified Versions?
+No, but users, designers and other developers might get very frustrated with you if you don't. People need to know how derivative fonts differ from the original, and how to take advantage of the changes, or build on them. There are utilities that can help create and maintain a FONTLOG, such as the FONTLOG support in FontForge.
+
+6.4 What should the FONTLOG look like?
+It is typically a separate text file (FONTLOG.txt), but can take other formats. It commonly includes these four sections:
+
+- brief header describing the FONTLOG itself and name of the font family
+- Basic Font Information - description of the font family, purpose and breadth
+- ChangeLog - chronological listing of changes
+- Acknowledgements - list of authors and contributors with contact information
+
+It could also include other sections, such as: where to find documentation, how to make contributions, information on contributing organizations, source code details, and a short design guide. See Appendix A for an example FONTLOG.
+
+
+7 MAKING CONTRIBUTIONS TO OFL PROJECTS
+
+7.1 Can I contribute work to OFL projects?
+In many cases, yes. It is common for OFL fonts to be developed by a team of people who welcome contributions from the wider community. Contact the original authors for specific information on how to participate in their projects.
+
+7.2 Why should I contribute my changes back to the original authors?
+It would benefit many people if you contributed back in response to what you've received. Your contributions and improvements to the fonts and other components could be a tremendous help and would encourage others to contribute as well and 'give back'. You will then benefit from other people's contributions as well. Sometimes maintaining your own separate version takes more effort than merging back with the original. Be aware that any contributions, however, must be either your own original creation or work that you own, and you may be asked to affirm that clearly when you contribute.
+
+7.3 I've made some very nice improvements to the font. Will you consider adopting them and putting them into future Original Versions?
+Most authors would be very happy to receive such contributions. Keep in mind that it is unlikely that they would want to incorporate major changes that would require additional work on their end. Any contributions would likely need to be made for all the fonts in a family and match the overall design and style. Authors are encouraged to include a guide to the design with the fonts. It would also help to have contributions submitted as patches or clearly marked changes - the use of smart source revision control systems like subversion, mercurial, git or bzr is a good idea. Please follow the recommendations given by the author(s) in terms of preferred source formats and configuration parameters for sending contributions. If this is not indicated in a FONTLOG or other documentation of the font, consider asking them directly. Examples of useful contributions are bug fixes, additional glyphs, stylistic alternates (and the smart font code to access them) or improved hinting. Keep in mind that some kinds of changes (esp. hinting) may be technically difficult to integrate.
+
+7.4 How can I financially support the development of OFL fonts?
+It is likely that most authors of OFL fonts would accept financial contributions - contact them for instructions on how to do this. Such contributions would support future development. You can also pay for others to enhance the fonts and contribute the results back to the original authors for inclusion in the Original Version.
+
+
+8 ABOUT THE LICENSE ITSELF
+
+8.1 I see that this is version 1.1 of the license. Will there be later changes?
+Version 1.1 is the first minor revision of the OFL. We are confident that version 1.1 will meet most needs, but are open to future improvements. Any revisions would be for future font releases, and previously existing licenses would remain in effect. No retroactive changes are possible, although the Copyright Holder(s) can re-release the font under a revised OFL. All versions will be available on our web site: http://scripts.sil.org/OFL.
+
+8.2 Does this license restrict the rights of the Copyright Holder(s)?
+No. The Copyright Holder(s) still retain(s) all the rights to their creation; they are only releasing a portion of it for use in a specific way. For example, the Copyright Holder(s) may choose to release a 'basic' version of their font under the OFL, but sell a restricted 'enhanced' version under a different license. They may also choose to release the same font under both the OFL and some other license. Only the Copyright Holder(s) can do this, and doing so does not change the terms of the OFL as it applies to that font.
+
+8.3 Is the OFL a contract or a license?
+The OFL is a worldwide license based on international copyright agreements and conventions. It is not a contract and so does not require you to sign it to have legal validity. By using, modifying and redistributing components under the OFL you indicate that you accept the license.
+
+8.4 I really like the terms of the OFL, but want to change it a little. Am I allowed to take ideas and actual wording from the OFL and put them into my own custom license for distributing my fonts?
+We strongly recommend against creating your very own unique open licensing model. Using a modified or derivative license will likely cut you off - along with the font(s) under that license - from the community of designers using the OFL, potentially expose you and your users to legal liabilities, and possibly put your work and rights at risk. The OFL went though a community and legal review process that took years of effort, and that review is only applicable to an unmodified OFL. The text of the OFL has been written by SIL (with review and consultation from the community) and is copyright (c) 2005-2013 SIL International. You may re-use the ideas and wording (in part, not in whole) in another non-proprietary license provided that you call your license by another unambiguous name, that you do not use the preamble, that you do not mention SIL and that you clearly present your license as different from the OFL so as not to cause confusion by being too similar to the original. If you feel the OFL does not meet your needs for an open license, please contact us.
+
+8.5 Can I translate the license and the FAQ into other languages?
+SIL certainly recognises the need for people who are not familiar with English to be able to understand the OFL and its use. Making the license very clear and readable has been a key goal for the OFL, but we know that people understand their own language best.
+
+If you are an experienced translator, you are very welcome to translate the OFL and OFL-FAQ so that designers and users in your language community can understand the license better. But only the original English version of the license has legal value and has been approved by the community. Translations do not count as legal substitutes and should only serve as a way to explain the original license. SIL - as the author and steward of the license for the community at large - does not approve any translation of the OFL as legally valid because even small translation ambiguities could be abused and create problems.
+
+SIL gives permission to publish unofficial translations into other languages provided that they comply with the following guidelines:
+
+- Put the following disclaimer in both English and the target language stating clearly that the translation is unofficial:
+
+"This is an unofficial translation of the SIL Open Font License into <language_name>. It was not published by SIL International, and does not legally state the distribution terms for fonts that use the OFL. A release under the OFL is only valid when using the original English text. However, we recognize that this unofficial translation will help users and designers not familiar with English to better understand and use the OFL. We encourage designers who consider releasing their creation under the OFL to read the OFL-FAQ in their own language if it is available. Please go to http://scripts.sil.org/OFL for the official version of the license and the accompanying OFL-FAQ."
+
+- Keep your unofficial translation current and update it at our request if needed, for example if there is any ambiguity which could lead to confusion.
+
+If you start such a unofficial translation effort of the OFL and OFL-FAQ please let us know.
+
+8.6 Does the OFL have an explicit expiration term?
+No, the implicit intent of the OFL is that the permissions granted are perpetual and irrevocable.
+
+
+9 ABOUT SIL INTERNATIONAL
+
+9.1 Who is SIL International and what do they do?
+SIL serves language communities worldwide, building their capacity for sustainable language development, by means of research, translation, training and materials development. SIL makes its services available to all without regard to religious belief, political ideology, gender, race, or ethnic background. SIL's members and volunteers share a Christian commitment.
+
+9.2 What does this have to do with font licensing?
+The ability to read, write, type and publish in one's own language is one of the most critical needs for millions of people around the world. This requires fonts that are widely available and support lesser-known languages. SIL develops - and encourages others to develop - a complete stack of writing systems implementation components available under open licenses. This open stack includes input methods, smart fonts, smart rendering libraries and smart applications. There has been a need for a common open license that is specifically applicable to fonts and related software (a crucial component of this stack), so SIL developed the SIL Open Font License with the help of the Free/Libre and Open Source Software community.
+
+9.3 How can I contact SIL?
+Our main web site is: http://www.sil.org/
+Our site about complex scripts is: http://scripts.sil.org/
+Information about this license (and contact information) is at: http://scripts.sil.org/OFL
+
+
+APPENDIX A - FONTLOG EXAMPLE
+
+Here is an example of the recommended format for a FONTLOG, although other formats are allowed.
+
+-----
+FONTLOG for the GlobalFontFamily fonts
+
+This file provides detailed information on the GlobalFontFamily Font Software. This information should be distributed along with the GlobalFontFamily fonts and any derivative works.
+
+Basic Font Information
+
+GlobalFontFamily is a Unicode typeface family that supports all languages that use the Latin script and its variants, and could be expanded to support other scripts.
+
+NewWorldFontFamily is based on the GlobalFontFamily and also supports Greek, Hebrew, Cyrillic and Armenian.
+
+More specifically, this release supports the following Unicode ranges...
+This release contains...
+Documentation can be found at...
+To contribute to the project...
+
+ChangeLog
+
+10 December 2010 (Fred Foobar) GlobalFontFamily-devel version 1.4
+- fix new build and testing system (bug #123456)
+
+1 August 2008 (Tom Parker) GlobalFontFamily version 1.2.1
+- Tweaked the smart font code (Branch merged with trunk version)
+- Provided improved build and debugging environment for smart behaviours
+
+7 February 2007 (Pat Johnson) NewWorldFontFamily Version 1.3
+- Added Greek and Cyrillic glyphs
+
+7 March 2006 (Fred Foobar) NewWorldFontFamily Version 1.2
+- Tweaked contextual behaviours
+
+1 Feb 2005 (Jane Doe) NewWorldFontFamily Version 1.1
+- Improved build script performance and verbosity
+- Extended the smart code documentation
+- Corrected minor typos in the documentation
+- Fixed position of combining inverted breve below (U+032F)
+- Added OpenType/Graphite smart code for Armenian
+- Added Armenian glyphs (U+0531 -> U+0587)
+- Released as "NewWorldFontFamily"
+
+1 Jan 2005 (Joe Smith) GlobalFontFamily Version 1.0
+- Initial release
+
+Acknowledgements
+
+If you make modifications be sure to add your name (N), email (E), web-address (if you have one) (W) and description (D). This list is in alphabetical order.
+
+N: Jane Doe
+E: jane@university.edu
+W: http://art.university.edu/projects/fonts
+D: Contributor - Armenian glyphs and code
+
+N: Fred Foobar
+E: fred@foobar.org
+W: http://foobar.org
+D: Contributor - misc Graphite fixes
+
+N: Pat Johnson
+E: pat@fontstudio.org
+W: http://pat.fontstudio.org
+D: Designer - Greek & Cyrillic glyphs based on Roman design
+
+N: Tom Parker
+E: tom@company.com
+W: http://www.company.com/tom/projects/fonts
+D: Engineer - original smart font code
+
+N: Joe Smith
+E: joe@fontstudio.org
+W: http://joe.fontstudio.org
+D: Designer - original Roman glyphs
+
+Fontstudio.org is an not-for-profit design group whose purpose is...
+Foobar.org is a distributed community of developers...
+Company.com is a small business who likes to support community designers...
+University.edu is a renowned educational institution with a strong design department...
+-----
+
diff --git a/tests/input/font-psf-test/OFL.txt b/tests/input/font-psf-test/OFL.txt
new file mode 100644
index 0000000..0208027
--- /dev/null
+++ b/tests/input/font-psf-test/OFL.txt
@@ -0,0 +1,94 @@
+Copyright (c) 2004-2015, SIL International (http://scripts.sil.org),
+with Reserved Font Names 'Andika' and 'SIL'.
+
+This Font Software is licensed under the SIL Open Font License, Version 1.1.
+This license is copied below, and is also available with a FAQ at:
+http://scripts.sil.org/OFL
+
+
+-----------------------------------------------------------
+SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007
+-----------------------------------------------------------
+
+PREAMBLE
+The goals of the Open Font License (OFL) are to stimulate worldwide
+development of collaborative font projects, to support the font creation
+efforts of academic and linguistic communities, and to provide a free and
+open framework in which fonts may be shared and improved in partnership
+with others.
+
+The OFL allows the licensed fonts to be used, studied, modified and
+redistributed freely as long as they are not sold by themselves. The
+fonts, including any derivative works, can be bundled, embedded,
+redistributed and/or sold with any software provided that any reserved
+names are not used by derivative works. The fonts and derivatives,
+however, cannot be released under any other type of license. The
+requirement for fonts to remain under this license does not apply
+to any document created using the fonts or their derivatives.
+
+DEFINITIONS
+"Font Software" refers to the set of files released by the Copyright
+Holder(s) under this license and clearly marked as such. This may
+include source files, build scripts and documentation.
+
+"Reserved Font Name" refers to any names specified as such after the
+copyright statement(s).
+
+"Original Version" refers to the collection of Font Software components as
+distributed by the Copyright Holder(s).
+
+"Modified Version" refers to any derivative made by adding to, deleting,
+or substituting -- in part or in whole -- any of the components of the
+Original Version, by changing formats or by porting the Font Software to a
+new environment.
+
+"Author" refers to any designer, engineer, programmer, technical
+writer or other person who contributed to the Font Software.
+
+PERMISSION & CONDITIONS
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of the Font Software, to use, study, copy, merge, embed, modify,
+redistribute, and sell modified and unmodified copies of the Font
+Software, subject to the following conditions:
+
+1) Neither the Font Software nor any of its individual components,
+in Original or Modified Versions, may be sold by itself.
+
+2) Original or Modified Versions of the Font Software may be bundled,
+redistributed and/or sold with any software, provided that each copy
+contains the above copyright notice and this license. These can be
+included either as stand-alone text files, human-readable headers or
+in the appropriate machine-readable metadata fields within text or
+binary files as long as those fields can be easily viewed by the user.
+
+3) No Modified Version of the Font Software may use the Reserved Font
+Name(s) unless explicit written permission is granted by the corresponding
+Copyright Holder. This restriction only applies to the primary font name as
+presented to the users.
+
+4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font
+Software shall not be used to promote, endorse or advertise any
+Modified Version, except to acknowledge the contribution(s) of the
+Copyright Holder(s) and the Author(s) or with their explicit written
+permission.
+
+5) The Font Software, modified or unmodified, in part or in whole,
+must be distributed entirely under this license, and must not be
+distributed under any other license. The requirement for fonts to
+remain under this license does not apply to any document created
+using the Font Software.
+
+TERMINATION
+This license becomes null and void if any of the above conditions are
+not met.
+
+DISCLAIMER
+THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT
+OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE
+COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL
+DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM
+OTHER DEALINGS IN THE FONT SOFTWARE.
diff --git a/tests/input/font-psf-test/README.md b/tests/input/font-psf-test/README.md
new file mode 100644
index 0000000..572d380
--- /dev/null
+++ b/tests/input/font-psf-test/README.md
@@ -0,0 +1,9 @@
+# Psf Test
+
+Psf Test is a font family used only for testing the pysilfont framework. It is not intended to be an installable font family and doesn't even contain a complete Latin alphabet (Z and z are missing). The contents of these fonts are taken from [Andika New Basic](https://scripts.sil.org/andika).
+
+For copyright and licensing information - including any Reserved Font Names - see [OFL.txt](OFL.txt).
+
+For practical information about using, modifying and redistributing this font see [OFL-FAQ.txt](OFL-FAQ.txt).
+
+For more details about this project, including changelog and acknowledgements see [FONTLOG.txt](FONTLOG.txt) and [README.txt](README.txt).
diff --git a/tests/input/font-psf-test/README.txt b/tests/input/font-psf-test/README.txt
new file mode 100644
index 0000000..a0d837c
--- /dev/null
+++ b/tests/input/font-psf-test/README.txt
@@ -0,0 +1,87 @@
+README
+Andika
+=========================================
+
+(see FONTLOG.txt for information on the Psf Test family)
+
+Thank you for your interest in Andika ("Write!" in Swahili), a
+Unicode-compliant sans serif font designed by SIL International
+primarily for literacy use.
+
+Andika supports a wide range of Latin and Cyrillic characters.
+Documentation for the font is available on Andika website
+(http://scripts.sil.org/andika), including details on what ranges are
+supported.
+
+Andika is released under the SIL Open Font License.
+
+See the OFL and OFL-FAQ for details of the SIL Open Font License.
+See the FONTLOG for information on this and previous releases.
+See the website (http://scripts.sil.org/andika) for further documentation.
+Andika FAQ (http://scripts.sil.org/Andika_FAQ-KI) for frequently
+asked questions and their answers.
+See the SIL Unicode Roman FAQ (http://scripts.sil.org/ComplexRomanFontFAQ)
+for frequently asked questions and their answers regarding SIL's Roman fonts.
+
+
+TIPS
+====
+
+As this font is distributed at no cost, we are unable to provide a
+commercial level of personal technical support. The font has, however,
+been through some testing on various platforms to be sure it works in most
+situations. In particular, it has been tested and shown to work on Windows
+XP, Windows Vista and Windows 7. Graphite capabilities have been tested
+on Graphite-supported platforms.
+
+If you do find a problem, please do report it to andika@sil.org.
+We can't guarantee any direct response, but will try to fix reported bugs in
+future versions. Make sure you read through the
+SIL Unicode Roman FAQ (http://scripts.sil.org/ComplexRomanFontFAQ).
+
+Many problems can be solved, or at least explained, through an understanding
+of the encoding and use of the fonts. Here are some basic hints:
+
+Encoding:
+The fonts are encoded according to Unicode, so your application must support
+Unicode text in order to access letters other than the standard alphabet.
+Most Windows applications provide basic Unicode support. You will, however,
+need some way of entering Unicode text into your document.
+
+Keyboarding:
+Andika does not include any keyboarding helps or utilities. It uses the
+built-in keyboards of the operating system. You will need to install the
+appropriate keyboard and input method for the characters of the language you
+wish to use. If you want to enter characters that are not supported by any
+system keyboard, the Keyman program (www.tavultesoft.com) can be helpful
+on Windows systems. Also available for Windows is MSKLC
+(http://www.microsoft.com/globaldev/tools/msklc.mspx).
+For other platforms, KMFL (http://kmfl.sourceforge.net/),
+XKB (http://www.x.org/wiki/XKB) or Ukelele (http://scripts.sil.org/ukelele)
+can be helpful.
+
+If you want to enter characters that are not supported by any system
+keyboard, and to access the full Unicode range, we suggest you use
+gucharmap, kcharselect on Ubuntu or similar software.
+
+Another method of entering some symbols is provided by a few applications such
+as Adobe InDesign or OpenOffice.org. They can display a glyph palette or input
+dialog that shows all the glyphs (symbols) in a font and allow you to enter
+them by clicking on the glyph you want.
+
+Rendering:
+This font is designed to work with Graphite or Opentype advanced font
+technologies. To take advantage of the advanced typographic
+capabilities of this font, you must be using applications that provide an
+adequate level of support for Graphite or OpenType. See "Applications
+that provide an adequate level of support for SIL Unicode Roman fonts"
+(http://scripts.sil.org/Complex_AdLvSup).
+
+
+CONTACT
+========
+For more information please visit the Andika page on SIL International's
+Computers and Writing systems website:
+http://scripts.sil.org/andika
+
+Support through the website: http://scripts.sil.org/Support
diff --git a/tests/input/font-psf-test/preflight b/tests/input/font-psf-test/preflight
new file mode 100755
index 0000000..9a63416
--- /dev/null
+++ b/tests/input/font-psf-test/preflight
@@ -0,0 +1,19 @@
+#!/bin/sh
+
+# This normalization will also run check and fix routines
+psfnormalize -p checkfix=fix source/PsfTest-Regular.ufo -l source/logs/normR.log
+psfnormalize -p checkfix=fix source/PsfTest-Bold.ufo -l source/logs/normB.log
+psfnormalize -p checkfix=fix source/PsfTest-Italic.ufo -l source/logs/normI.log
+psfnormalize -p checkfix=fix source/PsfTest-BoldItalic.ufo -l source/logs/normBI.log
+
+# Building composites - needs to be done after normalization or may complain due to bad anchor coordinates
+psfbuildcomp -i source/composites.txt source/PsfTest-Regular.ufo -l source/logs/compsR.log
+psfbuildcomp -i source/composites.txt source/PsfTest-Bold.ufo -l source/logs/compsB.log
+psfbuildcomp -i source/composites.txt source/PsfTest-Italic.ufo -l source/logs/compsI.log
+psfbuildcomp -i source/composites.txt source/PsfTest-BoldItalic.ufo -l source/logs/compsBI.log
+
+psfsetpsnames -i source/glyph_data.csv source/PsfTest-Regular.ufo -l source/logs/psnames.log
+psfsetglyphorder --header sort_final -i source/glyph_data.csv source/PsfTest-Regular.ufo -l source/logs/sortorder.log
+
+# Following sync will copy psnames and glyphorder updates to all fonts
+psfsyncmasters source/PsfTestRoman.designspace source/PsfTestItalic.designspace -l source/logs/sync.log
diff --git a/tests/input/font-psf-test/preflightg b/tests/input/font-psf-test/preflightg
new file mode 100755
index 0000000..f7618cf
--- /dev/null
+++ b/tests/input/font-psf-test/preflightg
@@ -0,0 +1,7 @@
+#!/bin/sh
+
+# Produce individual UFOs from Glyphs files
+psfglyphs2ufo --nofea source/PsfTestRoman.glyphs source -l source/logs/glyphs2ufoR.log
+psfglyphs2ufo --nofea source/PsfTestItalic.glyphs source -l source/logs/glyphs2ufoI.log
+
+./preflight \ No newline at end of file
diff --git a/tests/input/font-psf-test/source/PsfTest-Bold.ufo/fontinfo.plist b/tests/input/font-psf-test/source/PsfTest-Bold.ufo/fontinfo.plist
new file mode 100644
index 0000000..ca93d40
--- /dev/null
+++ b/tests/input/font-psf-test/source/PsfTest-Bold.ufo/fontinfo.plist
@@ -0,0 +1,245 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+ <key>ascender</key>
+ <integer>2100</integer>
+ <key>capHeight</key>
+ <integer>1485</integer>
+ <key>copyright</key>
+ <string>Copyright (c) 2004-2021 SIL International</string>
+ <key>descender</key>
+ <integer>-550</integer>
+ <key>familyName</key>
+ <string>Psf Test</string>
+ <key>note</key>
+ <string>Test note
+Second line
+
+Third line
+</string>
+ <key>openTypeHeadCreated</key>
+ <string>2021/01/01 11:00:00</string>
+ <key>openTypeHheaAscender</key>
+ <integer>2100</integer>
+ <key>openTypeHheaDescender</key>
+ <integer>-550</integer>
+ <key>openTypeHheaLineGap</key>
+ <integer>0</integer>
+ <key>openTypeNameDescription</key>
+ <string>Copyright (c) 2004-2021 SIL International</string>
+ <key>openTypeNameDesigner</key>
+ <string>Victor Gaultney, Annie Olsen, Julie Remington, Don Collingsworth, Eric Hays, Becca Hirsbrunner</string>
+ <key>openTypeNameDesignerURL</key>
+ <string>http://scripts.sil.org/</string>
+ <key>openTypeNameLicense</key>
+ <string>Copyright (c) 2004-2021 SIL International (http://www.sil.org/) with Reserved Font Names "Andika" and "SIL".
+
+This Font Software is licensed under the SIL Open Font License, Version 1.1. This license is copied below, and is also available with a FAQ at: http://scripts.sil.org/OFL
+
+
+-----------------------------------------------------------
+SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007
+-----------------------------------------------------------
+
+PREAMBLE
+The goals of the Open Font License (OFL) are to stimulate worldwide development of collaborative font projects, to support the font creation efforts of academic and linguistic communities, and to provide a free and open framework in which fonts may be shared and improved in partnership with others.
+
+The OFL allows the licensed fonts to be used, studied, modified and redistributed freely as long as they are not sold by themselves. The fonts, including any derivative works, can be bundled, embedded, redistributed and/or sold with any software provided that any reserved names are not used by derivative works. The fonts and derivatives, however, cannot be released under any other type of license. The requirement for fonts to remain under this license does not apply to any document created using the fonts or their derivatives.
+
+DEFINITIONS
+"Font Software" refers to the set of files released by the Copyright Holder(s) under this license and clearly marked as such. This may include source files, build scripts and documentation.
+
+"Reserved Font Name" refers to any names specified as such after the copyright statement(s).
+
+"Original Version" refers to the collection of Font Software components as distributed by the Copyright Holder(s).
+
+"Modified Version" refers to any derivative made by adding to, deleting, or substituting -- in part or in whole -- any of the components of the Original Version, by changing formats or by porting the Font Software to a new environment.
+
+"Author" refers to any designer, engineer, programmer, technical writer or other person who contributed to the Font Software.
+
+PERMISSION &amp; CONDITIONS
+Permission is hereby granted, free of charge, to any person obtaining a copy of the Font Software, to use, study, copy, merge, embed, modify, redistribute, and sell modified and unmodified copies of the Font Software, subject to the following conditions:
+
+1) Neither the Font Software nor any of its individual components, in Original or Modified Versions, may be sold by itself.
+
+2) Original or Modified Versions of the Font Software may be bundled, redistributed and/or sold with any software, provided that each copy contains the above copyright notice and this license. These can be included either as stand-alone text files, human-readable headers or in the appropriate machine-readable metadata fields within text or binary files as long as those fields can be easily viewed by the user.
+
+3) No Modified Version of the Font Software may use the Reserved Font Name(s) unless explicit written permission is granted by the corresponding Copyright Holder. This restriction only applies to the primary font name as presented to the users.
+
+4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font Software shall not be used to promote, endorse or advertise any Modified Version, except to acknowledge the contribution(s) of the Copyright Holder(s) and the Author(s) or with their explicit written permission.
+
+5) The Font Software, modified or unmodified, in part or in whole, must be distributed entirely under this license, and must not be distributed under any other license. The requirement for fonts to remain under this license does not apply to any document created using the Font Software.
+
+TERMINATION
+This license becomes null and void if any of the above conditions are not met.
+
+DISCLAIMER
+THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM OTHER DEALINGS IN THE FONT SOFTWARE.</string>
+ <key>openTypeNameLicenseURL</key>
+ <string>http://scripts.sil.org/OFL</string>
+ <key>openTypeNameManufacturer</key>
+ <string>SIL International</string>
+ <key>openTypeNameManufacturerURL</key>
+ <string>http://scripts.sil.org</string>
+ <key>openTypeNamePreferredFamilyName</key>
+ <string>Psf Test</string>
+ <key>openTypeNamePreferredSubfamilyName</key>
+ <string>Bold</string>
+ <key>openTypeNameUniqueID</key>
+ <string>SIL International: Psf Test Bold: 2022</string>
+ <key>openTypeNameVersion</key>
+ <string>Version 5.550</string>
+ <key>openTypeOS2CodePageRanges</key>
+ <array>
+ <integer>0</integer>
+ <integer>1</integer>
+ <integer>2</integer>
+ <integer>4</integer>
+ <integer>7</integer>
+ <integer>8</integer>
+ </array>
+ <key>openTypeOS2FamilyClass</key>
+ <array>
+ <integer>0</integer>
+ <integer>0</integer>
+ </array>
+ <key>openTypeOS2Panose</key>
+ <array>
+ <integer>2</integer>
+ <integer>0</integer>
+ <integer>0</integer>
+ <integer>0</integer>
+ <integer>0</integer>
+ <integer>0</integer>
+ <integer>0</integer>
+ <integer>0</integer>
+ <integer>0</integer>
+ <integer>0</integer>
+ </array>
+ <key>openTypeOS2StrikeoutPosition</key>
+ <integer>700</integer>
+ <key>openTypeOS2StrikeoutSize</key>
+ <integer>100</integer>
+ <key>openTypeOS2SubscriptXOffset</key>
+ <integer>0</integer>
+ <key>openTypeOS2SubscriptXSize</key>
+ <integer>1433</integer>
+ <key>openTypeOS2SubscriptYOffset</key>
+ <integer>286</integer>
+ <key>openTypeOS2SubscriptYSize</key>
+ <integer>1331</integer>
+ <key>openTypeOS2SuperscriptXOffset</key>
+ <integer>0</integer>
+ <key>openTypeOS2SuperscriptXSize</key>
+ <integer>1433</integer>
+ <key>openTypeOS2SuperscriptYOffset</key>
+ <integer>976</integer>
+ <key>openTypeOS2SuperscriptYSize</key>
+ <integer>1331</integer>
+ <key>openTypeOS2Type</key>
+ <array/>
+ <key>openTypeOS2TypoAscender</key>
+ <integer>2100</integer>
+ <key>openTypeOS2TypoDescender</key>
+ <integer>-550</integer>
+ <key>openTypeOS2TypoLineGap</key>
+ <integer>0</integer>
+ <key>openTypeOS2UnicodeRanges</key>
+ <array>
+ <integer>0</integer>
+ <integer>1</integer>
+ <integer>6</integer>
+ <integer>7</integer>
+ <integer>31</integer>
+ <integer>33</integer>
+ <integer>35</integer>
+ <integer>36</integer>
+ <integer>37</integer>
+ <integer>38</integer>
+ <integer>39</integer>
+ <integer>40</integer>
+ <integer>45</integer>
+ <integer>46</integer>
+ <integer>47</integer>
+ <integer>57</integer>
+ <integer>60</integer>
+ <integer>62</integer>
+ <integer>64</integer>
+ <integer>67</integer>
+ <integer>69</integer>
+ <integer>89</integer>
+ </array>
+ <key>openTypeOS2VendorID</key>
+ <string>SIL</string>
+ <key>openTypeOS2WeightClass</key>
+ <integer>700</integer>
+ <key>openTypeOS2WidthClass</key>
+ <integer>5</integer>
+ <key>openTypeOS2WinAscent</key>
+ <integer>2100</integer>
+ <key>openTypeOS2WinDescent</key>
+ <integer>550</integer>
+ <key>postscriptBlueValues</key>
+ <array>
+ <integer>-490</integer>
+ <integer>-490</integer>
+ <integer>-25</integer>
+ <integer>0</integer>
+ <integer>1020</integer>
+ <integer>1040</integer>
+ <integer>1455</integer>
+ <integer>1485</integer>
+ <integer>1600</integer>
+ <integer>1620</integer>
+ </array>
+ <key>postscriptFontName</key>
+ <string>PsfTest-Bold</string>
+ <key>postscriptFullName</key>
+ <string>Psf Test Bold</string>
+ <key>postscriptStemSnapH</key>
+ <array>
+ <integer>140</integer>
+ <integer>145</integer>
+ <integer>150</integer>
+ <integer>155</integer>
+ <integer>160</integer>
+ <integer>165</integer>
+ <integer>170</integer>
+ <integer>175</integer>
+ <integer>185</integer>
+ <integer>270</integer>
+ </array>
+ <key>postscriptStemSnapV</key>
+ <array>
+ <integer>165</integer>
+ <integer>180</integer>
+ <integer>185</integer>
+ <integer>190</integer>
+ <integer>195</integer>
+ <integer>200</integer>
+ <integer>205</integer>
+ <integer>270</integer>
+ </array>
+ <key>postscriptUnderlinePosition</key>
+ <integer>-110</integer>
+ <key>postscriptUnderlineThickness</key>
+ <integer>80</integer>
+ <key>styleMapFamilyName</key>
+ <string>Psf Test</string>
+ <key>styleMapStyleName</key>
+ <string>bold</string>
+ <key>styleName</key>
+ <string>Bold</string>
+ <key>trademark</key>
+ <string>Andika is a trademark of SIL International.</string>
+ <key>unitsPerEm</key>
+ <integer>2048</integer>
+ <key>versionMajor</key>
+ <integer>5</integer>
+ <key>versionMinor</key>
+ <integer>550</integer>
+ <key>xHeight</key>
+ <integer>1040</integer>
+</dict>
+</plist>
diff --git a/tests/input/font-psf-test/source/PsfTest-Bold.ufo/glyphs/A_mpersand.glif b/tests/input/font-psf-test/source/PsfTest-Bold.ufo/glyphs/A_mpersand.glif
new file mode 100644
index 0000000..f2749f2
--- /dev/null
+++ b/tests/input/font-psf-test/source/PsfTest-Bold.ufo/glyphs/A_mpersand.glif
@@ -0,0 +1,61 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="Ampersand" format="2">
+ <advance width="1355"/>
+ <unicode hex="0026"/>
+ <outline>
+ <contour>
+ <point x="1060" y="600" type="line"/>
+ <point x="996" y="433"/>
+ <point x="715" y="190"/>
+ <point x="540" y="190" type="curve" smooth="yes"/>
+ <point x="425" y="190"/>
+ <point x="335" y="257"/>
+ <point x="335" y="370" type="curve" smooth="yes"/>
+ <point x="335" y="480"/>
+ <point x="411" y="547"/>
+ <point x="585" y="700" type="curve" smooth="yes"/>
+ <point x="766" y="859"/>
+ <point x="925" y="1048"/>
+ <point x="925" y="1190" type="curve" smooth="yes"/>
+ <point x="925" y="1372"/>
+ <point x="777" y="1485"/>
+ <point x="575" y="1485" type="curve" smooth="yes"/>
+ <point x="366" y="1485"/>
+ <point x="190" y="1372"/>
+ <point x="190" y="1160" type="curve" smooth="yes"/>
+ <point x="190" y="1000"/>
+ <point x="407" y="785"/>
+ <point x="590" y="540" type="curve" smooth="yes"/>
+ <point x="859" y="179"/>
+ <point x="1038" y="-25"/>
+ <point x="1090" y="-25" type="curve" smooth="yes"/>
+ <point x="1125" y="-25"/>
+ <point x="1253" y="58"/>
+ <point x="1290" y="90" type="curve"/>
+ <point x="1195" y="130"/>
+ <point x="1060" y="305"/>
+ <point x="785" y="680" type="curve" smooth="yes"/>
+ <point x="619" y="906"/>
+ <point x="420" y="1085"/>
+ <point x="420" y="1170" type="curve" smooth="yes"/>
+ <point x="420" y="1241"/>
+ <point x="483" y="1310"/>
+ <point x="560" y="1310" type="curve" smooth="yes"/>
+ <point x="640" y="1310"/>
+ <point x="695" y="1254"/>
+ <point x="695" y="1175" type="curve" smooth="yes"/>
+ <point x="695" y="1106"/>
+ <point x="628" y="1001"/>
+ <point x="455" y="840" type="curve" smooth="yes"/>
+ <point x="251" y="651"/>
+ <point x="90" y="527"/>
+ <point x="90" y="344" type="curve" smooth="yes"/>
+ <point x="90" y="121"/>
+ <point x="242" y="-25"/>
+ <point x="525" y="-25" type="curve" smooth="yes"/>
+ <point x="808" y="-25"/>
+ <point x="1117" y="264"/>
+ <point x="1195" y="425" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/input/font-psf-test/source/PsfTest-Bold.ufo/glyphs/A_pos.glif b/tests/input/font-psf-test/source/PsfTest-Bold.ufo/glyphs/A_pos.glif
new file mode 100644
index 0000000..61494e8
--- /dev/null
+++ b/tests/input/font-psf-test/source/PsfTest-Bold.ufo/glyphs/A_pos.glif
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="Apos" format="2">
+ <advance width="625"/>
+ <unicode hex="0027"/>
+ <outline>
+ <contour>
+ <point x="400" y="1045" type="line"/>
+ <point x="405" y="1186"/>
+ <point x="406" y="1339"/>
+ <point x="435" y="1585" type="curve"/>
+ <point x="190" y="1585" type="line"/>
+ <point x="221" y="1339"/>
+ <point x="221" y="1186"/>
+ <point x="225" y="1045" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/input/font-psf-test/source/PsfTest-Bold.ufo/glyphs/A_sterisk.glif b/tests/input/font-psf-test/source/PsfTest-Bold.ufo/glyphs/A_sterisk.glif
new file mode 100644
index 0000000..ed9d25e
--- /dev/null
+++ b/tests/input/font-psf-test/source/PsfTest-Bold.ufo/glyphs/A_sterisk.glif
@@ -0,0 +1,51 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="Asterisk" format="2">
+ <advance width="1040"/>
+ <unicode hex="002A"/>
+ <outline>
+ <contour>
+ <point x="827" y="1493" type="line"/>
+ <point x="747" y="1426"/>
+ <point x="679" y="1367"/>
+ <point x="594" y="1308" type="curve"/>
+ <point x="599" y="1405"/>
+ <point x="609" y="1486"/>
+ <point x="624" y="1600" type="curve"/>
+ <point x="425" y="1600" type="line"/>
+ <point x="444" y="1497"/>
+ <point x="460" y="1412"/>
+ <point x="468" y="1308" type="curve"/>
+ <point x="383" y="1360"/>
+ <point x="312" y="1408"/>
+ <point x="228" y="1476" type="curve"/>
+ <point x="126" y="1306" type="line"/>
+ <point x="231" y="1271"/>
+ <point x="331" y="1234"/>
+ <point x="412" y="1196" type="curve"/>
+ <point x="328" y="1153"/>
+ <point x="243" y="1120"/>
+ <point x="136" y="1077" type="curve"/>
+ <point x="237" y="897" type="line"/>
+ <point x="316" y="968"/>
+ <point x="382" y="1026"/>
+ <point x="466" y="1087" type="curve"/>
+ <point x="459" y="983"/>
+ <point x="449" y="896"/>
+ <point x="431" y="793" type="curve"/>
+ <point x="632" y="793" type="line"/>
+ <point x="610" y="906"/>
+ <point x="602" y="987"/>
+ <point x="593" y="1084" type="curve"/>
+ <point x="682" y="1027"/>
+ <point x="747" y="981"/>
+ <point x="830" y="914" type="curve"/>
+ <point x="936" y="1089" type="line"/>
+ <point x="827" y="1127"/>
+ <point x="743" y="1155"/>
+ <point x="651" y="1196" type="curve"/>
+ <point x="738" y="1241"/>
+ <point x="820" y="1277"/>
+ <point x="924" y="1321" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/input/font-psf-test/source/PsfTest-Bold.ufo/glyphs/A_tS_gn.glif b/tests/input/font-psf-test/source/PsfTest-Bold.ufo/glyphs/A_tS_gn.glif
new file mode 100644
index 0000000..47fee96
--- /dev/null
+++ b/tests/input/font-psf-test/source/PsfTest-Bold.ufo/glyphs/A_tS_gn.glif
@@ -0,0 +1,80 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="AtSgn" format="2">
+ <advance width="1742"/>
+ <unicode hex="0040"/>
+ <outline>
+ <contour>
+ <point x="1140" y="10" type="line"/>
+ <point x="1077" y="-34"/>
+ <point x="988" y="-60"/>
+ <point x="895" y="-60" type="curve" smooth="yes"/>
+ <point x="558" y="-60"/>
+ <point x="290" y="204"/>
+ <point x="290" y="605" type="curve" smooth="yes"/>
+ <point x="290" y="973"/>
+ <point x="557" y="1240"/>
+ <point x="895" y="1240" type="curve" smooth="yes"/>
+ <point x="1278" y="1240"/>
+ <point x="1460" y="992"/>
+ <point x="1460" y="670" type="curve" smooth="yes"/>
+ <point x="1460" y="452"/>
+ <point x="1363" y="335"/>
+ <point x="1305" y="335" type="curve" smooth="yes"/>
+ <point x="1256" y="335"/>
+ <point x="1220" y="430"/>
+ <point x="1220" y="650" type="curve" smooth="yes"/>
+ <point x="1220" y="980" type="line"/>
+ <point x="1133" y="1015"/>
+ <point x="986" y="1040"/>
+ <point x="905" y="1040" type="curve" smooth="yes"/>
+ <point x="741" y="1040"/>
+ <point x="618" y="961"/>
+ <point x="535" y="825" type="curve" smooth="yes"/>
+ <point x="488" y="746"/>
+ <point x="460" y="653"/>
+ <point x="460" y="530" type="curve" smooth="yes"/>
+ <point x="460" y="304"/>
+ <point x="606" y="163"/>
+ <point x="740" y="163" type="curve" smooth="yes"/>
+ <point x="867" y="163"/>
+ <point x="1013" y="331"/>
+ <point x="1065" y="455" type="curve"/>
+ <point x="1075" y="287"/>
+ <point x="1153" y="160"/>
+ <point x="1275" y="160" type="curve" smooth="yes"/>
+ <point x="1450" y="160"/>
+ <point x="1650" y="358"/>
+ <point x="1650" y="700" type="curve" smooth="yes"/>
+ <point x="1650" y="1137"/>
+ <point x="1342" y="1425"/>
+ <point x="905" y="1425" type="curve" smooth="yes"/>
+ <point x="480" y="1425"/>
+ <point x="90" y="1136"/>
+ <point x="90" y="575" type="curve" smooth="yes"/>
+ <point x="90" y="38"/>
+ <point x="479" y="-245"/>
+ <point x="880" y="-245" type="curve" smooth="yes"/>
+ <point x="1015" y="-245"/>
+ <point x="1175" y="-198"/>
+ <point x="1275" y="-128" type="curve"/>
+ </contour>
+ <contour>
+ <point x="1020" y="710" type="line"/>
+ <point x="988" y="572"/>
+ <point x="863" y="350"/>
+ <point x="773" y="350" type="curve" smooth="yes"/>
+ <point x="701" y="350"/>
+ <point x="660" y="428"/>
+ <point x="660" y="575" type="curve" smooth="yes"/>
+ <point x="660" y="652"/>
+ <point x="682" y="737"/>
+ <point x="720" y="786" type="curve" smooth="yes"/>
+ <point x="756" y="831"/>
+ <point x="807" y="855"/>
+ <point x="875" y="855" type="curve" smooth="yes"/>
+ <point x="949" y="855"/>
+ <point x="987" y="836"/>
+ <point x="1020" y="820" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/input/font-psf-test/source/PsfTest-Bold.ufo/glyphs/C_ircumA_ccent.glif b/tests/input/font-psf-test/source/PsfTest-Bold.ufo/glyphs/C_ircumA_ccent.glif
new file mode 100644
index 0000000..7258b7d
--- /dev/null
+++ b/tests/input/font-psf-test/source/PsfTest-Bold.ufo/glyphs/C_ircumA_ccent.glif
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="CircumAccent" format="2">
+ <advance width="880"/>
+ <unicode hex="005E"/>
+ <anchor x="440" y="1635" name="U"/>
+ <outline>
+ <contour>
+ <point x="888" y="1200" type="line"/>
+ <point x="598" y="1600" type="line"/>
+ <point x="298" y="1600" type="line"/>
+ <point x="8" y="1200" type="line"/>
+ <point x="248" y="1200" type="line"/>
+ <point x="448" y="1430" type="line"/>
+ <point x="648" y="1200" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/input/font-psf-test/source/PsfTest-Bold.ufo/glyphs/C_olon.glif b/tests/input/font-psf-test/source/PsfTest-Bold.ufo/glyphs/C_olon.glif
new file mode 100644
index 0000000..ae4801a
--- /dev/null
+++ b/tests/input/font-psf-test/source/PsfTest-Bold.ufo/glyphs/C_olon.glif
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="Colon" format="2">
+ <advance width="710"/>
+ <unicode hex="003A"/>
+ <outline>
+ <contour>
+ <point x="200" y="150" type="curve" smooth="yes"/>
+ <point x="200" y="46"/>
+ <point x="274" y="-25"/>
+ <point x="375" y="-25" type="curve" smooth="yes"/>
+ <point x="477" y="-25"/>
+ <point x="550" y="46"/>
+ <point x="550" y="150" type="curve" smooth="yes"/>
+ <point x="550" y="252"/>
+ <point x="477" y="325"/>
+ <point x="375" y="325" type="curve" smooth="yes"/>
+ <point x="274" y="325"/>
+ <point x="200" y="252"/>
+ </contour>
+ <contour>
+ <point x="200" y="750" type="curve" smooth="yes"/>
+ <point x="200" y="646"/>
+ <point x="274" y="575"/>
+ <point x="375" y="575" type="curve" smooth="yes"/>
+ <point x="477" y="575"/>
+ <point x="550" y="646"/>
+ <point x="550" y="750" type="curve" smooth="yes"/>
+ <point x="550" y="852"/>
+ <point x="477" y="925"/>
+ <point x="375" y="925" type="curve" smooth="yes"/>
+ <point x="274" y="925"/>
+ <point x="200" y="852"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/input/font-psf-test/source/PsfTest-Bold.ufo/glyphs/C_ombA_cute.glif b/tests/input/font-psf-test/source/PsfTest-Bold.ufo/glyphs/C_ombA_cute.glif
new file mode 100644
index 0000000..5574223
--- /dev/null
+++ b/tests/input/font-psf-test/source/PsfTest-Bold.ufo/glyphs/C_ombA_cute.glif
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="CombAcute" format="2">
+ <unicode hex="0301"/>
+ <anchor x="-600" y="1635" name="U"/>
+ <anchor x="-540" y="1100" name="_U"/>
+ <outline>
+ <contour>
+ <point x="-470" y="1600" type="line"/>
+ <point x="-760" y="1200" type="line"/>
+ <point x="-520" y="1200" type="line"/>
+ <point x="-120" y="1600" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/input/font-psf-test/source/PsfTest-Bold.ufo/glyphs/C_ombC_ircum.glif b/tests/input/font-psf-test/source/PsfTest-Bold.ufo/glyphs/C_ombC_ircum.glif
new file mode 100644
index 0000000..ca30491
--- /dev/null
+++ b/tests/input/font-psf-test/source/PsfTest-Bold.ufo/glyphs/C_ombC_ircum.glif
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="CombCircum" format="2">
+ <unicode hex="0302"/>
+ <anchor x="-588" y="1635" name="U"/>
+ <anchor x="-580" y="1100" name="_U"/>
+ <outline>
+ <contour>
+ <point x="-140" y="1200" type="line"/>
+ <point x="-430" y="1600" type="line"/>
+ <point x="-730" y="1600" type="line"/>
+ <point x="-1020" y="1200" type="line"/>
+ <point x="-780" y="1200" type="line"/>
+ <point x="-580" y="1430" type="line"/>
+ <point x="-380" y="1200" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/input/font-psf-test/source/PsfTest-Bold.ufo/glyphs/C_ombD_iaer.glif b/tests/input/font-psf-test/source/PsfTest-Bold.ufo/glyphs/C_ombD_iaer.glif
new file mode 100644
index 0000000..5a15368
--- /dev/null
+++ b/tests/input/font-psf-test/source/PsfTest-Bold.ufo/glyphs/C_ombD_iaer.glif
@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="CombDiaer" format="2">
+ <unicode hex="0308"/>
+ <anchor x="-580" y="1585" name="U"/>
+ <anchor x="-580" y="1100" name="_U"/>
+ <outline>
+ <contour>
+ <point x="-510" y="1385" type="curve" smooth="yes"/>
+ <point x="-510" y="1281"/>
+ <point x="-436" y="1210"/>
+ <point x="-335" y="1210" type="curve" smooth="yes"/>
+ <point x="-233" y="1210"/>
+ <point x="-160" y="1281"/>
+ <point x="-160" y="1385" type="curve" smooth="yes"/>
+ <point x="-160" y="1487"/>
+ <point x="-233" y="1560"/>
+ <point x="-335" y="1560" type="curve" smooth="yes"/>
+ <point x="-436" y="1560"/>
+ <point x="-510" y="1487"/>
+ </contour>
+ <contour>
+ <point x="-1000" y="1385" type="curve" smooth="yes"/>
+ <point x="-1000" y="1281"/>
+ <point x="-926" y="1210"/>
+ <point x="-825" y="1210" type="curve" smooth="yes"/>
+ <point x="-723" y="1210"/>
+ <point x="-650" y="1281"/>
+ <point x="-650" y="1385" type="curve" smooth="yes"/>
+ <point x="-650" y="1487"/>
+ <point x="-723" y="1560"/>
+ <point x="-825" y="1560" type="curve" smooth="yes"/>
+ <point x="-926" y="1560"/>
+ <point x="-1000" y="1487"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/input/font-psf-test/source/PsfTest-Bold.ufo/glyphs/C_ombG_rave.glif b/tests/input/font-psf-test/source/PsfTest-Bold.ufo/glyphs/C_ombG_rave.glif
new file mode 100644
index 0000000..33bed8f
--- /dev/null
+++ b/tests/input/font-psf-test/source/PsfTest-Bold.ufo/glyphs/C_ombG_rave.glif
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="CombGrave" format="2">
+ <unicode hex="0300"/>
+ <anchor x="-590" y="1635" name="U"/>
+ <anchor x="-630" y="1100" name="_U"/>
+ <outline>
+ <contour>
+ <point x="-1050" y="1600" type="line"/>
+ <point x="-650" y="1200" type="line"/>
+ <point x="-410" y="1200" type="line"/>
+ <point x="-700" y="1600" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/input/font-psf-test/source/PsfTest-Bold.ufo/glyphs/C_ombR_ingA_bv.glif b/tests/input/font-psf-test/source/PsfTest-Bold.ufo/glyphs/C_ombR_ingA_bv.glif
new file mode 100644
index 0000000..7e03146
--- /dev/null
+++ b/tests/input/font-psf-test/source/PsfTest-Bold.ufo/glyphs/C_ombR_ingA_bv.glif
@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="CombRingAbv" format="2">
+ <unicode hex="030A"/>
+ <anchor x="-570" y="1635" name="U"/>
+ <anchor x="-572" y="1100" name="_U"/>
+ <outline>
+ <contour>
+ <point x="-475" y="1400" type="curve" smooth="yes"/>
+ <point x="-475" y="1345"/>
+ <point x="-515" y="1305"/>
+ <point x="-570" y="1305" type="curve" smooth="yes"/>
+ <point x="-625" y="1305"/>
+ <point x="-665" y="1345"/>
+ <point x="-665" y="1400" type="curve" smooth="yes"/>
+ <point x="-665" y="1455"/>
+ <point x="-625" y="1495"/>
+ <point x="-570" y="1495" type="curve" smooth="yes"/>
+ <point x="-515" y="1495"/>
+ <point x="-475" y="1455"/>
+ </contour>
+ <contour>
+ <point x="-815" y="1400" type="curve" smooth="yes"/>
+ <point x="-815" y="1260"/>
+ <point x="-710" y="1160"/>
+ <point x="-570" y="1160" type="curve" smooth="yes"/>
+ <point x="-430" y="1160"/>
+ <point x="-325" y="1260"/>
+ <point x="-325" y="1400" type="curve" smooth="yes"/>
+ <point x="-325" y="1540"/>
+ <point x="-430" y="1640"/>
+ <point x="-570" y="1640" type="curve" smooth="yes"/>
+ <point x="-710" y="1640"/>
+ <point x="-815" y="1540"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/input/font-psf-test/source/PsfTest-Bold.ufo/glyphs/C_ombT_ilde.glif b/tests/input/font-psf-test/source/PsfTest-Bold.ufo/glyphs/C_ombT_ilde.glif
new file mode 100644
index 0000000..ee23af5
--- /dev/null
+++ b/tests/input/font-psf-test/source/PsfTest-Bold.ufo/glyphs/C_ombT_ilde.glif
@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="CombTilde" format="2">
+ <unicode hex="0303"/>
+ <anchor x="-580" y="1490" name="U"/>
+ <anchor x="-580" y="1100" name="_U"/>
+ <outline>
+ <contour>
+ <point x="-830" y="1190" type="line"/>
+ <point x="-824" y="1232"/>
+ <point x="-803" y="1280"/>
+ <point x="-753" y="1280" type="curve" smooth="yes"/>
+ <point x="-710" y="1280"/>
+ <point x="-653" y="1264"/>
+ <point x="-570" y="1229" type="curve" smooth="yes"/>
+ <point x="-500" y="1199"/>
+ <point x="-448" y="1180"/>
+ <point x="-386" y="1180" type="curve" smooth="yes"/>
+ <point x="-250" y="1180"/>
+ <point x="-155" y="1307"/>
+ <point x="-155" y="1480" type="curve"/>
+ <point x="-310" y="1480" type="line"/>
+ <point x="-318" y="1438"/>
+ <point x="-340" y="1390"/>
+ <point x="-387" y="1390" type="curve" smooth="yes"/>
+ <point x="-435" y="1390"/>
+ <point x="-472" y="1408"/>
+ <point x="-550" y="1437" type="curve" smooth="yes"/>
+ <point x="-629" y="1466"/>
+ <point x="-695" y="1490"/>
+ <point x="-760" y="1490" type="curve" smooth="yes"/>
+ <point x="-892" y="1490"/>
+ <point x="-985" y="1349"/>
+ <point x="-985" y="1190" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/input/font-psf-test/source/PsfTest-Bold.ufo/glyphs/C_omma.glif b/tests/input/font-psf-test/source/PsfTest-Bold.ufo/glyphs/C_omma.glif
new file mode 100644
index 0000000..9d4845e
--- /dev/null
+++ b/tests/input/font-psf-test/source/PsfTest-Bold.ufo/glyphs/C_omma.glif
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="Comma" format="2">
+ <advance width="665"/>
+ <unicode hex="002C"/>
+ <outline>
+ <contour>
+ <point x="185" y="50" type="line"/>
+ <point x="345" y="50" type="line"/>
+ <point x="345" y="-34"/>
+ <point x="290" y="-153"/>
+ <point x="185" y="-265" type="curve"/>
+ <point x="330" y="-335" type="line"/>
+ <point x="454" y="-228"/>
+ <point x="560" y="-49"/>
+ <point x="560" y="130" type="curve" smooth="yes"/>
+ <point x="560" y="254"/>
+ <point x="489" y="340"/>
+ <point x="375" y="340" type="curve" smooth="yes"/>
+ <point x="262" y="340"/>
+ <point x="185" y="255"/>
+ <point x="185" y="180" type="curve" smooth="yes"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/input/font-psf-test/source/PsfTest-Bold.ufo/glyphs/D_igitE_ight.glif b/tests/input/font-psf-test/source/PsfTest-Bold.ufo/glyphs/D_igitE_ight.glif
new file mode 100644
index 0000000..a59fff4
--- /dev/null
+++ b/tests/input/font-psf-test/source/PsfTest-Bold.ufo/glyphs/D_igitE_ight.glif
@@ -0,0 +1,63 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="DigitEight" format="2">
+ <advance width="1200"/>
+ <unicode hex="0038"/>
+ <anchor x="600" y="-100" name="L"/>
+ <anchor x="600" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="600" y="-25" type="curve" smooth="yes"/>
+ <point x="877" y="-25"/>
+ <point x="1130" y="144"/>
+ <point x="1130" y="415" type="curve" smooth="yes"/>
+ <point x="1130" y="641"/>
+ <point x="985" y="739"/>
+ <point x="875" y="795" type="curve"/>
+ <point x="953" y="841"/>
+ <point x="1060" y="923"/>
+ <point x="1060" y="1105" type="curve" smooth="yes"/>
+ <point x="1060" y="1350"/>
+ <point x="860" y="1485"/>
+ <point x="610" y="1485" type="curve" smooth="yes"/>
+ <point x="361" y="1485"/>
+ <point x="140" y="1350"/>
+ <point x="140" y="1105" type="curve" smooth="yes"/>
+ <point x="140" y="923"/>
+ <point x="252" y="838"/>
+ <point x="330" y="795" type="curve"/>
+ <point x="201" y="725"/>
+ <point x="70" y="631"/>
+ <point x="70" y="405" type="curve" smooth="yes"/>
+ <point x="70" y="134"/>
+ <point x="324" y="-25"/>
+ </contour>
+ <contour>
+ <point x="810" y="1100" type="curve" smooth="yes"/>
+ <point x="810" y="974"/>
+ <point x="733" y="895"/>
+ <point x="600" y="895" type="curve" smooth="yes"/>
+ <point x="467" y="895"/>
+ <point x="390" y="974"/>
+ <point x="390" y="1100" type="curve" smooth="yes"/>
+ <point x="390" y="1217"/>
+ <point x="477" y="1290"/>
+ <point x="600" y="1290" type="curve" smooth="yes"/>
+ <point x="743" y="1290"/>
+ <point x="810" y="1207"/>
+ </contour>
+ <contour>
+ <point x="865" y="435" type="curve" smooth="yes"/>
+ <point x="865" y="300"/>
+ <point x="768" y="185"/>
+ <point x="600" y="185" type="curve" smooth="yes"/>
+ <point x="440" y="185"/>
+ <point x="335" y="300"/>
+ <point x="335" y="435" type="curve" smooth="yes"/>
+ <point x="335" y="582"/>
+ <point x="450" y="680"/>
+ <point x="600" y="680" type="curve" smooth="yes"/>
+ <point x="748" y="680"/>
+ <point x="865" y="582"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/input/font-psf-test/source/PsfTest-Bold.ufo/glyphs/D_igitF_ive.glif b/tests/input/font-psf-test/source/PsfTest-Bold.ufo/glyphs/D_igitF_ive.glif
new file mode 100644
index 0000000..102780d
--- /dev/null
+++ b/tests/input/font-psf-test/source/PsfTest-Bold.ufo/glyphs/D_igitF_ive.glif
@@ -0,0 +1,44 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="DigitFive" format="2">
+ <advance width="1200"/>
+ <unicode hex="0035"/>
+ <anchor x="600" y="-100" name="L"/>
+ <anchor x="600" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="175" y="645" type="line"/>
+ <point x="299" y="693"/>
+ <point x="404" y="710"/>
+ <point x="510" y="710" type="curve" smooth="yes"/>
+ <point x="670" y="710"/>
+ <point x="810" y="632"/>
+ <point x="810" y="470" type="curve" smooth="yes"/>
+ <point x="810" y="318"/>
+ <point x="690" y="215"/>
+ <point x="530" y="215" type="curve" smooth="yes"/>
+ <point x="390" y="215"/>
+ <point x="274" y="252"/>
+ <point x="140" y="360" type="curve"/>
+ <point x="100" y="80" type="line"/>
+ <point x="225" y="2"/>
+ <point x="365" y="-25"/>
+ <point x="520" y="-25" type="curve" smooth="yes"/>
+ <point x="833" y="-25"/>
+ <point x="1090" y="163"/>
+ <point x="1090" y="475" type="curve" smooth="yes"/>
+ <point x="1090" y="752"/>
+ <point x="882" y="930"/>
+ <point x="605" y="930" type="curve" smooth="yes"/>
+ <point x="543" y="930"/>
+ <point x="468" y="911"/>
+ <point x="435" y="895" type="curve"/>
+ <point x="435" y="1215" type="line"/>
+ <point x="765" y="1215" type="line" smooth="yes"/>
+ <point x="849" y="1215"/>
+ <point x="955" y="1211"/>
+ <point x="1030" y="1195" type="curve"/>
+ <point x="1030" y="1460" type="line"/>
+ <point x="175" y="1460" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/input/font-psf-test/source/PsfTest-Bold.ufo/glyphs/D_igitF_our.glif b/tests/input/font-psf-test/source/PsfTest-Bold.ufo/glyphs/D_igitF_our.glif
new file mode 100644
index 0000000..7d2cbe6
--- /dev/null
+++ b/tests/input/font-psf-test/source/PsfTest-Bold.ufo/glyphs/D_igitF_our.glif
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="DigitFour" format="2">
+ <advance width="1200"/>
+ <unicode hex="0034"/>
+ <anchor x="607" y="-100" name="L"/>
+ <anchor x="607" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="1155" y="345" type="line"/>
+ <point x="1155" y="570" type="line"/>
+ <point x="995" y="570" type="line"/>
+ <point x="995" y="1460" type="line"/>
+ <point x="695" y="1460" type="line"/>
+ <point x="60" y="570" type="line"/>
+ <point x="60" y="345" type="line"/>
+ <point x="730" y="345" type="line"/>
+ <point x="730" y="0" type="line"/>
+ <point x="995" y="0" type="line"/>
+ <point x="995" y="345" type="line"/>
+ </contour>
+ <contour>
+ <point x="730" y="1145" type="line"/>
+ <point x="730" y="570" type="line"/>
+ <point x="305" y="570" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/input/font-psf-test/source/PsfTest-Bold.ufo/glyphs/D_igitN_ine.glif b/tests/input/font-psf-test/source/PsfTest-Bold.ufo/glyphs/D_igitN_ine.glif
new file mode 100644
index 0000000..b1e153b
--- /dev/null
+++ b/tests/input/font-psf-test/source/PsfTest-Bold.ufo/glyphs/D_igitN_ine.glif
@@ -0,0 +1,49 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="DigitNine" format="2">
+ <advance width="1200"/>
+ <unicode hex="0039"/>
+ <anchor x="600" y="-100" name="L"/>
+ <anchor x="600" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="154" y="65" type="line"/>
+ <point x="248" y="5"/>
+ <point x="364" y="-25"/>
+ <point x="492" y="-25" type="curve" smooth="yes"/>
+ <point x="967" y="-25"/>
+ <point x="1135" y="411"/>
+ <point x="1135" y="780" type="curve" smooth="yes"/>
+ <point x="1135" y="1150"/>
+ <point x="977" y="1485"/>
+ <point x="589" y="1485" type="curve" smooth="yes"/>
+ <point x="310" y="1485"/>
+ <point x="70" y="1300"/>
+ <point x="70" y="1002" type="curve" smooth="yes"/>
+ <point x="70" y="763"/>
+ <point x="272" y="576"/>
+ <point x="550" y="576" type="curve" smooth="yes"/>
+ <point x="741" y="576"/>
+ <point x="913" y="707"/>
+ <point x="1010" y="868" type="curve"/>
+ <point x="939" y="991" type="line"/>
+ <point x="865" y="877"/>
+ <point x="729" y="790"/>
+ <point x="574" y="790" type="curve" smooth="yes"/>
+ <point x="425" y="790"/>
+ <point x="326" y="890"/>
+ <point x="326" y="1036" type="curve" smooth="yes"/>
+ <point x="326" y="1153"/>
+ <point x="425" y="1250"/>
+ <point x="573" y="1250" type="curve" smooth="yes"/>
+ <point x="773" y="1250"/>
+ <point x="870" y="1102"/>
+ <point x="870" y="813" type="curve" smooth="yes"/>
+ <point x="870" y="326"/>
+ <point x="699" y="210"/>
+ <point x="502" y="210" type="curve" smooth="yes"/>
+ <point x="406" y="210"/>
+ <point x="294" y="234"/>
+ <point x="208" y="320" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/input/font-psf-test/source/PsfTest-Bold.ufo/glyphs/D_igitO_ne.glif b/tests/input/font-psf-test/source/PsfTest-Bold.ufo/glyphs/D_igitO_ne.glif
new file mode 100644
index 0000000..c744b9f
--- /dev/null
+++ b/tests/input/font-psf-test/source/PsfTest-Bold.ufo/glyphs/D_igitO_ne.glif
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="DigitOne" format="2">
+ <advance width="1200"/>
+ <unicode hex="0031"/>
+ <anchor x="600" y="-100" name="L"/>
+ <anchor x="600" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="1075" y="0" type="line"/>
+ <point x="1075" y="235" type="line"/>
+ <point x="767" y="235" type="line"/>
+ <point x="767" y="1460" type="line"/>
+ <point x="492" y="1460" type="line"/>
+ <point x="177" y="1278" type="line"/>
+ <point x="212" y="1018" type="line"/>
+ <point x="492" y="1170" type="line"/>
+ <point x="492" y="235" type="line"/>
+ <point x="185" y="235" type="line"/>
+ <point x="185" y="0" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/input/font-psf-test/source/PsfTest-Bold.ufo/glyphs/D_igitS_even.glif b/tests/input/font-psf-test/source/PsfTest-Bold.ufo/glyphs/D_igitS_even.glif
new file mode 100644
index 0000000..63fb1c4
--- /dev/null
+++ b/tests/input/font-psf-test/source/PsfTest-Bold.ufo/glyphs/D_igitS_even.glif
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="DigitSeven" format="2">
+ <advance width="1200"/>
+ <unicode hex="0037"/>
+ <anchor x="600" y="-100" name="L"/>
+ <anchor x="600" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="520" y="0" type="line"/>
+ <point x="649" y="459"/>
+ <point x="834" y="855"/>
+ <point x="1130" y="1260" type="curve"/>
+ <point x="1130" y="1460" type="line"/>
+ <point x="100" y="1460" type="line"/>
+ <point x="100" y="1195" type="line"/>
+ <point x="176" y="1211"/>
+ <point x="292" y="1215"/>
+ <point x="480" y="1215" type="curve" smooth="yes"/>
+ <point x="800" y="1215" type="line"/>
+ <point x="542" y="842"/>
+ <point x="409" y="566"/>
+ <point x="235" y="0" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/input/font-psf-test/source/PsfTest-Bold.ufo/glyphs/D_igitS_ix.glif b/tests/input/font-psf-test/source/PsfTest-Bold.ufo/glyphs/D_igitS_ix.glif
new file mode 100644
index 0000000..7526cc6
--- /dev/null
+++ b/tests/input/font-psf-test/source/PsfTest-Bold.ufo/glyphs/D_igitS_ix.glif
@@ -0,0 +1,49 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="DigitSix" format="2">
+ <advance width="1200"/>
+ <unicode hex="0036"/>
+ <anchor x="610" y="-100" name="L"/>
+ <anchor x="610" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="1073" y="1395" type="line"/>
+ <point x="969" y="1465"/>
+ <point x="873" y="1485"/>
+ <point x="735" y="1485" type="curve" smooth="yes"/>
+ <point x="260" y="1485"/>
+ <point x="90" y="1069"/>
+ <point x="90" y="680" type="curve" smooth="yes"/>
+ <point x="90" y="223"/>
+ <point x="297" y="-25"/>
+ <point x="652" y="-25" type="curve" smooth="yes"/>
+ <point x="955" y="-25"/>
+ <point x="1155" y="179"/>
+ <point x="1155" y="470" type="curve" smooth="yes"/>
+ <point x="1155" y="729"/>
+ <point x="963" y="925"/>
+ <point x="675" y="925" type="curve" smooth="yes"/>
+ <point x="484" y="925"/>
+ <point x="338" y="810"/>
+ <point x="225" y="655" type="curve"/>
+ <point x="290" y="540" type="line"/>
+ <point x="372" y="643"/>
+ <point x="500" y="710"/>
+ <point x="655" y="710" type="curve" smooth="yes"/>
+ <point x="814" y="710"/>
+ <point x="900" y="601"/>
+ <point x="900" y="455" type="curve" smooth="yes"/>
+ <point x="900" y="329"/>
+ <point x="803" y="210"/>
+ <point x="656" y="210" type="curve" smooth="yes"/>
+ <point x="474" y="210"/>
+ <point x="355" y="386"/>
+ <point x="355" y="645" type="curve" smooth="yes"/>
+ <point x="355" y="1132"/>
+ <point x="528" y="1250"/>
+ <point x="725" y="1250" type="curve" smooth="yes"/>
+ <point x="821" y="1250"/>
+ <point x="923" y="1226"/>
+ <point x="1009" y="1140" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/input/font-psf-test/source/PsfTest-Bold.ufo/glyphs/D_igitT_hree.glif b/tests/input/font-psf-test/source/PsfTest-Bold.ufo/glyphs/D_igitT_hree.glif
new file mode 100644
index 0000000..883bd62
--- /dev/null
+++ b/tests/input/font-psf-test/source/PsfTest-Bold.ufo/glyphs/D_igitT_hree.glif
@@ -0,0 +1,52 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="DigitThree" format="2">
+ <advance width="1200"/>
+ <unicode hex="0033"/>
+ <anchor x="600" y="-100" name="L"/>
+ <anchor x="600" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="390" y="885" type="line"/>
+ <point x="390" y="645" type="line"/>
+ <point x="480" y="645" type="line" smooth="yes"/>
+ <point x="706" y="645"/>
+ <point x="835" y="548"/>
+ <point x="835" y="425" type="curve" smooth="yes"/>
+ <point x="835" y="291"/>
+ <point x="708" y="210"/>
+ <point x="565" y="210" type="curve" smooth="yes"/>
+ <point x="405" y="210"/>
+ <point x="244" y="282"/>
+ <point x="135" y="405" type="curve"/>
+ <point x="100" y="130" type="line"/>
+ <point x="205" y="32"/>
+ <point x="368" y="-25"/>
+ <point x="545" y="-25" type="curve" smooth="yes"/>
+ <point x="874" y="-25"/>
+ <point x="1120" y="170"/>
+ <point x="1120" y="405" type="curve" smooth="yes"/>
+ <point x="1120" y="672"/>
+ <point x="892" y="756"/>
+ <point x="750" y="780" type="curve"/>
+ <point x="892" y="809"/>
+ <point x="1070" y="957"/>
+ <point x="1070" y="1140" type="curve" smooth="yes"/>
+ <point x="1070" y="1354"/>
+ <point x="868" y="1485"/>
+ <point x="580" y="1485" type="curve" smooth="yes"/>
+ <point x="413" y="1485"/>
+ <point x="240" y="1416"/>
+ <point x="160" y="1325" type="curve"/>
+ <point x="195" y="1095" type="line"/>
+ <point x="308" y="1211"/>
+ <point x="436" y="1250"/>
+ <point x="590" y="1250" type="curve" smooth="yes"/>
+ <point x="689" y="1250"/>
+ <point x="791" y="1193"/>
+ <point x="791" y="1102" type="curve" smooth="yes"/>
+ <point x="791" y="994"/>
+ <point x="662" y="885"/>
+ <point x="480" y="885" type="curve" smooth="yes"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/input/font-psf-test/source/PsfTest-Bold.ufo/glyphs/D_igitT_wo.glif b/tests/input/font-psf-test/source/PsfTest-Bold.ufo/glyphs/D_igitT_wo.glif
new file mode 100644
index 0000000..1d73732
--- /dev/null
+++ b/tests/input/font-psf-test/source/PsfTest-Bold.ufo/glyphs/D_igitT_wo.glif
@@ -0,0 +1,37 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="DigitTwo" format="2">
+ <advance width="1200"/>
+ <unicode hex="0032"/>
+ <anchor x="600" y="-100" name="L"/>
+ <anchor x="560" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="1090" y="260" type="line"/>
+ <point x="1010" y="246"/>
+ <point x="942" y="245"/>
+ <point x="745" y="245" type="curve" smooth="yes"/>
+ <point x="480" y="245" type="line"/>
+ <point x="699" y="422"/>
+ <point x="1046" y="739"/>
+ <point x="1046" y="1065" type="curve" smooth="yes"/>
+ <point x="1046" y="1323"/>
+ <point x="850" y="1485"/>
+ <point x="560" y="1485" type="curve" smooth="yes"/>
+ <point x="391" y="1485"/>
+ <point x="196" y="1402"/>
+ <point x="105" y="1290" type="curve"/>
+ <point x="170" y="1050" type="line"/>
+ <point x="259" y="1158"/>
+ <point x="412" y="1235"/>
+ <point x="535" y="1235" type="curve" smooth="yes"/>
+ <point x="688" y="1235"/>
+ <point x="758" y="1133"/>
+ <point x="758" y="1015" type="curve" smooth="yes"/>
+ <point x="758" y="758"/>
+ <point x="381" y="415"/>
+ <point x="110" y="220" type="curve"/>
+ <point x="110" y="0" type="line"/>
+ <point x="1090" y="0" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/input/font-psf-test/source/PsfTest-Bold.ufo/glyphs/D_igitZ_ero.glif b/tests/input/font-psf-test/source/PsfTest-Bold.ufo/glyphs/D_igitZ_ero.glif
new file mode 100644
index 0000000..01f4532
--- /dev/null
+++ b/tests/input/font-psf-test/source/PsfTest-Bold.ufo/glyphs/D_igitZ_ero.glif
@@ -0,0 +1,37 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="DigitZero" format="2">
+ <advance width="1200"/>
+ <unicode hex="0030"/>
+ <anchor x="605" y="-100" name="L"/>
+ <anchor x="605" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="850" y="715" type="curve" smooth="yes"/>
+ <point x="850" y="368"/>
+ <point x="762" y="205"/>
+ <point x="600" y="205" type="curve" smooth="yes"/>
+ <point x="432" y="205"/>
+ <point x="350" y="375"/>
+ <point x="350" y="745" type="curve" smooth="yes"/>
+ <point x="350" y="1093"/>
+ <point x="437" y="1255"/>
+ <point x="600" y="1255" type="curve" smooth="yes"/>
+ <point x="772" y="1255"/>
+ <point x="850" y="1086"/>
+ </contour>
+ <contour>
+ <point x="1135" y="740" type="curve" smooth="yes"/>
+ <point x="1135" y="1286"/>
+ <point x="950" y="1485"/>
+ <point x="610" y="1485" type="curve" smooth="yes"/>
+ <point x="291" y="1485"/>
+ <point x="65" y="1283"/>
+ <point x="65" y="720" type="curve" smooth="yes"/>
+ <point x="65" y="165"/>
+ <point x="271" y="-25"/>
+ <point x="590" y="-25" type="curve" smooth="yes"/>
+ <point x="911" y="-25"/>
+ <point x="1135" y="161"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/input/font-psf-test/source/PsfTest-Bold.ufo/glyphs/D_ollarS_gn.glif b/tests/input/font-psf-test/source/PsfTest-Bold.ufo/glyphs/D_ollarS_gn.glif
new file mode 100644
index 0000000..f8b49cd
--- /dev/null
+++ b/tests/input/font-psf-test/source/PsfTest-Bold.ufo/glyphs/D_ollarS_gn.glif
@@ -0,0 +1,57 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="DollarSgn" format="2">
+ <advance width="1200"/>
+ <unicode hex="0024"/>
+ <outline>
+ <contour>
+ <point x="1006" y="1316" type="line"/>
+ <point x="886" y="1374"/>
+ <point x="764" y="1389"/>
+ <point x="623" y="1389" type="curve" smooth="yes"/>
+ <point x="317" y="1389"/>
+ <point x="150" y="1203"/>
+ <point x="150" y="1017" type="curve" smooth="yes"/>
+ <point x="150" y="830"/>
+ <point x="275" y="730"/>
+ <point x="540" y="623" type="curve" smooth="yes"/>
+ <point x="802" y="517"/>
+ <point x="851" y="472"/>
+ <point x="851" y="386" type="curve" smooth="yes"/>
+ <point x="851" y="267"/>
+ <point x="744" y="211"/>
+ <point x="586" y="211" type="curve" smooth="yes"/>
+ <point x="440" y="211"/>
+ <point x="297" y="281"/>
+ <point x="195" y="383" type="curve"/>
+ <point x="123" y="124" type="line"/>
+ <point x="216" y="49"/>
+ <point x="388" y="0"/>
+ <point x="586" y="0" type="curve" smooth="yes"/>
+ <point x="847" y="0"/>
+ <point x="1086" y="147"/>
+ <point x="1086" y="414" type="curve" smooth="yes"/>
+ <point x="1086" y="633"/>
+ <point x="927" y="723"/>
+ <point x="679" y="826" type="curve" smooth="yes"/>
+ <point x="431" y="929"/>
+ <point x="385" y="969"/>
+ <point x="385" y="1040" type="curve" smooth="yes"/>
+ <point x="385" y="1132"/>
+ <point x="466" y="1188"/>
+ <point x="613" y="1188" type="curve" smooth="yes"/>
+ <point x="741" y="1188"/>
+ <point x="876" y="1154"/>
+ <point x="949" y="1077" type="curve"/>
+ </contour>
+ <contour>
+ <point x="548" y="1600" type="line"/>
+ <point x="548" y="788" type="line"/>
+ <point x="518" y="726" type="line"/>
+ <point x="518" y="-220" type="line"/>
+ <point x="688" y="-220" type="line"/>
+ <point x="688" y="668" type="line"/>
+ <point x="718" y="734" type="line"/>
+ <point x="718" y="1600" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/input/font-psf-test/source/PsfTest-Bold.ufo/glyphs/D_ottedC_irc.glif b/tests/input/font-psf-test/source/PsfTest-Bold.ufo/glyphs/D_ottedC_irc.glif
new file mode 100644
index 0000000..4cf5cb4
--- /dev/null
+++ b/tests/input/font-psf-test/source/PsfTest-Bold.ufo/glyphs/D_ottedC_irc.glif
@@ -0,0 +1,235 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="DottedCirc" format="2">
+ <advance width="1106"/>
+ <unicode hex="25CC"/>
+ <anchor x="553" y="0" name="H"/>
+ <anchor x="553" y="-100" name="L"/>
+ <anchor x="810" y="0" name="O"/>
+ <anchor x="553" y="1000" name="U"/>
+ <outline>
+ <contour>
+ <point x="443" y="837" type="curve" smooth="yes"/>
+ <point x="443" y="864"/>
+ <point x="423" y="885"/>
+ <point x="398" y="885" type="curve" smooth="yes"/>
+ <point x="371" y="885"/>
+ <point x="348" y="861"/>
+ <point x="348" y="837" type="curve" smooth="yes"/>
+ <point x="348" y="809"/>
+ <point x="372" y="789"/>
+ <point x="398" y="789" type="curve" smooth="yes"/>
+ <point x="425" y="789"/>
+ <point x="443" y="812"/>
+ </contour>
+ <contour>
+ <point x="758" y="79" type="curve" smooth="yes"/>
+ <point x="758" y="106"/>
+ <point x="736" y="127"/>
+ <point x="710" y="127" type="curve" smooth="yes"/>
+ <point x="685" y="127"/>
+ <point x="662" y="103"/>
+ <point x="662" y="80" type="curve" smooth="yes"/>
+ <point x="662" y="52"/>
+ <point x="686" y="31"/>
+ <point x="710" y="31" type="curve" smooth="yes"/>
+ <point x="737" y="31"/>
+ <point x="758" y="55"/>
+ </contour>
+ <contour>
+ <point x="310" y="749" type="curve" smooth="yes"/>
+ <point x="310" y="775"/>
+ <point x="288" y="796"/>
+ <point x="263" y="796" type="curve" smooth="yes"/>
+ <point x="238" y="796"/>
+ <point x="215" y="774"/>
+ <point x="215" y="747" type="curve" smooth="yes"/>
+ <point x="215" y="722"/>
+ <point x="236" y="701"/>
+ <point x="263" y="701" type="curve" smooth="yes"/>
+ <point x="291" y="701"/>
+ <point x="310" y="720"/>
+ </contour>
+ <contour>
+ <point x="891" y="168" type="curve" smooth="yes"/>
+ <point x="891" y="197"/>
+ <point x="870" y="215"/>
+ <point x="843" y="215" type="curve" smooth="yes"/>
+ <point x="817" y="215"/>
+ <point x="795" y="194"/>
+ <point x="795" y="168" type="curve" smooth="yes"/>
+ <point x="795" y="143"/>
+ <point x="816" y="121"/>
+ <point x="843" y="121" type="curve" smooth="yes"/>
+ <point x="871" y="121"/>
+ <point x="891" y="143"/>
+ </contour>
+ <contour>
+ <point x="222" y="613" type="curve" smooth="yes"/>
+ <point x="222" y="640"/>
+ <point x="199" y="663"/>
+ <point x="173" y="663" type="curve" smooth="yes"/>
+ <point x="149" y="663"/>
+ <point x="126" y="642"/>
+ <point x="126" y="615" type="curve" smooth="yes"/>
+ <point x="126" y="591"/>
+ <point x="145" y="567"/>
+ <point x="173" y="567" type="curve" smooth="yes"/>
+ <point x="197" y="567"/>
+ <point x="222" y="587"/>
+ </contour>
+ <contour>
+ <point x="980" y="301" type="curve" smooth="yes"/>
+ <point x="980" y="327"/>
+ <point x="957" y="348"/>
+ <point x="932" y="348" type="curve" smooth="yes"/>
+ <point x="908" y="348"/>
+ <point x="884" y="332"/>
+ <point x="884" y="301" type="curve" smooth="yes"/>
+ <point x="884" y="277"/>
+ <point x="902" y="254"/>
+ <point x="932" y="254" type="curve" smooth="yes"/>
+ <point x="957" y="254"/>
+ <point x="980" y="274"/>
+ </contour>
+ <contour>
+ <point x="191" y="459" type="curve" smooth="yes"/>
+ <point x="191" y="484"/>
+ <point x="168" y="505"/>
+ <point x="143" y="505" type="curve" smooth="yes"/>
+ <point x="116" y="505"/>
+ <point x="95" y="484"/>
+ <point x="95" y="458" type="curve" smooth="yes"/>
+ <point x="95" y="433"/>
+ <point x="115" y="410"/>
+ <point x="143" y="410" type="curve" smooth="yes"/>
+ <point x="167" y="410"/>
+ <point x="191" y="432"/>
+ </contour>
+ <contour>
+ <point x="1011" y="458" type="curve" smooth="yes"/>
+ <point x="1011" y="484"/>
+ <point x="990" y="506"/>
+ <point x="964" y="506" type="curve" smooth="yes"/>
+ <point x="940" y="506"/>
+ <point x="915" y="484"/>
+ <point x="915" y="457" type="curve" smooth="yes"/>
+ <point x="915" y="433"/>
+ <point x="936" y="411"/>
+ <point x="964" y="411" type="curve" smooth="yes"/>
+ <point x="990" y="411"/>
+ <point x="1011" y="433"/>
+ </contour>
+ <contour>
+ <point x="222" y="302" type="curve" smooth="yes"/>
+ <point x="222" y="328"/>
+ <point x="200" y="348"/>
+ <point x="174" y="348" type="curve" smooth="yes"/>
+ <point x="147" y="348"/>
+ <point x="126" y="326"/>
+ <point x="126" y="302" type="curve" smooth="yes"/>
+ <point x="126" y="275"/>
+ <point x="149" y="253"/>
+ <point x="174" y="253" type="curve" smooth="yes"/>
+ <point x="201" y="253"/>
+ <point x="222" y="277"/>
+ </contour>
+ <contour>
+ <point x="980" y="615" type="curve" smooth="yes"/>
+ <point x="980" y="642"/>
+ <point x="955" y="663"/>
+ <point x="931" y="663" type="curve" smooth="yes"/>
+ <point x="904" y="663"/>
+ <point x="885" y="638"/>
+ <point x="885" y="614" type="curve" smooth="yes"/>
+ <point x="885" y="588"/>
+ <point x="907" y="567"/>
+ <point x="931" y="567" type="curve" smooth="yes"/>
+ <point x="959" y="567"/>
+ <point x="980" y="591"/>
+ </contour>
+ <contour>
+ <point x="310" y="168" type="curve" smooth="yes"/>
+ <point x="310" y="195"/>
+ <point x="291" y="215"/>
+ <point x="263" y="215" type="curve" smooth="yes"/>
+ <point x="238" y="215"/>
+ <point x="215" y="190"/>
+ <point x="215" y="168" type="curve" smooth="yes"/>
+ <point x="215" y="143"/>
+ <point x="238" y="120"/>
+ <point x="263" y="120" type="curve" smooth="yes"/>
+ <point x="289" y="120"/>
+ <point x="310" y="143"/>
+ </contour>
+ <contour>
+ <point x="890" y="748" type="curve" smooth="yes"/>
+ <point x="890" y="774"/>
+ <point x="870" y="796"/>
+ <point x="843" y="796" type="curve" smooth="yes"/>
+ <point x="815" y="796"/>
+ <point x="796" y="773"/>
+ <point x="796" y="748" type="curve" smooth="yes"/>
+ <point x="796" y="724"/>
+ <point x="817" y="700"/>
+ <point x="843" y="700" type="curve" smooth="yes"/>
+ <point x="869" y="700"/>
+ <point x="890" y="722"/>
+ </contour>
+ <contour>
+ <point x="444" y="78" type="curve" smooth="yes"/>
+ <point x="444" y="102"/>
+ <point x="423" y="126"/>
+ <point x="396" y="126" type="curve" smooth="yes"/>
+ <point x="370" y="126"/>
+ <point x="348" y="102"/>
+ <point x="348" y="78" type="curve" smooth="yes"/>
+ <point x="348" y="55"/>
+ <point x="370" y="31"/>
+ <point x="396" y="31" type="curve" smooth="yes"/>
+ <point x="420" y="31"/>
+ <point x="444" y="51"/>
+ </contour>
+ <contour>
+ <point x="758" y="836" type="curve" smooth="yes"/>
+ <point x="758" y="861"/>
+ <point x="737" y="885"/>
+ <point x="710" y="885" type="curve" smooth="yes"/>
+ <point x="684" y="885"/>
+ <point x="663" y="862"/>
+ <point x="663" y="838" type="curve" smooth="yes"/>
+ <point x="663" y="814"/>
+ <point x="683" y="789"/>
+ <point x="710" y="789" type="curve" smooth="yes"/>
+ <point x="734" y="789"/>
+ <point x="758" y="809"/>
+ </contour>
+ <contour>
+ <point x="601" y="47" type="curve" smooth="yes"/>
+ <point x="601" y="73"/>
+ <point x="579" y="95"/>
+ <point x="553" y="95" type="curve" smooth="yes"/>
+ <point x="527" y="95"/>
+ <point x="506" y="73"/>
+ <point x="506" y="47" type="curve" smooth="yes"/>
+ <point x="506" y="21"/>
+ <point x="527" y="0"/>
+ <point x="553" y="0" type="curve" smooth="yes"/>
+ <point x="579" y="0"/>
+ <point x="601" y="21"/>
+ </contour>
+ <contour>
+ <point x="601" y="868" type="curve" smooth="yes"/>
+ <point x="601" y="894"/>
+ <point x="579" y="916"/>
+ <point x="553" y="916" type="curve" smooth="yes"/>
+ <point x="527" y="916"/>
+ <point x="506" y="894"/>
+ <point x="506" y="868" type="curve" smooth="yes"/>
+ <point x="506" y="842"/>
+ <point x="527" y="821"/>
+ <point x="553" y="821" type="curve" smooth="yes"/>
+ <point x="579" y="821"/>
+ <point x="601" y="842"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/input/font-psf-test/source/PsfTest-Bold.ufo/glyphs/E_qS_gn.glif b/tests/input/font-psf-test/source/PsfTest-Bold.ufo/glyphs/E_qS_gn.glif
new file mode 100644
index 0000000..9eeb2ef
--- /dev/null
+++ b/tests/input/font-psf-test/source/PsfTest-Bold.ufo/glyphs/E_qS_gn.glif
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="EqSgn" format="2">
+ <advance width="1200"/>
+ <unicode hex="003D"/>
+ <outline>
+ <contour>
+ <point x="120" y="440" type="line"/>
+ <point x="1080" y="440" type="line"/>
+ <point x="1080" y="650" type="line"/>
+ <point x="120" y="650" type="line"/>
+ </contour>
+ <contour>
+ <point x="120" y="810" type="line"/>
+ <point x="1080" y="810" type="line"/>
+ <point x="1080" y="1020" type="line"/>
+ <point x="120" y="1020" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/input/font-psf-test/source/PsfTest-Bold.ufo/glyphs/E_xclamationM_rk.glif b/tests/input/font-psf-test/source/PsfTest-Bold.ufo/glyphs/E_xclamationM_rk.glif
new file mode 100644
index 0000000..cfdf1a6
--- /dev/null
+++ b/tests/input/font-psf-test/source/PsfTest-Bold.ufo/glyphs/E_xclamationM_rk.glif
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="ExclamationMrk" format="2">
+ <advance width="780"/>
+ <unicode hex="0021"/>
+ <outline>
+ <contour>
+ <point x="530" y="500" type="line"/>
+ <point x="536" y="790"/>
+ <point x="531" y="1076"/>
+ <point x="570" y="1510" type="curve"/>
+ <point x="235" y="1510" type="line"/>
+ <point x="273" y="1076"/>
+ <point x="268" y="790"/>
+ <point x="275" y="500" type="curve"/>
+ </contour>
+ <contour>
+ <point x="230" y="150" type="curve" smooth="yes"/>
+ <point x="230" y="46"/>
+ <point x="304" y="-25"/>
+ <point x="405" y="-25" type="curve" smooth="yes"/>
+ <point x="507" y="-25"/>
+ <point x="580" y="46"/>
+ <point x="580" y="150" type="curve" smooth="yes"/>
+ <point x="580" y="252"/>
+ <point x="507" y="325"/>
+ <point x="405" y="325" type="curve" smooth="yes"/>
+ <point x="304" y="325"/>
+ <point x="230" y="252"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/input/font-psf-test/source/PsfTest-Bold.ufo/glyphs/F_ullS_top.glif b/tests/input/font-psf-test/source/PsfTest-Bold.ufo/glyphs/F_ullS_top.glif
new file mode 100644
index 0000000..b05d598
--- /dev/null
+++ b/tests/input/font-psf-test/source/PsfTest-Bold.ufo/glyphs/F_ullS_top.glif
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="FullStop" format="2">
+ <advance width="710"/>
+ <unicode hex="002E"/>
+ <outline>
+ <contour>
+ <point x="200" y="150" type="curve" smooth="yes"/>
+ <point x="200" y="46"/>
+ <point x="274" y="-25"/>
+ <point x="375" y="-25" type="curve" smooth="yes"/>
+ <point x="477" y="-25"/>
+ <point x="550" y="46"/>
+ <point x="550" y="150" type="curve" smooth="yes"/>
+ <point x="550" y="252"/>
+ <point x="477" y="325"/>
+ <point x="375" y="325" type="curve" smooth="yes"/>
+ <point x="274" y="325"/>
+ <point x="200" y="252"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/input/font-psf-test/source/PsfTest-Bold.ufo/glyphs/G_T_S_gn.glif b/tests/input/font-psf-test/source/PsfTest-Bold.ufo/glyphs/G_T_S_gn.glif
new file mode 100644
index 0000000..650e4d2
--- /dev/null
+++ b/tests/input/font-psf-test/source/PsfTest-Bold.ufo/glyphs/G_T_S_gn.glif
@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="GTSgn" format="2">
+ <advance width="1200"/>
+ <unicode hex="003E"/>
+ <outline>
+ <contour>
+ <point x="130" y="245" type="line"/>
+ <point x="1090" y="635" type="line"/>
+ <point x="1090" y="825" type="line"/>
+ <point x="130" y="1215" type="line"/>
+ <point x="130" y="985" type="line"/>
+ <point x="810" y="730" type="line"/>
+ <point x="130" y="475" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/input/font-psf-test/source/PsfTest-Bold.ufo/glyphs/G_raveA_ccent.glif b/tests/input/font-psf-test/source/PsfTest-Bold.ufo/glyphs/G_raveA_ccent.glif
new file mode 100644
index 0000000..83a5f21
--- /dev/null
+++ b/tests/input/font-psf-test/source/PsfTest-Bold.ufo/glyphs/G_raveA_ccent.glif
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="GraveAccent" format="2">
+ <advance width="640"/>
+ <unicode hex="0060"/>
+ <anchor x="500" y="1635" name="U"/>
+ <outline>
+ <contour>
+ <point x="0" y="1600" type="line"/>
+ <point x="400" y="1200" type="line"/>
+ <point x="640" y="1200" type="line"/>
+ <point x="350" y="1600" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/input/font-psf-test/source/PsfTest-Bold.ufo/glyphs/H_yphen.glif b/tests/input/font-psf-test/source/PsfTest-Bold.ufo/glyphs/H_yphen.glif
new file mode 100644
index 0000000..d79c70a
--- /dev/null
+++ b/tests/input/font-psf-test/source/PsfTest-Bold.ufo/glyphs/H_yphen.glif
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="Hyphen" format="2">
+ <advance width="880"/>
+ <unicode hex="2010"/>
+ <anchor x="440" y="1100" name="U"/>
+ <outline>
+ <contour>
+ <point x="70" y="525" type="line"/>
+ <point x="810" y="525" type="line"/>
+ <point x="810" y="735" type="line"/>
+ <point x="70" y="735" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/input/font-psf-test/source/PsfTest-Bold.ufo/glyphs/H_yphenM_inus.glif b/tests/input/font-psf-test/source/PsfTest-Bold.ufo/glyphs/H_yphenM_inus.glif
new file mode 100644
index 0000000..b88bdd4
--- /dev/null
+++ b/tests/input/font-psf-test/source/PsfTest-Bold.ufo/glyphs/H_yphenM_inus.glif
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="HyphenMinus" format="2">
+ <advance width="895"/>
+ <unicode hex="002D"/>
+ <anchor x="450" y="1100" name="U"/>
+ <outline>
+ <contour>
+ <point x="80" y="525" type="line"/>
+ <point x="815" y="525" type="line"/>
+ <point x="815" y="735" type="line"/>
+ <point x="80" y="735" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/input/font-psf-test/source/PsfTest-Bold.ufo/glyphs/H_yphen_S_oft.glif b/tests/input/font-psf-test/source/PsfTest-Bold.ufo/glyphs/H_yphen_S_oft.glif
new file mode 100644
index 0000000..916f8cf
--- /dev/null
+++ b/tests/input/font-psf-test/source/PsfTest-Bold.ufo/glyphs/H_yphen_S_oft.glif
@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="Hyphen_Soft" format="2">
+ <advance width="895"/>
+ <unicode hex="00AD"/>
+ <anchor x="450" y="1100" name="U"/>
+ <outline>
+ <component base="HyphenMinus"/>
+ </outline>
+</glyph>
diff --git a/tests/input/font-psf-test/source/PsfTest-Bold.ufo/glyphs/L_T_S_gn.glif b/tests/input/font-psf-test/source/PsfTest-Bold.ufo/glyphs/L_T_S_gn.glif
new file mode 100644
index 0000000..ab92cf3
--- /dev/null
+++ b/tests/input/font-psf-test/source/PsfTest-Bold.ufo/glyphs/L_T_S_gn.glif
@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LTSgn" format="2">
+ <advance width="1200"/>
+ <unicode hex="003C"/>
+ <outline>
+ <contour>
+ <point x="1070" y="475" type="line"/>
+ <point x="390" y="730" type="line"/>
+ <point x="1070" y="985" type="line"/>
+ <point x="1070" y="1215" type="line"/>
+ <point x="110" y="825" type="line"/>
+ <point x="110" y="635" type="line"/>
+ <point x="1070" y="245" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/input/font-psf-test/source/PsfTest-Bold.ufo/glyphs/L_ftC_urlyB_rac.glif b/tests/input/font-psf-test/source/PsfTest-Bold.ufo/glyphs/L_ftC_urlyB_rac.glif
new file mode 100644
index 0000000..2370b56
--- /dev/null
+++ b/tests/input/font-psf-test/source/PsfTest-Bold.ufo/glyphs/L_ftC_urlyB_rac.glif
@@ -0,0 +1,47 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LftCurlyBrac" format="2">
+ <advance width="1040"/>
+ <unicode hex="007B"/>
+ <outline>
+ <contour>
+ <point x="895" y="-179" type="line"/>
+ <point x="828" y="-160"/>
+ <point x="704" y="-122"/>
+ <point x="685" y="-100" type="curve" smooth="yes"/>
+ <point x="650" y="-60"/>
+ <point x="663" y="411"/>
+ <point x="645" y="445" type="curve" smooth="yes"/>
+ <point x="621" y="491"/>
+ <point x="483" y="580"/>
+ <point x="483" y="615" type="curve" smooth="yes"/>
+ <point x="483" y="650"/>
+ <point x="620" y="740"/>
+ <point x="643" y="785" type="curve" smooth="yes"/>
+ <point x="661" y="820"/>
+ <point x="650" y="1289"/>
+ <point x="685" y="1330" type="curve" smooth="yes"/>
+ <point x="702" y="1351"/>
+ <point x="807" y="1390"/>
+ <point x="870" y="1409" type="curve"/>
+ <point x="820" y="1640" type="line"/>
+ <point x="692" y="1613"/>
+ <point x="502" y="1562"/>
+ <point x="455" y="1515" type="curve" smooth="yes"/>
+ <point x="381" y="1442"/>
+ <point x="392" y="852"/>
+ <point x="370" y="820" type="curve" smooth="yes"/>
+ <point x="340" y="777"/>
+ <point x="170" y="670"/>
+ <point x="170" y="615" type="curve" smooth="yes"/>
+ <point x="170" y="560"/>
+ <point x="340" y="453"/>
+ <point x="370" y="410" type="curve" smooth="yes"/>
+ <point x="392" y="378"/>
+ <point x="380" y="-213"/>
+ <point x="455" y="-285" type="curve" smooth="yes"/>
+ <point x="505" y="-333"/>
+ <point x="709" y="-383"/>
+ <point x="845" y="-410" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/input/font-psf-test/source/PsfTest-Bold.ufo/glyphs/L_ftP_aren.glif b/tests/input/font-psf-test/source/PsfTest-Bold.ufo/glyphs/L_ftP_aren.glif
new file mode 100644
index 0000000..99e1982
--- /dev/null
+++ b/tests/input/font-psf-test/source/PsfTest-Bold.ufo/glyphs/L_ftP_aren.glif
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LftParen" format="2">
+ <advance width="860"/>
+ <unicode hex="0028"/>
+ <outline>
+ <contour>
+ <point x="555" y="1640" type="line"/>
+ <point x="290" y="1444"/>
+ <point x="115" y="1062"/>
+ <point x="115" y="625" type="curve" smooth="yes"/>
+ <point x="115" y="218"/>
+ <point x="260" y="-125"/>
+ <point x="535" y="-410" type="curve"/>
+ <point x="686" y="-240" type="line"/>
+ <point x="462" y="11"/>
+ <point x="376" y="335"/>
+ <point x="376" y="635" type="curve" smooth="yes"/>
+ <point x="376" y="938"/>
+ <point x="466" y="1261"/>
+ <point x="676" y="1455" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/input/font-psf-test/source/PsfTest-Bold.ufo/glyphs/L_ftS_qrB_rac.glif b/tests/input/font-psf-test/source/PsfTest-Bold.ufo/glyphs/L_ftS_qrB_rac.glif
new file mode 100644
index 0000000..dcf019b
--- /dev/null
+++ b/tests/input/font-psf-test/source/PsfTest-Bold.ufo/glyphs/L_ftS_qrB_rac.glif
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LftSqrBrac" format="2">
+ <advance width="850"/>
+ <unicode hex="005B"/>
+ <outline>
+ <contour>
+ <point x="710" y="-410" type="line"/>
+ <point x="710" y="-200" type="line"/>
+ <point x="470" y="-200" type="line"/>
+ <point x="470" y="1390" type="line"/>
+ <point x="710" y="1390" type="line"/>
+ <point x="710" y="1600" type="line"/>
+ <point x="190" y="1600" type="line"/>
+ <point x="190" y="-410" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/input/font-psf-test/source/PsfTest-Bold.ufo/glyphs/L_owL_ine.glif b/tests/input/font-psf-test/source/PsfTest-Bold.ufo/glyphs/L_owL_ine.glif
new file mode 100644
index 0000000..225c4ce
--- /dev/null
+++ b/tests/input/font-psf-test/source/PsfTest-Bold.ufo/glyphs/L_owL_ine.glif
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LowLine" format="2">
+ <advance width="1274"/>
+ <unicode hex="005F"/>
+ <outline>
+ <contour>
+ <point x="0" y="-350" type="line"/>
+ <point x="1274" y="-350" type="line"/>
+ <point x="1274" y="-140" type="line"/>
+ <point x="0" y="-140" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/input/font-psf-test/source/PsfTest-Bold.ufo/glyphs/L_tnC_apA_.alt.glif b/tests/input/font-psf-test/source/PsfTest-Bold.ufo/glyphs/L_tnC_apA_.alt.glif
new file mode 100644
index 0000000..cf1b900
--- /dev/null
+++ b/tests/input/font-psf-test/source/PsfTest-Bold.ufo/glyphs/L_tnC_apA_.alt.glif
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnCapA.alt" format="2">
+ <advance width="1485"/>
+ <anchor x="1275" y="0" name="H"/>
+ <anchor x="732" y="-100" name="L"/>
+ <anchor x="1495" y="0" name="O"/>
+ <anchor x="732" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="1115" y="0" type="line"/>
+ <point x="1408" y="0" type="line"/>
+ <point x="1373" y="80"/>
+ <point x="1341" y="168"/>
+ <point x="1278" y="355" type="curve" smooth="yes"/>
+ <point x="908" y="1460" type="line"/>
+ <point x="552" y="1460" type="line"/>
+ <point x="182" y="355" type="line" smooth="yes"/>
+ <point x="119" y="166"/>
+ <point x="88" y="81"/>
+ <point x="52" y="0" type="curve"/>
+ <point x="350" y="0" type="line"/>
+ <point x="460" y="355" type="line"/>
+ <point x="1004" y="355" type="line"/>
+ </contour>
+ <contour>
+ <point x="730" y="1228" type="line"/>
+ <point x="936" y="570" type="line"/>
+ <point x="526" y="570" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/input/font-psf-test/source/PsfTest-Bold.ufo/glyphs/L_tnC_apA_.glif b/tests/input/font-psf-test/source/PsfTest-Bold.ufo/glyphs/L_tnC_apA_.glif
new file mode 100644
index 0000000..9fa1f45
--- /dev/null
+++ b/tests/input/font-psf-test/source/PsfTest-Bold.ufo/glyphs/L_tnC_apA_.glif
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnCapA" format="2">
+ <advance width="1485"/>
+ <unicode hex="0041"/>
+ <anchor x="1275" y="0" name="H"/>
+ <anchor x="732" y="-100" name="L"/>
+ <anchor x="1495" y="0" name="O"/>
+ <anchor x="732" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="1115" y="0" type="line"/>
+ <point x="1408" y="0" type="line"/>
+ <point x="1373" y="80"/>
+ <point x="1341" y="168"/>
+ <point x="1278" y="355" type="curve" smooth="yes"/>
+ <point x="908" y="1460" type="line"/>
+ <point x="552" y="1460" type="line"/>
+ <point x="182" y="355" type="line" smooth="yes"/>
+ <point x="119" y="166"/>
+ <point x="88" y="81"/>
+ <point x="52" y="0" type="curve"/>
+ <point x="350" y="0" type="line"/>
+ <point x="460" y="355" type="line"/>
+ <point x="1004" y="355" type="line"/>
+ </contour>
+ <contour>
+ <point x="730" y="1228" type="line"/>
+ <point x="936" y="570" type="line"/>
+ <point x="526" y="570" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/input/font-psf-test/source/PsfTest-Bold.ufo/glyphs/L_tnC_apA_D_iaer.glif b/tests/input/font-psf-test/source/PsfTest-Bold.ufo/glyphs/L_tnC_apA_D_iaer.glif
new file mode 100644
index 0000000..79101d0
--- /dev/null
+++ b/tests/input/font-psf-test/source/PsfTest-Bold.ufo/glyphs/L_tnC_apA_D_iaer.glif
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnCapADiaer" format="2">
+ <advance width="1485"/>
+ <unicode hex="00C4"/>
+ <anchor x="1275" y="0" name="H"/>
+ <anchor x="732" y="-100" name="L"/>
+ <anchor x="1495" y="0" name="O"/>
+ <anchor x="732" y="2015" name="U"/>
+ <outline>
+ <component base="LtnCapA"/>
+ <component base="CombDiaer" xOffset="1312" yOffset="430"/>
+ </outline>
+</glyph>
diff --git a/tests/input/font-psf-test/source/PsfTest-Bold.ufo/glyphs/L_tnC_apB_.glif b/tests/input/font-psf-test/source/PsfTest-Bold.ufo/glyphs/L_tnC_apB_.glif
new file mode 100644
index 0000000..df49e47
--- /dev/null
+++ b/tests/input/font-psf-test/source/PsfTest-Bold.ufo/glyphs/L_tnC_apB_.glif
@@ -0,0 +1,62 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnCapB" format="2">
+ <advance width="1385"/>
+ <unicode hex="0042"/>
+ <anchor x="670" y="-100" name="L"/>
+ <anchor x="670" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="450" y="1248" type="line"/>
+ <point x="487" y="1250"/>
+ <point x="562" y="1253"/>
+ <point x="631" y="1253" type="curve" smooth="yes"/>
+ <point x="818" y="1253"/>
+ <point x="897" y="1196"/>
+ <point x="897" y="1077" type="curve" smooth="yes"/>
+ <point x="897" y="951"/>
+ <point x="794" y="875"/>
+ <point x="605" y="875" type="curve" smooth="yes"/>
+ <point x="450" y="875" type="line"/>
+ </contour>
+ <contour>
+ <point x="1245" y="430" type="curve" smooth="yes"/>
+ <point x="1245" y="672"/>
+ <point x="1084" y="760"/>
+ <point x="935" y="800" type="curve"/>
+ <point x="1065" y="850"/>
+ <point x="1170" y="947"/>
+ <point x="1170" y="1110" type="curve" smooth="yes"/>
+ <point x="1170" y="1378"/>
+ <point x="937" y="1470"/>
+ <point x="615" y="1470" type="curve" smooth="yes"/>
+ <point x="422" y="1470"/>
+ <point x="248" y="1466"/>
+ <point x="150" y="1460" type="curve"/>
+ <point x="165" y="1380"/>
+ <point x="165" y="1196"/>
+ <point x="165" y="1000" type="curve" smooth="yes"/>
+ <point x="165" y="455" type="line" smooth="yes"/>
+ <point x="165" y="257"/>
+ <point x="165" y="80"/>
+ <point x="150" y="0" type="curve"/>
+ <point x="150" y="0"/>
+ <point x="401" y="-10"/>
+ <point x="631" y="-10" type="curve" smooth="yes"/>
+ <point x="1055" y="-10"/>
+ <point x="1245" y="181"/>
+ </contour>
+ <contour>
+ <point x="450" y="658" type="line"/>
+ <point x="643" y="658" type="line" smooth="yes"/>
+ <point x="853" y="658"/>
+ <point x="972" y="587"/>
+ <point x="972" y="450" type="curve" smooth="yes"/>
+ <point x="972" y="269"/>
+ <point x="826" y="215"/>
+ <point x="652" y="215" type="curve" smooth="yes"/>
+ <point x="552" y="215"/>
+ <point x="483" y="218"/>
+ <point x="450" y="220" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/input/font-psf-test/source/PsfTest-Bold.ufo/glyphs/L_tnC_apC_.glif b/tests/input/font-psf-test/source/PsfTest-Bold.ufo/glyphs/L_tnC_apC_.glif
new file mode 100644
index 0000000..78c5238
--- /dev/null
+++ b/tests/input/font-psf-test/source/PsfTest-Bold.ufo/glyphs/L_tnC_apC_.glif
@@ -0,0 +1,38 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnCapC" format="2">
+ <advance width="1385"/>
+ <unicode hex="0043"/>
+ <anchor x="745" y="0" name="H"/>
+ <anchor x="745" y="-100" name="L"/>
+ <anchor x="745" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="1215" y="405" type="line"/>
+ <point x="1105" y="293"/>
+ <point x="940" y="220"/>
+ <point x="790" y="220" type="curve" smooth="yes"/>
+ <point x="531" y="220"/>
+ <point x="375" y="413"/>
+ <point x="375" y="735" type="curve" smooth="yes"/>
+ <point x="375" y="1074"/>
+ <point x="557" y="1245"/>
+ <point x="800" y="1245" type="curve" smooth="yes"/>
+ <point x="931" y="1245"/>
+ <point x="1053" y="1205"/>
+ <point x="1180" y="1105" type="curve"/>
+ <point x="1250" y="1345" type="line"/>
+ <point x="1106" y="1449"/>
+ <point x="969" y="1485"/>
+ <point x="785" y="1485" type="curve" smooth="yes"/>
+ <point x="413" y="1485"/>
+ <point x="90" y="1225"/>
+ <point x="90" y="710" type="curve" smooth="yes"/>
+ <point x="90" y="260"/>
+ <point x="341" y="-25"/>
+ <point x="755" y="-25" type="curve" smooth="yes"/>
+ <point x="926" y="-25"/>
+ <point x="1142" y="42"/>
+ <point x="1265" y="140" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/input/font-psf-test/source/PsfTest-Bold.ufo/glyphs/L_tnC_apD_.glif b/tests/input/font-psf-test/source/PsfTest-Bold.ufo/glyphs/L_tnC_apD_.glif
new file mode 100644
index 0000000..4dd3b9c
--- /dev/null
+++ b/tests/input/font-psf-test/source/PsfTest-Bold.ufo/glyphs/L_tnC_apD_.glif
@@ -0,0 +1,45 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnCapD" format="2">
+ <advance width="1485"/>
+ <unicode hex="0044"/>
+ <anchor x="800" y="-100" name="L"/>
+ <anchor x="800" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="165" y="455" type="line"/>
+ <point x="164" y="257"/>
+ <point x="165" y="80"/>
+ <point x="150" y="0" type="curve"/>
+ <point x="150" y="0"/>
+ <point x="474" y="-10"/>
+ <point x="609" y="-10" type="curve" smooth="yes"/>
+ <point x="919" y="-10"/>
+ <point x="1370" y="145"/>
+ <point x="1370" y="740" type="curve" smooth="yes"/>
+ <point x="1370" y="1374"/>
+ <point x="906" y="1470"/>
+ <point x="630" y="1470" type="curve" smooth="yes"/>
+ <point x="487" y="1470"/>
+ <point x="239" y="1466"/>
+ <point x="150" y="1460" type="curve"/>
+ <point x="165" y="1380"/>
+ <point x="165" y="1196"/>
+ <point x="165" y="1000" type="curve" smooth="yes"/>
+ </contour>
+ <contour>
+ <point x="450" y="1241" type="line"/>
+ <point x="492" y="1243"/>
+ <point x="582" y="1246"/>
+ <point x="637" y="1246" type="curve" smooth="yes"/>
+ <point x="897" y="1246"/>
+ <point x="1078" y="1118"/>
+ <point x="1078" y="720" type="curve" smooth="yes"/>
+ <point x="1078" y="357"/>
+ <point x="856" y="221"/>
+ <point x="633" y="221" type="curve" smooth="yes"/>
+ <point x="554" y="221"/>
+ <point x="489" y="227"/>
+ <point x="450" y="231" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/input/font-psf-test/source/PsfTest-Bold.ufo/glyphs/L_tnC_apE_.glif b/tests/input/font-psf-test/source/PsfTest-Bold.ufo/glyphs/L_tnC_apE_.glif
new file mode 100644
index 0000000..9572dfd
--- /dev/null
+++ b/tests/input/font-psf-test/source/PsfTest-Bold.ufo/glyphs/L_tnC_apE_.glif
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnCapE" format="2">
+ <advance width="1212"/>
+ <unicode hex="0045"/>
+ <anchor x="610" y="0" name="H"/>
+ <anchor x="610" y="-100" name="L"/>
+ <anchor x="1004" y="0" name="O"/>
+ <anchor x="1247" y="1200" name="R"/>
+ <anchor x="610" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="450" y="875" type="line"/>
+ <point x="450" y="1230" type="line"/>
+ <point x="1072" y="1230" type="line"/>
+ <point x="1072" y="1460" type="line"/>
+ <point x="150" y="1460" type="line"/>
+ <point x="165" y="1380"/>
+ <point x="165" y="1222"/>
+ <point x="165" y="1025" type="curve" smooth="yes"/>
+ <point x="165" y="435" type="line" smooth="yes"/>
+ <point x="165" y="238"/>
+ <point x="165" y="80"/>
+ <point x="150" y="0" type="curve"/>
+ <point x="1102" y="0" type="line"/>
+ <point x="1102" y="245" type="line"/>
+ <point x="1024" y="231"/>
+ <point x="899" y="230"/>
+ <point x="708" y="230" type="curve" smooth="yes"/>
+ <point x="450" y="230" type="line"/>
+ <point x="450" y="650" type="line"/>
+ <point x="997" y="650" type="line"/>
+ <point x="997" y="875" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/input/font-psf-test/source/PsfTest-Bold.ufo/glyphs/L_tnC_apF_.glif b/tests/input/font-psf-test/source/PsfTest-Bold.ufo/glyphs/L_tnC_apF_.glif
new file mode 100644
index 0000000..9f4f14b
--- /dev/null
+++ b/tests/input/font-psf-test/source/PsfTest-Bold.ufo/glyphs/L_tnC_apF_.glif
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnCapF" format="2">
+ <advance width="1200"/>
+ <unicode hex="0046"/>
+ <anchor x="630" y="-100" name="L"/>
+ <anchor x="630" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="450" y="860" type="line"/>
+ <point x="450" y="1230" type="line"/>
+ <point x="1090" y="1230" type="line"/>
+ <point x="1090" y="1460" type="line"/>
+ <point x="150" y="1460" type="line"/>
+ <point x="165" y="1380"/>
+ <point x="165" y="1217"/>
+ <point x="165" y="1020" type="curve" smooth="yes"/>
+ <point x="165" y="435" type="line" smooth="yes"/>
+ <point x="165" y="238"/>
+ <point x="165" y="80"/>
+ <point x="150" y="0" type="curve"/>
+ <point x="465" y="0" type="line"/>
+ <point x="450" y="73"/>
+ <point x="450" y="222"/>
+ <point x="450" y="408" type="curve" smooth="yes"/>
+ <point x="450" y="635" type="line"/>
+ <point x="1005" y="635" type="line"/>
+ <point x="1005" y="860" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/input/font-psf-test/source/PsfTest-Bold.ufo/glyphs/L_tnC_apG_.glif b/tests/input/font-psf-test/source/PsfTest-Bold.ufo/glyphs/L_tnC_apG_.glif
new file mode 100644
index 0000000..8358b8a
--- /dev/null
+++ b/tests/input/font-psf-test/source/PsfTest-Bold.ufo/glyphs/L_tnC_apG_.glif
@@ -0,0 +1,42 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnCapG" format="2">
+ <advance width="1472"/>
+ <unicode hex="0047"/>
+ <anchor x="807" y="0" name="H"/>
+ <anchor x="807" y="-100" name="L"/>
+ <anchor x="807" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="1337" y="785" type="line"/>
+ <point x="767" y="785" type="line"/>
+ <point x="767" y="560" type="line"/>
+ <point x="1082" y="560" type="line"/>
+ <point x="1082" y="294" type="line"/>
+ <point x="966" y="236"/>
+ <point x="883" y="220"/>
+ <point x="769" y="220" type="curve" smooth="yes"/>
+ <point x="532" y="220"/>
+ <point x="375" y="420"/>
+ <point x="375" y="745" type="curve" smooth="yes"/>
+ <point x="375" y="1048"/>
+ <point x="545" y="1245"/>
+ <point x="810" y="1245" type="curve" smooth="yes"/>
+ <point x="953" y="1245"/>
+ <point x="1097" y="1205"/>
+ <point x="1236" y="1107" type="curve"/>
+ <point x="1322" y="1345" type="line"/>
+ <point x="1137" y="1462"/>
+ <point x="989" y="1485"/>
+ <point x="818" y="1485" type="curve" smooth="yes"/>
+ <point x="403" y="1485"/>
+ <point x="90" y="1199"/>
+ <point x="90" y="720" type="curve" smooth="yes"/>
+ <point x="90" y="241"/>
+ <point x="377" y="-25"/>
+ <point x="777" y="-25" type="curve" smooth="yes"/>
+ <point x="960" y="-25"/>
+ <point x="1120" y="11"/>
+ <point x="1337" y="155" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/input/font-psf-test/source/PsfTest-Bold.ufo/glyphs/L_tnC_apH_.glif b/tests/input/font-psf-test/source/PsfTest-Bold.ufo/glyphs/L_tnC_apH_.glif
new file mode 100644
index 0000000..2e2e5e6
--- /dev/null
+++ b/tests/input/font-psf-test/source/PsfTest-Bold.ufo/glyphs/L_tnC_apH_.glif
@@ -0,0 +1,40 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnCapH" format="2">
+ <advance width="1515"/>
+ <unicode hex="0048"/>
+ <anchor x="305" y="0" name="H"/>
+ <anchor x="745" y="-100" name="L"/>
+ <anchor x="745" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="1040" y="1460" type="line"/>
+ <point x="1040" y="860" type="line"/>
+ <point x="450" y="860" type="line"/>
+ <point x="450" y="1460" type="line"/>
+ <point x="150" y="1460" type="line"/>
+ <point x="165" y="1380"/>
+ <point x="165" y="1227"/>
+ <point x="165" y="1030" type="curve" smooth="yes"/>
+ <point x="165" y="430" type="line" smooth="yes"/>
+ <point x="165" y="233"/>
+ <point x="165" y="80"/>
+ <point x="150" y="0" type="curve"/>
+ <point x="150" y="0"/>
+ <point x="450" y="0"/>
+ <point x="450" y="0" type="curve"/>
+ <point x="450" y="635" type="line"/>
+ <point x="1040" y="635" type="line"/>
+ <point x="1040" y="0" type="line"/>
+ <point x="1040" y="0"/>
+ <point x="1340" y="0"/>
+ <point x="1340" y="0" type="curve"/>
+ <point x="1325" y="80"/>
+ <point x="1325" y="233"/>
+ <point x="1325" y="430" type="curve" smooth="yes"/>
+ <point x="1325" y="1030" type="line" smooth="yes"/>
+ <point x="1325" y="1227"/>
+ <point x="1325" y="1380"/>
+ <point x="1340" y="1460" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/input/font-psf-test/source/PsfTest-Bold.ufo/glyphs/L_tnC_apI_.glif b/tests/input/font-psf-test/source/PsfTest-Bold.ufo/glyphs/L_tnC_apI_.glif
new file mode 100644
index 0000000..388486b
--- /dev/null
+++ b/tests/input/font-psf-test/source/PsfTest-Bold.ufo/glyphs/L_tnC_apI_.glif
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnCapI" format="2">
+ <advance width="1045"/>
+ <unicode hex="0049"/>
+ <anchor x="520" y="0" name="H"/>
+ <anchor x="516" y="-100" name="L"/>
+ <anchor x="712" y="0" name="O"/>
+ <anchor x="1014" y="1200" name="R"/>
+ <anchor x="520" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="130" y="1460" type="line"/>
+ <point x="130" y="1255" type="line"/>
+ <point x="370" y="1255" type="line"/>
+ <point x="370" y="205" type="line"/>
+ <point x="130" y="205" type="line"/>
+ <point x="130" y="0" type="line"/>
+ <point x="895" y="0" type="line"/>
+ <point x="895" y="205" type="line"/>
+ <point x="655" y="205" type="line"/>
+ <point x="655" y="1255" type="line"/>
+ <point x="895" y="1255" type="line"/>
+ <point x="895" y="1460" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/input/font-psf-test/source/PsfTest-Bold.ufo/glyphs/L_tnC_apJ_.glif b/tests/input/font-psf-test/source/PsfTest-Bold.ufo/glyphs/L_tnC_apJ_.glif
new file mode 100644
index 0000000..8ee9ce3
--- /dev/null
+++ b/tests/input/font-psf-test/source/PsfTest-Bold.ufo/glyphs/L_tnC_apJ_.glif
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnCapJ" format="2">
+ <advance width="1030"/>
+ <unicode hex="004A"/>
+ <anchor x="415" y="-100" name="L"/>
+ <anchor x="705" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="555" y="1460" type="line"/>
+ <point x="568" y="1354"/>
+ <point x="570" y="1175"/>
+ <point x="570" y="980" type="curve" smooth="yes"/>
+ <point x="570" y="558" type="line" smooth="yes"/>
+ <point x="570" y="383"/>
+ <point x="540" y="227"/>
+ <point x="365" y="227" type="curve" smooth="yes"/>
+ <point x="264" y="227"/>
+ <point x="153" y="270"/>
+ <point x="79" y="347" type="curve"/>
+ <point x="30" y="90" type="line"/>
+ <point x="109" y="9"/>
+ <point x="258" y="-25"/>
+ <point x="363" y="-25" type="curve" smooth="yes"/>
+ <point x="658" y="-25"/>
+ <point x="855" y="129"/>
+ <point x="855" y="535" type="curve" smooth="yes"/>
+ <point x="855" y="618"/>
+ <point x="855" y="1460"/>
+ <point x="855" y="1460" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/input/font-psf-test/source/PsfTest-Bold.ufo/glyphs/L_tnC_apK_.glif b/tests/input/font-psf-test/source/PsfTest-Bold.ufo/glyphs/L_tnC_apK_.glif
new file mode 100644
index 0000000..abb6ff7
--- /dev/null
+++ b/tests/input/font-psf-test/source/PsfTest-Bold.ufo/glyphs/L_tnC_apK_.glif
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnCapK" format="2">
+ <advance width="1430"/>
+ <unicode hex="004B"/>
+ <anchor x="320" y="0" name="H"/>
+ <anchor x="740" y="-100" name="L"/>
+ <anchor x="725" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="944" y="1460" type="line"/>
+ <point x="371" y="732" type="line"/>
+ <point x="579" y="676" type="line"/>
+ <point x="1280" y="1460" type="line"/>
+ </contour>
+ <contour>
+ <point x="389" y="731" type="line"/>
+ <point x="990" y="0" type="line"/>
+ <point x="1360" y="0" type="line"/>
+ <point x="614" y="829" type="line"/>
+ </contour>
+ <contour>
+ <point x="450" y="1460" type="line"/>
+ <point x="150" y="1460" type="line"/>
+ <point x="165" y="1380"/>
+ <point x="165" y="1222"/>
+ <point x="165" y="1025" type="curve" smooth="yes"/>
+ <point x="165" y="435" type="line" smooth="yes"/>
+ <point x="165" y="238"/>
+ <point x="165" y="80"/>
+ <point x="150" y="0" type="curve"/>
+ <point x="450" y="0" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/input/font-psf-test/source/PsfTest-Bold.ufo/glyphs/L_tnC_apL_.glif b/tests/input/font-psf-test/source/PsfTest-Bold.ufo/glyphs/L_tnC_apL_.glif
new file mode 100644
index 0000000..e1c1e2e
--- /dev/null
+++ b/tests/input/font-psf-test/source/PsfTest-Bold.ufo/glyphs/L_tnC_apL_.glif
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnCapL" format="2">
+ <advance width="1130"/>
+ <unicode hex="004C"/>
+ <anchor x="620" y="0" name="H"/>
+ <anchor x="620" y="-100" name="L"/>
+ <anchor x="650" y="1200" name="R"/>
+ <anchor x="620" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="450" y="230" type="line"/>
+ <point x="450" y="1460" type="line"/>
+ <point x="150" y="1460" type="line"/>
+ <point x="165" y="1380"/>
+ <point x="165" y="1222"/>
+ <point x="165" y="1025" type="curve" smooth="yes"/>
+ <point x="165" y="435" type="line" smooth="yes"/>
+ <point x="165" y="238"/>
+ <point x="165" y="80"/>
+ <point x="150" y="0" type="curve"/>
+ <point x="1085" y="0" type="line"/>
+ <point x="1085" y="245" type="line"/>
+ <point x="1008" y="231"/>
+ <point x="855" y="230"/>
+ <point x="666" y="230" type="curve" smooth="yes"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/input/font-psf-test/source/PsfTest-Bold.ufo/glyphs/L_tnC_apM_.glif b/tests/input/font-psf-test/source/PsfTest-Bold.ufo/glyphs/L_tnC_apM_.glif
new file mode 100644
index 0000000..8da241e
--- /dev/null
+++ b/tests/input/font-psf-test/source/PsfTest-Bold.ufo/glyphs/L_tnC_apM_.glif
@@ -0,0 +1,38 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnCapM" format="2">
+ <advance width="1855"/>
+ <unicode hex="004D"/>
+ <anchor x="915" y="-100" name="L"/>
+ <anchor x="915" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="917" y="275" type="line"/>
+ <point x="575" y="1460" type="line"/>
+ <point x="315" y="1460" type="line"/>
+ <point x="436" y="1170" type="line"/>
+ <point x="770" y="0" type="line"/>
+ <point x="1065" y="0" type="line"/>
+ <point x="1397" y="1170" type="line"/>
+ <point x="1517" y="1460" type="line"/>
+ <point x="1260" y="1460" type="line"/>
+ </contour>
+ <contour>
+ <point x="220" y="1460" type="line"/>
+ <point x="220" y="1460"/>
+ <point x="176" y="198"/>
+ <point x="150" y="0" type="curve"/>
+ <point x="420" y="0" type="line"/>
+ <point x="449" y="1205" type="line"/>
+ <point x="485" y="1460" type="line"/>
+ </contour>
+ <contour>
+ <point x="1680" y="0" type="line"/>
+ <point x="1651" y="198"/>
+ <point x="1610" y="1460"/>
+ <point x="1610" y="1460" type="curve"/>
+ <point x="1340" y="1460" type="line"/>
+ <point x="1385" y="1205" type="line"/>
+ <point x="1410" y="0" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/input/font-psf-test/source/PsfTest-Bold.ufo/glyphs/L_tnC_apN_.glif b/tests/input/font-psf-test/source/PsfTest-Bold.ufo/glyphs/L_tnC_apN_.glif
new file mode 100644
index 0000000..aa2b5c4
--- /dev/null
+++ b/tests/input/font-psf-test/source/PsfTest-Bold.ufo/glyphs/L_tnC_apN_.glif
@@ -0,0 +1,37 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnCapN" format="2">
+ <advance width="1545"/>
+ <unicode hex="004E"/>
+ <anchor x="1240" y="0" name="H"/>
+ <anchor x="765" y="-100" name="L"/>
+ <anchor x="765" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="223" y="1310" type="line"/>
+ <point x="1095" y="0" type="line"/>
+ <point x="1297" y="150" type="line"/>
+ <point x="425" y="1460" type="line"/>
+ </contour>
+ <contour>
+ <point x="1095" y="0" type="line"/>
+ <point x="1355" y="0" type="line"/>
+ <point x="1355" y="1025" type="line" smooth="yes"/>
+ <point x="1355" y="1222"/>
+ <point x="1356" y="1380"/>
+ <point x="1370" y="1460" type="curve"/>
+ <point x="1095" y="1460" type="line"/>
+ </contour>
+ <contour>
+ <point x="425" y="1460" type="line"/>
+ <point x="150" y="1460" type="line"/>
+ <point x="165" y="1380"/>
+ <point x="165" y="1222"/>
+ <point x="165" y="1025" type="curve" smooth="yes"/>
+ <point x="165" y="435" type="line" smooth="yes"/>
+ <point x="165" y="238"/>
+ <point x="165" y="80"/>
+ <point x="150" y="0" type="curve"/>
+ <point x="425" y="0" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/input/font-psf-test/source/PsfTest-Bold.ufo/glyphs/L_tnC_apO_.glif b/tests/input/font-psf-test/source/PsfTest-Bold.ufo/glyphs/L_tnC_apO_.glif
new file mode 100644
index 0000000..10479ad
--- /dev/null
+++ b/tests/input/font-psf-test/source/PsfTest-Bold.ufo/glyphs/L_tnC_apO_.glif
@@ -0,0 +1,40 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnCapO" format="2">
+ <advance width="1500"/>
+ <unicode hex="004F"/>
+ <anchor x="740" y="0" name="H"/>
+ <anchor x="740" y="-100" name="L"/>
+ <anchor x="976" y="0" name="O"/>
+ <anchor x="1480" y="1200" name="R"/>
+ <anchor x="740" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="1100" y="715" type="curve" smooth="yes"/>
+ <point x="1100" y="404"/>
+ <point x="940" y="220"/>
+ <point x="740" y="220" type="curve" smooth="yes"/>
+ <point x="524" y="220"/>
+ <point x="375" y="423"/>
+ <point x="375" y="745" type="curve" smooth="yes"/>
+ <point x="375" y="1048"/>
+ <point x="529" y="1240"/>
+ <point x="740" y="1240" type="curve" smooth="yes"/>
+ <point x="951" y="1240"/>
+ <point x="1100" y="1041"/>
+ </contour>
+ <contour>
+ <point x="1385" y="740" type="curve" smooth="yes"/>
+ <point x="1385" y="1219"/>
+ <point x="1091" y="1485"/>
+ <point x="750" y="1485" type="curve" smooth="yes"/>
+ <point x="404" y="1485"/>
+ <point x="90" y="1199"/>
+ <point x="90" y="720" type="curve" smooth="yes"/>
+ <point x="90" y="241"/>
+ <point x="385" y="-25"/>
+ <point x="730" y="-25" type="curve" smooth="yes"/>
+ <point x="1072" y="-25"/>
+ <point x="1385" y="260"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/input/font-psf-test/source/PsfTest-Bold.ufo/glyphs/L_tnC_apP_.glif b/tests/input/font-psf-test/source/PsfTest-Bold.ufo/glyphs/L_tnC_apP_.glif
new file mode 100644
index 0000000..18e9ee0
--- /dev/null
+++ b/tests/input/font-psf-test/source/PsfTest-Bold.ufo/glyphs/L_tnC_apP_.glif
@@ -0,0 +1,50 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnCapP" format="2">
+ <advance width="1275"/>
+ <unicode hex="0050"/>
+ <anchor x="685" y="-100" name="L"/>
+ <anchor x="685" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="450" y="523" type="line"/>
+ <point x="515" y="516"/>
+ <point x="575" y="513"/>
+ <point x="648" y="513" type="curve" smooth="yes"/>
+ <point x="977" y="513"/>
+ <point x="1200" y="702"/>
+ <point x="1200" y="1010" type="curve" smooth="yes"/>
+ <point x="1200" y="1316"/>
+ <point x="981" y="1470"/>
+ <point x="658" y="1470" type="curve" smooth="yes"/>
+ <point x="445" y="1470"/>
+ <point x="150" y="1460"/>
+ <point x="150" y="1460" type="curve"/>
+ <point x="165" y="1380"/>
+ <point x="165" y="1196"/>
+ <point x="165" y="1000" type="curve" smooth="yes"/>
+ <point x="165" y="435" type="line" smooth="yes"/>
+ <point x="165" y="238"/>
+ <point x="165" y="80"/>
+ <point x="150" y="0" type="curve"/>
+ <point x="465" y="0" type="line"/>
+ <point x="451" y="78"/>
+ <point x="450" y="237"/>
+ <point x="450" y="435" type="curve" smooth="yes"/>
+ </contour>
+ <contour>
+ <point x="450" y="1240" type="line"/>
+ <point x="506" y="1243"/>
+ <point x="544" y="1245"/>
+ <point x="622" y="1245" type="curve" smooth="yes"/>
+ <point x="833" y="1245"/>
+ <point x="915" y="1145"/>
+ <point x="915" y="1000" type="curve" smooth="yes"/>
+ <point x="915" y="820"/>
+ <point x="811" y="730"/>
+ <point x="618" y="730" type="curve" smooth="yes"/>
+ <point x="556" y="730"/>
+ <point x="493" y="733"/>
+ <point x="450" y="740" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/input/font-psf-test/source/PsfTest-Bold.ufo/glyphs/L_tnC_apQ_.glif b/tests/input/font-psf-test/source/PsfTest-Bold.ufo/glyphs/L_tnC_apQ_.glif
new file mode 100644
index 0000000..433087c
--- /dev/null
+++ b/tests/input/font-psf-test/source/PsfTest-Bold.ufo/glyphs/L_tnC_apQ_.glif
@@ -0,0 +1,49 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnCapQ" format="2">
+ <advance width="1545"/>
+ <unicode hex="0051"/>
+ <anchor x="747" y="-270" name="L"/>
+ <anchor x="747" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="1385" y="740" type="curve" smooth="yes"/>
+ <point x="1385" y="1219"/>
+ <point x="1091" y="1485"/>
+ <point x="750" y="1485" type="curve" smooth="yes"/>
+ <point x="404" y="1485"/>
+ <point x="90" y="1199"/>
+ <point x="90" y="720" type="curve" smooth="yes"/>
+ <point x="90" y="241"/>
+ <point x="385" y="-25"/>
+ <point x="730" y="-25" type="curve" smooth="yes"/>
+ <point x="807" y="-25"/>
+ <point x="840" y="-23"/>
+ <point x="889" y="-15" type="curve"/>
+ <point x="958" y="-15"/>
+ <point x="1266" y="-228"/>
+ <point x="1350" y="-228" type="curve" smooth="yes"/>
+ <point x="1424" y="-228"/>
+ <point x="1502" y="-68"/>
+ <point x="1535" y="-15" type="curve"/>
+ <point x="1394" y="1"/>
+ <point x="1277" y="68"/>
+ <point x="1146" y="142" type="curve"/>
+ <point x="1294" y="283"/>
+ <point x="1385" y="471"/>
+ </contour>
+ <contour>
+ <point x="1100" y="715" type="curve" smooth="yes"/>
+ <point x="1100" y="404"/>
+ <point x="943" y="220"/>
+ <point x="740" y="220" type="curve" smooth="yes"/>
+ <point x="524" y="220"/>
+ <point x="375" y="423"/>
+ <point x="375" y="745" type="curve" smooth="yes"/>
+ <point x="375" y="1048"/>
+ <point x="529" y="1240"/>
+ <point x="740" y="1240" type="curve" smooth="yes"/>
+ <point x="951" y="1240"/>
+ <point x="1100" y="1041"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/input/font-psf-test/source/PsfTest-Bold.ufo/glyphs/L_tnC_apR_.glif b/tests/input/font-psf-test/source/PsfTest-Bold.ufo/glyphs/L_tnC_apR_.glif
new file mode 100644
index 0000000..6103056
--- /dev/null
+++ b/tests/input/font-psf-test/source/PsfTest-Bold.ufo/glyphs/L_tnC_apR_.glif
@@ -0,0 +1,55 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnCapR" format="2">
+ <advance width="1380"/>
+ <unicode hex="0052"/>
+ <anchor x="690" y="0" name="H"/>
+ <anchor x="690" y="-100" name="L"/>
+ <anchor x="660" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="450" y="585" type="line"/>
+ <point x="625" y="585" type="line" smooth="yes"/>
+ <point x="910" y="585"/>
+ <point x="1175" y="723"/>
+ <point x="1175" y="1040" type="curve" smooth="yes"/>
+ <point x="1175" y="1329"/>
+ <point x="961" y="1470"/>
+ <point x="650" y="1470" type="curve" smooth="yes"/>
+ <point x="416" y="1470"/>
+ <point x="150" y="1460"/>
+ <point x="150" y="1460" type="curve"/>
+ <point x="165" y="1380"/>
+ <point x="165" y="1196"/>
+ <point x="165" y="1000" type="curve" smooth="yes"/>
+ <point x="165" y="435" type="line" smooth="yes"/>
+ <point x="165" y="238"/>
+ <point x="165" y="80"/>
+ <point x="150" y="0" type="curve"/>
+ <point x="465" y="0" type="line"/>
+ <point x="451" y="78"/>
+ <point x="450" y="238"/>
+ <point x="450" y="435" type="curve" smooth="yes"/>
+ </contour>
+ <contour>
+ <point x="450" y="1240" type="line"/>
+ <point x="503" y="1243"/>
+ <point x="537" y="1245"/>
+ <point x="615" y="1245" type="curve" smooth="yes"/>
+ <point x="792" y="1245"/>
+ <point x="890" y="1186"/>
+ <point x="890" y="1035" type="curve" smooth="yes"/>
+ <point x="890" y="859"/>
+ <point x="780" y="800"/>
+ <point x="605" y="800" type="curve" smooth="yes"/>
+ <point x="450" y="800" type="line"/>
+ </contour>
+ <contour>
+ <point x="556" y="635" type="line"/>
+ <point x="975" y="0" type="line"/>
+ <point x="1330" y="0" type="line"/>
+ <point x="1263" y="73"/>
+ <point x="827" y="687"/>
+ <point x="827" y="687" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/input/font-psf-test/source/PsfTest-Bold.ufo/glyphs/L_tnC_apS_.glif b/tests/input/font-psf-test/source/PsfTest-Bold.ufo/glyphs/L_tnC_apS_.glif
new file mode 100644
index 0000000..486ff77
--- /dev/null
+++ b/tests/input/font-psf-test/source/PsfTest-Bold.ufo/glyphs/L_tnC_apS_.glif
@@ -0,0 +1,50 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnCapS" format="2">
+ <advance width="1243"/>
+ <unicode hex="0053"/>
+ <anchor x="616" y="0" name="H"/>
+ <anchor x="616" y="-100" name="L"/>
+ <anchor x="616" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="1075" y="1395" type="line"/>
+ <point x="932" y="1458"/>
+ <point x="810" y="1485"/>
+ <point x="640" y="1485" type="curve" smooth="yes"/>
+ <point x="280" y="1485"/>
+ <point x="130" y="1239"/>
+ <point x="130" y="1060" type="curve" smooth="yes"/>
+ <point x="130" y="882"/>
+ <point x="196" y="754"/>
+ <point x="510" y="655" type="curve" smooth="yes"/>
+ <point x="800" y="563"/>
+ <point x="851" y="504"/>
+ <point x="851" y="420" type="curve" smooth="yes"/>
+ <point x="851" y="293"/>
+ <point x="730" y="220"/>
+ <point x="600" y="220" type="curve" smooth="yes"/>
+ <point x="439" y="220"/>
+ <point x="283" y="270"/>
+ <point x="140" y="385" type="curve"/>
+ <point x="90" y="110" type="line"/>
+ <point x="201" y="31"/>
+ <point x="391" y="-25"/>
+ <point x="600" y="-25" type="curve" smooth="yes"/>
+ <point x="895" y="-25"/>
+ <point x="1138" y="169"/>
+ <point x="1138" y="455" type="curve" smooth="yes"/>
+ <point x="1138" y="666"/>
+ <point x="994" y="787"/>
+ <point x="727" y="870" type="curve" smooth="yes"/>
+ <point x="464" y="952"/>
+ <point x="416" y="994"/>
+ <point x="416" y="1080" type="curve" smooth="yes"/>
+ <point x="416" y="1162"/>
+ <point x="506" y="1245"/>
+ <point x="630" y="1245" type="curve" smooth="yes"/>
+ <point x="771" y="1245"/>
+ <point x="873" y="1209"/>
+ <point x="1030" y="1130" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/input/font-psf-test/source/PsfTest-Bold.ufo/glyphs/L_tnC_apT_.glif b/tests/input/font-psf-test/source/PsfTest-Bold.ufo/glyphs/L_tnC_apT_.glif
new file mode 100644
index 0000000..5f87c10
--- /dev/null
+++ b/tests/input/font-psf-test/source/PsfTest-Bold.ufo/glyphs/L_tnC_apT_.glif
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnCapT" format="2">
+ <advance width="1275"/>
+ <unicode hex="0054"/>
+ <anchor x="632" y="0" name="H"/>
+ <anchor x="632" y="-100" name="L"/>
+ <anchor x="632" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="45" y="1460" type="line"/>
+ <point x="45" y="1210" type="line"/>
+ <point x="117" y="1227"/>
+ <point x="196" y="1230"/>
+ <point x="276" y="1230" type="curve" smooth="yes"/>
+ <point x="488" y="1230" type="line"/>
+ <point x="488" y="413" type="line" smooth="yes"/>
+ <point x="488" y="226"/>
+ <point x="485" y="76"/>
+ <point x="468" y="0" type="curve"/>
+ <point x="793" y="0" type="line"/>
+ <point x="776" y="76"/>
+ <point x="773" y="226"/>
+ <point x="773" y="413" type="curve" smooth="yes"/>
+ <point x="773" y="1230" type="line"/>
+ <point x="989" y="1230" type="line" smooth="yes"/>
+ <point x="1070" y="1230"/>
+ <point x="1148" y="1227"/>
+ <point x="1220" y="1210" type="curve"/>
+ <point x="1220" y="1460" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/input/font-psf-test/source/PsfTest-Bold.ufo/glyphs/L_tnC_apU_.glif b/tests/input/font-psf-test/source/PsfTest-Bold.ufo/glyphs/L_tnC_apU_.glif
new file mode 100644
index 0000000..b3f6b6f
--- /dev/null
+++ b/tests/input/font-psf-test/source/PsfTest-Bold.ufo/glyphs/L_tnC_apU_.glif
@@ -0,0 +1,38 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnCapU" format="2">
+ <advance width="1490"/>
+ <unicode hex="0055"/>
+ <anchor x="732" y="0" name="H"/>
+ <anchor x="732" y="-100" name="L"/>
+ <anchor x="950" y="0" name="O"/>
+ <anchor x="1480" y="1200" name="R"/>
+ <anchor x="732" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="1015" y="1460" type="line"/>
+ <point x="1015" y="560" type="line" smooth="yes"/>
+ <point x="1015" y="344"/>
+ <point x="952" y="204"/>
+ <point x="735" y="204" type="curve" smooth="yes"/>
+ <point x="513" y="204"/>
+ <point x="450" y="344"/>
+ <point x="450" y="560" type="curve" smooth="yes"/>
+ <point x="450" y="1460" type="line"/>
+ <point x="150" y="1460" type="line"/>
+ <point x="164" y="1380"/>
+ <point x="165" y="1222"/>
+ <point x="165" y="1025" type="curve" smooth="yes"/>
+ <point x="165" y="515" type="line" smooth="yes"/>
+ <point x="165" y="190"/>
+ <point x="356" y="-25"/>
+ <point x="735" y="-25" type="curve" smooth="yes"/>
+ <point x="1110" y="-25"/>
+ <point x="1300" y="190"/>
+ <point x="1300" y="515" type="curve" smooth="yes"/>
+ <point x="1300" y="1025" type="line" smooth="yes"/>
+ <point x="1300" y="1232"/>
+ <point x="1302" y="1380"/>
+ <point x="1315" y="1460" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/input/font-psf-test/source/PsfTest-Bold.ufo/glyphs/L_tnC_apV_.glif b/tests/input/font-psf-test/source/PsfTest-Bold.ufo/glyphs/L_tnC_apV_.glif
new file mode 100644
index 0000000..3468784
--- /dev/null
+++ b/tests/input/font-psf-test/source/PsfTest-Bold.ufo/glyphs/L_tnC_apV_.glif
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnCapV" format="2">
+ <advance width="1465"/>
+ <unicode hex="0056"/>
+ <anchor x="730" y="0" name="H"/>
+ <anchor x="722" y="-100" name="L"/>
+ <anchor x="930" y="0" name="O"/>
+ <anchor x="722" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="1115" y="1460" type="line"/>
+ <point x="722" y="260" type="line"/>
+ <point x="330" y="1460" type="line"/>
+ <point x="25" y="1460" type="line"/>
+ <point x="58" y="1378"/>
+ <point x="96" y="1288"/>
+ <point x="165" y="1095" type="curve" smooth="yes"/>
+ <point x="555" y="0" type="line"/>
+ <point x="890" y="0" type="line"/>
+ <point x="1280" y="1095" type="line" smooth="yes"/>
+ <point x="1348" y="1289"/>
+ <point x="1384" y="1378"/>
+ <point x="1420" y="1460" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/input/font-psf-test/source/PsfTest-Bold.ufo/glyphs/L_tnC_apW_.glif b/tests/input/font-psf-test/source/PsfTest-Bold.ufo/glyphs/L_tnC_apW_.glif
new file mode 100644
index 0000000..98329a0
--- /dev/null
+++ b/tests/input/font-psf-test/source/PsfTest-Bold.ufo/glyphs/L_tnC_apW_.glif
@@ -0,0 +1,45 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnCapW" format="2">
+ <advance width="2135"/>
+ <unicode hex="0057"/>
+ <anchor x="1052" y="-100" name="L"/>
+ <anchor x="1052" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="1490" y="0" type="line"/>
+ <point x="1655" y="0" type="line"/>
+ <point x="1965" y="1095" type="line" smooth="yes"/>
+ <point x="2020" y="1289"/>
+ <point x="2048" y="1378"/>
+ <point x="2080" y="1460" type="curve"/>
+ <point x="1770" y="1460" type="line"/>
+ <point x="1470" y="130" type="line"/>
+ </contour>
+ <contour>
+ <point x="1180" y="1460" type="line"/>
+ <point x="920" y="1460" type="line"/>
+ <point x="995" y="1305" type="line"/>
+ <point x="1340" y="0" type="line"/>
+ <point x="1510" y="0" type="line"/>
+ <point x="1530" y="130" type="line"/>
+ </contour>
+ <contour>
+ <point x="600" y="0" type="line"/>
+ <point x="765" y="0" type="line"/>
+ <point x="1105" y="1305" type="line"/>
+ <point x="1180" y="1460" type="line"/>
+ <point x="920" y="1460" type="line"/>
+ <point x="580" y="130" type="line"/>
+ </contour>
+ <contour>
+ <point x="340" y="1460" type="line"/>
+ <point x="30" y="1460" type="line"/>
+ <point x="61" y="1381"/>
+ <point x="92" y="1286"/>
+ <point x="145" y="1095" type="curve" smooth="yes"/>
+ <point x="450" y="0" type="line"/>
+ <point x="620" y="0" type="line"/>
+ <point x="640" y="130" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/input/font-psf-test/source/PsfTest-Bold.ufo/glyphs/L_tnC_apX_.glif b/tests/input/font-psf-test/source/PsfTest-Bold.ufo/glyphs/L_tnC_apX_.glif
new file mode 100644
index 0000000..17126dd
--- /dev/null
+++ b/tests/input/font-psf-test/source/PsfTest-Bold.ufo/glyphs/L_tnC_apX_.glif
@@ -0,0 +1,39 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnCapX" format="2">
+ <advance width="1365"/>
+ <unicode hex="0058"/>
+ <anchor x="670" y="-100" name="L"/>
+ <anchor x="670" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="990" y="0" type="line"/>
+ <point x="1310" y="0" type="line"/>
+ <point x="1249" y="82"/>
+ <point x="1211" y="125"/>
+ <point x="1083" y="336" type="curve" smooth="yes"/>
+ <point x="400" y="1460" type="line"/>
+ <point x="75" y="1460" type="line"/>
+ <point x="139" y="1376"/>
+ <point x="189" y="1317"/>
+ <point x="315" y="1110" type="curve"/>
+ </contour>
+ <contour>
+ <point x="605" y="947" type="line"/>
+ <point x="255" y="340" type="line" smooth="yes"/>
+ <point x="133" y="128"/>
+ <point x="93" y="86"/>
+ <point x="30" y="0" type="curve"/>
+ <point x="350" y="0" type="line"/>
+ <point x="700" y="609" type="line"/>
+ </contour>
+ <contour>
+ <point x="750" y="609" type="line"/>
+ <point x="1040" y="1110" type="line" smooth="yes"/>
+ <point x="1153" y="1306"/>
+ <point x="1211" y="1383"/>
+ <point x="1275" y="1460" type="curve"/>
+ <point x="950" y="1460" type="line"/>
+ <point x="655" y="947" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/input/font-psf-test/source/PsfTest-Bold.ufo/glyphs/L_tnC_apY_.glif b/tests/input/font-psf-test/source/PsfTest-Bold.ufo/glyphs/L_tnC_apY_.glif
new file mode 100644
index 0000000..a7a345d
--- /dev/null
+++ b/tests/input/font-psf-test/source/PsfTest-Bold.ufo/glyphs/L_tnC_apY_.glif
@@ -0,0 +1,39 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnCapY" format="2">
+ <advance width="1364"/>
+ <unicode hex="0059"/>
+ <anchor x="672" y="-100" name="L"/>
+ <anchor x="672" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="575" y="560" type="line"/>
+ <point x="782" y="675" type="line"/>
+ <point x="357" y="1460" type="line"/>
+ <point x="25" y="1460" type="line"/>
+ <point x="137" y="1311"/>
+ <point x="203" y="1197"/>
+ <point x="280" y="1065" type="curve" smooth="yes"/>
+ </contour>
+ <contour>
+ <point x="770" y="560" type="line"/>
+ <point x="1069" y="1065" type="line" smooth="yes"/>
+ <point x="1145" y="1195"/>
+ <point x="1201" y="1291"/>
+ <point x="1319" y="1460" type="curve"/>
+ <point x="997" y="1460" type="line"/>
+ <point x="577" y="675" type="line"/>
+ </contour>
+ <contour>
+ <point x="530" y="695" type="line"/>
+ <point x="530" y="435" type="line" smooth="yes"/>
+ <point x="530" y="238"/>
+ <point x="530" y="80"/>
+ <point x="515" y="0" type="curve"/>
+ <point x="830" y="0" type="line"/>
+ <point x="815" y="80"/>
+ <point x="815" y="238"/>
+ <point x="815" y="435" type="curve" smooth="yes"/>
+ <point x="815" y="695" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/input/font-psf-test/source/PsfTest-Bold.ufo/glyphs/L_tnS_mA_.glif b/tests/input/font-psf-test/source/PsfTest-Bold.ufo/glyphs/L_tnS_mA_.glif
new file mode 100644
index 0000000..7885750
--- /dev/null
+++ b/tests/input/font-psf-test/source/PsfTest-Bold.ufo/glyphs/L_tnS_mA_.glif
@@ -0,0 +1,76 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmA" format="2">
+ <advance width="1205"/>
+ <unicode hex="0061"/>
+ <note>
+
+
+
+
+ GlyphNote A
+
+
+
+
+ </note>
+ <anchor x="985" y="0" name="H"/>
+ <anchor x="610" y="-100" name="L"/>
+ <anchor x="1185" y="0" name="O"/>
+ <anchor x="1145" y="1000" name="R"/>
+ <anchor x="610" y="1100" name="U"/>
+ <outline>
+ <contour>
+ <point x="1120" y="0" type="line"/>
+ <point x="1078" y="112"/>
+ <point x="1050" y="226"/>
+ <point x="1050" y="370" type="curve"/>
+ <point x="1050" y="760" type="line"/>
+ <point x="1050" y="919"/>
+ <point x="877" y="1040"/>
+ <point x="615" y="1040" type="curve" smooth="yes"/>
+ <point x="446" y="1040"/>
+ <point x="330" y="994"/>
+ <point x="216" y="950" type="curve"/>
+ <point x="210" y="868"/>
+ <point x="207" y="735"/>
+ <point x="206" y="691" type="curve"/>
+ <point x="323" y="773"/>
+ <point x="424" y="816"/>
+ <point x="530" y="816" type="curve" smooth="yes"/>
+ <point x="680" y="816"/>
+ <point x="770" y="785"/>
+ <point x="770" y="710" type="curve" smooth="yes"/>
+ <point x="770" y="660" type="line"/>
+ <point x="729" y="659"/>
+ <point x="569" y="649"/>
+ <point x="500" y="642" type="curve" smooth="yes"/>
+ <point x="191" y="612"/>
+ <point x="100" y="438"/>
+ <point x="100" y="285" type="curve" smooth="yes"/>
+ <point x="100" y="121"/>
+ <point x="245" y="-25"/>
+ <point x="445" y="-25" type="curve" smooth="yes"/>
+ <point x="562" y="-25"/>
+ <point x="688" y="23"/>
+ <point x="800" y="135" type="curve"/>
+ <point x="814" y="79"/>
+ <point x="838" y="28"/>
+ <point x="850" y="0" type="curve"/>
+ </contour>
+ <contour>
+ <point x="770" y="355" type="line"/>
+ <point x="674" y="225"/>
+ <point x="600" y="205"/>
+ <point x="518" y="205" type="curve" smooth="yes"/>
+ <point x="436" y="205"/>
+ <point x="380" y="256"/>
+ <point x="380" y="320" type="curve" smooth="yes"/>
+ <point x="380" y="386"/>
+ <point x="422" y="442"/>
+ <point x="560" y="457" type="curve" smooth="yes"/>
+ <point x="611" y="463"/>
+ <point x="730" y="474"/>
+ <point x="770" y="475" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/input/font-psf-test/source/PsfTest-Bold.ufo/glyphs/L_tnS_mA_A_cute.glif b/tests/input/font-psf-test/source/PsfTest-Bold.ufo/glyphs/L_tnS_mA_A_cute.glif
new file mode 100644
index 0000000..f1c66a5
--- /dev/null
+++ b/tests/input/font-psf-test/source/PsfTest-Bold.ufo/glyphs/L_tnS_mA_A_cute.glif
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmAAcute" format="2">
+ <advance width="1205"/>
+ <unicode hex="00E1"/>
+ <anchor x="985" y="0" name="H"/>
+ <anchor x="610" y="-100" name="L"/>
+ <anchor x="1185" y="0" name="O"/>
+ <anchor x="1145" y="1000" name="R"/>
+ <anchor x="550" y="1635" name="U"/>
+ <outline>
+ <component base="LtnSmA"/>
+ <component base="CombAcute" xOffset="1150"/>
+ </outline>
+</glyph>
diff --git a/tests/input/font-psf-test/source/PsfTest-Bold.ufo/glyphs/L_tnS_mA_C_ircum.glif b/tests/input/font-psf-test/source/PsfTest-Bold.ufo/glyphs/L_tnS_mA_C_ircum.glif
new file mode 100644
index 0000000..218d694
--- /dev/null
+++ b/tests/input/font-psf-test/source/PsfTest-Bold.ufo/glyphs/L_tnS_mA_C_ircum.glif
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmACircum" format="2">
+ <advance width="1205"/>
+ <unicode hex="00E2"/>
+ <anchor x="985" y="0" name="H"/>
+ <anchor x="610" y="-100" name="L"/>
+ <anchor x="1185" y="0" name="O"/>
+ <anchor x="1145" y="1000" name="R"/>
+ <anchor x="602" y="1635" name="U"/>
+ <outline>
+ <component base="LtnSmA"/>
+ <component base="CombCircum" xOffset="1190"/>
+ </outline>
+</glyph>
diff --git a/tests/input/font-psf-test/source/PsfTest-Bold.ufo/glyphs/L_tnS_mA_D_iaer.glif b/tests/input/font-psf-test/source/PsfTest-Bold.ufo/glyphs/L_tnS_mA_D_iaer.glif
new file mode 100644
index 0000000..bb0ea2c
--- /dev/null
+++ b/tests/input/font-psf-test/source/PsfTest-Bold.ufo/glyphs/L_tnS_mA_D_iaer.glif
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmADiaer" format="2">
+ <advance width="1205"/>
+ <unicode hex="00E4"/>
+ <anchor x="985" y="0" name="H"/>
+ <anchor x="610" y="-100" name="L"/>
+ <anchor x="1185" y="0" name="O"/>
+ <anchor x="1145" y="1000" name="R"/>
+ <anchor x="610" y="1585" name="U"/>
+ <outline>
+ <component base="LtnSmA"/>
+ <component base="CombDiaer" xOffset="1190"/>
+ </outline>
+</glyph>
diff --git a/tests/input/font-psf-test/source/PsfTest-Bold.ufo/glyphs/L_tnS_mA_G_rave.glif b/tests/input/font-psf-test/source/PsfTest-Bold.ufo/glyphs/L_tnS_mA_G_rave.glif
new file mode 100644
index 0000000..3153364
--- /dev/null
+++ b/tests/input/font-psf-test/source/PsfTest-Bold.ufo/glyphs/L_tnS_mA_G_rave.glif
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmAGrave" format="2">
+ <advance width="1205"/>
+ <unicode hex="00E0"/>
+ <anchor x="985" y="0" name="H"/>
+ <anchor x="610" y="-100" name="L"/>
+ <anchor x="1185" y="0" name="O"/>
+ <anchor x="1145" y="1000" name="R"/>
+ <anchor x="650" y="1635" name="U"/>
+ <outline>
+ <component base="LtnSmA"/>
+ <component base="CombGrave" xOffset="1240"/>
+ </outline>
+</glyph>
diff --git a/tests/input/font-psf-test/source/PsfTest-Bold.ufo/glyphs/L_tnS_mA_R_ingA_bv.glif b/tests/input/font-psf-test/source/PsfTest-Bold.ufo/glyphs/L_tnS_mA_R_ingA_bv.glif
new file mode 100644
index 0000000..3b8da5a
--- /dev/null
+++ b/tests/input/font-psf-test/source/PsfTest-Bold.ufo/glyphs/L_tnS_mA_R_ingA_bv.glif
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmARingAbv" format="2">
+ <advance width="1205"/>
+ <unicode hex="00E5"/>
+ <anchor x="985" y="0" name="H"/>
+ <anchor x="610" y="-100" name="L"/>
+ <anchor x="1185" y="0" name="O"/>
+ <anchor x="1145" y="1000" name="R"/>
+ <anchor x="612" y="1635" name="U"/>
+ <outline>
+ <component base="LtnSmA"/>
+ <component base="CombRingAbv" xOffset="1182"/>
+ </outline>
+</glyph>
diff --git a/tests/input/font-psf-test/source/PsfTest-Bold.ufo/glyphs/L_tnS_mA_T_ilde.glif b/tests/input/font-psf-test/source/PsfTest-Bold.ufo/glyphs/L_tnS_mA_T_ilde.glif
new file mode 100644
index 0000000..b3a8515
--- /dev/null
+++ b/tests/input/font-psf-test/source/PsfTest-Bold.ufo/glyphs/L_tnS_mA_T_ilde.glif
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmATilde" format="2">
+ <advance width="1205"/>
+ <unicode hex="00E3"/>
+ <anchor x="985" y="0" name="H"/>
+ <anchor x="610" y="-100" name="L"/>
+ <anchor x="1185" y="0" name="O"/>
+ <anchor x="1145" y="1000" name="R"/>
+ <anchor x="610" y="1490" name="U"/>
+ <outline>
+ <component base="LtnSmA"/>
+ <component base="CombTilde" xOffset="1190"/>
+ </outline>
+</glyph>
diff --git a/tests/input/font-psf-test/source/PsfTest-Bold.ufo/glyphs/L_tnS_mB_.glif b/tests/input/font-psf-test/source/PsfTest-Bold.ufo/glyphs/L_tnS_mB_.glif
new file mode 100644
index 0000000..6cc6671
--- /dev/null
+++ b/tests/input/font-psf-test/source/PsfTest-Bold.ufo/glyphs/L_tnS_mB_.glif
@@ -0,0 +1,50 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmB" format="2">
+ <advance width="1215"/>
+ <unicode hex="0062"/>
+ <anchor x="610" y="0" name="H"/>
+ <anchor x="610" y="-100" name="L"/>
+ <anchor x="1215" y="1000" name="R"/>
+ <anchor x="610" y="1635" name="U"/>
+ <outline>
+ <contour>
+ <point x="120" y="1600" type="line"/>
+ <point x="135" y="1488"/>
+ <point x="135" y="1273"/>
+ <point x="135" y="1130" type="curve" smooth="yes"/>
+ <point x="135" y="936"/>
+ <point x="135" y="228"/>
+ <point x="135" y="65" type="curve"/>
+ <point x="286" y="26"/>
+ <point x="457" y="-25"/>
+ <point x="650" y="-25" type="curve" smooth="yes"/>
+ <point x="939" y="-25"/>
+ <point x="1125" y="197"/>
+ <point x="1125" y="540" type="curve" smooth="yes"/>
+ <point x="1125" y="832"/>
+ <point x="986" y="1040"/>
+ <point x="789" y="1040" type="curve" smooth="yes"/>
+ <point x="626" y="1040"/>
+ <point x="505" y="956"/>
+ <point x="415" y="845" type="curve"/>
+ <point x="415" y="934"/>
+ <point x="415" y="1600"/>
+ <point x="415" y="1600" type="curve"/>
+ </contour>
+ <contour>
+ <point x="415" y="585" type="line"/>
+ <point x="471" y="709"/>
+ <point x="580" y="795"/>
+ <point x="683" y="795" type="curve" smooth="yes"/>
+ <point x="793" y="795"/>
+ <point x="855" y="684"/>
+ <point x="855" y="505" type="curve" smooth="yes"/>
+ <point x="855" y="317"/>
+ <point x="750" y="190"/>
+ <point x="605" y="190" type="curve" smooth="yes"/>
+ <point x="538" y="190"/>
+ <point x="492" y="204"/>
+ <point x="415" y="240" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/input/font-psf-test/source/PsfTest-Bold.ufo/glyphs/L_tnS_mC_.glif b/tests/input/font-psf-test/source/PsfTest-Bold.ufo/glyphs/L_tnS_mC_.glif
new file mode 100644
index 0000000..19a8a6d
--- /dev/null
+++ b/tests/input/font-psf-test/source/PsfTest-Bold.ufo/glyphs/L_tnS_mC_.glif
@@ -0,0 +1,39 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmC" format="2">
+ <advance width="1022"/>
+ <unicode hex="0063"/>
+ <anchor x="555" y="0" name="H"/>
+ <anchor x="575" y="-100" name="L"/>
+ <anchor x="1020" y="1000" name="R"/>
+ <anchor x="575" y="1100" name="U"/>
+ <outline>
+ <contour>
+ <point x="922" y="969" type="line"/>
+ <point x="849" y="1007"/>
+ <point x="744" y="1040"/>
+ <point x="612" y="1040" type="curve" smooth="yes"/>
+ <point x="295" y="1040"/>
+ <point x="90" y="802"/>
+ <point x="90" y="490" type="curve" smooth="yes"/>
+ <point x="90" y="161"/>
+ <point x="309" y="-25"/>
+ <point x="578" y="-25" type="curve" smooth="yes"/>
+ <point x="727" y="-25"/>
+ <point x="831" y="8"/>
+ <point x="932" y="70" type="curve"/>
+ <point x="902" y="314" type="line"/>
+ <point x="815" y="245"/>
+ <point x="737" y="205"/>
+ <point x="617" y="205" type="curve" smooth="yes"/>
+ <point x="467" y="205"/>
+ <point x="370" y="324"/>
+ <point x="370" y="500" type="curve" smooth="yes"/>
+ <point x="370" y="694"/>
+ <point x="478" y="810"/>
+ <point x="617" y="810" type="curve" smooth="yes"/>
+ <point x="720" y="810"/>
+ <point x="788" y="779"/>
+ <point x="878" y="717" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/input/font-psf-test/source/PsfTest-Bold.ufo/glyphs/L_tnS_mD_.glif b/tests/input/font-psf-test/source/PsfTest-Bold.ufo/glyphs/L_tnS_mD_.glif
new file mode 100644
index 0000000..fc1cc76
--- /dev/null
+++ b/tests/input/font-psf-test/source/PsfTest-Bold.ufo/glyphs/L_tnS_mD_.glif
@@ -0,0 +1,53 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmD" format="2">
+ <advance width="1265"/>
+ <unicode hex="0064"/>
+ <anchor x="595" y="0" name="H"/>
+ <anchor x="595" y="-100" name="L"/>
+ <anchor x="1285" y="1000" name="R"/>
+ <anchor x="610" y="1635" name="U"/>
+ <outline>
+ <contour>
+ <point x="1115" y="1600" type="line"/>
+ <point x="810" y="1600" type="line"/>
+ <point x="829" y="1516"/>
+ <point x="835" y="1395"/>
+ <point x="835" y="1235" type="curve" smooth="yes"/>
+ <point x="835" y="955" type="line"/>
+ <point x="763" y="999"/>
+ <point x="669" y="1040"/>
+ <point x="590" y="1040" type="curve" smooth="yes"/>
+ <point x="319" y="1040"/>
+ <point x="100" y="814"/>
+ <point x="100" y="460" type="curve" smooth="yes"/>
+ <point x="100" y="167"/>
+ <point x="268" y="-25"/>
+ <point x="515" y="-25" type="curve" smooth="yes"/>
+ <point x="654" y="-25"/>
+ <point x="770" y="47"/>
+ <point x="860" y="175" type="curve"/>
+ <point x="877" y="105"/>
+ <point x="900" y="32"/>
+ <point x="915" y="0" type="curve"/>
+ <point x="1190" y="0" type="line"/>
+ <point x="1147" y="112"/>
+ <point x="1115" y="278"/>
+ <point x="1115" y="530" type="curve" smooth="yes"/>
+ </contour>
+ <contour>
+ <point x="835" y="400" type="line"/>
+ <point x="787" y="300"/>
+ <point x="676" y="200"/>
+ <point x="570" y="200" type="curve" smooth="yes"/>
+ <point x="443" y="200"/>
+ <point x="380" y="300"/>
+ <point x="380" y="490" type="curve" smooth="yes"/>
+ <point x="380" y="685"/>
+ <point x="485" y="800"/>
+ <point x="590" y="800" type="curve" smooth="yes"/>
+ <point x="683" y="800"/>
+ <point x="743" y="783"/>
+ <point x="835" y="738" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/input/font-psf-test/source/PsfTest-Bold.ufo/glyphs/L_tnS_mE_.glif b/tests/input/font-psf-test/source/PsfTest-Bold.ufo/glyphs/L_tnS_mE_.glif
new file mode 100644
index 0000000..5c67455
--- /dev/null
+++ b/tests/input/font-psf-test/source/PsfTest-Bold.ufo/glyphs/L_tnS_mE_.glif
@@ -0,0 +1,45 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmE" format="2">
+ <advance width="1110"/>
+ <unicode hex="0065"/>
+ <anchor x="569" y="0" name="H"/>
+ <anchor x="589" y="-100" name="L"/>
+ <anchor x="900" y="0" name="O"/>
+ <anchor x="1130" y="1000" name="R"/>
+ <anchor x="537" y="1100" name="U"/>
+ <outline>
+ <contour>
+ <point x="1010" y="450" type="line"/>
+ <point x="1010" y="469"/>
+ <point x="1009" y="513"/>
+ <point x="1009" y="532" type="curve" smooth="yes"/>
+ <point x="1009" y="782"/>
+ <point x="924" y="1040"/>
+ <point x="589" y="1040" type="curve" smooth="yes"/>
+ <point x="281" y="1040"/>
+ <point x="90" y="826"/>
+ <point x="90" y="495" type="curve" smooth="yes"/>
+ <point x="90" y="155"/>
+ <point x="324" y="-25"/>
+ <point x="589" y="-25" type="curve" smooth="yes"/>
+ <point x="745" y="-25"/>
+ <point x="871" y="2"/>
+ <point x="1015" y="75" type="curve"/>
+ <point x="994" y="306" type="line"/>
+ <point x="870" y="232"/>
+ <point x="745" y="205"/>
+ <point x="614" y="205" type="curve" smooth="yes"/>
+ <point x="448" y="205"/>
+ <point x="362" y="293"/>
+ <point x="362" y="505" type="curve" smooth="yes"/>
+ <point x="362" y="739"/>
+ <point x="431" y="830"/>
+ <point x="575" y="830" type="curve" smooth="yes"/>
+ <point x="693" y="830"/>
+ <point x="755" y="770"/>
+ <point x="755" y="630" type="curve"/>
+ <point x="242" y="630" type="line"/>
+ <point x="242" y="450" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/input/font-psf-test/source/PsfTest-Bold.ufo/glyphs/L_tnS_mF_.glif b/tests/input/font-psf-test/source/PsfTest-Bold.ufo/glyphs/L_tnS_mF_.glif
new file mode 100644
index 0000000..8a5996d
--- /dev/null
+++ b/tests/input/font-psf-test/source/PsfTest-Bold.ufo/glyphs/L_tnS_mF_.glif
@@ -0,0 +1,39 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmF" format="2">
+ <advance width="800"/>
+ <unicode hex="0066"/>
+ <anchor x="380" y="0" name="H"/>
+ <anchor x="400" y="-100" name="L"/>
+ <anchor x="600" y="1635" name="U"/>
+ <outline>
+ <contour>
+ <point x="30" y="805" type="line"/>
+ <point x="230" y="805" type="line"/>
+ <point x="230" y="0" type="line"/>
+ <point x="540" y="0" type="line"/>
+ <point x="518" y="105"/>
+ <point x="510" y="300"/>
+ <point x="510" y="494" type="curve" smooth="yes"/>
+ <point x="510" y="805" type="line"/>
+ <point x="765" y="805" type="line"/>
+ <point x="765" y="1005" type="line"/>
+ <point x="510" y="1005" type="line"/>
+ <point x="510" y="1159" type="line" smooth="yes"/>
+ <point x="510" y="1322"/>
+ <point x="552" y="1387"/>
+ <point x="648" y="1387" type="curve" smooth="yes"/>
+ <point x="697" y="1387"/>
+ <point x="765" y="1362"/>
+ <point x="808" y="1322" type="curve"/>
+ <point x="865" y="1550" type="line"/>
+ <point x="806" y="1588"/>
+ <point x="699" y="1620"/>
+ <point x="625" y="1620" type="curve" smooth="yes"/>
+ <point x="378" y="1620"/>
+ <point x="230" y="1470"/>
+ <point x="230" y="1170" type="curve" smooth="yes"/>
+ <point x="230" y="1005" type="line"/>
+ <point x="30" y="1005" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/input/font-psf-test/source/PsfTest-Bold.ufo/glyphs/L_tnS_mG_.glif b/tests/input/font-psf-test/source/PsfTest-Bold.ufo/glyphs/L_tnS_mG_.glif
new file mode 100644
index 0000000..871e4e9
--- /dev/null
+++ b/tests/input/font-psf-test/source/PsfTest-Bold.ufo/glyphs/L_tnS_mG_.glif
@@ -0,0 +1,91 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmG" format="2">
+ <advance width="1170"/>
+ <unicode hex="0067"/>
+ <anchor x="597" y="-465" name="H"/>
+ <anchor x="597" y="-535" name="L"/>
+ <anchor x="1187" y="1000" name="R"/>
+ <anchor x="567" y="1100" name="U"/>
+ <outline>
+ <contour>
+ <point x="352" y="395" type="line"/>
+ <point x="256" y="357"/>
+ <point x="202" y="275"/>
+ <point x="202" y="215" type="curve" smooth="yes"/>
+ <point x="202" y="113"/>
+ <point x="280" y="12"/>
+ <point x="547" y="-23" type="curve" smooth="yes"/>
+ <point x="797" y="-50"/>
+ <point x="870" y="-99"/>
+ <point x="870" y="-170" type="curve" smooth="yes"/>
+ <point x="870" y="-229"/>
+ <point x="748" y="-302"/>
+ <point x="602" y="-302" type="curve" smooth="yes"/>
+ <point x="418" y="-302"/>
+ <point x="330" y="-235"/>
+ <point x="330" y="-180" type="curve" smooth="yes"/>
+ <point x="330" y="-121"/>
+ <point x="357" y="-56"/>
+ <point x="562" y="20" type="curve"/>
+ <point x="554" y="49"/>
+ <point x="322" y="75"/>
+ <point x="322" y="75" type="curve"/>
+ <point x="138" y="2"/>
+ <point x="50" y="-89"/>
+ <point x="50" y="-200" type="curve" smooth="yes"/>
+ <point x="50" y="-409"/>
+ <point x="341" y="-505"/>
+ <point x="587" y="-505" type="curve" smooth="yes"/>
+ <point x="843" y="-505"/>
+ <point x="1150" y="-375"/>
+ <point x="1150" y="-160" type="curve" smooth="yes"/>
+ <point x="1150" y="13"/>
+ <point x="1049" y="125"/>
+ <point x="752" y="165" type="curve" smooth="yes"/>
+ <point x="497" y="191"/>
+ <point x="433" y="216"/>
+ <point x="433" y="255" type="curve" smooth="yes"/>
+ <point x="433" y="285"/>
+ <point x="472" y="322"/>
+ <point x="588" y="350" type="curve"/>
+ </contour>
+ <contour>
+ <point x="1102" y="1040" type="line"/>
+ <point x="1003" y="1033"/>
+ <point x="871" y="997"/>
+ <point x="782" y="940" type="curve"/>
+ <point x="847" y="770" type="line"/>
+ <point x="939" y="808"/>
+ <point x="1019" y="823"/>
+ <point x="1092" y="825" type="curve"/>
+ </contour>
+ <contour>
+ <point x="122" y="670" type="curve" smooth="yes"/>
+ <point x="122" y="455"/>
+ <point x="316" y="305"/>
+ <point x="567" y="305" type="curve" smooth="yes"/>
+ <point x="820" y="305"/>
+ <point x="1012" y="465"/>
+ <point x="1012" y="680" type="curve" smooth="yes"/>
+ <point x="1012" y="884"/>
+ <point x="820" y="1040"/>
+ <point x="567" y="1040" type="curve" smooth="yes"/>
+ <point x="316" y="1040"/>
+ <point x="122" y="874"/>
+ </contour>
+ <contour>
+ <point x="377" y="680" type="curve" smooth="yes"/>
+ <point x="377" y="770"/>
+ <point x="457" y="847"/>
+ <point x="567" y="847" type="curve" smooth="yes"/>
+ <point x="678" y="847"/>
+ <point x="757" y="770"/>
+ <point x="757" y="680" type="curve" smooth="yes"/>
+ <point x="757" y="578"/>
+ <point x="678" y="501"/>
+ <point x="567" y="501" type="curve" smooth="yes"/>
+ <point x="457" y="501"/>
+ <point x="377" y="578"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/input/font-psf-test/source/PsfTest-Bold.ufo/glyphs/L_tnS_mH_.glif b/tests/input/font-psf-test/source/PsfTest-Bold.ufo/glyphs/L_tnS_mH_.glif
new file mode 100644
index 0000000..15fc451
--- /dev/null
+++ b/tests/input/font-psf-test/source/PsfTest-Bold.ufo/glyphs/L_tnS_mH_.glif
@@ -0,0 +1,43 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmH" format="2">
+ <advance width="1235"/>
+ <unicode hex="0068"/>
+ <anchor x="280" y="0" name="H"/>
+ <anchor x="620" y="-100" name="L"/>
+ <anchor x="620" y="1635" name="U"/>
+ <outline>
+ <contour>
+ <point x="415" y="580" type="line"/>
+ <point x="450" y="683"/>
+ <point x="560" y="795"/>
+ <point x="675" y="795" type="curve" smooth="yes"/>
+ <point x="782" y="795"/>
+ <point x="830" y="744"/>
+ <point x="830" y="550" type="curve" smooth="yes"/>
+ <point x="830" y="413"/>
+ <point x="830" y="0"/>
+ <point x="830" y="0" type="curve"/>
+ <point x="1110" y="0" type="line"/>
+ <point x="1110" y="0"/>
+ <point x="1110" y="459"/>
+ <point x="1110" y="625" type="curve" smooth="yes"/>
+ <point x="1110" y="900"/>
+ <point x="1008" y="1040"/>
+ <point x="805" y="1040" type="curve" smooth="yes"/>
+ <point x="662" y="1040"/>
+ <point x="513" y="976"/>
+ <point x="415" y="850" type="curve"/>
+ <point x="415" y="894"/>
+ <point x="415" y="1600"/>
+ <point x="415" y="1600" type="curve"/>
+ <point x="120" y="1600" type="line"/>
+ <point x="135" y="1514"/>
+ <point x="135" y="1345"/>
+ <point x="135" y="1130" type="curve" smooth="yes"/>
+ <point x="135" y="935"/>
+ <point x="135" y="0"/>
+ <point x="135" y="0" type="curve"/>
+ <point x="415" y="0" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/input/font-psf-test/source/PsfTest-Bold.ufo/glyphs/L_tnS_mI_.glif b/tests/input/font-psf-test/source/PsfTest-Bold.ufo/glyphs/L_tnS_mI_.glif
new file mode 100644
index 0000000..05022d4
--- /dev/null
+++ b/tests/input/font-psf-test/source/PsfTest-Bold.ufo/glyphs/L_tnS_mI_.glif
@@ -0,0 +1,42 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmI" format="2">
+ <advance width="640"/>
+ <unicode hex="0069"/>
+ <anchor x="320" y="0" name="H"/>
+ <anchor x="320" y="-100" name="L"/>
+ <anchor x="580" y="0" name="O"/>
+ <anchor x="640" y="1000" name="R"/>
+ <anchor x="320" y="1100" name="U"/>
+ <outline>
+ <contour>
+ <point x="165" y="1020" type="line"/>
+ <point x="178" y="915"/>
+ <point x="180" y="725"/>
+ <point x="180" y="530" type="curve" smooth="yes"/>
+ <point x="180" y="336"/>
+ <point x="180" y="0"/>
+ <point x="180" y="0" type="curve"/>
+ <point x="480" y="0" type="line"/>
+ <point x="467" y="107"/>
+ <point x="460" y="346"/>
+ <point x="460" y="475" type="curve" smooth="yes"/>
+ <point x="460" y="558"/>
+ <point x="460" y="1020"/>
+ <point x="460" y="1020" type="curve"/>
+ </contour>
+ <contour>
+ <point x="145" y="1385" type="curve" smooth="yes"/>
+ <point x="145" y="1281"/>
+ <point x="219" y="1210"/>
+ <point x="320" y="1210" type="curve" smooth="yes"/>
+ <point x="422" y="1210"/>
+ <point x="495" y="1281"/>
+ <point x="495" y="1385" type="curve" smooth="yes"/>
+ <point x="495" y="1487"/>
+ <point x="422" y="1560"/>
+ <point x="320" y="1560" type="curve" smooth="yes"/>
+ <point x="219" y="1560"/>
+ <point x="145" y="1487"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/input/font-psf-test/source/PsfTest-Bold.ufo/glyphs/L_tnS_mJ_.glif b/tests/input/font-psf-test/source/PsfTest-Bold.ufo/glyphs/L_tnS_mJ_.glif
new file mode 100644
index 0000000..6e044af
--- /dev/null
+++ b/tests/input/font-psf-test/source/PsfTest-Bold.ufo/glyphs/L_tnS_mJ_.glif
@@ -0,0 +1,44 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmJ" format="2">
+ <advance width="670"/>
+ <unicode hex="006A"/>
+ <anchor x="140" y="-500" name="L"/>
+ <anchor x="355" y="1100" name="U"/>
+ <outline>
+ <contour>
+ <point x="185" y="1385" type="curve" smooth="yes"/>
+ <point x="185" y="1281"/>
+ <point x="259" y="1210"/>
+ <point x="360" y="1210" type="curve" smooth="yes"/>
+ <point x="462" y="1210"/>
+ <point x="535" y="1281"/>
+ <point x="535" y="1385" type="curve" smooth="yes"/>
+ <point x="535" y="1487"/>
+ <point x="462" y="1560"/>
+ <point x="360" y="1560" type="curve" smooth="yes"/>
+ <point x="259" y="1560"/>
+ <point x="185" y="1487"/>
+ </contour>
+ <contour>
+ <point x="500" y="1020" type="line"/>
+ <point x="205" y="1020" type="line"/>
+ <point x="218" y="915"/>
+ <point x="220" y="725"/>
+ <point x="220" y="530" type="curve"/>
+ <point x="220" y="20" type="line"/>
+ <point x="220" y="-150"/>
+ <point x="165" y="-232"/>
+ <point x="48" y="-232" type="curve" smooth="yes"/>
+ <point x="-20" y="-232"/>
+ <point x="-101" y="-195"/>
+ <point x="-145" y="-152" type="curve"/>
+ <point x="-190" y="-389" type="line"/>
+ <point x="-148" y="-421"/>
+ <point x="-37" y="-470"/>
+ <point x="56" y="-470" type="curve" smooth="yes"/>
+ <point x="306" y="-470"/>
+ <point x="500" y="-348"/>
+ <point x="500" y="25" type="curve" smooth="yes"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/input/font-psf-test/source/PsfTest-Bold.ufo/glyphs/L_tnS_mK_.glif b/tests/input/font-psf-test/source/PsfTest-Bold.ufo/glyphs/L_tnS_mK_.glif
new file mode 100644
index 0000000..529f7dd
--- /dev/null
+++ b/tests/input/font-psf-test/source/PsfTest-Bold.ufo/glyphs/L_tnS_mK_.glif
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmK" format="2">
+ <advance width="1138"/>
+ <unicode hex="006B"/>
+ <anchor x="940" y="0" name="H"/>
+ <anchor x="585" y="-100" name="L"/>
+ <anchor x="1140" y="1000" name="R"/>
+ <anchor x="595" y="1635" name="U"/>
+ <outline>
+ <contour>
+ <point x="415" y="0" type="line"/>
+ <point x="415" y="1600" type="line"/>
+ <point x="120" y="1600" type="line"/>
+ <point x="135" y="1514"/>
+ <point x="135" y="1345"/>
+ <point x="135" y="1130" type="curve" smooth="yes"/>
+ <point x="135" y="934"/>
+ <point x="135" y="0"/>
+ <point x="135" y="0" type="curve"/>
+ </contour>
+ <contour>
+ <point x="723" y="1020" type="line"/>
+ <point x="353" y="570" type="line"/>
+ <point x="572" y="528" type="line"/>
+ <point x="1098" y="1020" type="line"/>
+ </contour>
+ <contour>
+ <point x="350" y="570" type="line"/>
+ <point x="761" y="0" type="line"/>
+ <point x="1128" y="0" type="line"/>
+ <point x="540" y="664" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/input/font-psf-test/source/PsfTest-Bold.ufo/glyphs/L_tnS_mL_.glif b/tests/input/font-psf-test/source/PsfTest-Bold.ufo/glyphs/L_tnS_mL_.glif
new file mode 100644
index 0000000..0b21294
--- /dev/null
+++ b/tests/input/font-psf-test/source/PsfTest-Bold.ufo/glyphs/L_tnS_mL_.glif
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmL" format="2">
+ <advance width="640"/>
+ <unicode hex="006C"/>
+ <anchor x="335" y="0" name="H"/>
+ <anchor x="335" y="-100" name="L"/>
+ <anchor x="660" y="1000" name="R"/>
+ <anchor x="320" y="1635" name="U"/>
+ <outline>
+ <contour>
+ <point x="460" y="1600" type="line"/>
+ <point x="160" y="1600" type="line"/>
+ <point x="173" y="1485"/>
+ <point x="180" y="1324"/>
+ <point x="180" y="1130" type="curve" smooth="yes"/>
+ <point x="180" y="0" type="line"/>
+ <point x="480" y="0" type="line"/>
+ <point x="467" y="109"/>
+ <point x="460" y="346"/>
+ <point x="460" y="475" type="curve" smooth="yes"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/input/font-psf-test/source/PsfTest-Bold.ufo/glyphs/L_tnS_mM_.glif b/tests/input/font-psf-test/source/PsfTest-Bold.ufo/glyphs/L_tnS_mM_.glif
new file mode 100644
index 0000000..eace489
--- /dev/null
+++ b/tests/input/font-psf-test/source/PsfTest-Bold.ufo/glyphs/L_tnS_mM_.glif
@@ -0,0 +1,52 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmM" format="2">
+ <advance width="1760"/>
+ <unicode hex="006D"/>
+ <anchor x="890" y="0" name="H"/>
+ <anchor x="890" y="-100" name="L"/>
+ <anchor x="890" y="1100" name="U"/>
+ <outline>
+ <contour>
+ <point x="115" y="1020" type="line"/>
+ <point x="136" y="951"/>
+ <point x="165" y="811"/>
+ <point x="165" y="615" type="curve" smooth="yes"/>
+ <point x="165" y="0" type="line"/>
+ <point x="445" y="0" type="line"/>
+ <point x="445" y="640" type="line"/>
+ <point x="484" y="731"/>
+ <point x="560" y="795"/>
+ <point x="635" y="795" type="curve" smooth="yes"/>
+ <point x="723" y="795"/>
+ <point x="750" y="759"/>
+ <point x="750" y="570" type="curve" smooth="yes"/>
+ <point x="750" y="0" type="line"/>
+ <point x="1030" y="0" type="line"/>
+ <point x="1030" y="660" type="line"/>
+ <point x="1073" y="742"/>
+ <point x="1147" y="795"/>
+ <point x="1220" y="795" type="curve" smooth="yes"/>
+ <point x="1310" y="795"/>
+ <point x="1335" y="751"/>
+ <point x="1335" y="550" type="curve" smooth="yes"/>
+ <point x="1335" y="0" type="line"/>
+ <point x="1615" y="0" type="line"/>
+ <point x="1615" y="660" type="line" smooth="yes"/>
+ <point x="1615" y="907"/>
+ <point x="1548" y="1040"/>
+ <point x="1345" y="1040" type="curve" smooth="yes"/>
+ <point x="1240" y="1040"/>
+ <point x="1131" y="1007"/>
+ <point x="1006" y="872" type="curve"/>
+ <point x="973" y="960"/>
+ <point x="891" y="1040"/>
+ <point x="760" y="1040" type="curve" smooth="yes"/>
+ <point x="644" y="1040"/>
+ <point x="544" y="1008"/>
+ <point x="422" y="875" type="curve"/>
+ <point x="412" y="920"/>
+ <point x="397" y="981"/>
+ <point x="375" y="1020" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/input/font-psf-test/source/PsfTest-Bold.ufo/glyphs/L_tnS_mN_.glif b/tests/input/font-psf-test/source/PsfTest-Bold.ufo/glyphs/L_tnS_mN_.glif
new file mode 100644
index 0000000..f7abb6f
--- /dev/null
+++ b/tests/input/font-psf-test/source/PsfTest-Bold.ufo/glyphs/L_tnS_mN_.glif
@@ -0,0 +1,43 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmN" format="2">
+ <advance width="1245"/>
+ <unicode hex="006E"/>
+ <anchor x="620" y="0" name="H"/>
+ <anchor x="620" y="-100" name="L"/>
+ <anchor x="620" y="1100" name="U"/>
+ <outline>
+ <contour>
+ <point x="1120" y="0" type="line"/>
+ <point x="1120" y="0"/>
+ <point x="1120" y="459"/>
+ <point x="1120" y="625" type="curve" smooth="yes"/>
+ <point x="1120" y="900"/>
+ <point x="998" y="1040"/>
+ <point x="795" y="1040" type="curve" smooth="yes"/>
+ <point x="654" y="1040"/>
+ <point x="537" y="980"/>
+ <point x="410" y="835" type="curve"/>
+ <point x="403" y="881"/>
+ <point x="385" y="980"/>
+ <point x="370" y="1020" type="curve"/>
+ <point x="95" y="1020" type="line"/>
+ <point x="117" y="951"/>
+ <point x="145" y="811"/>
+ <point x="145" y="615" type="curve" smooth="yes"/>
+ <point x="145" y="420"/>
+ <point x="145" y="0"/>
+ <point x="145" y="0" type="curve"/>
+ <point x="425" y="0" type="line"/>
+ <point x="425" y="580" type="line"/>
+ <point x="460" y="683"/>
+ <point x="570" y="795"/>
+ <point x="685" y="795" type="curve" smooth="yes"/>
+ <point x="792" y="795"/>
+ <point x="840" y="734"/>
+ <point x="840" y="550" type="curve" smooth="yes"/>
+ <point x="840" y="413"/>
+ <point x="840" y="0"/>
+ <point x="840" y="0" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/input/font-psf-test/source/PsfTest-Bold.ufo/glyphs/L_tnS_mO_.glif b/tests/input/font-psf-test/source/PsfTest-Bold.ufo/glyphs/L_tnS_mO_.glif
new file mode 100644
index 0000000..063c297
--- /dev/null
+++ b/tests/input/font-psf-test/source/PsfTest-Bold.ufo/glyphs/L_tnS_mO_.glif
@@ -0,0 +1,40 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmO" format="2">
+ <advance width="1160"/>
+ <unicode hex="006F"/>
+ <anchor x="578" y="0" name="H"/>
+ <anchor x="580" y="-100" name="L"/>
+ <anchor x="790" y="0" name="O"/>
+ <anchor x="1160" y="1000" name="R"/>
+ <anchor x="580" y="1100" name="U"/>
+ <outline>
+ <contour>
+ <point x="90" y="507" type="curve" smooth="yes"/>
+ <point x="90" y="163"/>
+ <point x="288" y="-25"/>
+ <point x="570" y="-25" type="curve" smooth="yes"/>
+ <point x="840" y="-25"/>
+ <point x="1070" y="163"/>
+ <point x="1070" y="507" type="curve" smooth="yes"/>
+ <point x="1070" y="851"/>
+ <point x="873" y="1040"/>
+ <point x="590" y="1040" type="curve" smooth="yes"/>
+ <point x="320" y="1040"/>
+ <point x="90" y="851"/>
+ </contour>
+ <contour>
+ <point x="370" y="507" type="curve" smooth="yes"/>
+ <point x="370" y="699"/>
+ <point x="451" y="815"/>
+ <point x="580" y="815" type="curve" smooth="yes"/>
+ <point x="717" y="815"/>
+ <point x="790" y="699"/>
+ <point x="790" y="507" type="curve" smooth="yes"/>
+ <point x="790" y="316"/>
+ <point x="709" y="200"/>
+ <point x="580" y="200" type="curve" smooth="yes"/>
+ <point x="443" y="200"/>
+ <point x="370" y="316"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/input/font-psf-test/source/PsfTest-Bold.ufo/glyphs/L_tnS_mP_.glif b/tests/input/font-psf-test/source/PsfTest-Bold.ufo/glyphs/L_tnS_mP_.glif
new file mode 100644
index 0000000..4fe224b
--- /dev/null
+++ b/tests/input/font-psf-test/source/PsfTest-Bold.ufo/glyphs/L_tnS_mP_.glif
@@ -0,0 +1,59 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmP" format="2">
+ <advance width="1235"/>
+ <unicode hex="0070"/>
+ <anchor x="290" y="-435" name="H"/>
+ <anchor x="640" y="-500" name="L"/>
+ <anchor x="1235" y="1000" name="R"/>
+ <anchor x="640" y="1100" name="U"/>
+ <outline>
+ <contour>
+ <point x="450" y="-490" type="line"/>
+ <point x="433" y="-405"/>
+ <point x="425" y="-310"/>
+ <point x="425" y="-150" type="curve" smooth="yes"/>
+ <point x="425" y="-71"/>
+ <point x="425" y="-41"/>
+ <point x="425" y="65" type="curve"/>
+ <point x="518" y="10"/>
+ <point x="594" y="-25"/>
+ <point x="699" y="-25" type="curve" smooth="yes"/>
+ <point x="945" y="-25"/>
+ <point x="1145" y="193"/>
+ <point x="1145" y="535" type="curve" smooth="yes"/>
+ <point x="1145" y="828"/>
+ <point x="996" y="1040"/>
+ <point x="773" y="1040" type="curve" smooth="yes"/>
+ <point x="628" y="1040"/>
+ <point x="502" y="962"/>
+ <point x="410" y="850" type="curve"/>
+ <point x="401" y="932"/>
+ <point x="385" y="990"/>
+ <point x="370" y="1020" type="curve"/>
+ <point x="95" y="1020" type="line"/>
+ <point x="140" y="907"/>
+ <point x="145" y="734"/>
+ <point x="145" y="485" type="curve" smooth="yes"/>
+ <point x="145" y="291"/>
+ <point x="145" y="-345"/>
+ <point x="145" y="-490" type="curve"/>
+ </contour>
+ <contour>
+ <point x="633" y="206" type="curve" smooth="yes"/>
+ <point x="564" y="206"/>
+ <point x="527" y="225"/>
+ <point x="425" y="300" type="curve"/>
+ <point x="425" y="390"/>
+ <point x="425" y="507"/>
+ <point x="425" y="585" type="curve"/>
+ <point x="482" y="726"/>
+ <point x="583" y="802"/>
+ <point x="672" y="802" type="curve" smooth="yes"/>
+ <point x="793" y="802"/>
+ <point x="865" y="686"/>
+ <point x="865" y="505" type="curve" smooth="yes"/>
+ <point x="865" y="320"/>
+ <point x="755" y="206"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/input/font-psf-test/source/PsfTest-Bold.ufo/glyphs/L_tnS_mQ_.glif b/tests/input/font-psf-test/source/PsfTest-Bold.ufo/glyphs/L_tnS_mQ_.glif
new file mode 100644
index 0000000..9727ad7
--- /dev/null
+++ b/tests/input/font-psf-test/source/PsfTest-Bold.ufo/glyphs/L_tnS_mQ_.glif
@@ -0,0 +1,47 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmQ" format="2">
+ <advance width="1210"/>
+ <unicode hex="0071"/>
+ <anchor x="600" y="-500" name="L"/>
+ <anchor x="1210" y="1000" name="R"/>
+ <anchor x="600" y="1100" name="U"/>
+ <outline>
+ <contour>
+ <point x="790" y="-490" type="line"/>
+ <point x="1095" y="-490" type="line"/>
+ <point x="1078" y="-405"/>
+ <point x="1070" y="-310"/>
+ <point x="1070" y="-150" type="curve" smooth="yes"/>
+ <point x="1070" y="-26"/>
+ <point x="1070" y="965"/>
+ <point x="1070" y="965" type="curve"/>
+ <point x="934" y="1001"/>
+ <point x="773" y="1040"/>
+ <point x="620" y="1040" type="curve" smooth="yes"/>
+ <point x="255" y="1040"/>
+ <point x="100" y="742"/>
+ <point x="100" y="435" type="curve" smooth="yes"/>
+ <point x="100" y="117"/>
+ <point x="316" y="-25"/>
+ <point x="500" y="-25" type="curve" smooth="yes"/>
+ <point x="593" y="-25"/>
+ <point x="686" y="14"/>
+ <point x="790" y="120" type="curve"/>
+ </contour>
+ <contour>
+ <point x="790" y="368" type="line"/>
+ <point x="727" y="258"/>
+ <point x="650" y="203"/>
+ <point x="580" y="203" type="curve" smooth="yes"/>
+ <point x="475" y="203"/>
+ <point x="380" y="287"/>
+ <point x="380" y="485" type="curve" smooth="yes"/>
+ <point x="380" y="641"/>
+ <point x="456" y="802"/>
+ <point x="655" y="802" type="curve" smooth="yes"/>
+ <point x="696" y="802"/>
+ <point x="749" y="789"/>
+ <point x="790" y="770" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/input/font-psf-test/source/PsfTest-Bold.ufo/glyphs/L_tnS_mR_.glif b/tests/input/font-psf-test/source/PsfTest-Bold.ufo/glyphs/L_tnS_mR_.glif
new file mode 100644
index 0000000..8a81116
--- /dev/null
+++ b/tests/input/font-psf-test/source/PsfTest-Bold.ufo/glyphs/L_tnS_mR_.glif
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmR" format="2">
+ <advance width="995"/>
+ <unicode hex="0072"/>
+ <anchor x="285" y="0" name="H"/>
+ <anchor x="275" y="-100" name="L"/>
+ <anchor x="550" y="1100" name="U"/>
+ <outline>
+ <contour>
+ <point x="425" y="0" type="line"/>
+ <point x="425" y="530" type="line"/>
+ <point x="460" y="654"/>
+ <point x="570" y="781"/>
+ <point x="637" y="781" type="curve" smooth="yes"/>
+ <point x="722" y="781"/>
+ <point x="755" y="721"/>
+ <point x="762" y="630" type="curve"/>
+ <point x="985" y="665" type="line"/>
+ <point x="985" y="868"/>
+ <point x="913" y="1040"/>
+ <point x="725" y="1040" type="curve" smooth="yes"/>
+ <point x="634" y="1040"/>
+ <point x="507" y="964"/>
+ <point x="410" y="825" type="curve"/>
+ <point x="403" y="873"/>
+ <point x="385" y="978"/>
+ <point x="370" y="1020" type="curve"/>
+ <point x="95" y="1020" type="line"/>
+ <point x="117" y="951"/>
+ <point x="145" y="811"/>
+ <point x="145" y="615" type="curve" smooth="yes"/>
+ <point x="145" y="0" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/input/font-psf-test/source/PsfTest-Bold.ufo/glyphs/L_tnS_mS_.glif b/tests/input/font-psf-test/source/PsfTest-Bold.ufo/glyphs/L_tnS_mS_.glif
new file mode 100644
index 0000000..06b1a9a
--- /dev/null
+++ b/tests/input/font-psf-test/source/PsfTest-Bold.ufo/glyphs/L_tnS_mS_.glif
@@ -0,0 +1,50 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmS" format="2">
+ <advance width="1035"/>
+ <unicode hex="0073"/>
+ <anchor x="515" y="0" name="H"/>
+ <anchor x="515" y="-100" name="L"/>
+ <anchor x="530" y="1100" name="U"/>
+ <outline>
+ <contour>
+ <point x="905" y="960" type="line"/>
+ <point x="827" y="998"/>
+ <point x="708" y="1040"/>
+ <point x="545" y="1040" type="curve" smooth="yes"/>
+ <point x="202" y="1040"/>
+ <point x="110" y="818"/>
+ <point x="110" y="720" type="curve" smooth="yes"/>
+ <point x="110" y="594"/>
+ <point x="171" y="491"/>
+ <point x="455" y="432" type="curve" smooth="yes"/>
+ <point x="646" y="390"/>
+ <point x="690" y="348"/>
+ <point x="690" y="290" type="curve" smooth="yes"/>
+ <point x="690" y="243"/>
+ <point x="624" y="199"/>
+ <point x="530" y="199" type="curve" smooth="yes"/>
+ <point x="413" y="199"/>
+ <point x="254" y="253"/>
+ <point x="155" y="334" type="curve"/>
+ <point x="100" y="90" type="line"/>
+ <point x="187" y="28"/>
+ <point x="346" y="-25"/>
+ <point x="525" y="-25" type="curve" smooth="yes"/>
+ <point x="768" y="-25"/>
+ <point x="960" y="123"/>
+ <point x="960" y="315" type="curve" smooth="yes"/>
+ <point x="960" y="504"/>
+ <point x="788" y="583"/>
+ <point x="580" y="625" type="curve" smooth="yes"/>
+ <point x="405" y="659"/>
+ <point x="380" y="681"/>
+ <point x="380" y="730" type="curve" smooth="yes"/>
+ <point x="380" y="770"/>
+ <point x="418" y="816"/>
+ <point x="535" y="816" type="curve" smooth="yes"/>
+ <point x="674" y="816"/>
+ <point x="791" y="760"/>
+ <point x="866" y="721" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/input/font-psf-test/source/PsfTest-Bold.ufo/glyphs/L_tnS_mT_.glif b/tests/input/font-psf-test/source/PsfTest-Bold.ufo/glyphs/L_tnS_mT_.glif
new file mode 100644
index 0000000..d4123c7
--- /dev/null
+++ b/tests/input/font-psf-test/source/PsfTest-Bold.ufo/glyphs/L_tnS_mT_.glif
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmT" format="2">
+ <advance width="885"/>
+ <unicode hex="0074"/>
+ <anchor x="530" y="0" name="H"/>
+ <anchor x="530" y="-100" name="L"/>
+ <anchor x="885" y="1000" name="R"/>
+ <anchor x="360" y="1360" name="U"/>
+ <outline>
+ <contour>
+ <point x="220" y="270" type="line"/>
+ <point x="220" y="39"/>
+ <point x="374" y="-25"/>
+ <point x="563" y="-25" type="curve" smooth="yes"/>
+ <point x="635" y="-25"/>
+ <point x="725" y="-3"/>
+ <point x="820" y="57" type="curve"/>
+ <point x="820" y="281" type="line"/>
+ <point x="741" y="232"/>
+ <point x="678" y="206"/>
+ <point x="627" y="206" type="curve" smooth="yes"/>
+ <point x="537" y="206"/>
+ <point x="500" y="235"/>
+ <point x="500" y="462" type="curve" smooth="yes"/>
+ <point x="500" y="1320" type="line"/>
+ <point x="220" y="1320" type="line"/>
+ </contour>
+ <contour>
+ <point x="805" y="805" type="line"/>
+ <point x="805" y="1005" type="line"/>
+ <point x="30" y="1005" type="line"/>
+ <point x="30" y="805" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/input/font-psf-test/source/PsfTest-Bold.ufo/glyphs/L_tnS_mU_.glif b/tests/input/font-psf-test/source/PsfTest-Bold.ufo/glyphs/L_tnS_mU_.glif
new file mode 100644
index 0000000..5b8d434
--- /dev/null
+++ b/tests/input/font-psf-test/source/PsfTest-Bold.ufo/glyphs/L_tnS_mU_.glif
@@ -0,0 +1,51 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmU" format="2">
+ <advance width="1245"/>
+ <unicode hex="0075"/>
+ <anchor x="515" y="0" name="H"/>
+ <anchor x="615" y="-100" name="L"/>
+ <anchor x="690" y="0" name="O"/>
+ <anchor x="1258" y="1000" name="R"/>
+ <anchor x="615" y="1100" name="U"/>
+ <outline>
+ <contour>
+ <point x="1160" y="0" type="line"/>
+ <point x="1118" y="112"/>
+ <point x="1095" y="256"/>
+ <point x="1095" y="450" type="curve" smooth="yes"/>
+ <point x="1095" y="646"/>
+ <point x="1095" y="1020"/>
+ <point x="1095" y="1020" type="curve"/>
+ <point x="795" y="1020" type="line"/>
+ <point x="813" y="898"/>
+ <point x="815" y="832"/>
+ <point x="815" y="700" type="curve" smooth="yes"/>
+ <point x="815" y="418" type="line"/>
+ <point x="774" y="326"/>
+ <point x="651" y="206"/>
+ <point x="560" y="206" type="curve" smooth="yes"/>
+ <point x="458" y="206"/>
+ <point x="425" y="284"/>
+ <point x="425" y="465" type="curve" smooth="yes"/>
+ <point x="425" y="603"/>
+ <point x="425" y="1020"/>
+ <point x="425" y="1020" type="curve"/>
+ <point x="125" y="1020" type="line"/>
+ <point x="143" y="900"/>
+ <point x="145" y="827"/>
+ <point x="145" y="700" type="curve" smooth="yes"/>
+ <point x="145" y="681"/>
+ <point x="145" y="424"/>
+ <point x="145" y="405" type="curve" smooth="yes"/>
+ <point x="145" y="120"/>
+ <point x="250" y="-25"/>
+ <point x="458" y="-25" type="curve" smooth="yes"/>
+ <point x="595" y="-25"/>
+ <point x="722" y="48"/>
+ <point x="840" y="185" type="curve"/>
+ <point x="850" y="116"/>
+ <point x="876" y="43"/>
+ <point x="895" y="0" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/input/font-psf-test/source/PsfTest-Bold.ufo/glyphs/L_tnS_mV_.glif b/tests/input/font-psf-test/source/PsfTest-Bold.ufo/glyphs/L_tnS_mV_.glif
new file mode 100644
index 0000000..daf1468
--- /dev/null
+++ b/tests/input/font-psf-test/source/PsfTest-Bold.ufo/glyphs/L_tnS_mV_.glif
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmV" format="2">
+ <advance width="1104"/>
+ <unicode hex="0076"/>
+ <anchor x="565" y="0" name="H"/>
+ <anchor x="565" y="-100" name="L"/>
+ <anchor x="750" y="0" name="O"/>
+ <anchor x="565" y="1100" name="U"/>
+ <outline>
+ <contour>
+ <point x="786" y="1020" type="line"/>
+ <point x="556" y="290" type="line"/>
+ <point x="322" y="1020" type="line"/>
+ <point x="10" y="1020" type="line"/>
+ <point x="65" y="905"/>
+ <point x="133" y="746"/>
+ <point x="165" y="665" type="curve" smooth="yes"/>
+ <point x="227" y="510"/>
+ <point x="430" y="0"/>
+ <point x="430" y="0" type="curve"/>
+ <point x="674" y="0" type="line"/>
+ <point x="674" y="0"/>
+ <point x="886" y="536"/>
+ <point x="939" y="665" type="curve" smooth="yes"/>
+ <point x="972" y="744"/>
+ <point x="1037" y="905"/>
+ <point x="1094" y="1020" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/input/font-psf-test/source/PsfTest-Bold.ufo/glyphs/L_tnS_mW_.glif b/tests/input/font-psf-test/source/PsfTest-Bold.ufo/glyphs/L_tnS_mW_.glif
new file mode 100644
index 0000000..1ca1ec4
--- /dev/null
+++ b/tests/input/font-psf-test/source/PsfTest-Bold.ufo/glyphs/L_tnS_mW_.glif
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmW" format="2">
+ <advance width="1570"/>
+ <unicode hex="0077"/>
+ <anchor x="785" y="-100" name="L"/>
+ <anchor x="785" y="1100" name="U"/>
+ <outline>
+ <contour>
+ <point x="665" y="1020" type="line"/>
+ <point x="480" y="285" type="line"/>
+ <point x="323" y="1020" type="line"/>
+ <point x="35" y="1020" type="line"/>
+ <point x="82" y="867"/>
+ <point x="110" y="771"/>
+ <point x="140" y="665" type="curve" smooth="yes"/>
+ <point x="325" y="0" type="line"/>
+ <point x="615" y="0" type="line"/>
+ <point x="785" y="695" type="line"/>
+ <point x="955" y="0" type="line"/>
+ <point x="1245" y="0" type="line"/>
+ <point x="1430" y="665" type="line" smooth="yes"/>
+ <point x="1464" y="785"/>
+ <point x="1488" y="868"/>
+ <point x="1535" y="1020" type="curve"/>
+ <point x="1247" y="1020" type="line"/>
+ <point x="1090" y="285" type="line"/>
+ <point x="905" y="1020" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/input/font-psf-test/source/PsfTest-Bold.ufo/glyphs/L_tnS_mX_.glif b/tests/input/font-psf-test/source/PsfTest-Bold.ufo/glyphs/L_tnS_mX_.glif
new file mode 100644
index 0000000..971c129
--- /dev/null
+++ b/tests/input/font-psf-test/source/PsfTest-Bold.ufo/glyphs/L_tnS_mX_.glif
@@ -0,0 +1,40 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmX" format="2">
+ <advance width="1185"/>
+ <unicode hex="0078"/>
+ <anchor x="960" y="0" name="H"/>
+ <anchor x="590" y="-100" name="L"/>
+ <anchor x="615" y="1100" name="U"/>
+ <outline>
+ <contour>
+ <point x="815" y="0" type="line"/>
+ <point x="1145" y="0" type="line"/>
+ <point x="1037" y="129"/>
+ <point x="989" y="190"/>
+ <point x="930" y="270" type="curve" smooth="yes"/>
+ <point x="380" y="1020" type="line"/>
+ <point x="50" y="1020" type="line"/>
+ <point x="158" y="887"/>
+ <point x="192" y="842"/>
+ <point x="260" y="750" type="curve" smooth="yes"/>
+ </contour>
+ <contour>
+ <point x="499" y="616" type="line"/>
+ <point x="245" y="270" type="line" smooth="yes"/>
+ <point x="195" y="201"/>
+ <point x="150" y="143"/>
+ <point x="40" y="0" type="curve"/>
+ <point x="345" y="0" type="line"/>
+ <point x="584" y="359" type="line"/>
+ </contour>
+ <contour>
+ <point x="675" y="405" type="line"/>
+ <point x="925" y="750" type="line" smooth="yes"/>
+ <point x="980" y="826"/>
+ <point x="1027" y="886"/>
+ <point x="1130" y="1020" type="curve"/>
+ <point x="825" y="1020" type="line"/>
+ <point x="595" y="668" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/input/font-psf-test/source/PsfTest-Bold.ufo/glyphs/L_tnS_mY_.glif b/tests/input/font-psf-test/source/PsfTest-Bold.ufo/glyphs/L_tnS_mY_.glif
new file mode 100644
index 0000000..ea8d25e
--- /dev/null
+++ b/tests/input/font-psf-test/source/PsfTest-Bold.ufo/glyphs/L_tnS_mY_.glif
@@ -0,0 +1,39 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmY" format="2">
+ <advance width="1100"/>
+ <unicode hex="0079"/>
+ <anchor x="845" y="-100" name="L"/>
+ <anchor x="1155" y="1000" name="R"/>
+ <anchor x="565" y="1100" name="U"/>
+ <outline>
+ <contour>
+ <point x="945" y="665" type="line" smooth="yes"/>
+ <point x="978" y="758"/>
+ <point x="1021" y="865"/>
+ <point x="1090" y="1020" type="curve"/>
+ <point x="777" y="1020" type="line"/>
+ <point x="777" y="1020"/>
+ <point x="646" y="549"/>
+ <point x="573" y="293" type="curve"/>
+ <point x="333" y="1020" type="line"/>
+ <point x="20" y="1020" type="line"/>
+ <point x="97" y="864"/>
+ <point x="144" y="757"/>
+ <point x="180" y="665" type="curve" smooth="yes"/>
+ <point x="445" y="-18" type="line"/>
+ <point x="366" y="-209"/>
+ <point x="304" y="-242"/>
+ <point x="245" y="-242" type="curve" smooth="yes"/>
+ <point x="179" y="-242"/>
+ <point x="102" y="-202"/>
+ <point x="60" y="-167" type="curve"/>
+ <point x="-10" y="-385" type="line"/>
+ <point x="63" y="-439"/>
+ <point x="154" y="-470"/>
+ <point x="245" y="-470" type="curve" smooth="yes"/>
+ <point x="427" y="-470"/>
+ <point x="565" y="-387"/>
+ <point x="705" y="0" type="curve" smooth="yes"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/input/font-psf-test/source/PsfTest-Bold.ufo/glyphs/N_onB_reakingH_yphen.glif b/tests/input/font-psf-test/source/PsfTest-Bold.ufo/glyphs/N_onB_reakingH_yphen.glif
new file mode 100644
index 0000000..7dc67c0
--- /dev/null
+++ b/tests/input/font-psf-test/source/PsfTest-Bold.ufo/glyphs/N_onB_reakingH_yphen.glif
@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="NonBreakingHyphen" format="2">
+ <advance width="895"/>
+ <unicode hex="2011"/>
+ <anchor x="450" y="1100" name="U"/>
+ <outline>
+ <component base="HyphenMinus"/>
+ </outline>
+</glyph>
diff --git a/tests/input/font-psf-test/source/PsfTest-Bold.ufo/glyphs/N_umS_gn.glif b/tests/input/font-psf-test/source/PsfTest-Bold.ufo/glyphs/N_umS_gn.glif
new file mode 100644
index 0000000..54b82cb
--- /dev/null
+++ b/tests/input/font-psf-test/source/PsfTest-Bold.ufo/glyphs/N_umS_gn.glif
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="NumSgn" format="2">
+ <advance width="1200"/>
+ <unicode hex="0023"/>
+ <outline>
+ <contour>
+ <point x="412" y="1360" type="line"/>
+ <point x="52" y="100" type="line"/>
+ <point x="272" y="100" type="line"/>
+ <point x="632" y="1360" type="line"/>
+ </contour>
+ <contour>
+ <point x="10" y="425" type="line"/>
+ <point x="1101" y="425" type="line"/>
+ <point x="1101" y="635" type="line"/>
+ <point x="10" y="635" type="line"/>
+ </contour>
+ <contour>
+ <point x="69" y="850" type="line"/>
+ <point x="1160" y="850" type="line"/>
+ <point x="1160" y="1060" type="line"/>
+ <point x="69" y="1060" type="line"/>
+ </contour>
+ <contour>
+ <point x="887" y="1360" type="line"/>
+ <point x="527" y="100" type="line"/>
+ <point x="747" y="100" type="line"/>
+ <point x="1107" y="1360" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/input/font-psf-test/source/PsfTest-Bold.ufo/glyphs/P_ercentS_gn.glif b/tests/input/font-psf-test/source/PsfTest-Bold.ufo/glyphs/P_ercentS_gn.glif
new file mode 100644
index 0000000..5017543
--- /dev/null
+++ b/tests/input/font-psf-test/source/PsfTest-Bold.ufo/glyphs/P_ercentS_gn.glif
@@ -0,0 +1,69 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="PercentSgn" format="2">
+ <advance width="1565"/>
+ <unicode hex="0025"/>
+ <outline>
+ <contour>
+ <point x="1073" y="1480" type="line"/>
+ <point x="291" y="-25" type="line"/>
+ <point x="499" y="-25" type="line"/>
+ <point x="1279" y="1480" type="line"/>
+ </contour>
+ <contour>
+ <point x="511" y="1076" type="curve" smooth="yes"/>
+ <point x="511" y="892"/>
+ <point x="470" y="815"/>
+ <point x="394" y="815" type="curve" smooth="yes"/>
+ <point x="315" y="815"/>
+ <point x="279" y="891"/>
+ <point x="279" y="1091" type="curve" smooth="yes"/>
+ <point x="279" y="1275"/>
+ <point x="317" y="1350"/>
+ <point x="394" y="1350" type="curve" smooth="yes"/>
+ <point x="475" y="1350"/>
+ <point x="511" y="1276"/>
+ </contour>
+ <contour>
+ <point x="721" y="1089" type="curve" smooth="yes"/>
+ <point x="721" y="1362"/>
+ <point x="584" y="1480"/>
+ <point x="399" y="1480" type="curve" smooth="yes"/>
+ <point x="215" y="1480"/>
+ <point x="69" y="1360"/>
+ <point x="69" y="1078" type="curve" smooth="yes"/>
+ <point x="69" y="796"/>
+ <point x="205" y="685"/>
+ <point x="390" y="685" type="curve" smooth="yes"/>
+ <point x="575" y="685"/>
+ <point x="721" y="794"/>
+ </contour>
+ <contour>
+ <point x="1286" y="366" type="curve" smooth="yes"/>
+ <point x="1286" y="182"/>
+ <point x="1245" y="105"/>
+ <point x="1169" y="105" type="curve" smooth="yes"/>
+ <point x="1090" y="105"/>
+ <point x="1054" y="181"/>
+ <point x="1054" y="381" type="curve" smooth="yes"/>
+ <point x="1054" y="565"/>
+ <point x="1092" y="640"/>
+ <point x="1169" y="640" type="curve" smooth="yes"/>
+ <point x="1250" y="640"/>
+ <point x="1286" y="566"/>
+ </contour>
+ <contour>
+ <point x="1496" y="379" type="curve" smooth="yes"/>
+ <point x="1496" y="652"/>
+ <point x="1359" y="770"/>
+ <point x="1174" y="770" type="curve" smooth="yes"/>
+ <point x="990" y="770"/>
+ <point x="844" y="650"/>
+ <point x="844" y="368" type="curve" smooth="yes"/>
+ <point x="844" y="86"/>
+ <point x="980" y="-25"/>
+ <point x="1165" y="-25" type="curve" smooth="yes"/>
+ <point x="1350" y="-25"/>
+ <point x="1496" y="84"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/input/font-psf-test/source/PsfTest-Bold.ufo/glyphs/P_lusS_gn.glif b/tests/input/font-psf-test/source/PsfTest-Bold.ufo/glyphs/P_lusS_gn.glif
new file mode 100644
index 0000000..a1a4c93
--- /dev/null
+++ b/tests/input/font-psf-test/source/PsfTest-Bold.ufo/glyphs/P_lusS_gn.glif
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="PlusSgn" format="2">
+ <advance width="1200"/>
+ <unicode hex="002B"/>
+ <outline>
+ <contour>
+ <point x="495" y="1180" type="line"/>
+ <point x="495" y="285" type="line"/>
+ <point x="705" y="285" type="line"/>
+ <point x="705" y="1180" type="line"/>
+ </contour>
+ <contour>
+ <point x="155" y="630" type="line"/>
+ <point x="1045" y="630" type="line"/>
+ <point x="1045" y="840" type="line"/>
+ <point x="155" y="840" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/input/font-psf-test/source/PsfTest-Bold.ufo/glyphs/Q_stnM_rk.glif b/tests/input/font-psf-test/source/PsfTest-Bold.ufo/glyphs/Q_stnM_rk.glif
new file mode 100644
index 0000000..c9bbb28
--- /dev/null
+++ b/tests/input/font-psf-test/source/PsfTest-Bold.ufo/glyphs/Q_stnM_rk.glif
@@ -0,0 +1,49 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="QstnMrk" format="2">
+ <advance width="1090"/>
+ <unicode hex="003F"/>
+ <outline>
+ <contour>
+ <point x="640" y="500" type="line"/>
+ <point x="640" y="671"/>
+ <point x="668" y="805"/>
+ <point x="767" y="956" type="curve" smooth="yes"/>
+ <point x="837" y="1063"/>
+ <point x="900" y="1117"/>
+ <point x="900" y="1220" type="curve" smooth="yes"/>
+ <point x="900" y="1402"/>
+ <point x="757" y="1540"/>
+ <point x="500" y="1540" type="curve" smooth="yes"/>
+ <point x="355" y="1540"/>
+ <point x="206" y="1470"/>
+ <point x="140" y="1407" type="curve"/>
+ <point x="185" y="1168" type="line"/>
+ <point x="261" y="1247"/>
+ <point x="372" y="1295"/>
+ <point x="472" y="1295" type="curve" smooth="yes"/>
+ <point x="569" y="1295"/>
+ <point x="615" y="1249"/>
+ <point x="615" y="1190" type="curve" smooth="yes"/>
+ <point x="615" y="1139"/>
+ <point x="565" y="1096"/>
+ <point x="495" y="980" type="curve" smooth="yes"/>
+ <point x="434" y="879"/>
+ <point x="375" y="710"/>
+ <point x="375" y="500" type="curve"/>
+ </contour>
+ <contour>
+ <point x="335" y="150" type="curve" smooth="yes"/>
+ <point x="335" y="46"/>
+ <point x="409" y="-25"/>
+ <point x="510" y="-25" type="curve" smooth="yes"/>
+ <point x="612" y="-25"/>
+ <point x="685" y="46"/>
+ <point x="685" y="150" type="curve" smooth="yes"/>
+ <point x="685" y="252"/>
+ <point x="612" y="325"/>
+ <point x="510" y="325" type="curve" smooth="yes"/>
+ <point x="409" y="325"/>
+ <point x="335" y="252"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/input/font-psf-test/source/PsfTest-Bold.ufo/glyphs/Q_uotM_rk.glif b/tests/input/font-psf-test/source/PsfTest-Bold.ufo/glyphs/Q_uotM_rk.glif
new file mode 100644
index 0000000..794a655
--- /dev/null
+++ b/tests/input/font-psf-test/source/PsfTest-Bold.ufo/glyphs/Q_uotM_rk.glif
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="QuotMrk" format="2">
+ <advance width="1085"/>
+ <unicode hex="0022"/>
+ <outline>
+ <contour>
+ <point x="450" y="1045" type="line"/>
+ <point x="455" y="1186"/>
+ <point x="456" y="1339"/>
+ <point x="485" y="1585" type="curve"/>
+ <point x="240" y="1585" type="line"/>
+ <point x="271" y="1339"/>
+ <point x="271" y="1186"/>
+ <point x="275" y="1045" type="curve"/>
+ </contour>
+ <contour>
+ <point x="810" y="1045" type="line"/>
+ <point x="815" y="1186"/>
+ <point x="816" y="1339"/>
+ <point x="845" y="1585" type="curve"/>
+ <point x="600" y="1585" type="line"/>
+ <point x="631" y="1339"/>
+ <point x="631" y="1186"/>
+ <point x="635" y="1045" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/input/font-psf-test/source/PsfTest-Bold.ufo/glyphs/R_everseS_olidus.glif b/tests/input/font-psf-test/source/PsfTest-Bold.ufo/glyphs/R_everseS_olidus.glif
new file mode 100644
index 0000000..799c999
--- /dev/null
+++ b/tests/input/font-psf-test/source/PsfTest-Bold.ufo/glyphs/R_everseS_olidus.glif
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="ReverseSolidus" format="2">
+ <advance width="1080"/>
+ <unicode hex="005C"/>
+ <outline>
+ <contour>
+ <point x="10" y="1600" type="line"/>
+ <point x="840" y="-245" type="line"/>
+ <point x="1070" y="-245" type="line"/>
+ <point x="240" y="1600" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/input/font-psf-test/source/PsfTest-Bold.ufo/glyphs/R_tC_urlyB_rac.glif b/tests/input/font-psf-test/source/PsfTest-Bold.ufo/glyphs/R_tC_urlyB_rac.glif
new file mode 100644
index 0000000..48383fb
--- /dev/null
+++ b/tests/input/font-psf-test/source/PsfTest-Bold.ufo/glyphs/R_tC_urlyB_rac.glif
@@ -0,0 +1,47 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="RtCurlyBrac" format="2">
+ <advance width="1040"/>
+ <unicode hex="007D"/>
+ <outline>
+ <contour>
+ <point x="180" y="-410" type="line"/>
+ <point x="316" y="-383"/>
+ <point x="520" y="-333"/>
+ <point x="570" y="-285" type="curve" smooth="yes"/>
+ <point x="645" y="-213"/>
+ <point x="633" y="378"/>
+ <point x="655" y="410" type="curve" smooth="yes"/>
+ <point x="685" y="453"/>
+ <point x="855" y="560"/>
+ <point x="855" y="615" type="curve" smooth="yes"/>
+ <point x="855" y="670"/>
+ <point x="685" y="777"/>
+ <point x="655" y="820" type="curve" smooth="yes"/>
+ <point x="633" y="852"/>
+ <point x="644" y="1442"/>
+ <point x="570" y="1515" type="curve" smooth="yes"/>
+ <point x="523" y="1562"/>
+ <point x="333" y="1613"/>
+ <point x="205" y="1640" type="curve"/>
+ <point x="155" y="1409" type="line"/>
+ <point x="218" y="1390"/>
+ <point x="323" y="1351"/>
+ <point x="340" y="1330" type="curve" smooth="yes"/>
+ <point x="375" y="1289"/>
+ <point x="364" y="820"/>
+ <point x="382" y="785" type="curve" smooth="yes"/>
+ <point x="405" y="740"/>
+ <point x="542" y="650"/>
+ <point x="542" y="615" type="curve" smooth="yes"/>
+ <point x="542" y="580"/>
+ <point x="404" y="491"/>
+ <point x="380" y="445" type="curve" smooth="yes"/>
+ <point x="362" y="411"/>
+ <point x="375" y="-60"/>
+ <point x="340" y="-100" type="curve" smooth="yes"/>
+ <point x="321" y="-122"/>
+ <point x="197" y="-160"/>
+ <point x="130" y="-179" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/input/font-psf-test/source/PsfTest-Bold.ufo/glyphs/R_tP_aren.glif b/tests/input/font-psf-test/source/PsfTest-Bold.ufo/glyphs/R_tP_aren.glif
new file mode 100644
index 0000000..ae49fca
--- /dev/null
+++ b/tests/input/font-psf-test/source/PsfTest-Bold.ufo/glyphs/R_tP_aren.glif
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="RtParen" format="2">
+ <advance width="860"/>
+ <unicode hex="0029"/>
+ <outline>
+ <contour>
+ <point x="185" y="1455" type="line"/>
+ <point x="395" y="1261"/>
+ <point x="485" y="938"/>
+ <point x="485" y="635" type="curve" smooth="yes"/>
+ <point x="485" y="335"/>
+ <point x="399" y="11"/>
+ <point x="175" y="-240" type="curve"/>
+ <point x="326" y="-410" type="line"/>
+ <point x="601" y="-125"/>
+ <point x="746" y="218"/>
+ <point x="746" y="625" type="curve" smooth="yes"/>
+ <point x="746" y="1062"/>
+ <point x="571" y="1444"/>
+ <point x="306" y="1640" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/input/font-psf-test/source/PsfTest-Bold.ufo/glyphs/R_tS_qrB_rac.glif b/tests/input/font-psf-test/source/PsfTest-Bold.ufo/glyphs/R_tS_qrB_rac.glif
new file mode 100644
index 0000000..325e575
--- /dev/null
+++ b/tests/input/font-psf-test/source/PsfTest-Bold.ufo/glyphs/R_tS_qrB_rac.glif
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="RtSqrBrac" format="2">
+ <advance width="850"/>
+ <unicode hex="005D"/>
+ <outline>
+ <contour>
+ <point x="660" y="-410" type="line"/>
+ <point x="660" y="1600" type="line"/>
+ <point x="140" y="1600" type="line"/>
+ <point x="140" y="1390" type="line"/>
+ <point x="380" y="1390" type="line"/>
+ <point x="380" y="-200" type="line"/>
+ <point x="140" y="-200" type="line"/>
+ <point x="140" y="-410" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/input/font-psf-test/source/PsfTest-Bold.ufo/glyphs/S_emicolon.glif b/tests/input/font-psf-test/source/PsfTest-Bold.ufo/glyphs/S_emicolon.glif
new file mode 100644
index 0000000..ae95657
--- /dev/null
+++ b/tests/input/font-psf-test/source/PsfTest-Bold.ufo/glyphs/S_emicolon.glif
@@ -0,0 +1,38 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="Semicolon" format="2">
+ <advance width="710"/>
+ <unicode hex="003B"/>
+ <outline>
+ <contour>
+ <point x="200" y="750" type="curve" smooth="yes"/>
+ <point x="200" y="646"/>
+ <point x="274" y="575"/>
+ <point x="375" y="575" type="curve" smooth="yes"/>
+ <point x="477" y="575"/>
+ <point x="550" y="646"/>
+ <point x="550" y="750" type="curve" smooth="yes"/>
+ <point x="550" y="852"/>
+ <point x="477" y="925"/>
+ <point x="375" y="925" type="curve" smooth="yes"/>
+ <point x="274" y="925"/>
+ <point x="200" y="852"/>
+ </contour>
+ <contour>
+ <point x="185" y="50" type="line"/>
+ <point x="345" y="50" type="line"/>
+ <point x="345" y="-34"/>
+ <point x="290" y="-153"/>
+ <point x="185" y="-265" type="curve"/>
+ <point x="330" y="-335" type="line"/>
+ <point x="454" y="-228"/>
+ <point x="560" y="-49"/>
+ <point x="560" y="130" type="curve" smooth="yes"/>
+ <point x="560" y="254"/>
+ <point x="489" y="340"/>
+ <point x="375" y="340" type="curve" smooth="yes"/>
+ <point x="262" y="340"/>
+ <point x="185" y="255"/>
+ <point x="185" y="180" type="curve" smooth="yes"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/input/font-psf-test/source/PsfTest-Bold.ufo/glyphs/S_olidus.glif b/tests/input/font-psf-test/source/PsfTest-Bold.ufo/glyphs/S_olidus.glif
new file mode 100644
index 0000000..1e33c05
--- /dev/null
+++ b/tests/input/font-psf-test/source/PsfTest-Bold.ufo/glyphs/S_olidus.glif
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="Solidus" format="2">
+ <advance width="1080"/>
+ <unicode hex="002F"/>
+ <outline>
+ <contour>
+ <point x="840" y="1600" type="line"/>
+ <point x="10" y="-245" type="line"/>
+ <point x="240" y="-245" type="line"/>
+ <point x="1070" y="1600" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/input/font-psf-test/source/PsfTest-Bold.ufo/glyphs/S_pace.glif b/tests/input/font-psf-test/source/PsfTest-Bold.ufo/glyphs/S_pace.glif
new file mode 100644
index 0000000..ef0bed7
--- /dev/null
+++ b/tests/input/font-psf-test/source/PsfTest-Bold.ufo/glyphs/S_pace.glif
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="Space" format="2">
+ <advance width="550"/>
+ <unicode hex="0020"/>
+ <outline/>
+</glyph>
diff --git a/tests/input/font-psf-test/source/PsfTest-Bold.ufo/glyphs/T_ilde.glif b/tests/input/font-psf-test/source/PsfTest-Bold.ufo/glyphs/T_ilde.glif
new file mode 100644
index 0000000..ec9fc73
--- /dev/null
+++ b/tests/input/font-psf-test/source/PsfTest-Bold.ufo/glyphs/T_ilde.glif
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="Tilde" format="2">
+ <advance width="1115"/>
+ <unicode hex="007E"/>
+ <outline>
+ <contour>
+ <point x="165" y="345" type="line"/>
+ <point x="170" y="394"/>
+ <point x="202" y="435"/>
+ <point x="280" y="435" type="curve" smooth="yes"/>
+ <point x="435" y="435"/>
+ <point x="615" y="330"/>
+ <point x="825" y="330" type="curve" smooth="yes"/>
+ <point x="984" y="330"/>
+ <point x="1080" y="512"/>
+ <point x="1080" y="640" type="curve"/>
+ <point x="935" y="640" type="line"/>
+ <point x="928" y="594"/>
+ <point x="898" y="540"/>
+ <point x="815" y="540" type="curve" smooth="yes"/>
+ <point x="599" y="540"/>
+ <point x="461" y="645"/>
+ <point x="260" y="645" type="curve" smooth="yes"/>
+ <point x="104" y="645"/>
+ <point x="20" y="467"/>
+ <point x="20" y="345" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/input/font-psf-test/source/PsfTest-Bold.ufo/glyphs/V_ertL_ine.glif b/tests/input/font-psf-test/source/PsfTest-Bold.ufo/glyphs/V_ertL_ine.glif
new file mode 100644
index 0000000..d7caa84
--- /dev/null
+++ b/tests/input/font-psf-test/source/PsfTest-Bold.ufo/glyphs/V_ertL_ine.glif
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="VertLine" format="2">
+ <advance width="690"/>
+ <unicode hex="007C"/>
+ <outline>
+ <contour>
+ <point x="240" y="1600" type="line"/>
+ <point x="240" y="-390" type="line"/>
+ <point x="450" y="-390" type="line"/>
+ <point x="450" y="1600" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/input/font-psf-test/source/PsfTest-Bold.ufo/glyphs/_notdef.glif b/tests/input/font-psf-test/source/PsfTest-Bold.ufo/glyphs/_notdef.glif
new file mode 100644
index 0000000..a3e9354
--- /dev/null
+++ b/tests/input/font-psf-test/source/PsfTest-Bold.ufo/glyphs/_notdef.glif
@@ -0,0 +1,18 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name=".notdef" format="2">
+ <advance width="1400"/>
+ <outline>
+ <contour>
+ <point x="100" y="0" type="line"/>
+ <point x="1300" y="0" type="line"/>
+ <point x="1300" y="1800" type="line"/>
+ <point x="100" y="1800" type="line"/>
+ </contour>
+ <contour>
+ <point x="150" y="1750" type="line"/>
+ <point x="1250" y="1750" type="line"/>
+ <point x="1250" y="50" type="line"/>
+ <point x="150" y="50" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/input/font-psf-test/source/PsfTest-Bold.ufo/glyphs/_null.glif b/tests/input/font-psf-test/source/PsfTest-Bold.ufo/glyphs/_null.glif
new file mode 100644
index 0000000..0b9caa6
--- /dev/null
+++ b/tests/input/font-psf-test/source/PsfTest-Bold.ufo/glyphs/_null.glif
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name=".null" format="2">
+ <outline/>
+</glyph>
diff --git a/tests/input/font-psf-test/source/PsfTest-Bold.ufo/glyphs/contents.plist b/tests/input/font-psf-test/source/PsfTest-Bold.ufo/glyphs/contents.plist
new file mode 100644
index 0000000..de3c0b3
--- /dev/null
+++ b/tests/input/font-psf-test/source/PsfTest-Bold.ufo/glyphs/contents.plist
@@ -0,0 +1,234 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+ <key>.notdef</key>
+ <string>_notdef.glif</string>
+ <key>.null</key>
+ <string>_null.glif</string>
+ <key>Ampersand</key>
+ <string>A_mpersand.glif</string>
+ <key>Apos</key>
+ <string>A_pos.glif</string>
+ <key>Asterisk</key>
+ <string>A_sterisk.glif</string>
+ <key>AtSgn</key>
+ <string>A_tS_gn.glif</string>
+ <key>CircumAccent</key>
+ <string>C_ircumA_ccent.glif</string>
+ <key>Colon</key>
+ <string>C_olon.glif</string>
+ <key>CombAcute</key>
+ <string>C_ombA_cute.glif</string>
+ <key>CombCircum</key>
+ <string>C_ombC_ircum.glif</string>
+ <key>CombDiaer</key>
+ <string>C_ombD_iaer.glif</string>
+ <key>CombGrave</key>
+ <string>C_ombG_rave.glif</string>
+ <key>CombRingAbv</key>
+ <string>C_ombR_ingA_bv.glif</string>
+ <key>CombTilde</key>
+ <string>C_ombT_ilde.glif</string>
+ <key>Comma</key>
+ <string>C_omma.glif</string>
+ <key>DigitEight</key>
+ <string>D_igitE_ight.glif</string>
+ <key>DigitFive</key>
+ <string>D_igitF_ive.glif</string>
+ <key>DigitFour</key>
+ <string>D_igitF_our.glif</string>
+ <key>DigitNine</key>
+ <string>D_igitN_ine.glif</string>
+ <key>DigitOne</key>
+ <string>D_igitO_ne.glif</string>
+ <key>DigitSeven</key>
+ <string>D_igitS_even.glif</string>
+ <key>DigitSix</key>
+ <string>D_igitS_ix.glif</string>
+ <key>DigitThree</key>
+ <string>D_igitT_hree.glif</string>
+ <key>DigitTwo</key>
+ <string>D_igitT_wo.glif</string>
+ <key>DigitZero</key>
+ <string>D_igitZ_ero.glif</string>
+ <key>DollarSgn</key>
+ <string>D_ollarS_gn.glif</string>
+ <key>DottedCirc</key>
+ <string>D_ottedC_irc.glif</string>
+ <key>EqSgn</key>
+ <string>E_qS_gn.glif</string>
+ <key>ExclamationMrk</key>
+ <string>E_xclamationM_rk.glif</string>
+ <key>FullStop</key>
+ <string>F_ullS_top.glif</string>
+ <key>GTSgn</key>
+ <string>G_T_S_gn.glif</string>
+ <key>GraveAccent</key>
+ <string>G_raveA_ccent.glif</string>
+ <key>Hyphen</key>
+ <string>H_yphen.glif</string>
+ <key>HyphenMinus</key>
+ <string>H_yphenM_inus.glif</string>
+ <key>Hyphen_Soft</key>
+ <string>H_yphen_S_oft.glif</string>
+ <key>LTSgn</key>
+ <string>L_T_S_gn.glif</string>
+ <key>LftCurlyBrac</key>
+ <string>L_ftC_urlyB_rac.glif</string>
+ <key>LftParen</key>
+ <string>L_ftP_aren.glif</string>
+ <key>LftSqrBrac</key>
+ <string>L_ftS_qrB_rac.glif</string>
+ <key>LowLine</key>
+ <string>L_owL_ine.glif</string>
+ <key>LtnCapA</key>
+ <string>L_tnC_apA_.glif</string>
+ <key>LtnCapA.alt</key>
+ <string>L_tnC_apA_.alt.glif</string>
+ <key>LtnCapADiaer</key>
+ <string>L_tnC_apA_D_iaer.glif</string>
+ <key>LtnCapB</key>
+ <string>L_tnC_apB_.glif</string>
+ <key>LtnCapC</key>
+ <string>L_tnC_apC_.glif</string>
+ <key>LtnCapD</key>
+ <string>L_tnC_apD_.glif</string>
+ <key>LtnCapE</key>
+ <string>L_tnC_apE_.glif</string>
+ <key>LtnCapF</key>
+ <string>L_tnC_apF_.glif</string>
+ <key>LtnCapG</key>
+ <string>L_tnC_apG_.glif</string>
+ <key>LtnCapH</key>
+ <string>L_tnC_apH_.glif</string>
+ <key>LtnCapI</key>
+ <string>L_tnC_apI_.glif</string>
+ <key>LtnCapJ</key>
+ <string>L_tnC_apJ_.glif</string>
+ <key>LtnCapK</key>
+ <string>L_tnC_apK_.glif</string>
+ <key>LtnCapL</key>
+ <string>L_tnC_apL_.glif</string>
+ <key>LtnCapM</key>
+ <string>L_tnC_apM_.glif</string>
+ <key>LtnCapN</key>
+ <string>L_tnC_apN_.glif</string>
+ <key>LtnCapO</key>
+ <string>L_tnC_apO_.glif</string>
+ <key>LtnCapP</key>
+ <string>L_tnC_apP_.glif</string>
+ <key>LtnCapQ</key>
+ <string>L_tnC_apQ_.glif</string>
+ <key>LtnCapR</key>
+ <string>L_tnC_apR_.glif</string>
+ <key>LtnCapS</key>
+ <string>L_tnC_apS_.glif</string>
+ <key>LtnCapT</key>
+ <string>L_tnC_apT_.glif</string>
+ <key>LtnCapU</key>
+ <string>L_tnC_apU_.glif</string>
+ <key>LtnCapV</key>
+ <string>L_tnC_apV_.glif</string>
+ <key>LtnCapW</key>
+ <string>L_tnC_apW_.glif</string>
+ <key>LtnCapX</key>
+ <string>L_tnC_apX_.glif</string>
+ <key>LtnCapY</key>
+ <string>L_tnC_apY_.glif</string>
+ <key>LtnSmA</key>
+ <string>L_tnS_mA_.glif</string>
+ <key>LtnSmAAcute</key>
+ <string>L_tnS_mA_A_cute.glif</string>
+ <key>LtnSmACircum</key>
+ <string>L_tnS_mA_C_ircum.glif</string>
+ <key>LtnSmADiaer</key>
+ <string>L_tnS_mA_D_iaer.glif</string>
+ <key>LtnSmAGrave</key>
+ <string>L_tnS_mA_G_rave.glif</string>
+ <key>LtnSmARingAbv</key>
+ <string>L_tnS_mA_R_ingA_bv.glif</string>
+ <key>LtnSmATilde</key>
+ <string>L_tnS_mA_T_ilde.glif</string>
+ <key>LtnSmB</key>
+ <string>L_tnS_mB_.glif</string>
+ <key>LtnSmC</key>
+ <string>L_tnS_mC_.glif</string>
+ <key>LtnSmD</key>
+ <string>L_tnS_mD_.glif</string>
+ <key>LtnSmE</key>
+ <string>L_tnS_mE_.glif</string>
+ <key>LtnSmF</key>
+ <string>L_tnS_mF_.glif</string>
+ <key>LtnSmG</key>
+ <string>L_tnS_mG_.glif</string>
+ <key>LtnSmH</key>
+ <string>L_tnS_mH_.glif</string>
+ <key>LtnSmI</key>
+ <string>L_tnS_mI_.glif</string>
+ <key>LtnSmJ</key>
+ <string>L_tnS_mJ_.glif</string>
+ <key>LtnSmK</key>
+ <string>L_tnS_mK_.glif</string>
+ <key>LtnSmL</key>
+ <string>L_tnS_mL_.glif</string>
+ <key>LtnSmM</key>
+ <string>L_tnS_mM_.glif</string>
+ <key>LtnSmN</key>
+ <string>L_tnS_mN_.glif</string>
+ <key>LtnSmO</key>
+ <string>L_tnS_mO_.glif</string>
+ <key>LtnSmP</key>
+ <string>L_tnS_mP_.glif</string>
+ <key>LtnSmQ</key>
+ <string>L_tnS_mQ_.glif</string>
+ <key>LtnSmR</key>
+ <string>L_tnS_mR_.glif</string>
+ <key>LtnSmS</key>
+ <string>L_tnS_mS_.glif</string>
+ <key>LtnSmT</key>
+ <string>L_tnS_mT_.glif</string>
+ <key>LtnSmU</key>
+ <string>L_tnS_mU_.glif</string>
+ <key>LtnSmV</key>
+ <string>L_tnS_mV_.glif</string>
+ <key>LtnSmW</key>
+ <string>L_tnS_mW_.glif</string>
+ <key>LtnSmX</key>
+ <string>L_tnS_mX_.glif</string>
+ <key>LtnSmY</key>
+ <string>L_tnS_mY_.glif</string>
+ <key>NonBreakingHyphen</key>
+ <string>N_onB_reakingH_yphen.glif</string>
+ <key>NumSgn</key>
+ <string>N_umS_gn.glif</string>
+ <key>PercentSgn</key>
+ <string>P_ercentS_gn.glif</string>
+ <key>PlusSgn</key>
+ <string>P_lusS_gn.glif</string>
+ <key>QstnMrk</key>
+ <string>Q_stnM_rk.glif</string>
+ <key>QuotMrk</key>
+ <string>Q_uotM_rk.glif</string>
+ <key>ReverseSolidus</key>
+ <string>R_everseS_olidus.glif</string>
+ <key>RtCurlyBrac</key>
+ <string>R_tC_urlyB_rac.glif</string>
+ <key>RtParen</key>
+ <string>R_tP_aren.glif</string>
+ <key>RtSqrBrac</key>
+ <string>R_tS_qrB_rac.glif</string>
+ <key>Semicolon</key>
+ <string>S_emicolon.glif</string>
+ <key>Solidus</key>
+ <string>S_olidus.glif</string>
+ <key>Space</key>
+ <string>S_pace.glif</string>
+ <key>Tilde</key>
+ <string>T_ilde.glif</string>
+ <key>VertLine</key>
+ <string>V_ertL_ine.glif</string>
+ <key>nonmarkingreturn</key>
+ <string>nonmarkingreturn.glif</string>
+</dict>
+</plist>
diff --git a/tests/input/font-psf-test/source/PsfTest-Bold.ufo/glyphs/nonmarkingreturn.glif b/tests/input/font-psf-test/source/PsfTest-Bold.ufo/glyphs/nonmarkingreturn.glif
new file mode 100644
index 0000000..ee41448
--- /dev/null
+++ b/tests/input/font-psf-test/source/PsfTest-Bold.ufo/glyphs/nonmarkingreturn.glif
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="nonmarkingreturn" format="2">
+ <advance width="1024"/>
+ <outline/>
+</glyph>
diff --git a/tests/input/font-psf-test/source/PsfTest-Bold.ufo/layercontents.plist b/tests/input/font-psf-test/source/PsfTest-Bold.ufo/layercontents.plist
new file mode 100644
index 0000000..42b7482
--- /dev/null
+++ b/tests/input/font-psf-test/source/PsfTest-Bold.ufo/layercontents.plist
@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<array>
+ <array>
+ <string>public.default</string>
+ <string>glyphs</string>
+ </array>
+</array>
+</plist>
diff --git a/tests/input/font-psf-test/source/PsfTest-Bold.ufo/lib.plist b/tests/input/font-psf-test/source/PsfTest-Bold.ufo/lib.plist
new file mode 100644
index 0000000..4fe2e05
--- /dev/null
+++ b/tests/input/font-psf-test/source/PsfTest-Bold.ufo/lib.plist
@@ -0,0 +1,535 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+ <key>com.schriftgestaltung.Glyphs.fontUserData</key>
+ <dict/>
+ <key>com.schriftgestaltung.appVersion</key>
+ <string>1161</string>
+ <key>com.schriftgestaltung.customParameter.GSFont.DisplayStrings</key>
+ <string/>
+ <key>com.schriftgestaltung.customParameter.GSFont.disablesAutomaticAlignment</key>
+ <true/>
+ <key>com.schriftgestaltung.customParameter.GSFont.disablesLastChange</key>
+ <true/>
+ <key>com.schriftgestaltung.customParameter.GSFont.useNiceNames</key>
+ <integer>0</integer>
+ <key>com.schriftgestaltung.customParameter.GSFontMaster.customValue</key>
+ <integer>0</integer>
+ <key>com.schriftgestaltung.customParameter.GSFontMaster.customValue1</key>
+ <integer>0</integer>
+ <key>com.schriftgestaltung.customParameter.GSFontMaster.customValue2</key>
+ <integer>0</integer>
+ <key>com.schriftgestaltung.customParameter.GSFontMaster.customValue3</key>
+ <integer>0</integer>
+ <key>com.schriftgestaltung.customParameter.GSFontMaster.iconName</key>
+ <string/>
+ <key>com.schriftgestaltung.customParameter.GSFontMaster.weightValue</key>
+ <integer>700</integer>
+ <key>com.schriftgestaltung.customParameter.GSFontMaster.widthValue</key>
+ <integer>100</integer>
+ <key>com.schriftgestaltung.disablesAutomaticAlignment</key>
+ <true/>
+ <key>com.schriftgestaltung.disablesLastChange</key>
+ <true/>
+ <key>com.schriftgestaltung.fontMasterOrder</key>
+ <integer>1</integer>
+ <key>com.schriftgestaltung.glyphOrder</key>
+ <array>
+ <string>.notdef</string>
+ <string>.null</string>
+ <string>nonmarkingreturn</string>
+ <string>Space</string>
+ <string>ExclamationMrk</string>
+ <string>QuotMrk</string>
+ <string>NumSgn</string>
+ <string>DollarSgn</string>
+ <string>PercentSgn</string>
+ <string>Ampersand</string>
+ <string>Apos</string>
+ <string>LftParen</string>
+ <string>RtParen</string>
+ <string>Asterisk</string>
+ <string>PlusSgn</string>
+ <string>Comma</string>
+ <string>HyphenMinus</string>
+ <string>FullStop</string>
+ <string>Solidus</string>
+ <string>DigitOne</string>
+ <string>DigitTwo</string>
+ <string>DigitThree</string>
+ <string>DigitFour</string>
+ <string>DigitFive</string>
+ <string>DigitSix</string>
+ <string>DigitSeven</string>
+ <string>DigitEight</string>
+ <string>DigitNine</string>
+ <string>Colon</string>
+ <string>Semicolon</string>
+ <string>LTSgn</string>
+ <string>EqSgn</string>
+ <string>GTSgn</string>
+ <string>QstnMrk</string>
+ <string>AtSgn</string>
+ <string>LtnCapA</string>
+ <string>LtnCapA.alt</string>
+ <string>LtnCapB</string>
+ <string>LtnCapC</string>
+ <string>LtnCapD</string>
+ <string>LtnCapE</string>
+ <string>LtnCapF</string>
+ <string>LtnCapG</string>
+ <string>LtnCapH</string>
+ <string>LtnCapI</string>
+ <string>LtnCapJ</string>
+ <string>LtnCapK</string>
+ <string>LtnCapL</string>
+ <string>LtnCapM</string>
+ <string>LtnCapN</string>
+ <string>LtnCapO</string>
+ <string>LtnCapP</string>
+ <string>LtnCapQ</string>
+ <string>LtnCapR</string>
+ <string>LtnCapS</string>
+ <string>LtnCapT</string>
+ <string>LtnCapU</string>
+ <string>LtnCapV</string>
+ <string>LtnCapW</string>
+ <string>LtnCapX</string>
+ <string>LtnCapY</string>
+ <string>LftSqrBrac</string>
+ <string>ReverseSolidus</string>
+ <string>RtSqrBrac</string>
+ <string>CircumAccent</string>
+ <string>LowLine</string>
+ <string>GraveAccent</string>
+ <string>LtnSmA</string>
+ <string>LtnSmB</string>
+ <string>LtnSmC</string>
+ <string>LtnSmD</string>
+ <string>LtnSmE</string>
+ <string>LtnSmF</string>
+ <string>LtnSmG</string>
+ <string>LtnSmH</string>
+ <string>LtnSmI</string>
+ <string>LtnSmJ</string>
+ <string>LtnSmK</string>
+ <string>LtnSmL</string>
+ <string>LtnSmM</string>
+ <string>LtnSmN</string>
+ <string>LtnSmO</string>
+ <string>LtnSmP</string>
+ <string>LtnSmQ</string>
+ <string>LtnSmR</string>
+ <string>LtnSmS</string>
+ <string>LtnSmT</string>
+ <string>LtnSmU</string>
+ <string>LtnSmV</string>
+ <string>LtnSmW</string>
+ <string>LtnSmX</string>
+ <string>LtnSmY</string>
+ <string>LftCurlyBrac</string>
+ <string>VertLine</string>
+ <string>RtCurlyBrac</string>
+ <string>Tilde</string>
+ <string>LtnCapADiaer</string>
+ <string>LtnSmAAcute</string>
+ <string>LtnSmAGrave</string>
+ <string>LtnSmACircum</string>
+ <string>LtnSmADiaer</string>
+ <string>LtnSmATilde</string>
+ <string>LtnSmARingAbv</string>
+ <string>DottedCirc</string>
+ <string>Hyphen</string>
+ <string>NonBreakingHyphen</string>
+ <string>Hyphen_Soft</string>
+ <string>CombAcute</string>
+ <string>CombGrave</string>
+ <string>CombCircum</string>
+ <string>CombTilde</string>
+ <string>CombDiaer</string>
+ <string>CombRingAbv</string>
+ </array>
+ <key>com.schriftgestaltung.keyboardIncrement</key>
+ <integer>1</integer>
+ <key>com.schriftgestaltung.weight</key>
+ <string>Bold</string>
+ <key>com.schriftgestaltung.weightValue</key>
+ <integer>700</integer>
+ <key>com.schriftgestaltung.width</key>
+ <string>Regular</string>
+ <key>com.schriftgestaltung.widthValue</key>
+ <integer>100</integer>
+ <key>org.sil.lcg.toneLetters</key>
+ <dict>
+ <key>contourWidth</key>
+ <integer>540</integer>
+ <key>dotSize</key>
+ <integer>280</integer>
+ <key>dotSpacing</key>
+ <integer>200</integer>
+ <key>glyphDepth</key>
+ <integer>-25</integer>
+ <key>glyphHeight</key>
+ <integer>1600</integer>
+ <key>italicAngle</key>
+ <integer>0</integer>
+ <key>marginDotLeft</key>
+ <integer>100</integer>
+ <key>marginDotRight</key>
+ <integer>140</integer>
+ <key>marginFlatLeft</key>
+ <integer>100</integer>
+ <key>marginFlatRight</key>
+ <integer>140</integer>
+ <key>marginPointLeft</key>
+ <integer>80</integer>
+ <key>marginPointRight</key>
+ <integer>120</integer>
+ <key>strokeThickness</key>
+ <integer>200</integer>
+ </dict>
+ <key>public.glyphOrder</key>
+ <array>
+ <string>.notdef</string>
+ <string>.null</string>
+ <string>nonmarkingreturn</string>
+ <string>Space</string>
+ <string>ExclamationMrk</string>
+ <string>QuotMrk</string>
+ <string>NumSgn</string>
+ <string>DollarSgn</string>
+ <string>PercentSgn</string>
+ <string>Ampersand</string>
+ <string>Apos</string>
+ <string>LftParen</string>
+ <string>RtParen</string>
+ <string>Asterisk</string>
+ <string>PlusSgn</string>
+ <string>Comma</string>
+ <string>HyphenMinus</string>
+ <string>FullStop</string>
+ <string>Solidus</string>
+ <string>DigitZero</string>
+ <string>DigitOne</string>
+ <string>DigitTwo</string>
+ <string>DigitThree</string>
+ <string>DigitFour</string>
+ <string>DigitFive</string>
+ <string>DigitSix</string>
+ <string>DigitSeven</string>
+ <string>DigitEight</string>
+ <string>DigitNine</string>
+ <string>Colon</string>
+ <string>Semicolon</string>
+ <string>LTSgn</string>
+ <string>EqSgn</string>
+ <string>GTSgn</string>
+ <string>QstnMrk</string>
+ <string>AtSgn</string>
+ <string>LtnCapA</string>
+ <string>LtnCapA.alt</string>
+ <string>LtnCapB</string>
+ <string>LtnCapC</string>
+ <string>LtnCapD</string>
+ <string>LtnCapE</string>
+ <string>LtnCapF</string>
+ <string>LtnCapG</string>
+ <string>LtnCapH</string>
+ <string>LtnCapI</string>
+ <string>LtnCapJ</string>
+ <string>LtnCapK</string>
+ <string>LtnCapL</string>
+ <string>LtnCapM</string>
+ <string>LtnCapN</string>
+ <string>LtnCapO</string>
+ <string>LtnCapP</string>
+ <string>LtnCapQ</string>
+ <string>LtnCapR</string>
+ <string>LtnCapS</string>
+ <string>LtnCapT</string>
+ <string>LtnCapU</string>
+ <string>LtnCapV</string>
+ <string>LtnCapW</string>
+ <string>LtnCapX</string>
+ <string>LtnCapY</string>
+ <string>LftSqrBrac</string>
+ <string>ReverseSolidus</string>
+ <string>RtSqrBrac</string>
+ <string>CircumAccent</string>
+ <string>LowLine</string>
+ <string>GraveAccent</string>
+ <string>LtnSmA</string>
+ <string>LtnSmB</string>
+ <string>LtnSmC</string>
+ <string>LtnSmD</string>
+ <string>LtnSmE</string>
+ <string>LtnSmF</string>
+ <string>LtnSmG</string>
+ <string>LtnSmH</string>
+ <string>LtnSmI</string>
+ <string>LtnSmJ</string>
+ <string>LtnSmK</string>
+ <string>LtnSmL</string>
+ <string>LtnSmM</string>
+ <string>LtnSmN</string>
+ <string>LtnSmO</string>
+ <string>LtnSmP</string>
+ <string>LtnSmQ</string>
+ <string>LtnSmR</string>
+ <string>LtnSmS</string>
+ <string>LtnSmT</string>
+ <string>LtnSmU</string>
+ <string>LtnSmV</string>
+ <string>LtnSmW</string>
+ <string>LtnSmX</string>
+ <string>LtnSmY</string>
+ <string>LftCurlyBrac</string>
+ <string>VertLine</string>
+ <string>RtCurlyBrac</string>
+ <string>Tilde</string>
+ <string>LtnCapADiaer</string>
+ <string>LtnSmAAcute</string>
+ <string>LtnSmAGrave</string>
+ <string>LtnSmACircum</string>
+ <string>LtnSmADiaer</string>
+ <string>LtnSmATilde</string>
+ <string>LtnSmARingAbv</string>
+ <string>DottedCirc</string>
+ <string>Hyphen</string>
+ <string>NonBreakingHyphen</string>
+ <string>Hyphen_Soft</string>
+ <string>CombAcute</string>
+ <string>CombGrave</string>
+ <string>CombCircum</string>
+ <string>CombTilde</string>
+ <string>CombDiaer</string>
+ <string>CombRingAbv</string>
+ </array>
+ <key>public.postscriptNames</key>
+ <dict>
+ <key>Ampersand</key>
+ <string>ampersand</string>
+ <key>Apos</key>
+ <string>quotesingle</string>
+ <key>Asterisk</key>
+ <string>asterisk</string>
+ <key>AtSgn</key>
+ <string>at</string>
+ <key>CircumAccent</key>
+ <string>asciicircum</string>
+ <key>Colon</key>
+ <string>colon</string>
+ <key>CombAcute</key>
+ <string>acutecomb</string>
+ <key>CombCircum</key>
+ <string>uni0302</string>
+ <key>CombDiaer</key>
+ <string>uni0308</string>
+ <key>CombGrave</key>
+ <string>gravecomb</string>
+ <key>CombRingAbv</key>
+ <string>uni030A</string>
+ <key>CombTilde</key>
+ <string>tildecomb</string>
+ <key>Comma</key>
+ <string>comma</string>
+ <key>DigitEight</key>
+ <string>eight</string>
+ <key>DigitFive</key>
+ <string>five</string>
+ <key>DigitFour</key>
+ <string>four</string>
+ <key>DigitNine</key>
+ <string>nine</string>
+ <key>DigitOne</key>
+ <string>one</string>
+ <key>DigitSeven</key>
+ <string>seven</string>
+ <key>DigitSix</key>
+ <string>six</string>
+ <key>DigitThree</key>
+ <string>three</string>
+ <key>DigitTwo</key>
+ <string>two</string>
+ <key>DigitZero</key>
+ <string>zero</string>
+ <key>DollarSgn</key>
+ <string>dollar</string>
+ <key>DottedCirc</key>
+ <string>uni25CC</string>
+ <key>EqSgn</key>
+ <string>equal</string>
+ <key>ExclamationMrk</key>
+ <string>exclam</string>
+ <key>FullStop</key>
+ <string>period</string>
+ <key>GTSgn</key>
+ <string>greater</string>
+ <key>GraveAccent</key>
+ <string>grave</string>
+ <key>Hyphen</key>
+ <string>uni2010</string>
+ <key>HyphenMinus</key>
+ <string>hyphen</string>
+ <key>Hyphen_Soft</key>
+ <string>uni00AD</string>
+ <key>LTSgn</key>
+ <string>less</string>
+ <key>LftCurlyBrac</key>
+ <string>braceleft</string>
+ <key>LftParen</key>
+ <string>parenleft</string>
+ <key>LftSqrBrac</key>
+ <string>bracketleft</string>
+ <key>LowLine</key>
+ <string>underscore</string>
+ <key>LtnCapA</key>
+ <string>A</string>
+ <key>LtnCapA.alt</key>
+ <string>A</string>
+ <key>LtnCapADiaer</key>
+ <string>Adieresis</string>
+ <key>LtnCapB</key>
+ <string>B</string>
+ <key>LtnCapC</key>
+ <string>C</string>
+ <key>LtnCapD</key>
+ <string>D</string>
+ <key>LtnCapE</key>
+ <string>E</string>
+ <key>LtnCapF</key>
+ <string>F</string>
+ <key>LtnCapG</key>
+ <string>G</string>
+ <key>LtnCapH</key>
+ <string>H</string>
+ <key>LtnCapI</key>
+ <string>I</string>
+ <key>LtnCapJ</key>
+ <string>J</string>
+ <key>LtnCapK</key>
+ <string>K</string>
+ <key>LtnCapL</key>
+ <string>L</string>
+ <key>LtnCapM</key>
+ <string>M</string>
+ <key>LtnCapN</key>
+ <string>N</string>
+ <key>LtnCapO</key>
+ <string>O</string>
+ <key>LtnCapP</key>
+ <string>P</string>
+ <key>LtnCapQ</key>
+ <string>Q</string>
+ <key>LtnCapR</key>
+ <string>R</string>
+ <key>LtnCapS</key>
+ <string>S</string>
+ <key>LtnCapT</key>
+ <string>T</string>
+ <key>LtnCapU</key>
+ <string>U</string>
+ <key>LtnCapV</key>
+ <string>V</string>
+ <key>LtnCapW</key>
+ <string>W</string>
+ <key>LtnCapX</key>
+ <string>X</string>
+ <key>LtnCapY</key>
+ <string>Y</string>
+ <key>LtnSmA</key>
+ <string>a</string>
+ <key>LtnSmAAcute</key>
+ <string>aacute</string>
+ <key>LtnSmACircum</key>
+ <string>acircumflex</string>
+ <key>LtnSmADiaer</key>
+ <string>adieresis</string>
+ <key>LtnSmAGrave</key>
+ <string>agrave</string>
+ <key>LtnSmARingAbv</key>
+ <string>aring</string>
+ <key>LtnSmATilde</key>
+ <string>atilde</string>
+ <key>LtnSmB</key>
+ <string>b</string>
+ <key>LtnSmC</key>
+ <string>c</string>
+ <key>LtnSmD</key>
+ <string>d</string>
+ <key>LtnSmE</key>
+ <string>e</string>
+ <key>LtnSmF</key>
+ <string>f</string>
+ <key>LtnSmG</key>
+ <string>g</string>
+ <key>LtnSmH</key>
+ <string>h</string>
+ <key>LtnSmI</key>
+ <string>i</string>
+ <key>LtnSmJ</key>
+ <string>j</string>
+ <key>LtnSmK</key>
+ <string>k</string>
+ <key>LtnSmL</key>
+ <string>l</string>
+ <key>LtnSmM</key>
+ <string>m</string>
+ <key>LtnSmN</key>
+ <string>n</string>
+ <key>LtnSmO</key>
+ <string>o</string>
+ <key>LtnSmP</key>
+ <string>p</string>
+ <key>LtnSmQ</key>
+ <string>q</string>
+ <key>LtnSmR</key>
+ <string>r</string>
+ <key>LtnSmS</key>
+ <string>s</string>
+ <key>LtnSmT</key>
+ <string>t</string>
+ <key>LtnSmU</key>
+ <string>u</string>
+ <key>LtnSmV</key>
+ <string>v</string>
+ <key>LtnSmW</key>
+ <string>w</string>
+ <key>LtnSmX</key>
+ <string>x</string>
+ <key>LtnSmY</key>
+ <string>y</string>
+ <key>NonBreakingHyphen</key>
+ <string>uni2011</string>
+ <key>NumSgn</key>
+ <string>numbersign</string>
+ <key>PercentSgn</key>
+ <string>percent</string>
+ <key>PlusSgn</key>
+ <string>plus</string>
+ <key>QstnMrk</key>
+ <string>question</string>
+ <key>QuotMrk</key>
+ <string>quotedbl</string>
+ <key>ReverseSolidus</key>
+ <string>backslash</string>
+ <key>RtCurlyBrac</key>
+ <string>braceright</string>
+ <key>RtParen</key>
+ <string>parenright</string>
+ <key>RtSqrBrac</key>
+ <string>bracketright</string>
+ <key>Semicolon</key>
+ <string>semicolon</string>
+ <key>Solidus</key>
+ <string>slash</string>
+ <key>Space</key>
+ <string>space</string>
+ <key>Tilde</key>
+ <string>asciitilde</string>
+ <key>VertLine</key>
+ <string>bar</string>
+ </dict>
+</dict>
+</plist>
diff --git a/tests/input/font-psf-test/source/PsfTest-Bold.ufo/metainfo.plist b/tests/input/font-psf-test/source/PsfTest-Bold.ufo/metainfo.plist
new file mode 100644
index 0000000..aa10c5c
--- /dev/null
+++ b/tests/input/font-psf-test/source/PsfTest-Bold.ufo/metainfo.plist
@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+ <key>creator</key>
+ <string>org.sil.scripts.pysilfont</string>
+ <key>formatVersion</key>
+ <integer>3</integer>
+</dict>
+</plist>
diff --git a/tests/input/font-psf-test/source/PsfTest-BoldItalic.ufo/fontinfo.plist b/tests/input/font-psf-test/source/PsfTest-BoldItalic.ufo/fontinfo.plist
new file mode 100644
index 0000000..3f3c5f4
--- /dev/null
+++ b/tests/input/font-psf-test/source/PsfTest-BoldItalic.ufo/fontinfo.plist
@@ -0,0 +1,245 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+ <key>ascender</key>
+ <integer>2100</integer>
+ <key>capHeight</key>
+ <integer>1485</integer>
+ <key>copyright</key>
+ <string>Copyright (c) 2004-2021 SIL International</string>
+ <key>descender</key>
+ <integer>-550</integer>
+ <key>familyName</key>
+ <string>Psf Test</string>
+ <key>italicAngle</key>
+ <integer>-14</integer>
+ <key>macintoshFONDName</key>
+ <string>My Test</string>
+ <key>openTypeHeadCreated</key>
+ <string>2021/01/01 11:00:00</string>
+ <key>openTypeHheaAscender</key>
+ <integer>2200</integer>
+ <key>openTypeHheaDescender</key>
+ <integer>-550</integer>
+ <key>openTypeHheaLineGap</key>
+ <integer>0</integer>
+ <key>openTypeNameDescription</key>
+ <string>Copyright (c) 2004-2021 SIL International</string>
+ <key>openTypeNameDesigner</key>
+ <string>Victor Gaultney, Annie Olsen, Julie Remington, Don Collingsworth, Eric Hays, Becca Hirsbrunner</string>
+ <key>openTypeNameDesignerURL</key>
+ <string>http://scripts.sil.org/</string>
+ <key>openTypeNameLicense</key>
+ <string>Copyright (c) 2004-2021 SIL International (http://www.sil.org/) with Reserved Font Names "Andika" and "SIL".
+
+This Font Software is licensed under the SIL Open Font License, Version 1.1. This license is copied below, and is also available with a FAQ at: http://scripts.sil.org/OFL
+
+
+-----------------------------------------------------------
+SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007
+-----------------------------------------------------------
+
+PREAMBLE
+The goals of the Open Font License (OFL) are to stimulate worldwide development of collaborative font projects, to support the font creation efforts of academic and linguistic communities, and to provide a free and open framework in which fonts may be shared and improved in partnership with others.
+
+The OFL allows the licensed fonts to be used, studied, modified and redistributed freely as long as they are not sold by themselves. The fonts, including any derivative works, can be bundled, embedded, redistributed and/or sold with any software provided that any reserved names are not used by derivative works. The fonts and derivatives, however, cannot be released under any other type of license. The requirement for fonts to remain under this license does not apply to any document created using the fonts or their derivatives.
+
+DEFINITIONS
+"Font Software" refers to the set of files released by the Copyright Holder(s) under this license and clearly marked as such. This may include source files, build scripts and documentation.
+
+"Reserved Font Name" refers to any names specified as such after the copyright statement(s).
+
+"Original Version" refers to the collection of Font Software components as distributed by the Copyright Holder(s).
+
+"Modified Version" refers to any derivative made by adding to, deleting, or substituting -- in part or in whole -- any of the components of the Original Version, by changing formats or by porting the Font Software to a new environment.
+
+"Author" refers to any designer, engineer, programmer, technical writer or other person who contributed to the Font Software.
+
+PERMISSION &amp; CONDITIONS
+Permission is hereby granted, free of charge, to any person obtaining a copy of the Font Software, to use, study, copy, merge, embed, modify, redistribute, and sell modified and unmodified copies of the Font Software, subject to the following conditions:
+
+1) Neither the Font Software nor any of its individual components, in Original or Modified Versions, may be sold by itself.
+
+2) Original or Modified Versions of the Font Software may be bundled, redistributed and/or sold with any software, provided that each copy contains the above copyright notice and this license. These can be included either as stand-alone text files, human-readable headers or in the appropriate machine-readable metadata fields within text or binary files as long as those fields can be easily viewed by the user.
+
+3) No Modified Version of the Font Software may use the Reserved Font Name(s) unless explicit written permission is granted by the corresponding Copyright Holder. This restriction only applies to the primary font name as presented to the users.
+
+4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font Software shall not be used to promote, endorse or advertise any Modified Version, except to acknowledge the contribution(s) of the Copyright Holder(s) and the Author(s) or with their explicit written permission.
+
+5) The Font Software, modified or unmodified, in part or in whole, must be distributed entirely under this license, and must not be distributed under any other license. The requirement for fonts to remain under this license does not apply to any document created using the Font Software.
+
+TERMINATION
+This license becomes null and void if any of the above conditions are not met.
+
+DISCLAIMER
+THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM OTHER DEALINGS IN THE FONT SOFTWARE.</string>
+ <key>openTypeNameLicenseURL</key>
+ <string>http://scripts.sil.org/OFL</string>
+ <key>openTypeNameManufacturer</key>
+ <string>SIL International</string>
+ <key>openTypeNameManufacturerURL</key>
+ <string>http://scripts.sil.org</string>
+ <key>openTypeNamePreferredFamilyName</key>
+ <string>Psf Test</string>
+ <key>openTypeNamePreferredSubfamilyName</key>
+ <string>Bold Italic</string>
+ <key>openTypeNameUniqueID</key>
+ <string>SIL International: Psf Test Bold Italic: 2022</string>
+ <key>openTypeNameVersion</key>
+ <string>Version 5.550</string>
+ <key>openTypeOS2CodePageRanges</key>
+ <array>
+ <integer>0</integer>
+ <integer>1</integer>
+ <integer>2</integer>
+ <integer>4</integer>
+ <integer>7</integer>
+ <integer>8</integer>
+ </array>
+ <key>openTypeOS2FamilyClass</key>
+ <array>
+ <integer>0</integer>
+ <integer>0</integer>
+ </array>
+ <key>openTypeOS2Panose</key>
+ <array>
+ <integer>2</integer>
+ <integer>0</integer>
+ <integer>0</integer>
+ <integer>0</integer>
+ <integer>0</integer>
+ <integer>0</integer>
+ <integer>0</integer>
+ <integer>0</integer>
+ <integer>0</integer>
+ <integer>0</integer>
+ </array>
+ <key>openTypeOS2StrikeoutPosition</key>
+ <integer>700</integer>
+ <key>openTypeOS2StrikeoutSize</key>
+ <integer>100</integer>
+ <key>openTypeOS2SubscriptXOffset</key>
+ <integer>0</integer>
+ <key>openTypeOS2SubscriptXSize</key>
+ <integer>1433</integer>
+ <key>openTypeOS2SubscriptYOffset</key>
+ <integer>286</integer>
+ <key>openTypeOS2SubscriptYSize</key>
+ <integer>1331</integer>
+ <key>openTypeOS2SuperscriptXOffset</key>
+ <integer>0</integer>
+ <key>openTypeOS2SuperscriptXSize</key>
+ <integer>1433</integer>
+ <key>openTypeOS2SuperscriptYOffset</key>
+ <integer>976</integer>
+ <key>openTypeOS2SuperscriptYSize</key>
+ <integer>1331</integer>
+ <key>openTypeOS2Type</key>
+ <array/>
+ <key>openTypeOS2TypoAscender</key>
+ <integer>2100</integer>
+ <key>openTypeOS2TypoDescender</key>
+ <integer>-550</integer>
+ <key>openTypeOS2TypoLineGap</key>
+ <integer>0</integer>
+ <key>openTypeOS2UnicodeRanges</key>
+ <array>
+ <integer>0</integer>
+ <integer>1</integer>
+ <integer>6</integer>
+ <integer>7</integer>
+ <integer>31</integer>
+ <integer>33</integer>
+ <integer>35</integer>
+ <integer>36</integer>
+ <integer>37</integer>
+ <integer>38</integer>
+ <integer>39</integer>
+ <integer>40</integer>
+ <integer>45</integer>
+ <integer>46</integer>
+ <integer>47</integer>
+ <integer>57</integer>
+ <integer>60</integer>
+ <integer>62</integer>
+ <integer>64</integer>
+ <integer>67</integer>
+ <integer>69</integer>
+ <integer>89</integer>
+ </array>
+ <key>openTypeOS2VendorID</key>
+ <string>SIL</string>
+ <key>openTypeOS2WeightClass</key>
+ <integer>700</integer>
+ <key>openTypeOS2WidthClass</key>
+ <integer>5</integer>
+ <key>openTypeOS2WinAscent</key>
+ <integer>2100</integer>
+ <key>openTypeOS2WinDescent</key>
+ <integer>550</integer>
+ <key>postscriptBlueValues</key>
+ <array>
+ <integer>-490</integer>
+ <integer>-490</integer>
+ <integer>-25</integer>
+ <integer>0</integer>
+ <integer>1020</integer>
+ <integer>1040</integer>
+ <integer>1455</integer>
+ <integer>1485</integer>
+ <integer>1600</integer>
+ <integer>1620</integer>
+ </array>
+ <key>postscriptFamilyBlues</key>
+ <array/>
+ <key>postscriptFontName</key>
+ <string>PsfTest-BoldItalic</string>
+ <key>postscriptFullName</key>
+ <string>Psf Test Bold Italic</string>
+ <key>postscriptStemSnapH</key>
+ <array>
+ <integer>140</integer>
+ <integer>145</integer>
+ <integer>150</integer>
+ <integer>155</integer>
+ <integer>160</integer>
+ <integer>165</integer>
+ <integer>170</integer>
+ <integer>175</integer>
+ <integer>185</integer>
+ <integer>270</integer>
+ </array>
+ <key>postscriptStemSnapV</key>
+ <array>
+ <integer>165</integer>
+ <integer>180</integer>
+ <integer>185</integer>
+ <integer>190</integer>
+ <integer>195</integer>
+ <integer>200</integer>
+ <integer>205</integer>
+ <integer>270</integer>
+ </array>
+ <key>postscriptUnderlinePosition</key>
+ <integer>-110</integer>
+ <key>postscriptUnderlineThickness</key>
+ <integer>80</integer>
+ <key>styleMapFamilyName</key>
+ <string>Psf Test</string>
+ <key>styleMapStyleName</key>
+ <string>bold italic</string>
+ <key>styleName</key>
+ <string>Bold Italic</string>
+ <key>trademark</key>
+ <string>Andika is a trademark of SIL International.</string>
+ <key>unitsPerEm</key>
+ <integer>2048</integer>
+ <key>versionMajor</key>
+ <integer>5</integer>
+ <key>versionMinor</key>
+ <integer>550</integer>
+ <key>xHeight</key>
+ <integer>1040</integer>
+</dict>
+</plist>
diff --git a/tests/input/font-psf-test/source/PsfTest-BoldItalic.ufo/glyphs/A_mpersand.glif b/tests/input/font-psf-test/source/PsfTest-BoldItalic.ufo/glyphs/A_mpersand.glif
new file mode 100644
index 0000000..f3fb1c7
--- /dev/null
+++ b/tests/input/font-psf-test/source/PsfTest-BoldItalic.ufo/glyphs/A_mpersand.glif
@@ -0,0 +1,61 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="Ampersand" format="2">
+ <advance width="1333"/>
+ <unicode hex="0026"/>
+ <outline>
+ <contour>
+ <point x="1146" y="594" type="line"/>
+ <point x="1040" y="429"/>
+ <point x="712" y="198"/>
+ <point x="537" y="198" type="curve" smooth="yes"/>
+ <point x="437" y="198"/>
+ <point x="363" y="257"/>
+ <point x="363" y="345" type="curve" smooth="yes"/>
+ <point x="363" y="490"/>
+ <point x="474" y="535"/>
+ <point x="695" y="693" type="curve" smooth="yes"/>
+ <point x="940" y="868"/>
+ <point x="1160" y="1032"/>
+ <point x="1160" y="1213" type="curve" smooth="yes"/>
+ <point x="1160" y="1361"/>
+ <point x="1026" y="1470"/>
+ <point x="849" y="1470" type="curve" smooth="yes"/>
+ <point x="637" y="1470"/>
+ <point x="414" y="1364"/>
+ <point x="414" y="1124" type="curve" smooth="yes"/>
+ <point x="414" y="968"/>
+ <point x="552" y="751"/>
+ <point x="661" y="535" type="curve" smooth="yes"/>
+ <point x="842" y="177"/>
+ <point x="969" y="-25"/>
+ <point x="1021" y="-25" type="curve" smooth="yes"/>
+ <point x="1056" y="-25"/>
+ <point x="1205" y="57"/>
+ <point x="1250" y="89" type="curve"/>
+ <point x="1165" y="129"/>
+ <point x="1073" y="302"/>
+ <point x="890" y="673" type="curve" smooth="yes"/>
+ <point x="788" y="881"/>
+ <point x="651" y="1063"/>
+ <point x="651" y="1163" type="curve" smooth="yes"/>
+ <point x="651" y="1245"/>
+ <point x="729" y="1307"/>
+ <point x="803" y="1307" type="curve" smooth="yes"/>
+ <point x="873" y="1307"/>
+ <point x="926" y="1250"/>
+ <point x="926" y="1184" type="curve" smooth="yes"/>
+ <point x="926" y="1081"/>
+ <point x="821" y="997"/>
+ <point x="600" y="832" type="curve" smooth="yes"/>
+ <point x="392" y="677"/>
+ <point x="108" y="540"/>
+ <point x="108" y="268" type="curve" smooth="yes"/>
+ <point x="108" y="98"/>
+ <point x="229" y="-25"/>
+ <point x="466" y="-25" type="curve" smooth="yes"/>
+ <point x="749" y="-25"/>
+ <point x="1120" y="261"/>
+ <point x="1237" y="421" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/input/font-psf-test/source/PsfTest-BoldItalic.ufo/glyphs/A_pos.glif b/tests/input/font-psf-test/source/PsfTest-BoldItalic.ufo/glyphs/A_pos.glif
new file mode 100644
index 0000000..68b000e
--- /dev/null
+++ b/tests/input/font-psf-test/source/PsfTest-BoldItalic.ufo/glyphs/A_pos.glif
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="Apos" format="2">
+ <advance width="605"/>
+ <unicode hex="0027"/>
+ <outline>
+ <contour>
+ <point x="598" y="1035" type="line"/>
+ <point x="637" y="1174"/>
+ <point x="676" y="1326"/>
+ <point x="766" y="1569" type="curve"/>
+ <point x="521" y="1569" type="line"/>
+ <point x="491" y="1326"/>
+ <point x="453" y="1174"/>
+ <point x="423" y="1035" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/input/font-psf-test/source/PsfTest-BoldItalic.ufo/glyphs/A_sterisk.glif b/tests/input/font-psf-test/source/PsfTest-BoldItalic.ufo/glyphs/A_sterisk.glif
new file mode 100644
index 0000000..a36131c
--- /dev/null
+++ b/tests/input/font-psf-test/source/PsfTest-BoldItalic.ufo/glyphs/A_sterisk.glif
@@ -0,0 +1,51 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="Asterisk" format="2">
+ <advance width="1020"/>
+ <unicode hex="002A"/>
+ <outline>
+ <contour>
+ <point x="1135" y="1478" type="line"/>
+ <point x="1039" y="1412"/>
+ <point x="956" y="1353"/>
+ <point x="856" y="1295" type="curve"/>
+ <point x="885" y="1391"/>
+ <point x="915" y="1471"/>
+ <point x="958" y="1584" type="curve"/>
+ <point x="759" y="1584" type="line"/>
+ <point x="753" y="1482"/>
+ <point x="748" y="1398"/>
+ <point x="730" y="1295" type="curve"/>
+ <point x="658" y="1346"/>
+ <point x="599" y="1394"/>
+ <point x="532" y="1461" type="curve"/>
+ <point x="388" y="1293" type="line"/>
+ <point x="484" y="1258"/>
+ <point x="575" y="1222"/>
+ <point x="647" y="1184" type="curve"/>
+ <point x="552" y="1141"/>
+ <point x="459" y="1109"/>
+ <point x="341" y="1066" type="curve"/>
+ <point x="398" y="888" type="line"/>
+ <point x="494" y="958"/>
+ <point x="575" y="1016"/>
+ <point x="674" y="1076" type="curve"/>
+ <point x="641" y="973"/>
+ <point x="610" y="887"/>
+ <point x="566" y="785" type="curve"/>
+ <point x="767" y="785" type="line"/>
+ <point x="773" y="897"/>
+ <point x="785" y="977"/>
+ <point x="800" y="1073" type="curve"/>
+ <point x="875" y="1017"/>
+ <point x="929" y="971"/>
+ <point x="995" y="905" type="curve"/>
+ <point x="1144" y="1078" type="line"/>
+ <point x="1045" y="1116"/>
+ <point x="967" y="1143"/>
+ <point x="886" y="1184" type="curve"/>
+ <point x="984" y="1229"/>
+ <point x="1075" y="1264"/>
+ <point x="1190" y="1308" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/input/font-psf-test/source/PsfTest-BoldItalic.ufo/glyphs/A_tS_gn.glif b/tests/input/font-psf-test/source/PsfTest-BoldItalic.ufo/glyphs/A_tS_gn.glif
new file mode 100644
index 0000000..e2233cf
--- /dev/null
+++ b/tests/input/font-psf-test/source/PsfTest-BoldItalic.ufo/glyphs/A_tS_gn.glif
@@ -0,0 +1,104 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="AtSgn" format="2">
+ <advance width="1693"/>
+ <unicode hex="0040"/>
+ <outline>
+ <contour>
+ <point x="1082" y="10" type="line"/>
+ <point x="1008" y="-34"/>
+ <point x="933" y="-59"/>
+ <point x="840" y="-59" type="curve" smooth="yes"/>
+ <point x="540" y="-59"/>
+ <point x="362" y="143"/>
+ <point x="362" y="434" type="curve" smooth="yes"/>
+ <point x="362" y="498"/>
+ <point x="371" y="567"/>
+ <point x="389" y="639" type="curve" smooth="yes"/>
+ <point x="480" y="1003"/>
+ <point x="783" y="1228"/>
+ <point x="1121" y="1228" type="curve" smooth="yes"/>
+ <point x="1424" y="1228"/>
+ <point x="1581" y="1069"/>
+ <point x="1581" y="813" type="curve" smooth="yes"/>
+ <point x="1581" y="753"/>
+ <point x="1572" y="688"/>
+ <point x="1555" y="619" type="curve" smooth="yes"/>
+ <point x="1506" y="418"/>
+ <point x="1400" y="331"/>
+ <point x="1340" y="331" type="curve" smooth="yes"/>
+ <point x="1307" y="331"/>
+ <point x="1287" y="362"/>
+ <point x="1287" y="432" type="curve" smooth="yes"/>
+ <point x="1287" y="482"/>
+ <point x="1297" y="551"/>
+ <point x="1320" y="643" type="curve" smooth="yes"/>
+ <point x="1401" y="970" type="line"/>
+ <point x="1323" y="1005"/>
+ <point x="1182" y="1030"/>
+ <point x="1101" y="1030" type="curve" smooth="yes"/>
+ <point x="937" y="1030"/>
+ <point x="822" y="974"/>
+ <point x="710" y="862" type="curve" smooth="yes"/>
+ <point x="637" y="789"/>
+ <point x="569" y="677"/>
+ <point x="539" y="556" type="curve" smooth="yes"/>
+ <point x="529" y="518"/>
+ <point x="525" y="481"/>
+ <point x="525" y="447" type="curve" smooth="yes"/>
+ <point x="525" y="279"/>
+ <point x="629" y="161"/>
+ <point x="740" y="161" type="curve" smooth="yes"/>
+ <point x="867" y="161"/>
+ <point x="1034" y="328"/>
+ <point x="1117" y="450" type="curve"/>
+ <point x="1112" y="422"/>
+ <point x="1110" y="394"/>
+ <point x="1110" y="367" type="curve" smooth="yes"/>
+ <point x="1110" y="252"/>
+ <point x="1157" y="155"/>
+ <point x="1291" y="155" type="curve" smooth="yes"/>
+ <point x="1454" y="155"/>
+ <point x="1674" y="332"/>
+ <point x="1752" y="646" type="curve" smooth="yes"/>
+ <point x="1768" y="710"/>
+ <point x="1775" y="771"/>
+ <point x="1775" y="829" type="curve" smooth="yes"/>
+ <point x="1775" y="1169"/>
+ <point x="1520" y="1411"/>
+ <point x="1156" y="1411" type="curve" smooth="yes"/>
+ <point x="731" y="1411"/>
+ <point x="322" y="1180"/>
+ <point x="183" y="624" type="curve" smooth="yes"/>
+ <point x="163" y="544"/>
+ <point x="154" y="469"/>
+ <point x="154" y="398" type="curve" smooth="yes"/>
+ <point x="154" y="-1"/>
+ <point x="448" y="-243"/>
+ <point x="789" y="-243" type="curve" smooth="yes"/>
+ <point x="924" y="-243"/>
+ <point x="1076" y="-206"/>
+ <point x="1193" y="-137" type="curve"/>
+ </contour>
+ <contour>
+ <point x="1135" y="703" type="line"/>
+ <point x="1069" y="566"/>
+ <point x="899" y="346"/>
+ <point x="809" y="346" type="curve" smooth="yes"/>
+ <point x="757" y="346"/>
+ <point x="726" y="386"/>
+ <point x="726" y="463" type="curve" smooth="yes"/>
+ <point x="726" y="493"/>
+ <point x="731" y="528"/>
+ <point x="741" y="569" type="curve" smooth="yes"/>
+ <point x="760" y="645"/>
+ <point x="803" y="731"/>
+ <point x="853" y="778" type="curve" smooth="yes"/>
+ <point x="901" y="824"/>
+ <point x="957" y="846"/>
+ <point x="1025" y="846" type="curve" smooth="yes"/>
+ <point x="1099" y="846"/>
+ <point x="1133" y="828"/>
+ <point x="1162" y="812" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/input/font-psf-test/source/PsfTest-BoldItalic.ufo/glyphs/C_ircumA_ccent.glif b/tests/input/font-psf-test/source/PsfTest-BoldItalic.ufo/glyphs/C_ircumA_ccent.glif
new file mode 100644
index 0000000..b60b998
--- /dev/null
+++ b/tests/input/font-psf-test/source/PsfTest-BoldItalic.ufo/glyphs/C_ircumA_ccent.glif
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="CircumAccent" format="2">
+ <advance width="860"/>
+ <unicode hex="005E"/>
+ <anchor x="788" y="1635" name="U"/>
+ <outline>
+ <contour>
+ <point x="1056" y="1188" type="line"/>
+ <point x="845" y="1584" type="line"/>
+ <point x="545" y="1584" type="line"/>
+ <point x="177" y="1188" type="line"/>
+ <point x="417" y="1188" type="line"/>
+ <point x="674" y="1416" type="line"/>
+ <point x="817" y="1188" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/input/font-psf-test/source/PsfTest-BoldItalic.ufo/glyphs/C_olon.glif b/tests/input/font-psf-test/source/PsfTest-BoldItalic.ufo/glyphs/C_olon.glif
new file mode 100644
index 0000000..37f30d8
--- /dev/null
+++ b/tests/input/font-psf-test/source/PsfTest-BoldItalic.ufo/glyphs/C_olon.glif
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="Colon" format="2">
+ <advance width="690"/>
+ <unicode hex="003A"/>
+ <outline>
+ <contour>
+ <point x="171" y="116" type="curve" smooth="yes"/>
+ <point x="171" y="35"/>
+ <point x="232" y="-25"/>
+ <point x="318" y="-25" type="curve" smooth="yes"/>
+ <point x="436" y="-25"/>
+ <point x="531" y="71"/>
+ <point x="531" y="181" type="curve" smooth="yes"/>
+ <point x="531" y="261"/>
+ <point x="472" y="322"/>
+ <point x="385" y="322" type="curve" smooth="yes"/>
+ <point x="268" y="322"/>
+ <point x="171" y="226"/>
+ </contour>
+ <contour>
+ <point x="319" y="710" type="curve" smooth="yes"/>
+ <point x="319" y="629"/>
+ <point x="380" y="569"/>
+ <point x="466" y="569" type="curve" smooth="yes"/>
+ <point x="584" y="569"/>
+ <point x="679" y="665"/>
+ <point x="679" y="775" type="curve" smooth="yes"/>
+ <point x="679" y="855"/>
+ <point x="620" y="916"/>
+ <point x="533" y="916" type="curve" smooth="yes"/>
+ <point x="416" y="916"/>
+ <point x="319" y="820"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/input/font-psf-test/source/PsfTest-BoldItalic.ufo/glyphs/C_ombA_cute.glif b/tests/input/font-psf-test/source/PsfTest-BoldItalic.ufo/glyphs/C_ombA_cute.glif
new file mode 100644
index 0000000..f3ea065
--- /dev/null
+++ b/tests/input/font-psf-test/source/PsfTest-BoldItalic.ufo/glyphs/C_ombA_cute.glif
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="CombAcute" format="2">
+ <unicode hex="0301"/>
+ <anchor x="-251" y="1635" name="U"/>
+ <anchor x="-325" y="1100" name="_U"/>
+ <outline>
+ <contour>
+ <point x="-165" y="1584" type="line"/>
+ <point x="-523" y="1188" type="line"/>
+ <point x="-283" y="1188" type="line"/>
+ <point x="204" y="1584" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/input/font-psf-test/source/PsfTest-BoldItalic.ufo/glyphs/C_ombC_ircum.glif b/tests/input/font-psf-test/source/PsfTest-BoldItalic.ufo/glyphs/C_ombC_ircum.glif
new file mode 100644
index 0000000..9dc18ac
--- /dev/null
+++ b/tests/input/font-psf-test/source/PsfTest-BoldItalic.ufo/glyphs/C_ombC_ircum.glif
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="CombCircum" format="2">
+ <unicode hex="0302"/>
+ <anchor x="-239" y="1635" name="U"/>
+ <anchor x="-330" y="1100" name="_U"/>
+ <outline>
+ <contour>
+ <point x="88" y="1188" type="line"/>
+ <point x="-123" y="1584" type="line"/>
+ <point x="-423" y="1584" type="line"/>
+ <point x="-791" y="1188" type="line"/>
+ <point x="-551" y="1188" type="line"/>
+ <point x="-294" y="1416" type="line"/>
+ <point x="-151" y="1188" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/input/font-psf-test/source/PsfTest-BoldItalic.ufo/glyphs/C_ombD_iaer.glif b/tests/input/font-psf-test/source/PsfTest-BoldItalic.ufo/glyphs/C_ombD_iaer.glif
new file mode 100644
index 0000000..490587d
--- /dev/null
+++ b/tests/input/font-psf-test/source/PsfTest-BoldItalic.ufo/glyphs/C_ombD_iaer.glif
@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="CombDiaer" format="2">
+ <unicode hex="0308"/>
+ <anchor x="-243" y="1585" name="U"/>
+ <anchor x="-365" y="1100" name="_U"/>
+ <outline>
+ <contour>
+ <point x="-233" y="1338" type="curve" smooth="yes"/>
+ <point x="-233" y="1256"/>
+ <point x="-172" y="1198"/>
+ <point x="-86" y="1198" type="curve" smooth="yes"/>
+ <point x="32" y="1198"/>
+ <point x="126" y="1294"/>
+ <point x="126" y="1404" type="curve" smooth="yes"/>
+ <point x="126" y="1484"/>
+ <point x="66" y="1544"/>
+ <point x="-21" y="1544" type="curve" smooth="yes"/>
+ <point x="-139" y="1544"/>
+ <point x="-233" y="1447"/>
+ </contour>
+ <contour>
+ <point x="-723" y="1338" type="curve" smooth="yes"/>
+ <point x="-723" y="1256"/>
+ <point x="-662" y="1198"/>
+ <point x="-576" y="1198" type="curve" smooth="yes"/>
+ <point x="-457" y="1198"/>
+ <point x="-363" y="1293"/>
+ <point x="-363" y="1404" type="curve" smooth="yes"/>
+ <point x="-363" y="1484"/>
+ <point x="-423" y="1544"/>
+ <point x="-510" y="1544" type="curve" smooth="yes"/>
+ <point x="-628" y="1544"/>
+ <point x="-723" y="1448"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/input/font-psf-test/source/PsfTest-BoldItalic.ufo/glyphs/C_ombG_rave.glif b/tests/input/font-psf-test/source/PsfTest-BoldItalic.ufo/glyphs/C_ombG_rave.glif
new file mode 100644
index 0000000..49617c2
--- /dev/null
+++ b/tests/input/font-psf-test/source/PsfTest-BoldItalic.ufo/glyphs/C_ombG_rave.glif
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="CombGrave" format="2">
+ <unicode hex="0300"/>
+ <anchor x="-241" y="1635" name="U"/>
+ <anchor x="-415" y="1100" name="_U"/>
+ <outline>
+ <contour>
+ <point x="-725" y="1584" type="line"/>
+ <point x="-403" y="1188" type="line"/>
+ <point x="-173" y="1188" type="line"/>
+ <point x="-395" y="1584" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/input/font-psf-test/source/PsfTest-BoldItalic.ufo/glyphs/C_ombR_ingA_bv.glif b/tests/input/font-psf-test/source/PsfTest-BoldItalic.ufo/glyphs/C_ombR_ingA_bv.glif
new file mode 100644
index 0000000..27f9832
--- /dev/null
+++ b/tests/input/font-psf-test/source/PsfTest-BoldItalic.ufo/glyphs/C_ombR_ingA_bv.glif
@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="CombRingAbv" format="2">
+ <unicode hex="030A"/>
+ <anchor x="-221" y="1635" name="U"/>
+ <anchor x="-357" y="1100" name="_U"/>
+ <outline>
+ <contour>
+ <point x="-358" y="1292" type="curve" smooth="yes"/>
+ <point x="-406" y="1292"/>
+ <point x="-442" y="1330"/>
+ <point x="-442" y="1375" type="curve" smooth="yes"/>
+ <point x="-442" y="1440"/>
+ <point x="-385" y="1480"/>
+ <point x="-331" y="1480" type="curve" smooth="yes"/>
+ <point x="-283" y="1480"/>
+ <point x="-247" y="1443"/>
+ <point x="-247" y="1398" type="curve" smooth="yes"/>
+ <point x="-247" y="1335"/>
+ <point x="-301" y="1292"/>
+ </contour>
+ <contour>
+ <point x="-598" y="1348" type="curve" smooth="yes"/>
+ <point x="-598" y="1238"/>
+ <point x="-504" y="1148"/>
+ <point x="-384" y="1148" type="curve" smooth="yes"/>
+ <point x="-223" y="1148"/>
+ <point x="-92" y="1271"/>
+ <point x="-92" y="1424" type="curve" smooth="yes"/>
+ <point x="-92" y="1534"/>
+ <point x="-186" y="1624"/>
+ <point x="-306" y="1624" type="curve" smooth="yes"/>
+ <point x="-467" y="1624"/>
+ <point x="-598" y="1501"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/input/font-psf-test/source/PsfTest-BoldItalic.ufo/glyphs/C_ombT_ilde.glif b/tests/input/font-psf-test/source/PsfTest-BoldItalic.ufo/glyphs/C_ombT_ilde.glif
new file mode 100644
index 0000000..1aa1b62
--- /dev/null
+++ b/tests/input/font-psf-test/source/PsfTest-BoldItalic.ufo/glyphs/C_ombT_ilde.glif
@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="CombTilde" format="2">
+ <unicode hex="0303"/>
+ <anchor x="-355" y="1490" name="U"/>
+ <anchor x="-390" y="1100" name="_U"/>
+ <outline>
+ <contour>
+ <point x="-687" y="1178" type="line"/>
+ <point x="-673" y="1232"/>
+ <point x="-628" y="1271"/>
+ <point x="-584" y="1271" type="curve" smooth="yes"/>
+ <point x="-546" y="1271"/>
+ <point x="-498" y="1247"/>
+ <point x="-437" y="1217" type="curve" smooth="yes"/>
+ <point x="-375" y="1187"/>
+ <point x="-327" y="1168"/>
+ <point x="-265" y="1168" type="curve" smooth="yes"/>
+ <point x="-129" y="1168"/>
+ <point x="-13" y="1294"/>
+ <point x="30" y="1465" type="curve"/>
+ <point x="-125" y="1465" type="line"/>
+ <point x="-138" y="1415"/>
+ <point x="-190" y="1373"/>
+ <point x="-235" y="1373" type="curve" smooth="yes"/>
+ <point x="-272" y="1373"/>
+ <point x="-306" y="1399"/>
+ <point x="-366" y="1423" type="curve" smooth="yes"/>
+ <point x="-438" y="1452"/>
+ <point x="-498" y="1475"/>
+ <point x="-563" y="1475" type="curve" smooth="yes"/>
+ <point x="-695" y="1475"/>
+ <point x="-802" y="1336"/>
+ <point x="-842" y="1178" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/input/font-psf-test/source/PsfTest-BoldItalic.ufo/glyphs/C_omma.glif b/tests/input/font-psf-test/source/PsfTest-BoldItalic.ufo/glyphs/C_omma.glif
new file mode 100644
index 0000000..4105316
--- /dev/null
+++ b/tests/input/font-psf-test/source/PsfTest-BoldItalic.ufo/glyphs/C_omma.glif
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="Comma" format="2">
+ <advance width="645"/>
+ <unicode hex="002C"/>
+ <outline>
+ <contour>
+ <point x="137" y="49" type="line"/>
+ <point x="297" y="49" type="line"/>
+ <point x="276" y="-34"/>
+ <point x="192" y="-151"/>
+ <point x="59" y="-262" type="curve"/>
+ <point x="187" y="-332" type="line"/>
+ <point x="337" y="-222"/>
+ <point x="539" y="-11"/>
+ <point x="539" y="165" type="curve" smooth="yes"/>
+ <point x="539" y="262"/>
+ <point x="495" y="337"/>
+ <point x="379" y="337" type="curve" smooth="yes"/>
+ <point x="266" y="337"/>
+ <point x="187" y="252"/>
+ <point x="169" y="178" type="curve" smooth="yes"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/input/font-psf-test/source/PsfTest-BoldItalic.ufo/glyphs/D_igitE_ight.glif b/tests/input/font-psf-test/source/PsfTest-BoldItalic.ufo/glyphs/D_igitE_ight.glif
new file mode 100644
index 0000000..9272dc9
--- /dev/null
+++ b/tests/input/font-psf-test/source/PsfTest-BoldItalic.ufo/glyphs/D_igitE_ight.glif
@@ -0,0 +1,63 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="DigitEight" format="2">
+ <advance width="1180"/>
+ <unicode hex="0038"/>
+ <anchor x="515" y="-100" name="L"/>
+ <anchor x="922" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="543" y="-25" type="curve" smooth="yes"/>
+ <point x="860" y="-25"/>
+ <point x="1182" y="176"/>
+ <point x="1182" y="498" type="curve" smooth="yes"/>
+ <point x="1182" y="642"/>
+ <point x="1090" y="742"/>
+ <point x="1011" y="787" type="curve"/>
+ <point x="1159" y="866"/>
+ <point x="1279" y="994"/>
+ <point x="1279" y="1163" type="curve" smooth="yes"/>
+ <point x="1279" y="1342"/>
+ <point x="1123" y="1470"/>
+ <point x="906" y="1470" type="curve" smooth="yes"/>
+ <point x="632" y="1470"/>
+ <point x="349" y="1310"/>
+ <point x="349" y="1028" type="curve" smooth="yes"/>
+ <point x="349" y="904"/>
+ <point x="412" y="821"/>
+ <point x="466" y="787" type="curve"/>
+ <point x="270" y="703"/>
+ <point x="108" y="563"/>
+ <point x="108" y="341" type="curve" smooth="yes"/>
+ <point x="108" y="123"/>
+ <point x="301" y="-25"/>
+ </contour>
+ <contour>
+ <point x="760" y="886" type="curve" smooth="yes"/>
+ <point x="651" y="886"/>
+ <point x="593" y="939"/>
+ <point x="593" y="1038" type="curve" smooth="yes"/>
+ <point x="593" y="1175"/>
+ <point x="721" y="1277"/>
+ <point x="858" y="1277" type="curve" smooth="yes"/>
+ <point x="976" y="1277"/>
+ <point x="1028" y="1221"/>
+ <point x="1028" y="1127" type="curve" smooth="yes"/>
+ <point x="1028" y="993"/>
+ <point x="898" y="886"/>
+ </contour>
+ <contour>
+ <point x="595" y="183" type="curve" smooth="yes"/>
+ <point x="458" y="183"/>
+ <point x="375" y="267"/>
+ <point x="375" y="384" type="curve" smooth="yes"/>
+ <point x="375" y="549"/>
+ <point x="549" y="673"/>
+ <point x="707" y="673" type="curve" smooth="yes"/>
+ <point x="833" y="673"/>
+ <point x="920" y="602"/>
+ <point x="920" y="477" type="curve" smooth="yes"/>
+ <point x="920" y="317"/>
+ <point x="759" y="183"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/input/font-psf-test/source/PsfTest-BoldItalic.ufo/glyphs/D_igitF_ive.glif b/tests/input/font-psf-test/source/PsfTest-BoldItalic.ufo/glyphs/D_igitF_ive.glif
new file mode 100644
index 0000000..1c4dd99
--- /dev/null
+++ b/tests/input/font-psf-test/source/PsfTest-BoldItalic.ufo/glyphs/D_igitF_ive.glif
@@ -0,0 +1,44 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="DigitFive" format="2">
+ <advance width="1180"/>
+ <unicode hex="0035"/>
+ <anchor x="515" y="-100" name="L"/>
+ <anchor x="922" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="1330" y="1445" type="line"/>
+ <point x="475" y="1445" type="line"/>
+ <point x="274" y="639" type="line"/>
+ <point x="410" y="686"/>
+ <point x="519" y="703"/>
+ <point x="625" y="703" type="curve" smooth="yes"/>
+ <point x="763" y="703"/>
+ <point x="867" y="630"/>
+ <point x="867" y="507" type="curve" smooth="yes"/>
+ <point x="867" y="318"/>
+ <point x="680" y="213"/>
+ <point x="503" y="213" type="curve" smooth="yes"/>
+ <point x="363" y="213"/>
+ <point x="255" y="260"/>
+ <point x="168" y="356" type="curve"/>
+ <point x="59" y="79" type="line"/>
+ <point x="165" y="2"/>
+ <point x="308" y="-25"/>
+ <point x="483" y="-25" type="curve" smooth="yes"/>
+ <point x="841" y="-25"/>
+ <point x="1155" y="204"/>
+ <point x="1155" y="564" type="curve" smooth="yes"/>
+ <point x="1155" y="774"/>
+ <point x="1007" y="921"/>
+ <point x="774" y="921" type="curve" smooth="yes"/>
+ <point x="712" y="921"/>
+ <point x="632" y="902"/>
+ <point x="595" y="886" type="curve"/>
+ <point x="674" y="1203" type="line"/>
+ <point x="1004" y="1203" type="line" smooth="yes"/>
+ <point x="1088" y="1203"/>
+ <point x="1193" y="1199"/>
+ <point x="1264" y="1183" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/input/font-psf-test/source/PsfTest-BoldItalic.ufo/glyphs/D_igitF_our.glif b/tests/input/font-psf-test/source/PsfTest-BoldItalic.ufo/glyphs/D_igitF_our.glif
new file mode 100644
index 0000000..617709f
--- /dev/null
+++ b/tests/input/font-psf-test/source/PsfTest-BoldItalic.ufo/glyphs/D_igitF_our.glif
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="DigitFour" format="2">
+ <advance width="1180"/>
+ <unicode hex="0034"/>
+ <anchor x="522" y="-100" name="L"/>
+ <anchor x="929" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="1180" y="342" type="line"/>
+ <point x="1235" y="564" type="line"/>
+ <point x="1075" y="564" type="line"/>
+ <point x="1295" y="1445" type="line"/>
+ <point x="945" y="1445" type="line"/>
+ <point x="120" y="564" type="line"/>
+ <point x="65" y="342" type="line"/>
+ <point x="755" y="342" type="line"/>
+ <point x="670" y="0" type="line"/>
+ <point x="935" y="0" type="line"/>
+ <point x="1020" y="342" type="line"/>
+ </contour>
+ <contour>
+ <point x="954" y="1143" type="line"/>
+ <point x="810" y="564" type="line"/>
+ <point x="385" y="564" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/input/font-psf-test/source/PsfTest-BoldItalic.ufo/glyphs/D_igitN_ine.glif b/tests/input/font-psf-test/source/PsfTest-BoldItalic.ufo/glyphs/D_igitN_ine.glif
new file mode 100644
index 0000000..85e36a0
--- /dev/null
+++ b/tests/input/font-psf-test/source/PsfTest-BoldItalic.ufo/glyphs/D_igitN_ine.glif
@@ -0,0 +1,49 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="DigitNine" format="2">
+ <advance width="1180"/>
+ <unicode hex="0039"/>
+ <anchor x="515" y="-100" name="L"/>
+ <anchor x="922" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="119" y="84" type="line"/>
+ <point x="199" y="25"/>
+ <point x="327" y="-25"/>
+ <point x="455" y="-25" type="curve" smooth="yes"/>
+ <point x="979" y="-25"/>
+ <point x="1289" y="533"/>
+ <point x="1289" y="979" type="curve" smooth="yes"/>
+ <point x="1289" y="1248"/>
+ <point x="1164" y="1470"/>
+ <point x="833" y="1470" type="curve" smooth="yes"/>
+ <point x="554" y="1470"/>
+ <point x="255" y="1239"/>
+ <point x="255" y="932" type="curve" smooth="yes"/>
+ <point x="255" y="736"/>
+ <point x="399" y="570"/>
+ <point x="644" y="570" type="curve" smooth="yes"/>
+ <point x="833" y="570"/>
+ <point x="1027" y="700"/>
+ <point x="1164" y="859" type="curve"/>
+ <point x="1123" y="981" type="line"/>
+ <point x="1021" y="868"/>
+ <point x="863" y="782"/>
+ <point x="728" y="782" type="curve" smooth="yes"/>
+ <point x="589" y="782"/>
+ <point x="519" y="845"/>
+ <point x="519" y="955" type="curve" smooth="yes"/>
+ <point x="519" y="1133"/>
+ <point x="653" y="1237"/>
+ <point x="801" y="1237" type="curve" smooth="yes"/>
+ <point x="951" y="1237"/>
+ <point x="1029" y="1136"/>
+ <point x="1029" y="965" type="curve" smooth="yes"/>
+ <point x="1029" y="476"/>
+ <point x="710" y="208"/>
+ <point x="513" y="208" type="curve" smooth="yes"/>
+ <point x="417" y="208"/>
+ <point x="301" y="252"/>
+ <point x="237" y="337" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/input/font-psf-test/source/PsfTest-BoldItalic.ufo/glyphs/D_igitO_ne.glif b/tests/input/font-psf-test/source/PsfTest-BoldItalic.ufo/glyphs/D_igitO_ne.glif
new file mode 100644
index 0000000..df3633d
--- /dev/null
+++ b/tests/input/font-psf-test/source/PsfTest-BoldItalic.ufo/glyphs/D_igitO_ne.glif
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="DigitOne" format="2">
+ <advance width="1180"/>
+ <unicode hex="0031"/>
+ <anchor x="515" y="-100" name="L"/>
+ <anchor x="922" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="490" y="233" type="line"/>
+ <point x="183" y="233" type="line"/>
+ <point x="125" y="0" type="line"/>
+ <point x="1015" y="0" type="line"/>
+ <point x="1073" y="233" type="line"/>
+ <point x="765" y="233" type="line"/>
+ <point x="1067" y="1445" type="line"/>
+ <point x="792" y="1445" type="line"/>
+ <point x="432" y="1265" type="line"/>
+ <point x="403" y="1008" type="line"/>
+ <point x="720" y="1158" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/input/font-psf-test/source/PsfTest-BoldItalic.ufo/glyphs/D_igitS_even.glif b/tests/input/font-psf-test/source/PsfTest-BoldItalic.ufo/glyphs/D_igitS_even.glif
new file mode 100644
index 0000000..23ac13b
--- /dev/null
+++ b/tests/input/font-psf-test/source/PsfTest-BoldItalic.ufo/glyphs/D_igitS_even.glif
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="DigitSeven" format="2">
+ <advance width="1180"/>
+ <unicode hex="0037"/>
+ <anchor x="515" y="-100" name="L"/>
+ <anchor x="922" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="480" y="0" type="line"/>
+ <point x="722" y="454"/>
+ <point x="1004" y="846"/>
+ <point x="1400" y="1247" type="curve"/>
+ <point x="1450" y="1445" type="line"/>
+ <point x="390" y="1445" type="line"/>
+ <point x="324" y="1178" type="line"/>
+ <point x="404" y="1194"/>
+ <point x="521" y="1198"/>
+ <point x="709" y="1198" type="curve" smooth="yes"/>
+ <point x="1039" y="1198" type="line"/>
+ <point x="689" y="829"/>
+ <point x="488" y="560"/>
+ <point x="175" y="0" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/input/font-psf-test/source/PsfTest-BoldItalic.ufo/glyphs/D_igitS_ix.glif b/tests/input/font-psf-test/source/PsfTest-BoldItalic.ufo/glyphs/D_igitS_ix.glif
new file mode 100644
index 0000000..5fad278
--- /dev/null
+++ b/tests/input/font-psf-test/source/PsfTest-BoldItalic.ufo/glyphs/D_igitS_ix.glif
@@ -0,0 +1,49 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="DigitSix" format="2">
+ <advance width="1180"/>
+ <unicode hex="0036"/>
+ <anchor x="525" y="-100" name="L"/>
+ <anchor x="932" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="1347" y="1371" type="line"/>
+ <point x="1260" y="1440"/>
+ <point x="1149" y="1470"/>
+ <point x="1011" y="1470" type="curve" smooth="yes"/>
+ <point x="493" y="1470"/>
+ <point x="181" y="971"/>
+ <point x="181" y="500" type="curve" smooth="yes"/>
+ <point x="181" y="188"/>
+ <point x="368" y="-25"/>
+ <point x="635" y="-25" type="curve" smooth="yes"/>
+ <point x="954" y="-25"/>
+ <point x="1207" y="192"/>
+ <point x="1207" y="498" type="curve" smooth="yes"/>
+ <point x="1207" y="714"/>
+ <point x="1058" y="916"/>
+ <point x="813" y="916" type="curve" smooth="yes"/>
+ <point x="622" y="916"/>
+ <point x="477" y="802"/>
+ <point x="326" y="648" type="curve"/>
+ <point x="363" y="525" type="line"/>
+ <point x="470" y="637"/>
+ <point x="595" y="703"/>
+ <point x="750" y="703" type="curve" smooth="yes"/>
+ <point x="882" y="703"/>
+ <point x="954" y="586"/>
+ <point x="954" y="466" type="curve" smooth="yes"/>
+ <point x="954" y="325"/>
+ <point x="828" y="208"/>
+ <point x="677" y="208" type="curve" smooth="yes"/>
+ <point x="526" y="208"/>
+ <point x="447" y="350"/>
+ <point x="447" y="533" type="curve" smooth="yes"/>
+ <point x="447" y="978"/>
+ <point x="738" y="1237"/>
+ <point x="953" y="1237" type="curve" smooth="yes"/>
+ <point x="1049" y="1237"/>
+ <point x="1155" y="1204"/>
+ <point x="1220" y="1119" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/input/font-psf-test/source/PsfTest-BoldItalic.ufo/glyphs/D_igitT_hree.glif b/tests/input/font-psf-test/source/PsfTest-BoldItalic.ufo/glyphs/D_igitT_hree.glif
new file mode 100644
index 0000000..5be951b
--- /dev/null
+++ b/tests/input/font-psf-test/source/PsfTest-BoldItalic.ufo/glyphs/D_igitT_hree.glif
@@ -0,0 +1,52 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="DigitThree" format="2">
+ <advance width="1180"/>
+ <unicode hex="0033"/>
+ <anchor x="515" y="-100" name="L"/>
+ <anchor x="922" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="548" y="876" type="line"/>
+ <point x="489" y="639" type="line"/>
+ <point x="579" y="639" type="line" smooth="yes"/>
+ <point x="778" y="639"/>
+ <point x="880" y="555"/>
+ <point x="880" y="452" type="curve" smooth="yes"/>
+ <point x="880" y="295"/>
+ <point x="726" y="208"/>
+ <point x="576" y="208" type="curve" smooth="yes"/>
+ <point x="386" y="208"/>
+ <point x="253" y="279"/>
+ <point x="174" y="401" type="curve"/>
+ <point x="72" y="129" type="line"/>
+ <point x="162" y="32"/>
+ <point x="321" y="-25"/>
+ <point x="518" y="-25" type="curve" smooth="yes"/>
+ <point x="867" y="-25"/>
+ <point x="1163" y="169"/>
+ <point x="1163" y="471" type="curve" smooth="yes"/>
+ <point x="1163" y="644"/>
+ <point x="999" y="751"/>
+ <point x="882" y="772" type="curve"/>
+ <point x="1076" y="817"/>
+ <point x="1296" y="963"/>
+ <point x="1296" y="1172" type="curve" smooth="yes"/>
+ <point x="1296" y="1348"/>
+ <point x="1112" y="1470"/>
+ <point x="856" y="1470" type="curve" smooth="yes"/>
+ <point x="689" y="1470"/>
+ <point x="529" y="1402"/>
+ <point x="427" y="1312" type="curve"/>
+ <point x="405" y="1084" type="line"/>
+ <point x="546" y="1199"/>
+ <point x="664" y="1237"/>
+ <point x="818" y="1237" type="curve" smooth="yes"/>
+ <point x="928" y="1237"/>
+ <point x="1001" y="1178"/>
+ <point x="1001" y="1100" type="curve" smooth="yes"/>
+ <point x="1001" y="975"/>
+ <point x="819" y="876"/>
+ <point x="638" y="876" type="curve" smooth="yes"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/input/font-psf-test/source/PsfTest-BoldItalic.ufo/glyphs/D_igitT_wo.glif b/tests/input/font-psf-test/source/PsfTest-BoldItalic.ufo/glyphs/D_igitT_wo.glif
new file mode 100644
index 0000000..001d438
--- /dev/null
+++ b/tests/input/font-psf-test/source/PsfTest-BoldItalic.ufo/glyphs/D_igitT_wo.glif
@@ -0,0 +1,37 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="DigitTwo" format="2">
+ <advance width="1180"/>
+ <unicode hex="0032"/>
+ <anchor x="515" y="-100" name="L"/>
+ <anchor x="882" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="1094" y="257" type="line"/>
+ <point x="1010" y="244"/>
+ <point x="942" y="243"/>
+ <point x="745" y="243" type="curve" smooth="yes"/>
+ <point x="480" y="243" type="line"/>
+ <point x="875" y="492"/>
+ <point x="1255" y="786"/>
+ <point x="1255" y="1125" type="curve" smooth="yes"/>
+ <point x="1255" y="1324"/>
+ <point x="1106" y="1470"/>
+ <point x="846" y="1470" type="curve" smooth="yes"/>
+ <point x="667" y="1470"/>
+ <point x="472" y="1388"/>
+ <point x="363" y="1277" type="curve"/>
+ <point x="374" y="1039" type="line"/>
+ <point x="489" y="1146"/>
+ <point x="646" y="1223"/>
+ <point x="762" y="1223" type="curve" smooth="yes"/>
+ <point x="890" y="1223"/>
+ <point x="949" y="1138"/>
+ <point x="949" y="1040" type="curve" smooth="yes"/>
+ <point x="949" y="805"/>
+ <point x="500" y="440"/>
+ <point x="104" y="218" type="curve"/>
+ <point x="50" y="0" type="line"/>
+ <point x="1030" y="0" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/input/font-psf-test/source/PsfTest-BoldItalic.ufo/glyphs/D_igitZ_ero.glif b/tests/input/font-psf-test/source/PsfTest-BoldItalic.ufo/glyphs/D_igitZ_ero.glif
new file mode 100644
index 0000000..895a8e4
--- /dev/null
+++ b/tests/input/font-psf-test/source/PsfTest-BoldItalic.ufo/glyphs/D_igitZ_ero.glif
@@ -0,0 +1,49 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="DigitZero" format="2">
+ <advance width="1180"/>
+ <unicode hex="0030"/>
+ <anchor x="520" y="-100" name="L"/>
+ <anchor x="927" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="959" y="683" type="curve" smooth="yes"/>
+ <point x="873" y="339"/>
+ <point x="762" y="203"/>
+ <point x="600" y="203" type="curve" smooth="yes"/>
+ <point x="469" y="203"/>
+ <point x="432" y="294"/>
+ <point x="432" y="454" type="curve" smooth="yes"/>
+ <point x="432" y="537"/>
+ <point x="447" y="630"/>
+ <point x="478" y="755" type="curve" smooth="yes"/>
+ <point x="564" y="1099"/>
+ <point x="676" y="1242"/>
+ <point x="839" y="1242" type="curve" smooth="yes"/>
+ <point x="971" y="1242"/>
+ <point x="1010" y="1140"/>
+ <point x="1010" y="992" type="curve" smooth="yes"/>
+ <point x="1010" y="907"/>
+ <point x="991" y="811"/>
+ </contour>
+ <contour>
+ <point x="1246" y="689" type="curve" smooth="yes"/>
+ <point x="1281" y="828"/>
+ <point x="1298" y="927"/>
+ <point x="1298" y="1028" type="curve" smooth="yes"/>
+ <point x="1298" y="1317"/>
+ <point x="1158" y="1470"/>
+ <point x="906" y="1470" type="curve" smooth="yes"/>
+ <point x="587" y="1470"/>
+ <point x="329" y="1302"/>
+ <point x="190" y="745" type="curve" smooth="yes"/>
+ <point x="157" y="611"/>
+ <point x="141" y="516"/>
+ <point x="141" y="420" type="curve" smooth="yes"/>
+ <point x="141" y="131"/>
+ <point x="292" y="-25"/>
+ <point x="533" y="-25" type="curve" smooth="yes"/>
+ <point x="854" y="-25"/>
+ <point x="1103" y="115"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/input/font-psf-test/source/PsfTest-BoldItalic.ufo/glyphs/D_ollarS_gn.glif b/tests/input/font-psf-test/source/PsfTest-BoldItalic.ufo/glyphs/D_ollarS_gn.glif
new file mode 100644
index 0000000..0b8bdfc
--- /dev/null
+++ b/tests/input/font-psf-test/source/PsfTest-BoldItalic.ufo/glyphs/D_ollarS_gn.glif
@@ -0,0 +1,57 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="DollarSgn" format="2">
+ <advance width="1180"/>
+ <unicode hex="0024"/>
+ <outline>
+ <contour>
+ <point x="879" y="1584" type="line"/>
+ <point x="679" y="780" type="line"/>
+ <point x="634" y="719" type="line"/>
+ <point x="400" y="-218" type="line"/>
+ <point x="576" y="-218" type="line"/>
+ <point x="795" y="661" type="line"/>
+ <point x="842" y="727" type="line"/>
+ <point x="1055" y="1584" type="line"/>
+ </contour>
+ <contour>
+ <point x="1250" y="1303" type="line"/>
+ <point x="1145" y="1355"/>
+ <point x="1026" y="1375"/>
+ <point x="885" y="1375" type="curve" smooth="yes"/>
+ <point x="537" y="1375"/>
+ <point x="345" y="1216"/>
+ <point x="345" y="984" type="curve" smooth="yes"/>
+ <point x="345" y="841"/>
+ <point x="441" y="726"/>
+ <point x="638" y="622" type="curve" smooth="yes"/>
+ <point x="832" y="519"/>
+ <point x="881" y="451"/>
+ <point x="881" y="381" type="curve" smooth="yes"/>
+ <point x="881" y="274"/>
+ <point x="817" y="209"/>
+ <point x="613" y="209" type="curve" smooth="yes"/>
+ <point x="462" y="209"/>
+ <point x="336" y="298"/>
+ <point x="259" y="389" type="curve"/>
+ <point x="133" y="143" type="line"/>
+ <point x="243" y="56"/>
+ <point x="378" y="0"/>
+ <point x="566" y="0" type="curve" smooth="yes"/>
+ <point x="879" y="0"/>
+ <point x="1120" y="142"/>
+ <point x="1120" y="396" type="curve" smooth="yes"/>
+ <point x="1120" y="562"/>
+ <point x="1028" y="682"/>
+ <point x="817" y="803" type="curve" smooth="yes"/>
+ <point x="635" y="908"/>
+ <point x="592" y="958"/>
+ <point x="592" y="1016" type="curve" smooth="yes"/>
+ <point x="592" y="1113"/>
+ <point x="649" y="1176"/>
+ <point x="826" y="1176" type="curve" smooth="yes"/>
+ <point x="954" y="1176"/>
+ <point x="1048" y="1135"/>
+ <point x="1134" y="1066" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/input/font-psf-test/source/PsfTest-BoldItalic.ufo/glyphs/D_ottedC_irc.glif b/tests/input/font-psf-test/source/PsfTest-BoldItalic.ufo/glyphs/D_ottedC_irc.glif
new file mode 100644
index 0000000..f7581b6
--- /dev/null
+++ b/tests/input/font-psf-test/source/PsfTest-BoldItalic.ufo/glyphs/D_ottedC_irc.glif
@@ -0,0 +1,235 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="DottedCirc" format="2">
+ <advance width="1086"/>
+ <unicode hex="25CC"/>
+ <anchor x="493" y="0" name="H"/>
+ <anchor x="545" y="-100" name="L"/>
+ <anchor x="750" y="0" name="O"/>
+ <anchor x="645" y="1000" name="U"/>
+ <outline>
+ <contour>
+ <point x="443" y="837" type="curve" smooth="yes"/>
+ <point x="443" y="864"/>
+ <point x="423" y="885"/>
+ <point x="398" y="885" type="curve" smooth="yes"/>
+ <point x="371" y="885"/>
+ <point x="348" y="861"/>
+ <point x="348" y="837" type="curve" smooth="yes"/>
+ <point x="348" y="809"/>
+ <point x="372" y="789"/>
+ <point x="398" y="789" type="curve" smooth="yes"/>
+ <point x="425" y="789"/>
+ <point x="443" y="812"/>
+ </contour>
+ <contour>
+ <point x="758" y="79" type="curve" smooth="yes"/>
+ <point x="758" y="106"/>
+ <point x="736" y="127"/>
+ <point x="710" y="127" type="curve" smooth="yes"/>
+ <point x="685" y="127"/>
+ <point x="662" y="103"/>
+ <point x="662" y="80" type="curve" smooth="yes"/>
+ <point x="662" y="52"/>
+ <point x="686" y="31"/>
+ <point x="710" y="31" type="curve" smooth="yes"/>
+ <point x="737" y="31"/>
+ <point x="758" y="55"/>
+ </contour>
+ <contour>
+ <point x="310" y="749" type="curve" smooth="yes"/>
+ <point x="310" y="775"/>
+ <point x="288" y="796"/>
+ <point x="263" y="796" type="curve" smooth="yes"/>
+ <point x="238" y="796"/>
+ <point x="215" y="774"/>
+ <point x="215" y="747" type="curve" smooth="yes"/>
+ <point x="215" y="722"/>
+ <point x="236" y="701"/>
+ <point x="263" y="701" type="curve" smooth="yes"/>
+ <point x="291" y="701"/>
+ <point x="310" y="720"/>
+ </contour>
+ <contour>
+ <point x="891" y="168" type="curve" smooth="yes"/>
+ <point x="891" y="197"/>
+ <point x="870" y="215"/>
+ <point x="843" y="215" type="curve" smooth="yes"/>
+ <point x="817" y="215"/>
+ <point x="795" y="194"/>
+ <point x="795" y="168" type="curve" smooth="yes"/>
+ <point x="795" y="143"/>
+ <point x="816" y="121"/>
+ <point x="843" y="121" type="curve" smooth="yes"/>
+ <point x="871" y="121"/>
+ <point x="891" y="143"/>
+ </contour>
+ <contour>
+ <point x="222" y="613" type="curve" smooth="yes"/>
+ <point x="222" y="640"/>
+ <point x="199" y="663"/>
+ <point x="173" y="663" type="curve" smooth="yes"/>
+ <point x="149" y="663"/>
+ <point x="126" y="642"/>
+ <point x="126" y="615" type="curve" smooth="yes"/>
+ <point x="126" y="591"/>
+ <point x="145" y="567"/>
+ <point x="173" y="567" type="curve" smooth="yes"/>
+ <point x="197" y="567"/>
+ <point x="222" y="587"/>
+ </contour>
+ <contour>
+ <point x="980" y="301" type="curve" smooth="yes"/>
+ <point x="980" y="327"/>
+ <point x="957" y="348"/>
+ <point x="932" y="348" type="curve" smooth="yes"/>
+ <point x="908" y="348"/>
+ <point x="884" y="332"/>
+ <point x="884" y="301" type="curve" smooth="yes"/>
+ <point x="884" y="277"/>
+ <point x="902" y="254"/>
+ <point x="932" y="254" type="curve" smooth="yes"/>
+ <point x="957" y="254"/>
+ <point x="980" y="274"/>
+ </contour>
+ <contour>
+ <point x="191" y="459" type="curve" smooth="yes"/>
+ <point x="191" y="484"/>
+ <point x="168" y="505"/>
+ <point x="143" y="505" type="curve" smooth="yes"/>
+ <point x="116" y="505"/>
+ <point x="95" y="484"/>
+ <point x="95" y="458" type="curve" smooth="yes"/>
+ <point x="95" y="433"/>
+ <point x="115" y="410"/>
+ <point x="143" y="410" type="curve" smooth="yes"/>
+ <point x="167" y="410"/>
+ <point x="191" y="432"/>
+ </contour>
+ <contour>
+ <point x="1011" y="458" type="curve" smooth="yes"/>
+ <point x="1011" y="484"/>
+ <point x="990" y="506"/>
+ <point x="964" y="506" type="curve" smooth="yes"/>
+ <point x="940" y="506"/>
+ <point x="915" y="484"/>
+ <point x="915" y="457" type="curve" smooth="yes"/>
+ <point x="915" y="433"/>
+ <point x="936" y="411"/>
+ <point x="964" y="411" type="curve" smooth="yes"/>
+ <point x="990" y="411"/>
+ <point x="1011" y="433"/>
+ </contour>
+ <contour>
+ <point x="222" y="302" type="curve" smooth="yes"/>
+ <point x="222" y="328"/>
+ <point x="200" y="348"/>
+ <point x="174" y="348" type="curve" smooth="yes"/>
+ <point x="147" y="348"/>
+ <point x="126" y="326"/>
+ <point x="126" y="302" type="curve" smooth="yes"/>
+ <point x="126" y="275"/>
+ <point x="149" y="253"/>
+ <point x="174" y="253" type="curve" smooth="yes"/>
+ <point x="201" y="253"/>
+ <point x="222" y="277"/>
+ </contour>
+ <contour>
+ <point x="980" y="615" type="curve" smooth="yes"/>
+ <point x="980" y="642"/>
+ <point x="955" y="663"/>
+ <point x="931" y="663" type="curve" smooth="yes"/>
+ <point x="904" y="663"/>
+ <point x="885" y="638"/>
+ <point x="885" y="614" type="curve" smooth="yes"/>
+ <point x="885" y="588"/>
+ <point x="907" y="567"/>
+ <point x="931" y="567" type="curve" smooth="yes"/>
+ <point x="959" y="567"/>
+ <point x="980" y="591"/>
+ </contour>
+ <contour>
+ <point x="310" y="168" type="curve" smooth="yes"/>
+ <point x="310" y="195"/>
+ <point x="291" y="215"/>
+ <point x="263" y="215" type="curve" smooth="yes"/>
+ <point x="238" y="215"/>
+ <point x="215" y="190"/>
+ <point x="215" y="168" type="curve" smooth="yes"/>
+ <point x="215" y="143"/>
+ <point x="238" y="120"/>
+ <point x="263" y="120" type="curve" smooth="yes"/>
+ <point x="289" y="120"/>
+ <point x="310" y="143"/>
+ </contour>
+ <contour>
+ <point x="890" y="748" type="curve" smooth="yes"/>
+ <point x="890" y="774"/>
+ <point x="870" y="796"/>
+ <point x="843" y="796" type="curve" smooth="yes"/>
+ <point x="815" y="796"/>
+ <point x="796" y="773"/>
+ <point x="796" y="748" type="curve" smooth="yes"/>
+ <point x="796" y="724"/>
+ <point x="817" y="700"/>
+ <point x="843" y="700" type="curve" smooth="yes"/>
+ <point x="869" y="700"/>
+ <point x="890" y="722"/>
+ </contour>
+ <contour>
+ <point x="444" y="78" type="curve" smooth="yes"/>
+ <point x="444" y="102"/>
+ <point x="423" y="126"/>
+ <point x="396" y="126" type="curve" smooth="yes"/>
+ <point x="370" y="126"/>
+ <point x="348" y="102"/>
+ <point x="348" y="78" type="curve" smooth="yes"/>
+ <point x="348" y="55"/>
+ <point x="370" y="31"/>
+ <point x="396" y="31" type="curve" smooth="yes"/>
+ <point x="420" y="31"/>
+ <point x="444" y="51"/>
+ </contour>
+ <contour>
+ <point x="758" y="836" type="curve" smooth="yes"/>
+ <point x="758" y="861"/>
+ <point x="737" y="885"/>
+ <point x="710" y="885" type="curve" smooth="yes"/>
+ <point x="684" y="885"/>
+ <point x="663" y="862"/>
+ <point x="663" y="838" type="curve" smooth="yes"/>
+ <point x="663" y="814"/>
+ <point x="683" y="789"/>
+ <point x="710" y="789" type="curve" smooth="yes"/>
+ <point x="734" y="789"/>
+ <point x="758" y="809"/>
+ </contour>
+ <contour>
+ <point x="601" y="47" type="curve" smooth="yes"/>
+ <point x="601" y="73"/>
+ <point x="579" y="95"/>
+ <point x="553" y="95" type="curve" smooth="yes"/>
+ <point x="527" y="95"/>
+ <point x="506" y="73"/>
+ <point x="506" y="47" type="curve" smooth="yes"/>
+ <point x="506" y="21"/>
+ <point x="527" y="0"/>
+ <point x="553" y="0" type="curve" smooth="yes"/>
+ <point x="579" y="0"/>
+ <point x="601" y="21"/>
+ </contour>
+ <contour>
+ <point x="601" y="868" type="curve" smooth="yes"/>
+ <point x="601" y="894"/>
+ <point x="579" y="916"/>
+ <point x="553" y="916" type="curve" smooth="yes"/>
+ <point x="527" y="916"/>
+ <point x="506" y="894"/>
+ <point x="506" y="868" type="curve" smooth="yes"/>
+ <point x="506" y="842"/>
+ <point x="527" y="821"/>
+ <point x="553" y="821" type="curve" smooth="yes"/>
+ <point x="579" y="821"/>
+ <point x="601" y="842"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/input/font-psf-test/source/PsfTest-BoldItalic.ufo/glyphs/E_qS_gn.glif b/tests/input/font-psf-test/source/PsfTest-BoldItalic.ufo/glyphs/E_qS_gn.glif
new file mode 100644
index 0000000..0461eab
--- /dev/null
+++ b/tests/input/font-psf-test/source/PsfTest-BoldItalic.ufo/glyphs/E_qS_gn.glif
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="EqSgn" format="2">
+ <advance width="1180"/>
+ <unicode hex="003D"/>
+ <outline>
+ <contour>
+ <point x="168" y="436" type="line"/>
+ <point x="1128" y="436" type="line"/>
+ <point x="1180" y="643" type="line"/>
+ <point x="220" y="643" type="line"/>
+ </contour>
+ <contour>
+ <point x="259" y="802" type="line"/>
+ <point x="1219" y="802" type="line"/>
+ <point x="1271" y="1010" type="line"/>
+ <point x="311" y="1010" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/input/font-psf-test/source/PsfTest-BoldItalic.ufo/glyphs/E_xclamationM_rk.glif b/tests/input/font-psf-test/source/PsfTest-BoldItalic.ufo/glyphs/E_xclamationM_rk.glif
new file mode 100644
index 0000000..167f45e
--- /dev/null
+++ b/tests/input/font-psf-test/source/PsfTest-BoldItalic.ufo/glyphs/E_xclamationM_rk.glif
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="ExclamationMrk" format="2">
+ <advance width="760"/>
+ <unicode hex="0021"/>
+ <outline>
+ <contour>
+ <point x="593" y="495" type="line"/>
+ <point x="670" y="782"/>
+ <point x="736" y="1065"/>
+ <point x="882" y="1495" type="curve"/>
+ <point x="547" y="1495" type="line"/>
+ <point x="478" y="1065"/>
+ <point x="402" y="782"/>
+ <point x="338" y="495" type="curve"/>
+ </contour>
+ <contour>
+ <point x="201" y="116" type="curve" smooth="yes"/>
+ <point x="201" y="35"/>
+ <point x="262" y="-25"/>
+ <point x="348" y="-25" type="curve" smooth="yes"/>
+ <point x="466" y="-25"/>
+ <point x="561" y="71"/>
+ <point x="561" y="181" type="curve" smooth="yes"/>
+ <point x="561" y="261"/>
+ <point x="502" y="322"/>
+ <point x="415" y="322" type="curve" smooth="yes"/>
+ <point x="298" y="322"/>
+ <point x="201" y="226"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/input/font-psf-test/source/PsfTest-BoldItalic.ufo/glyphs/F_ullS_top.glif b/tests/input/font-psf-test/source/PsfTest-BoldItalic.ufo/glyphs/F_ullS_top.glif
new file mode 100644
index 0000000..cfedcd4
--- /dev/null
+++ b/tests/input/font-psf-test/source/PsfTest-BoldItalic.ufo/glyphs/F_ullS_top.glif
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="FullStop" format="2">
+ <advance width="690"/>
+ <unicode hex="002E"/>
+ <outline>
+ <contour>
+ <point x="171" y="116" type="curve" smooth="yes"/>
+ <point x="171" y="35"/>
+ <point x="232" y="-25"/>
+ <point x="318" y="-25" type="curve" smooth="yes"/>
+ <point x="436" y="-25"/>
+ <point x="531" y="71"/>
+ <point x="531" y="181" type="curve" smooth="yes"/>
+ <point x="531" y="261"/>
+ <point x="472" y="322"/>
+ <point x="385" y="322" type="curve" smooth="yes"/>
+ <point x="268" y="322"/>
+ <point x="171" y="226"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/input/font-psf-test/source/PsfTest-BoldItalic.ufo/glyphs/G_T_S_gn.glif b/tests/input/font-psf-test/source/PsfTest-BoldItalic.ufo/glyphs/G_T_S_gn.glif
new file mode 100644
index 0000000..6dab866
--- /dev/null
+++ b/tests/input/font-psf-test/source/PsfTest-BoldItalic.ufo/glyphs/G_T_S_gn.glif
@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="GTSgn" format="2">
+ <advance width="1180"/>
+ <unicode hex="003E"/>
+ <outline>
+ <contour>
+ <point x="130" y="243" type="line"/>
+ <point x="1186" y="629" type="line"/>
+ <point x="1233" y="817" type="line"/>
+ <point x="369" y="1203" type="line"/>
+ <point x="313" y="975" type="line"/>
+ <point x="930" y="733" type="line"/>
+ <point x="187" y="470" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/input/font-psf-test/source/PsfTest-BoldItalic.ufo/glyphs/G_raveA_ccent.glif b/tests/input/font-psf-test/source/PsfTest-BoldItalic.ufo/glyphs/G_raveA_ccent.glif
new file mode 100644
index 0000000..f745b6a
--- /dev/null
+++ b/tests/input/font-psf-test/source/PsfTest-BoldItalic.ufo/glyphs/G_raveA_ccent.glif
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="GraveAccent" format="2">
+ <advance width="620"/>
+ <unicode hex="0060"/>
+ <anchor x="848" y="1635" name="U"/>
+ <outline>
+ <contour>
+ <point x="265" y="1584" type="line"/>
+ <point x="587" y="1188" type="line"/>
+ <point x="817" y="1188" type="line"/>
+ <point x="595" y="1584" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/input/font-psf-test/source/PsfTest-BoldItalic.ufo/glyphs/H_yphen.glif b/tests/input/font-psf-test/source/PsfTest-BoldItalic.ufo/glyphs/H_yphen.glif
new file mode 100644
index 0000000..810f855
--- /dev/null
+++ b/tests/input/font-psf-test/source/PsfTest-BoldItalic.ufo/glyphs/H_yphen.glif
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="Hyphen" format="2">
+ <advance width="860"/>
+ <unicode hex="2010"/>
+ <anchor x="655" y="1100" name="U"/>
+ <outline>
+ <contour>
+ <point x="139" y="520" type="line"/>
+ <point x="879" y="520" type="line"/>
+ <point x="931" y="728" type="line"/>
+ <point x="191" y="728" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/input/font-psf-test/source/PsfTest-BoldItalic.ufo/glyphs/H_yphenM_inus.glif b/tests/input/font-psf-test/source/PsfTest-BoldItalic.ufo/glyphs/H_yphenM_inus.glif
new file mode 100644
index 0000000..d8ce949
--- /dev/null
+++ b/tests/input/font-psf-test/source/PsfTest-BoldItalic.ufo/glyphs/H_yphenM_inus.glif
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="HyphenMinus" format="2">
+ <advance width="875"/>
+ <unicode hex="002D"/>
+ <anchor x="665" y="1100" name="U"/>
+ <outline>
+ <contour>
+ <point x="149" y="520" type="line"/>
+ <point x="884" y="520" type="line"/>
+ <point x="936" y="728" type="line"/>
+ <point x="201" y="728" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/input/font-psf-test/source/PsfTest-BoldItalic.ufo/glyphs/H_yphen_S_oft.glif b/tests/input/font-psf-test/source/PsfTest-BoldItalic.ufo/glyphs/H_yphen_S_oft.glif
new file mode 100644
index 0000000..2f651fa
--- /dev/null
+++ b/tests/input/font-psf-test/source/PsfTest-BoldItalic.ufo/glyphs/H_yphen_S_oft.glif
@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="Hyphen_Soft" format="2">
+ <advance width="875"/>
+ <unicode hex="00AD"/>
+ <anchor x="665" y="1100" name="U"/>
+ <outline>
+ <component base="HyphenMinus"/>
+ </outline>
+</glyph>
diff --git a/tests/input/font-psf-test/source/PsfTest-BoldItalic.ufo/glyphs/L_T_S_gn.glif b/tests/input/font-psf-test/source/PsfTest-BoldItalic.ufo/glyphs/L_T_S_gn.glif
new file mode 100644
index 0000000..b2883d3
--- /dev/null
+++ b/tests/input/font-psf-test/source/PsfTest-BoldItalic.ufo/glyphs/L_T_S_gn.glif
@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LTSgn" format="2">
+ <advance width="1180"/>
+ <unicode hex="003C"/>
+ <outline>
+ <contour>
+ <point x="1127" y="470" type="line"/>
+ <point x="510" y="713" type="line"/>
+ <point x="1253" y="975" type="line"/>
+ <point x="1309" y="1203" type="line"/>
+ <point x="253" y="817" type="line"/>
+ <point x="206" y="629" type="line"/>
+ <point x="1070" y="243" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/input/font-psf-test/source/PsfTest-BoldItalic.ufo/glyphs/L_ftC_urlyB_rac.glif b/tests/input/font-psf-test/source/PsfTest-BoldItalic.ufo/glyphs/L_ftC_urlyB_rac.glif
new file mode 100644
index 0000000..c92f889
--- /dev/null
+++ b/tests/input/font-psf-test/source/PsfTest-BoldItalic.ufo/glyphs/L_ftC_urlyB_rac.glif
@@ -0,0 +1,50 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LftCurlyBrac" format="2">
+ <advance width="1020"/>
+ <unicode hex="007B"/>
+ <outline>
+ <contour>
+ <point x="790" y="-177" type="line"/>
+ <point x="717" y="-149"/>
+ <point x="597" y="-129"/>
+ <point x="597" y="-79" type="curve" smooth="yes"/>
+ <point x="597" y="16"/>
+ <point x="695" y="378"/>
+ <point x="695" y="435" type="curve" smooth="yes"/>
+ <point x="695" y="476"/>
+ <point x="574" y="568"/>
+ <point x="574" y="605" type="curve" smooth="yes"/>
+ <point x="574" y="644"/>
+ <point x="742" y="733"/>
+ <point x="776" y="777" type="curve" smooth="yes"/>
+ <point x="803" y="812"/>
+ <point x="908" y="1276"/>
+ <point x="953" y="1317" type="curve" smooth="yes"/>
+ <point x="975" y="1337"/>
+ <point x="1090" y="1376"/>
+ <point x="1157" y="1395" type="curve"/>
+ <point x="1165" y="1624" type="line"/>
+ <point x="1031" y="1597"/>
+ <point x="827" y="1546"/>
+ <point x="768" y="1500" type="curve" smooth="yes"/>
+ <point x="677" y="1428"/>
+ <point x="542" y="843"/>
+ <point x="512" y="812" type="curve" smooth="yes"/>
+ <point x="472" y="770"/>
+ <point x="260" y="659"/>
+ <point x="260" y="601" type="curve" smooth="yes"/>
+ <point x="260" y="540"/>
+ <point x="412" y="434"/>
+ <point x="412" y="399" type="curve" smooth="yes"/>
+ <point x="412" y="337"/>
+ <point x="311" y="-52"/>
+ <point x="311" y="-216" type="curve" smooth="yes"/>
+ <point x="311" y="-248"/>
+ <point x="315" y="-271"/>
+ <point x="324" y="-282" type="curve" smooth="yes"/>
+ <point x="362" y="-330"/>
+ <point x="554" y="-379"/>
+ <point x="683" y="-406" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/input/font-psf-test/source/PsfTest-BoldItalic.ufo/glyphs/L_ftP_aren.glif b/tests/input/font-psf-test/source/PsfTest-BoldItalic.ufo/glyphs/L_ftP_aren.glif
new file mode 100644
index 0000000..42e4531
--- /dev/null
+++ b/tests/input/font-psf-test/source/PsfTest-BoldItalic.ufo/glyphs/L_ftP_aren.glif
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LftParen" format="2">
+ <advance width="840"/>
+ <unicode hex="0028"/>
+ <outline>
+ <contour>
+ <point x="899" y="1624" type="line"/>
+ <point x="586" y="1430"/>
+ <point x="317" y="1081"/>
+ <point x="209" y="649" type="curve" smooth="yes"/>
+ <point x="177" y="521"/>
+ <point x="161" y="397"/>
+ <point x="161" y="277" type="curve" smooth="yes"/>
+ <point x="161" y="20"/>
+ <point x="234" y="-214"/>
+ <point x="373" y="-406" type="curve"/>
+ <point x="565" y="-198" type="line"/>
+ <point x="479" y="-42"/>
+ <point x="436" y="130"/>
+ <point x="436" y="315" type="curve" smooth="yes"/>
+ <point x="436" y="422"/>
+ <point x="450" y="534"/>
+ <point x="479" y="649" type="curve" smooth="yes"/>
+ <point x="559" y="972"/>
+ <point x="715" y="1216"/>
+ <point x="966" y="1411" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/input/font-psf-test/source/PsfTest-BoldItalic.ufo/glyphs/L_ftS_qrB_rac.glif b/tests/input/font-psf-test/source/PsfTest-BoldItalic.ufo/glyphs/L_ftS_qrB_rac.glif
new file mode 100644
index 0000000..db76a2d
--- /dev/null
+++ b/tests/input/font-psf-test/source/PsfTest-BoldItalic.ufo/glyphs/L_ftS_qrB_rac.glif
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LftSqrBrac" format="2">
+ <advance width="830"/>
+ <unicode hex="005B"/>
+ <outline>
+ <contour>
+ <point x="553" y="-406" type="line"/>
+ <point x="605" y="-198" type="line"/>
+ <point x="365" y="-198" type="line"/>
+ <point x="753" y="1376" type="line"/>
+ <point x="993" y="1376" type="line"/>
+ <point x="1044" y="1584" type="line"/>
+ <point x="524" y="1584" type="line"/>
+ <point x="33" y="-406" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/input/font-psf-test/source/PsfTest-BoldItalic.ufo/glyphs/L_owL_ine.glif b/tests/input/font-psf-test/source/PsfTest-BoldItalic.ufo/glyphs/L_owL_ine.glif
new file mode 100644
index 0000000..de8a991
--- /dev/null
+++ b/tests/input/font-psf-test/source/PsfTest-BoldItalic.ufo/glyphs/L_owL_ine.glif
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LowLine" format="2">
+ <advance width="1254"/>
+ <unicode hex="005F"/>
+ <outline>
+ <contour>
+ <point x="-146" y="-347" type="line"/>
+ <point x="1127" y="-347" type="line"/>
+ <point x="1179" y="-139" type="line"/>
+ <point x="-94" y="-139" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/input/font-psf-test/source/PsfTest-BoldItalic.ufo/glyphs/L_tnC_apA_.glif b/tests/input/font-psf-test/source/PsfTest-BoldItalic.ufo/glyphs/L_tnC_apA_.glif
new file mode 100644
index 0000000..592502c
--- /dev/null
+++ b/tests/input/font-psf-test/source/PsfTest-BoldItalic.ufo/glyphs/L_tnC_apA_.glif
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnCapA" format="2">
+ <advance width="1465"/>
+ <unicode hex="0041"/>
+ <anchor x="1215" y="0" name="H"/>
+ <anchor x="647" y="-100" name="L"/>
+ <anchor x="1435" y="0" name="O"/>
+ <anchor x="1054" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="1055" y="0" type="line"/>
+ <point x="1338" y="0" type="line"/>
+ <point x="1322" y="79"/>
+ <point x="1312" y="166"/>
+ <point x="1295" y="351" type="curve" smooth="yes"/>
+ <point x="1198" y="1445" type="line"/>
+ <point x="842" y="1445" type="line"/>
+ <point x="199" y="351" type="line" smooth="yes"/>
+ <point x="89" y="164"/>
+ <point x="37" y="80"/>
+ <point x="-18" y="0" type="curve"/>
+ <point x="290" y="0" type="line"/>
+ <point x="487" y="351" type="line"/>
+ <point x="1031" y="351" type="line"/>
+ </contour>
+ <contour>
+ <point x="973" y="1216" type="line"/>
+ <point x="1016" y="564" type="line"/>
+ <point x="606" y="564" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/input/font-psf-test/source/PsfTest-BoldItalic.ufo/glyphs/L_tnC_apA_D_iaer.glif b/tests/input/font-psf-test/source/PsfTest-BoldItalic.ufo/glyphs/L_tnC_apA_D_iaer.glif
new file mode 100644
index 0000000..17600b4
--- /dev/null
+++ b/tests/input/font-psf-test/source/PsfTest-BoldItalic.ufo/glyphs/L_tnC_apA_D_iaer.glif
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnCapADiaer" format="2">
+ <advance width="1465"/>
+ <unicode hex="00C4"/>
+ <anchor x="1215" y="0" name="H"/>
+ <anchor x="647" y="-100" name="L"/>
+ <anchor x="1435" y="0" name="O"/>
+ <anchor x="1176" y="2015" name="U"/>
+ <outline>
+ <component base="LtnCapA"/>
+ <component base="CombDiaer" xOffset="1419" yOffset="430"/>
+ </outline>
+</glyph>
diff --git a/tests/input/font-psf-test/source/PsfTest-BoldItalic.ufo/glyphs/L_tnC_apB_.glif b/tests/input/font-psf-test/source/PsfTest-BoldItalic.ufo/glyphs/L_tnC_apB_.glif
new file mode 100644
index 0000000..2b14150
--- /dev/null
+++ b/tests/input/font-psf-test/source/PsfTest-BoldItalic.ufo/glyphs/L_tnC_apB_.glif
@@ -0,0 +1,62 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnCapB" format="2">
+ <advance width="1367"/>
+ <unicode hex="0042"/>
+ <anchor x="585" y="-100" name="L"/>
+ <anchor x="992" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="698" y="1236" type="line"/>
+ <point x="735" y="1237"/>
+ <point x="791" y="1240"/>
+ <point x="860" y="1240" type="curve" smooth="yes"/>
+ <point x="1021" y="1240"/>
+ <point x="1101" y="1179"/>
+ <point x="1101" y="1087" type="curve" smooth="yes"/>
+ <point x="1101" y="932"/>
+ <point x="962" y="866"/>
+ <point x="770" y="866" type="curve" smooth="yes"/>
+ <point x="605" y="866" type="line"/>
+ </contour>
+ <contour>
+ <point x="217" y="450" type="line"/>
+ <point x="168" y="254"/>
+ <point x="124" y="79"/>
+ <point x="90" y="0" type="curve"/>
+ <point x="161" y="-3"/>
+ <point x="368" y="-10"/>
+ <point x="598" y="-10" type="curve" smooth="yes"/>
+ <point x="1055" y="-10"/>
+ <point x="1298" y="206"/>
+ <point x="1298" y="508" type="curve" smooth="yes"/>
+ <point x="1298" y="673"/>
+ <point x="1188" y="759"/>
+ <point x="1072" y="792" type="curve"/>
+ <point x="1254" y="848"/>
+ <point x="1388" y="956"/>
+ <point x="1388" y="1155" type="curve" smooth="yes"/>
+ <point x="1388" y="1359"/>
+ <point x="1181" y="1455"/>
+ <point x="897" y="1455" type="curve" smooth="yes"/>
+ <point x="704" y="1455"/>
+ <point x="549" y="1451"/>
+ <point x="450" y="1445" type="curve"/>
+ <point x="445" y="1366"/>
+ <point x="399" y="1182"/>
+ <point x="351" y="990" type="curve" smooth="yes"/>
+ </contour>
+ <contour>
+ <point x="552" y="651" type="line"/>
+ <point x="745" y="651" type="line" smooth="yes"/>
+ <point x="927" y="651"/>
+ <point x="1019" y="577"/>
+ <point x="1019" y="468" type="curve" smooth="yes"/>
+ <point x="1019" y="295"/>
+ <point x="879" y="213"/>
+ <point x="675" y="213" type="curve" smooth="yes"/>
+ <point x="575" y="213"/>
+ <point x="476" y="216"/>
+ <point x="444" y="218" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/input/font-psf-test/source/PsfTest-BoldItalic.ufo/glyphs/L_tnC_apC_.glif b/tests/input/font-psf-test/source/PsfTest-BoldItalic.ufo/glyphs/L_tnC_apC_.glif
new file mode 100644
index 0000000..569eba9
--- /dev/null
+++ b/tests/input/font-psf-test/source/PsfTest-BoldItalic.ufo/glyphs/L_tnC_apC_.glif
@@ -0,0 +1,38 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnCapC" format="2">
+ <advance width="1357"/>
+ <unicode hex="0043"/>
+ <anchor x="685" y="0" name="H"/>
+ <anchor x="660" y="-100" name="L"/>
+ <anchor x="1067" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="1286" y="391" type="line"/>
+ <point x="1149" y="280"/>
+ <point x="966" y="218"/>
+ <point x="816" y="218" type="curve" smooth="yes"/>
+ <point x="594" y="218"/>
+ <point x="472" y="349"/>
+ <point x="472" y="588" type="curve" smooth="yes"/>
+ <point x="472" y="922"/>
+ <point x="690" y="1230"/>
+ <point x="1039" y="1230" type="curve" smooth="yes"/>
+ <point x="1170" y="1230"/>
+ <point x="1298" y="1188"/>
+ <point x="1385" y="1093" type="curve"/>
+ <point x="1515" y="1331" type="line"/>
+ <point x="1408" y="1418"/>
+ <point x="1247" y="1470"/>
+ <point x="1073" y="1470" type="curve" smooth="yes"/>
+ <point x="545" y="1470"/>
+ <point x="191" y="1032"/>
+ <point x="191" y="544" type="curve" smooth="yes"/>
+ <point x="191" y="210"/>
+ <point x="404" y="-25"/>
+ <point x="750" y="-25" type="curve" smooth="yes"/>
+ <point x="921" y="-25"/>
+ <point x="1124" y="27"/>
+ <point x="1271" y="124" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/input/font-psf-test/source/PsfTest-BoldItalic.ufo/glyphs/L_tnC_apD_.glif b/tests/input/font-psf-test/source/PsfTest-BoldItalic.ufo/glyphs/L_tnC_apD_.glif
new file mode 100644
index 0000000..093d346
--- /dev/null
+++ b/tests/input/font-psf-test/source/PsfTest-BoldItalic.ufo/glyphs/L_tnC_apD_.glif
@@ -0,0 +1,51 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnCapD" format="2">
+ <advance width="1465"/>
+ <unicode hex="0044"/>
+ <anchor x="690" y="-100" name="L"/>
+ <anchor x="1122" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="217" y="450" type="line" smooth="yes"/>
+ <point x="167" y="251"/>
+ <point x="124" y="79"/>
+ <point x="90" y="0" type="curve"/>
+ <point x="90" y="0"/>
+ <point x="431" y="-10"/>
+ <point x="566" y="-10" type="curve" smooth="yes"/>
+ <point x="1036" y="-10"/>
+ <point x="1361" y="195"/>
+ <point x="1471" y="648" type="curve" smooth="yes"/>
+ <point x="1494" y="742"/>
+ <point x="1505" y="827"/>
+ <point x="1505" y="902" type="curve" smooth="yes"/>
+ <point x="1505" y="1325"/>
+ <point x="1172" y="1455"/>
+ <point x="912" y="1455" type="curve" smooth="yes"/>
+ <point x="769" y="1455"/>
+ <point x="540" y="1451"/>
+ <point x="450" y="1445" type="curve"/>
+ <point x="445" y="1371"/>
+ <point x="404" y="1205"/>
+ <point x="359" y="1024" type="curve" smooth="yes"/>
+ </contour>
+ <contour>
+ <point x="696" y="1229" type="line"/>
+ <point x="738" y="1231"/>
+ <point x="809" y="1234"/>
+ <point x="864" y="1234" type="curve" smooth="yes"/>
+ <point x="1077" y="1234"/>
+ <point x="1212" y="1104"/>
+ <point x="1212" y="871" type="curve" smooth="yes"/>
+ <point x="1212" y="805"/>
+ <point x="1201" y="731"/>
+ <point x="1181" y="647" type="curve" smooth="yes"/>
+ <point x="1108" y="346"/>
+ <point x="930" y="219"/>
+ <point x="647" y="219" type="curve" smooth="yes"/>
+ <point x="568" y="219"/>
+ <point x="485" y="225"/>
+ <point x="447" y="229" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/input/font-psf-test/source/PsfTest-BoldItalic.ufo/glyphs/L_tnC_apE_.glif b/tests/input/font-psf-test/source/PsfTest-BoldItalic.ufo/glyphs/L_tnC_apE_.glif
new file mode 100644
index 0000000..8e7a0a1
--- /dev/null
+++ b/tests/input/font-psf-test/source/PsfTest-BoldItalic.ufo/glyphs/L_tnC_apE_.glif
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnCapE" format="2">
+ <advance width="1192"/>
+ <unicode hex="0045"/>
+ <anchor x="550" y="0" name="H"/>
+ <anchor x="525" y="-100" name="L"/>
+ <anchor x="944" y="0" name="O"/>
+ <anchor x="1487" y="1200" name="R"/>
+ <anchor x="932" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="605" y="866" type="line"/>
+ <point x="693" y="1217" type="line"/>
+ <point x="1315" y="1217" type="line"/>
+ <point x="1372" y="1445" type="line"/>
+ <point x="450" y="1445" type="line"/>
+ <point x="444" y="1366"/>
+ <point x="406" y="1210"/>
+ <point x="358" y="1015" type="curve" smooth="yes"/>
+ <point x="212" y="431" type="line" smooth="yes"/>
+ <point x="163" y="236"/>
+ <point x="123" y="79"/>
+ <point x="90" y="0" type="curve"/>
+ <point x="1042" y="0" type="line"/>
+ <point x="1102" y="243" type="line"/>
+ <point x="1021" y="229"/>
+ <point x="895" y="228"/>
+ <point x="704" y="228" type="curve" smooth="yes"/>
+ <point x="446" y="228" type="line"/>
+ <point x="550" y="644" type="line"/>
+ <point x="1097" y="644" type="line"/>
+ <point x="1152" y="866" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/input/font-psf-test/source/PsfTest-BoldItalic.ufo/glyphs/L_tnC_apF_.glif b/tests/input/font-psf-test/source/PsfTest-BoldItalic.ufo/glyphs/L_tnC_apF_.glif
new file mode 100644
index 0000000..df3370c
--- /dev/null
+++ b/tests/input/font-psf-test/source/PsfTest-BoldItalic.ufo/glyphs/L_tnC_apF_.glif
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnCapF" format="2">
+ <advance width="1180"/>
+ <unicode hex="0046"/>
+ <anchor x="545" y="-100" name="L"/>
+ <anchor x="952" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="602" y="851" type="line"/>
+ <point x="693" y="1217" type="line"/>
+ <point x="1333" y="1217" type="line"/>
+ <point x="1390" y="1445" type="line"/>
+ <point x="450" y="1445" type="line"/>
+ <point x="445" y="1366"/>
+ <point x="405" y="1205"/>
+ <point x="356" y="1010" type="curve" smooth="yes"/>
+ <point x="212" y="431" type="line" smooth="yes"/>
+ <point x="163" y="236"/>
+ <point x="123" y="79"/>
+ <point x="90" y="0" type="curve"/>
+ <point x="405" y="0" type="line"/>
+ <point x="407" y="72"/>
+ <point x="444" y="220"/>
+ <point x="490" y="404" type="curve" smooth="yes"/>
+ <point x="546" y="629" type="line"/>
+ <point x="1101" y="629" type="line"/>
+ <point x="1157" y="851" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/input/font-psf-test/source/PsfTest-BoldItalic.ufo/glyphs/L_tnC_apG_.glif b/tests/input/font-psf-test/source/PsfTest-BoldItalic.ufo/glyphs/L_tnC_apG_.glif
new file mode 100644
index 0000000..7d36953
--- /dev/null
+++ b/tests/input/font-psf-test/source/PsfTest-BoldItalic.ufo/glyphs/L_tnC_apG_.glif
@@ -0,0 +1,48 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnCapG" format="2">
+ <advance width="1452"/>
+ <unicode hex="0047"/>
+ <anchor x="747" y="0" name="H"/>
+ <anchor x="722" y="-100" name="L"/>
+ <anchor x="1129" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="1480" y="767" type="line"/>
+ <point x="910" y="767" type="line"/>
+ <point x="855" y="544" type="line"/>
+ <point x="1170" y="544" type="line"/>
+ <point x="1104" y="271" type="line"/>
+ <point x="1015" y="231"/>
+ <point x="916" y="218"/>
+ <point x="805" y="218" type="curve" smooth="yes"/>
+ <point x="593" y="218"/>
+ <point x="475" y="352"/>
+ <point x="475" y="567" type="curve" smooth="yes"/>
+ <point x="475" y="633"/>
+ <point x="484" y="708"/>
+ <point x="505" y="789" type="curve" smooth="yes"/>
+ <point x="581" y="1079"/>
+ <point x="802" y="1230"/>
+ <point x="1067" y="1230" type="curve" smooth="yes"/>
+ <point x="1220" y="1230"/>
+ <point x="1334" y="1193"/>
+ <point x="1449" y="1096" type="curve"/>
+ <point x="1594" y="1332" type="line"/>
+ <point x="1447" y="1437"/>
+ <point x="1275" y="1470"/>
+ <point x="1094" y="1470" type="curve" smooth="yes"/>
+ <point x="709" y="1470"/>
+ <point x="345" y="1257"/>
+ <point x="227" y="783" type="curve" smooth="yes"/>
+ <point x="205" y="694"/>
+ <point x="194" y="611"/>
+ <point x="194" y="534" type="curve" smooth="yes"/>
+ <point x="194" y="176"/>
+ <point x="419" y="-25"/>
+ <point x="768" y="-25" type="curve" smooth="yes"/>
+ <point x="940" y="-25"/>
+ <point x="1105" y="10"/>
+ <point x="1325" y="133" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/input/font-psf-test/source/PsfTest-BoldItalic.ufo/glyphs/L_tnC_apH_.glif b/tests/input/font-psf-test/source/PsfTest-BoldItalic.ufo/glyphs/L_tnC_apH_.glif
new file mode 100644
index 0000000..a49f5fb
--- /dev/null
+++ b/tests/input/font-psf-test/source/PsfTest-BoldItalic.ufo/glyphs/L_tnC_apH_.glif
@@ -0,0 +1,40 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnCapH" format="2">
+ <advance width="1495"/>
+ <unicode hex="0048"/>
+ <anchor x="245" y="0" name="H"/>
+ <anchor x="660" y="-100" name="L"/>
+ <anchor x="1067" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="1340" y="1445" type="line"/>
+ <point x="1192" y="851" type="line"/>
+ <point x="602" y="851" type="line"/>
+ <point x="750" y="1445" type="line"/>
+ <point x="450" y="1445" type="line"/>
+ <point x="445" y="1366"/>
+ <point x="408" y="1215"/>
+ <point x="359" y="1020" type="curve" smooth="yes"/>
+ <point x="211" y="426" type="line" smooth="yes"/>
+ <point x="162" y="231"/>
+ <point x="124" y="79"/>
+ <point x="90" y="0" type="curve"/>
+ <point x="90" y="0"/>
+ <point x="390" y="0"/>
+ <point x="390" y="0" type="curve"/>
+ <point x="546" y="629" type="line"/>
+ <point x="1136" y="629" type="line"/>
+ <point x="980" y="0" type="line"/>
+ <point x="980" y="0"/>
+ <point x="1280" y="0"/>
+ <point x="1280" y="0" type="curve"/>
+ <point x="1284" y="79"/>
+ <point x="1322" y="231"/>
+ <point x="1371" y="426" type="curve" smooth="yes"/>
+ <point x="1519" y="1020" type="line" smooth="yes"/>
+ <point x="1567" y="1215"/>
+ <point x="1605" y="1366"/>
+ <point x="1640" y="1445" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/input/font-psf-test/source/PsfTest-BoldItalic.ufo/glyphs/L_tnC_apI_.glif b/tests/input/font-psf-test/source/PsfTest-BoldItalic.ufo/glyphs/L_tnC_apI_.glif
new file mode 100644
index 0000000..fc059de
--- /dev/null
+++ b/tests/input/font-psf-test/source/PsfTest-BoldItalic.ufo/glyphs/L_tnC_apI_.glif
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnCapI" format="2">
+ <advance width="1025"/>
+ <unicode hex="0049"/>
+ <anchor x="460" y="0" name="H"/>
+ <anchor x="431" y="-100" name="L"/>
+ <anchor x="652" y="0" name="O"/>
+ <anchor x="1254" y="1200" name="R"/>
+ <anchor x="842" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="430" y="1445" type="line"/>
+ <point x="379" y="1242" type="line"/>
+ <point x="619" y="1242" type="line"/>
+ <point x="360" y="203" type="line"/>
+ <point x="120" y="203" type="line"/>
+ <point x="70" y="0" type="line"/>
+ <point x="835" y="0" type="line"/>
+ <point x="885" y="203" type="line"/>
+ <point x="645" y="203" type="line"/>
+ <point x="904" y="1242" type="line"/>
+ <point x="1144" y="1242" type="line"/>
+ <point x="1195" y="1445" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/input/font-psf-test/source/PsfTest-BoldItalic.ufo/glyphs/L_tnC_apJ_.glif b/tests/input/font-psf-test/source/PsfTest-BoldItalic.ufo/glyphs/L_tnC_apJ_.glif
new file mode 100644
index 0000000..6a3a604
--- /dev/null
+++ b/tests/input/font-psf-test/source/PsfTest-BoldItalic.ufo/glyphs/L_tnC_apJ_.glif
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnCapJ" format="2">
+ <advance width="1010"/>
+ <unicode hex="004A"/>
+ <anchor x="330" y="-100" name="L"/>
+ <anchor x="1027" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="855" y="1445" type="line"/>
+ <point x="842" y="1340"/>
+ <point x="799" y="1163"/>
+ <point x="751" y="970" type="curve" smooth="yes"/>
+ <point x="647" y="552" type="line" smooth="yes"/>
+ <point x="602" y="370"/>
+ <point x="516" y="225"/>
+ <point x="341" y="225" type="curve" smooth="yes"/>
+ <point x="260" y="225"/>
+ <point x="159" y="267"/>
+ <point x="104" y="344" type="curve"/>
+ <point x="-8" y="89" type="line"/>
+ <point x="51" y="19"/>
+ <point x="191" y="-25"/>
+ <point x="326" y="-25" type="curve" smooth="yes"/>
+ <point x="611" y="-25"/>
+ <point x="826" y="128"/>
+ <point x="927" y="530" type="curve" smooth="yes"/>
+ <point x="947" y="612"/>
+ <point x="1155" y="1445"/>
+ <point x="1155" y="1445" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/input/font-psf-test/source/PsfTest-BoldItalic.ufo/glyphs/L_tnC_apK_.glif b/tests/input/font-psf-test/source/PsfTest-BoldItalic.ufo/glyphs/L_tnC_apK_.glif
new file mode 100644
index 0000000..44d4d68
--- /dev/null
+++ b/tests/input/font-psf-test/source/PsfTest-BoldItalic.ufo/glyphs/L_tnC_apK_.glif
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnCapK" format="2">
+ <advance width="1410"/>
+ <unicode hex="004B"/>
+ <anchor x="260" y="0" name="H"/>
+ <anchor x="655" y="-100" name="L"/>
+ <anchor x="1047" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="750" y="1445" type="line"/>
+ <point x="450" y="1445" type="line"/>
+ <point x="444" y="1366"/>
+ <point x="406" y="1210"/>
+ <point x="358" y="1015" type="curve" smooth="yes"/>
+ <point x="212" y="431" type="line" smooth="yes"/>
+ <point x="163" y="236"/>
+ <point x="123" y="79"/>
+ <point x="90" y="0" type="curve"/>
+ <point x="390" y="0" type="line"/>
+ </contour>
+ <contour>
+ <point x="1244" y="1445" type="line"/>
+ <point x="461" y="697" type="line"/>
+ <point x="634" y="738" type="line"/>
+ <point x="758" y="724" type="line"/>
+ <point x="1580" y="1445" type="line"/>
+ </contour>
+ <contour>
+ <point x="509" y="724" type="line"/>
+ <point x="950" y="0" type="line"/>
+ <point x="1300" y="0" type="line"/>
+ <point x="738" y="801" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/input/font-psf-test/source/PsfTest-BoldItalic.ufo/glyphs/L_tnC_apL_.glif b/tests/input/font-psf-test/source/PsfTest-BoldItalic.ufo/glyphs/L_tnC_apL_.glif
new file mode 100644
index 0000000..f8d6959
--- /dev/null
+++ b/tests/input/font-psf-test/source/PsfTest-BoldItalic.ufo/glyphs/L_tnC_apL_.glif
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnCapL" format="2">
+ <advance width="1110"/>
+ <unicode hex="004C"/>
+ <anchor x="560" y="0" name="H"/>
+ <anchor x="535" y="-100" name="L"/>
+ <anchor x="890" y="1200" name="R"/>
+ <anchor x="942" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="446" y="228" type="line"/>
+ <point x="750" y="1445" type="line"/>
+ <point x="450" y="1445" type="line"/>
+ <point x="444" y="1366"/>
+ <point x="406" y="1210"/>
+ <point x="358" y="1015" type="curve" smooth="yes"/>
+ <point x="212" y="431" type="line" smooth="yes"/>
+ <point x="163" y="236"/>
+ <point x="123" y="79"/>
+ <point x="90" y="0" type="curve"/>
+ <point x="1025" y="0" type="line"/>
+ <point x="1085" y="243" type="line"/>
+ <point x="1005" y="229"/>
+ <point x="851" y="228"/>
+ <point x="662" y="228" type="curve" smooth="yes"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/input/font-psf-test/source/PsfTest-BoldItalic.ufo/glyphs/L_tnC_apM_.glif b/tests/input/font-psf-test/source/PsfTest-BoldItalic.ufo/glyphs/L_tnC_apM_.glif
new file mode 100644
index 0000000..67d1463
--- /dev/null
+++ b/tests/input/font-psf-test/source/PsfTest-BoldItalic.ufo/glyphs/L_tnC_apM_.glif
@@ -0,0 +1,38 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnCapM" format="2">
+ <advance width="1835"/>
+ <unicode hex="004D"/>
+ <anchor x="830" y="-100" name="L"/>
+ <anchor x="1237" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="919" y="272" type="line"/>
+ <point x="865" y="1445" type="line"/>
+ <point x="615" y="1445" type="line"/>
+ <point x="664" y="1158" type="line"/>
+ <point x="710" y="0" type="line"/>
+ <point x="1005" y="0" type="line"/>
+ <point x="1625" y="1158" type="line"/>
+ <point x="1817" y="1445" type="line"/>
+ <point x="1550" y="1445" type="line"/>
+ </contour>
+ <contour>
+ <point x="520" y="1445" type="line"/>
+ <point x="520" y="1445"/>
+ <point x="164" y="196"/>
+ <point x="90" y="0" type="curve"/>
+ <point x="360" y="0" type="line"/>
+ <point x="686" y="1193" type="line"/>
+ <point x="785" y="1445" type="line"/>
+ </contour>
+ <contour>
+ <point x="1630" y="0" type="line"/>
+ <point x="1649" y="196"/>
+ <point x="1910" y="1445"/>
+ <point x="1910" y="1445" type="curve"/>
+ <point x="1640" y="1445" type="line"/>
+ <point x="1622" y="1193" type="line"/>
+ <point x="1360" y="0" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/input/font-psf-test/source/PsfTest-BoldItalic.ufo/glyphs/L_tnC_apN_.glif b/tests/input/font-psf-test/source/PsfTest-BoldItalic.ufo/glyphs/L_tnC_apN_.glif
new file mode 100644
index 0000000..838490a
--- /dev/null
+++ b/tests/input/font-psf-test/source/PsfTest-BoldItalic.ufo/glyphs/L_tnC_apN_.glif
@@ -0,0 +1,37 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnCapN" format="2">
+ <advance width="1525"/>
+ <unicode hex="004E"/>
+ <anchor x="1180" y="0" name="H"/>
+ <anchor x="680" y="-100" name="L"/>
+ <anchor x="1087" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="506" y="1297" type="line"/>
+ <point x="1035" y="0" type="line"/>
+ <point x="1253" y="148" type="line"/>
+ <point x="725" y="1445" type="line"/>
+ </contour>
+ <contour>
+ <point x="1035" y="0" type="line"/>
+ <point x="1305" y="0" type="line"/>
+ <point x="1558" y="1015" type="line" smooth="yes"/>
+ <point x="1606" y="1210"/>
+ <point x="1646" y="1366"/>
+ <point x="1680" y="1445" type="curve"/>
+ <point x="1395" y="1445" type="line"/>
+ </contour>
+ <contour>
+ <point x="725" y="1445" type="line"/>
+ <point x="440" y="1445" type="line"/>
+ <point x="434" y="1366"/>
+ <point x="396" y="1210"/>
+ <point x="348" y="1015" type="curve" smooth="yes"/>
+ <point x="202" y="431" type="line" smooth="yes"/>
+ <point x="153" y="236"/>
+ <point x="113" y="79"/>
+ <point x="80" y="0" type="curve"/>
+ <point x="365" y="0" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/input/font-psf-test/source/PsfTest-BoldItalic.ufo/glyphs/L_tnC_apO_.glif b/tests/input/font-psf-test/source/PsfTest-BoldItalic.ufo/glyphs/L_tnC_apO_.glif
new file mode 100644
index 0000000..4410e20
--- /dev/null
+++ b/tests/input/font-psf-test/source/PsfTest-BoldItalic.ufo/glyphs/L_tnC_apO_.glif
@@ -0,0 +1,40 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnCapO" format="2">
+ <advance width="1480"/>
+ <unicode hex="004F"/>
+ <anchor x="680" y="0" name="H"/>
+ <anchor x="655" y="-100" name="L"/>
+ <anchor x="916" y="0" name="O"/>
+ <anchor x="1720" y="1200" name="R"/>
+ <anchor x="1062" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="754" y="218" type="curve" smooth="yes"/>
+ <point x="580" y="218"/>
+ <point x="471" y="345"/>
+ <point x="471" y="568" type="curve" smooth="yes"/>
+ <point x="471" y="922"/>
+ <point x="664" y="1228"/>
+ <point x="966" y="1228" type="curve" smooth="yes"/>
+ <point x="1134" y="1228"/>
+ <point x="1237" y="1106"/>
+ <point x="1237" y="891" type="curve" smooth="yes"/>
+ <point x="1237" y="540"/>
+ <point x="1060" y="218"/>
+ </contour>
+ <contour>
+ <point x="1519" y="911" type="curve" smooth="yes"/>
+ <point x="1519" y="1249"/>
+ <point x="1350" y="1470"/>
+ <point x="1026" y="1470" type="curve" smooth="yes"/>
+ <point x="510" y="1470"/>
+ <point x="191" y="1010"/>
+ <point x="191" y="539" type="curve" smooth="yes"/>
+ <point x="191" y="199"/>
+ <point x="401" y="-25"/>
+ <point x="693" y="-25" type="curve" smooth="yes"/>
+ <point x="1121" y="-25"/>
+ <point x="1519" y="337"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/input/font-psf-test/source/PsfTest-BoldItalic.ufo/glyphs/L_tnC_apP_.glif b/tests/input/font-psf-test/source/PsfTest-BoldItalic.ufo/glyphs/L_tnC_apP_.glif
new file mode 100644
index 0000000..b0d40c0
--- /dev/null
+++ b/tests/input/font-psf-test/source/PsfTest-BoldItalic.ufo/glyphs/L_tnC_apP_.glif
@@ -0,0 +1,50 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnCapP" format="2">
+ <advance width="1255"/>
+ <unicode hex="0050"/>
+ <anchor x="600" y="-100" name="L"/>
+ <anchor x="970" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="519" y="518" type="line"/>
+ <point x="582" y="511"/>
+ <point x="661" y="508"/>
+ <point x="734" y="508" type="curve" smooth="yes"/>
+ <point x="1118" y="508"/>
+ <point x="1393" y="718"/>
+ <point x="1393" y="1076" type="curve" smooth="yes"/>
+ <point x="1393" y="1306"/>
+ <point x="1215" y="1455"/>
+ <point x="940" y="1455" type="curve" smooth="yes"/>
+ <point x="727" y="1455"/>
+ <point x="450" y="1445"/>
+ <point x="450" y="1445" type="curve"/>
+ <point x="445" y="1366"/>
+ <point x="400" y="1184"/>
+ <point x="351" y="990" type="curve" smooth="yes"/>
+ <point x="212" y="431" type="line" smooth="yes"/>
+ <point x="164" y="237"/>
+ <point x="124" y="79"/>
+ <point x="90" y="0" type="curve"/>
+ <point x="405" y="0" type="line"/>
+ <point x="410" y="77"/>
+ <point x="448" y="235"/>
+ <point x="497" y="431" type="curve" smooth="yes"/>
+ </contour>
+ <contour>
+ <point x="696" y="1228" type="line"/>
+ <point x="752" y="1231"/>
+ <point x="781" y="1233"/>
+ <point x="849" y="1233" type="curve" smooth="yes"/>
+ <point x="1020" y="1233"/>
+ <point x="1103" y="1135"/>
+ <point x="1103" y="1020" type="curve" smooth="yes"/>
+ <point x="1103" y="827"/>
+ <point x="965" y="723"/>
+ <point x="758" y="723" type="curve" smooth="yes"/>
+ <point x="696" y="723"/>
+ <point x="614" y="726"/>
+ <point x="572" y="733" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/input/font-psf-test/source/PsfTest-BoldItalic.ufo/glyphs/L_tnC_apQ_.glif b/tests/input/font-psf-test/source/PsfTest-BoldItalic.ufo/glyphs/L_tnC_apQ_.glif
new file mode 100644
index 0000000..7013e5f
--- /dev/null
+++ b/tests/input/font-psf-test/source/PsfTest-BoldItalic.ufo/glyphs/L_tnC_apQ_.glif
@@ -0,0 +1,52 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnCapQ" format="2">
+ <advance width="1488"/>
+ <unicode hex="0051"/>
+ <anchor x="619" y="-270" name="L"/>
+ <anchor x="1069" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="1527" y="922" type="curve" smooth="yes"/>
+ <point x="1527" y="1259"/>
+ <point x="1324" y="1470"/>
+ <point x="1029" y="1470" type="curve" smooth="yes"/>
+ <point x="663" y="1470"/>
+ <point x="339" y="1229"/>
+ <point x="221" y="755" type="curve" smooth="yes"/>
+ <point x="201" y="673"/>
+ <point x="191" y="597"/>
+ <point x="191" y="526" type="curve" smooth="yes"/>
+ <point x="191" y="185"/>
+ <point x="410" y="-25"/>
+ <point x="696" y="-25" type="curve" smooth="yes"/>
+ <point x="743" y="-25"/>
+ <point x="787" y="-23"/>
+ <point x="838" y="-15" type="curve"/>
+ <point x="907" y="-15"/>
+ <point x="1162" y="-221"/>
+ <point x="1246" y="-221" type="curve" smooth="yes"/>
+ <point x="1310" y="-221"/>
+ <point x="1422" y="-74"/>
+ <point x="1468" y="-22" type="curve"/>
+ <point x="1331" y="-6"/>
+ <point x="1227" y="60"/>
+ <point x="1115" y="134" type="curve"/>
+ <point x="1312" y="242"/>
+ <point x="1527" y="566"/>
+ </contour>
+ <contour>
+ <point x="757" y="218" type="curve" smooth="yes"/>
+ <point x="563" y="218"/>
+ <point x="471" y="355"/>
+ <point x="471" y="558" type="curve" smooth="yes"/>
+ <point x="471" y="912"/>
+ <point x="677" y="1228"/>
+ <point x="969" y="1228" type="curve" smooth="yes"/>
+ <point x="1147" y="1228"/>
+ <point x="1246" y="1106"/>
+ <point x="1246" y="891" type="curve" smooth="yes"/>
+ <point x="1246" y="560"/>
+ <point x="1053" y="218"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/input/font-psf-test/source/PsfTest-BoldItalic.ufo/glyphs/L_tnC_apR_.glif b/tests/input/font-psf-test/source/PsfTest-BoldItalic.ufo/glyphs/L_tnC_apR_.glif
new file mode 100644
index 0000000..9133fd2
--- /dev/null
+++ b/tests/input/font-psf-test/source/PsfTest-BoldItalic.ufo/glyphs/L_tnC_apR_.glif
@@ -0,0 +1,55 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnCapR" format="2">
+ <advance width="1360"/>
+ <unicode hex="0052"/>
+ <anchor x="630" y="0" name="H"/>
+ <anchor x="605" y="-100" name="L"/>
+ <anchor x="982" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="534" y="579" type="line"/>
+ <point x="749" y="579" type="line" smooth="yes"/>
+ <point x="1071" y="579"/>
+ <point x="1378" y="761"/>
+ <point x="1378" y="1117" type="curve" smooth="yes"/>
+ <point x="1378" y="1332"/>
+ <point x="1199" y="1455"/>
+ <point x="932" y="1455" type="curve" smooth="yes"/>
+ <point x="698" y="1455"/>
+ <point x="450" y="1445"/>
+ <point x="450" y="1445" type="curve"/>
+ <point x="445" y="1366"/>
+ <point x="400" y="1184"/>
+ <point x="351" y="990" type="curve" smooth="yes"/>
+ <point x="212" y="431" type="line"/>
+ <point x="164" y="236"/>
+ <point x="124" y="79"/>
+ <point x="90" y="0" type="curve"/>
+ <point x="405" y="0" type="line"/>
+ <point x="410" y="77"/>
+ <point x="448" y="236"/>
+ <point x="497" y="431" type="curve"/>
+ </contour>
+ <contour>
+ <point x="696" y="1228" type="line"/>
+ <point x="749" y="1231"/>
+ <point x="764" y="1233"/>
+ <point x="842" y="1233" type="curve" smooth="yes"/>
+ <point x="995" y="1233"/>
+ <point x="1089" y="1167"/>
+ <point x="1089" y="1060" type="curve" smooth="yes"/>
+ <point x="1089" y="899"/>
+ <point x="956" y="792"/>
+ <point x="782" y="792" type="curve" smooth="yes"/>
+ <point x="587" y="792" type="line"/>
+ </contour>
+ <contour>
+ <point x="652" y="629" type="line"/>
+ <point x="915" y="0" type="line"/>
+ <point x="1270" y="0" type="line"/>
+ <point x="1220" y="72"/>
+ <point x="962" y="623"/>
+ <point x="936" y="680" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/input/font-psf-test/source/PsfTest-BoldItalic.ufo/glyphs/L_tnC_apS_.glif b/tests/input/font-psf-test/source/PsfTest-BoldItalic.ufo/glyphs/L_tnC_apS_.glif
new file mode 100644
index 0000000..79fe933
--- /dev/null
+++ b/tests/input/font-psf-test/source/PsfTest-BoldItalic.ufo/glyphs/L_tnC_apS_.glif
@@ -0,0 +1,50 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnCapS" format="2">
+ <advance width="1223"/>
+ <unicode hex="0053"/>
+ <anchor x="556" y="0" name="H"/>
+ <anchor x="531" y="-100" name="L"/>
+ <anchor x="938" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="1339" y="1361" type="line"/>
+ <point x="1232" y="1430"/>
+ <point x="1086" y="1470"/>
+ <point x="916" y="1470" type="curve" smooth="yes"/>
+ <point x="600" y="1470"/>
+ <point x="332" y="1333"/>
+ <point x="332" y="1053" type="curve" smooth="yes"/>
+ <point x="332" y="889"/>
+ <point x="413" y="800"/>
+ <point x="621" y="658" type="curve" smooth="yes"/>
+ <point x="829" y="516"/>
+ <point x="885" y="448"/>
+ <point x="885" y="374" type="curve" smooth="yes"/>
+ <point x="885" y="276"/>
+ <point x="772" y="218"/>
+ <point x="624" y="218" type="curve" smooth="yes"/>
+ <point x="463" y="218"/>
+ <point x="270" y="340"/>
+ <point x="184" y="461" type="curve"/>
+ <point x="67" y="189" type="line"/>
+ <point x="147" y="91"/>
+ <point x="394" y="-25"/>
+ <point x="573" y="-25" type="curve" smooth="yes"/>
+ <point x="923" y="-25"/>
+ <point x="1182" y="124"/>
+ <point x="1182" y="419" type="curve" smooth="yes"/>
+ <point x="1182" y="584"/>
+ <point x="1077" y="682"/>
+ <point x="881" y="831" type="curve" smooth="yes"/>
+ <point x="728" y="947"/>
+ <point x="628" y="1010"/>
+ <point x="628" y="1082" type="curve" smooth="yes"/>
+ <point x="628" y="1198"/>
+ <point x="790" y="1230"/>
+ <point x="877" y="1230" type="curve" smooth="yes"/>
+ <point x="1018" y="1230"/>
+ <point x="1119" y="1189"/>
+ <point x="1228" y="1099" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/input/font-psf-test/source/PsfTest-BoldItalic.ufo/glyphs/L_tnC_apT_.glif b/tests/input/font-psf-test/source/PsfTest-BoldItalic.ufo/glyphs/L_tnC_apT_.glif
new file mode 100644
index 0000000..b7aa4cd
--- /dev/null
+++ b/tests/input/font-psf-test/source/PsfTest-BoldItalic.ufo/glyphs/L_tnC_apT_.glif
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnCapT" format="2">
+ <advance width="1255"/>
+ <unicode hex="0054"/>
+ <anchor x="572" y="0" name="H"/>
+ <anchor x="547" y="-100" name="L"/>
+ <anchor x="954" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="345" y="1445" type="line"/>
+ <point x="283" y="1198" type="line"/>
+ <point x="359" y="1215"/>
+ <point x="439" y="1218"/>
+ <point x="519" y="1218" type="curve" smooth="yes"/>
+ <point x="731" y="1218" type="line"/>
+ <point x="529" y="409" type="line" smooth="yes"/>
+ <point x="483" y="224"/>
+ <point x="443" y="75"/>
+ <point x="408" y="0" type="curve"/>
+ <point x="733" y="0" type="line"/>
+ <point x="734" y="75"/>
+ <point x="768" y="224"/>
+ <point x="814" y="409" type="curve" smooth="yes"/>
+ <point x="1016" y="1218" type="line"/>
+ <point x="1232" y="1218" type="line" smooth="yes"/>
+ <point x="1313" y="1218"/>
+ <point x="1390" y="1215"/>
+ <point x="1458" y="1198" type="curve"/>
+ <point x="1520" y="1445" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/input/font-psf-test/source/PsfTest-BoldItalic.ufo/glyphs/L_tnC_apU_.glif b/tests/input/font-psf-test/source/PsfTest-BoldItalic.ufo/glyphs/L_tnC_apU_.glif
new file mode 100644
index 0000000..a01a283
--- /dev/null
+++ b/tests/input/font-psf-test/source/PsfTest-BoldItalic.ufo/glyphs/L_tnC_apU_.glif
@@ -0,0 +1,44 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnCapU" format="2">
+ <advance width="1470"/>
+ <unicode hex="0055"/>
+ <anchor x="672" y="0" name="H"/>
+ <anchor x="647" y="-100" name="L"/>
+ <anchor x="890" y="0" name="O"/>
+ <anchor x="1720" y="1200" name="R"/>
+ <anchor x="1054" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="1315" y="1445" type="line"/>
+ <point x="1093" y="554" type="line" smooth="yes"/>
+ <point x="1040" y="341"/>
+ <point x="952" y="202"/>
+ <point x="735" y="202" type="curve" smooth="yes"/>
+ <point x="572" y="202"/>
+ <point x="515" y="305"/>
+ <point x="515" y="435" type="curve" smooth="yes"/>
+ <point x="515" y="482"/>
+ <point x="523" y="533"/>
+ <point x="535" y="583" type="curve" smooth="yes"/>
+ <point x="750" y="1445" type="line"/>
+ <point x="450" y="1445" type="line"/>
+ <point x="444" y="1366"/>
+ <point x="406" y="1210"/>
+ <point x="358" y="1015" type="curve" smooth="yes"/>
+ <point x="249" y="570" type="line" smooth="yes"/>
+ <point x="235" y="512"/>
+ <point x="228" y="457"/>
+ <point x="228" y="404" type="curve" smooth="yes"/>
+ <point x="228" y="155"/>
+ <point x="385" y="-25"/>
+ <point x="698" y="-25" type="curve" smooth="yes"/>
+ <point x="1063" y="-25"/>
+ <point x="1275" y="148"/>
+ <point x="1356" y="470" type="curve" smooth="yes"/>
+ <point x="1493" y="1015" type="line" smooth="yes"/>
+ <point x="1544" y="1220"/>
+ <point x="1582" y="1366"/>
+ <point x="1615" y="1445" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/input/font-psf-test/source/PsfTest-BoldItalic.ufo/glyphs/L_tnC_apV_.glif b/tests/input/font-psf-test/source/PsfTest-BoldItalic.ufo/glyphs/L_tnC_apV_.glif
new file mode 100644
index 0000000..07a71af
--- /dev/null
+++ b/tests/input/font-psf-test/source/PsfTest-BoldItalic.ufo/glyphs/L_tnC_apV_.glif
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnCapV" format="2">
+ <advance width="1445"/>
+ <unicode hex="0056"/>
+ <anchor x="670" y="0" name="H"/>
+ <anchor x="637" y="-100" name="L"/>
+ <anchor x="870" y="0" name="O"/>
+ <anchor x="1044" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="1405" y="1445" type="line"/>
+ <point x="721" y="257" type="line"/>
+ <point x="620" y="1445" type="line"/>
+ <point x="325" y="1445" type="line"/>
+ <point x="339" y="1364"/>
+ <point x="354" y="1275"/>
+ <point x="375" y="1084" type="curve" smooth="yes"/>
+ <point x="495" y="0" type="line"/>
+ <point x="830" y="0" type="line"/>
+ <point x="1490" y="1084" type="line" smooth="yes"/>
+ <point x="1606" y="1276"/>
+ <point x="1664" y="1364"/>
+ <point x="1720" y="1445" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/input/font-psf-test/source/PsfTest-BoldItalic.ufo/glyphs/L_tnC_apW_.glif b/tests/input/font-psf-test/source/PsfTest-BoldItalic.ufo/glyphs/L_tnC_apW_.glif
new file mode 100644
index 0000000..f0e3607
--- /dev/null
+++ b/tests/input/font-psf-test/source/PsfTest-BoldItalic.ufo/glyphs/L_tnC_apW_.glif
@@ -0,0 +1,45 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnCapW" format="2">
+ <advance width="2115"/>
+ <unicode hex="0057"/>
+ <anchor x="967" y="-100" name="L"/>
+ <anchor x="1374" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="1430" y="0" type="line"/>
+ <point x="1595" y="0" type="line"/>
+ <point x="2165" y="1084" type="line" smooth="yes"/>
+ <point x="2266" y="1277"/>
+ <point x="2318" y="1364"/>
+ <point x="2370" y="1445" type="curve"/>
+ <point x="2050" y="1445" type="line"/>
+ <point x="1432" y="129" type="line"/>
+ </contour>
+ <contour>
+ <point x="1470" y="1445" type="line"/>
+ <point x="1220" y="1445" type="line"/>
+ <point x="1257" y="1292" type="line"/>
+ <point x="1280" y="0" type="line"/>
+ <point x="1450" y="0" type="line"/>
+ <point x="1492" y="129" type="line"/>
+ </contour>
+ <contour>
+ <point x="540" y="0" type="line"/>
+ <point x="705" y="0" type="line"/>
+ <point x="1367" y="1292" type="line"/>
+ <point x="1470" y="1445" type="line"/>
+ <point x="1210" y="1445" type="line"/>
+ <point x="542" y="129" type="line"/>
+ </contour>
+ <contour>
+ <point x="630" y="1445" type="line"/>
+ <point x="330" y="1445" type="line"/>
+ <point x="341" y="1367"/>
+ <point x="349" y="1273"/>
+ <point x="355" y="1084" type="curve" smooth="yes"/>
+ <point x="390" y="0" type="line"/>
+ <point x="560" y="0" type="line"/>
+ <point x="602" y="129" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/input/font-psf-test/source/PsfTest-BoldItalic.ufo/glyphs/L_tnC_apX_.glif b/tests/input/font-psf-test/source/PsfTest-BoldItalic.ufo/glyphs/L_tnC_apX_.glif
new file mode 100644
index 0000000..633303c
--- /dev/null
+++ b/tests/input/font-psf-test/source/PsfTest-BoldItalic.ufo/glyphs/L_tnC_apX_.glif
@@ -0,0 +1,39 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnCapX" format="2">
+ <advance width="1345"/>
+ <unicode hex="0058"/>
+ <anchor x="585" y="-100" name="L"/>
+ <anchor x="992" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="930" y="0" type="line"/>
+ <point x="1240" y="0" type="line"/>
+ <point x="1199" y="81"/>
+ <point x="1172" y="125"/>
+ <point x="1096" y="333" type="curve" smooth="yes"/>
+ <point x="690" y="1445" type="line"/>
+ <point x="375" y="1445" type="line"/>
+ <point x="418" y="1362"/>
+ <point x="454" y="1304"/>
+ <point x="529" y="1099" type="curve" smooth="yes"/>
+ </contour>
+ <contour>
+ <point x="768" y="938" type="line"/>
+ <point x="269" y="337" type="line" smooth="yes"/>
+ <point x="94" y="126"/>
+ <point x="44" y="85"/>
+ <point x="-40" y="0" type="curve"/>
+ <point x="290" y="0" type="line"/>
+ <point x="790" y="603" type="line"/>
+ </contour>
+ <contour>
+ <point x="830" y="603" type="line"/>
+ <point x="1251" y="1099" type="line" smooth="yes"/>
+ <point x="1423" y="1302"/>
+ <point x="1492" y="1369"/>
+ <point x="1575" y="1445" type="curve"/>
+ <point x="1240" y="1445" type="line"/>
+ <point x="808" y="938" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/input/font-psf-test/source/PsfTest-BoldItalic.ufo/glyphs/L_tnC_apY_.glif b/tests/input/font-psf-test/source/PsfTest-BoldItalic.ufo/glyphs/L_tnC_apY_.glif
new file mode 100644
index 0000000..49af854
--- /dev/null
+++ b/tests/input/font-psf-test/source/PsfTest-BoldItalic.ufo/glyphs/L_tnC_apY_.glif
@@ -0,0 +1,39 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnCapY" format="2">
+ <advance width="1344"/>
+ <unicode hex="0059"/>
+ <anchor x="587" y="-100" name="L"/>
+ <anchor x="994" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="325" y="1445" type="line"/>
+ <point x="400" y="1298"/>
+ <point x="438" y="1185"/>
+ <point x="482" y="1054" type="curve" smooth="yes"/>
+ <point x="653" y="554" type="line"/>
+ <point x="868" y="668" type="line"/>
+ <point x="637" y="1445" type="line"/>
+ </contour>
+ <contour>
+ <point x="1282" y="1445" type="line"/>
+ <point x="668" y="668" type="line"/>
+ <point x="848" y="554" type="line"/>
+ <point x="1271" y="1054" type="line" smooth="yes"/>
+ <point x="1379" y="1183"/>
+ <point x="1459" y="1278"/>
+ <point x="1619" y="1445" type="curve"/>
+ </contour>
+ <contour>
+ <point x="770" y="0" type="line"/>
+ <point x="774" y="79"/>
+ <point x="813" y="236"/>
+ <point x="862" y="431" type="curve" smooth="yes"/>
+ <point x="926" y="688" type="line"/>
+ <point x="641" y="688" type="line"/>
+ <point x="577" y="431" type="line" smooth="yes"/>
+ <point x="528" y="236"/>
+ <point x="488" y="79"/>
+ <point x="455" y="0" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/input/font-psf-test/source/PsfTest-BoldItalic.ufo/glyphs/L_tnS_mA_.glif b/tests/input/font-psf-test/source/PsfTest-BoldItalic.ufo/glyphs/L_tnS_mA_.glif
new file mode 100644
index 0000000..0208140
--- /dev/null
+++ b/tests/input/font-psf-test/source/PsfTest-BoldItalic.ufo/glyphs/L_tnS_mA_.glif
@@ -0,0 +1,79 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmA" format="2">
+ <advance width="1185"/>
+ <unicode hex="0061"/>
+ <anchor x="925" y="0" name="H"/>
+ <anchor x="525" y="-100" name="L"/>
+ <anchor x="1125" y="0" name="O"/>
+ <anchor x="1335" y="1000" name="R"/>
+ <anchor x="825" y="1100" name="U"/>
+ <outline>
+ <contour>
+ <point x="1060" y="0" type="line"/>
+ <point x="1054" y="44"/>
+ <point x="1051" y="87"/>
+ <point x="1051" y="133" type="curve" smooth="yes"/>
+ <point x="1051" y="204"/>
+ <point x="1059" y="280"/>
+ <point x="1081" y="366" type="curve"/>
+ <point x="1128" y="557"/>
+ <point x="1156" y="665"/>
+ <point x="1170" y="722" type="curve"/>
+ <point x="1174" y="738"/>
+ <point x="1176" y="754"/>
+ <point x="1176" y="770" type="curve" smooth="yes"/>
+ <point x="1176" y="909"/>
+ <point x="1026" y="1030"/>
+ <point x="791" y="1030" type="curve" smooth="yes"/>
+ <point x="632" y="1030"/>
+ <point x="514" y="994"/>
+ <point x="389" y="940" type="curve"/>
+ <point x="363" y="859"/>
+ <point x="327" y="728"/>
+ <point x="315" y="684" type="curve"/>
+ <point x="452" y="765"/>
+ <point x="565" y="808"/>
+ <point x="673" y="808" type="curve" smooth="yes"/>
+ <point x="809" y="808"/>
+ <point x="885" y="760"/>
+ <point x="885" y="709" type="curve" smooth="yes"/>
+ <point x="885" y="705"/>
+ <point x="884" y="700"/>
+ <point x="883" y="696" type="curve" smooth="yes"/>
+ <point x="872" y="653" type="line"/>
+ <point x="831" y="652"/>
+ <point x="669" y="643"/>
+ <point x="598" y="636" type="curve" smooth="yes"/>
+ <point x="367" y="614"/>
+ <point x="109" y="474"/>
+ <point x="109" y="236" type="curve" smooth="yes"/>
+ <point x="109" y="97"/>
+ <point x="215" y="-25"/>
+ <point x="388" y="-25" type="curve" smooth="yes"/>
+ <point x="505" y="-25"/>
+ <point x="633" y="23"/>
+ <point x="773" y="134" type="curve"/>
+ <point x="773" y="78"/>
+ <point x="784" y="28"/>
+ <point x="790" y="0" type="curve"/>
+ </contour>
+ <contour>
+ <point x="797" y="351" type="line"/>
+ <point x="669" y="223"/>
+ <point x="590" y="203"/>
+ <point x="508" y="203" type="curve" smooth="yes"/>
+ <point x="438" y="203"/>
+ <point x="398" y="246"/>
+ <point x="398" y="299" type="curve" smooth="yes"/>
+ <point x="398" y="308"/>
+ <point x="399" y="317"/>
+ <point x="401" y="326" type="curve" smooth="yes"/>
+ <point x="417" y="391"/>
+ <point x="471" y="438"/>
+ <point x="612" y="452" type="curve" smooth="yes"/>
+ <point x="665" y="458"/>
+ <point x="786" y="469"/>
+ <point x="827" y="470" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/input/font-psf-test/source/PsfTest-BoldItalic.ufo/glyphs/L_tnS_mA_A_cute.glif b/tests/input/font-psf-test/source/PsfTest-BoldItalic.ufo/glyphs/L_tnS_mA_A_cute.glif
new file mode 100644
index 0000000..a91e18b
--- /dev/null
+++ b/tests/input/font-psf-test/source/PsfTest-BoldItalic.ufo/glyphs/L_tnS_mA_A_cute.glif
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmAAcute" format="2">
+ <advance width="1185"/>
+ <unicode hex="00E1"/>
+ <anchor x="925" y="0" name="H"/>
+ <anchor x="525" y="-100" name="L"/>
+ <anchor x="1125" y="0" name="O"/>
+ <anchor x="1335" y="1000" name="R"/>
+ <anchor x="899" y="1635" name="U"/>
+ <outline>
+ <component base="LtnSmA"/>
+ <component base="CombAcute" xOffset="1150"/>
+ </outline>
+</glyph>
diff --git a/tests/input/font-psf-test/source/PsfTest-BoldItalic.ufo/glyphs/L_tnS_mA_C_ircum.glif b/tests/input/font-psf-test/source/PsfTest-BoldItalic.ufo/glyphs/L_tnS_mA_C_ircum.glif
new file mode 100644
index 0000000..c17afb1
--- /dev/null
+++ b/tests/input/font-psf-test/source/PsfTest-BoldItalic.ufo/glyphs/L_tnS_mA_C_ircum.glif
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmACircum" format="2">
+ <advance width="1185"/>
+ <unicode hex="00E2"/>
+ <anchor x="925" y="0" name="H"/>
+ <anchor x="525" y="-100" name="L"/>
+ <anchor x="1125" y="0" name="O"/>
+ <anchor x="1335" y="1000" name="R"/>
+ <anchor x="916" y="1635" name="U"/>
+ <outline>
+ <component base="LtnSmA"/>
+ <component base="CombCircum" xOffset="1155"/>
+ </outline>
+</glyph>
diff --git a/tests/input/font-psf-test/source/PsfTest-BoldItalic.ufo/glyphs/L_tnS_mA_D_iaer.glif b/tests/input/font-psf-test/source/PsfTest-BoldItalic.ufo/glyphs/L_tnS_mA_D_iaer.glif
new file mode 100644
index 0000000..af45db4
--- /dev/null
+++ b/tests/input/font-psf-test/source/PsfTest-BoldItalic.ufo/glyphs/L_tnS_mA_D_iaer.glif
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmADiaer" format="2">
+ <advance width="1185"/>
+ <unicode hex="00E4"/>
+ <anchor x="925" y="0" name="H"/>
+ <anchor x="525" y="-100" name="L"/>
+ <anchor x="1125" y="0" name="O"/>
+ <anchor x="1335" y="1000" name="R"/>
+ <anchor x="947" y="1585" name="U"/>
+ <outline>
+ <component base="LtnSmA"/>
+ <component base="CombDiaer" xOffset="1190"/>
+ </outline>
+</glyph>
diff --git a/tests/input/font-psf-test/source/PsfTest-BoldItalic.ufo/glyphs/L_tnS_mA_G_rave.glif b/tests/input/font-psf-test/source/PsfTest-BoldItalic.ufo/glyphs/L_tnS_mA_G_rave.glif
new file mode 100644
index 0000000..2374c69
--- /dev/null
+++ b/tests/input/font-psf-test/source/PsfTest-BoldItalic.ufo/glyphs/L_tnS_mA_G_rave.glif
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmAGrave" format="2">
+ <advance width="1185"/>
+ <unicode hex="00E0"/>
+ <anchor x="925" y="0" name="H"/>
+ <anchor x="525" y="-100" name="L"/>
+ <anchor x="1125" y="0" name="O"/>
+ <anchor x="1335" y="1000" name="R"/>
+ <anchor x="999" y="1635" name="U"/>
+ <outline>
+ <component base="LtnSmA"/>
+ <component base="CombGrave" xOffset="1240"/>
+ </outline>
+</glyph>
diff --git a/tests/input/font-psf-test/source/PsfTest-BoldItalic.ufo/glyphs/L_tnS_mA_R_ingA_bv.glif b/tests/input/font-psf-test/source/PsfTest-BoldItalic.ufo/glyphs/L_tnS_mA_R_ingA_bv.glif
new file mode 100644
index 0000000..f8a7dcc
--- /dev/null
+++ b/tests/input/font-psf-test/source/PsfTest-BoldItalic.ufo/glyphs/L_tnS_mA_R_ingA_bv.glif
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmARingAbv" format="2">
+ <advance width="1185"/>
+ <unicode hex="00E5"/>
+ <anchor x="925" y="0" name="H"/>
+ <anchor x="525" y="-100" name="L"/>
+ <anchor x="1125" y="0" name="O"/>
+ <anchor x="1335" y="1000" name="R"/>
+ <anchor x="961" y="1635" name="U"/>
+ <outline>
+ <component base="LtnSmA"/>
+ <component base="CombRingAbv" xOffset="1182"/>
+ </outline>
+</glyph>
diff --git a/tests/input/font-psf-test/source/PsfTest-BoldItalic.ufo/glyphs/L_tnS_mA_T_ilde.glif b/tests/input/font-psf-test/source/PsfTest-BoldItalic.ufo/glyphs/L_tnS_mA_T_ilde.glif
new file mode 100644
index 0000000..4a46027
--- /dev/null
+++ b/tests/input/font-psf-test/source/PsfTest-BoldItalic.ufo/glyphs/L_tnS_mA_T_ilde.glif
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmATilde" format="2">
+ <advance width="1185"/>
+ <unicode hex="00E3"/>
+ <anchor x="925" y="0" name="H"/>
+ <anchor x="525" y="-100" name="L"/>
+ <anchor x="1125" y="0" name="O"/>
+ <anchor x="1335" y="1000" name="R"/>
+ <anchor x="860" y="1490" name="U"/>
+ <outline>
+ <component base="LtnSmA"/>
+ <component base="CombTilde" xOffset="1215"/>
+ </outline>
+</glyph>
diff --git a/tests/input/font-psf-test/source/PsfTest-BoldItalic.ufo/glyphs/L_tnS_mB_.glif b/tests/input/font-psf-test/source/PsfTest-BoldItalic.ufo/glyphs/L_tnS_mB_.glif
new file mode 100644
index 0000000..92bd16b
--- /dev/null
+++ b/tests/input/font-psf-test/source/PsfTest-BoldItalic.ufo/glyphs/L_tnS_mB_.glif
@@ -0,0 +1,55 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmB" format="2">
+ <advance width="1229"/>
+ <unicode hex="0062"/>
+ <anchor x="550" y="0" name="H"/>
+ <anchor x="525" y="-100" name="L"/>
+ <anchor x="1405" y="1000" name="R"/>
+ <anchor x="958" y="1635" name="U"/>
+ <outline>
+ <contour>
+ <point x="482" y="432" type="line"/>
+ <point x="576" y="610"/>
+ <point x="726" y="787"/>
+ <point x="829" y="787" type="curve" smooth="yes"/>
+ <point x="911" y="787"/>
+ <point x="946" y="705"/>
+ <point x="946" y="590" type="curve" smooth="yes"/>
+ <point x="946" y="465"/>
+ <point x="897" y="350"/>
+ <point x="823" y="275" type="curve" smooth="yes"/>
+ <point x="769" y="221"/>
+ <point x="703" y="188"/>
+ <point x="631" y="188" type="curve" smooth="yes"/>
+ <point x="564" y="188"/>
+ <point x="502" y="202"/>
+ <point x="434" y="238" type="curve"/>
+ </contour>
+ <contour>
+ <point x="445" y="1585" type="line"/>
+ <point x="445" y="1439"/>
+ <point x="404" y="1242"/>
+ <point x="367" y="1095" type="curve" smooth="yes"/>
+ <point x="110" y="64" type="line"/>
+ <point x="252" y="16"/>
+ <point x="400" y="-25"/>
+ <point x="593" y="-25" type="curve" smooth="yes"/>
+ <point x="727" y="-25"/>
+ <point x="845" y="19"/>
+ <point x="942" y="91" type="curve" smooth="yes"/>
+ <point x="1122" y="224"/>
+ <point x="1229" y="453"/>
+ <point x="1229" y="672" type="curve" smooth="yes"/>
+ <point x="1229" y="906"/>
+ <point x="1138" y="1030"/>
+ <point x="985" y="1030" type="curve" smooth="yes"/>
+ <point x="822" y="1030"/>
+ <point x="684" y="906"/>
+ <point x="562" y="756" type="curve"/>
+ <point x="646" y="1095" type="line" smooth="yes"/>
+ <point x="686" y="1255"/>
+ <point x="725" y="1474"/>
+ <point x="725" y="1585" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/input/font-psf-test/source/PsfTest-BoldItalic.ufo/glyphs/L_tnS_mC_.glif b/tests/input/font-psf-test/source/PsfTest-BoldItalic.ufo/glyphs/L_tnS_mC_.glif
new file mode 100644
index 0000000..62c096c
--- /dev/null
+++ b/tests/input/font-psf-test/source/PsfTest-BoldItalic.ufo/glyphs/L_tnS_mC_.glif
@@ -0,0 +1,39 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmC" format="2">
+ <advance width="1019"/>
+ <unicode hex="0063"/>
+ <anchor x="495" y="0" name="H"/>
+ <anchor x="490" y="-100" name="L"/>
+ <anchor x="1210" y="1000" name="R"/>
+ <anchor x="790" y="1100" name="U"/>
+ <outline>
+ <contour>
+ <point x="1099" y="959" type="line"/>
+ <point x="1035" y="997"/>
+ <point x="928" y="1030"/>
+ <point x="796" y="1030" type="curve" smooth="yes"/>
+ <point x="446" y="1030"/>
+ <point x="150" y="774"/>
+ <point x="150" y="386" type="curve" smooth="yes"/>
+ <point x="150" y="137"/>
+ <point x="341" y="-25"/>
+ <point x="569" y="-25" type="curve" smooth="yes"/>
+ <point x="718" y="-25"/>
+ <point x="835" y="11"/>
+ <point x="927" y="69" type="curve"/>
+ <point x="937" y="311" type="line"/>
+ <point x="840" y="238"/>
+ <point x="755" y="203"/>
+ <point x="625" y="203" type="curve" smooth="yes"/>
+ <point x="494" y="203"/>
+ <point x="417" y="302"/>
+ <point x="417" y="416" type="curve" smooth="yes"/>
+ <point x="417" y="661"/>
+ <point x="588" y="802"/>
+ <point x="754" y="802" type="curve" smooth="yes"/>
+ <point x="857" y="802"/>
+ <point x="918" y="781"/>
+ <point x="993" y="720" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/input/font-psf-test/source/PsfTest-BoldItalic.ufo/glyphs/L_tnS_mD_.glif b/tests/input/font-psf-test/source/PsfTest-BoldItalic.ufo/glyphs/L_tnS_mD_.glif
new file mode 100644
index 0000000..fa38d37
--- /dev/null
+++ b/tests/input/font-psf-test/source/PsfTest-BoldItalic.ufo/glyphs/L_tnS_mD_.glif
@@ -0,0 +1,65 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmD" format="2">
+ <advance width="1265"/>
+ <unicode hex="0064"/>
+ <anchor x="535" y="0" name="H"/>
+ <anchor x="540" y="-100" name="L"/>
+ <anchor x="1475" y="1000" name="R"/>
+ <anchor x="958" y="1635" name="U"/>
+ <outline>
+ <contour>
+ <point x="913" y="558" type="line"/>
+ <point x="861" y="438"/>
+ <point x="666" y="200"/>
+ <point x="560" y="200" type="curve" smooth="yes"/>
+ <point x="470" y="200"/>
+ <point x="427" y="263"/>
+ <point x="427" y="367" type="curve" smooth="yes"/>
+ <point x="427" y="480"/>
+ <point x="469" y="626"/>
+ <point x="554" y="714" type="curve" smooth="yes"/>
+ <point x="599" y="761"/>
+ <point x="657" y="792"/>
+ <point x="727" y="792" type="curve" smooth="yes"/>
+ <point x="820" y="792"/>
+ <point x="876" y="775"/>
+ <point x="957" y="731" type="curve"/>
+ </contour>
+ <contour>
+ <point x="1144" y="1585" type="line"/>
+ <point x="1144" y="1471"/>
+ <point x="1116" y="1327"/>
+ <point x="1079" y="1175" type="curve" smooth="yes"/>
+ <point x="1020" y="935" type="line"/>
+ <point x="949" y="989"/>
+ <point x="845" y="1030"/>
+ <point x="756" y="1030" type="curve" smooth="yes"/>
+ <point x="630" y="1030"/>
+ <point x="518" y="987"/>
+ <point x="426" y="917" type="curve" smooth="yes"/>
+ <point x="250" y="784"/>
+ <point x="145" y="553"/>
+ <point x="145" y="341" type="curve" smooth="yes"/>
+ <point x="145" y="130"/>
+ <point x="258" y="-25"/>
+ <point x="448" y="-25" type="curve" smooth="yes"/>
+ <point x="597" y="-25"/>
+ <point x="785" y="145"/>
+ <point x="867" y="267" type="curve"/>
+ <point x="855" y="181"/>
+ <point x="855" y="72"/>
+ <point x="855" y="0" type="curve"/>
+ <point x="1130" y="0" type="line"/>
+ <point x="1126" y="23"/>
+ <point x="1125" y="63"/>
+ <point x="1125" y="100" type="curve" smooth="yes"/>
+ <point x="1125" y="200"/>
+ <point x="1142" y="340"/>
+ <point x="1185" y="520" type="curve" smooth="yes"/>
+ <point x="1345" y="1190" type="line" smooth="yes"/>
+ <point x="1387" y="1366"/>
+ <point x="1415" y="1490"/>
+ <point x="1415" y="1585" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/input/font-psf-test/source/PsfTest-BoldItalic.ufo/glyphs/L_tnS_mE_.glif b/tests/input/font-psf-test/source/PsfTest-BoldItalic.ufo/glyphs/L_tnS_mE_.glif
new file mode 100644
index 0000000..49f5856
--- /dev/null
+++ b/tests/input/font-psf-test/source/PsfTest-BoldItalic.ufo/glyphs/L_tnS_mE_.glif
@@ -0,0 +1,52 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmE" format="2">
+ <advance width="1087"/>
+ <unicode hex="0065"/>
+ <anchor x="509" y="0" name="H"/>
+ <anchor x="555" y="-100" name="L"/>
+ <anchor x="840" y="0" name="O"/>
+ <anchor x="1320" y="1000" name="R"/>
+ <anchor x="752" y="1100" name="U"/>
+ <outline>
+ <contour>
+ <point x="1013" y="303" type="line"/>
+ <point x="871" y="230"/>
+ <point x="739" y="198"/>
+ <point x="608" y="198" type="curve" smooth="yes"/>
+ <point x="459" y="198"/>
+ <point x="401" y="297"/>
+ <point x="401" y="428" type="curve" smooth="yes"/>
+ <point x="401" y="683"/>
+ <point x="552" y="822"/>
+ <point x="713" y="822" type="curve" smooth="yes"/>
+ <point x="811" y="822"/>
+ <point x="869" y="782"/>
+ <point x="869" y="720" type="curve" smooth="yes"/>
+ <point x="869" y="635"/>
+ <point x="777" y="580"/>
+ <point x="533" y="580" type="curve" smooth="yes"/>
+ <point x="461" y="580"/>
+ <point x="385" y="589"/>
+ <point x="283" y="610" type="curve"/>
+ <point x="283" y="437" type="line"/>
+ <point x="353" y="422"/>
+ <point x="487" y="413"/>
+ <point x="569" y="413" type="curve" smooth="yes"/>
+ <point x="935" y="413"/>
+ <point x="1125" y="583"/>
+ <point x="1125" y="774" type="curve" smooth="yes"/>
+ <point x="1125" y="922"/>
+ <point x="993" y="1030"/>
+ <point x="769" y="1030" type="curve" smooth="yes"/>
+ <point x="435" y="1030"/>
+ <point x="148" y="775"/>
+ <point x="148" y="388" type="curve" smooth="yes"/>
+ <point x="148" y="135"/>
+ <point x="332" y="-25"/>
+ <point x="556" y="-25" type="curve" smooth="yes"/>
+ <point x="712" y="-25"/>
+ <point x="835" y="2"/>
+ <point x="997" y="74" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/input/font-psf-test/source/PsfTest-BoldItalic.ufo/glyphs/L_tnS_mF_.glif b/tests/input/font-psf-test/source/PsfTest-BoldItalic.ufo/glyphs/L_tnS_mF_.glif
new file mode 100644
index 0000000..fd86bf3
--- /dev/null
+++ b/tests/input/font-psf-test/source/PsfTest-BoldItalic.ufo/glyphs/L_tnS_mF_.glif
@@ -0,0 +1,44 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmF" format="2">
+ <advance width="859"/>
+ <unicode hex="0066"/>
+ <anchor x="320" y="0" name="H"/>
+ <anchor x="400" y="-100" name="L"/>
+ <anchor x="948" y="1635" name="U"/>
+ <outline>
+ <contour>
+ <point x="180" y="797" type="line"/>
+ <point x="915" y="797" type="line"/>
+ <point x="965" y="995" type="line"/>
+ <point x="230" y="995" type="line"/>
+ </contour>
+ <contour>
+ <point x="1189" y="1534" type="line"/>
+ <point x="1139" y="1572"/>
+ <point x="1040" y="1604"/>
+ <point x="966" y="1604" type="curve" smooth="yes"/>
+ <point x="719" y="1604"/>
+ <point x="535" y="1455"/>
+ <point x="460" y="1158" type="curve" smooth="yes"/>
+ <point x="416" y="983"/>
+ <point x="253" y="334"/>
+ <point x="232" y="0" type="curve"/>
+ <point x="542" y="0" type="line"/>
+ <point x="536" y="28"/>
+ <point x="533" y="66"/>
+ <point x="533" y="110" type="curve" smooth="yes"/>
+ <point x="533" y="213"/>
+ <point x="550" y="356"/>
+ <point x="581" y="489" type="curve" smooth="yes"/>
+ <point x="649" y="784"/>
+ <point x="682" y="926"/>
+ <point x="735" y="1147" type="curve" smooth="yes"/>
+ <point x="774" y="1309"/>
+ <point x="836" y="1373"/>
+ <point x="932" y="1373" type="curve" smooth="yes"/>
+ <point x="981" y="1373"/>
+ <point x="1043" y="1348"/>
+ <point x="1076" y="1309" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/input/font-psf-test/source/PsfTest-BoldItalic.ufo/glyphs/L_tnS_mG_.glif b/tests/input/font-psf-test/source/PsfTest-BoldItalic.ufo/glyphs/L_tnS_mG_.glif
new file mode 100644
index 0000000..c651c04
--- /dev/null
+++ b/tests/input/font-psf-test/source/PsfTest-BoldItalic.ufo/glyphs/L_tnS_mG_.glif
@@ -0,0 +1,91 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmG" format="2">
+ <advance width="1120"/>
+ <unicode hex="0067"/>
+ <anchor x="420" y="-465" name="H"/>
+ <anchor x="403" y="-535" name="L"/>
+ <anchor x="1360" y="1000" name="R"/>
+ <anchor x="782" y="1100" name="U"/>
+ <outline>
+ <contour>
+ <point x="1027" y="-117" type="curve" smooth="yes"/>
+ <point x="1027" y="8"/>
+ <point x="938" y="114"/>
+ <point x="702" y="163" type="curve" smooth="yes"/>
+ <point x="473" y="210"/>
+ <point x="402" y="217"/>
+ <point x="402" y="249" type="curve" smooth="yes"/>
+ <point x="402" y="279"/>
+ <point x="493" y="321"/>
+ <point x="584" y="346" type="curve"/>
+ <point x="359" y="391" type="line"/>
+ <point x="263" y="354"/>
+ <point x="161" y="283"/>
+ <point x="161" y="188" type="curve" smooth="yes"/>
+ <point x="161" y="101"/>
+ <point x="230" y="4"/>
+ <point x="451" y="-23" type="curve" smooth="yes"/>
+ <point x="669" y="-50"/>
+ <point x="740" y="-97"/>
+ <point x="740" y="-157" type="curve" smooth="yes"/>
+ <point x="740" y="-245"/>
+ <point x="591" y="-299"/>
+ <point x="457" y="-299" type="curve" smooth="yes"/>
+ <point x="286" y="-299"/>
+ <point x="197" y="-233"/>
+ <point x="197" y="-180" type="curve" smooth="yes"/>
+ <point x="197" y="-74"/>
+ <point x="405" y="-4"/>
+ <point x="476" y="20" type="curve"/>
+ <point x="476" y="49"/>
+ <point x="250" y="74"/>
+ <point x="250" y="74" type="curve"/>
+ <point x="103" y="20"/>
+ <point x="-91" y="-65"/>
+ <point x="-91" y="-233" type="curve" smooth="yes"/>
+ <point x="-91" y="-409"/>
+ <point x="166" y="-500"/>
+ <point x="392" y="-500" type="curve" smooth="yes"/>
+ <point x="690" y="-500"/>
+ <point x="1027" y="-380"/>
+ </contour>
+ <contour>
+ <point x="1268" y="1030" type="line"/>
+ <point x="1168" y="1023"/>
+ <point x="1027" y="987"/>
+ <point x="924" y="931" type="curve"/>
+ <point x="946" y="762" type="line"/>
+ <point x="1048" y="800"/>
+ <point x="1132" y="815"/>
+ <point x="1205" y="817" type="curve"/>
+ </contour>
+ <contour>
+ <point x="198" y="627" type="curve" smooth="yes"/>
+ <point x="198" y="450"/>
+ <point x="353" y="302"/>
+ <point x="572" y="302" type="curve" smooth="yes"/>
+ <point x="824" y="302"/>
+ <point x="1087" y="444"/>
+ <point x="1087" y="702" type="curve" smooth="yes"/>
+ <point x="1087" y="874"/>
+ <point x="955" y="1030"/>
+ <point x="703" y="1030" type="curve" smooth="yes"/>
+ <point x="454" y="1030"/>
+ <point x="198" y="881"/>
+ </contour>
+ <contour>
+ <point x="663" y="829" type="curve" smooth="yes"/>
+ <point x="761" y="829"/>
+ <point x="842" y="762"/>
+ <point x="842" y="675" type="curve" smooth="yes"/>
+ <point x="842" y="559"/>
+ <point x="733" y="496"/>
+ <point x="620" y="496" type="curve" smooth="yes"/>
+ <point x="524" y="496"/>
+ <point x="450" y="569"/>
+ <point x="450" y="653" type="curve" smooth="yes"/>
+ <point x="450" y="769"/>
+ <point x="560" y="829"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/input/font-psf-test/source/PsfTest-BoldItalic.ufo/glyphs/L_tnS_mH_.glif b/tests/input/font-psf-test/source/PsfTest-BoldItalic.ufo/glyphs/L_tnS_mH_.glif
new file mode 100644
index 0000000..7160c61
--- /dev/null
+++ b/tests/input/font-psf-test/source/PsfTest-BoldItalic.ufo/glyphs/L_tnS_mH_.glif
@@ -0,0 +1,54 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmH" format="2">
+ <advance width="1273"/>
+ <unicode hex="0068"/>
+ <anchor x="220" y="0" name="H"/>
+ <anchor x="635" y="-100" name="L"/>
+ <anchor x="968" y="1635" name="U"/>
+ <outline>
+ <contour>
+ <point x="1140" y="0" type="line"/>
+ <point x="1135" y="29"/>
+ <point x="1129" y="60"/>
+ <point x="1129" y="90" type="curve" smooth="yes"/>
+ <point x="1129" y="135"/>
+ <point x="1134" y="170"/>
+ <point x="1141" y="215" type="curve" smooth="yes"/>
+ <point x="1171" y="400"/>
+ <point x="1253" y="590"/>
+ <point x="1253" y="725" type="curve" smooth="yes"/>
+ <point x="1253" y="900"/>
+ <point x="1183" y="1030"/>
+ <point x="990" y="1030" type="curve" smooth="yes"/>
+ <point x="849" y="1030"/>
+ <point x="694" y="902"/>
+ <point x="566" y="740" type="curve"/>
+ <point x="656" y="1095" type="line" smooth="yes"/>
+ <point x="696" y="1255"/>
+ <point x="735" y="1474"/>
+ <point x="735" y="1585" type="curve"/>
+ <point x="455" y="1585" type="line"/>
+ <point x="455" y="1439"/>
+ <point x="413" y="1242"/>
+ <point x="377" y="1095" type="curve" smooth="yes"/>
+ <point x="105" y="0" type="line"/>
+ <point x="385" y="0" type="line"/>
+ <point x="485" y="400" type="line"/>
+ <point x="580" y="596"/>
+ <point x="745" y="787"/>
+ <point x="850" y="787" type="curve" smooth="yes"/>
+ <point x="937" y="787"/>
+ <point x="953" y="722"/>
+ <point x="953" y="625" type="curve" smooth="yes"/>
+ <point x="953" y="529"/>
+ <point x="889" y="374"/>
+ <point x="863" y="213" type="curve" smooth="yes"/>
+ <point x="857" y="174"/>
+ <point x="853" y="134"/>
+ <point x="853" y="95" type="curve" smooth="yes"/>
+ <point x="853" y="63"/>
+ <point x="854" y="31"/>
+ <point x="860" y="0" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/input/font-psf-test/source/PsfTest-BoldItalic.ufo/glyphs/L_tnS_mI_.glif b/tests/input/font-psf-test/source/PsfTest-BoldItalic.ufo/glyphs/L_tnS_mI_.glif
new file mode 100644
index 0000000..c19769e
--- /dev/null
+++ b/tests/input/font-psf-test/source/PsfTest-BoldItalic.ufo/glyphs/L_tnS_mI_.glif
@@ -0,0 +1,50 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmI" format="2">
+ <advance width="625"/>
+ <unicode hex="0069"/>
+ <anchor x="260" y="0" name="H"/>
+ <anchor x="335" y="-100" name="L"/>
+ <anchor x="520" y="0" name="O"/>
+ <anchor x="830" y="1000" name="R"/>
+ <anchor x="535" y="1100" name="U"/>
+ <outline>
+ <contour>
+ <point x="341" y="1010" type="line"/>
+ <point x="341" y="877"/>
+ <point x="290" y="698"/>
+ <point x="252" y="547" type="curve" smooth="yes"/>
+ <point x="213" y="390" type="line" smooth="yes"/>
+ <point x="193" y="309"/>
+ <point x="170" y="191"/>
+ <point x="170" y="88" type="curve" smooth="yes"/>
+ <point x="170" y="57"/>
+ <point x="172" y="27"/>
+ <point x="177" y="0" type="curve"/>
+ <point x="472" y="0" type="line"/>
+ <point x="463" y="39"/>
+ <point x="459" y="82"/>
+ <point x="459" y="126" type="curve" smooth="yes"/>
+ <point x="459" y="217"/>
+ <point x="475" y="310"/>
+ <point x="486" y="358" type="curve" smooth="yes"/>
+ <point x="531" y="546" type="line" smooth="yes"/>
+ <point x="572" y="719"/>
+ <point x="621" y="875"/>
+ <point x="625" y="1010" type="curve"/>
+ </contour>
+ <contour>
+ <point x="404" y="1341" type="curve" smooth="yes"/>
+ <point x="404" y="1259"/>
+ <point x="462" y="1197"/>
+ <point x="548" y="1197" type="curve" smooth="yes"/>
+ <point x="668" y="1197"/>
+ <point x="759" y="1292"/>
+ <point x="759" y="1403" type="curve" smooth="yes"/>
+ <point x="759" y="1483"/>
+ <point x="701" y="1544"/>
+ <point x="614" y="1544" type="curve" smooth="yes"/>
+ <point x="496" y="1544"/>
+ <point x="404" y="1451"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/input/font-psf-test/source/PsfTest-BoldItalic.ufo/glyphs/L_tnS_mJ_.glif b/tests/input/font-psf-test/source/PsfTest-BoldItalic.ufo/glyphs/L_tnS_mJ_.glif
new file mode 100644
index 0000000..a454f7a
--- /dev/null
+++ b/tests/input/font-psf-test/source/PsfTest-BoldItalic.ufo/glyphs/L_tnS_mJ_.glif
@@ -0,0 +1,45 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmJ" format="2">
+ <advance width="695"/>
+ <unicode hex="006A"/>
+ <anchor x="-45" y="-500" name="L"/>
+ <anchor x="565" y="1100" name="U"/>
+ <outline>
+ <contour>
+ <point x="361" y="1010" type="line"/>
+ <point x="361" y="866"/>
+ <point x="284" y="395"/>
+ <point x="205" y="87" type="curve" smooth="yes"/>
+ <point x="148" y="-136"/>
+ <point x="54" y="-221"/>
+ <point x="-56" y="-221" type="curve" smooth="yes"/>
+ <point x="-137" y="-221"/>
+ <point x="-217" y="-187"/>
+ <point x="-252" y="-150" type="curve"/>
+ <point x="-355" y="-385" type="line"/>
+ <point x="-321" y="-417"/>
+ <point x="-172" y="-465"/>
+ <point x="-79" y="-465" type="curve" smooth="yes"/>
+ <point x="170" y="-465"/>
+ <point x="388" y="-295"/>
+ <point x="481" y="75" type="curve" smooth="yes"/>
+ <point x="501" y="157"/>
+ <point x="646" y="882"/>
+ <point x="646" y="1010" type="curve"/>
+ </contour>
+ <contour>
+ <point x="395" y="1341" type="curve" smooth="yes"/>
+ <point x="395" y="1259"/>
+ <point x="453" y="1197"/>
+ <point x="539" y="1197" type="curve" smooth="yes"/>
+ <point x="659" y="1197"/>
+ <point x="750" y="1292"/>
+ <point x="750" y="1403" type="curve" smooth="yes"/>
+ <point x="750" y="1483"/>
+ <point x="692" y="1544"/>
+ <point x="605" y="1544" type="curve" smooth="yes"/>
+ <point x="487" y="1544"/>
+ <point x="395" y="1451"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/input/font-psf-test/source/PsfTest-BoldItalic.ufo/glyphs/L_tnS_mK_.glif b/tests/input/font-psf-test/source/PsfTest-BoldItalic.ufo/glyphs/L_tnS_mK_.glif
new file mode 100644
index 0000000..ed9d720
--- /dev/null
+++ b/tests/input/font-psf-test/source/PsfTest-BoldItalic.ufo/glyphs/L_tnS_mK_.glif
@@ -0,0 +1,45 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmK" format="2">
+ <advance width="1209"/>
+ <unicode hex="006B"/>
+ <anchor x="880" y="0" name="H"/>
+ <anchor x="600" y="-100" name="L"/>
+ <anchor x="1330" y="1000" name="R"/>
+ <anchor x="943" y="1635" name="U"/>
+ <outline>
+ <contour>
+ <point x="964" y="1010" type="line"/>
+ <point x="920" y="864"/>
+ <point x="682" y="702"/>
+ <point x="483" y="576" type="curve"/>
+ <point x="676" y="518" type="line"/>
+ <point x="915" y="662"/>
+ <point x="1289" y="867"/>
+ <point x="1289" y="1010" type="curve"/>
+ </contour>
+ <contour>
+ <point x="1168" y="0" type="line"/>
+ <point x="992" y="302"/>
+ <point x="856" y="620"/>
+ <point x="633" y="620" type="curve"/>
+ <point x="442" y="529" type="line"/>
+ <point x="606" y="529"/>
+ <point x="722" y="252"/>
+ <point x="831" y="0" type="curve"/>
+ </contour>
+ <contour>
+ <point x="394" y="0" type="line"/>
+ <point x="669" y="1105" type="line" smooth="yes"/>
+ <point x="713" y="1280"/>
+ <point x="744" y="1497"/>
+ <point x="744" y="1585" type="curve"/>
+ <point x="462" y="1585" type="line"/>
+ <point x="462" y="1471"/>
+ <point x="431" y="1274"/>
+ <point x="393" y="1122" type="curve" smooth="yes"/>
+ <point x="345" y="928"/>
+ <point x="115" y="0"/>
+ <point x="115" y="0" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/input/font-psf-test/source/PsfTest-BoldItalic.ufo/glyphs/L_tnS_mL_.glif b/tests/input/font-psf-test/source/PsfTest-BoldItalic.ufo/glyphs/L_tnS_mL_.glif
new file mode 100644
index 0000000..3ecb48c
--- /dev/null
+++ b/tests/input/font-psf-test/source/PsfTest-BoldItalic.ufo/glyphs/L_tnS_mL_.glif
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmL" format="2">
+ <advance width="641"/>
+ <unicode hex="006C"/>
+ <anchor x="275" y="0" name="H"/>
+ <anchor x="350" y="-100" name="L"/>
+ <anchor x="850" y="1000" name="R"/>
+ <anchor x="630" y="1635" name="U"/>
+ <outline>
+ <contour>
+ <point x="461" y="1585" type="line"/>
+ <point x="461" y="1439"/>
+ <point x="420" y="1242"/>
+ <point x="383" y="1095" type="curve" smooth="yes"/>
+ <point x="232" y="488" type="line" smooth="yes"/>
+ <point x="208" y="394"/>
+ <point x="175" y="269"/>
+ <point x="175" y="116" type="curve" smooth="yes"/>
+ <point x="175" y="89"/>
+ <point x="178" y="30"/>
+ <point x="180" y="0" type="curve"/>
+ <point x="470" y="0" type="line"/>
+ <point x="464" y="39"/>
+ <point x="461" y="80"/>
+ <point x="461" y="121" type="curve" smooth="yes"/>
+ <point x="461" y="277"/>
+ <point x="498" y="434"/>
+ <point x="518" y="515" type="curve" smooth="yes"/>
+ <point x="662" y="1095" type="line" smooth="yes"/>
+ <point x="702" y="1255"/>
+ <point x="741" y="1474"/>
+ <point x="741" y="1585" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/input/font-psf-test/source/PsfTest-BoldItalic.ufo/glyphs/L_tnS_mM_.glif b/tests/input/font-psf-test/source/PsfTest-BoldItalic.ufo/glyphs/L_tnS_mM_.glif
new file mode 100644
index 0000000..6f5967a
--- /dev/null
+++ b/tests/input/font-psf-test/source/PsfTest-BoldItalic.ufo/glyphs/L_tnS_mM_.glif
@@ -0,0 +1,80 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmM" format="2">
+ <advance width="1770"/>
+ <unicode hex="006D"/>
+ <anchor x="830" y="0" name="H"/>
+ <anchor x="805" y="-100" name="L"/>
+ <anchor x="1105" y="1100" name="U"/>
+ <outline>
+ <contour>
+ <point x="1609" y="0" type="line"/>
+ <point x="1604" y="29"/>
+ <point x="1602" y="60"/>
+ <point x="1602" y="90" type="curve" smooth="yes"/>
+ <point x="1602" y="136"/>
+ <point x="1606" y="181"/>
+ <point x="1613" y="228" type="curve" smooth="yes"/>
+ <point x="1628" y="333"/>
+ <point x="1747" y="670"/>
+ <point x="1747" y="822" type="curve" smooth="yes"/>
+ <point x="1747" y="958"/>
+ <point x="1681" y="1030"/>
+ <point x="1547" y="1030" type="curve" smooth="yes"/>
+ <point x="1391" y="1030"/>
+ <point x="1227" y="876"/>
+ <point x="1120" y="705" type="curve"/>
+ <point x="1125" y="738"/>
+ <point x="1127" y="769"/>
+ <point x="1127" y="798" type="curve" smooth="yes"/>
+ <point x="1127" y="944"/>
+ <point x="1067" y="1030"/>
+ <point x="941" y="1030" type="curve" smooth="yes"/>
+ <point x="815" y="1030"/>
+ <point x="664" y="911"/>
+ <point x="537" y="715" type="curve"/>
+ <point x="553" y="840"/>
+ <point x="556" y="911"/>
+ <point x="556" y="955" type="curve" smooth="yes"/>
+ <point x="556" y="981"/>
+ <point x="554" y="998"/>
+ <point x="551" y="1010" type="curve"/>
+ <point x="291" y="1010" type="line"/>
+ <point x="293" y="999"/>
+ <point x="294" y="975"/>
+ <point x="294" y="942" type="curve" smooth="yes"/>
+ <point x="294" y="855"/>
+ <point x="286" y="710"/>
+ <point x="261" y="609" type="curve" smooth="yes"/>
+ <point x="110" y="0" type="line"/>
+ <point x="390" y="0" type="line"/>
+ <point x="479" y="370" type="line"/>
+ <point x="541" y="552"/>
+ <point x="711" y="787"/>
+ <point x="791" y="787" type="curve" smooth="yes"/>
+ <point x="843" y="787"/>
+ <point x="857" y="741"/>
+ <point x="857" y="688" type="curve" smooth="yes"/>
+ <point x="857" y="625"/>
+ <point x="832" y="535"/>
+ <point x="819" y="483" type="curve" smooth="yes"/>
+ <point x="695" y="0" type="line"/>
+ <point x="975" y="0" type="line"/>
+ <point x="1067" y="370" type="line"/>
+ <point x="1139" y="556"/>
+ <point x="1300" y="787"/>
+ <point x="1381" y="787" type="curve" smooth="yes"/>
+ <point x="1434" y="787"/>
+ <point x="1450" y="762"/>
+ <point x="1450" y="706" type="curve" smooth="yes"/>
+ <point x="1450" y="592"/>
+ <point x="1350" y="331"/>
+ <point x="1330" y="205" type="curve" smooth="yes"/>
+ <point x="1324" y="168"/>
+ <point x="1321" y="132"/>
+ <point x="1321" y="95" type="curve" smooth="yes"/>
+ <point x="1321" y="63"/>
+ <point x="1323" y="31"/>
+ <point x="1329" y="0" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/input/font-psf-test/source/PsfTest-BoldItalic.ufo/glyphs/L_tnS_mN_.glif b/tests/input/font-psf-test/source/PsfTest-BoldItalic.ufo/glyphs/L_tnS_mN_.glif
new file mode 100644
index 0000000..009224e
--- /dev/null
+++ b/tests/input/font-psf-test/source/PsfTest-BoldItalic.ufo/glyphs/L_tnS_mN_.glif
@@ -0,0 +1,57 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmN" format="2">
+ <advance width="1281"/>
+ <unicode hex="006E"/>
+ <anchor x="560" y="0" name="H"/>
+ <anchor x="635" y="-100" name="L"/>
+ <anchor x="835" y="1100" name="U"/>
+ <outline>
+ <contour>
+ <point x="1145" y="0" type="line"/>
+ <point x="1140" y="29"/>
+ <point x="1138" y="60"/>
+ <point x="1138" y="90" type="curve" smooth="yes"/>
+ <point x="1138" y="136"/>
+ <point x="1141" y="182"/>
+ <point x="1149" y="228" type="curve" smooth="yes"/>
+ <point x="1173" y="366"/>
+ <point x="1258" y="591"/>
+ <point x="1258" y="725" type="curve" smooth="yes"/>
+ <point x="1258" y="890"/>
+ <point x="1188" y="1030"/>
+ <point x="995" y="1030" type="curve" smooth="yes"/>
+ <point x="844" y="1030"/>
+ <point x="685" y="903"/>
+ <point x="546" y="715" type="curve"/>
+ <point x="555" y="771"/>
+ <point x="569" y="875"/>
+ <point x="569" y="933" type="curve" smooth="yes"/>
+ <point x="569" y="962"/>
+ <point x="568" y="988"/>
+ <point x="565" y="1010" type="curve"/>
+ <point x="290" y="1010" type="line"/>
+ <point x="290" y="962" type="line" smooth="yes"/>
+ <point x="290" y="859"/>
+ <point x="280" y="685"/>
+ <point x="261" y="609" type="curve" smooth="yes"/>
+ <point x="110" y="0" type="line"/>
+ <point x="388" y="0" type="line"/>
+ <point x="490" y="405" type="line"/>
+ <point x="569" y="569"/>
+ <point x="740" y="787"/>
+ <point x="835" y="787" type="curve" smooth="yes"/>
+ <point x="922" y="787"/>
+ <point x="958" y="732"/>
+ <point x="958" y="625" type="curve" smooth="yes"/>
+ <point x="958" y="527"/>
+ <point x="891" y="369"/>
+ <point x="866" y="205" type="curve" smooth="yes"/>
+ <point x="860" y="168"/>
+ <point x="857" y="132"/>
+ <point x="857" y="95" type="curve" smooth="yes"/>
+ <point x="857" y="63"/>
+ <point x="859" y="31"/>
+ <point x="865" y="0" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/input/font-psf-test/source/PsfTest-BoldItalic.ufo/glyphs/L_tnS_mO_.glif b/tests/input/font-psf-test/source/PsfTest-BoldItalic.ufo/glyphs/L_tnS_mO_.glif
new file mode 100644
index 0000000..d21fb58
--- /dev/null
+++ b/tests/input/font-psf-test/source/PsfTest-BoldItalic.ufo/glyphs/L_tnS_mO_.glif
@@ -0,0 +1,40 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmO" format="2">
+ <advance width="1139"/>
+ <unicode hex="006F"/>
+ <anchor x="518" y="0" name="H"/>
+ <anchor x="530" y="-100" name="L"/>
+ <anchor x="730" y="0" name="O"/>
+ <anchor x="1350" y="1000" name="R"/>
+ <anchor x="795" y="1100" name="U"/>
+ <outline>
+ <contour>
+ <point x="140" y="370" type="curve" smooth="yes"/>
+ <point x="140" y="128"/>
+ <point x="289" y="-25"/>
+ <point x="520" y="-25" type="curve" smooth="yes"/>
+ <point x="906" y="-25"/>
+ <point x="1144" y="295"/>
+ <point x="1144" y="641" type="curve" smooth="yes"/>
+ <point x="1144" y="880"/>
+ <point x="1003" y="1030"/>
+ <point x="773" y="1030" type="curve" smooth="yes"/>
+ <point x="390" y="1030"/>
+ <point x="140" y="718"/>
+ </contour>
+ <contour>
+ <point x="718" y="807" type="curve" smooth="yes"/>
+ <point x="826" y="807"/>
+ <point x="879" y="737"/>
+ <point x="879" y="612" type="curve" smooth="yes"/>
+ <point x="879" y="413"/>
+ <point x="764" y="198"/>
+ <point x="566" y="198" type="curve" smooth="yes"/>
+ <point x="464" y="198"/>
+ <point x="404" y="264"/>
+ <point x="404" y="385" type="curve" smooth="yes"/>
+ <point x="404" y="570"/>
+ <point x="512" y="807"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/input/font-psf-test/source/PsfTest-BoldItalic.ufo/glyphs/L_tnS_mP_.glif b/tests/input/font-psf-test/source/PsfTest-BoldItalic.ufo/glyphs/L_tnS_mP_.glif
new file mode 100644
index 0000000..55c6e8b
--- /dev/null
+++ b/tests/input/font-psf-test/source/PsfTest-BoldItalic.ufo/glyphs/L_tnS_mP_.glif
@@ -0,0 +1,66 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmP" format="2">
+ <advance width="1272"/>
+ <unicode hex="0070"/>
+ <anchor x="121" y="-435" name="H"/>
+ <anchor x="555" y="-500" name="L"/>
+ <anchor x="1425" y="1000" name="R"/>
+ <anchor x="855" y="1100" name="U"/>
+ <outline>
+ <contour>
+ <point x="523" y="500" type="line"/>
+ <point x="605" y="650"/>
+ <point x="765" y="794"/>
+ <point x="854" y="794" type="curve" smooth="yes"/>
+ <point x="932" y="794"/>
+ <point x="975" y="719"/>
+ <point x="975" y="609" type="curve" smooth="yes"/>
+ <point x="975" y="478"/>
+ <point x="924" y="334"/>
+ <point x="823" y="258" type="curve" smooth="yes"/>
+ <point x="778" y="224"/>
+ <point x="723" y="204"/>
+ <point x="658" y="204" type="curve" smooth="yes"/>
+ <point x="589" y="204"/>
+ <point x="517" y="243"/>
+ <point x="473" y="297" type="curve"/>
+ </contour>
+ <contour>
+ <point x="300" y="1010" type="line"/>
+ <point x="300" y="962" type="line" smooth="yes"/>
+ <point x="300" y="859"/>
+ <point x="290" y="685"/>
+ <point x="271" y="609" type="curve" smooth="yes"/>
+ <point x="75" y="-180" type="line" smooth="yes"/>
+ <point x="49" y="-286"/>
+ <point x="25" y="-403"/>
+ <point x="25" y="-485" type="curve"/>
+ <point x="314" y="-485" type="line"/>
+ <point x="314" y="-393"/>
+ <point x="328" y="-287"/>
+ <point x="362" y="-149" type="curve" smooth="yes"/>
+ <point x="415" y="64" type="line"/>
+ <point x="495" y="10"/>
+ <point x="562" y="-25"/>
+ <point x="667" y="-25" type="curve" smooth="yes"/>
+ <point x="750" y="-25"/>
+ <point x="833" y="-2"/>
+ <point x="909" y="40" type="curve" smooth="yes"/>
+ <point x="1112" y="152"/>
+ <point x="1267" y="398"/>
+ <point x="1267" y="685" type="curve" smooth="yes"/>
+ <point x="1267" y="884"/>
+ <point x="1176" y="1030"/>
+ <point x="1004" y="1030" type="curve" smooth="yes"/>
+ <point x="849" y="1030"/>
+ <point x="677" y="901"/>
+ <point x="565" y="752" type="curve"/>
+ <point x="574" y="808"/>
+ <point x="579" y="875"/>
+ <point x="579" y="933" type="curve" smooth="yes"/>
+ <point x="579" y="962"/>
+ <point x="578" y="988"/>
+ <point x="575" y="1010" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/input/font-psf-test/source/PsfTest-BoldItalic.ufo/glyphs/L_tnS_mQ_.glif b/tests/input/font-psf-test/source/PsfTest-BoldItalic.ufo/glyphs/L_tnS_mQ_.glif
new file mode 100644
index 0000000..d3068d2
--- /dev/null
+++ b/tests/input/font-psf-test/source/PsfTest-BoldItalic.ufo/glyphs/L_tnS_mQ_.glif
@@ -0,0 +1,54 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmQ" format="2">
+ <advance width="1206"/>
+ <unicode hex="0071"/>
+ <anchor x="415" y="-500" name="L"/>
+ <anchor x="1400" y="1000" name="R"/>
+ <anchor x="815" y="1100" name="U"/>
+ <outline>
+ <contour>
+ <point x="889" y="583" type="line"/>
+ <point x="832" y="467"/>
+ <point x="615" y="211"/>
+ <point x="520" y="211" type="curve" smooth="yes"/>
+ <point x="457" y="211"/>
+ <point x="429" y="263"/>
+ <point x="429" y="362" type="curve" smooth="yes"/>
+ <point x="429" y="484"/>
+ <point x="469" y="616"/>
+ <point x="551" y="702" type="curve" smooth="yes"/>
+ <point x="605" y="758"/>
+ <point x="676" y="794"/>
+ <point x="765" y="794" type="curve" smooth="yes"/>
+ <point x="806" y="794"/>
+ <point x="897" y="781"/>
+ <point x="933" y="762" type="curve"/>
+ </contour>
+ <contour>
+ <point x="936" y="-485" type="line"/>
+ <point x="936" y="-396"/>
+ <point x="951" y="-299"/>
+ <point x="978" y="-190" type="curve" smooth="yes"/>
+ <point x="1261" y="955" type="line"/>
+ <point x="1134" y="991"/>
+ <point x="972" y="1030"/>
+ <point x="819" y="1030" type="curve" smooth="yes"/>
+ <point x="678" y="1030"/>
+ <point x="516" y="969"/>
+ <point x="403" y="874" type="curve" smooth="yes"/>
+ <point x="244" y="739"/>
+ <point x="145" y="535"/>
+ <point x="145" y="331" type="curve" smooth="yes"/>
+ <point x="145" y="105"/>
+ <point x="275" y="-25"/>
+ <point x="391" y="-25" type="curve" smooth="yes"/>
+ <point x="529" y="-25"/>
+ <point x="729" y="134"/>
+ <point x="838" y="300" type="curve"/>
+ <point x="706" y="-185" type="line" smooth="yes"/>
+ <point x="675" y="-299"/>
+ <point x="661" y="-419"/>
+ <point x="661" y="-485" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/input/font-psf-test/source/PsfTest-BoldItalic.ufo/glyphs/L_tnS_mR_.glif b/tests/input/font-psf-test/source/PsfTest-BoldItalic.ufo/glyphs/L_tnS_mR_.glif
new file mode 100644
index 0000000..48a3cc8
--- /dev/null
+++ b/tests/input/font-psf-test/source/PsfTest-BoldItalic.ufo/glyphs/L_tnS_mR_.glif
@@ -0,0 +1,42 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmR" format="2">
+ <advance width="1021"/>
+ <unicode hex="0072"/>
+ <anchor x="225" y="0" name="H"/>
+ <anchor x="255" y="-100" name="L"/>
+ <anchor x="765" y="1100" name="U"/>
+ <outline>
+ <contour>
+ <point x="390" y="0" type="line"/>
+ <point x="494" y="420" type="line"/>
+ <point x="555" y="557"/>
+ <point x="727" y="773"/>
+ <point x="810" y="773" type="curve" smooth="yes"/>
+ <point x="864" y="773"/>
+ <point x="887" y="737"/>
+ <point x="887" y="678" type="curve" smooth="yes"/>
+ <point x="887" y="662"/>
+ <point x="885" y="644"/>
+ <point x="882" y="624" type="curve"/>
+ <point x="1114" y="658" type="line"/>
+ <point x="1123" y="706"/>
+ <point x="1136" y="752"/>
+ <point x="1136" y="794" type="curve" smooth="yes"/>
+ <point x="1136" y="931"/>
+ <point x="1084" y="1030"/>
+ <point x="963" y="1030" type="curve" smooth="yes"/>
+ <point x="828" y="1030"/>
+ <point x="670" y="883"/>
+ <point x="544" y="716" type="curve"/>
+ <point x="555" y="787"/>
+ <point x="570" y="960"/>
+ <point x="570" y="1010" type="curve"/>
+ <point x="295" y="1010" type="line"/>
+ <point x="295" y="962" type="line" smooth="yes"/>
+ <point x="295" y="894"/>
+ <point x="281" y="689"/>
+ <point x="261" y="609" type="curve" smooth="yes"/>
+ <point x="110" y="0" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/input/font-psf-test/source/PsfTest-BoldItalic.ufo/glyphs/L_tnS_mS_.glif b/tests/input/font-psf-test/source/PsfTest-BoldItalic.ufo/glyphs/L_tnS_mS_.glif
new file mode 100644
index 0000000..568c40a
--- /dev/null
+++ b/tests/input/font-psf-test/source/PsfTest-BoldItalic.ufo/glyphs/L_tnS_mS_.glif
@@ -0,0 +1,50 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmS" format="2">
+ <advance width="1015"/>
+ <unicode hex="0073"/>
+ <anchor x="455" y="0" name="H"/>
+ <anchor x="530" y="-100" name="L"/>
+ <anchor x="745" y="1100" name="U"/>
+ <outline>
+ <contour>
+ <point x="1058" y="952" type="line"/>
+ <point x="990" y="990"/>
+ <point x="854" y="1030"/>
+ <point x="691" y="1030" type="curve" smooth="yes"/>
+ <point x="457" y="1030"/>
+ <point x="217" y="936"/>
+ <point x="217" y="722" type="curve" smooth="yes"/>
+ <point x="217" y="593"/>
+ <point x="306" y="517"/>
+ <point x="501" y="430" type="curve" smooth="yes"/>
+ <point x="648" y="364"/>
+ <point x="710" y="345"/>
+ <point x="710" y="288" type="curve" smooth="yes"/>
+ <point x="710" y="224"/>
+ <point x="649" y="197"/>
+ <point x="549" y="197" type="curve" smooth="yes"/>
+ <point x="392" y="197"/>
+ <point x="276" y="280"/>
+ <point x="197" y="371" type="curve"/>
+ <point x="72" y="129" type="line"/>
+ <point x="143" y="68"/>
+ <point x="319" y="-25"/>
+ <point x="498" y="-25" type="curve" smooth="yes"/>
+ <point x="767" y="-25"/>
+ <point x="979" y="104"/>
+ <point x="979" y="315" type="curve" smooth="yes"/>
+ <point x="979" y="440"/>
+ <point x="884" y="513"/>
+ <point x="695" y="600" type="curve" smooth="yes"/>
+ <point x="581" y="652"/>
+ <point x="477" y="688"/>
+ <point x="477" y="743" type="curve" smooth="yes"/>
+ <point x="477" y="785"/>
+ <point x="548" y="808"/>
+ <point x="646" y="808" type="curve" smooth="yes"/>
+ <point x="785" y="808"/>
+ <point x="895" y="764"/>
+ <point x="961" y="716" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/input/font-psf-test/source/PsfTest-BoldItalic.ufo/glyphs/L_tnS_mT_.glif b/tests/input/font-psf-test/source/PsfTest-BoldItalic.ufo/glyphs/L_tnS_mT_.glif
new file mode 100644
index 0000000..c6a02c1
--- /dev/null
+++ b/tests/input/font-psf-test/source/PsfTest-BoldItalic.ufo/glyphs/L_tnS_mT_.glif
@@ -0,0 +1,45 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmT" format="2">
+ <advance width="900"/>
+ <unicode hex="0074"/>
+ <anchor x="470" y="0" name="H"/>
+ <anchor x="520" y="-100" name="L"/>
+ <anchor x="1075" y="1000" name="R"/>
+ <anchor x="640" y="1360" name="U"/>
+ <outline>
+ <contour>
+ <point x="831" y="278" type="line"/>
+ <point x="740" y="230"/>
+ <point x="670" y="204"/>
+ <point x="619" y="204" type="curve" smooth="yes"/>
+ <point x="556" y="204"/>
+ <point x="536" y="250"/>
+ <point x="536" y="318" type="curve" smooth="yes"/>
+ <point x="536" y="347"/>
+ <point x="539" y="380"/>
+ <point x="545" y="415" type="curve" smooth="yes"/>
+ <point x="567" y="549"/>
+ <point x="700" y="1039"/>
+ <point x="767" y="1307" type="curve"/>
+ <point x="487" y="1307" type="line"/>
+ <point x="419" y="1038"/>
+ <point x="265" y="471"/>
+ <point x="243" y="328" type="curve" smooth="yes"/>
+ <point x="239" y="302"/>
+ <point x="237" y="277"/>
+ <point x="237" y="253" type="curve" smooth="yes"/>
+ <point x="237" y="73"/>
+ <point x="351" y="-25"/>
+ <point x="518" y="-25" type="curve" smooth="yes"/>
+ <point x="590" y="-25"/>
+ <point x="703" y="-4"/>
+ <point x="812" y="55" type="curve"/>
+ </contour>
+ <contour>
+ <point x="945" y="797" type="line"/>
+ <point x="995" y="995" type="line"/>
+ <point x="220" y="995" type="line"/>
+ <point x="170" y="797" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/input/font-psf-test/source/PsfTest-BoldItalic.ufo/glyphs/L_tnS_mU_.glif b/tests/input/font-psf-test/source/PsfTest-BoldItalic.ufo/glyphs/L_tnS_mU_.glif
new file mode 100644
index 0000000..5067d38
--- /dev/null
+++ b/tests/input/font-psf-test/source/PsfTest-BoldItalic.ufo/glyphs/L_tnS_mU_.glif
@@ -0,0 +1,57 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmU" format="2">
+ <advance width="1257"/>
+ <unicode hex="0075"/>
+ <anchor x="455" y="0" name="H"/>
+ <anchor x="530" y="-100" name="L"/>
+ <anchor x="630" y="0" name="O"/>
+ <anchor x="1448" y="1000" name="R"/>
+ <anchor x="830" y="1100" name="U"/>
+ <outline>
+ <contour>
+ <point x="1117" y="0" type="line"/>
+ <point x="1113" y="29"/>
+ <point x="1112" y="62"/>
+ <point x="1112" y="100" type="curve" smooth="yes"/>
+ <point x="1112" y="206"/>
+ <point x="1131" y="341"/>
+ <point x="1157" y="455" type="curve" smooth="yes"/>
+ <point x="1212" y="689"/>
+ <point x="1274" y="905"/>
+ <point x="1282" y="1010" type="curve"/>
+ <point x="993" y="1010" type="line"/>
+ <point x="981" y="889"/>
+ <point x="992" y="918"/>
+ <point x="910" y="595" type="curve"/>
+ <point x="835" y="427"/>
+ <point x="618" y="205"/>
+ <point x="537" y="205" type="curve" smooth="yes"/>
+ <point x="491" y="205"/>
+ <point x="462" y="236"/>
+ <point x="462" y="308" type="curve" smooth="yes"/>
+ <point x="462" y="405"/>
+ <point x="536" y="663"/>
+ <point x="549" y="712" type="curve" smooth="yes"/>
+ <point x="583" y="847"/>
+ <point x="605" y="935"/>
+ <point x="610" y="1010" type="curve"/>
+ <point x="323" y="1010" type="line"/>
+ <point x="312" y="891"/>
+ <point x="296" y="819"/>
+ <point x="264" y="693" type="curve" smooth="yes"/>
+ <point x="191" y="401" type="line" smooth="yes"/>
+ <point x="173" y="330"/>
+ <point x="165" y="267"/>
+ <point x="165" y="214" type="curve" smooth="yes"/>
+ <point x="165" y="55"/>
+ <point x="252" y="-25"/>
+ <point x="381" y="-25" type="curve" smooth="yes"/>
+ <point x="545" y="-25"/>
+ <point x="769" y="160"/>
+ <point x="860" y="295" type="curve"/>
+ <point x="850" y="227"/>
+ <point x="842" y="53"/>
+ <point x="842" y="0" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/input/font-psf-test/source/PsfTest-BoldItalic.ufo/glyphs/L_tnS_mV_.glif b/tests/input/font-psf-test/source/PsfTest-BoldItalic.ufo/glyphs/L_tnS_mV_.glif
new file mode 100644
index 0000000..d7ceb46
--- /dev/null
+++ b/tests/input/font-psf-test/source/PsfTest-BoldItalic.ufo/glyphs/L_tnS_mV_.glif
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmV" format="2">
+ <advance width="1049"/>
+ <unicode hex="0076"/>
+ <anchor x="505" y="0" name="H"/>
+ <anchor x="410" y="-100" name="L"/>
+ <anchor x="690" y="0" name="O"/>
+ <anchor x="695" y="1100" name="U"/>
+ <outline>
+ <contour>
+ <point x="881" y="1010" type="line"/>
+ <point x="881" y="788"/>
+ <point x="719" y="534"/>
+ <point x="507" y="270" type="curve"/>
+ <point x="516" y="353"/>
+ <point x="521" y="457"/>
+ <point x="521" y="564" type="curve" smooth="yes"/>
+ <point x="521" y="730"/>
+ <point x="507" y="903"/>
+ <point x="472" y="1010" type="curve"/>
+ <point x="195" y="1010" type="line"/>
+ <point x="259" y="758"/>
+ <point x="282" y="509"/>
+ <point x="282" y="262" type="curve" smooth="yes"/>
+ <point x="282" y="174"/>
+ <point x="279" y="87"/>
+ <point x="274" y="0" type="curve"/>
+ <point x="535" y="0" type="line"/>
+ <point x="823" y="314"/>
+ <point x="1159" y="766"/>
+ <point x="1159" y="1010" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/input/font-psf-test/source/PsfTest-BoldItalic.ufo/glyphs/L_tnS_mW_.glif b/tests/input/font-psf-test/source/PsfTest-BoldItalic.ufo/glyphs/L_tnS_mW_.glif
new file mode 100644
index 0000000..02f3211
--- /dev/null
+++ b/tests/input/font-psf-test/source/PsfTest-BoldItalic.ufo/glyphs/L_tnS_mW_.glif
@@ -0,0 +1,50 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmW" format="2">
+ <advance width="1620"/>
+ <unicode hex="0077"/>
+ <anchor x="700" y="-100" name="L"/>
+ <anchor x="1000" y="1100" name="U"/>
+ <outline>
+ <contour>
+ <point x="850" y="1010" type="line"/>
+ <point x="758" y="793"/>
+ <point x="592" y="496"/>
+ <point x="438" y="242" type="curve"/>
+ <point x="459" y="351"/>
+ <point x="476" y="509"/>
+ <point x="476" y="669" type="curve" smooth="yes"/>
+ <point x="476" y="788"/>
+ <point x="468" y="908"/>
+ <point x="448" y="1010" type="curve"/>
+ <point x="190" y="1010" type="line"/>
+ <point x="230" y="831"/>
+ <point x="236" y="678"/>
+ <point x="236" y="494" type="curve" smooth="yes"/>
+ <point x="236" y="364"/>
+ <point x="228" y="211"/>
+ <point x="209" y="0" type="curve"/>
+ <point x="499" y="0" type="line"/>
+ <point x="624" y="181"/>
+ <point x="838" y="560"/>
+ <point x="901" y="690" type="curve"/>
+ <point x="919" y="477"/>
+ <point x="919" y="212"/>
+ <point x="919" y="0" type="curve"/>
+ <point x="1179" y="0" type="line"/>
+ <point x="1430" y="328"/>
+ <point x="1710" y="775"/>
+ <point x="1710" y="1010" type="curve"/>
+ <point x="1432" y="1010" type="line"/>
+ <point x="1432" y="995" type="line" smooth="yes"/>
+ <point x="1432" y="797"/>
+ <point x="1245" y="435"/>
+ <point x="1106" y="242" type="curve"/>
+ <point x="1108" y="298"/>
+ <point x="1108" y="355"/>
+ <point x="1108" y="411" type="curve" smooth="yes"/>
+ <point x="1108" y="637"/>
+ <point x="1096" y="860"/>
+ <point x="1070" y="1010" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/input/font-psf-test/source/PsfTest-BoldItalic.ufo/glyphs/L_tnS_mX_.glif b/tests/input/font-psf-test/source/PsfTest-BoldItalic.ufo/glyphs/L_tnS_mX_.glif
new file mode 100644
index 0000000..2e620de
--- /dev/null
+++ b/tests/input/font-psf-test/source/PsfTest-BoldItalic.ufo/glyphs/L_tnS_mX_.glif
@@ -0,0 +1,40 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmX" format="2">
+ <advance width="1104"/>
+ <unicode hex="0078"/>
+ <anchor x="900" y="0" name="H"/>
+ <anchor x="505" y="-100" name="L"/>
+ <anchor x="730" y="1100" name="U"/>
+ <outline>
+ <contour>
+ <point x="1040" y="0" type="line"/>
+ <point x="860" y="133"/>
+ <point x="655" y="882"/>
+ <point x="524" y="1010" type="curve"/>
+ <point x="186" y="1010" type="line"/>
+ <point x="425" y="832"/>
+ <point x="593" y="141"/>
+ <point x="713" y="0" type="curve"/>
+ </contour>
+ <contour>
+ <point x="509" y="572" type="line"/>
+ <point x="291" y="463"/>
+ <point x="62" y="230"/>
+ <point x="35" y="0" type="curve"/>
+ <point x="335" y="0" type="line"/>
+ <point x="336" y="156"/>
+ <point x="470" y="390"/>
+ <point x="658" y="477" type="curve"/>
+ </contour>
+ <contour>
+ <point x="764" y="471" type="line"/>
+ <point x="943" y="591"/>
+ <point x="1197" y="808"/>
+ <point x="1204" y="1010" type="curve"/>
+ <point x="894" y="1010" type="line"/>
+ <point x="894" y="852"/>
+ <point x="773" y="665"/>
+ <point x="616" y="571" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/input/font-psf-test/source/PsfTest-BoldItalic.ufo/glyphs/L_tnS_mY_.glif b/tests/input/font-psf-test/source/PsfTest-BoldItalic.ufo/glyphs/L_tnS_mY_.glif
new file mode 100644
index 0000000..f2ae46b
--- /dev/null
+++ b/tests/input/font-psf-test/source/PsfTest-BoldItalic.ufo/glyphs/L_tnS_mY_.glif
@@ -0,0 +1,45 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmY" format="2">
+ <advance width="1041"/>
+ <unicode hex="0079"/>
+ <anchor x="810" y="-100" name="L"/>
+ <anchor x="1325" y="1000" name="R"/>
+ <anchor x="640" y="1100" name="U"/>
+ <outline>
+ <contour>
+ <point x="847" y="1010" type="line"/>
+ <point x="851" y="994"/>
+ <point x="852" y="977"/>
+ <point x="852" y="958" type="curve" smooth="yes"/>
+ <point x="852" y="786"/>
+ <point x="713" y="473"/>
+ <point x="596" y="260" type="curve"/>
+ <point x="596" y="478"/>
+ <point x="503" y="877"/>
+ <point x="403" y="1010" type="curve"/>
+ <point x="120" y="1010" type="line"/>
+ <point x="259" y="811"/>
+ <point x="401" y="401"/>
+ <point x="409" y="-18" type="curve"/>
+ <point x="283" y="-207"/>
+ <point x="183" y="-250"/>
+ <point x="114" y="-250" type="curve" smooth="yes"/>
+ <point x="48" y="-250"/>
+ <point x="-33" y="-201"/>
+ <point x="-63" y="-165" type="curve"/>
+ <point x="-195" y="-381" type="line"/>
+ <point x="-136" y="-435"/>
+ <point x="-13" y="-465"/>
+ <point x="78" y="-465" type="curve" smooth="yes"/>
+ <point x="260" y="-465"/>
+ <point x="447" y="-385"/>
+ <point x="684" y="0" type="curve" smooth="yes"/>
+ <point x="919" y="381"/>
+ <point x="1116" y="766"/>
+ <point x="1116" y="960" type="curve" smooth="yes"/>
+ <point x="1116" y="978"/>
+ <point x="1114" y="995"/>
+ <point x="1110" y="1010" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/input/font-psf-test/source/PsfTest-BoldItalic.ufo/glyphs/N_onB_reakingH_yphen.glif b/tests/input/font-psf-test/source/PsfTest-BoldItalic.ufo/glyphs/N_onB_reakingH_yphen.glif
new file mode 100644
index 0000000..cd90adf
--- /dev/null
+++ b/tests/input/font-psf-test/source/PsfTest-BoldItalic.ufo/glyphs/N_onB_reakingH_yphen.glif
@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="NonBreakingHyphen" format="2">
+ <advance width="875"/>
+ <unicode hex="2011"/>
+ <anchor x="665" y="1100" name="U"/>
+ <outline>
+ <component base="HyphenMinus"/>
+ </outline>
+</glyph>
diff --git a/tests/input/font-psf-test/source/PsfTest-BoldItalic.ufo/glyphs/N_umS_gn.glif b/tests/input/font-psf-test/source/PsfTest-BoldItalic.ufo/glyphs/N_umS_gn.glif
new file mode 100644
index 0000000..1d3e5e9
--- /dev/null
+++ b/tests/input/font-psf-test/source/PsfTest-BoldItalic.ufo/glyphs/N_umS_gn.glif
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="NumSgn" format="2">
+ <advance width="1180"/>
+ <unicode hex="0023"/>
+ <outline>
+ <contour>
+ <point x="667" y="1346" type="line"/>
+ <point x="16" y="99" type="line"/>
+ <point x="256" y="99" type="line"/>
+ <point x="907" y="1346" type="line"/>
+ </contour>
+ <contour>
+ <point x="54" y="421" type="line"/>
+ <point x="1145" y="421" type="line"/>
+ <point x="1197" y="629" type="line"/>
+ <point x="106" y="629" type="line"/>
+ </contour>
+ <contour>
+ <point x="218" y="841" type="line"/>
+ <point x="1309" y="841" type="line"/>
+ <point x="1361" y="1049" type="line"/>
+ <point x="270" y="1049" type="line"/>
+ </contour>
+ <contour>
+ <point x="1142" y="1346" type="line"/>
+ <point x="491" y="99" type="line"/>
+ <point x="731" y="99" type="line"/>
+ <point x="1382" y="1346" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/input/font-psf-test/source/PsfTest-BoldItalic.ufo/glyphs/P_ercentS_gn.glif b/tests/input/font-psf-test/source/PsfTest-BoldItalic.ufo/glyphs/P_ercentS_gn.glif
new file mode 100644
index 0000000..f87ea9f
--- /dev/null
+++ b/tests/input/font-psf-test/source/PsfTest-BoldItalic.ufo/glyphs/P_ercentS_gn.glif
@@ -0,0 +1,93 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="PercentSgn" format="2">
+ <advance width="1545"/>
+ <unicode hex="0025"/>
+ <outline>
+ <contour>
+ <point x="1375" y="1465" type="line"/>
+ <point x="221" y="-25" type="line"/>
+ <point x="435" y="-25" type="line"/>
+ <point x="1587" y="1465" type="line"/>
+ </contour>
+ <contour>
+ <point x="714" y="1043" type="curve" smooth="yes"/>
+ <point x="669" y="861"/>
+ <point x="611" y="807"/>
+ <point x="535" y="807" type="curve" smooth="yes"/>
+ <point x="486" y="807"/>
+ <point x="461" y="843"/>
+ <point x="461" y="917" type="curve" smooth="yes"/>
+ <point x="461" y="963"/>
+ <point x="471" y="1023"/>
+ <point x="490" y="1099" type="curve" smooth="yes"/>
+ <point x="535" y="1281"/>
+ <point x="580" y="1336"/>
+ <point x="657" y="1336" type="curve" smooth="yes"/>
+ <point x="710" y="1336"/>
+ <point x="739" y="1296"/>
+ <point x="739" y="1212" type="curve" smooth="yes"/>
+ <point x="739" y="1168"/>
+ <point x="731" y="1111"/>
+ </contour>
+ <contour>
+ <point x="926" y="1054" type="curve" smooth="yes"/>
+ <point x="939" y="1107"/>
+ <point x="946" y="1156"/>
+ <point x="946" y="1199" type="curve" smooth="yes"/>
+ <point x="946" y="1374"/>
+ <point x="842" y="1465"/>
+ <point x="694" y="1465" type="curve" smooth="yes"/>
+ <point x="510" y="1465"/>
+ <point x="346" y="1369"/>
+ <point x="277" y="1090" type="curve" smooth="yes"/>
+ <point x="262" y="1031"/>
+ <point x="255" y="979"/>
+ <point x="255" y="933" type="curve" smooth="yes"/>
+ <point x="255" y="761"/>
+ <point x="353" y="678"/>
+ <point x="499" y="678" type="curve" smooth="yes"/>
+ <point x="684" y="678"/>
+ <point x="853" y="762"/>
+ </contour>
+ <contour>
+ <point x="1314" y="337" type="curve" smooth="yes"/>
+ <point x="1268" y="155"/>
+ <point x="1220" y="104"/>
+ <point x="1144" y="104" type="curve" smooth="yes"/>
+ <point x="1093" y="104"/>
+ <point x="1065" y="144"/>
+ <point x="1065" y="227" type="curve" smooth="yes"/>
+ <point x="1065" y="272"/>
+ <point x="1073" y="329"/>
+ <point x="1090" y="398" type="curve" smooth="yes"/>
+ <point x="1136" y="580"/>
+ <point x="1190" y="634"/>
+ <point x="1267" y="634" type="curve" smooth="yes"/>
+ <point x="1317" y="634"/>
+ <point x="1342" y="596"/>
+ <point x="1342" y="520" type="curve" smooth="yes"/>
+ <point x="1342" y="473"/>
+ <point x="1333" y="412"/>
+ </contour>
+ <contour>
+ <point x="1526" y="350" type="curve" smooth="yes"/>
+ <point x="1540" y="406"/>
+ <point x="1546" y="456"/>
+ <point x="1546" y="501" type="curve" smooth="yes"/>
+ <point x="1546" y="673"/>
+ <point x="1450" y="762"/>
+ <point x="1303" y="762" type="curve" smooth="yes"/>
+ <point x="1119" y="762"/>
+ <point x="946" y="665"/>
+ <point x="876" y="386" type="curve" smooth="yes"/>
+ <point x="862" y="331"/>
+ <point x="856" y="281"/>
+ <point x="856" y="237" type="curve" smooth="yes"/>
+ <point x="856" y="60"/>
+ <point x="960" y="-25"/>
+ <point x="1108" y="-25" type="curve" smooth="yes"/>
+ <point x="1293" y="-25"/>
+ <point x="1453" y="58"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/input/font-psf-test/source/PsfTest-BoldItalic.ufo/glyphs/P_lusS_gn.glif b/tests/input/font-psf-test/source/PsfTest-BoldItalic.ufo/glyphs/P_lusS_gn.glif
new file mode 100644
index 0000000..bb54e70
--- /dev/null
+++ b/tests/input/font-psf-test/source/PsfTest-BoldItalic.ufo/glyphs/P_lusS_gn.glif
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="PlusSgn" format="2">
+ <advance width="1180"/>
+ <unicode hex="002B"/>
+ <outline>
+ <contour>
+ <point x="722" y="1168" type="line"/>
+ <point x="500" y="282" type="line"/>
+ <point x="715" y="282" type="line"/>
+ <point x="936" y="1168" type="line"/>
+ </contour>
+ <contour>
+ <point x="250" y="624" type="line"/>
+ <point x="1140" y="624" type="line"/>
+ <point x="1192" y="832" type="line"/>
+ <point x="302" y="832" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/input/font-psf-test/source/PsfTest-BoldItalic.ufo/glyphs/Q_stnM_rk.glif b/tests/input/font-psf-test/source/PsfTest-BoldItalic.ufo/glyphs/Q_stnM_rk.glif
new file mode 100644
index 0000000..5acaded
--- /dev/null
+++ b/tests/input/font-psf-test/source/PsfTest-BoldItalic.ufo/glyphs/Q_stnM_rk.glif
@@ -0,0 +1,49 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="QstnMrk" format="2">
+ <advance width="1070"/>
+ <unicode hex="003F"/>
+ <outline>
+ <contour>
+ <point x="703" y="495" type="line"/>
+ <point x="745" y="664"/>
+ <point x="787" y="792"/>
+ <point x="931" y="933" type="curve" smooth="yes"/>
+ <point x="1034" y="1033"/>
+ <point x="1143" y="1118"/>
+ <point x="1143" y="1256" type="curve" smooth="yes"/>
+ <point x="1143" y="1404"/>
+ <point x="1022" y="1525"/>
+ <point x="800" y="1525" type="curve" smooth="yes"/>
+ <point x="675" y="1525"/>
+ <point x="508" y="1455"/>
+ <point x="427" y="1393" type="curve"/>
+ <point x="413" y="1156" type="line"/>
+ <point x="508" y="1235"/>
+ <point x="621" y="1282"/>
+ <point x="721" y="1282" type="curve" smooth="yes"/>
+ <point x="811" y="1282"/>
+ <point x="846" y="1238"/>
+ <point x="846" y="1189" type="curve" smooth="yes"/>
+ <point x="846" y="1109"/>
+ <point x="760" y="1086"/>
+ <point x="650" y="956" type="curve" smooth="yes"/>
+ <point x="564" y="855"/>
+ <point x="490" y="703"/>
+ <point x="438" y="495" type="curve"/>
+ </contour>
+ <contour>
+ <point x="306" y="116" type="curve" smooth="yes"/>
+ <point x="306" y="35"/>
+ <point x="367" y="-25"/>
+ <point x="453" y="-25" type="curve" smooth="yes"/>
+ <point x="571" y="-25"/>
+ <point x="666" y="71"/>
+ <point x="666" y="181" type="curve" smooth="yes"/>
+ <point x="666" y="261"/>
+ <point x="607" y="322"/>
+ <point x="520" y="322" type="curve" smooth="yes"/>
+ <point x="403" y="322"/>
+ <point x="306" y="226"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/input/font-psf-test/source/PsfTest-BoldItalic.ufo/glyphs/Q_uotM_rk.glif b/tests/input/font-psf-test/source/PsfTest-BoldItalic.ufo/glyphs/Q_uotM_rk.glif
new file mode 100644
index 0000000..f33fd18
--- /dev/null
+++ b/tests/input/font-psf-test/source/PsfTest-BoldItalic.ufo/glyphs/Q_uotM_rk.glif
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="QuotMrk" format="2">
+ <advance width="1065"/>
+ <unicode hex="0022"/>
+ <outline>
+ <contour>
+ <point x="648" y="1035" type="line"/>
+ <point x="687" y="1174"/>
+ <point x="726" y="1326"/>
+ <point x="816" y="1569" type="curve"/>
+ <point x="571" y="1569" type="line"/>
+ <point x="541" y="1326"/>
+ <point x="503" y="1174"/>
+ <point x="473" y="1035" type="curve"/>
+ </contour>
+ <contour>
+ <point x="1008" y="1035" type="line"/>
+ <point x="1047" y="1174"/>
+ <point x="1086" y="1326"/>
+ <point x="1176" y="1569" type="curve"/>
+ <point x="931" y="1569" type="line"/>
+ <point x="901" y="1326"/>
+ <point x="863" y="1174"/>
+ <point x="833" y="1035" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/input/font-psf-test/source/PsfTest-BoldItalic.ufo/glyphs/R_everseS_olidus.glif b/tests/input/font-psf-test/source/PsfTest-BoldItalic.ufo/glyphs/R_everseS_olidus.glif
new file mode 100644
index 0000000..0068c20
--- /dev/null
+++ b/tests/input/font-psf-test/source/PsfTest-BoldItalic.ufo/glyphs/R_everseS_olidus.glif
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="ReverseSolidus" format="2">
+ <advance width="1060"/>
+ <unicode hex="005C"/>
+ <outline>
+ <contour>
+ <point x="344" y="1584" type="line"/>
+ <point x="719" y="-243" type="line"/>
+ <point x="949" y="-243" type="line"/>
+ <point x="574" y="1584" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/input/font-psf-test/source/PsfTest-BoldItalic.ufo/glyphs/R_tC_urlyB_rac.glif b/tests/input/font-psf-test/source/PsfTest-BoldItalic.ufo/glyphs/R_tC_urlyB_rac.glif
new file mode 100644
index 0000000..726adad
--- /dev/null
+++ b/tests/input/font-psf-test/source/PsfTest-BoldItalic.ufo/glyphs/R_tC_urlyB_rac.glif
@@ -0,0 +1,47 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="RtCurlyBrac" format="2">
+ <advance width="1020"/>
+ <unicode hex="007D"/>
+ <outline>
+ <contour>
+ <point x="442" y="1395" type="line"/>
+ <point x="513" y="1366"/>
+ <point x="611" y="1344"/>
+ <point x="611" y="1296" type="curve" smooth="yes"/>
+ <point x="611" y="1200"/>
+ <point x="515" y="837"/>
+ <point x="515" y="782" type="curve" smooth="yes"/>
+ <point x="515" y="743"/>
+ <point x="633" y="649"/>
+ <point x="633" y="613" type="curve" smooth="yes"/>
+ <point x="633" y="573"/>
+ <point x="465" y="486"/>
+ <point x="429" y="441" type="curve" smooth="yes"/>
+ <point x="403" y="407"/>
+ <point x="300" y="-59"/>
+ <point x="255" y="-99" type="curve" smooth="yes"/>
+ <point x="230" y="-121"/>
+ <point x="97" y="-158"/>
+ <point x="25" y="-177" type="curve"/>
+ <point x="17" y="-406" type="line"/>
+ <point x="160" y="-379"/>
+ <point x="377" y="-330"/>
+ <point x="439" y="-282" type="curve" smooth="yes"/>
+ <point x="532" y="-211"/>
+ <point x="666" y="374"/>
+ <point x="696" y="406" type="curve" smooth="yes"/>
+ <point x="734" y="446"/>
+ <point x="947" y="559"/>
+ <point x="947" y="616" type="curve" smooth="yes"/>
+ <point x="947" y="676"/>
+ <point x="796" y="783"/>
+ <point x="796" y="819" type="curve" smooth="yes"/>
+ <point x="796" y="880"/>
+ <point x="896" y="1288"/>
+ <point x="896" y="1453" type="curve" smooth="yes"/>
+ <point x="896" y="1529"/>
+ <point x="709" y="1591"/>
+ <point x="549" y="1624" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/input/font-psf-test/source/PsfTest-BoldItalic.ufo/glyphs/R_tP_aren.glif b/tests/input/font-psf-test/source/PsfTest-BoldItalic.ufo/glyphs/R_tP_aren.glif
new file mode 100644
index 0000000..544faff
--- /dev/null
+++ b/tests/input/font-psf-test/source/PsfTest-BoldItalic.ufo/glyphs/R_tP_aren.glif
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="RtParen" format="2">
+ <advance width="840"/>
+ <unicode hex="0029"/>
+ <outline>
+ <contour>
+ <point x="476" y="1411" type="line"/>
+ <point x="572" y="1290"/>
+ <point x="616" y="1127"/>
+ <point x="616" y="944" type="curve" smooth="yes"/>
+ <point x="616" y="832"/>
+ <point x="599" y="712"/>
+ <point x="569" y="589" type="curve" smooth="yes"/>
+ <point x="491" y="275"/>
+ <point x="333" y="48"/>
+ <point x="75" y="-198" type="curve"/>
+ <point x="163" y="-406" type="line"/>
+ <point x="509" y="-124"/>
+ <point x="743" y="206"/>
+ <point x="844" y="609" type="curve" smooth="yes"/>
+ <point x="876" y="735"/>
+ <point x="891" y="858"/>
+ <point x="891" y="973" type="curve" smooth="yes"/>
+ <point x="891" y="1252"/>
+ <point x="803" y="1487"/>
+ <point x="649" y="1624" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/input/font-psf-test/source/PsfTest-BoldItalic.ufo/glyphs/R_tS_qrB_rac.glif b/tests/input/font-psf-test/source/PsfTest-BoldItalic.ufo/glyphs/R_tS_qrB_rac.glif
new file mode 100644
index 0000000..804527d
--- /dev/null
+++ b/tests/input/font-psf-test/source/PsfTest-BoldItalic.ufo/glyphs/R_tS_qrB_rac.glif
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="RtSqrBrac" format="2">
+ <advance width="830"/>
+ <unicode hex="005D"/>
+ <outline>
+ <contour>
+ <point x="503" y="-406" type="line"/>
+ <point x="994" y="1584" type="line"/>
+ <point x="474" y="1584" type="line"/>
+ <point x="423" y="1376" type="line"/>
+ <point x="663" y="1376" type="line"/>
+ <point x="275" y="-198" type="line"/>
+ <point x="35" y="-198" type="line"/>
+ <point x="-17" y="-406" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/input/font-psf-test/source/PsfTest-BoldItalic.ufo/glyphs/S_emicolon.glif b/tests/input/font-psf-test/source/PsfTest-BoldItalic.ufo/glyphs/S_emicolon.glif
new file mode 100644
index 0000000..1c9af02
--- /dev/null
+++ b/tests/input/font-psf-test/source/PsfTest-BoldItalic.ufo/glyphs/S_emicolon.glif
@@ -0,0 +1,38 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="Semicolon" format="2">
+ <advance width="690"/>
+ <unicode hex="003B"/>
+ <outline>
+ <contour>
+ <point x="137" y="49" type="line"/>
+ <point x="297" y="49" type="line"/>
+ <point x="276" y="-34"/>
+ <point x="192" y="-151"/>
+ <point x="59" y="-262" type="curve"/>
+ <point x="187" y="-332" type="line"/>
+ <point x="337" y="-222"/>
+ <point x="539" y="-11"/>
+ <point x="539" y="165" type="curve" smooth="yes"/>
+ <point x="539" y="262"/>
+ <point x="495" y="337"/>
+ <point x="379" y="337" type="curve" smooth="yes"/>
+ <point x="266" y="337"/>
+ <point x="187" y="252"/>
+ <point x="169" y="178" type="curve" smooth="yes"/>
+ </contour>
+ <contour>
+ <point x="319" y="710" type="curve" smooth="yes"/>
+ <point x="319" y="629"/>
+ <point x="380" y="569"/>
+ <point x="466" y="569" type="curve" smooth="yes"/>
+ <point x="584" y="569"/>
+ <point x="679" y="665"/>
+ <point x="679" y="775" type="curve" smooth="yes"/>
+ <point x="679" y="855"/>
+ <point x="620" y="916"/>
+ <point x="533" y="916" type="curve" smooth="yes"/>
+ <point x="416" y="916"/>
+ <point x="319" y="820"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/input/font-psf-test/source/PsfTest-BoldItalic.ufo/glyphs/S_olidus.glif b/tests/input/font-psf-test/source/PsfTest-BoldItalic.ufo/glyphs/S_olidus.glif
new file mode 100644
index 0000000..0bac67c
--- /dev/null
+++ b/tests/input/font-psf-test/source/PsfTest-BoldItalic.ufo/glyphs/S_olidus.glif
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="Solidus" format="2">
+ <advance width="1060"/>
+ <unicode hex="002F"/>
+ <outline>
+ <contour>
+ <point x="1164" y="1584" type="line"/>
+ <point x="-120" y="-243" type="line"/>
+ <point x="129" y="-243" type="line"/>
+ <point x="1414" y="1584" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/input/font-psf-test/source/PsfTest-BoldItalic.ufo/glyphs/S_pace.glif b/tests/input/font-psf-test/source/PsfTest-BoldItalic.ufo/glyphs/S_pace.glif
new file mode 100644
index 0000000..c49f0f2
--- /dev/null
+++ b/tests/input/font-psf-test/source/PsfTest-BoldItalic.ufo/glyphs/S_pace.glif
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="Space" format="2">
+ <advance width="530"/>
+ <unicode hex="0020"/>
+ <outline/>
+</glyph>
diff --git a/tests/input/font-psf-test/source/PsfTest-BoldItalic.ufo/glyphs/T_ilde.glif b/tests/input/font-psf-test/source/PsfTest-BoldItalic.ufo/glyphs/T_ilde.glif
new file mode 100644
index 0000000..26c105f
--- /dev/null
+++ b/tests/input/font-psf-test/source/PsfTest-BoldItalic.ufo/glyphs/T_ilde.glif
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="Tilde" format="2">
+ <advance width="1155"/>
+ <unicode hex="007E"/>
+ <outline>
+ <contour>
+ <point x="190" y="342" type="line"/>
+ <point x="207" y="390"/>
+ <point x="249" y="431"/>
+ <point x="327" y="431" type="curve" smooth="yes"/>
+ <point x="502" y="431"/>
+ <point x="676" y="327"/>
+ <point x="906" y="327" type="curve" smooth="yes"/>
+ <point x="1065" y="327"/>
+ <point x="1206" y="507"/>
+ <point x="1238" y="634" type="curve"/>
+ <point x="1093" y="634" type="line"/>
+ <point x="1074" y="588"/>
+ <point x="1031" y="535"/>
+ <point x="948" y="535" type="curve" smooth="yes"/>
+ <point x="712" y="535"/>
+ <point x="580" y="639"/>
+ <point x="359" y="639" type="curve" smooth="yes"/>
+ <point x="203" y="639"/>
+ <point x="75" y="462"/>
+ <point x="45" y="342" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/input/font-psf-test/source/PsfTest-BoldItalic.ufo/glyphs/V_ertL_ine.glif b/tests/input/font-psf-test/source/PsfTest-BoldItalic.ufo/glyphs/V_ertL_ine.glif
new file mode 100644
index 0000000..204ac86
--- /dev/null
+++ b/tests/input/font-psf-test/source/PsfTest-BoldItalic.ufo/glyphs/V_ertL_ine.glif
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="VertLine" format="2">
+ <advance width="670"/>
+ <unicode hex="007C"/>
+ <outline>
+ <contour>
+ <point x="574" y="1594" type="line"/>
+ <point x="83" y="-396" type="line"/>
+ <point x="293" y="-396" type="line"/>
+ <point x="784" y="1594" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/input/font-psf-test/source/PsfTest-BoldItalic.ufo/glyphs/_notdef.glif b/tests/input/font-psf-test/source/PsfTest-BoldItalic.ufo/glyphs/_notdef.glif
new file mode 100644
index 0000000..a3e9354
--- /dev/null
+++ b/tests/input/font-psf-test/source/PsfTest-BoldItalic.ufo/glyphs/_notdef.glif
@@ -0,0 +1,18 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name=".notdef" format="2">
+ <advance width="1400"/>
+ <outline>
+ <contour>
+ <point x="100" y="0" type="line"/>
+ <point x="1300" y="0" type="line"/>
+ <point x="1300" y="1800" type="line"/>
+ <point x="100" y="1800" type="line"/>
+ </contour>
+ <contour>
+ <point x="150" y="1750" type="line"/>
+ <point x="1250" y="1750" type="line"/>
+ <point x="1250" y="50" type="line"/>
+ <point x="150" y="50" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/input/font-psf-test/source/PsfTest-BoldItalic.ufo/glyphs/_null.glif b/tests/input/font-psf-test/source/PsfTest-BoldItalic.ufo/glyphs/_null.glif
new file mode 100644
index 0000000..0b9caa6
--- /dev/null
+++ b/tests/input/font-psf-test/source/PsfTest-BoldItalic.ufo/glyphs/_null.glif
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name=".null" format="2">
+ <outline/>
+</glyph>
diff --git a/tests/input/font-psf-test/source/PsfTest-BoldItalic.ufo/glyphs/contents.plist b/tests/input/font-psf-test/source/PsfTest-BoldItalic.ufo/glyphs/contents.plist
new file mode 100644
index 0000000..ad2aa41
--- /dev/null
+++ b/tests/input/font-psf-test/source/PsfTest-BoldItalic.ufo/glyphs/contents.plist
@@ -0,0 +1,232 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+ <key>.notdef</key>
+ <string>_notdef.glif</string>
+ <key>.null</key>
+ <string>_null.glif</string>
+ <key>Ampersand</key>
+ <string>A_mpersand.glif</string>
+ <key>Apos</key>
+ <string>A_pos.glif</string>
+ <key>Asterisk</key>
+ <string>A_sterisk.glif</string>
+ <key>AtSgn</key>
+ <string>A_tS_gn.glif</string>
+ <key>CircumAccent</key>
+ <string>C_ircumA_ccent.glif</string>
+ <key>Colon</key>
+ <string>C_olon.glif</string>
+ <key>CombAcute</key>
+ <string>C_ombA_cute.glif</string>
+ <key>CombCircum</key>
+ <string>C_ombC_ircum.glif</string>
+ <key>CombDiaer</key>
+ <string>C_ombD_iaer.glif</string>
+ <key>CombGrave</key>
+ <string>C_ombG_rave.glif</string>
+ <key>CombRingAbv</key>
+ <string>C_ombR_ingA_bv.glif</string>
+ <key>CombTilde</key>
+ <string>C_ombT_ilde.glif</string>
+ <key>Comma</key>
+ <string>C_omma.glif</string>
+ <key>DigitEight</key>
+ <string>D_igitE_ight.glif</string>
+ <key>DigitFive</key>
+ <string>D_igitF_ive.glif</string>
+ <key>DigitFour</key>
+ <string>D_igitF_our.glif</string>
+ <key>DigitNine</key>
+ <string>D_igitN_ine.glif</string>
+ <key>DigitOne</key>
+ <string>D_igitO_ne.glif</string>
+ <key>DigitSeven</key>
+ <string>D_igitS_even.glif</string>
+ <key>DigitSix</key>
+ <string>D_igitS_ix.glif</string>
+ <key>DigitThree</key>
+ <string>D_igitT_hree.glif</string>
+ <key>DigitTwo</key>
+ <string>D_igitT_wo.glif</string>
+ <key>DigitZero</key>
+ <string>D_igitZ_ero.glif</string>
+ <key>DollarSgn</key>
+ <string>D_ollarS_gn.glif</string>
+ <key>DottedCirc</key>
+ <string>D_ottedC_irc.glif</string>
+ <key>EqSgn</key>
+ <string>E_qS_gn.glif</string>
+ <key>ExclamationMrk</key>
+ <string>E_xclamationM_rk.glif</string>
+ <key>FullStop</key>
+ <string>F_ullS_top.glif</string>
+ <key>GTSgn</key>
+ <string>G_T_S_gn.glif</string>
+ <key>GraveAccent</key>
+ <string>G_raveA_ccent.glif</string>
+ <key>Hyphen</key>
+ <string>H_yphen.glif</string>
+ <key>HyphenMinus</key>
+ <string>H_yphenM_inus.glif</string>
+ <key>Hyphen_Soft</key>
+ <string>H_yphen_S_oft.glif</string>
+ <key>LTSgn</key>
+ <string>L_T_S_gn.glif</string>
+ <key>LftCurlyBrac</key>
+ <string>L_ftC_urlyB_rac.glif</string>
+ <key>LftParen</key>
+ <string>L_ftP_aren.glif</string>
+ <key>LftSqrBrac</key>
+ <string>L_ftS_qrB_rac.glif</string>
+ <key>LowLine</key>
+ <string>L_owL_ine.glif</string>
+ <key>LtnCapA</key>
+ <string>L_tnC_apA_.glif</string>
+ <key>LtnCapADiaer</key>
+ <string>L_tnC_apA_D_iaer.glif</string>
+ <key>LtnCapB</key>
+ <string>L_tnC_apB_.glif</string>
+ <key>LtnCapC</key>
+ <string>L_tnC_apC_.glif</string>
+ <key>LtnCapD</key>
+ <string>L_tnC_apD_.glif</string>
+ <key>LtnCapE</key>
+ <string>L_tnC_apE_.glif</string>
+ <key>LtnCapF</key>
+ <string>L_tnC_apF_.glif</string>
+ <key>LtnCapG</key>
+ <string>L_tnC_apG_.glif</string>
+ <key>LtnCapH</key>
+ <string>L_tnC_apH_.glif</string>
+ <key>LtnCapI</key>
+ <string>L_tnC_apI_.glif</string>
+ <key>LtnCapJ</key>
+ <string>L_tnC_apJ_.glif</string>
+ <key>LtnCapK</key>
+ <string>L_tnC_apK_.glif</string>
+ <key>LtnCapL</key>
+ <string>L_tnC_apL_.glif</string>
+ <key>LtnCapM</key>
+ <string>L_tnC_apM_.glif</string>
+ <key>LtnCapN</key>
+ <string>L_tnC_apN_.glif</string>
+ <key>LtnCapO</key>
+ <string>L_tnC_apO_.glif</string>
+ <key>LtnCapP</key>
+ <string>L_tnC_apP_.glif</string>
+ <key>LtnCapQ</key>
+ <string>L_tnC_apQ_.glif</string>
+ <key>LtnCapR</key>
+ <string>L_tnC_apR_.glif</string>
+ <key>LtnCapS</key>
+ <string>L_tnC_apS_.glif</string>
+ <key>LtnCapT</key>
+ <string>L_tnC_apT_.glif</string>
+ <key>LtnCapU</key>
+ <string>L_tnC_apU_.glif</string>
+ <key>LtnCapV</key>
+ <string>L_tnC_apV_.glif</string>
+ <key>LtnCapW</key>
+ <string>L_tnC_apW_.glif</string>
+ <key>LtnCapX</key>
+ <string>L_tnC_apX_.glif</string>
+ <key>LtnCapY</key>
+ <string>L_tnC_apY_.glif</string>
+ <key>LtnSmA</key>
+ <string>L_tnS_mA_.glif</string>
+ <key>LtnSmAAcute</key>
+ <string>L_tnS_mA_A_cute.glif</string>
+ <key>LtnSmACircum</key>
+ <string>L_tnS_mA_C_ircum.glif</string>
+ <key>LtnSmADiaer</key>
+ <string>L_tnS_mA_D_iaer.glif</string>
+ <key>LtnSmAGrave</key>
+ <string>L_tnS_mA_G_rave.glif</string>
+ <key>LtnSmARingAbv</key>
+ <string>L_tnS_mA_R_ingA_bv.glif</string>
+ <key>LtnSmATilde</key>
+ <string>L_tnS_mA_T_ilde.glif</string>
+ <key>LtnSmB</key>
+ <string>L_tnS_mB_.glif</string>
+ <key>LtnSmC</key>
+ <string>L_tnS_mC_.glif</string>
+ <key>LtnSmD</key>
+ <string>L_tnS_mD_.glif</string>
+ <key>LtnSmE</key>
+ <string>L_tnS_mE_.glif</string>
+ <key>LtnSmF</key>
+ <string>L_tnS_mF_.glif</string>
+ <key>LtnSmG</key>
+ <string>L_tnS_mG_.glif</string>
+ <key>LtnSmH</key>
+ <string>L_tnS_mH_.glif</string>
+ <key>LtnSmI</key>
+ <string>L_tnS_mI_.glif</string>
+ <key>LtnSmJ</key>
+ <string>L_tnS_mJ_.glif</string>
+ <key>LtnSmK</key>
+ <string>L_tnS_mK_.glif</string>
+ <key>LtnSmL</key>
+ <string>L_tnS_mL_.glif</string>
+ <key>LtnSmM</key>
+ <string>L_tnS_mM_.glif</string>
+ <key>LtnSmN</key>
+ <string>L_tnS_mN_.glif</string>
+ <key>LtnSmO</key>
+ <string>L_tnS_mO_.glif</string>
+ <key>LtnSmP</key>
+ <string>L_tnS_mP_.glif</string>
+ <key>LtnSmQ</key>
+ <string>L_tnS_mQ_.glif</string>
+ <key>LtnSmR</key>
+ <string>L_tnS_mR_.glif</string>
+ <key>LtnSmS</key>
+ <string>L_tnS_mS_.glif</string>
+ <key>LtnSmT</key>
+ <string>L_tnS_mT_.glif</string>
+ <key>LtnSmU</key>
+ <string>L_tnS_mU_.glif</string>
+ <key>LtnSmV</key>
+ <string>L_tnS_mV_.glif</string>
+ <key>LtnSmW</key>
+ <string>L_tnS_mW_.glif</string>
+ <key>LtnSmX</key>
+ <string>L_tnS_mX_.glif</string>
+ <key>LtnSmY</key>
+ <string>L_tnS_mY_.glif</string>
+ <key>NonBreakingHyphen</key>
+ <string>N_onB_reakingH_yphen.glif</string>
+ <key>NumSgn</key>
+ <string>N_umS_gn.glif</string>
+ <key>PercentSgn</key>
+ <string>P_ercentS_gn.glif</string>
+ <key>PlusSgn</key>
+ <string>P_lusS_gn.glif</string>
+ <key>QstnMrk</key>
+ <string>Q_stnM_rk.glif</string>
+ <key>QuotMrk</key>
+ <string>Q_uotM_rk.glif</string>
+ <key>ReverseSolidus</key>
+ <string>R_everseS_olidus.glif</string>
+ <key>RtCurlyBrac</key>
+ <string>R_tC_urlyB_rac.glif</string>
+ <key>RtParen</key>
+ <string>R_tP_aren.glif</string>
+ <key>RtSqrBrac</key>
+ <string>R_tS_qrB_rac.glif</string>
+ <key>Semicolon</key>
+ <string>S_emicolon.glif</string>
+ <key>Solidus</key>
+ <string>S_olidus.glif</string>
+ <key>Space</key>
+ <string>S_pace.glif</string>
+ <key>Tilde</key>
+ <string>T_ilde.glif</string>
+ <key>VertLine</key>
+ <string>V_ertL_ine.glif</string>
+ <key>nonmarkingreturn</key>
+ <string>nonmarkingreturn.glif</string>
+</dict>
+</plist>
diff --git a/tests/input/font-psf-test/source/PsfTest-BoldItalic.ufo/glyphs/nonmarkingreturn.glif b/tests/input/font-psf-test/source/PsfTest-BoldItalic.ufo/glyphs/nonmarkingreturn.glif
new file mode 100644
index 0000000..9a63f06
--- /dev/null
+++ b/tests/input/font-psf-test/source/PsfTest-BoldItalic.ufo/glyphs/nonmarkingreturn.glif
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="nonmarkingreturn" format="2">
+ <advance width="1004"/>
+ <outline/>
+</glyph>
diff --git a/tests/input/font-psf-test/source/PsfTest-BoldItalic.ufo/layercontents.plist b/tests/input/font-psf-test/source/PsfTest-BoldItalic.ufo/layercontents.plist
new file mode 100644
index 0000000..42b7482
--- /dev/null
+++ b/tests/input/font-psf-test/source/PsfTest-BoldItalic.ufo/layercontents.plist
@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<array>
+ <array>
+ <string>public.default</string>
+ <string>glyphs</string>
+ </array>
+</array>
+</plist>
diff --git a/tests/input/font-psf-test/source/PsfTest-BoldItalic.ufo/lib.plist b/tests/input/font-psf-test/source/PsfTest-BoldItalic.ufo/lib.plist
new file mode 100644
index 0000000..8d40b99
--- /dev/null
+++ b/tests/input/font-psf-test/source/PsfTest-BoldItalic.ufo/lib.plist
@@ -0,0 +1,538 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+ <key>com.schriftgestaltung.Glyphs.fontUserData</key>
+ <dict/>
+ <key>com.schriftgestaltung.appVersion</key>
+ <string>1161</string>
+ <key>com.schriftgestaltung.customName</key>
+ <string>Italic</string>
+ <key>com.schriftgestaltung.customParameter.GSFont.DisplayStrings</key>
+ <string/>
+ <key>com.schriftgestaltung.customParameter.GSFont.disablesAutomaticAlignment</key>
+ <true/>
+ <key>com.schriftgestaltung.customParameter.GSFont.disablesLastChange</key>
+ <true/>
+ <key>com.schriftgestaltung.customParameter.GSFont.useNiceNames</key>
+ <integer>0</integer>
+ <key>com.schriftgestaltung.customParameter.GSFontMaster.customValue</key>
+ <integer>0</integer>
+ <key>com.schriftgestaltung.customParameter.GSFontMaster.customValue1</key>
+ <integer>0</integer>
+ <key>com.schriftgestaltung.customParameter.GSFontMaster.customValue2</key>
+ <integer>0</integer>
+ <key>com.schriftgestaltung.customParameter.GSFontMaster.customValue3</key>
+ <integer>0</integer>
+ <key>com.schriftgestaltung.customParameter.GSFontMaster.iconName</key>
+ <string/>
+ <key>com.schriftgestaltung.customParameter.GSFontMaster.weightValue</key>
+ <integer>700</integer>
+ <key>com.schriftgestaltung.customParameter.GSFontMaster.widthValue</key>
+ <integer>100</integer>
+ <key>com.schriftgestaltung.disablesAutomaticAlignment</key>
+ <true/>
+ <key>com.schriftgestaltung.disablesLastChange</key>
+ <true/>
+ <key>com.schriftgestaltung.fontMasterOrder</key>
+ <integer>1</integer>
+ <key>com.schriftgestaltung.glyphOrder</key>
+ <array>
+ <string>.notdef</string>
+ <string>.null</string>
+ <string>nonmarkingreturn</string>
+ <string>Space</string>
+ <string>ExclamationMrk</string>
+ <string>QuotMrk</string>
+ <string>NumSgn</string>
+ <string>DollarSgn</string>
+ <string>PercentSgn</string>
+ <string>Ampersand</string>
+ <string>Apos</string>
+ <string>LftParen</string>
+ <string>RtParen</string>
+ <string>Asterisk</string>
+ <string>PlusSgn</string>
+ <string>Comma</string>
+ <string>HyphenMinus</string>
+ <string>FullStop</string>
+ <string>Solidus</string>
+ <string>DigitZero</string>
+ <string>DigitOne</string>
+ <string>DigitTwo</string>
+ <string>DigitThree</string>
+ <string>DigitFour</string>
+ <string>DigitFive</string>
+ <string>DigitSix</string>
+ <string>DigitSeven</string>
+ <string>DigitEight</string>
+ <string>DigitNine</string>
+ <string>Colon</string>
+ <string>Semicolon</string>
+ <string>LTSgn</string>
+ <string>EqSgn</string>
+ <string>GTSgn</string>
+ <string>QstnMrk</string>
+ <string>AtSgn</string>
+ <string>LtnCapA</string>
+ <string>LtnCapA.alt</string>
+ <string>LtnCapB</string>
+ <string>LtnCapC</string>
+ <string>LtnCapD</string>
+ <string>LtnCapE</string>
+ <string>LtnCapF</string>
+ <string>LtnCapG</string>
+ <string>LtnCapH</string>
+ <string>LtnCapI</string>
+ <string>LtnCapJ</string>
+ <string>LtnCapK</string>
+ <string>LtnCapL</string>
+ <string>LtnCapM</string>
+ <string>LtnCapN</string>
+ <string>LtnCapO</string>
+ <string>LtnCapP</string>
+ <string>LtnCapQ</string>
+ <string>LtnCapR</string>
+ <string>LtnCapS</string>
+ <string>LtnCapT</string>
+ <string>LtnCapU</string>
+ <string>LtnCapV</string>
+ <string>LtnCapW</string>
+ <string>LtnCapX</string>
+ <string>LtnCapY</string>
+ <string>LftSqrBrac</string>
+ <string>ReverseSolidus</string>
+ <string>RtSqrBrac</string>
+ <string>CircumAccent</string>
+ <string>LowLine</string>
+ <string>GraveAccent</string>
+ <string>LtnSmA</string>
+ <string>LtnSmB</string>
+ <string>LtnSmC</string>
+ <string>LtnSmD</string>
+ <string>LtnSmE</string>
+ <string>LtnSmF</string>
+ <string>LtnSmG</string>
+ <string>LtnSmH</string>
+ <string>LtnSmI</string>
+ <string>LtnSmJ</string>
+ <string>LtnSmK</string>
+ <string>LtnSmL</string>
+ <string>LtnSmM</string>
+ <string>LtnSmN</string>
+ <string>LtnSmO</string>
+ <string>LtnSmP</string>
+ <string>LtnSmQ</string>
+ <string>LtnSmR</string>
+ <string>LtnSmS</string>
+ <string>LtnSmT</string>
+ <string>LtnSmU</string>
+ <string>LtnSmV</string>
+ <string>LtnSmW</string>
+ <string>LtnSmX</string>
+ <string>LtnSmY</string>
+ <string>LftCurlyBrac</string>
+ <string>VertLine</string>
+ <string>RtCurlyBrac</string>
+ <string>Tilde</string>
+ <string>LtnCapADiaer</string>
+ <string>LtnSmAAcute</string>
+ <string>LtnSmAGrave</string>
+ <string>LtnSmACircum</string>
+ <string>LtnSmADiaer</string>
+ <string>LtnSmATilde</string>
+ <string>LtnSmARingAbv</string>
+ <string>DottedCirc</string>
+ <string>Hyphen</string>
+ <string>NonBreakingHyphen</string>
+ <string>Hyphen_Soft</string>
+ <string>CombAcute</string>
+ <string>CombGrave</string>
+ <string>CombCircum</string>
+ <string>CombTilde</string>
+ <string>CombDiaer</string>
+ <string>CombRingAbv</string>
+ </array>
+ <key>com.schriftgestaltung.keyboardIncrement</key>
+ <integer>1</integer>
+ <key>com.schriftgestaltung.weight</key>
+ <string>Bold</string>
+ <key>com.schriftgestaltung.weightValue</key>
+ <integer>700</integer>
+ <key>com.schriftgestaltung.width</key>
+ <string>Regular</string>
+ <key>com.schriftgestaltung.widthValue</key>
+ <integer>100</integer>
+ <key>org.sil.lcg.toneLetters</key>
+ <dict>
+ <key>contourWidth</key>
+ <integer>540</integer>
+ <key>dotSize</key>
+ <integer>280</integer>
+ <key>dotSpacing</key>
+ <integer>200</integer>
+ <key>glyphDepth</key>
+ <integer>-25</integer>
+ <key>glyphHeight</key>
+ <integer>1600</integer>
+ <key>italicAngle</key>
+ <integer>14</integer>
+ <key>marginDotLeft</key>
+ <integer>100</integer>
+ <key>marginDotRight</key>
+ <integer>140</integer>
+ <key>marginFlatLeft</key>
+ <integer>100</integer>
+ <key>marginFlatRight</key>
+ <integer>140</integer>
+ <key>marginPointLeft</key>
+ <integer>80</integer>
+ <key>marginPointRight</key>
+ <integer>120</integer>
+ <key>strokeThickness</key>
+ <integer>200</integer>
+ </dict>
+ <key>public.glyphOrder</key>
+ <array>
+ <string>.notdef</string>
+ <string>.null</string>
+ <string>nonmarkingreturn</string>
+ <string>Space</string>
+ <string>ExclamationMrk</string>
+ <string>QuotMrk</string>
+ <string>NumSgn</string>
+ <string>DollarSgn</string>
+ <string>PercentSgn</string>
+ <string>Ampersand</string>
+ <string>Apos</string>
+ <string>LftParen</string>
+ <string>RtParen</string>
+ <string>Asterisk</string>
+ <string>PlusSgn</string>
+ <string>Comma</string>
+ <string>HyphenMinus</string>
+ <string>FullStop</string>
+ <string>Solidus</string>
+ <string>DigitZero</string>
+ <string>DigitOne</string>
+ <string>DigitTwo</string>
+ <string>DigitThree</string>
+ <string>DigitFour</string>
+ <string>DigitFive</string>
+ <string>DigitSix</string>
+ <string>DigitSeven</string>
+ <string>DigitEight</string>
+ <string>DigitNine</string>
+ <string>Colon</string>
+ <string>Semicolon</string>
+ <string>LTSgn</string>
+ <string>EqSgn</string>
+ <string>GTSgn</string>
+ <string>QstnMrk</string>
+ <string>AtSgn</string>
+ <string>LtnCapA</string>
+ <string>LtnCapA.alt</string>
+ <string>LtnCapB</string>
+ <string>LtnCapC</string>
+ <string>LtnCapD</string>
+ <string>LtnCapE</string>
+ <string>LtnCapF</string>
+ <string>LtnCapG</string>
+ <string>LtnCapH</string>
+ <string>LtnCapI</string>
+ <string>LtnCapJ</string>
+ <string>LtnCapK</string>
+ <string>LtnCapL</string>
+ <string>LtnCapM</string>
+ <string>LtnCapN</string>
+ <string>LtnCapO</string>
+ <string>LtnCapP</string>
+ <string>LtnCapQ</string>
+ <string>LtnCapR</string>
+ <string>LtnCapS</string>
+ <string>LtnCapT</string>
+ <string>LtnCapU</string>
+ <string>LtnCapV</string>
+ <string>LtnCapW</string>
+ <string>LtnCapX</string>
+ <string>LtnCapY</string>
+ <string>LftSqrBrac</string>
+ <string>ReverseSolidus</string>
+ <string>RtSqrBrac</string>
+ <string>CircumAccent</string>
+ <string>LowLine</string>
+ <string>GraveAccent</string>
+ <string>LtnSmA</string>
+ <string>LtnSmB</string>
+ <string>LtnSmC</string>
+ <string>LtnSmD</string>
+ <string>LtnSmE</string>
+ <string>LtnSmF</string>
+ <string>LtnSmG</string>
+ <string>LtnSmH</string>
+ <string>LtnSmI</string>
+ <string>LtnSmJ</string>
+ <string>LtnSmK</string>
+ <string>LtnSmL</string>
+ <string>LtnSmM</string>
+ <string>LtnSmN</string>
+ <string>LtnSmO</string>
+ <string>LtnSmP</string>
+ <string>LtnSmQ</string>
+ <string>LtnSmR</string>
+ <string>LtnSmS</string>
+ <string>LtnSmT</string>
+ <string>LtnSmU</string>
+ <string>LtnSmV</string>
+ <string>LtnSmW</string>
+ <string>LtnSmX</string>
+ <string>LtnSmY</string>
+ <string>LftCurlyBrac</string>
+ <string>VertLine</string>
+ <string>RtCurlyBrac</string>
+ <string>Tilde</string>
+ <string>LtnCapADiaer</string>
+ <string>LtnSmAAcute</string>
+ <string>LtnSmAGrave</string>
+ <string>LtnSmACircum</string>
+ <string>LtnSmADiaer</string>
+ <string>LtnSmATilde</string>
+ <string>LtnSmARingAbv</string>
+ <string>DottedCirc</string>
+ <string>Hyphen</string>
+ <string>NonBreakingHyphen</string>
+ <string>Hyphen_Soft</string>
+ <string>CombAcute</string>
+ <string>CombGrave</string>
+ <string>CombCircum</string>
+ <string>CombTilde</string>
+ <string>CombDiaer</string>
+ <string>CombRingAbv</string>
+ </array>
+ <key>public.postscriptNames</key>
+ <dict>
+ <key>Ampersand</key>
+ <string>ampersand</string>
+ <key>Apos</key>
+ <string>quotesingle</string>
+ <key>Asterisk</key>
+ <string>asterisk</string>
+ <key>AtSgn</key>
+ <string>at</string>
+ <key>CircumAccent</key>
+ <string>asciicircum</string>
+ <key>Colon</key>
+ <string>colon</string>
+ <key>CombAcute</key>
+ <string>acutecomb</string>
+ <key>CombCircum</key>
+ <string>uni0302</string>
+ <key>CombDiaer</key>
+ <string>uni0308</string>
+ <key>CombGrave</key>
+ <string>gravecomb</string>
+ <key>CombRingAbv</key>
+ <string>uni030A</string>
+ <key>CombTilde</key>
+ <string>tildecomb</string>
+ <key>Comma</key>
+ <string>comma</string>
+ <key>DigitEight</key>
+ <string>eight</string>
+ <key>DigitFive</key>
+ <string>five</string>
+ <key>DigitFour</key>
+ <string>four</string>
+ <key>DigitNine</key>
+ <string>nine</string>
+ <key>DigitOne</key>
+ <string>one</string>
+ <key>DigitSeven</key>
+ <string>seven</string>
+ <key>DigitSix</key>
+ <string>six</string>
+ <key>DigitThree</key>
+ <string>three</string>
+ <key>DigitTwo</key>
+ <string>two</string>
+ <key>DigitZero</key>
+ <string>zero</string>
+ <key>DollarSgn</key>
+ <string>dollar</string>
+ <key>DottedCirc</key>
+ <string>uni25CC</string>
+ <key>EqSgn</key>
+ <string>equal</string>
+ <key>ExclamationMrk</key>
+ <string>exclam</string>
+ <key>FullStop</key>
+ <string>period</string>
+ <key>GTSgn</key>
+ <string>greater</string>
+ <key>GraveAccent</key>
+ <string>grave</string>
+ <key>Hyphen</key>
+ <string>uni2010</string>
+ <key>HyphenMinus</key>
+ <string>hyphen</string>
+ <key>Hyphen_Soft</key>
+ <string>uni00AD</string>
+ <key>LTSgn</key>
+ <string>less</string>
+ <key>LftCurlyBrac</key>
+ <string>braceleft</string>
+ <key>LftParen</key>
+ <string>parenleft</string>
+ <key>LftSqrBrac</key>
+ <string>bracketleft</string>
+ <key>LowLine</key>
+ <string>underscore</string>
+ <key>LtnCapA</key>
+ <string>A</string>
+ <key>LtnCapA.alt</key>
+ <string>A</string>
+ <key>LtnCapADiaer</key>
+ <string>Adieresis</string>
+ <key>LtnCapB</key>
+ <string>B</string>
+ <key>LtnCapC</key>
+ <string>C</string>
+ <key>LtnCapD</key>
+ <string>D</string>
+ <key>LtnCapE</key>
+ <string>E</string>
+ <key>LtnCapF</key>
+ <string>F</string>
+ <key>LtnCapG</key>
+ <string>G</string>
+ <key>LtnCapH</key>
+ <string>H</string>
+ <key>LtnCapI</key>
+ <string>I</string>
+ <key>LtnCapJ</key>
+ <string>J</string>
+ <key>LtnCapK</key>
+ <string>K</string>
+ <key>LtnCapL</key>
+ <string>L</string>
+ <key>LtnCapM</key>
+ <string>M</string>
+ <key>LtnCapN</key>
+ <string>N</string>
+ <key>LtnCapO</key>
+ <string>O</string>
+ <key>LtnCapP</key>
+ <string>P</string>
+ <key>LtnCapQ</key>
+ <string>Q</string>
+ <key>LtnCapR</key>
+ <string>R</string>
+ <key>LtnCapS</key>
+ <string>S</string>
+ <key>LtnCapT</key>
+ <string>T</string>
+ <key>LtnCapU</key>
+ <string>U</string>
+ <key>LtnCapV</key>
+ <string>V</string>
+ <key>LtnCapW</key>
+ <string>W</string>
+ <key>LtnCapX</key>
+ <string>X</string>
+ <key>LtnCapY</key>
+ <string>Y</string>
+ <key>LtnSmA</key>
+ <string>a</string>
+ <key>LtnSmAAcute</key>
+ <string>aacute</string>
+ <key>LtnSmACircum</key>
+ <string>acircumflex</string>
+ <key>LtnSmADiaer</key>
+ <string>adieresis</string>
+ <key>LtnSmAGrave</key>
+ <string>agrave</string>
+ <key>LtnSmARingAbv</key>
+ <string>aring</string>
+ <key>LtnSmATilde</key>
+ <string>atilde</string>
+ <key>LtnSmB</key>
+ <string>b</string>
+ <key>LtnSmC</key>
+ <string>c</string>
+ <key>LtnSmD</key>
+ <string>d</string>
+ <key>LtnSmE</key>
+ <string>e</string>
+ <key>LtnSmF</key>
+ <string>f</string>
+ <key>LtnSmG</key>
+ <string>g</string>
+ <key>LtnSmH</key>
+ <string>h</string>
+ <key>LtnSmI</key>
+ <string>i</string>
+ <key>LtnSmJ</key>
+ <string>j</string>
+ <key>LtnSmK</key>
+ <string>k</string>
+ <key>LtnSmL</key>
+ <string>l</string>
+ <key>LtnSmM</key>
+ <string>m</string>
+ <key>LtnSmN</key>
+ <string>n</string>
+ <key>LtnSmO</key>
+ <string>o</string>
+ <key>LtnSmP</key>
+ <string>p</string>
+ <key>LtnSmQ</key>
+ <string>q</string>
+ <key>LtnSmR</key>
+ <string>r</string>
+ <key>LtnSmS</key>
+ <string>s</string>
+ <key>LtnSmT</key>
+ <string>t</string>
+ <key>LtnSmU</key>
+ <string>u</string>
+ <key>LtnSmV</key>
+ <string>v</string>
+ <key>LtnSmW</key>
+ <string>w</string>
+ <key>LtnSmX</key>
+ <string>x</string>
+ <key>LtnSmY</key>
+ <string>y</string>
+ <key>NonBreakingHyphen</key>
+ <string>uni2011</string>
+ <key>NumSgn</key>
+ <string>numbersign</string>
+ <key>PercentSgn</key>
+ <string>percent</string>
+ <key>PlusSgn</key>
+ <string>plus</string>
+ <key>QstnMrk</key>
+ <string>question</string>
+ <key>QuotMrk</key>
+ <string>quotedbl</string>
+ <key>ReverseSolidus</key>
+ <string>backslash</string>
+ <key>RtCurlyBrac</key>
+ <string>braceright</string>
+ <key>RtParen</key>
+ <string>parenright</string>
+ <key>RtSqrBrac</key>
+ <string>bracketright</string>
+ <key>Semicolon</key>
+ <string>semicolon</string>
+ <key>Solidus</key>
+ <string>slash</string>
+ <key>Space</key>
+ <string>space</string>
+ <key>Tilde</key>
+ <string>asciitilde</string>
+ <key>VertLine</key>
+ <string>bar</string>
+ </dict>
+</dict>
+</plist>
diff --git a/tests/input/font-psf-test/source/PsfTest-BoldItalic.ufo/metainfo.plist b/tests/input/font-psf-test/source/PsfTest-BoldItalic.ufo/metainfo.plist
new file mode 100644
index 0000000..aa10c5c
--- /dev/null
+++ b/tests/input/font-psf-test/source/PsfTest-BoldItalic.ufo/metainfo.plist
@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+ <key>creator</key>
+ <string>org.sil.scripts.pysilfont</string>
+ <key>formatVersion</key>
+ <integer>3</integer>
+</dict>
+</plist>
diff --git a/tests/input/font-psf-test/source/PsfTest-Italic.ufo/fontinfo.plist b/tests/input/font-psf-test/source/PsfTest-Italic.ufo/fontinfo.plist
new file mode 100644
index 0000000..e6bd28c
--- /dev/null
+++ b/tests/input/font-psf-test/source/PsfTest-Italic.ufo/fontinfo.plist
@@ -0,0 +1,243 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+ <key>ascender</key>
+ <integer>2100</integer>
+ <key>capHeight</key>
+ <real>1485.3</real>
+ <key>copyright</key>
+ <string>Copyright (c) 2004-2021 SIL International</string>
+ <key>descender</key>
+ <integer>-550</integer>
+ <key>familyName</key>
+ <string>Psf Test</string>
+ <key>italicAngle</key>
+ <integer>-14</integer>
+ <key>openTypeHeadCreated</key>
+ <string>2021/01/01 11:00:00</string>
+ <key>openTypeHheaAscender</key>
+ <integer>2100</integer>
+ <key>openTypeHheaDescender</key>
+ <integer>-550</integer>
+ <key>openTypeHheaLineGap</key>
+ <integer>0</integer>
+ <key>openTypeNameDescription</key>
+ <string>Copyright (c) 2004-2021 SIL International</string>
+ <key>openTypeNameDesigner</key>
+ <string>Victor Gaultney, Annie Olsen, Julie Remington, Don Collingsworth, Eric Hays, Becca Hirsbrunner</string>
+ <key>openTypeNameDesignerURL</key>
+ <string>http://scripts.sil.org/</string>
+ <key>openTypeNameLicense</key>
+ <string>Copyright (c) 2004-2021 SIL International (http://www.sil.org/) with Reserved Font Names "Andika" and "SIL".
+
+This Font Software is licensed under the SIL Open Font License, Version 1.1. This license is copied below, and is also available with a FAQ at: http://scripts.sil.org/OFL
+
+
+-----------------------------------------------------------
+SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007
+-----------------------------------------------------------
+
+PREAMBLE
+The goals of the Open Font License (OFL) are to stimulate worldwide development of collaborative font projects, to support the font creation efforts of academic and linguistic communities, and to provide a free and open framework in which fonts may be shared and improved in partnership with others.
+
+The OFL allows the licensed fonts to be used, studied, modified and redistributed freely as long as they are not sold by themselves. The fonts, including any derivative works, can be bundled, embedded, redistributed and/or sold with any software provided that any reserved names are not used by derivative works. The fonts and derivatives, however, cannot be released under any other type of license. The requirement for fonts to remain under this license does not apply to any document created using the fonts or their derivatives.
+
+DEFINITIONS
+"Font Software" refers to the set of files released by the Copyright Holder(s) under this license and clearly marked as such. This may include source files, build scripts and documentation.
+
+"Reserved Font Name" refers to any names specified as such after the copyright statement(s).
+
+"Original Version" refers to the collection of Font Software components as distributed by the Copyright Holder(s).
+
+"Modified Version" refers to any derivative made by adding to, deleting, or substituting -- in part or in whole -- any of the components of the Original Version, by changing formats or by porting the Font Software to a new environment.
+
+"Author" refers to any designer, engineer, programmer, technical writer or other person who contributed to the Font Software.
+
+PERMISSION &amp; CONDITIONS
+Permission is hereby granted, free of charge, to any person obtaining a copy of the Font Software, to use, study, copy, merge, embed, modify, redistribute, and sell modified and unmodified copies of the Font Software, subject to the following conditions:
+
+1) Neither the Font Software nor any of its individual components, in Original or Modified Versions, may be sold by itself.
+
+2) Original or Modified Versions of the Font Software may be bundled, redistributed and/or sold with any software, provided that each copy contains the above copyright notice and this license. These can be included either as stand-alone text files, human-readable headers or in the appropriate machine-readable metadata fields within text or binary files as long as those fields can be easily viewed by the user.
+
+3) No Modified Version of the Font Software may use the Reserved Font Name(s) unless explicit written permission is granted by the corresponding Copyright Holder. This restriction only applies to the primary font name as presented to the users.
+
+4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font Software shall not be used to promote, endorse or advertise any Modified Version, except to acknowledge the contribution(s) of the Copyright Holder(s) and the Author(s) or with their explicit written permission.
+
+5) The Font Software, modified or unmodified, in part or in whole, must be distributed entirely under this license, and must not be distributed under any other license. The requirement for fonts to remain under this license does not apply to any document created using the Font Software.
+
+TERMINATION
+This license becomes null and void if any of the above conditions are not met.
+
+DISCLAIMER
+THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM OTHER DEALINGS IN THE FONT SOFTWARE.</string>
+ <key>openTypeNameLicenseURL</key>
+ <string>http://scripts.sil.org/OFL</string>
+ <key>openTypeNameManufacturer</key>
+ <string>SIL International</string>
+ <key>openTypeNameManufacturerURL</key>
+ <string>http://scripts.sil.org</string>
+ <key>openTypeNamePreferredFamilyName</key>
+ <string>Psf Testing</string>
+ <key>openTypeNamePreferredSubfamilyName</key>
+ <string>Italic</string>
+ <key>openTypeNameUniqueID</key>
+ <string>SIL International: Psf Test Italic: 2022</string>
+ <key>openTypeNameVersion</key>
+ <string>Version 5.550</string>
+ <key>openTypeOS2CodePageRanges</key>
+ <array>
+ <integer>0</integer>
+ <integer>1</integer>
+ <integer>2</integer>
+ <integer>4</integer>
+ <integer>7</integer>
+ <integer>8</integer>
+ </array>
+ <key>openTypeOS2FamilyClass</key>
+ <array>
+ <integer>0</integer>
+ <integer>0</integer>
+ </array>
+ <key>openTypeOS2Panose</key>
+ <array>
+ <integer>2</integer>
+ <integer>0</integer>
+ <integer>0</integer>
+ <integer>0</integer>
+ <integer>0</integer>
+ <integer>0</integer>
+ <integer>0</integer>
+ <integer>0</integer>
+ <integer>0</integer>
+ <integer>0</integer>
+ </array>
+ <key>openTypeOS2StrikeoutPosition</key>
+ <integer>700</integer>
+ <key>openTypeOS2StrikeoutSize</key>
+ <integer>100</integer>
+ <key>openTypeOS2SubscriptXOffset</key>
+ <integer>0</integer>
+ <key>openTypeOS2SubscriptXSize</key>
+ <integer>1433</integer>
+ <key>openTypeOS2SubscriptYOffset</key>
+ <integer>286</integer>
+ <key>openTypeOS2SubscriptYSize</key>
+ <integer>1331</integer>
+ <key>openTypeOS2SuperscriptXOffset</key>
+ <integer>0</integer>
+ <key>openTypeOS2SuperscriptXSize</key>
+ <integer>1433</integer>
+ <key>openTypeOS2SuperscriptYOffset</key>
+ <integer>976</integer>
+ <key>openTypeOS2SuperscriptYSize</key>
+ <integer>1331</integer>
+ <key>openTypeOS2Type</key>
+ <array/>
+ <key>openTypeOS2TypoAscender</key>
+ <integer>2100</integer>
+ <key>openTypeOS2TypoDescender</key>
+ <integer>-550</integer>
+ <key>openTypeOS2TypoLineGap</key>
+ <integer>1</integer>
+ <key>openTypeOS2UnicodeRanges</key>
+ <array>
+ <integer>0</integer>
+ <integer>1</integer>
+ <integer>6</integer>
+ <integer>7</integer>
+ <integer>31</integer>
+ <integer>33</integer>
+ <integer>35</integer>
+ <integer>36</integer>
+ <integer>37</integer>
+ <integer>38</integer>
+ <integer>39</integer>
+ <integer>40</integer>
+ <integer>45</integer>
+ <integer>46</integer>
+ <integer>47</integer>
+ <integer>57</integer>
+ <integer>60</integer>
+ <integer>62</integer>
+ <integer>64</integer>
+ <integer>67</integer>
+ <integer>69</integer>
+ <integer>89</integer>
+ </array>
+ <key>openTypeOS2VendorID</key>
+ <string>SIL</string>
+ <key>openTypeOS2WeightClass</key>
+ <integer>400</integer>
+ <key>openTypeOS2WidthClass</key>
+ <integer>5</integer>
+ <key>openTypeOS2WinAscent</key>
+ <integer>2100</integer>
+ <key>openTypeOS2WinDescent</key>
+ <integer>550</integer>
+ <key>postscriptBlueValues</key>
+ <array>
+ <integer>-490</integer>
+ <integer>-490</integer>
+ <integer>-25</integer>
+ <integer>0</integer>
+ <integer>1020</integer>
+ <integer>1040</integer>
+ <integer>1455</integer>
+ <integer>1485</integer>
+ <integer>1600</integer>
+ <integer>1620</integer>
+ </array>
+ <key>postscriptFontName</key>
+ <string>PsfTest-Italic</string>
+ <key>postscriptFullName</key>
+ <string>Psf Test Italic</string>
+ <key>postscriptStemSnapH</key>
+ <array>
+ <integer>140</integer>
+ <integer>145</integer>
+ <integer>150</integer>
+ <integer>155</integer>
+ <integer>160</integer>
+ <integer>165</integer>
+ <integer>170</integer>
+ <integer>175</integer>
+ <integer>185</integer>
+ <integer>270</integer>
+ </array>
+ <key>postscriptStemSnapV</key>
+ <array>
+ <integer>165</integer>
+ <integer>180</integer>
+ <integer>185</integer>
+ <integer>190</integer>
+ <integer>195</integer>
+ <integer>200</integer>
+ <integer>205</integer>
+ <integer>270</integer>
+ </array>
+ <key>postscriptUnderlinePosition</key>
+ <integer>-110</integer>
+ <key>postscriptUnderlineThickness</key>
+ <integer>80</integer>
+ <key>styleMapFamilyName</key>
+ <string>Psf test</string>
+ <key>styleMapStyleName</key>
+ <string>italic</string>
+ <key>styleName</key>
+ <string>Italic</string>
+ <key>trademark</key>
+ <string>Andika is a trademark of SIL International.</string>
+ <key>unitsPerEm</key>
+ <integer>2048</integer>
+ <key>versionMajor</key>
+ <integer>5</integer>
+ <key>versionMinor</key>
+ <integer>550</integer>
+ <key>xHeight</key>
+ <integer>1040</integer>
+ <key>year</key>
+ <integer>2021</integer>
+</dict>
+</plist>
diff --git a/tests/input/font-psf-test/source/PsfTest-Italic.ufo/glyphs/A_mpersand.glif b/tests/input/font-psf-test/source/PsfTest-Italic.ufo/glyphs/A_mpersand.glif
new file mode 100644
index 0000000..689cb3e
--- /dev/null
+++ b/tests/input/font-psf-test/source/PsfTest-Italic.ufo/glyphs/A_mpersand.glif
@@ -0,0 +1,61 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="Ampersand" format="2">
+ <advance width="1202"/>
+ <unicode hex="0026"/>
+ <outline>
+ <contour>
+ <point x="1054" y="559" type="line"/>
+ <point x="949" y="395"/>
+ <point x="616" y="147"/>
+ <point x="441" y="147" type="curve" smooth="yes"/>
+ <point x="318" y="147"/>
+ <point x="256" y="224"/>
+ <point x="256" y="314" type="curve" smooth="yes"/>
+ <point x="256" y="453"/>
+ <point x="369" y="575"/>
+ <point x="590" y="725" type="curve" smooth="yes"/>
+ <point x="836" y="892"/>
+ <point x="1022" y="1067"/>
+ <point x="1022" y="1223" type="curve" smooth="yes"/>
+ <point x="1022" y="1363"/>
+ <point x="894" y="1455"/>
+ <point x="762" y="1455" type="curve" smooth="yes"/>
+ <point x="504" y="1455"/>
+ <point x="378" y="1328"/>
+ <point x="378" y="1114" type="curve" smooth="yes"/>
+ <point x="378" y="953"/>
+ <point x="514" y="771"/>
+ <point x="614" y="559" type="curve" smooth="yes"/>
+ <point x="783" y="198"/>
+ <point x="906" y="-25"/>
+ <point x="958" y="-25" type="curve" smooth="yes"/>
+ <point x="993" y="-25"/>
+ <point x="1087" y="37"/>
+ <point x="1132" y="69" type="curve"/>
+ <point x="1046" y="108"/>
+ <point x="926" y="291"/>
+ <point x="756" y="666" type="curve" smooth="yes"/>
+ <point x="665" y="866"/>
+ <point x="544" y="1029"/>
+ <point x="544" y="1149" type="curve" smooth="yes"/>
+ <point x="544" y="1252"/>
+ <point x="632" y="1323"/>
+ <point x="724" y="1323" type="curve" smooth="yes"/>
+ <point x="794" y="1323"/>
+ <point x="858" y="1266"/>
+ <point x="858" y="1193" type="curve" smooth="yes"/>
+ <point x="858" y="1107"/>
+ <point x="743" y="1004"/>
+ <point x="492" y="826" type="curve" smooth="yes"/>
+ <point x="182" y="606"/>
+ <point x="73" y="439"/>
+ <point x="73" y="288" type="curve" smooth="yes"/>
+ <point x="73" y="113"/>
+ <point x="195" y="-25"/>
+ <point x="383" y="-25" type="curve" smooth="yes"/>
+ <point x="656" y="-25"/>
+ <point x="1009" y="269"/>
+ <point x="1126" y="426" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/input/font-psf-test/source/PsfTest-Italic.ufo/glyphs/A_pos.glif b/tests/input/font-psf-test/source/PsfTest-Italic.ufo/glyphs/A_pos.glif
new file mode 100644
index 0000000..deb1650
--- /dev/null
+++ b/tests/input/font-psf-test/source/PsfTest-Italic.ufo/glyphs/A_pos.glif
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="Apos" format="2">
+ <advance width="585"/>
+ <unicode hex="0027"/>
+ <outline>
+ <contour>
+ <point x="560" y="1024" type="line"/>
+ <point x="599" y="1162"/>
+ <point x="643" y="1312"/>
+ <point x="732" y="1553" type="curve"/>
+ <point x="527" y="1553" type="line"/>
+ <point x="498" y="1312"/>
+ <point x="465" y="1162"/>
+ <point x="435" y="1024" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/input/font-psf-test/source/PsfTest-Italic.ufo/glyphs/A_sterisk.glif b/tests/input/font-psf-test/source/PsfTest-Italic.ufo/glyphs/A_sterisk.glif
new file mode 100644
index 0000000..3027a5d
--- /dev/null
+++ b/tests/input/font-psf-test/source/PsfTest-Italic.ufo/glyphs/A_sterisk.glif
@@ -0,0 +1,51 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="Asterisk" format="2">
+ <advance width="1008"/>
+ <unicode hex="002A"/>
+ <outline>
+ <contour>
+ <point x="745" y="1568" type="line"/>
+ <point x="733" y="1438"/>
+ <point x="725" y="1359"/>
+ <point x="707" y="1274" type="curve"/>
+ <point x="644" y="1317"/>
+ <point x="587" y="1359"/>
+ <point x="498" y="1436" type="curve"/>
+ <point x="392" y="1313" type="line"/>
+ <point x="505" y="1264"/>
+ <point x="575" y="1236"/>
+ <point x="643" y="1196" type="curve"/>
+ <point x="556" y="1153"/>
+ <point x="474" y="1117"/>
+ <point x="340" y="1063" type="curve"/>
+ <point x="379" y="941" type="line"/>
+ <point x="504" y="1021"/>
+ <point x="584" y="1072"/>
+ <point x="668" y="1117" type="curve"/>
+ <point x="645" y="1034"/>
+ <point x="619" y="954"/>
+ <point x="575" y="823" type="curve"/>
+ <point x="715" y="823" type="line"/>
+ <point x="727" y="954"/>
+ <point x="741" y="1031"/>
+ <point x="758" y="1117" type="curve"/>
+ <point x="821" y="1073"/>
+ <point x="878" y="1032"/>
+ <point x="968" y="956" type="curve"/>
+ <point x="1073" y="1078" type="line"/>
+ <point x="959" y="1126"/>
+ <point x="890" y="1155"/>
+ <point x="823" y="1196" type="curve"/>
+ <point x="909" y="1236"/>
+ <point x="990" y="1273"/>
+ <point x="1126" y="1328" type="curve"/>
+ <point x="1086" y="1450" type="line"/>
+ <point x="961" y="1368"/>
+ <point x="883" y="1321"/>
+ <point x="797" y="1274" type="curve"/>
+ <point x="819" y="1359"/>
+ <point x="845" y="1438"/>
+ <point x="890" y="1568" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/input/font-psf-test/source/PsfTest-Italic.ufo/glyphs/A_tS_gn.glif b/tests/input/font-psf-test/source/PsfTest-Italic.ufo/glyphs/A_tS_gn.glif
new file mode 100644
index 0000000..2cd2542
--- /dev/null
+++ b/tests/input/font-psf-test/source/PsfTest-Italic.ufo/glyphs/A_tS_gn.glif
@@ -0,0 +1,104 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="AtSgn" format="2">
+ <advance width="1682"/>
+ <unicode hex="0040"/>
+ <outline>
+ <contour>
+ <point x="1082" y="-10" type="line"/>
+ <point x="980" y="-69"/>
+ <point x="889" y="-93"/>
+ <point x="796" y="-93" type="curve" smooth="yes"/>
+ <point x="507" y="-93"/>
+ <point x="301" y="104"/>
+ <point x="301" y="414" type="curve" smooth="yes"/>
+ <point x="301" y="476"/>
+ <point x="309" y="543"/>
+ <point x="327" y="613" type="curve" smooth="yes"/>
+ <point x="425" y="1003"/>
+ <point x="782" y="1245"/>
+ <point x="1110" y="1245" type="curve" smooth="yes"/>
+ <point x="1433" y="1245"/>
+ <point x="1590" y="1060"/>
+ <point x="1590" y="813" type="curve" smooth="yes"/>
+ <point x="1590" y="760"/>
+ <point x="1582" y="705"/>
+ <point x="1568" y="647" type="curve" smooth="yes"/>
+ <point x="1510" y="413"/>
+ <point x="1365" y="309"/>
+ <point x="1297" y="309" type="curve" smooth="yes"/>
+ <point x="1261" y="309"/>
+ <point x="1238" y="344"/>
+ <point x="1238" y="420" type="curve" smooth="yes"/>
+ <point x="1238" y="468"/>
+ <point x="1247" y="533"/>
+ <point x="1268" y="617" type="curve" smooth="yes"/>
+ <point x="1354" y="960" type="line"/>
+ <point x="1276" y="995"/>
+ <point x="1155" y="1019"/>
+ <point x="1074" y="1019" type="curve" smooth="yes"/>
+ <point x="910" y="1019"/>
+ <point x="790" y="962"/>
+ <point x="673" y="828" type="curve" smooth="yes"/>
+ <point x="607" y="751"/>
+ <point x="554" y="650"/>
+ <point x="524" y="529" type="curve" smooth="yes"/>
+ <point x="514" y="488"/>
+ <point x="509" y="450"/>
+ <point x="509" y="416" type="curve" smooth="yes"/>
+ <point x="509" y="259"/>
+ <point x="609" y="179"/>
+ <point x="719" y="179" type="curve" smooth="yes"/>
+ <point x="836" y="179"/>
+ <point x="1017" y="359"/>
+ <point x="1099" y="480" type="curve"/>
+ <point x="1093" y="446"/>
+ <point x="1089" y="413"/>
+ <point x="1089" y="382" type="curve" smooth="yes"/>
+ <point x="1089" y="264"/>
+ <point x="1136" y="176"/>
+ <point x="1233" y="176" type="curve" smooth="yes"/>
+ <point x="1408" y="176"/>
+ <point x="1635" y="331"/>
+ <point x="1716" y="656" type="curve" smooth="yes"/>
+ <point x="1732" y="722"/>
+ <point x="1740" y="784"/>
+ <point x="1740" y="843" type="curve" smooth="yes"/>
+ <point x="1740" y="1161"/>
+ <point x="1513" y="1377"/>
+ <point x="1153" y="1377" type="curve" smooth="yes"/>
+ <point x="738" y="1377"/>
+ <point x="310" y="1143"/>
+ <point x="175" y="603" type="curve" smooth="yes"/>
+ <point x="155" y="522"/>
+ <point x="145" y="446"/>
+ <point x="145" y="375" type="curve" smooth="yes"/>
+ <point x="145" y="-5"/>
+ <point x="417" y="-230"/>
+ <point x="747" y="-230" type="curve" smooth="yes"/>
+ <point x="882" y="-230"/>
+ <point x="1044" y="-184"/>
+ <point x="1161" y="-116" type="curve"/>
+ </contour>
+ <contour>
+ <point x="1141" y="706" type="line"/>
+ <point x="1075" y="570"/>
+ <point x="856" y="314"/>
+ <point x="766" y="314" type="curve" smooth="yes"/>
+ <point x="712" y="314"/>
+ <point x="669" y="362"/>
+ <point x="669" y="459" type="curve" smooth="yes"/>
+ <point x="669" y="491"/>
+ <point x="674" y="530"/>
+ <point x="685" y="573" type="curve" smooth="yes"/>
+ <point x="704" y="649"/>
+ <point x="739" y="726"/>
+ <point x="780" y="774" type="curve" smooth="yes"/>
+ <point x="859" y="868"/>
+ <point x="943" y="887"/>
+ <point x="1011" y="887" type="curve" smooth="yes"/>
+ <point x="1085" y="887"/>
+ <point x="1148" y="868"/>
+ <point x="1177" y="853" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/input/font-psf-test/source/PsfTest-Italic.ufo/glyphs/C_ircumA_ccent.glif b/tests/input/font-psf-test/source/PsfTest-Italic.ufo/glyphs/C_ircumA_ccent.glif
new file mode 100644
index 0000000..91ab811
--- /dev/null
+++ b/tests/input/font-psf-test/source/PsfTest-Italic.ufo/glyphs/C_ircumA_ccent.glif
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="CircumAccent" format="2">
+ <advance width="830"/>
+ <unicode hex="005E"/>
+ <anchor x="705" y="1635" name="U"/>
+ <outline>
+ <contour>
+ <point x="316" y="1147" type="line"/>
+ <point x="660" y="1421" type="line"/>
+ <point x="866" y="1147" type="line"/>
+ <point x="1015" y="1147" type="line"/>
+ <point x="761" y="1568" type="line"/>
+ <point x="591" y="1568" type="line"/>
+ <point x="166" y="1147" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/input/font-psf-test/source/PsfTest-Italic.ufo/glyphs/C_olon.glif b/tests/input/font-psf-test/source/PsfTest-Italic.ufo/glyphs/C_olon.glif
new file mode 100644
index 0000000..bcccfc2
--- /dev/null
+++ b/tests/input/font-psf-test/source/PsfTest-Italic.ufo/glyphs/C_olon.glif
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="Colon" format="2">
+ <advance width="620"/>
+ <unicode hex="003A"/>
+ <outline>
+ <contour>
+ <point x="314" y="758" type="curve" smooth="yes"/>
+ <point x="314" y="696"/>
+ <point x="365" y="642"/>
+ <point x="430" y="642" type="curve" smooth="yes"/>
+ <point x="514" y="642"/>
+ <point x="590" y="712"/>
+ <point x="590" y="792" type="curve" smooth="yes"/>
+ <point x="590" y="854"/>
+ <point x="540" y="907"/>
+ <point x="476" y="907" type="curve" smooth="yes"/>
+ <point x="393" y="907"/>
+ <point x="314" y="837"/>
+ </contour>
+ <contour>
+ <point x="148" y="90" type="curve" smooth="yes"/>
+ <point x="148" y="28"/>
+ <point x="198" y="-25"/>
+ <point x="263" y="-25" type="curve" smooth="yes"/>
+ <point x="347" y="-25"/>
+ <point x="424" y="45"/>
+ <point x="424" y="125" type="curve" smooth="yes"/>
+ <point x="424" y="186"/>
+ <point x="374" y="240"/>
+ <point x="309" y="240" type="curve" smooth="yes"/>
+ <point x="225" y="240"/>
+ <point x="148" y="170"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/input/font-psf-test/source/PsfTest-Italic.ufo/glyphs/C_ombA_cute.glif b/tests/input/font-psf-test/source/PsfTest-Italic.ufo/glyphs/C_ombA_cute.glif
new file mode 100644
index 0000000..a7607fe
--- /dev/null
+++ b/tests/input/font-psf-test/source/PsfTest-Italic.ufo/glyphs/C_ombA_cute.glif
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="CombAcute" format="2">
+ <unicode hex="0301"/>
+ <anchor x="-221" y="1635" name="U"/>
+ <anchor x="-355" y="1100" name="_U"/>
+ <outline>
+ <contour>
+ <point x="-99" y="1568" type="line"/>
+ <point x="-524" y="1147" type="line"/>
+ <point x="-354" y="1147" type="line"/>
+ <point x="150" y="1568" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/input/font-psf-test/source/PsfTest-Italic.ufo/glyphs/C_ombC_ircum.glif b/tests/input/font-psf-test/source/PsfTest-Italic.ufo/glyphs/C_ombC_ircum.glif
new file mode 100644
index 0000000..6614f85
--- /dev/null
+++ b/tests/input/font-psf-test/source/PsfTest-Italic.ufo/glyphs/C_ombC_ircum.glif
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="CombCircum" format="2">
+ <unicode hex="0302"/>
+ <anchor x="-221" y="1635" name="U"/>
+ <anchor x="-320" y="1100" name="_U"/>
+ <outline>
+ <contour>
+ <point x="-619" y="1147" type="line"/>
+ <point x="-275" y="1421" type="line"/>
+ <point x="-69" y="1147" type="line"/>
+ <point x="80" y="1147" type="line"/>
+ <point x="-174" y="1568" type="line"/>
+ <point x="-344" y="1568" type="line"/>
+ <point x="-769" y="1147" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/input/font-psf-test/source/PsfTest-Italic.ufo/glyphs/C_ombD_iaer.glif b/tests/input/font-psf-test/source/PsfTest-Italic.ufo/glyphs/C_ombD_iaer.glif
new file mode 100644
index 0000000..d6b35b7
--- /dev/null
+++ b/tests/input/font-psf-test/source/PsfTest-Italic.ufo/glyphs/C_ombD_iaer.glif
@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="CombDiaer" format="2">
+ <unicode hex="0308"/>
+ <anchor x="-253" y="1505" name="U"/>
+ <anchor x="-350" y="1100" name="_U"/>
+ <outline>
+ <contour>
+ <point x="39" y="1338" type="curve" smooth="yes"/>
+ <point x="39" y="1399"/>
+ <point x="-7" y="1450"/>
+ <point x="-72" y="1450" type="curve" smooth="yes"/>
+ <point x="-167" y="1450"/>
+ <point x="-229" y="1372"/>
+ <point x="-229" y="1299" type="curve" smooth="yes"/>
+ <point x="-229" y="1238"/>
+ <point x="-182" y="1186"/>
+ <point x="-118" y="1186" type="curve" smooth="yes"/>
+ <point x="-33" y="1186"/>
+ <point x="39" y="1259"/>
+ </contour>
+ <contour>
+ <point x="-381" y="1338" type="curve" smooth="yes"/>
+ <point x="-381" y="1399"/>
+ <point x="-427" y="1450"/>
+ <point x="-492" y="1450" type="curve" smooth="yes"/>
+ <point x="-587" y="1450"/>
+ <point x="-649" y="1372"/>
+ <point x="-649" y="1299" type="curve" smooth="yes"/>
+ <point x="-649" y="1238"/>
+ <point x="-602" y="1186"/>
+ <point x="-538" y="1186" type="curve" smooth="yes"/>
+ <point x="-453" y="1186"/>
+ <point x="-381" y="1259"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/input/font-psf-test/source/PsfTest-Italic.ufo/glyphs/C_ombG_rave.glif b/tests/input/font-psf-test/source/PsfTest-Italic.ufo/glyphs/C_ombG_rave.glif
new file mode 100644
index 0000000..8869bb9
--- /dev/null
+++ b/tests/input/font-psf-test/source/PsfTest-Italic.ufo/glyphs/C_ombG_rave.glif
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="CombGrave" format="2">
+ <unicode hex="0300"/>
+ <anchor x="-201" y="1635" name="U"/>
+ <anchor x="-335" y="1100" name="_U"/>
+ <outline>
+ <contour>
+ <point x="-619" y="1568" type="line"/>
+ <point x="-284" y="1147" type="line"/>
+ <point x="-134" y="1147" type="line"/>
+ <point x="-409" y="1568" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/input/font-psf-test/source/PsfTest-Italic.ufo/glyphs/C_ombR_ingA_bv.glif b/tests/input/font-psf-test/source/PsfTest-Italic.ufo/glyphs/C_ombR_ingA_bv.glif
new file mode 100644
index 0000000..38232a0
--- /dev/null
+++ b/tests/input/font-psf-test/source/PsfTest-Italic.ufo/glyphs/C_ombR_ingA_bv.glif
@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="CombRingAbv" format="2">
+ <unicode hex="030A"/>
+ <anchor x="-221" y="1635" name="U"/>
+ <anchor x="-385" y="1100" name="_U"/>
+ <outline>
+ <contour>
+ <point x="-377" y="1259" type="curve" smooth="yes"/>
+ <point x="-427" y="1259"/>
+ <point x="-456" y="1287"/>
+ <point x="-456" y="1329" type="curve" smooth="yes"/>
+ <point x="-456" y="1400"/>
+ <point x="-393" y="1455"/>
+ <point x="-328" y="1455" type="curve" smooth="yes"/>
+ <point x="-278" y="1455"/>
+ <point x="-248" y="1428"/>
+ <point x="-248" y="1385" type="curve" smooth="yes"/>
+ <point x="-248" y="1314"/>
+ <point x="-312" y="1259"/>
+ </contour>
+ <contour>
+ <point x="-573" y="1320" type="curve" smooth="yes"/>
+ <point x="-573" y="1224"/>
+ <point x="-498" y="1147"/>
+ <point x="-395" y="1147" type="curve" smooth="yes"/>
+ <point x="-257" y="1147"/>
+ <point x="-131" y="1263"/>
+ <point x="-131" y="1394" type="curve" smooth="yes"/>
+ <point x="-131" y="1491"/>
+ <point x="-206" y="1568"/>
+ <point x="-310" y="1568" type="curve" smooth="yes"/>
+ <point x="-448" y="1568"/>
+ <point x="-573" y="1451"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/input/font-psf-test/source/PsfTest-Italic.ufo/glyphs/C_ombT_ilde.glif b/tests/input/font-psf-test/source/PsfTest-Italic.ufo/glyphs/C_ombT_ilde.glif
new file mode 100644
index 0000000..f79322e
--- /dev/null
+++ b/tests/input/font-psf-test/source/PsfTest-Italic.ufo/glyphs/C_ombT_ilde.glif
@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="CombTilde" format="2">
+ <unicode hex="0303"/>
+ <anchor x="-290" y="1475" name="U"/>
+ <anchor x="-385" y="1100" name="_U"/>
+ <outline>
+ <contour>
+ <point x="-646" y="1181" type="line"/>
+ <point x="-629" y="1229"/>
+ <point x="-589" y="1269"/>
+ <point x="-540" y="1269" type="curve" smooth="yes"/>
+ <point x="-503" y="1269"/>
+ <point x="-466" y="1253"/>
+ <point x="-398" y="1218" type="curve" smooth="yes"/>
+ <point x="-344" y="1190"/>
+ <point x="-296" y="1171"/>
+ <point x="-243" y="1171" type="curve" smooth="yes"/>
+ <point x="-120" y="1171"/>
+ <point x="-15" y="1286"/>
+ <point x="16" y="1411" type="curve"/>
+ <point x="-89" y="1411" type="line"/>
+ <point x="-107" y="1366"/>
+ <point x="-147" y="1323"/>
+ <point x="-194" y="1323" type="curve" smooth="yes"/>
+ <point x="-236" y="1323"/>
+ <point x="-273" y="1342"/>
+ <point x="-338" y="1370" type="curve" smooth="yes"/>
+ <point x="-401" y="1397"/>
+ <point x="-442" y="1421"/>
+ <point x="-498" y="1421" type="curve" smooth="yes"/>
+ <point x="-617" y="1421"/>
+ <point x="-721" y="1300"/>
+ <point x="-751" y="1181" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/input/font-psf-test/source/PsfTest-Italic.ufo/glyphs/C_omma.glif b/tests/input/font-psf-test/source/PsfTest-Italic.ufo/glyphs/C_omma.glif
new file mode 100644
index 0000000..eaff517
--- /dev/null
+++ b/tests/input/font-psf-test/source/PsfTest-Italic.ufo/glyphs/C_omma.glif
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="Comma" format="2">
+ <advance width="630"/>
+ <unicode hex="002C"/>
+ <outline>
+ <contour>
+ <point x="137" y="49" type="line"/>
+ <point x="277" y="49" type="line"/>
+ <point x="252" y="-50"/>
+ <point x="145" y="-169"/>
+ <point x="73" y="-225" type="curve"/>
+ <point x="163" y="-265" type="line"/>
+ <point x="280" y="-175"/>
+ <point x="431" y="-28"/>
+ <point x="431" y="118" type="curve" smooth="yes"/>
+ <point x="431" y="193"/>
+ <point x="378" y="245"/>
+ <point x="311" y="245" type="curve" smooth="yes"/>
+ <point x="254" y="245"/>
+ <point x="190" y="209"/>
+ <point x="161" y="147" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/input/font-psf-test/source/PsfTest-Italic.ufo/glyphs/D_igitE_ight.glif b/tests/input/font-psf-test/source/PsfTest-Italic.ufo/glyphs/D_igitE_ight.glif
new file mode 100644
index 0000000..262f860
--- /dev/null
+++ b/tests/input/font-psf-test/source/PsfTest-Italic.ufo/glyphs/D_igitE_ight.glif
@@ -0,0 +1,63 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="DigitEight" format="2">
+ <advance width="1180"/>
+ <unicode hex="0038"/>
+ <anchor x="515" y="-100" name="L"/>
+ <anchor x="922" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="542" y="-25" type="curve" smooth="yes"/>
+ <point x="839" y="-25"/>
+ <point x="1160" y="170"/>
+ <point x="1160" y="475" type="curve" smooth="yes"/>
+ <point x="1160" y="626"/>
+ <point x="1068" y="733"/>
+ <point x="988" y="779" type="curve"/>
+ <point x="1155" y="860"/>
+ <point x="1270" y="970"/>
+ <point x="1270" y="1151" type="curve" smooth="yes"/>
+ <point x="1270" y="1340"/>
+ <point x="1102" y="1455"/>
+ <point x="901" y="1455" type="curve" smooth="yes"/>
+ <point x="620" y="1455"/>
+ <point x="348" y="1292"/>
+ <point x="348" y="1018" type="curve" smooth="yes"/>
+ <point x="348" y="891"/>
+ <point x="427" y="814"/>
+ <point x="483" y="779" type="curve"/>
+ <point x="297" y="706"/>
+ <point x="115" y="549"/>
+ <point x="115" y="325" type="curve" smooth="yes"/>
+ <point x="115" y="111"/>
+ <point x="317" y="-25"/>
+ </contour>
+ <contour>
+ <point x="750" y="848" type="curve" smooth="yes"/>
+ <point x="628" y="848"/>
+ <point x="541" y="917"/>
+ <point x="541" y="1029" type="curve" smooth="yes"/>
+ <point x="541" y="1205"/>
+ <point x="704" y="1299"/>
+ <point x="862" y="1299" type="curve" smooth="yes"/>
+ <point x="985" y="1299"/>
+ <point x="1076" y="1235"/>
+ <point x="1076" y="1128" type="curve" smooth="yes"/>
+ <point x="1076" y="955"/>
+ <point x="907" y="848"/>
+ </contour>
+ <contour>
+ <point x="564" y="142" type="curve" smooth="yes"/>
+ <point x="413" y="142"/>
+ <point x="322" y="225"/>
+ <point x="322" y="350" type="curve" smooth="yes"/>
+ <point x="322" y="557"/>
+ <point x="520" y="696"/>
+ <point x="712" y="696" type="curve" smooth="yes"/>
+ <point x="864" y="696"/>
+ <point x="961" y="602"/>
+ <point x="961" y="476" type="curve" smooth="yes"/>
+ <point x="961" y="266"/>
+ <point x="753" y="142"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/input/font-psf-test/source/PsfTest-Italic.ufo/glyphs/D_igitF_ive.glif b/tests/input/font-psf-test/source/PsfTest-Italic.ufo/glyphs/D_igitF_ive.glif
new file mode 100644
index 0000000..a224838
--- /dev/null
+++ b/tests/input/font-psf-test/source/PsfTest-Italic.ufo/glyphs/D_igitF_ive.glif
@@ -0,0 +1,44 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="DigitFive" format="2">
+ <advance width="1180"/>
+ <unicode hex="0035"/>
+ <anchor x="515" y="-100" name="L"/>
+ <anchor x="922" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="1296" y="1431" type="line"/>
+ <point x="491" y="1431" type="line"/>
+ <point x="302" y="671" type="line"/>
+ <point x="438" y="718"/>
+ <point x="537" y="735"/>
+ <point x="643" y="735" type="curve" smooth="yes"/>
+ <point x="784" y="735"/>
+ <point x="933" y="660"/>
+ <point x="933" y="508" type="curve" smooth="yes"/>
+ <point x="933" y="273"/>
+ <point x="710" y="152"/>
+ <point x="497" y="152" type="curve" smooth="yes"/>
+ <point x="357" y="152"/>
+ <point x="263" y="195"/>
+ <point x="170" y="284" type="curve"/>
+ <point x="89" y="78" type="line"/>
+ <point x="195" y="2"/>
+ <point x="326" y="-25"/>
+ <point x="481" y="-25" type="curve" smooth="yes"/>
+ <point x="807" y="-25"/>
+ <point x="1129" y="190"/>
+ <point x="1129" y="546" type="curve" smooth="yes"/>
+ <point x="1129" y="757"/>
+ <point x="951" y="911"/>
+ <point x="702" y="911" type="curve" smooth="yes"/>
+ <point x="629" y="911"/>
+ <point x="576" y="906"/>
+ <point x="544" y="902" type="curve"/>
+ <point x="635" y="1264" type="line"/>
+ <point x="1020" y="1264" type="line" smooth="yes"/>
+ <point x="1104" y="1264"/>
+ <point x="1179" y="1260"/>
+ <point x="1250" y="1245" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/input/font-psf-test/source/PsfTest-Italic.ufo/glyphs/D_igitF_our.glif b/tests/input/font-psf-test/source/PsfTest-Italic.ufo/glyphs/D_igitF_our.glif
new file mode 100644
index 0000000..eeccb48
--- /dev/null
+++ b/tests/input/font-psf-test/source/PsfTest-Italic.ufo/glyphs/D_igitF_our.glif
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="DigitFour" format="2">
+ <advance width="1180"/>
+ <unicode hex="0034"/>
+ <anchor x="522" y="-100" name="L"/>
+ <anchor x="929" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="1161" y="387" type="line"/>
+ <point x="1199" y="539" type="line"/>
+ <point x="1009" y="539" type="line"/>
+ <point x="1236" y="1450" type="line"/>
+ <point x="1026" y="1450" type="line"/>
+ <point x="144" y="539" type="line"/>
+ <point x="106" y="387" type="line"/>
+ <point x="781" y="387" type="line"/>
+ <point x="685" y="0" type="line"/>
+ <point x="875" y="0" type="line"/>
+ <point x="971" y="387" type="line"/>
+ </contour>
+ <contour>
+ <point x="985" y="1205" type="line"/>
+ <point x="819" y="539" type="line"/>
+ <point x="337" y="539" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/input/font-psf-test/source/PsfTest-Italic.ufo/glyphs/D_igitN_ine.glif b/tests/input/font-psf-test/source/PsfTest-Italic.ufo/glyphs/D_igitN_ine.glif
new file mode 100644
index 0000000..191cd79
--- /dev/null
+++ b/tests/input/font-psf-test/source/PsfTest-Italic.ufo/glyphs/D_igitN_ine.glif
@@ -0,0 +1,49 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="DigitNine" format="2">
+ <advance width="1180"/>
+ <unicode hex="0039"/>
+ <anchor x="515" y="-100" name="L"/>
+ <anchor x="922" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="157" y="94" type="line"/>
+ <point x="208" y="29"/>
+ <point x="355" y="-25"/>
+ <point x="473" y="-25" type="curve" smooth="yes"/>
+ <point x="999" y="-25"/>
+ <point x="1267" y="520"/>
+ <point x="1267" y="982" type="curve" smooth="yes"/>
+ <point x="1267" y="1248"/>
+ <point x="1127" y="1455"/>
+ <point x="866" y="1455" type="curve" smooth="yes"/>
+ <point x="596" y="1455"/>
+ <point x="303" y="1269"/>
+ <point x="303" y="932" type="curve" smooth="yes"/>
+ <point x="303" y="761"/>
+ <point x="425" y="574"/>
+ <point x="661" y="574" type="curve" smooth="yes"/>
+ <point x="852" y="574"/>
+ <point x="1036" y="683"/>
+ <point x="1172" y="840" type="curve"/>
+ <point x="1121" y="922" type="line"/>
+ <point x="1019" y="810"/>
+ <point x="872" y="745"/>
+ <point x="717" y="745" type="curve" smooth="yes"/>
+ <point x="584" y="745"/>
+ <point x="498" y="833"/>
+ <point x="498" y="956" type="curve" smooth="yes"/>
+ <point x="498" y="1146"/>
+ <point x="638" y="1284"/>
+ <point x="821" y="1284" type="curve" smooth="yes"/>
+ <point x="998" y="1284"/>
+ <point x="1073" y="1119"/>
+ <point x="1073" y="956" type="curve" smooth="yes"/>
+ <point x="1073" y="455"/>
+ <point x="760" y="147"/>
+ <point x="496" y="147" type="curve" smooth="yes"/>
+ <point x="410" y="147"/>
+ <point x="298" y="209"/>
+ <point x="249" y="285" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/input/font-psf-test/source/PsfTest-Italic.ufo/glyphs/D_igitO_ne.glif b/tests/input/font-psf-test/source/PsfTest-Italic.ufo/glyphs/D_igitO_ne.glif
new file mode 100644
index 0000000..a639774
--- /dev/null
+++ b/tests/input/font-psf-test/source/PsfTest-Italic.ufo/glyphs/D_igitO_ne.glif
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="DigitOne" format="2">
+ <advance width="1180"/>
+ <unicode hex="0031"/>
+ <anchor x="515" y="-100" name="L"/>
+ <anchor x="922" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="1021" y="167" type="line"/>
+ <point x="706" y="167" type="line"/>
+ <point x="1026" y="1450" type="line"/>
+ <point x="856" y="1450" type="line"/>
+ <point x="459" y="1243" type="line"/>
+ <point x="440" y="1066" type="line"/>
+ <point x="782" y="1235" type="line"/>
+ <point x="516" y="167" type="line"/>
+ <point x="201" y="167" type="line"/>
+ <point x="160" y="0" type="line"/>
+ <point x="980" y="0" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/input/font-psf-test/source/PsfTest-Italic.ufo/glyphs/D_igitS_even.glif b/tests/input/font-psf-test/source/PsfTest-Italic.ufo/glyphs/D_igitS_even.glif
new file mode 100644
index 0000000..68c6ef6
--- /dev/null
+++ b/tests/input/font-psf-test/source/PsfTest-Italic.ufo/glyphs/D_igitS_even.glif
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="DigitSeven" format="2">
+ <advance width="1180"/>
+ <unicode hex="0037"/>
+ <anchor x="515" y="-100" name="L"/>
+ <anchor x="922" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="420" y="0" type="line"/>
+ <point x="661" y="450"/>
+ <point x="972" y="877"/>
+ <point x="1367" y="1274" type="curve"/>
+ <point x="1406" y="1431" type="line"/>
+ <point x="386" y="1431" type="line"/>
+ <point x="341" y="1245" type="line"/>
+ <point x="421" y="1260"/>
+ <point x="538" y="1264"/>
+ <point x="726" y="1264" type="curve" smooth="yes"/>
+ <point x="1126" y="1264" type="line"/>
+ <point x="774" y="889"/>
+ <point x="517" y="555"/>
+ <point x="215" y="0" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/input/font-psf-test/source/PsfTest-Italic.ufo/glyphs/D_igitS_ix.glif b/tests/input/font-psf-test/source/PsfTest-Italic.ufo/glyphs/D_igitS_ix.glif
new file mode 100644
index 0000000..b6be793
--- /dev/null
+++ b/tests/input/font-psf-test/source/PsfTest-Italic.ufo/glyphs/D_igitS_ix.glif
@@ -0,0 +1,49 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="DigitSix" format="2">
+ <advance width="1180"/>
+ <unicode hex="0036"/>
+ <anchor x="515" y="-100" name="L"/>
+ <anchor x="922" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="1313" y="1347" type="line"/>
+ <point x="1248" y="1418"/>
+ <point x="1135" y="1455"/>
+ <point x="1017" y="1455" type="curve" smooth="yes"/>
+ <point x="481" y="1454"/>
+ <point x="208" y="915"/>
+ <point x="208" y="475" type="curve" smooth="yes"/>
+ <point x="208" y="167"/>
+ <point x="392" y="-25"/>
+ <point x="623" y="-25" type="curve" smooth="yes"/>
+ <point x="947" y="-25"/>
+ <point x="1183" y="169"/>
+ <point x="1183" y="517" type="curve" smooth="yes"/>
+ <point x="1183" y="709"/>
+ <point x="1029" y="887"/>
+ <point x="793" y="887" type="curve" smooth="yes"/>
+ <point x="636" y="887"/>
+ <point x="432" y="784"/>
+ <point x="317" y="633" type="curve"/>
+ <point x="364" y="559" type="line"/>
+ <point x="471" y="660"/>
+ <point x="596" y="716"/>
+ <point x="751" y="716" type="curve" smooth="yes"/>
+ <point x="898" y="716"/>
+ <point x="987" y="614"/>
+ <point x="987" y="454" type="curve" smooth="yes"/>
+ <point x="987" y="263"/>
+ <point x="816" y="147"/>
+ <point x="656" y="147" type="curve" smooth="yes"/>
+ <point x="491" y="147"/>
+ <point x="403" y="284"/>
+ <point x="403" y="472" type="curve" smooth="yes"/>
+ <point x="403" y="962"/>
+ <point x="664" y="1284"/>
+ <point x="985" y="1284" type="curve" smooth="yes"/>
+ <point x="1081" y="1284"/>
+ <point x="1174" y="1235"/>
+ <point x="1222" y="1156" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/input/font-psf-test/source/PsfTest-Italic.ufo/glyphs/D_igitT_hree.glif b/tests/input/font-psf-test/source/PsfTest-Italic.ufo/glyphs/D_igitT_hree.glif
new file mode 100644
index 0000000..e01df2c
--- /dev/null
+++ b/tests/input/font-psf-test/source/PsfTest-Italic.ufo/glyphs/D_igitT_hree.glif
@@ -0,0 +1,52 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="DigitThree" format="2">
+ <advance width="1180"/>
+ <unicode hex="0033"/>
+ <anchor x="515" y="-100" name="L"/>
+ <anchor x="922" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="562" y="853" type="line"/>
+ <point x="521" y="686" type="line"/>
+ <point x="591" y="686" type="line" smooth="yes"/>
+ <point x="802" y="686"/>
+ <point x="944" y="606"/>
+ <point x="944" y="476" type="curve" smooth="yes"/>
+ <point x="944" y="268"/>
+ <point x="738" y="147"/>
+ <point x="551" y="147" type="curve" smooth="yes"/>
+ <point x="371" y="147"/>
+ <point x="260" y="227"/>
+ <point x="181" y="348" type="curve"/>
+ <point x="104" y="137" type="line"/>
+ <point x="185" y="41"/>
+ <point x="341" y="-25"/>
+ <point x="518" y="-25" type="curve" smooth="yes"/>
+ <point x="815" y="-25"/>
+ <point x="1141" y="168"/>
+ <point x="1141" y="475" type="curve" smooth="yes"/>
+ <point x="1141" y="670"/>
+ <point x="973" y="763"/>
+ <point x="855" y="784" type="curve"/>
+ <point x="1046" y="827"/>
+ <point x="1266" y="955"/>
+ <point x="1266" y="1163" type="curve" smooth="yes"/>
+ <point x="1266" y="1338"/>
+ <point x="1073" y="1455"/>
+ <point x="852" y="1455" type="curve" smooth="yes"/>
+ <point x="685" y="1455"/>
+ <point x="536" y="1388"/>
+ <point x="433" y="1299" type="curve"/>
+ <point x="427" y="1132" type="line"/>
+ <point x="568" y="1246"/>
+ <point x="696" y="1284"/>
+ <point x="850" y="1284" type="curve" smooth="yes"/>
+ <point x="957" y="1284"/>
+ <point x="1068" y="1236"/>
+ <point x="1068" y="1137" type="curve" smooth="yes"/>
+ <point x="1068" y="949"/>
+ <point x="781" y="853"/>
+ <point x="632" y="853" type="curve" smooth="yes"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/input/font-psf-test/source/PsfTest-Italic.ufo/glyphs/D_igitT_wo.glif b/tests/input/font-psf-test/source/PsfTest-Italic.ufo/glyphs/D_igitT_wo.glif
new file mode 100644
index 0000000..d1bbb54
--- /dev/null
+++ b/tests/input/font-psf-test/source/PsfTest-Italic.ufo/glyphs/D_igitT_wo.glif
@@ -0,0 +1,37 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="DigitTwo" format="2">
+ <advance width="1180"/>
+ <unicode hex="0032"/>
+ <anchor x="515" y="-100" name="L"/>
+ <anchor x="882" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="1063" y="176" type="line"/>
+ <point x="980" y="163"/>
+ <point x="822" y="162"/>
+ <point x="625" y="162" type="curve" smooth="yes"/>
+ <point x="370" y="162" type="line"/>
+ <point x="783" y="393"/>
+ <point x="1210" y="830"/>
+ <point x="1210" y="1098" type="curve" smooth="yes"/>
+ <point x="1210" y="1296"/>
+ <point x="1075" y="1455"/>
+ <point x="842" y="1455" type="curve" smooth="yes"/>
+ <point x="673" y="1455"/>
+ <point x="488" y="1374"/>
+ <point x="380" y="1264" type="curve"/>
+ <point x="388" y="1098" type="line"/>
+ <point x="503" y="1203"/>
+ <point x="660" y="1279"/>
+ <point x="783" y="1279" type="curve" smooth="yes"/>
+ <point x="915" y="1279"/>
+ <point x="1003" y="1199"/>
+ <point x="1003" y="1063" type="curve" smooth="yes"/>
+ <point x="1003" y="848"/>
+ <point x="506" y="386"/>
+ <point x="101" y="167" type="curve"/>
+ <point x="60" y="0" type="line"/>
+ <point x="1020" y="0" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/input/font-psf-test/source/PsfTest-Italic.ufo/glyphs/D_igitZ_ero.glif b/tests/input/font-psf-test/source/PsfTest-Italic.ufo/glyphs/D_igitZ_ero.glif
new file mode 100644
index 0000000..5d1bf0e
--- /dev/null
+++ b/tests/input/font-psf-test/source/PsfTest-Italic.ufo/glyphs/D_igitZ_ero.glif
@@ -0,0 +1,49 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="DigitZero" format="2">
+ <advance width="1180"/>
+ <unicode hex="0030"/>
+ <anchor x="520" y="-100" name="L"/>
+ <anchor x="927" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="1024" y="711" type="curve" smooth="yes"/>
+ <point x="925" y="312"/>
+ <point x="747" y="142"/>
+ <point x="565" y="142" type="curve" smooth="yes"/>
+ <point x="432" y="142"/>
+ <point x="360" y="218"/>
+ <point x="360" y="383" type="curve" smooth="yes"/>
+ <point x="360" y="468"/>
+ <point x="377" y="579"/>
+ <point x="412" y="720" type="curve" smooth="yes"/>
+ <point x="512" y="1120"/>
+ <point x="678" y="1289"/>
+ <point x="871" y="1289" type="curve" smooth="yes"/>
+ <point x="1006" y="1289"/>
+ <point x="1077" y="1223"/>
+ <point x="1077" y="1051" type="curve" smooth="yes"/>
+ <point x="1077" y="966"/>
+ <point x="1060" y="854"/>
+ </contour>
+ <contour>
+ <point x="1230" y="715" type="curve" smooth="yes"/>
+ <point x="1262" y="841"/>
+ <point x="1276" y="949"/>
+ <point x="1276" y="1040" type="curve" smooth="yes"/>
+ <point x="1276" y="1335"/>
+ <point x="1124" y="1455"/>
+ <point x="902" y="1455" type="curve" smooth="yes"/>
+ <point x="613" y="1455"/>
+ <point x="344" y="1267"/>
+ <point x="206" y="716" type="curve" smooth="yes"/>
+ <point x="173" y="584"/>
+ <point x="158" y="474"/>
+ <point x="158" y="381" type="curve" smooth="yes"/>
+ <point x="158" y="104"/>
+ <point x="313" y="-25"/>
+ <point x="533" y="-25" type="curve" smooth="yes"/>
+ <point x="804" y="-25"/>
+ <point x="1086" y="138"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/input/font-psf-test/source/PsfTest-Italic.ufo/glyphs/D_ollarS_gn.glif b/tests/input/font-psf-test/source/PsfTest-Italic.ufo/glyphs/D_ollarS_gn.glif
new file mode 100644
index 0000000..5c2db20
--- /dev/null
+++ b/tests/input/font-psf-test/source/PsfTest-Italic.ufo/glyphs/D_ollarS_gn.glif
@@ -0,0 +1,53 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="DollarSgn" format="2">
+ <advance width="1180"/>
+ <unicode hex="0024"/>
+ <outline>
+ <contour>
+ <point x="1225" y="1280" type="line"/>
+ <point x="1119" y="1337"/>
+ <point x="1023" y="1361"/>
+ <point x="882" y="1361" type="curve" smooth="yes"/>
+ <point x="513" y="1361"/>
+ <point x="354" y="1182"/>
+ <point x="354" y="992" type="curve" smooth="yes"/>
+ <point x="354" y="837"/>
+ <point x="446" y="771"/>
+ <point x="639" y="650" type="curve" smooth="yes"/>
+ <point x="844" y="521"/>
+ <point x="919" y="439"/>
+ <point x="919" y="357" type="curve" smooth="yes"/>
+ <point x="919" y="244"/>
+ <point x="826" y="158"/>
+ <point x="635" y="158" type="curve" smooth="yes"/>
+ <point x="469" y="158"/>
+ <point x="314" y="266"/>
+ <point x="251" y="347" type="curve"/>
+ <point x="163" y="162" type="line"/>
+ <point x="304" y="58"/>
+ <point x="453" y="0"/>
+ <point x="606" y="0" type="curve" smooth="yes"/>
+ <point x="872" y="0"/>
+ <point x="1102" y="119"/>
+ <point x="1102" y="381" type="curve" smooth="yes"/>
+ <point x="1102" y="528"/>
+ <point x="981" y="657"/>
+ <point x="801" y="771" type="curve" smooth="yes"/>
+ <point x="610" y="892"/>
+ <point x="535" y="943"/>
+ <point x="535" y="1024" type="curve" smooth="yes"/>
+ <point x="535" y="1116"/>
+ <point x="657" y="1203"/>
+ <point x="832" y="1203" type="curve" smooth="yes"/>
+ <point x="950" y="1203"/>
+ <point x="1031" y="1176"/>
+ <point x="1144" y="1104" type="curve"/>
+ </contour>
+ <contour>
+ <point x="878" y="1568" type="line"/>
+ <point x="434" y="-216" type="line"/>
+ <point x="574" y="-216" type="line"/>
+ <point x="1018" y="1568" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/input/font-psf-test/source/PsfTest-Italic.ufo/glyphs/D_ottedC_irc.glif b/tests/input/font-psf-test/source/PsfTest-Italic.ufo/glyphs/D_ottedC_irc.glif
new file mode 100644
index 0000000..2cdf8fd
--- /dev/null
+++ b/tests/input/font-psf-test/source/PsfTest-Italic.ufo/glyphs/D_ottedC_irc.glif
@@ -0,0 +1,235 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="DottedCirc" format="2">
+ <advance width="1086"/>
+ <unicode hex="25CC"/>
+ <anchor x="493" y="0" name="H"/>
+ <anchor x="468" y="-100" name="L"/>
+ <anchor x="750" y="0" name="O"/>
+ <anchor x="743" y="1000" name="U"/>
+ <outline>
+ <contour>
+ <point x="588" y="834" type="curve" smooth="yes"/>
+ <point x="588" y="858"/>
+ <point x="571" y="867"/>
+ <point x="553" y="867" type="curve" smooth="yes"/>
+ <point x="521" y="867"/>
+ <point x="491" y="837"/>
+ <point x="491" y="809" type="curve" smooth="yes"/>
+ <point x="491" y="788"/>
+ <point x="508" y="773"/>
+ <point x="530" y="773" type="curve" smooth="yes"/>
+ <point x="564" y="773"/>
+ <point x="588" y="805"/>
+ </contour>
+ <contour>
+ <point x="677" y="124" type="curve" smooth="yes"/>
+ <point x="647" y="124"/>
+ <point x="620" y="93"/>
+ <point x="620" y="67" type="curve" smooth="yes"/>
+ <point x="620" y="46"/>
+ <point x="636" y="30"/>
+ <point x="657" y="30" type="curve" smooth="yes"/>
+ <point x="687" y="30"/>
+ <point x="718" y="60"/>
+ <point x="718" y="86" type="curve" smooth="yes"/>
+ <point x="718" y="109"/>
+ <point x="700" y="124"/>
+ </contour>
+ <contour>
+ <point x="396" y="780" type="curve" smooth="yes"/>
+ <point x="369" y="780"/>
+ <point x="336" y="753"/>
+ <point x="336" y="722" type="curve" smooth="yes"/>
+ <point x="336" y="702"/>
+ <point x="351" y="687"/>
+ <point x="374" y="687" type="curve" smooth="yes"/>
+ <point x="403" y="687"/>
+ <point x="434" y="711"/>
+ <point x="434" y="744" type="curve" smooth="yes"/>
+ <point x="434" y="764"/>
+ <point x="414" y="780"/>
+ </contour>
+ <contour>
+ <point x="873" y="175" type="curve" smooth="yes"/>
+ <point x="872" y="199"/>
+ <point x="854" y="211"/>
+ <point x="833" y="211" type="curve" smooth="yes"/>
+ <point x="803" y="211"/>
+ <point x="774" y="183"/>
+ <point x="774" y="153" type="curve" smooth="yes"/>
+ <point x="774" y="133"/>
+ <point x="789" y="119"/>
+ <point x="812" y="119" type="curve" smooth="yes"/>
+ <point x="843" y="119"/>
+ <point x="873" y="146"/>
+ </contour>
+ <contour>
+ <point x="313" y="612" type="curve" smooth="yes"/>
+ <point x="312" y="633"/>
+ <point x="296" y="650"/>
+ <point x="275" y="650" type="curve" smooth="yes"/>
+ <point x="247" y="650"/>
+ <point x="215" y="623"/>
+ <point x="215" y="592" type="curve" smooth="yes"/>
+ <point x="215" y="573"/>
+ <point x="227" y="556"/>
+ <point x="251" y="556" type="curve" smooth="yes"/>
+ <point x="278" y="556"/>
+ <point x="313" y="581"/>
+ </contour>
+ <contour>
+ <point x="994" y="306" type="curve" smooth="yes"/>
+ <point x="993" y="327"/>
+ <point x="978" y="341"/>
+ <point x="958" y="341" type="curve" smooth="yes"/>
+ <point x="933" y="341"/>
+ <point x="896" y="321"/>
+ <point x="896" y="284" type="curve" smooth="yes"/>
+ <point x="896" y="265"/>
+ <point x="909" y="249"/>
+ <point x="934" y="249" type="curve" smooth="yes"/>
+ <point x="963" y="249"/>
+ <point x="994" y="275"/>
+ </contour>
+ <contour>
+ <point x="205" y="495" type="curve" smooth="yes"/>
+ <point x="175" y="495"/>
+ <point x="145" y="468"/>
+ <point x="145" y="438" type="curve" smooth="yes"/>
+ <point x="145" y="418"/>
+ <point x="159" y="402"/>
+ <point x="183" y="402" type="curve" smooth="yes"/>
+ <point x="208" y="402"/>
+ <point x="244" y="428"/>
+ <point x="244" y="459" type="curve" smooth="yes"/>
+ <point x="244" y="479"/>
+ <point x="227" y="495"/>
+ </contour>
+ <contour>
+ <point x="1026" y="496" type="curve" smooth="yes"/>
+ <point x="999" y="496"/>
+ <point x="965" y="469"/>
+ <point x="965" y="438" type="curve" smooth="yes"/>
+ <point x="965" y="418"/>
+ <point x="979" y="403"/>
+ <point x="1004" y="403" type="curve" smooth="yes"/>
+ <point x="1033" y="403"/>
+ <point x="1064" y="431"/>
+ <point x="1064" y="460" type="curve" smooth="yes"/>
+ <point x="1064" y="480"/>
+ <point x="1048" y="496"/>
+ </contour>
+ <contour>
+ <point x="237" y="307" type="curve" smooth="yes"/>
+ <point x="237" y="327"/>
+ <point x="221" y="341"/>
+ <point x="199" y="341" type="curve" smooth="yes"/>
+ <point x="169" y="341"/>
+ <point x="138" y="314"/>
+ <point x="138" y="285" type="curve" smooth="yes"/>
+ <point x="138" y="263"/>
+ <point x="153" y="248"/>
+ <point x="175" y="248" type="curve" smooth="yes"/>
+ <point x="206" y="248"/>
+ <point x="237" y="278"/>
+ </contour>
+ <contour>
+ <point x="1071" y="613" type="curve" smooth="yes"/>
+ <point x="1071" y="634"/>
+ <point x="1055" y="650"/>
+ <point x="1034" y="650" type="curve" smooth="yes"/>
+ <point x="1003" y="650"/>
+ <point x="973" y="619"/>
+ <point x="973" y="590" type="curve" smooth="yes"/>
+ <point x="973" y="570"/>
+ <point x="989" y="556"/>
+ <point x="1009" y="556" type="curve" smooth="yes"/>
+ <point x="1041" y="556"/>
+ <point x="1071" y="585"/>
+ </contour>
+ <contour>
+ <point x="292" y="177" type="curve" smooth="yes"/>
+ <point x="292" y="197"/>
+ <point x="277" y="211"/>
+ <point x="253" y="211" type="curve" smooth="yes"/>
+ <point x="224" y="211"/>
+ <point x="194" y="181"/>
+ <point x="194" y="154" type="curve" smooth="yes"/>
+ <point x="194" y="134"/>
+ <point x="211" y="118"/>
+ <point x="232" y="118" type="curve" smooth="yes"/>
+ <point x="262" y="118"/>
+ <point x="292" y="148"/>
+ </contour>
+ <contour>
+ <point x="917" y="724" type="curve" smooth="yes"/>
+ <point x="917" y="704"/>
+ <point x="931" y="686"/>
+ <point x="954" y="686" type="curve" smooth="yes"/>
+ <point x="984" y="686"/>
+ <point x="1014" y="716"/>
+ <point x="1014" y="745" type="curve" smooth="yes"/>
+ <point x="1014" y="765"/>
+ <point x="1000" y="780"/>
+ <point x="977" y="780" type="curve" smooth="yes"/>
+ <point x="947" y="780"/>
+ <point x="917" y="753"/>
+ </contour>
+ <contour>
+ <point x="403" y="87" type="curve" smooth="yes"/>
+ <point x="403" y="107"/>
+ <point x="390" y="123"/>
+ <point x="367" y="123" type="curve" smooth="yes"/>
+ <point x="339" y="123"/>
+ <point x="305" y="96"/>
+ <point x="305" y="68" type="curve" smooth="yes"/>
+ <point x="305" y="49"/>
+ <point x="320" y="30"/>
+ <point x="343" y="30" type="curve" smooth="yes"/>
+ <point x="371" y="30"/>
+ <point x="403" y="56"/>
+ </contour>
+ <contour>
+ <point x="806" y="810" type="curve" smooth="yes"/>
+ <point x="806" y="791"/>
+ <point x="819" y="773"/>
+ <point x="842" y="773" type="curve" smooth="yes"/>
+ <point x="869" y="773"/>
+ <point x="903" y="799"/>
+ <point x="903" y="830" type="curve" smooth="yes"/>
+ <point x="903" y="850"/>
+ <point x="889" y="867"/>
+ <point x="866" y="867" type="curve" smooth="yes"/>
+ <point x="836" y="867"/>
+ <point x="806" y="839"/>
+ </contour>
+ <contour>
+ <point x="553" y="57" type="curve" smooth="yes"/>
+ <point x="553" y="78"/>
+ <point x="538" y="93"/>
+ <point x="516" y="93" type="curve" smooth="yes"/>
+ <point x="485" y="93"/>
+ <point x="456" y="65"/>
+ <point x="456" y="36" type="curve" smooth="yes"/>
+ <point x="456" y="16"/>
+ <point x="471" y="0"/>
+ <point x="493" y="0" type="curve" smooth="yes"/>
+ <point x="523" y="0"/>
+ <point x="553" y="27"/>
+ </contour>
+ <contour>
+ <point x="656" y="839" type="curve" smooth="yes"/>
+ <point x="656" y="819"/>
+ <point x="671" y="805"/>
+ <point x="693" y="805" type="curve" smooth="yes"/>
+ <point x="721" y="805"/>
+ <point x="754" y="830"/>
+ <point x="754" y="861" type="curve" smooth="yes"/>
+ <point x="754" y="882"/>
+ <point x="738" y="898"/>
+ <point x="716" y="898" type="curve" smooth="yes"/>
+ <point x="685" y="898"/>
+ <point x="656" y="868"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/input/font-psf-test/source/PsfTest-Italic.ufo/glyphs/E_qS_gn.glif b/tests/input/font-psf-test/source/PsfTest-Italic.ufo/glyphs/E_qS_gn.glif
new file mode 100644
index 0000000..3d756e8
--- /dev/null
+++ b/tests/input/font-psf-test/source/PsfTest-Italic.ufo/glyphs/E_qS_gn.glif
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="EqSgn" format="2">
+ <advance width="1180"/>
+ <unicode hex="003D"/>
+ <outline>
+ <contour>
+ <point x="177" y="470" type="line"/>
+ <point x="1137" y="470" type="line"/>
+ <point x="1173" y="617" type="line"/>
+ <point x="213" y="617" type="line"/>
+ </contour>
+ <contour>
+ <point x="262" y="813" type="line"/>
+ <point x="1222" y="813" type="line"/>
+ <point x="1259" y="960" type="line"/>
+ <point x="299" y="960" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/input/font-psf-test/source/PsfTest-Italic.ufo/glyphs/E_xclamationM_rk.glif b/tests/input/font-psf-test/source/PsfTest-Italic.ufo/glyphs/E_xclamationM_rk.glif
new file mode 100644
index 0000000..a1c14d9
--- /dev/null
+++ b/tests/input/font-psf-test/source/PsfTest-Italic.ufo/glyphs/E_xclamationM_rk.glif
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="ExclamationMrk" format="2">
+ <advance width="744"/>
+ <unicode hex="0021"/>
+ <outline>
+ <contour>
+ <point x="497" y="431" type="line"/>
+ <point x="574" y="715"/>
+ <point x="653" y="1054"/>
+ <point x="799" y="1480" type="curve"/>
+ <point x="544" y="1480" type="line"/>
+ <point x="475" y="1054"/>
+ <point x="386" y="715"/>
+ <point x="322" y="431" type="curve"/>
+ </contour>
+ <contour>
+ <point x="188" y="90" type="curve" smooth="yes"/>
+ <point x="188" y="28"/>
+ <point x="238" y="-25"/>
+ <point x="303" y="-25" type="curve" smooth="yes"/>
+ <point x="387" y="-25"/>
+ <point x="464" y="45"/>
+ <point x="464" y="125" type="curve" smooth="yes"/>
+ <point x="464" y="186"/>
+ <point x="414" y="240"/>
+ <point x="349" y="240" type="curve" smooth="yes"/>
+ <point x="265" y="240"/>
+ <point x="188" y="170"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/input/font-psf-test/source/PsfTest-Italic.ufo/glyphs/F_ullS_top.glif b/tests/input/font-psf-test/source/PsfTest-Italic.ufo/glyphs/F_ullS_top.glif
new file mode 100644
index 0000000..a6c4d08
--- /dev/null
+++ b/tests/input/font-psf-test/source/PsfTest-Italic.ufo/glyphs/F_ullS_top.glif
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="FullStop" format="2">
+ <advance width="620"/>
+ <unicode hex="002E"/>
+ <outline>
+ <contour>
+ <point x="148" y="90" type="curve" smooth="yes"/>
+ <point x="148" y="28"/>
+ <point x="198" y="-25"/>
+ <point x="263" y="-25" type="curve" smooth="yes"/>
+ <point x="347" y="-25"/>
+ <point x="424" y="45"/>
+ <point x="424" y="125" type="curve" smooth="yes"/>
+ <point x="424" y="186"/>
+ <point x="374" y="240"/>
+ <point x="309" y="240" type="curve" smooth="yes"/>
+ <point x="225" y="240"/>
+ <point x="148" y="170"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/input/font-psf-test/source/PsfTest-Italic.ufo/glyphs/G_T_S_gn.glif b/tests/input/font-psf-test/source/PsfTest-Italic.ufo/glyphs/G_T_S_gn.glif
new file mode 100644
index 0000000..12da8b3
--- /dev/null
+++ b/tests/input/font-psf-test/source/PsfTest-Italic.ufo/glyphs/G_T_S_gn.glif
@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="GTSgn" format="2">
+ <advance width="1180"/>
+ <unicode hex="003E"/>
+ <outline>
+ <contour>
+ <point x="312" y="1014" type="line"/>
+ <point x="1028" y="725" type="line"/>
+ <point x="163" y="417" type="line"/>
+ <point x="119" y="240" type="line"/>
+ <point x="1197" y="632" type="line"/>
+ <point x="1239" y="799" type="line"/>
+ <point x="356" y="1191" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/input/font-psf-test/source/PsfTest-Italic.ufo/glyphs/G_raveA_ccent.glif b/tests/input/font-psf-test/source/PsfTest-Italic.ufo/glyphs/G_raveA_ccent.glif
new file mode 100644
index 0000000..48adfc4
--- /dev/null
+++ b/tests/input/font-psf-test/source/PsfTest-Italic.ufo/glyphs/G_raveA_ccent.glif
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="GraveAccent" format="2">
+ <advance width="560"/>
+ <unicode hex="0060"/>
+ <anchor x="738" y="1635" name="U"/>
+ <outline>
+ <contour>
+ <point x="261" y="1568" type="line"/>
+ <point x="596" y="1147" type="line"/>
+ <point x="746" y="1147" type="line"/>
+ <point x="471" y="1568" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/input/font-psf-test/source/PsfTest-Italic.ufo/glyphs/H_yphen.glif b/tests/input/font-psf-test/source/PsfTest-Italic.ufo/glyphs/H_yphen.glif
new file mode 100644
index 0000000..ae8cad5
--- /dev/null
+++ b/tests/input/font-psf-test/source/PsfTest-Italic.ufo/glyphs/H_yphen.glif
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="Hyphen" format="2">
+ <advance width="840"/>
+ <unicode hex="2010"/>
+ <anchor x="645" y="1100" name="U"/>
+ <outline>
+ <contour>
+ <point x="155" y="544" type="line"/>
+ <point x="855" y="544" type="line"/>
+ <point x="892" y="691" type="line"/>
+ <point x="192" y="691" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/input/font-psf-test/source/PsfTest-Italic.ufo/glyphs/H_yphenM_inus.glif b/tests/input/font-psf-test/source/PsfTest-Italic.ufo/glyphs/H_yphenM_inus.glif
new file mode 100644
index 0000000..155b460
--- /dev/null
+++ b/tests/input/font-psf-test/source/PsfTest-Italic.ufo/glyphs/H_yphenM_inus.glif
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="HyphenMinus" format="2">
+ <advance width="840"/>
+ <unicode hex="002D"/>
+ <anchor x="645" y="1100" name="U"/>
+ <outline>
+ <contour>
+ <point x="155" y="544" type="line"/>
+ <point x="855" y="544" type="line"/>
+ <point x="892" y="691" type="line"/>
+ <point x="192" y="691" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/input/font-psf-test/source/PsfTest-Italic.ufo/glyphs/H_yphen_S_oft.glif b/tests/input/font-psf-test/source/PsfTest-Italic.ufo/glyphs/H_yphen_S_oft.glif
new file mode 100644
index 0000000..0c7b834
--- /dev/null
+++ b/tests/input/font-psf-test/source/PsfTest-Italic.ufo/glyphs/H_yphen_S_oft.glif
@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="Hyphen_Soft" format="2">
+ <advance width="840"/>
+ <unicode hex="00AD"/>
+ <anchor x="645" y="1100" name="U"/>
+ <outline>
+ <component base="HyphenMinus"/>
+ </outline>
+</glyph>
diff --git a/tests/input/font-psf-test/source/PsfTest-Italic.ufo/glyphs/L_T_S_gn.glif b/tests/input/font-psf-test/source/PsfTest-Italic.ufo/glyphs/L_T_S_gn.glif
new file mode 100644
index 0000000..3c857a5
--- /dev/null
+++ b/tests/input/font-psf-test/source/PsfTest-Italic.ufo/glyphs/L_T_S_gn.glif
@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LTSgn" format="2">
+ <advance width="1180"/>
+ <unicode hex="003C"/>
+ <outline>
+ <contour>
+ <point x="1123" y="417" type="line"/>
+ <point x="408" y="705" type="line"/>
+ <point x="1272" y="1014" type="line"/>
+ <point x="1316" y="1191" type="line"/>
+ <point x="239" y="799" type="line"/>
+ <point x="197" y="632" type="line"/>
+ <point x="1079" y="240" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/input/font-psf-test/source/PsfTest-Italic.ufo/glyphs/L_ftC_urlyB_rac.glif b/tests/input/font-psf-test/source/PsfTest-Italic.ufo/glyphs/L_ftC_urlyB_rac.glif
new file mode 100644
index 0000000..4f8c90c
--- /dev/null
+++ b/tests/input/font-psf-test/source/PsfTest-Italic.ufo/glyphs/L_ftC_urlyB_rac.glif
@@ -0,0 +1,50 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LftCurlyBrac" format="2">
+ <advance width="980"/>
+ <unicode hex="007B"/>
+ <outline>
+ <contour>
+ <point x="713" y="-265" type="line"/>
+ <point x="660" y="-250"/>
+ <point x="526" y="-188"/>
+ <point x="526" y="-158" type="curve" smooth="yes"/>
+ <point x="526" y="-59"/>
+ <point x="649" y="404"/>
+ <point x="649" y="469" type="curve" smooth="yes"/>
+ <point x="649" y="509"/>
+ <point x="520" y="577"/>
+ <point x="520" y="602" type="curve" smooth="yes"/>
+ <point x="520" y="620"/>
+ <point x="688" y="700"/>
+ <point x="712" y="730" type="curve" smooth="yes"/>
+ <point x="741" y="767"/>
+ <point x="867" y="1326"/>
+ <point x="912" y="1372" type="curve" smooth="yes"/>
+ <point x="938" y="1399"/>
+ <point x="1073" y="1447"/>
+ <point x="1146" y="1470" type="curve"/>
+ <point x="1140" y="1607" type="line"/>
+ <point x="1030" y="1581"/>
+ <point x="856" y="1529"/>
+ <point x="805" y="1485" type="curve" smooth="yes"/>
+ <point x="714" y="1406"/>
+ <point x="572" y="796"/>
+ <point x="540" y="764" type="curve" smooth="yes"/>
+ <point x="504" y="729"/>
+ <point x="300" y="633"/>
+ <point x="300" y="601" type="curve" smooth="yes"/>
+ <point x="300" y="560"/>
+ <point x="460" y="468"/>
+ <point x="460" y="432" type="curve" smooth="yes"/>
+ <point x="460" y="362"/>
+ <point x="355" y="-53"/>
+ <point x="355" y="-219" type="curve" smooth="yes"/>
+ <point x="355" y="-247"/>
+ <point x="358" y="-268"/>
+ <point x="365" y="-279" type="curve" smooth="yes"/>
+ <point x="394" y="-323"/>
+ <point x="542" y="-375"/>
+ <point x="639" y="-402" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/input/font-psf-test/source/PsfTest-Italic.ufo/glyphs/L_ftP_aren.glif b/tests/input/font-psf-test/source/PsfTest-Italic.ufo/glyphs/L_ftP_aren.glif
new file mode 100644
index 0000000..bc65fc1
--- /dev/null
+++ b/tests/input/font-psf-test/source/PsfTest-Italic.ufo/glyphs/L_ftP_aren.glif
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LftParen" format="2">
+ <advance width="775"/>
+ <unicode hex="0028"/>
+ <outline>
+ <contour>
+ <point x="895" y="1607" type="line"/>
+ <point x="582" y="1415"/>
+ <point x="314" y="1061"/>
+ <point x="207" y="633" type="curve" smooth="yes"/>
+ <point x="176" y="508"/>
+ <point x="161" y="386"/>
+ <point x="161" y="270" type="curve" smooth="yes"/>
+ <point x="161" y="17"/>
+ <point x="233" y="-211"/>
+ <point x="374" y="-402" type="curve"/>
+ <point x="505" y="-260" type="line"/>
+ <point x="397" y="-102"/>
+ <point x="348" y="75"/>
+ <point x="348" y="270" type="curve" smooth="yes"/>
+ <point x="348" y="385"/>
+ <point x="365" y="506"/>
+ <point x="397" y="633" type="curve" smooth="yes"/>
+ <point x="484" y="982"/>
+ <point x="647" y="1254"/>
+ <point x="932" y="1455" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/input/font-psf-test/source/PsfTest-Italic.ufo/glyphs/L_ftS_qrB_rac.glif b/tests/input/font-psf-test/source/PsfTest-Italic.ufo/glyphs/L_ftS_qrB_rac.glif
new file mode 100644
index 0000000..6d064d1
--- /dev/null
+++ b/tests/input/font-psf-test/source/PsfTest-Italic.ufo/glyphs/L_ftS_qrB_rac.glif
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LftSqrBrac" format="2">
+ <advance width="770"/>
+ <unicode hex="005B"/>
+ <outline>
+ <contour>
+ <point x="484" y="-402" type="line"/>
+ <point x="521" y="-255" type="line"/>
+ <point x="266" y="-255" type="line"/>
+ <point x="679" y="1421" type="line"/>
+ <point x="934" y="1421" type="line"/>
+ <point x="970" y="1568" type="line"/>
+ <point x="530" y="1568" type="line"/>
+ <point x="44" y="-402" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/input/font-psf-test/source/PsfTest-Italic.ufo/glyphs/L_owL_ine.glif b/tests/input/font-psf-test/source/PsfTest-Italic.ufo/glyphs/L_owL_ine.glif
new file mode 100644
index 0000000..879d36b
--- /dev/null
+++ b/tests/input/font-psf-test/source/PsfTest-Italic.ufo/glyphs/L_owL_ine.glif
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LowLine" format="2">
+ <advance width="1254"/>
+ <unicode hex="005F"/>
+ <outline>
+ <contour>
+ <point x="-138" y="-314" type="line"/>
+ <point x="1135" y="-314" type="line"/>
+ <point x="1172" y="-167" type="line"/>
+ <point x="-101" y="-167" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/input/font-psf-test/source/PsfTest-Italic.ufo/glyphs/L_tnC_apA_.glif b/tests/input/font-psf-test/source/PsfTest-Italic.ufo/glyphs/L_tnC_apA_.glif
new file mode 100644
index 0000000..3a14b0e
--- /dev/null
+++ b/tests/input/font-psf-test/source/PsfTest-Italic.ufo/glyphs/L_tnC_apA_.glif
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnCapA" format="2">
+ <advance width="1395"/>
+ <unicode hex="0041"/>
+ <anchor x="1170" y="0" name="H"/>
+ <anchor x="602" y="-100" name="L"/>
+ <anchor x="1390" y="0" name="O"/>
+ <anchor x="1009" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="1080" y="0" type="line"/>
+ <point x="1275" y="0" type="line"/>
+ <point x="1259" y="78"/>
+ <point x="1243" y="166"/>
+ <point x="1221" y="348" type="curve" smooth="yes"/>
+ <point x="1091" y="1431" type="line"/>
+ <point x="876" y="1431" type="line"/>
+ <point x="206" y="348" type="line" smooth="yes"/>
+ <point x="93" y="165"/>
+ <point x="35" y="79"/>
+ <point x="-20" y="0" type="curve"/>
+ <point x="195" y="0" type="line"/>
+ <point x="422" y="377" type="line"/>
+ <point x="1038" y="377" type="line"/>
+ </contour>
+ <contour>
+ <point x="944" y="1240" type="line"/>
+ <point x="1022" y="529" type="line"/>
+ <point x="514" y="529" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/input/font-psf-test/source/PsfTest-Italic.ufo/glyphs/L_tnC_apA_D_iaer.glif b/tests/input/font-psf-test/source/PsfTest-Italic.ufo/glyphs/L_tnC_apA_D_iaer.glif
new file mode 100644
index 0000000..6c3502c
--- /dev/null
+++ b/tests/input/font-psf-test/source/PsfTest-Italic.ufo/glyphs/L_tnC_apA_D_iaer.glif
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnCapADiaer" format="2">
+ <advance width="1395"/>
+ <unicode hex="00C4"/>
+ <anchor x="1170" y="0" name="H"/>
+ <anchor x="602" y="-100" name="L"/>
+ <anchor x="1390" y="0" name="O"/>
+ <anchor x="1106" y="1935" name="U"/>
+ <outline>
+ <component base="LtnCapA"/>
+ <component base="CombDiaer" xOffset="1359" yOffset="430"/>
+ </outline>
+</glyph>
diff --git a/tests/input/font-psf-test/source/PsfTest-Italic.ufo/glyphs/L_tnC_apB_.glif b/tests/input/font-psf-test/source/PsfTest-Italic.ufo/glyphs/L_tnC_apB_.glif
new file mode 100644
index 0000000..5445f93
--- /dev/null
+++ b/tests/input/font-psf-test/source/PsfTest-Italic.ufo/glyphs/L_tnC_apB_.glif
@@ -0,0 +1,62 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnCapB" format="2">
+ <advance width="1271"/>
+ <unicode hex="0042"/>
+ <anchor x="530" y="-100" name="L"/>
+ <anchor x="937" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="625" y="1284" type="line"/>
+ <point x="667" y="1286"/>
+ <point x="733" y="1289"/>
+ <point x="811" y="1289" type="curve" smooth="yes"/>
+ <point x="993" y="1289"/>
+ <point x="1080" y="1230"/>
+ <point x="1080" y="1105" type="curve" smooth="yes"/>
+ <point x="1080" y="932"/>
+ <point x="931" y="838"/>
+ <point x="698" y="838" type="curve" smooth="yes"/>
+ <point x="513" y="838" type="line"/>
+ </contour>
+ <contour>
+ <point x="226" y="446" type="line"/>
+ <point x="178" y="252"/>
+ <point x="134" y="78"/>
+ <point x="100" y="0" type="curve"/>
+ <point x="151" y="-5"/>
+ <point x="359" y="-10"/>
+ <point x="562" y="-10" type="curve" smooth="yes"/>
+ <point x="960" y="-10"/>
+ <point x="1201" y="149"/>
+ <point x="1201" y="453" type="curve" smooth="yes"/>
+ <point x="1201" y="644"/>
+ <point x="1067" y="736"/>
+ <point x="955" y="764" type="curve"/>
+ <point x="1155" y="819"/>
+ <point x="1283" y="941"/>
+ <point x="1283" y="1140" type="curve" smooth="yes"/>
+ <point x="1283" y="1310"/>
+ <point x="1136" y="1441"/>
+ <point x="869" y="1441" type="curve" smooth="yes"/>
+ <point x="700" y="1441"/>
+ <point x="546" y="1437"/>
+ <point x="456" y="1431" type="curve"/>
+ <point x="452" y="1352"/>
+ <point x="407" y="1172"/>
+ <point x="359" y="980" type="curve" smooth="yes"/>
+ </contour>
+ <contour>
+ <point x="476" y="686" type="line"/>
+ <point x="721" y="686" type="line" smooth="yes"/>
+ <point x="892" y="686"/>
+ <point x="1011" y="598"/>
+ <point x="1011" y="450" type="curve" smooth="yes"/>
+ <point x="1011" y="218"/>
+ <point x="806" y="147"/>
+ <point x="586" y="147" type="curve" smooth="yes"/>
+ <point x="474" y="147"/>
+ <point x="379" y="150"/>
+ <point x="342" y="152" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/input/font-psf-test/source/PsfTest-Italic.ufo/glyphs/L_tnC_apC_.glif b/tests/input/font-psf-test/source/PsfTest-Italic.ufo/glyphs/L_tnC_apC_.glif
new file mode 100644
index 0000000..c2e4948
--- /dev/null
+++ b/tests/input/font-psf-test/source/PsfTest-Italic.ufo/glyphs/L_tnC_apC_.glif
@@ -0,0 +1,38 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnCapC" format="2">
+ <advance width="1341"/>
+ <unicode hex="0043"/>
+ <anchor x="690" y="0" name="H"/>
+ <anchor x="665" y="-100" name="L"/>
+ <anchor x="1072" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="1237" y="318" type="line"/>
+ <point x="1115" y="222"/>
+ <point x="934" y="147"/>
+ <point x="752" y="147" type="curve" smooth="yes"/>
+ <point x="537" y="147"/>
+ <point x="385" y="304"/>
+ <point x="385" y="532" type="curve" smooth="yes"/>
+ <point x="385" y="964"/>
+ <point x="704" y="1289"/>
+ <point x="1037" y="1289" type="curve" smooth="yes"/>
+ <point x="1168" y="1289"/>
+ <point x="1310" y="1235"/>
+ <point x="1385" y="1132" type="curve"/>
+ <point x="1489" y="1308" type="line"/>
+ <point x="1388" y="1408"/>
+ <point x="1201" y="1455"/>
+ <point x="1058" y="1455" type="curve" smooth="yes"/>
+ <point x="645" y="1455"/>
+ <point x="185" y="1093"/>
+ <point x="185" y="513" type="curve" smooth="yes"/>
+ <point x="185" y="202"/>
+ <point x="381" y="-25"/>
+ <point x="709" y="-25" type="curve" smooth="yes"/>
+ <point x="896" y="-25"/>
+ <point x="1087" y="21"/>
+ <point x="1230" y="127" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/input/font-psf-test/source/PsfTest-Italic.ufo/glyphs/L_tnC_apD_.glif b/tests/input/font-psf-test/source/PsfTest-Italic.ufo/glyphs/L_tnC_apD_.glif
new file mode 100644
index 0000000..3b93811
--- /dev/null
+++ b/tests/input/font-psf-test/source/PsfTest-Italic.ufo/glyphs/L_tnC_apD_.glif
@@ -0,0 +1,51 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnCapD" format="2">
+ <advance width="1421"/>
+ <unicode hex="0044"/>
+ <anchor x="630" y="-100" name="L"/>
+ <anchor x="1037" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="226" y="446" type="line"/>
+ <point x="176" y="252"/>
+ <point x="134" y="78"/>
+ <point x="100" y="0" type="curve"/>
+ <point x="100" y="0"/>
+ <point x="414" y="-10"/>
+ <point x="542" y="-10" type="curve" smooth="yes"/>
+ <point x="985" y="-10"/>
+ <point x="1299" y="181"/>
+ <point x="1415" y="648" type="curve" smooth="yes"/>
+ <point x="1437" y="738"/>
+ <point x="1447" y="819"/>
+ <point x="1447" y="891" type="curve" smooth="yes"/>
+ <point x="1447" y="1279"/>
+ <point x="1188" y="1441"/>
+ <point x="894" y="1441" type="curve" smooth="yes"/>
+ <point x="759" y="1441"/>
+ <point x="543" y="1437"/>
+ <point x="456" y="1431" type="curve"/>
+ <point x="452" y="1352"/>
+ <point x="407" y="1172"/>
+ <point x="359" y="980" type="curve" smooth="yes"/>
+ </contour>
+ <contour>
+ <point x="623" y="1279" type="line"/>
+ <point x="674" y="1281"/>
+ <point x="764" y="1284"/>
+ <point x="830" y="1284" type="curve" smooth="yes"/>
+ <point x="1105" y="1284"/>
+ <point x="1246" y="1140"/>
+ <point x="1246" y="850" type="curve" smooth="yes"/>
+ <point x="1246" y="784"/>
+ <point x="1236" y="710"/>
+ <point x="1216" y="629" type="curve" smooth="yes"/>
+ <point x="1134" y="300"/>
+ <point x="925" y="152"/>
+ <point x="572" y="152" type="curve" smooth="yes"/>
+ <point x="477" y="152"/>
+ <point x="391" y="158"/>
+ <point x="345" y="162" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/input/font-psf-test/source/PsfTest-Italic.ufo/glyphs/L_tnC_apE_.glif b/tests/input/font-psf-test/source/PsfTest-Italic.ufo/glyphs/L_tnC_apE_.glif
new file mode 100644
index 0000000..8b5f8b9
--- /dev/null
+++ b/tests/input/font-psf-test/source/PsfTest-Italic.ufo/glyphs/L_tnC_apE_.glif
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnCapE" format="2">
+ <advance width="1140"/>
+ <unicode hex="0045"/>
+ <anchor x="540" y="0" name="H"/>
+ <anchor x="515" y="-100" name="L"/>
+ <anchor x="857" y="0" name="O"/>
+ <anchor x="1400" y="1200" name="R"/>
+ <anchor x="922" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="511" y="828" type="line"/>
+ <point x="621" y="1269" type="line"/>
+ <point x="1266" y="1269" type="line"/>
+ <point x="1306" y="1431" type="line"/>
+ <point x="456" y="1431" type="line"/>
+ <point x="452" y="1352"/>
+ <point x="413" y="1197"/>
+ <point x="365" y="1005" type="curve" smooth="yes"/>
+ <point x="221" y="426" type="line" smooth="yes"/>
+ <point x="173" y="233"/>
+ <point x="134" y="78"/>
+ <point x="100" y="0" type="curve"/>
+ <point x="980" y="0" type="line"/>
+ <point x="1023" y="176" type="line"/>
+ <point x="940" y="163"/>
+ <point x="806" y="162"/>
+ <point x="609" y="162" type="curve" smooth="yes"/>
+ <point x="345" y="162" type="line"/>
+ <point x="472" y="671" type="line"/>
+ <point x="1042" y="671" type="line"/>
+ <point x="1081" y="828" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/input/font-psf-test/source/PsfTest-Italic.ufo/glyphs/L_tnC_apF_.glif b/tests/input/font-psf-test/source/PsfTest-Italic.ufo/glyphs/L_tnC_apF_.glif
new file mode 100644
index 0000000..cbc1726
--- /dev/null
+++ b/tests/input/font-psf-test/source/PsfTest-Italic.ufo/glyphs/L_tnC_apF_.glif
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnCapF" format="2">
+ <advance width="1130"/>
+ <unicode hex="0046"/>
+ <anchor x="510" y="-100" name="L"/>
+ <anchor x="917" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="508" y="818" type="line"/>
+ <point x="621" y="1269" type="line"/>
+ <point x="1286" y="1269" type="line"/>
+ <point x="1326" y="1431" type="line"/>
+ <point x="456" y="1431" type="line"/>
+ <point x="452" y="1352"/>
+ <point x="412" y="1193"/>
+ <point x="364" y="1000" type="curve" smooth="yes"/>
+ <point x="221" y="426" type="line" smooth="yes"/>
+ <point x="173" y="233"/>
+ <point x="134" y="78"/>
+ <point x="100" y="0" type="curve"/>
+ <point x="320" y="0" type="line"/>
+ <point x="323" y="76"/>
+ <point x="362" y="232"/>
+ <point x="411" y="426" type="curve" smooth="yes"/>
+ <point x="470" y="662" type="line"/>
+ <point x="1050" y="662" type="line"/>
+ <point x="1088" y="818" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/input/font-psf-test/source/PsfTest-Italic.ufo/glyphs/L_tnC_apG_.glif b/tests/input/font-psf-test/source/PsfTest-Italic.ufo/glyphs/L_tnC_apG_.glif
new file mode 100644
index 0000000..c39b75a
--- /dev/null
+++ b/tests/input/font-psf-test/source/PsfTest-Italic.ufo/glyphs/L_tnC_apG_.glif
@@ -0,0 +1,48 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnCapG" format="2">
+ <advance width="1406"/>
+ <unicode hex="0047"/>
+ <anchor x="685" y="0" name="H"/>
+ <anchor x="660" y="-100" name="L"/>
+ <anchor x="1067" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="1403" y="710" type="line"/>
+ <point x="863" y="710" type="line"/>
+ <point x="822" y="548" type="line"/>
+ <point x="1172" y="548" type="line"/>
+ <point x="1090" y="220" type="line"/>
+ <point x="1012" y="176"/>
+ <point x="858" y="147"/>
+ <point x="739" y="147" type="curve" smooth="yes"/>
+ <point x="520" y="147"/>
+ <point x="384" y="272"/>
+ <point x="384" y="493" type="curve" smooth="yes"/>
+ <point x="384" y="560"/>
+ <point x="394" y="636"/>
+ <point x="415" y="720" type="curve" smooth="yes"/>
+ <point x="500" y="1062"/>
+ <point x="747" y="1289"/>
+ <point x="1052" y="1289" type="curve" smooth="yes"/>
+ <point x="1195" y="1289"/>
+ <point x="1335" y="1233"/>
+ <point x="1425" y="1122" type="curve"/>
+ <point x="1534" y="1298" type="line"/>
+ <point x="1409" y="1405"/>
+ <point x="1235" y="1455"/>
+ <point x="1063" y="1455" type="curve" smooth="yes"/>
+ <point x="680" y="1455"/>
+ <point x="334" y="1195"/>
+ <point x="217" y="726" type="curve" smooth="yes"/>
+ <point x="195" y="639"/>
+ <point x="185" y="559"/>
+ <point x="185" y="486" type="curve" smooth="yes"/>
+ <point x="185" y="162"/>
+ <point x="406" y="-25"/>
+ <point x="714" y="-25" type="curve" smooth="yes"/>
+ <point x="907" y="-25"/>
+ <point x="1149" y="50"/>
+ <point x="1258" y="132" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/input/font-psf-test/source/PsfTest-Italic.ufo/glyphs/L_tnC_apH_.glif b/tests/input/font-psf-test/source/PsfTest-Italic.ufo/glyphs/L_tnC_apH_.glif
new file mode 100644
index 0000000..f454288
--- /dev/null
+++ b/tests/input/font-psf-test/source/PsfTest-Italic.ufo/glyphs/L_tnC_apH_.glif
@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnCapH" format="2">
+ <advance width="1455"/>
+ <unicode hex="0048"/>
+ <anchor x="225" y="0" name="H"/>
+ <anchor x="640" y="-100" name="L"/>
+ <anchor x="1047" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="1230" y="0" type="line"/>
+ <point x="1234" y="78"/>
+ <point x="1273" y="233"/>
+ <point x="1321" y="426" type="curve" smooth="yes"/>
+ <point x="1465" y="1005" type="line" smooth="yes"/>
+ <point x="1513" y="1198"/>
+ <point x="1552" y="1352"/>
+ <point x="1586" y="1431" type="curve"/>
+ <point x="1381" y="1431" type="line"/>
+ <point x="1228" y="818" type="line"/>
+ <point x="508" y="818" type="line"/>
+ <point x="661" y="1431" type="line"/>
+ <point x="456" y="1431" type="line"/>
+ <point x="452" y="1352"/>
+ <point x="413" y="1197"/>
+ <point x="365" y="1005" type="curve" smooth="yes"/>
+ <point x="221" y="426" type="line" smooth="yes"/>
+ <point x="173" y="233"/>
+ <point x="134" y="78"/>
+ <point x="100" y="0" type="curve"/>
+ <point x="305" y="0" type="line"/>
+ <point x="470" y="662" type="line"/>
+ <point x="1190" y="662" type="line"/>
+ <point x="1025" y="0" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/input/font-psf-test/source/PsfTest-Italic.ufo/glyphs/L_tnC_apI_.glif b/tests/input/font-psf-test/source/PsfTest-Italic.ufo/glyphs/L_tnC_apI_.glif
new file mode 100644
index 0000000..78b151c
--- /dev/null
+++ b/tests/input/font-psf-test/source/PsfTest-Italic.ufo/glyphs/L_tnC_apI_.glif
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnCapI" format="2">
+ <advance width="955"/>
+ <unicode hex="0049"/>
+ <anchor x="417" y="0" name="H"/>
+ <anchor x="392" y="-100" name="L"/>
+ <anchor x="613" y="0" name="O"/>
+ <anchor x="1215" y="1200" name="R"/>
+ <anchor x="799" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="436" y="1431" type="line"/>
+ <point x="401" y="1289" type="line"/>
+ <point x="641" y="1289" type="line"/>
+ <point x="355" y="142" type="line"/>
+ <point x="115" y="142" type="line"/>
+ <point x="80" y="0" type="line"/>
+ <point x="755" y="0" type="line"/>
+ <point x="790" y="142" type="line"/>
+ <point x="545" y="142" type="line"/>
+ <point x="831" y="1289" type="line"/>
+ <point x="1076" y="1289" type="line"/>
+ <point x="1111" y="1431" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/input/font-psf-test/source/PsfTest-Italic.ufo/glyphs/L_tnC_apJ_.glif b/tests/input/font-psf-test/source/PsfTest-Italic.ufo/glyphs/L_tnC_apJ_.glif
new file mode 100644
index 0000000..417d1f8
--- /dev/null
+++ b/tests/input/font-psf-test/source/PsfTest-Italic.ufo/glyphs/L_tnC_apJ_.glif
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnCapJ" format="2">
+ <advance width="996"/>
+ <unicode hex="004A"/>
+ <anchor x="325" y="-100" name="L"/>
+ <anchor x="997" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="871" y="1431" type="line"/>
+ <point x="858" y="1327"/>
+ <point x="817" y="1151"/>
+ <point x="769" y="960" type="curve" smooth="yes"/>
+ <point x="648" y="475" type="line" smooth="yes"/>
+ <point x="592" y="251"/>
+ <point x="484" y="152"/>
+ <point x="337" y="152" type="curve" smooth="yes"/>
+ <point x="245" y="152"/>
+ <point x="145" y="224"/>
+ <point x="97" y="299" type="curve"/>
+ <point x="6" y="118" type="line"/>
+ <point x="58" y="39"/>
+ <point x="193" y="-25"/>
+ <point x="298" y="-25" type="curve" smooth="yes"/>
+ <point x="555" y="-25"/>
+ <point x="749" y="117"/>
+ <point x="850" y="524" type="curve" smooth="yes"/>
+ <point x="1076" y="1431" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/input/font-psf-test/source/PsfTest-Italic.ufo/glyphs/L_tnC_apK_.glif b/tests/input/font-psf-test/source/PsfTest-Italic.ufo/glyphs/L_tnC_apK_.glif
new file mode 100644
index 0000000..8e54a6d
--- /dev/null
+++ b/tests/input/font-psf-test/source/PsfTest-Italic.ufo/glyphs/L_tnC_apK_.glif
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnCapK" format="2">
+ <advance width="1261"/>
+ <unicode hex="004B"/>
+ <anchor x="210" y="0" name="H"/>
+ <anchor x="610" y="-100" name="L"/>
+ <anchor x="972" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="1221" y="1431" type="line"/>
+ <point x="406" y="689" type="line"/>
+ <point x="547" y="730" type="line"/>
+ <point x="660" y="725" type="line"/>
+ <point x="1461" y="1431" type="line"/>
+ </contour>
+ <contour>
+ <point x="1170" y="0" type="line"/>
+ <point x="615" y="823" type="line"/>
+ <point x="469" y="720" type="line"/>
+ <point x="925" y="0" type="line"/>
+ </contour>
+ <contour>
+ <point x="661" y="1431" type="line"/>
+ <point x="456" y="1431" type="line"/>
+ <point x="452" y="1352"/>
+ <point x="413" y="1197"/>
+ <point x="365" y="1005" type="curve" smooth="yes"/>
+ <point x="221" y="426" type="line" smooth="yes"/>
+ <point x="173" y="233"/>
+ <point x="134" y="78"/>
+ <point x="100" y="0" type="curve"/>
+ <point x="305" y="0" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/input/font-psf-test/source/PsfTest-Italic.ufo/glyphs/L_tnC_apL_.glif b/tests/input/font-psf-test/source/PsfTest-Italic.ufo/glyphs/L_tnC_apL_.glif
new file mode 100644
index 0000000..d2eb932
--- /dev/null
+++ b/tests/input/font-psf-test/source/PsfTest-Italic.ufo/glyphs/L_tnC_apL_.glif
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnCapL" format="2">
+ <advance width="1060"/>
+ <unicode hex="004C"/>
+ <anchor x="532" y="0" name="H"/>
+ <anchor x="507" y="-100" name="L"/>
+ <anchor x="780" y="1200" name="R"/>
+ <anchor x="914" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="345" y="162" type="line"/>
+ <point x="661" y="1431" type="line"/>
+ <point x="456" y="1431" type="line"/>
+ <point x="452" y="1352"/>
+ <point x="413" y="1197"/>
+ <point x="365" y="1005" type="curve" smooth="yes"/>
+ <point x="221" y="426" type="line" smooth="yes"/>
+ <point x="173" y="233"/>
+ <point x="134" y="78"/>
+ <point x="100" y="0" type="curve"/>
+ <point x="965" y="0" type="line"/>
+ <point x="1008" y="176" type="line"/>
+ <point x="925" y="163"/>
+ <point x="766" y="162"/>
+ <point x="569" y="162" type="curve" smooth="yes"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/input/font-psf-test/source/PsfTest-Italic.ufo/glyphs/L_tnC_apM_.glif b/tests/input/font-psf-test/source/PsfTest-Italic.ufo/glyphs/L_tnC_apM_.glif
new file mode 100644
index 0000000..7c3c824
--- /dev/null
+++ b/tests/input/font-psf-test/source/PsfTest-Italic.ufo/glyphs/L_tnC_apM_.glif
@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnCapM" format="2">
+ <advance width="1785"/>
+ <unicode hex="004D"/>
+ <anchor x="800" y="-100" name="L"/>
+ <anchor x="1207" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="880" y="201" type="line"/>
+ <point x="751" y="1431" type="line"/>
+ <point x="591" y="1431" type="line"/>
+ <point x="740" y="0" type="line"/>
+ <point x="935" y="0" type="line"/>
+ <point x="1793" y="1431" type="line"/>
+ <point x="1616" y="1431" type="line"/>
+ </contour>
+ <contour>
+ <point x="536" y="1431" type="line"/>
+ <point x="536" y="1431"/>
+ <point x="184" y="194"/>
+ <point x="110" y="0" type="curve"/>
+ <point x="295" y="0" type="line"/>
+ <point x="621" y="1181" type="line"/>
+ <point x="711" y="1431" type="line"/>
+ </contour>
+ <contour>
+ <point x="1560" y="0" type="line"/>
+ <point x="1579" y="194"/>
+ <point x="1846" y="1431"/>
+ <point x="1846" y="1431" type="curve"/>
+ <point x="1671" y="1431" type="line"/>
+ <point x="1641" y="1181" type="line"/>
+ <point x="1375" y="0" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/input/font-psf-test/source/PsfTest-Italic.ufo/glyphs/L_tnC_apN_.glif b/tests/input/font-psf-test/source/PsfTest-Italic.ufo/glyphs/L_tnC_apN_.glif
new file mode 100644
index 0000000..7306669
--- /dev/null
+++ b/tests/input/font-psf-test/source/PsfTest-Italic.ufo/glyphs/L_tnC_apN_.glif
@@ -0,0 +1,37 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnCapN" format="2">
+ <advance width="1480"/>
+ <unicode hex="004E"/>
+ <anchor x="1170" y="0" name="H"/>
+ <anchor x="652" y="-100" name="L"/>
+ <anchor x="1059" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="491" y="1328" type="line"/>
+ <point x="1075" y="0" type="line"/>
+ <point x="1219" y="98" type="line"/>
+ <point x="636" y="1431" type="line"/>
+ </contour>
+ <contour>
+ <point x="1075" y="0" type="line"/>
+ <point x="1250" y="0" type="line"/>
+ <point x="1500" y="1005" type="line" smooth="yes"/>
+ <point x="1548" y="1198"/>
+ <point x="1588" y="1352"/>
+ <point x="1621" y="1431" type="curve"/>
+ <point x="1431" y="1431" type="line"/>
+ </contour>
+ <contour>
+ <point x="636" y="1431" type="line"/>
+ <point x="446" y="1431" type="line"/>
+ <point x="442" y="1352"/>
+ <point x="403" y="1197"/>
+ <point x="355" y="1005" type="curve" smooth="yes"/>
+ <point x="211" y="426" type="line" smooth="yes"/>
+ <point x="163" y="233"/>
+ <point x="124" y="78"/>
+ <point x="90" y="0" type="curve"/>
+ <point x="280" y="0" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/input/font-psf-test/source/PsfTest-Italic.ufo/glyphs/L_tnC_apO_.glif b/tests/input/font-psf-test/source/PsfTest-Italic.ufo/glyphs/L_tnC_apO_.glif
new file mode 100644
index 0000000..19c4886
--- /dev/null
+++ b/tests/input/font-psf-test/source/PsfTest-Italic.ufo/glyphs/L_tnC_apO_.glif
@@ -0,0 +1,40 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnCapO" format="2">
+ <advance width="1447"/>
+ <unicode hex="004F"/>
+ <anchor x="657" y="0" name="H"/>
+ <anchor x="632" y="-100" name="L"/>
+ <anchor x="896" y="0" name="O"/>
+ <anchor x="1700" y="1200" name="R"/>
+ <anchor x="1039" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="719" y="147" type="curve" smooth="yes"/>
+ <point x="514" y="147"/>
+ <point x="386" y="300"/>
+ <point x="386" y="541" type="curve" smooth="yes"/>
+ <point x="386" y="871"/>
+ <point x="606" y="1284"/>
+ <point x="963" y="1284" type="curve" smooth="yes"/>
+ <point x="1164" y="1284"/>
+ <point x="1291" y="1133"/>
+ <point x="1291" y="892" type="curve" smooth="yes"/>
+ <point x="1291" y="563"/>
+ <point x="1077" y="147"/>
+ </contour>
+ <contour>
+ <point x="1492" y="931" type="curve" smooth="yes"/>
+ <point x="1492" y="1263"/>
+ <point x="1278" y="1455"/>
+ <point x="1015" y="1455" type="curve" smooth="yes"/>
+ <point x="599" y="1455"/>
+ <point x="185" y="1036"/>
+ <point x="185" y="500" type="curve" smooth="yes"/>
+ <point x="185" y="167"/>
+ <point x="400" y="-25"/>
+ <point x="666" y="-25" type="curve" smooth="yes"/>
+ <point x="1078" y="-25"/>
+ <point x="1492" y="395"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/input/font-psf-test/source/PsfTest-Italic.ufo/glyphs/L_tnC_apP_.glif b/tests/input/font-psf-test/source/PsfTest-Italic.ufo/glyphs/L_tnC_apP_.glif
new file mode 100644
index 0000000..5b51a57
--- /dev/null
+++ b/tests/input/font-psf-test/source/PsfTest-Italic.ufo/glyphs/L_tnC_apP_.glif
@@ -0,0 +1,50 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnCapP" format="2">
+ <advance width="1190"/>
+ <unicode hex="0050"/>
+ <anchor x="552" y="-100" name="L"/>
+ <anchor x="959" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="443" y="554" type="line"/>
+ <point x="506" y="547"/>
+ <point x="597" y="544"/>
+ <point x="670" y="544" type="curve" smooth="yes"/>
+ <point x="1058" y="544"/>
+ <point x="1321" y="733"/>
+ <point x="1321" y="1084" type="curve" smooth="yes"/>
+ <point x="1321" y="1302"/>
+ <point x="1141" y="1441"/>
+ <point x="864" y="1441" type="curve" smooth="yes"/>
+ <point x="651" y="1441"/>
+ <point x="456" y="1431"/>
+ <point x="456" y="1431" type="curve"/>
+ <point x="452" y="1352"/>
+ <point x="407" y="1172"/>
+ <point x="359" y="980" type="curve"/>
+ <point x="221" y="426" type="line" smooth="yes"/>
+ <point x="173" y="233"/>
+ <point x="134" y="78"/>
+ <point x="100" y="0" type="curve"/>
+ <point x="320" y="0" type="line"/>
+ <point x="324" y="76"/>
+ <point x="362" y="232"/>
+ <point x="411" y="426" type="curve" smooth="yes"/>
+ </contour>
+ <contour>
+ <point x="623" y="1279" type="line"/>
+ <point x="692" y="1282"/>
+ <point x="721" y="1284"/>
+ <point x="815" y="1284" type="curve" smooth="yes"/>
+ <point x="1036" y="1284"/>
+ <point x="1121" y="1172"/>
+ <point x="1121" y="1048" type="curve" smooth="yes"/>
+ <point x="1121" y="845"/>
+ <point x="968" y="696"/>
+ <point x="693" y="696" type="curve" smooth="yes"/>
+ <point x="618" y="696"/>
+ <point x="542" y="698"/>
+ <point x="481" y="706" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/input/font-psf-test/source/PsfTest-Italic.ufo/glyphs/L_tnC_apQ_.glif b/tests/input/font-psf-test/source/PsfTest-Italic.ufo/glyphs/L_tnC_apQ_.glif
new file mode 100644
index 0000000..3dcbc8d
--- /dev/null
+++ b/tests/input/font-psf-test/source/PsfTest-Italic.ufo/glyphs/L_tnC_apQ_.glif
@@ -0,0 +1,52 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnCapQ" format="2">
+ <advance width="1459"/>
+ <unicode hex="0051"/>
+ <anchor x="589" y="-270" name="L"/>
+ <anchor x="1039" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="1495" y="939" type="curve" smooth="yes"/>
+ <point x="1495" y="1266"/>
+ <point x="1306" y="1455"/>
+ <point x="1026" y="1455" type="curve" smooth="yes"/>
+ <point x="703" y="1455"/>
+ <point x="332" y="1195"/>
+ <point x="215" y="726" type="curve" smooth="yes"/>
+ <point x="194" y="642"/>
+ <point x="185" y="564"/>
+ <point x="185" y="492" type="curve" smooth="yes"/>
+ <point x="185" y="165"/>
+ <point x="388" y="-25"/>
+ <point x="652" y="-25" type="curve" smooth="yes"/>
+ <point x="714" y="-25"/>
+ <point x="781" y="-17"/>
+ <point x="829" y="0" type="curve"/>
+ <point x="898" y="0"/>
+ <point x="1133" y="-186"/>
+ <point x="1217" y="-186" type="curve" smooth="yes"/>
+ <point x="1271" y="-186"/>
+ <point x="1355" y="-79"/>
+ <point x="1388" y="-44" type="curve"/>
+ <point x="1258" y="-27"/>
+ <point x="1155" y="27"/>
+ <point x="1049" y="103" type="curve"/>
+ <point x="1253" y="217"/>
+ <point x="1495" y="528"/>
+ </contour>
+ <contour>
+ <point x="690" y="147" type="curve" smooth="yes"/>
+ <point x="492" y="147"/>
+ <point x="384" y="284"/>
+ <point x="384" y="508" type="curve" smooth="yes"/>
+ <point x="384" y="856"/>
+ <point x="609" y="1284"/>
+ <point x="994" y="1284" type="curve" smooth="yes"/>
+ <point x="1188" y="1284"/>
+ <point x="1295" y="1149"/>
+ <point x="1295" y="925" type="curve" smooth="yes"/>
+ <point x="1295" y="490"/>
+ <point x="985" y="147"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/input/font-psf-test/source/PsfTest-Italic.ufo/glyphs/L_tnC_apR_.glif b/tests/input/font-psf-test/source/PsfTest-Italic.ufo/glyphs/L_tnC_apR_.glif
new file mode 100644
index 0000000..c8f8186
--- /dev/null
+++ b/tests/input/font-psf-test/source/PsfTest-Italic.ufo/glyphs/L_tnC_apR_.glif
@@ -0,0 +1,55 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnCapR" format="2">
+ <advance width="1295"/>
+ <unicode hex="0052"/>
+ <anchor x="590" y="0" name="H"/>
+ <anchor x="525" y="-100" name="L"/>
+ <anchor x="932" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="457" y="613" type="line"/>
+ <point x="712" y="613" type="line" smooth="yes"/>
+ <point x="1010" y="613"/>
+ <point x="1303" y="784"/>
+ <point x="1303" y="1114" type="curve" smooth="yes"/>
+ <point x="1303" y="1326"/>
+ <point x="1114" y="1441"/>
+ <point x="844" y="1441" type="curve" smooth="yes"/>
+ <point x="610" y="1441"/>
+ <point x="456" y="1431"/>
+ <point x="456" y="1431" type="curve"/>
+ <point x="452" y="1352"/>
+ <point x="407" y="1172"/>
+ <point x="359" y="980" type="curve" smooth="yes"/>
+ <point x="221" y="426" type="line"/>
+ <point x="173" y="233"/>
+ <point x="134" y="78"/>
+ <point x="100" y="0" type="curve"/>
+ <point x="320" y="0" type="line"/>
+ <point x="324" y="76"/>
+ <point x="363" y="233"/>
+ <point x="411" y="426" type="curve"/>
+ </contour>
+ <contour>
+ <point x="623" y="1279" type="line"/>
+ <point x="677" y="1281"/>
+ <point x="725" y="1284"/>
+ <point x="795" y="1284" type="curve" smooth="yes"/>
+ <point x="1003" y="1284"/>
+ <point x="1104" y="1203"/>
+ <point x="1104" y="1076" type="curve" smooth="yes"/>
+ <point x="1104" y="856"/>
+ <point x="921" y="764"/>
+ <point x="685" y="764" type="curve" smooth="yes"/>
+ <point x="495" y="764" type="line"/>
+ </contour>
+ <contour>
+ <point x="656" y="622" type="line"/>
+ <point x="930" y="0" type="line"/>
+ <point x="1185" y="0" type="line"/>
+ <point x="1122" y="89"/>
+ <point x="864" y="602"/>
+ <point x="828" y="676" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/input/font-psf-test/source/PsfTest-Italic.ufo/glyphs/L_tnC_apS_.glif b/tests/input/font-psf-test/source/PsfTest-Italic.ufo/glyphs/L_tnC_apS_.glif
new file mode 100644
index 0000000..01e9f47
--- /dev/null
+++ b/tests/input/font-psf-test/source/PsfTest-Italic.ufo/glyphs/L_tnC_apS_.glif
@@ -0,0 +1,50 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnCapS" format="2">
+ <advance width="1155"/>
+ <unicode hex="0053"/>
+ <anchor x="520" y="0" name="H"/>
+ <anchor x="495" y="-100" name="L"/>
+ <anchor x="902" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="1260" y="1347" type="line"/>
+ <point x="1146" y="1419"/>
+ <point x="1021" y="1455"/>
+ <point x="867" y="1455" type="curve" smooth="yes"/>
+ <point x="549" y="1455"/>
+ <point x="320" y="1303"/>
+ <point x="320" y="1040" type="curve" smooth="yes"/>
+ <point x="320" y="901"/>
+ <point x="438" y="794"/>
+ <point x="622" y="691" type="curve" smooth="yes"/>
+ <point x="877" y="549"/>
+ <point x="914" y="461"/>
+ <point x="914" y="378" type="curve" smooth="yes"/>
+ <point x="914" y="256"/>
+ <point x="792" y="147"/>
+ <point x="621" y="147" type="curve" smooth="yes"/>
+ <point x="473" y="147"/>
+ <point x="278" y="235"/>
+ <point x="161" y="378" type="curve"/>
+ <point x="65" y="187" type="line"/>
+ <point x="178" y="73"/>
+ <point x="365" y="-25"/>
+ <point x="558" y="-25" type="curve" smooth="yes"/>
+ <point x="852" y="-25"/>
+ <point x="1114" y="115"/>
+ <point x="1114" y="414" type="curve" smooth="yes"/>
+ <point x="1114" y="526"/>
+ <point x="1057" y="679"/>
+ <point x="800" y="828" type="curve" smooth="yes"/>
+ <point x="597" y="946"/>
+ <point x="510" y="1005"/>
+ <point x="510" y="1079" type="curve" smooth="yes"/>
+ <point x="510" y="1210"/>
+ <point x="659" y="1284"/>
+ <point x="845" y="1284" type="curve" smooth="yes"/>
+ <point x="959" y="1284"/>
+ <point x="1075" y="1240"/>
+ <point x="1173" y="1156" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/input/font-psf-test/source/PsfTest-Italic.ufo/glyphs/L_tnC_apT_.glif b/tests/input/font-psf-test/source/PsfTest-Italic.ufo/glyphs/L_tnC_apT_.glif
new file mode 100644
index 0000000..0eeece4
--- /dev/null
+++ b/tests/input/font-psf-test/source/PsfTest-Italic.ufo/glyphs/L_tnC_apT_.glif
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnCapT" format="2">
+ <advance width="1245"/>
+ <unicode hex="0054"/>
+ <anchor x="562" y="0" name="H"/>
+ <anchor x="562" y="-100" name="L"/>
+ <anchor x="944" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="341" y="1431" type="line"/>
+ <point x="296" y="1250" type="line"/>
+ <point x="380" y="1266"/>
+ <point x="457" y="1269"/>
+ <point x="546" y="1269" type="curve" smooth="yes"/>
+ <point x="781" y="1269" type="line"/>
+ <point x="571" y="426" type="line" smooth="yes"/>
+ <point x="523" y="233"/>
+ <point x="481" y="78"/>
+ <point x="445" y="0" type="curve"/>
+ <point x="675" y="0" type="line"/>
+ <point x="677" y="78"/>
+ <point x="713" y="233"/>
+ <point x="761" y="426" type="curve" smooth="yes"/>
+ <point x="971" y="1269" type="line"/>
+ <point x="1211" y="1269" type="line" smooth="yes"/>
+ <point x="1301" y="1269"/>
+ <point x="1375" y="1266"/>
+ <point x="1451" y="1250" type="curve"/>
+ <point x="1496" y="1431" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/input/font-psf-test/source/PsfTest-Italic.ufo/glyphs/L_tnC_apU_.glif b/tests/input/font-psf-test/source/PsfTest-Italic.ufo/glyphs/L_tnC_apU_.glif
new file mode 100644
index 0000000..9576e20
--- /dev/null
+++ b/tests/input/font-psf-test/source/PsfTest-Italic.ufo/glyphs/L_tnC_apU_.glif
@@ -0,0 +1,44 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnCapU" format="2">
+ <advance width="1420"/>
+ <unicode hex="0055"/>
+ <anchor x="647" y="0" name="H"/>
+ <anchor x="622" y="-100" name="L"/>
+ <anchor x="865" y="0" name="O"/>
+ <anchor x="1640" y="1200" name="R"/>
+ <anchor x="1029" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="1346" y="1431" type="line"/>
+ <point x="1126" y="549" type="line" smooth="yes"/>
+ <point x="1055" y="264"/>
+ <point x="916" y="132"/>
+ <point x="682" y="132" type="curve" smooth="yes"/>
+ <point x="485" y="132"/>
+ <point x="421" y="244"/>
+ <point x="421" y="391" type="curve" smooth="yes"/>
+ <point x="421" y="451"/>
+ <point x="431" y="516"/>
+ <point x="448" y="582" type="curve" smooth="yes"/>
+ <point x="661" y="1431" type="line"/>
+ <point x="456" y="1431" type="line"/>
+ <point x="451" y="1352"/>
+ <point x="414" y="1198"/>
+ <point x="365" y="1005" type="curve" smooth="yes"/>
+ <point x="251" y="552" type="line" smooth="yes"/>
+ <point x="236" y="493"/>
+ <point x="228" y="435"/>
+ <point x="228" y="379" type="curve" smooth="yes"/>
+ <point x="228" y="157"/>
+ <point x="351" y="-25"/>
+ <point x="643" y="-25" type="curve" smooth="yes"/>
+ <point x="1020" y="-25"/>
+ <point x="1223" y="177"/>
+ <point x="1299" y="480" type="curve" smooth="yes"/>
+ <point x="1430" y="1005" type="line" smooth="yes"/>
+ <point x="1480" y="1207"/>
+ <point x="1519" y="1352"/>
+ <point x="1551" y="1431" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/input/font-psf-test/source/PsfTest-Italic.ufo/glyphs/L_tnC_apV_.glif b/tests/input/font-psf-test/source/PsfTest-Italic.ufo/glyphs/L_tnC_apV_.glif
new file mode 100644
index 0000000..2bf8b96
--- /dev/null
+++ b/tests/input/font-psf-test/source/PsfTest-Italic.ufo/glyphs/L_tnC_apV_.glif
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnCapV" format="2">
+ <advance width="1345"/>
+ <unicode hex="0056"/>
+ <anchor x="620" y="0" name="H"/>
+ <anchor x="587" y="-100" name="L"/>
+ <anchor x="820" y="0" name="O"/>
+ <anchor x="994" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="1381" y="1431" type="line"/>
+ <point x="654" y="191" type="line"/>
+ <point x="536" y="1431" type="line"/>
+ <point x="331" y="1431" type="line"/>
+ <point x="344" y="1350"/>
+ <point x="355" y="1262"/>
+ <point x="377" y="1073" type="curve" smooth="yes"/>
+ <point x="500" y="0" type="line"/>
+ <point x="725" y="0" type="line"/>
+ <point x="1377" y="1073" type="line" smooth="yes"/>
+ <point x="1492" y="1263"/>
+ <point x="1550" y="1350"/>
+ <point x="1606" y="1431" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/input/font-psf-test/source/PsfTest-Italic.ufo/glyphs/L_tnC_apW_.glif b/tests/input/font-psf-test/source/PsfTest-Italic.ufo/glyphs/L_tnC_apW_.glif
new file mode 100644
index 0000000..553ea17
--- /dev/null
+++ b/tests/input/font-psf-test/source/PsfTest-Italic.ufo/glyphs/L_tnC_apW_.glif
@@ -0,0 +1,44 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnCapW" format="2">
+ <advance width="2060"/>
+ <unicode hex="0057"/>
+ <anchor x="942" y="-100" name="L"/>
+ <anchor x="1349" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="1535" y="0" type="line"/>
+ <point x="2107" y="1073" type="line" smooth="yes"/>
+ <point x="2208" y="1263"/>
+ <point x="2259" y="1350"/>
+ <point x="2311" y="1431" type="curve"/>
+ <point x="2081" y="1431" type="line"/>
+ <point x="1431" y="127" type="line"/>
+ <point x="1420" y="0" type="line"/>
+ </contour>
+ <contour>
+ <point x="1310" y="0" type="line"/>
+ <point x="1420" y="0" type="line"/>
+ <point x="1461" y="127" type="line"/>
+ <point x="1406" y="1431" type="line"/>
+ <point x="1231" y="1431" type="line"/>
+ <point x="1248" y="1279" type="line"/>
+ </contour>
+ <contour>
+ <point x="625" y="0" type="line"/>
+ <point x="1406" y="1431" type="line"/>
+ <point x="1221" y="1431" type="line"/>
+ <point x="521" y="127" type="line"/>
+ <point x="521" y="0" type="line"/>
+ </contour>
+ <contour>
+ <point x="546" y="1431" type="line"/>
+ <point x="336" y="1431" type="line"/>
+ <point x="348" y="1353"/>
+ <point x="355" y="1260"/>
+ <point x="362" y="1073" type="curve" smooth="yes"/>
+ <point x="400" y="0" type="line"/>
+ <point x="521" y="0" type="line"/>
+ <point x="551" y="127" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/input/font-psf-test/source/PsfTest-Italic.ufo/glyphs/L_tnC_apX_.glif b/tests/input/font-psf-test/source/PsfTest-Italic.ufo/glyphs/L_tnC_apX_.glif
new file mode 100644
index 0000000..2da5787
--- /dev/null
+++ b/tests/input/font-psf-test/source/PsfTest-Italic.ufo/glyphs/L_tnC_apX_.glif
@@ -0,0 +1,39 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnCapX" format="2">
+ <advance width="1305"/>
+ <unicode hex="0058"/>
+ <anchor x="565" y="-100" name="L"/>
+ <anchor x="972" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="970" y="0" type="line"/>
+ <point x="1190" y="0" type="line"/>
+ <point x="1148" y="80"/>
+ <point x="1125" y="124"/>
+ <point x="1045" y="329" type="curve" smooth="yes"/>
+ <point x="611" y="1431" type="line"/>
+ <point x="386" y="1431" type="line"/>
+ <point x="430" y="1348"/>
+ <point x="462" y="1289"/>
+ <point x="541" y="1088" type="curve" smooth="yes"/>
+ </contour>
+ <contour>
+ <point x="752" y="872" type="line"/>
+ <point x="278" y="333" type="line" smooth="yes"/>
+ <point x="98" y="129"/>
+ <point x="53" y="84"/>
+ <point x="-30" y="0" type="curve"/>
+ <point x="210" y="0" type="line"/>
+ <point x="750" y="622" type="line"/>
+ </contour>
+ <contour>
+ <point x="765" y="622" type="line"/>
+ <point x="1183" y="1088" type="line" smooth="yes"/>
+ <point x="1360" y="1285"/>
+ <point x="1425" y="1355"/>
+ <point x="1506" y="1431" type="curve"/>
+ <point x="1261" y="1431" type="line"/>
+ <point x="767" y="872" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/input/font-psf-test/source/PsfTest-Italic.ufo/glyphs/L_tnC_apY_.glif b/tests/input/font-psf-test/source/PsfTest-Italic.ufo/glyphs/L_tnC_apY_.glif
new file mode 100644
index 0000000..9ec65ef
--- /dev/null
+++ b/tests/input/font-psf-test/source/PsfTest-Italic.ufo/glyphs/L_tnC_apY_.glif
@@ -0,0 +1,39 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnCapY" format="2">
+ <advance width="1300"/>
+ <unicode hex="0059"/>
+ <anchor x="565" y="-100" name="L"/>
+ <anchor x="972" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="331" y="1431" type="line"/>
+ <point x="407" y="1285"/>
+ <point x="446" y="1173"/>
+ <point x="490" y="1044" type="curve"/>
+ <point x="661" y="549" type="line"/>
+ <point x="829" y="661" type="line"/>
+ <point x="551" y="1431" type="line"/>
+ </contour>
+ <contour>
+ <point x="1321" y="1431" type="line"/>
+ <point x="684" y="661" type="line"/>
+ <point x="796" y="549" type="line"/>
+ <point x="1215" y="1044" type="line" smooth="yes"/>
+ <point x="1322" y="1171"/>
+ <point x="1402" y="1265"/>
+ <point x="1561" y="1431" type="curve"/>
+ </contour>
+ <contour>
+ <point x="700" y="0" type="line"/>
+ <point x="704" y="78"/>
+ <point x="743" y="233"/>
+ <point x="791" y="426" type="curve" smooth="yes"/>
+ <point x="854" y="681" type="line"/>
+ <point x="664" y="681" type="line"/>
+ <point x="601" y="426" type="line" smooth="yes"/>
+ <point x="553" y="233"/>
+ <point x="514" y="78"/>
+ <point x="480" y="0" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/input/font-psf-test/source/PsfTest-Italic.ufo/glyphs/L_tnS_mA_.glif b/tests/input/font-psf-test/source/PsfTest-Italic.ufo/glyphs/L_tnS_mA_.glif
new file mode 100644
index 0000000..586e494
--- /dev/null
+++ b/tests/input/font-psf-test/source/PsfTest-Italic.ufo/glyphs/L_tnS_mA_.glif
@@ -0,0 +1,77 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmA" format="2">
+ <advance width="1107"/>
+ <unicode hex="0061"/>
+ <anchor x="860" y="0" name="H"/>
+ <anchor x="455" y="-100" name="L"/>
+ <anchor x="1065" y="0" name="O"/>
+ <anchor x="1310" y="1000" name="R"/>
+ <anchor x="755" y="1100" name="U"/>
+ <outline>
+ <contour>
+ <point x="972" y="0" type="line"/>
+ <point x="965" y="48"/>
+ <point x="960" y="98"/>
+ <point x="960" y="149" type="curve" smooth="yes"/>
+ <point x="960" y="214"/>
+ <point x="967" y="284"/>
+ <point x="987" y="363" type="curve"/>
+ <point x="1077" y="726" type="line"/>
+ <point x="1081" y="744"/>
+ <point x="1084" y="762"/>
+ <point x="1084" y="779" type="curve" smooth="yes"/>
+ <point x="1084" y="912"/>
+ <point x="955" y="1019"/>
+ <point x="751" y="1019" type="curve" smooth="yes"/>
+ <point x="599" y="1019"/>
+ <point x="502" y="974"/>
+ <point x="389" y="931" type="curve"/>
+ <point x="373" y="889"/>
+ <point x="343" y="783"/>
+ <point x="331" y="740" type="curve"/>
+ <point x="468" y="820"/>
+ <point x="560" y="862"/>
+ <point x="666" y="862" type="curve" smooth="yes"/>
+ <point x="798" y="862"/>
+ <point x="885" y="810"/>
+ <point x="885" y="718" type="curve" smooth="yes"/>
+ <point x="885" y="705"/>
+ <point x="884" y="691"/>
+ <point x="880" y="677" type="curve" smooth="yes"/>
+ <point x="867" y="622" type="line"/>
+ <point x="825" y="619"/>
+ <point x="661" y="605"/>
+ <point x="591" y="598" type="curve" smooth="yes"/>
+ <point x="282" y="568"/>
+ <point x="102" y="415"/>
+ <point x="102" y="233" type="curve" smooth="yes"/>
+ <point x="102" y="103"/>
+ <point x="223" y="-25"/>
+ <point x="390" y="-25" type="curve" smooth="yes"/>
+ <point x="514" y="-25"/>
+ <point x="674" y="47"/>
+ <point x="779" y="152" type="curve"/>
+ <point x="779" y="89"/>
+ <point x="787" y="31"/>
+ <point x="792" y="0" type="curve"/>
+ </contour>
+ <contour>
+ <point x="791" y="319" type="line"/>
+ <point x="674" y="191"/>
+ <point x="553" y="137"/>
+ <point x="451" y="137" type="curve" smooth="yes"/>
+ <point x="355" y="137"/>
+ <point x="290" y="192"/>
+ <point x="290" y="264" type="curve" smooth="yes"/>
+ <point x="290" y="274"/>
+ <point x="291" y="285"/>
+ <point x="294" y="296" type="curve" smooth="yes"/>
+ <point x="315" y="380"/>
+ <point x="432" y="450"/>
+ <point x="566" y="461" type="curve" smooth="yes"/>
+ <point x="631" y="466"/>
+ <point x="782" y="483"/>
+ <point x="832" y="485" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/input/font-psf-test/source/PsfTest-Italic.ufo/glyphs/L_tnS_mA_A_cute.glif b/tests/input/font-psf-test/source/PsfTest-Italic.ufo/glyphs/L_tnS_mA_A_cute.glif
new file mode 100644
index 0000000..198d6db
--- /dev/null
+++ b/tests/input/font-psf-test/source/PsfTest-Italic.ufo/glyphs/L_tnS_mA_A_cute.glif
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmAAcute" format="2">
+ <advance width="1107"/>
+ <unicode hex="00E1"/>
+ <anchor x="860" y="0" name="H"/>
+ <anchor x="455" y="-100" name="L"/>
+ <anchor x="1065" y="0" name="O"/>
+ <anchor x="1310" y="1000" name="R"/>
+ <anchor x="889" y="1635" name="U"/>
+ <outline>
+ <component base="LtnSmA"/>
+ <component base="CombAcute" xOffset="1110"/>
+ </outline>
+</glyph>
diff --git a/tests/input/font-psf-test/source/PsfTest-Italic.ufo/glyphs/L_tnS_mA_C_ircum.glif b/tests/input/font-psf-test/source/PsfTest-Italic.ufo/glyphs/L_tnS_mA_C_ircum.glif
new file mode 100644
index 0000000..f5cfb16
--- /dev/null
+++ b/tests/input/font-psf-test/source/PsfTest-Italic.ufo/glyphs/L_tnS_mA_C_ircum.glif
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmACircum" format="2">
+ <advance width="1107"/>
+ <unicode hex="00E2"/>
+ <anchor x="860" y="0" name="H"/>
+ <anchor x="455" y="-100" name="L"/>
+ <anchor x="1065" y="0" name="O"/>
+ <anchor x="1310" y="1000" name="R"/>
+ <anchor x="854" y="1635" name="U"/>
+ <outline>
+ <component base="LtnSmA"/>
+ <component base="CombCircum" xOffset="1075"/>
+ </outline>
+</glyph>
diff --git a/tests/input/font-psf-test/source/PsfTest-Italic.ufo/glyphs/L_tnS_mA_D_iaer.glif b/tests/input/font-psf-test/source/PsfTest-Italic.ufo/glyphs/L_tnS_mA_D_iaer.glif
new file mode 100644
index 0000000..6f05301
--- /dev/null
+++ b/tests/input/font-psf-test/source/PsfTest-Italic.ufo/glyphs/L_tnS_mA_D_iaer.glif
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmADiaer" format="2">
+ <advance width="1107"/>
+ <unicode hex="00E4"/>
+ <anchor x="860" y="0" name="H"/>
+ <anchor x="455" y="-100" name="L"/>
+ <anchor x="1065" y="0" name="O"/>
+ <anchor x="1310" y="1000" name="R"/>
+ <anchor x="852" y="1505" name="U"/>
+ <outline>
+ <component base="LtnSmA"/>
+ <component base="CombDiaer" xOffset="1105"/>
+ </outline>
+</glyph>
diff --git a/tests/input/font-psf-test/source/PsfTest-Italic.ufo/glyphs/L_tnS_mA_G_rave.glif b/tests/input/font-psf-test/source/PsfTest-Italic.ufo/glyphs/L_tnS_mA_G_rave.glif
new file mode 100644
index 0000000..9048920
--- /dev/null
+++ b/tests/input/font-psf-test/source/PsfTest-Italic.ufo/glyphs/L_tnS_mA_G_rave.glif
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmAGrave" format="2">
+ <advance width="1107"/>
+ <unicode hex="00E0"/>
+ <anchor x="860" y="0" name="H"/>
+ <anchor x="455" y="-100" name="L"/>
+ <anchor x="1065" y="0" name="O"/>
+ <anchor x="1310" y="1000" name="R"/>
+ <anchor x="889" y="1635" name="U"/>
+ <outline>
+ <component base="LtnSmA"/>
+ <component base="CombGrave" xOffset="1090"/>
+ </outline>
+</glyph>
diff --git a/tests/input/font-psf-test/source/PsfTest-Italic.ufo/glyphs/L_tnS_mA_R_ingA_bv.glif b/tests/input/font-psf-test/source/PsfTest-Italic.ufo/glyphs/L_tnS_mA_R_ingA_bv.glif
new file mode 100644
index 0000000..8ada58f
--- /dev/null
+++ b/tests/input/font-psf-test/source/PsfTest-Italic.ufo/glyphs/L_tnS_mA_R_ingA_bv.glif
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmARingAbv" format="2">
+ <advance width="1107"/>
+ <unicode hex="00E5"/>
+ <anchor x="860" y="0" name="H"/>
+ <anchor x="455" y="-100" name="L"/>
+ <anchor x="1065" y="0" name="O"/>
+ <anchor x="1310" y="1000" name="R"/>
+ <anchor x="919" y="1635" name="U"/>
+ <outline>
+ <component base="LtnSmA"/>
+ <component base="CombRingAbv" xOffset="1140"/>
+ </outline>
+</glyph>
diff --git a/tests/input/font-psf-test/source/PsfTest-Italic.ufo/glyphs/L_tnS_mA_T_ilde.glif b/tests/input/font-psf-test/source/PsfTest-Italic.ufo/glyphs/L_tnS_mA_T_ilde.glif
new file mode 100644
index 0000000..c29348b
--- /dev/null
+++ b/tests/input/font-psf-test/source/PsfTest-Italic.ufo/glyphs/L_tnS_mA_T_ilde.glif
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmATilde" format="2">
+ <advance width="1107"/>
+ <unicode hex="00E3"/>
+ <anchor x="860" y="0" name="H"/>
+ <anchor x="455" y="-100" name="L"/>
+ <anchor x="1065" y="0" name="O"/>
+ <anchor x="1310" y="1000" name="R"/>
+ <anchor x="850" y="1475" name="U"/>
+ <outline>
+ <component base="LtnSmA"/>
+ <component base="CombTilde" xOffset="1140"/>
+ </outline>
+</glyph>
diff --git a/tests/input/font-psf-test/source/PsfTest-Italic.ufo/glyphs/L_tnS_mB_.glif b/tests/input/font-psf-test/source/PsfTest-Italic.ufo/glyphs/L_tnS_mB_.glif
new file mode 100644
index 0000000..b3a3696
--- /dev/null
+++ b/tests/input/font-psf-test/source/PsfTest-Italic.ufo/glyphs/L_tnS_mB_.glif
@@ -0,0 +1,55 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmB" format="2">
+ <advance width="1144"/>
+ <unicode hex="0062"/>
+ <anchor x="530" y="0" name="H"/>
+ <anchor x="505" y="-100" name="L"/>
+ <anchor x="1345" y="1000" name="R"/>
+ <anchor x="938" y="1635" name="U"/>
+ <outline>
+ <contour>
+ <point x="437" y="1570" type="line"/>
+ <point x="437" y="1456"/>
+ <point x="402" y="1246"/>
+ <point x="367" y="1105" type="curve" smooth="yes"/>
+ <point x="110" y="85" type="line"/>
+ <point x="198" y="44"/>
+ <point x="355" y="-25"/>
+ <point x="517" y="-25" type="curve" smooth="yes"/>
+ <point x="675" y="-25"/>
+ <point x="795" y="24"/>
+ <point x="907" y="125" type="curve" smooth="yes"/>
+ <point x="1050" y="255"/>
+ <point x="1162" y="466"/>
+ <point x="1162" y="695" type="curve" smooth="yes"/>
+ <point x="1162" y="930"/>
+ <point x="1046" y="1020"/>
+ <point x="907" y="1020" type="curve" smooth="yes"/>
+ <point x="754" y="1020"/>
+ <point x="584" y="878"/>
+ <point x="456" y="719" type="curve"/>
+ <point x="552" y="1105" type="line" smooth="yes"/>
+ <point x="600" y="1296"/>
+ <point x="627" y="1508"/>
+ <point x="627" y="1570" type="curve"/>
+ </contour>
+ <contour>
+ <point x="382" y="429" type="line"/>
+ <point x="485" y="617"/>
+ <point x="708" y="850"/>
+ <point x="822" y="850" type="curve" smooth="yes"/>
+ <point x="913" y="850"/>
+ <point x="972" y="784"/>
+ <point x="972" y="635" type="curve" smooth="yes"/>
+ <point x="972" y="469"/>
+ <point x="909" y="336"/>
+ <point x="822" y="250" type="curve" smooth="yes"/>
+ <point x="741" y="169"/>
+ <point x="638" y="125"/>
+ <point x="552" y="125" type="curve" smooth="yes"/>
+ <point x="466" y="125"/>
+ <point x="376" y="167"/>
+ <point x="325" y="200" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/input/font-psf-test/source/PsfTest-Italic.ufo/glyphs/L_tnS_mC_.glif b/tests/input/font-psf-test/source/PsfTest-Italic.ufo/glyphs/L_tnS_mC_.glif
new file mode 100644
index 0000000..f54fbe9
--- /dev/null
+++ b/tests/input/font-psf-test/source/PsfTest-Italic.ufo/glyphs/L_tnS_mC_.glif
@@ -0,0 +1,39 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmC" format="2">
+ <advance width="989"/>
+ <unicode hex="0063"/>
+ <anchor x="520" y="0" name="H"/>
+ <anchor x="495" y="-100" name="L"/>
+ <anchor x="1210" y="1000" name="R"/>
+ <anchor x="785" y="1100" name="U"/>
+ <outline>
+ <contour>
+ <point x="917" y="255" type="line"/>
+ <point x="811" y="179"/>
+ <point x="703" y="137"/>
+ <point x="583" y="137" type="curve" smooth="yes"/>
+ <point x="427" y="137"/>
+ <point x="331" y="239"/>
+ <point x="331" y="406" type="curve" smooth="yes"/>
+ <point x="331" y="619"/>
+ <point x="499" y="858"/>
+ <point x="742" y="858" type="curve" smooth="yes"/>
+ <point x="845" y="858"/>
+ <point x="924" y="824"/>
+ <point x="998" y="760" type="curve"/>
+ <point x="1077" y="936" type="line"/>
+ <point x="1016" y="985"/>
+ <point x="902" y="1020"/>
+ <point x="789" y="1020" type="curve" smooth="yes"/>
+ <point x="420" y="1020"/>
+ <point x="139" y="737"/>
+ <point x="139" y="381" type="curve" smooth="yes"/>
+ <point x="139" y="130"/>
+ <point x="309" y="-25"/>
+ <point x="532" y="-25" type="curve" smooth="yes"/>
+ <point x="682" y="-25"/>
+ <point x="785" y="9"/>
+ <point x="904" y="83" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/input/font-psf-test/source/PsfTest-Italic.ufo/glyphs/L_tnS_mD_.glif b/tests/input/font-psf-test/source/PsfTest-Italic.ufo/glyphs/L_tnS_mD_.glif
new file mode 100644
index 0000000..4ea9ea1
--- /dev/null
+++ b/tests/input/font-psf-test/source/PsfTest-Italic.ufo/glyphs/L_tnS_mD_.glif
@@ -0,0 +1,65 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmD" format="2">
+ <advance width="1197"/>
+ <unicode hex="0064"/>
+ <anchor x="545" y="0" name="H"/>
+ <anchor x="520" y="-100" name="L"/>
+ <anchor x="1380" y="1000" name="R"/>
+ <anchor x="953" y="1635" name="U"/>
+ <outline>
+ <contour>
+ <point x="1144" y="1570" type="line"/>
+ <point x="1144" y="1456"/>
+ <point x="1114" y="1327"/>
+ <point x="1079" y="1175" type="curve" smooth="yes"/>
+ <point x="1024" y="935" type="line"/>
+ <point x="957" y="978"/>
+ <point x="854" y="1020"/>
+ <point x="759" y="1020" type="curve" smooth="yes"/>
+ <point x="650" y="1020"/>
+ <point x="534" y="979"/>
+ <point x="429" y="895" type="curve" smooth="yes"/>
+ <point x="262" y="761"/>
+ <point x="139" y="532"/>
+ <point x="139" y="288" type="curve" smooth="yes"/>
+ <point x="139" y="94"/>
+ <point x="250" y="-25"/>
+ <point x="424" y="-25" type="curve" smooth="yes"/>
+ <point x="563" y="-25"/>
+ <point x="791" y="141"/>
+ <point x="899" y="305" type="curve"/>
+ <point x="875" y="196"/>
+ <point x="869" y="93"/>
+ <point x="869" y="0" type="curve"/>
+ <point x="1052" y="0" type="line"/>
+ <point x="1048" y="23"/>
+ <point x="1047" y="53"/>
+ <point x="1047" y="90" type="curve" smooth="yes"/>
+ <point x="1047" y="190"/>
+ <point x="1063" y="340"/>
+ <point x="1107" y="520" type="curve" smooth="yes"/>
+ <point x="1267" y="1175" type="line" smooth="yes"/>
+ <point x="1310" y="1351"/>
+ <point x="1337" y="1475"/>
+ <point x="1337" y="1570" type="curve"/>
+ </contour>
+ <contour>
+ <point x="930" y="545" type="line"/>
+ <point x="846" y="370"/>
+ <point x="592" y="130"/>
+ <point x="479" y="130" type="curve" smooth="yes"/>
+ <point x="374" y="130"/>
+ <point x="330" y="195"/>
+ <point x="330" y="316" type="curve" smooth="yes"/>
+ <point x="330" y="460"/>
+ <point x="397" y="649"/>
+ <point x="509" y="760" type="curve" smooth="yes"/>
+ <point x="572" y="822"/>
+ <point x="643" y="855"/>
+ <point x="734" y="855" type="curve" smooth="yes"/>
+ <point x="835" y="855"/>
+ <point x="898" y="832"/>
+ <point x="984" y="780" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/input/font-psf-test/source/PsfTest-Italic.ufo/glyphs/L_tnS_mE_.glif b/tests/input/font-psf-test/source/PsfTest-Italic.ufo/glyphs/L_tnS_mE_.glif
new file mode 100644
index 0000000..a3a6490
--- /dev/null
+++ b/tests/input/font-psf-test/source/PsfTest-Italic.ufo/glyphs/L_tnS_mE_.glif
@@ -0,0 +1,52 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmE" format="2">
+ <advance width="1042"/>
+ <unicode hex="0065"/>
+ <anchor x="485" y="0" name="H"/>
+ <anchor x="484" y="-100" name="L"/>
+ <anchor x="840" y="0" name="O"/>
+ <anchor x="1285" y="1000" name="R"/>
+ <anchor x="784" y="1100" name="U"/>
+ <outline>
+ <contour>
+ <point x="967" y="270" type="line"/>
+ <point x="854" y="189"/>
+ <point x="700" y="135"/>
+ <point x="567" y="135" type="curve" smooth="yes"/>
+ <point x="386" y="135"/>
+ <point x="317" y="263"/>
+ <point x="317" y="420" type="curve" smooth="yes"/>
+ <point x="317" y="686"/>
+ <point x="522" y="872"/>
+ <point x="720" y="872" type="curve" smooth="yes"/>
+ <point x="813" y="872"/>
+ <point x="883" y="823"/>
+ <point x="883" y="753" type="curve" smooth="yes"/>
+ <point x="883" y="660"/>
+ <point x="766" y="590"/>
+ <point x="539" y="590" type="curve" smooth="yes"/>
+ <point x="468" y="590"/>
+ <point x="382" y="596"/>
+ <point x="279" y="610" type="curve"/>
+ <point x="279" y="477" type="line"/>
+ <point x="391" y="461"/>
+ <point x="487" y="453"/>
+ <point x="569" y="453" type="curve" smooth="yes"/>
+ <point x="931" y="453"/>
+ <point x="1077" y="609"/>
+ <point x="1077" y="791" type="curve" smooth="yes"/>
+ <point x="1077" y="899"/>
+ <point x="986" y="1020"/>
+ <point x="772" y="1020" type="curve" smooth="yes"/>
+ <point x="399" y="1020"/>
+ <point x="137" y="710"/>
+ <point x="137" y="380" type="curve" smooth="yes"/>
+ <point x="137" y="147"/>
+ <point x="258" y="-25"/>
+ <point x="523" y="-25" type="curve" smooth="yes"/>
+ <point x="689" y="-25"/>
+ <point x="849" y="26"/>
+ <point x="955" y="83" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/input/font-psf-test/source/PsfTest-Italic.ufo/glyphs/L_tnS_mF_.glif b/tests/input/font-psf-test/source/PsfTest-Italic.ufo/glyphs/L_tnS_mF_.glif
new file mode 100644
index 0000000..ede52a9
--- /dev/null
+++ b/tests/input/font-psf-test/source/PsfTest-Italic.ufo/glyphs/L_tnS_mF_.glif
@@ -0,0 +1,44 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmF" format="2">
+ <advance width="756"/>
+ <unicode hex="0066"/>
+ <anchor x="290" y="0" name="H"/>
+ <anchor x="315" y="-100" name="L"/>
+ <anchor x="908" y="1635" name="U"/>
+ <outline>
+ <contour>
+ <point x="180" y="833" type="line"/>
+ <point x="835" y="833" type="line"/>
+ <point x="871" y="975" type="line"/>
+ <point x="216" y="975" type="line"/>
+ </contour>
+ <contour>
+ <point x="1106" y="1519" type="line"/>
+ <point x="1062" y="1555"/>
+ <point x="981" y="1588"/>
+ <point x="903" y="1588" type="curve" smooth="yes"/>
+ <point x="687" y="1588"/>
+ <point x="533" y="1478"/>
+ <point x="448" y="1147" type="curve" smooth="yes"/>
+ <point x="403" y="972"/>
+ <point x="244" y="334"/>
+ <point x="223" y="0" type="curve"/>
+ <point x="436" y="0" type="line"/>
+ <point x="430" y="28"/>
+ <point x="427" y="66"/>
+ <point x="427" y="110" type="curve" smooth="yes"/>
+ <point x="427" y="213"/>
+ <point x="447" y="351"/>
+ <point x="476" y="484" type="curve" smooth="yes"/>
+ <point x="510" y="641"/>
+ <point x="558" y="846"/>
+ <point x="641" y="1186" type="curve" smooth="yes"/>
+ <point x="682" y="1353"/>
+ <point x="758" y="1421"/>
+ <point x="862" y="1421" type="curve" smooth="yes"/>
+ <point x="920" y="1421"/>
+ <point x="988" y="1392"/>
+ <point x="1022" y="1362" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/input/font-psf-test/source/PsfTest-Italic.ufo/glyphs/L_tnS_mG_.glif b/tests/input/font-psf-test/source/PsfTest-Italic.ufo/glyphs/L_tnS_mG_.glif
new file mode 100644
index 0000000..8931f8d
--- /dev/null
+++ b/tests/input/font-psf-test/source/PsfTest-Italic.ufo/glyphs/L_tnS_mG_.glif
@@ -0,0 +1,100 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmG" format="2">
+ <advance width="1075"/>
+ <unicode hex="0067"/>
+ <anchor x="368" y="-465" name="H"/>
+ <anchor x="351" y="-535" name="L"/>
+ <anchor x="1285" y="1000" name="R"/>
+ <anchor x="730" y="1100" name="U"/>
+ <outline>
+ <contour>
+ <point x="360" y="389" type="line"/>
+ <point x="277" y="352"/>
+ <point x="168" y="266"/>
+ <point x="168" y="176" type="curve" smooth="yes"/>
+ <point x="168" y="96"/>
+ <point x="246" y="33"/>
+ <point x="483" y="-5" type="curve" smooth="yes"/>
+ <point x="707" y="-41"/>
+ <point x="781" y="-94"/>
+ <point x="781" y="-151" type="curve" smooth="yes"/>
+ <point x="781" y="-256"/>
+ <point x="580" y="-353"/>
+ <point x="411" y="-353" type="curve" smooth="yes"/>
+ <point x="202" y="-353"/>
+ <point x="104" y="-271"/>
+ <point x="104" y="-196" type="curve" smooth="yes"/>
+ <point x="104" y="-189"/>
+ <point x="104" y="-183"/>
+ <point x="106" y="-176" type="curve" smooth="yes"/>
+ <point x="120" y="-119"/>
+ <point x="170" y="-55"/>
+ <point x="409" y="20" type="curve"/>
+ <point x="410" y="48"/>
+ <point x="248" y="73"/>
+ <point x="248" y="73" type="curve"/>
+ <point x="53" y="12"/>
+ <point x="-51" y="-77"/>
+ <point x="-78" y="-186" type="curve" smooth="yes"/>
+ <point x="-82" y="-201"/>
+ <point x="-84" y="-217"/>
+ <point x="-84" y="-231" type="curve" smooth="yes"/>
+ <point x="-84" y="-396"/>
+ <point x="158" y="-495"/>
+ <point x="371" y="-495" type="curve" smooth="yes"/>
+ <point x="632" y="-495"/>
+ <point x="972" y="-360"/>
+ <point x="972" y="-125" type="curve" smooth="yes"/>
+ <point x="972" y="0"/>
+ <point x="849" y="90"/>
+ <point x="619" y="127" type="curve" smooth="yes"/>
+ <point x="403" y="162"/>
+ <point x="341" y="184"/>
+ <point x="341" y="218" type="curve" smooth="yes"/>
+ <point x="341" y="263"/>
+ <point x="447" y="325"/>
+ <point x="522" y="342" type="curve"/>
+ </contour>
+ <contour>
+ <point x="1244" y="1019" type="line"/>
+ <point x="1143" y="1012"/>
+ <point x="1002" y="977"/>
+ <point x="899" y="921" type="curve"/>
+ <point x="936" y="809" type="line"/>
+ <point x="1037" y="846"/>
+ <point x="1121" y="860"/>
+ <point x="1194" y="862" type="curve"/>
+ </contour>
+ <contour>
+ <point x="212" y="613" type="curve" smooth="yes"/>
+ <point x="212" y="449"/>
+ <point x="356" y="319"/>
+ <point x="554" y="319" type="curve" smooth="yes"/>
+ <point x="791" y="319"/>
+ <point x="1030" y="495"/>
+ <point x="1030" y="729" type="curve" smooth="yes"/>
+ <point x="1030" y="894"/>
+ <point x="887" y="1019"/>
+ <point x="689" y="1019" type="curve" smooth="yes"/>
+ <point x="441" y="1019"/>
+ <point x="212" y="847"/>
+ </contour>
+ <contour>
+ <point x="857" y="704" type="curve" smooth="yes"/>
+ <point x="857" y="555"/>
+ <point x="712" y="456"/>
+ <point x="578" y="456" type="curve" smooth="yes"/>
+ <point x="463" y="456"/>
+ <point x="385" y="530"/>
+ <point x="385" y="628" type="curve" smooth="yes"/>
+ <point x="385" y="643"/>
+ <point x="387" y="660"/>
+ <point x="391" y="676" type="curve" smooth="yes"/>
+ <point x="421" y="797"/>
+ <point x="530" y="877"/>
+ <point x="663" y="877" type="curve" smooth="yes"/>
+ <point x="779" y="877"/>
+ <point x="857" y="802"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/input/font-psf-test/source/PsfTest-Italic.ufo/glyphs/L_tnS_mH_.glif b/tests/input/font-psf-test/source/PsfTest-Italic.ufo/glyphs/L_tnS_mH_.glif
new file mode 100644
index 0000000..08afbac
--- /dev/null
+++ b/tests/input/font-psf-test/source/PsfTest-Italic.ufo/glyphs/L_tnS_mH_.glif
@@ -0,0 +1,54 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmH" format="2">
+ <advance width="1185"/>
+ <unicode hex="0068"/>
+ <anchor x="190" y="0" name="H"/>
+ <anchor x="550" y="-100" name="L"/>
+ <anchor x="933" y="1635" name="U"/>
+ <outline>
+ <contour>
+ <point x="1055" y="0" type="line"/>
+ <point x="1047" y="30"/>
+ <point x="1043" y="65"/>
+ <point x="1043" y="102" type="curve" smooth="yes"/>
+ <point x="1043" y="143"/>
+ <point x="1048" y="188"/>
+ <point x="1055" y="238" type="curve" smooth="yes"/>
+ <point x="1069" y="327"/>
+ <point x="1170" y="636"/>
+ <point x="1170" y="745" type="curve" smooth="yes"/>
+ <point x="1170" y="917"/>
+ <point x="1095" y="1020"/>
+ <point x="930" y="1020" type="curve" smooth="yes"/>
+ <point x="760" y="1020"/>
+ <point x="591" y="877"/>
+ <point x="475" y="723" type="curve"/>
+ <point x="571" y="1105" type="line" smooth="yes"/>
+ <point x="609" y="1259"/>
+ <point x="645" y="1482"/>
+ <point x="645" y="1570" type="curve"/>
+ <point x="455" y="1570" type="line"/>
+ <point x="455" y="1456"/>
+ <point x="423" y="1257"/>
+ <point x="385" y="1105" type="curve" smooth="yes"/>
+ <point x="110" y="0" type="line"/>
+ <point x="295" y="0" type="line"/>
+ <point x="397" y="408" type="line"/>
+ <point x="492" y="612"/>
+ <point x="717" y="850"/>
+ <point x="840" y="850" type="curve" smooth="yes"/>
+ <point x="937" y="850"/>
+ <point x="970" y="798"/>
+ <point x="970" y="680" type="curve" smooth="yes"/>
+ <point x="970" y="592"/>
+ <point x="886" y="319"/>
+ <point x="872" y="203" type="curve" smooth="yes"/>
+ <point x="867" y="158"/>
+ <point x="864" y="115"/>
+ <point x="864" y="77" type="curve" smooth="yes"/>
+ <point x="864" y="48"/>
+ <point x="866" y="21"/>
+ <point x="870" y="0" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/input/font-psf-test/source/PsfTest-Italic.ufo/glyphs/L_tnS_mI_.glif b/tests/input/font-psf-test/source/PsfTest-Italic.ufo/glyphs/L_tnS_mI_.glif
new file mode 100644
index 0000000..65ed550
--- /dev/null
+++ b/tests/input/font-psf-test/source/PsfTest-Italic.ufo/glyphs/L_tnS_mI_.glif
@@ -0,0 +1,50 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmI" format="2">
+ <advance width="554"/>
+ <unicode hex="0069"/>
+ <anchor x="235" y="0" name="H"/>
+ <anchor x="250" y="-100" name="L"/>
+ <anchor x="455" y="0" name="O"/>
+ <anchor x="745" y="1000" name="R"/>
+ <anchor x="472" y="1100" name="U"/>
+ <outline>
+ <contour>
+ <point x="361" y="1297" type="curve" smooth="yes"/>
+ <point x="361" y="1237"/>
+ <point x="404" y="1186"/>
+ <point x="467" y="1186" type="curve" smooth="yes"/>
+ <point x="552" y="1186"/>
+ <point x="624" y="1259"/>
+ <point x="624" y="1338" type="curve" smooth="yes"/>
+ <point x="624" y="1399"/>
+ <point x="578" y="1450"/>
+ <point x="513" y="1450" type="curve" smooth="yes"/>
+ <point x="428" y="1450"/>
+ <point x="361" y="1375"/>
+ </contour>
+ <contour>
+ <point x="335" y="1000" type="line"/>
+ <point x="335" y="886"/>
+ <point x="286" y="688"/>
+ <point x="246" y="537" type="curve" smooth="yes"/>
+ <point x="207" y="388" type="line" smooth="yes"/>
+ <point x="180" y="284"/>
+ <point x="165" y="172"/>
+ <point x="165" y="87" type="curve" smooth="yes"/>
+ <point x="165" y="53"/>
+ <point x="167" y="24"/>
+ <point x="172" y="0" type="curve"/>
+ <point x="372" y="0" type="line"/>
+ <point x="365" y="37"/>
+ <point x="360" y="85"/>
+ <point x="360" y="136" type="curve" smooth="yes"/>
+ <point x="360" y="208"/>
+ <point x="368" y="287"/>
+ <point x="386" y="357" type="curve" smooth="yes"/>
+ <point x="431" y="536" type="line" smooth="yes"/>
+ <point x="476" y="712"/>
+ <point x="525" y="912"/>
+ <point x="525" y="1000" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/input/font-psf-test/source/PsfTest-Italic.ufo/glyphs/L_tnS_mJ_.glif b/tests/input/font-psf-test/source/PsfTest-Italic.ufo/glyphs/L_tnS_mJ_.glif
new file mode 100644
index 0000000..e9e18b8
--- /dev/null
+++ b/tests/input/font-psf-test/source/PsfTest-Italic.ufo/glyphs/L_tnS_mJ_.glif
@@ -0,0 +1,45 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmJ" format="2">
+ <advance width="602"/>
+ <unicode hex="006A"/>
+ <anchor x="-60" y="-500" name="L"/>
+ <anchor x="510" y="1100" name="U"/>
+ <outline>
+ <contour>
+ <point x="370" y="1000" type="line"/>
+ <point x="370" y="856"/>
+ <point x="288" y="374"/>
+ <point x="214" y="77" type="curve" smooth="yes"/>
+ <point x="152" y="-173"/>
+ <point x="29" y="-295"/>
+ <point x="-77" y="-295" type="curve" smooth="yes"/>
+ <point x="-133" y="-295"/>
+ <point x="-217" y="-264"/>
+ <point x="-253" y="-229" type="curve"/>
+ <point x="-328" y="-397" type="line"/>
+ <point x="-278" y="-437"/>
+ <point x="-170" y="-465"/>
+ <point x="-114" y="-465" type="curve" smooth="yes"/>
+ <point x="103" y="-465"/>
+ <point x="303" y="-314"/>
+ <point x="396" y="66" type="curve" smooth="yes"/>
+ <point x="455" y="307"/>
+ <point x="560" y="872"/>
+ <point x="560" y="1000" type="curve"/>
+ </contour>
+ <contour>
+ <point x="397" y="1297" type="curve" smooth="yes"/>
+ <point x="397" y="1237"/>
+ <point x="440" y="1186"/>
+ <point x="503" y="1186" type="curve" smooth="yes"/>
+ <point x="588" y="1186"/>
+ <point x="660" y="1259"/>
+ <point x="660" y="1338" type="curve" smooth="yes"/>
+ <point x="660" y="1399"/>
+ <point x="614" y="1450"/>
+ <point x="549" y="1450" type="curve" smooth="yes"/>
+ <point x="464" y="1450"/>
+ <point x="397" y="1375"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/input/font-psf-test/source/PsfTest-Italic.ufo/glyphs/L_tnS_mK_.glif b/tests/input/font-psf-test/source/PsfTest-Italic.ufo/glyphs/L_tnS_mK_.glif
new file mode 100644
index 0000000..28fbc71
--- /dev/null
+++ b/tests/input/font-psf-test/source/PsfTest-Italic.ufo/glyphs/L_tnS_mK_.glif
@@ -0,0 +1,50 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmK" format="2">
+ <advance width="1059"/>
+ <unicode hex="006B"/>
+ <anchor x="840" y="0" name="H"/>
+ <anchor x="537" y="-100" name="L"/>
+ <anchor x="1225" y="1000" name="R"/>
+ <anchor x="920" y="1635" name="U"/>
+ <outline>
+ <contour>
+ <point x="295" y="0" type="line"/>
+ <point x="570" y="1105" type="line" smooth="yes"/>
+ <point x="614" y="1280"/>
+ <point x="645" y="1482"/>
+ <point x="645" y="1570" type="curve"/>
+ <point x="455" y="1570" type="line"/>
+ <point x="455" y="1456"/>
+ <point x="424" y="1259"/>
+ <point x="386" y="1107" type="curve" smooth="yes"/>
+ <point x="338" y="915"/>
+ <point x="110" y="0"/>
+ <point x="110" y="0" type="curve"/>
+ </contour>
+ <contour>
+ <point x="909" y="1000" type="line"/>
+ <point x="885" y="863"/>
+ <point x="654" y="700"/>
+ <point x="379" y="539" type="curve"/>
+ <point x="386" y="540"/>
+ <point x="393" y="540"/>
+ <point x="400" y="540" type="curve" smooth="yes"/>
+ <point x="467" y="540"/>
+ <point x="559" y="514"/>
+ <point x="559" y="514" type="curve"/>
+ <point x="902" y="702"/>
+ <point x="1134" y="884"/>
+ <point x="1134" y="1000" type="curve"/>
+ </contour>
+ <contour>
+ <point x="1010" y="0" type="line"/>
+ <point x="863" y="238"/>
+ <point x="718" y="600"/>
+ <point x="527" y="600" type="curve"/>
+ <point x="385" y="529" type="line"/>
+ <point x="540" y="529"/>
+ <point x="667" y="246"/>
+ <point x="775" y="0" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/input/font-psf-test/source/PsfTest-Italic.ufo/glyphs/L_tnS_mL_.glif b/tests/input/font-psf-test/source/PsfTest-Italic.ufo/glyphs/L_tnS_mL_.glif
new file mode 100644
index 0000000..06d68fd
--- /dev/null
+++ b/tests/input/font-psf-test/source/PsfTest-Italic.ufo/glyphs/L_tnS_mL_.glif
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmL" format="2">
+ <advance width="575"/>
+ <unicode hex="006C"/>
+ <anchor x="230" y="0" name="H"/>
+ <anchor x="255" y="-100" name="L"/>
+ <anchor x="740" y="1000" name="R"/>
+ <anchor x="630" y="1635" name="U"/>
+ <outline>
+ <contour>
+ <point x="465" y="1570" type="line"/>
+ <point x="465" y="1456"/>
+ <point x="434" y="1259"/>
+ <point x="396" y="1107" type="curve" smooth="yes"/>
+ <point x="241" y="489" type="line" smooth="yes"/>
+ <point x="204" y="343"/>
+ <point x="186" y="220"/>
+ <point x="186" y="104" type="curve" smooth="yes"/>
+ <point x="186" y="69"/>
+ <point x="188" y="34"/>
+ <point x="191" y="0" type="curve"/>
+ <point x="391" y="0" type="line"/>
+ <point x="386" y="32"/>
+ <point x="384" y="70"/>
+ <point x="384" y="112" type="curve" smooth="yes"/>
+ <point x="384" y="230"/>
+ <point x="402" y="380"/>
+ <point x="436" y="517" type="curve" smooth="yes"/>
+ <point x="580" y="1105" type="line" smooth="yes"/>
+ <point x="623" y="1280"/>
+ <point x="655" y="1482"/>
+ <point x="655" y="1570" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/input/font-psf-test/source/PsfTest-Italic.ufo/glyphs/L_tnS_mM_.glif b/tests/input/font-psf-test/source/PsfTest-Italic.ufo/glyphs/L_tnS_mM_.glif
new file mode 100644
index 0000000..a6b80db
--- /dev/null
+++ b/tests/input/font-psf-test/source/PsfTest-Italic.ufo/glyphs/L_tnS_mM_.glif
@@ -0,0 +1,80 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmM" format="2">
+ <advance width="1680"/>
+ <unicode hex="006D"/>
+ <anchor x="805" y="0" name="H"/>
+ <anchor x="780" y="-100" name="L"/>
+ <anchor x="1080" y="1100" name="U"/>
+ <outline>
+ <contour>
+ <point x="1520" y="0" type="line"/>
+ <point x="1512" y="30"/>
+ <point x="1510" y="65"/>
+ <point x="1510" y="102" type="curve" smooth="yes"/>
+ <point x="1510" y="143"/>
+ <point x="1515" y="188"/>
+ <point x="1522" y="238" type="curve" smooth="yes"/>
+ <point x="1536" y="327"/>
+ <point x="1655" y="691"/>
+ <point x="1655" y="800" type="curve" smooth="yes"/>
+ <point x="1655" y="930"/>
+ <point x="1594" y="1020"/>
+ <point x="1445" y="1020" type="curve" smooth="yes"/>
+ <point x="1292" y="1020"/>
+ <point x="1124" y="867"/>
+ <point x="1026" y="680" type="curve"/>
+ <point x="1030" y="704"/>
+ <point x="1045" y="778"/>
+ <point x="1045" y="800" type="curve" smooth="yes"/>
+ <point x="1045" y="932"/>
+ <point x="982" y="1020"/>
+ <point x="860" y="1020" type="curve" smooth="yes"/>
+ <point x="717" y="1020"/>
+ <point x="563" y="879"/>
+ <point x="446" y="680" type="curve"/>
+ <point x="466" y="753"/>
+ <point x="476" y="880"/>
+ <point x="476" y="961" type="curve" smooth="yes"/>
+ <point x="476" y="976"/>
+ <point x="476" y="989"/>
+ <point x="475" y="1000" type="curve"/>
+ <point x="295" y="1000" type="line"/>
+ <point x="296" y="983"/>
+ <point x="296" y="964"/>
+ <point x="296" y="945" type="curve" smooth="yes"/>
+ <point x="296" y="825"/>
+ <point x="283" y="680"/>
+ <point x="262" y="595" type="curve" smooth="yes"/>
+ <point x="115" y="0" type="line"/>
+ <point x="300" y="0" type="line"/>
+ <point x="389" y="359" type="line"/>
+ <point x="475" y="573"/>
+ <point x="685" y="850"/>
+ <point x="775" y="850" type="curve" smooth="yes"/>
+ <point x="833" y="850"/>
+ <point x="865" y="813"/>
+ <point x="865" y="720" type="curve" smooth="yes"/>
+ <point x="865" y="679"/>
+ <point x="846" y="583"/>
+ <point x="822" y="486" type="curve" smooth="yes"/>
+ <point x="700" y="0" type="line"/>
+ <point x="885" y="0" type="line"/>
+ <point x="974" y="359" type="line"/>
+ <point x="1032" y="531"/>
+ <point x="1242" y="850"/>
+ <point x="1357" y="850" type="curve" smooth="yes"/>
+ <point x="1425" y="850"/>
+ <point x="1457" y="813"/>
+ <point x="1457" y="720" type="curve" smooth="yes"/>
+ <point x="1457" y="632"/>
+ <point x="1349" y="319"/>
+ <point x="1335" y="203" type="curve" smooth="yes"/>
+ <point x="1330" y="158"/>
+ <point x="1327" y="115"/>
+ <point x="1327" y="77" type="curve" smooth="yes"/>
+ <point x="1327" y="48"/>
+ <point x="1331" y="21"/>
+ <point x="1335" y="0" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/input/font-psf-test/source/PsfTest-Italic.ufo/glyphs/L_tnS_mN_.glif b/tests/input/font-psf-test/source/PsfTest-Italic.ufo/glyphs/L_tnS_mN_.glif
new file mode 100644
index 0000000..1f38f20
--- /dev/null
+++ b/tests/input/font-psf-test/source/PsfTest-Italic.ufo/glyphs/L_tnS_mN_.glif
@@ -0,0 +1,57 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmN" format="2">
+ <advance width="1195"/>
+ <unicode hex="006E"/>
+ <anchor x="540" y="0" name="H"/>
+ <anchor x="565" y="-100" name="L"/>
+ <anchor x="815" y="1100" name="U"/>
+ <outline>
+ <contour>
+ <point x="1060" y="0" type="line"/>
+ <point x="1052" y="30"/>
+ <point x="1050" y="65"/>
+ <point x="1050" y="102" type="curve" smooth="yes"/>
+ <point x="1050" y="143"/>
+ <point x="1055" y="188"/>
+ <point x="1062" y="238" type="curve" smooth="yes"/>
+ <point x="1075" y="327"/>
+ <point x="1175" y="636"/>
+ <point x="1175" y="745" type="curve" smooth="yes"/>
+ <point x="1175" y="917"/>
+ <point x="1100" y="1020"/>
+ <point x="935" y="1020" type="curve" smooth="yes"/>
+ <point x="755" y="1020"/>
+ <point x="581" y="870"/>
+ <point x="445" y="672" type="curve"/>
+ <point x="463" y="740"/>
+ <point x="477" y="873"/>
+ <point x="477" y="957" type="curve" smooth="yes"/>
+ <point x="477" y="973"/>
+ <point x="476" y="988"/>
+ <point x="475" y="1000" type="curve"/>
+ <point x="295" y="1000" type="line"/>
+ <point x="295" y="961" type="line" smooth="yes"/>
+ <point x="295" y="833"/>
+ <point x="283" y="679"/>
+ <point x="262" y="595" type="curve" smooth="yes"/>
+ <point x="115" y="0" type="line"/>
+ <point x="300" y="0" type="line"/>
+ <point x="392" y="370" type="line"/>
+ <point x="478" y="573"/>
+ <point x="708" y="850"/>
+ <point x="835" y="850" type="curve" smooth="yes"/>
+ <point x="927" y="850"/>
+ <point x="975" y="798"/>
+ <point x="975" y="680" type="curve" smooth="yes"/>
+ <point x="975" y="592"/>
+ <point x="888" y="319"/>
+ <point x="875" y="203" type="curve" smooth="yes"/>
+ <point x="870" y="158"/>
+ <point x="867" y="115"/>
+ <point x="867" y="77" type="curve" smooth="yes"/>
+ <point x="867" y="48"/>
+ <point x="871" y="21"/>
+ <point x="875" y="0" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/input/font-psf-test/source/PsfTest-Italic.ufo/glyphs/L_tnS_mO_.glif b/tests/input/font-psf-test/source/PsfTest-Italic.ufo/glyphs/L_tnS_mO_.glif
new file mode 100644
index 0000000..bec7b9e
--- /dev/null
+++ b/tests/input/font-psf-test/source/PsfTest-Italic.ufo/glyphs/L_tnS_mO_.glif
@@ -0,0 +1,40 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmO" format="2">
+ <advance width="1133"/>
+ <unicode hex="006F"/>
+ <anchor x="510" y="0" name="H"/>
+ <anchor x="505" y="-100" name="L"/>
+ <anchor x="800" y="0" name="O"/>
+ <anchor x="1330" y="1000" name="R"/>
+ <anchor x="785" y="1100" name="U"/>
+ <outline>
+ <contour>
+ <point x="142" y="344" type="curve" smooth="yes"/>
+ <point x="142" y="114"/>
+ <point x="306" y="-25"/>
+ <point x="530" y="-25" type="curve" smooth="yes"/>
+ <point x="896" y="-25"/>
+ <point x="1138" y="314"/>
+ <point x="1138" y="648" type="curve" smooth="yes"/>
+ <point x="1138" y="879"/>
+ <point x="985" y="1020"/>
+ <point x="761" y="1020" type="curve" smooth="yes"/>
+ <point x="387" y="1020"/>
+ <point x="142" y="677"/>
+ </contour>
+ <contour>
+ <point x="721" y="862" type="curve" smooth="yes"/>
+ <point x="859" y="862"/>
+ <point x="947" y="767"/>
+ <point x="947" y="611" type="curve" smooth="yes"/>
+ <point x="947" y="391"/>
+ <point x="795" y="132"/>
+ <point x="559" y="132" type="curve" smooth="yes"/>
+ <point x="421" y="132"/>
+ <point x="333" y="226"/>
+ <point x="333" y="380" type="curve" smooth="yes"/>
+ <point x="333" y="599"/>
+ <point x="486" y="862"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/input/font-psf-test/source/PsfTest-Italic.ufo/glyphs/L_tnS_mP_.glif b/tests/input/font-psf-test/source/PsfTest-Italic.ufo/glyphs/L_tnS_mP_.glif
new file mode 100644
index 0000000..f9e06b1
--- /dev/null
+++ b/tests/input/font-psf-test/source/PsfTest-Italic.ufo/glyphs/L_tnS_mP_.glif
@@ -0,0 +1,66 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmP" format="2">
+ <advance width="1185"/>
+ <unicode hex="0070"/>
+ <anchor x="105" y="-435" name="H"/>
+ <anchor x="405" y="-500" name="L"/>
+ <anchor x="1360" y="1000" name="R"/>
+ <anchor x="805" y="1100" name="U"/>
+ <outline>
+ <contour>
+ <point x="215" y="-480" type="line"/>
+ <point x="215" y="-388"/>
+ <point x="229" y="-282"/>
+ <point x="255" y="-175" type="curve" smooth="yes"/>
+ <point x="320" y="85" type="line"/>
+ <point x="399" y="20"/>
+ <point x="468" y="-25"/>
+ <point x="575" y="-25" type="curve" smooth="yes"/>
+ <point x="685" y="-25"/>
+ <point x="797" y="9"/>
+ <point x="895" y="85" type="curve" smooth="yes"/>
+ <point x="1063" y="215"/>
+ <point x="1185" y="438"/>
+ <point x="1185" y="680" type="curve" smooth="yes"/>
+ <point x="1185" y="878"/>
+ <point x="1101" y="1020"/>
+ <point x="920" y="1020" type="curve" smooth="yes"/>
+ <point x="757" y="1020"/>
+ <point x="559" y="842"/>
+ <point x="452" y="680" type="curve"/>
+ <point x="468" y="760"/>
+ <point x="477" y="860"/>
+ <point x="477" y="940" type="curve" smooth="yes"/>
+ <point x="477" y="962"/>
+ <point x="477" y="982"/>
+ <point x="475" y="1000" type="curve"/>
+ <point x="295" y="1000" type="line"/>
+ <point x="295" y="971" type="line" smooth="yes"/>
+ <point x="295" y="819"/>
+ <point x="273" y="625"/>
+ <point x="235" y="475" type="curve" smooth="yes"/>
+ <point x="70" y="-175" type="line" smooth="yes"/>
+ <point x="43" y="-281"/>
+ <point x="20" y="-398"/>
+ <point x="20" y="-480" type="curve"/>
+ </contour>
+ <contour>
+ <point x="407" y="432" type="line"/>
+ <point x="544" y="656"/>
+ <point x="732" y="850"/>
+ <point x="840" y="850" type="curve" smooth="yes"/>
+ <point x="939" y="850"/>
+ <point x="990" y="763"/>
+ <point x="990" y="630" type="curve" smooth="yes"/>
+ <point x="990" y="491"/>
+ <point x="926" y="322"/>
+ <point x="815" y="220" type="curve" smooth="yes"/>
+ <point x="759" y="168"/>
+ <point x="693" y="135"/>
+ <point x="615" y="135" type="curve" smooth="yes"/>
+ <point x="523" y="135"/>
+ <point x="479" y="161"/>
+ <point x="365" y="255" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/input/font-psf-test/source/PsfTest-Italic.ufo/glyphs/L_tnS_mQ_.glif b/tests/input/font-psf-test/source/PsfTest-Italic.ufo/glyphs/L_tnS_mQ_.glif
new file mode 100644
index 0000000..58d9f87
--- /dev/null
+++ b/tests/input/font-psf-test/source/PsfTest-Italic.ufo/glyphs/L_tnS_mQ_.glif
@@ -0,0 +1,54 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmQ" format="2">
+ <advance width="1115"/>
+ <unicode hex="0071"/>
+ <anchor x="370" y="-500" name="L"/>
+ <anchor x="1320" y="1000" name="R"/>
+ <anchor x="770" y="1100" name="U"/>
+ <outline>
+ <contour>
+ <point x="843" y="-480" type="line"/>
+ <point x="843" y="-391"/>
+ <point x="858" y="-294"/>
+ <point x="885" y="-185" type="curve" smooth="yes"/>
+ <point x="1165" y="945" type="line"/>
+ <point x="1066" y="980"/>
+ <point x="946" y="1020"/>
+ <point x="825" y="1020" type="curve" smooth="yes"/>
+ <point x="675" y="1020"/>
+ <point x="550" y="977"/>
+ <point x="440" y="890" type="curve" smooth="yes"/>
+ <point x="260" y="747"/>
+ <point x="135" y="505"/>
+ <point x="135" y="285" type="curve" smooth="yes"/>
+ <point x="135" y="73"/>
+ <point x="261" y="-25"/>
+ <point x="380" y="-25" type="curve" smooth="yes"/>
+ <point x="524" y="-25"/>
+ <point x="751" y="172"/>
+ <point x="825" y="300" type="curve"/>
+ <point x="693" y="-180" type="line" smooth="yes"/>
+ <point x="662" y="-294"/>
+ <point x="648" y="-414"/>
+ <point x="648" y="-480" type="curve"/>
+ </contour>
+ <contour>
+ <point x="885" y="565" type="line"/>
+ <point x="807" y="413"/>
+ <point x="550" y="140"/>
+ <point x="455" y="140" type="curve" smooth="yes"/>
+ <point x="376" y="140"/>
+ <point x="330" y="199"/>
+ <point x="330" y="330" type="curve" smooth="yes"/>
+ <point x="330" y="481"/>
+ <point x="400" y="658"/>
+ <point x="515" y="760" type="curve" smooth="yes"/>
+ <point x="580" y="817"/>
+ <point x="658" y="855"/>
+ <point x="750" y="855" type="curve" smooth="yes"/>
+ <point x="811" y="855"/>
+ <point x="893" y="840"/>
+ <point x="947" y="817" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/input/font-psf-test/source/PsfTest-Italic.ufo/glyphs/L_tnS_mR_.glif b/tests/input/font-psf-test/source/PsfTest-Italic.ufo/glyphs/L_tnS_mR_.glif
new file mode 100644
index 0000000..8037612
--- /dev/null
+++ b/tests/input/font-psf-test/source/PsfTest-Italic.ufo/glyphs/L_tnS_mR_.glif
@@ -0,0 +1,42 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmR" format="2">
+ <advance width="910"/>
+ <unicode hex="0072"/>
+ <anchor x="210" y="0" name="H"/>
+ <anchor x="220" y="-100" name="L"/>
+ <anchor x="670" y="1100" name="U"/>
+ <outline>
+ <contour>
+ <point x="300" y="0" type="line"/>
+ <point x="402" y="415" type="line"/>
+ <point x="502" y="602"/>
+ <point x="703" y="850"/>
+ <point x="785" y="850" type="curve" smooth="yes"/>
+ <point x="831" y="850"/>
+ <point x="855" y="801"/>
+ <point x="855" y="740" type="curve" smooth="yes"/>
+ <point x="855" y="715"/>
+ <point x="852" y="689"/>
+ <point x="845" y="660" type="curve"/>
+ <point x="1010" y="690" type="line"/>
+ <point x="1022" y="737"/>
+ <point x="1030" y="783"/>
+ <point x="1030" y="825" type="curve" smooth="yes"/>
+ <point x="1030" y="935"/>
+ <point x="986" y="1020"/>
+ <point x="865" y="1020" type="curve" smooth="yes"/>
+ <point x="735" y="1020"/>
+ <point x="575" y="867"/>
+ <point x="445" y="675" type="curve"/>
+ <point x="467" y="773"/>
+ <point x="475" y="929"/>
+ <point x="475" y="1000" type="curve"/>
+ <point x="295" y="1000" type="line"/>
+ <point x="295" y="961" type="line" smooth="yes"/>
+ <point x="295" y="833"/>
+ <point x="283" y="679"/>
+ <point x="262" y="595" type="curve" smooth="yes"/>
+ <point x="115" y="0" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/input/font-psf-test/source/PsfTest-Italic.ufo/glyphs/L_tnS_mS_.glif b/tests/input/font-psf-test/source/PsfTest-Italic.ufo/glyphs/L_tnS_mS_.glif
new file mode 100644
index 0000000..848ddda
--- /dev/null
+++ b/tests/input/font-psf-test/source/PsfTest-Italic.ufo/glyphs/L_tnS_mS_.glif
@@ -0,0 +1,50 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmS" format="2">
+ <advance width="945"/>
+ <unicode hex="0073"/>
+ <anchor x="435" y="0" name="H"/>
+ <anchor x="440" y="-100" name="L"/>
+ <anchor x="710" y="1100" name="U"/>
+ <outline>
+ <contour>
+ <point x="990" y="941" type="line"/>
+ <point x="930" y="978"/>
+ <point x="815" y="1020"/>
+ <point x="640" y="1020" type="curve" smooth="yes"/>
+ <point x="384" y="1020"/>
+ <point x="230" y="881"/>
+ <point x="230" y="716" type="curve" smooth="yes"/>
+ <point x="230" y="614"/>
+ <point x="320" y="533"/>
+ <point x="466" y="461" type="curve" smooth="yes"/>
+ <point x="638" y="376"/>
+ <point x="700" y="333"/>
+ <point x="700" y="265" type="curve" smooth="yes"/>
+ <point x="700" y="188"/>
+ <point x="621" y="132"/>
+ <point x="532" y="132" type="curve" smooth="yes"/>
+ <point x="376" y="132"/>
+ <point x="244" y="216"/>
+ <point x="159" y="325" type="curve"/>
+ <point x="71" y="158" type="line"/>
+ <point x="160" y="60"/>
+ <point x="296" y="-25"/>
+ <point x="488" y="-25" type="curve" smooth="yes"/>
+ <point x="713" y="-25"/>
+ <point x="891" y="106"/>
+ <point x="891" y="306" type="curve" smooth="yes"/>
+ <point x="891" y="432"/>
+ <point x="774" y="515"/>
+ <point x="626" y="593" type="curve" smooth="yes"/>
+ <point x="476" y="672"/>
+ <point x="418" y="695"/>
+ <point x="418" y="753" type="curve" smooth="yes"/>
+ <point x="418" y="822"/>
+ <point x="494" y="862"/>
+ <point x="619" y="862" type="curve" smooth="yes"/>
+ <point x="743" y="862"/>
+ <point x="854" y="808"/>
+ <point x="911" y="769" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/input/font-psf-test/source/PsfTest-Italic.ufo/glyphs/L_tnS_mT_.glif b/tests/input/font-psf-test/source/PsfTest-Italic.ufo/glyphs/L_tnS_mT_.glif
new file mode 100644
index 0000000..0eddfe9
--- /dev/null
+++ b/tests/input/font-psf-test/source/PsfTest-Italic.ufo/glyphs/L_tnS_mT_.glif
@@ -0,0 +1,45 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmT" format="2">
+ <advance width="815"/>
+ <unicode hex="0074"/>
+ <anchor x="455" y="0" name="H"/>
+ <anchor x="390" y="-100" name="L"/>
+ <anchor x="1025" y="1000" name="R"/>
+ <anchor x="605" y="1360" name="U"/>
+ <outline>
+ <contour>
+ <point x="752" y="211" type="line"/>
+ <point x="665" y="169"/>
+ <point x="593" y="134"/>
+ <point x="527" y="134" type="curve" smooth="yes"/>
+ <point x="448" y="134"/>
+ <point x="425" y="188"/>
+ <point x="425" y="247" type="curve" smooth="yes"/>
+ <point x="425" y="274"/>
+ <point x="429" y="301"/>
+ <point x="434" y="326" type="curve" smooth="yes"/>
+ <point x="470" y="519"/>
+ <point x="564" y="843"/>
+ <point x="677" y="1294" type="curve"/>
+ <point x="492" y="1294" type="line"/>
+ <point x="377" y="841"/>
+ <point x="263" y="429"/>
+ <point x="243" y="301" type="curve" smooth="yes"/>
+ <point x="238" y="269"/>
+ <point x="236" y="240"/>
+ <point x="236" y="213" type="curve" smooth="yes"/>
+ <point x="236" y="41"/>
+ <point x="330" y="-25"/>
+ <point x="465" y="-25" type="curve" smooth="yes"/>
+ <point x="535" y="-25"/>
+ <point x="634" y="-6"/>
+ <point x="740" y="52" type="curve"/>
+ </contour>
+ <contour>
+ <point x="177" y="833" type="line"/>
+ <point x="887" y="833" type="line"/>
+ <point x="923" y="975" type="line"/>
+ <point x="213" y="975" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/input/font-psf-test/source/PsfTest-Italic.ufo/glyphs/L_tnS_mU_.glif b/tests/input/font-psf-test/source/PsfTest-Italic.ufo/glyphs/L_tnS_mU_.glif
new file mode 100644
index 0000000..0eda3d2
--- /dev/null
+++ b/tests/input/font-psf-test/source/PsfTest-Italic.ufo/glyphs/L_tnS_mU_.glif
@@ -0,0 +1,57 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmU" format="2">
+ <advance width="1175"/>
+ <unicode hex="0075"/>
+ <anchor x="465" y="0" name="H"/>
+ <anchor x="504" y="-100" name="L"/>
+ <anchor x="640" y="0" name="O"/>
+ <anchor x="1375" y="1000" name="R"/>
+ <anchor x="804" y="1100" name="U"/>
+ <outline>
+ <contour>
+ <point x="1040" y="0" type="line"/>
+ <point x="1036" y="29"/>
+ <point x="1035" y="62"/>
+ <point x="1035" y="100" type="curve" smooth="yes"/>
+ <point x="1035" y="206"/>
+ <point x="1054" y="341"/>
+ <point x="1080" y="455" type="curve" smooth="yes"/>
+ <point x="1135" y="689"/>
+ <point x="1197" y="895"/>
+ <point x="1205" y="1000" type="curve"/>
+ <point x="1010" y="1000" type="line"/>
+ <point x="1003" y="882"/>
+ <point x="971" y="769"/>
+ <point x="920" y="565" type="curve"/>
+ <point x="827" y="376"/>
+ <point x="573" y="135"/>
+ <point x="475" y="135" type="curve" smooth="yes"/>
+ <point x="409" y="135"/>
+ <point x="365" y="181"/>
+ <point x="365" y="280" type="curve" smooth="yes"/>
+ <point x="365" y="347"/>
+ <point x="407" y="500"/>
+ <point x="459" y="702" type="curve" smooth="yes"/>
+ <point x="494" y="837"/>
+ <point x="515" y="925"/>
+ <point x="520" y="1000" type="curve"/>
+ <point x="325" y="1000" type="line"/>
+ <point x="313" y="882"/>
+ <point x="295" y="809"/>
+ <point x="265" y="685" type="curve" smooth="yes"/>
+ <point x="195" y="395" type="line" smooth="yes"/>
+ <point x="179" y="330"/>
+ <point x="170" y="275"/>
+ <point x="170" y="225" type="curve" smooth="yes"/>
+ <point x="170" y="60"/>
+ <point x="257" y="-25"/>
+ <point x="410" y="-25" type="curve" smooth="yes"/>
+ <point x="551" y="-25"/>
+ <point x="745" y="118"/>
+ <point x="880" y="305" type="curve"/>
+ <point x="861" y="196"/>
+ <point x="860" y="98"/>
+ <point x="860" y="0" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/input/font-psf-test/source/PsfTest-Italic.ufo/glyphs/L_tnS_mV_.glif b/tests/input/font-psf-test/source/PsfTest-Italic.ufo/glyphs/L_tnS_mV_.glif
new file mode 100644
index 0000000..33e91d6
--- /dev/null
+++ b/tests/input/font-psf-test/source/PsfTest-Italic.ufo/glyphs/L_tnS_mV_.glif
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmV" format="2">
+ <advance width="941"/>
+ <unicode hex="0076"/>
+ <anchor x="359" y="0" name="H"/>
+ <anchor x="350" y="-100" name="L"/>
+ <anchor x="565" y="0" name="O"/>
+ <anchor x="650" y="1100" name="U"/>
+ <outline>
+ <contour>
+ <point x="180" y="1000" type="line"/>
+ <point x="232" y="825"/>
+ <point x="256" y="602"/>
+ <point x="256" y="354" type="curve" smooth="yes"/>
+ <point x="256" y="241"/>
+ <point x="251" y="122"/>
+ <point x="241" y="0" type="curve"/>
+ <point x="441" y="0" type="line"/>
+ <point x="744" y="336"/>
+ <point x="1056" y="765"/>
+ <point x="1056" y="1000" type="curve"/>
+ <point x="856" y="1000" type="line"/>
+ <point x="856" y="769"/>
+ <point x="606" y="394"/>
+ <point x="404" y="176" type="curve"/>
+ <point x="421" y="277"/>
+ <point x="429" y="402"/>
+ <point x="429" y="526" type="curve" smooth="yes"/>
+ <point x="429" y="707"/>
+ <point x="412" y="887"/>
+ <point x="380" y="1000" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/input/font-psf-test/source/PsfTest-Italic.ufo/glyphs/L_tnS_mW_.glif b/tests/input/font-psf-test/source/PsfTest-Italic.ufo/glyphs/L_tnS_mW_.glif
new file mode 100644
index 0000000..1daea7c
--- /dev/null
+++ b/tests/input/font-psf-test/source/PsfTest-Italic.ufo/glyphs/L_tnS_mW_.glif
@@ -0,0 +1,50 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmW" format="2">
+ <advance width="1555"/>
+ <unicode hex="0077"/>
+ <anchor x="690" y="-100" name="L"/>
+ <anchor x="990" y="1100" name="U"/>
+ <outline>
+ <contour>
+ <point x="858" y="1000" type="line"/>
+ <point x="743" y="739"/>
+ <point x="588" y="466"/>
+ <point x="388" y="181" type="curve"/>
+ <point x="417" y="339"/>
+ <point x="430" y="500"/>
+ <point x="430" y="644" type="curve" smooth="yes"/>
+ <point x="430" y="784"/>
+ <point x="418" y="908"/>
+ <point x="395" y="1000" type="curve"/>
+ <point x="195" y="1000" type="line"/>
+ <point x="234" y="873"/>
+ <point x="256" y="688"/>
+ <point x="256" y="472" type="curve" smooth="yes"/>
+ <point x="256" y="326"/>
+ <point x="246" y="166"/>
+ <point x="225" y="0" type="curve"/>
+ <point x="425" y="0" type="line"/>
+ <point x="632" y="298"/>
+ <point x="825" y="583"/>
+ <point x="896" y="765" type="curve"/>
+ <point x="920" y="478"/>
+ <point x="912" y="233"/>
+ <point x="915" y="0" type="curve"/>
+ <point x="1115" y="0" type="line"/>
+ <point x="1362" y="330"/>
+ <point x="1642" y="777"/>
+ <point x="1645" y="1000" type="curve"/>
+ <point x="1445" y="1000" type="line"/>
+ <point x="1445" y="990" type="line"/>
+ <point x="1445" y="797"/>
+ <point x="1242" y="417"/>
+ <point x="1063" y="181" type="curve"/>
+ <point x="1064" y="221"/>
+ <point x="1064" y="260"/>
+ <point x="1064" y="298" type="curve" smooth="yes"/>
+ <point x="1064" y="577"/>
+ <point x="1046" y="811"/>
+ <point x="1020" y="1000" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/input/font-psf-test/source/PsfTest-Italic.ufo/glyphs/L_tnS_mX_.glif b/tests/input/font-psf-test/source/PsfTest-Italic.ufo/glyphs/L_tnS_mX_.glif
new file mode 100644
index 0000000..5508ff9
--- /dev/null
+++ b/tests/input/font-psf-test/source/PsfTest-Italic.ufo/glyphs/L_tnS_mX_.glif
@@ -0,0 +1,40 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmX" format="2">
+ <advance width="1009"/>
+ <unicode hex="0078"/>
+ <anchor x="840" y="0" name="H"/>
+ <anchor x="457" y="-100" name="L"/>
+ <anchor x="657" y="1100" name="U"/>
+ <outline>
+ <contour>
+ <point x="945" y="0" type="line"/>
+ <point x="765" y="133"/>
+ <point x="558" y="867"/>
+ <point x="439" y="1000" type="curve"/>
+ <point x="181" y="1000" type="line"/>
+ <point x="410" y="832"/>
+ <point x="578" y="141"/>
+ <point x="698" y="0" type="curve"/>
+ </contour>
+ <contour>
+ <point x="504" y="572" type="line"/>
+ <point x="286" y="463"/>
+ <point x="57" y="230"/>
+ <point x="30" y="0" type="curve"/>
+ <point x="230" y="0" type="line"/>
+ <point x="231" y="156"/>
+ <point x="375" y="380"/>
+ <point x="563" y="467" type="curve"/>
+ </contour>
+ <contour>
+ <point x="659" y="471" type="line"/>
+ <point x="838" y="591"/>
+ <point x="1092" y="798"/>
+ <point x="1099" y="1000" type="curve"/>
+ <point x="889" y="1000" type="line"/>
+ <point x="883" y="842"/>
+ <point x="758" y="675"/>
+ <point x="601" y="581" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/input/font-psf-test/source/PsfTest-Italic.ufo/glyphs/L_tnS_mY_.glif b/tests/input/font-psf-test/source/PsfTest-Italic.ufo/glyphs/L_tnS_mY_.glif
new file mode 100644
index 0000000..b9000c5
--- /dev/null
+++ b/tests/input/font-psf-test/source/PsfTest-Italic.ufo/glyphs/L_tnS_mY_.glif
@@ -0,0 +1,45 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmY" format="2">
+ <advance width="976"/>
+ <unicode hex="0079"/>
+ <anchor x="710" y="-100" name="L"/>
+ <anchor x="1270" y="1000" name="R"/>
+ <anchor x="630" y="1100" name="U"/>
+ <outline>
+ <contour>
+ <point x="132" y="1000" type="line"/>
+ <point x="270" y="825"/>
+ <point x="398" y="406"/>
+ <point x="403" y="-16" type="curve"/>
+ <point x="263" y="-232"/>
+ <point x="145" y="-295"/>
+ <point x="64" y="-295" type="curve" smooth="yes"/>
+ <point x="-2" y="-295"/>
+ <point x="-69" y="-254"/>
+ <point x="-102" y="-220" type="curve"/>
+ <point x="-200" y="-377" type="line"/>
+ <point x="-141" y="-430"/>
+ <point x="-68" y="-465"/>
+ <point x="23" y="-465" type="curve" smooth="yes"/>
+ <point x="193" y="-465"/>
+ <point x="369" y="-371"/>
+ <point x="609" y="0" type="curve" smooth="yes"/>
+ <point x="877" y="414"/>
+ <point x="1056" y="808"/>
+ <point x="1056" y="964" type="curve" smooth="yes"/>
+ <point x="1056" y="978"/>
+ <point x="1055" y="990"/>
+ <point x="1052" y="1000" type="curve"/>
+ <point x="852" y="1000" type="line"/>
+ <point x="856" y="984"/>
+ <point x="858" y="967"/>
+ <point x="858" y="946" type="curve" smooth="yes"/>
+ <point x="858" y="783"/>
+ <point x="722" y="472"/>
+ <point x="548" y="189" type="curve"/>
+ <point x="548" y="484"/>
+ <point x="447" y="866"/>
+ <point x="347" y="1000" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/input/font-psf-test/source/PsfTest-Italic.ufo/glyphs/N_onB_reakingH_yphen.glif b/tests/input/font-psf-test/source/PsfTest-Italic.ufo/glyphs/N_onB_reakingH_yphen.glif
new file mode 100644
index 0000000..e7d9c06
--- /dev/null
+++ b/tests/input/font-psf-test/source/PsfTest-Italic.ufo/glyphs/N_onB_reakingH_yphen.glif
@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="NonBreakingHyphen" format="2">
+ <advance width="840"/>
+ <unicode hex="2011"/>
+ <anchor x="645" y="1100" name="U"/>
+ <outline>
+ <component base="HyphenMinus"/>
+ </outline>
+</glyph>
diff --git a/tests/input/font-psf-test/source/PsfTest-Italic.ufo/glyphs/N_umS_gn.glif b/tests/input/font-psf-test/source/PsfTest-Italic.ufo/glyphs/N_umS_gn.glif
new file mode 100644
index 0000000..b7506f7
--- /dev/null
+++ b/tests/input/font-psf-test/source/PsfTest-Italic.ufo/glyphs/N_umS_gn.glif
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="NumSgn" format="2">
+ <advance width="1180"/>
+ <unicode hex="0023"/>
+ <outline>
+ <contour>
+ <point x="739" y="1333" type="line"/>
+ <point x="91" y="98" type="line"/>
+ <point x="261" y="98" type="line"/>
+ <point x="909" y="1333" type="line"/>
+ </contour>
+ <contour>
+ <point x="80" y="465" type="line"/>
+ <point x="1171" y="465" type="line"/>
+ <point x="1208" y="612" type="line"/>
+ <point x="117" y="612" type="line"/>
+ </contour>
+ <contour>
+ <point x="234" y="843" type="line"/>
+ <point x="1325" y="843" type="line"/>
+ <point x="1361" y="990" type="line"/>
+ <point x="270" y="990" type="line"/>
+ </contour>
+ <contour>
+ <point x="1164" y="1333" type="line"/>
+ <point x="516" y="98" type="line"/>
+ <point x="686" y="98" type="line"/>
+ <point x="1334" y="1333" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/input/font-psf-test/source/PsfTest-Italic.ufo/glyphs/P_ercentS_gn.glif b/tests/input/font-psf-test/source/PsfTest-Italic.ufo/glyphs/P_ercentS_gn.glif
new file mode 100644
index 0000000..84241ea
--- /dev/null
+++ b/tests/input/font-psf-test/source/PsfTest-Italic.ufo/glyphs/P_ercentS_gn.glif
@@ -0,0 +1,93 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="PercentSgn" format="2">
+ <advance width="1506"/>
+ <unicode hex="0025"/>
+ <outline>
+ <contour>
+ <point x="1300" y="349" type="curve" smooth="yes"/>
+ <point x="1255" y="168"/>
+ <point x="1204" y="113"/>
+ <point x="1118" y="113" type="curve" smooth="yes"/>
+ <point x="1056" y="113"/>
+ <point x="1021" y="148"/>
+ <point x="1021" y="235" type="curve" smooth="yes"/>
+ <point x="1021" y="274"/>
+ <point x="1028" y="322"/>
+ <point x="1043" y="383" type="curve" smooth="yes"/>
+ <point x="1088" y="564"/>
+ <point x="1136" y="617"/>
+ <point x="1223" y="617" type="curve" smooth="yes"/>
+ <point x="1286" y="617"/>
+ <point x="1322" y="582"/>
+ <point x="1322" y="496" type="curve" smooth="yes"/>
+ <point x="1322" y="458"/>
+ <point x="1315" y="409"/>
+ </contour>
+ <contour>
+ <point x="1468" y="361" type="curve" smooth="yes"/>
+ <point x="1483" y="419"/>
+ <point x="1489" y="470"/>
+ <point x="1489" y="515" type="curve" smooth="yes"/>
+ <point x="1489" y="677"/>
+ <point x="1400" y="755"/>
+ <point x="1263" y="755" type="curve" smooth="yes"/>
+ <point x="1089" y="755"/>
+ <point x="945" y="647"/>
+ <point x="876" y="371" type="curve" smooth="yes"/>
+ <point x="861" y="310"/>
+ <point x="854" y="256"/>
+ <point x="854" y="210" type="curve" smooth="yes"/>
+ <point x="854" y="47"/>
+ <point x="943" y="-25"/>
+ <point x="1079" y="-25" type="curve" smooth="yes"/>
+ <point x="1254" y="-25"/>
+ <point x="1396" y="72"/>
+ </contour>
+ <contour>
+ <point x="1369" y="1450" type="line"/>
+ <point x="219" y="-25" type="line"/>
+ <point x="397" y="-25" type="line"/>
+ <point x="1545" y="1450" type="line"/>
+ </contour>
+ <contour>
+ <point x="717" y="1044" type="curve" smooth="yes"/>
+ <point x="672" y="864"/>
+ <point x="621" y="809"/>
+ <point x="535" y="809" type="curve" smooth="yes"/>
+ <point x="474" y="809"/>
+ <point x="439" y="844"/>
+ <point x="439" y="930" type="curve" smooth="yes"/>
+ <point x="439" y="969"/>
+ <point x="446" y="1018"/>
+ <point x="461" y="1079" type="curve" smooth="yes"/>
+ <point x="506" y="1260"/>
+ <point x="554" y="1313"/>
+ <point x="641" y="1313" type="curve" smooth="yes"/>
+ <point x="704" y="1313"/>
+ <point x="739" y="1278"/>
+ <point x="739" y="1192" type="curve" smooth="yes"/>
+ <point x="739" y="1153"/>
+ <point x="732" y="1105"/>
+ </contour>
+ <contour>
+ <point x="886" y="1057" type="curve" smooth="yes"/>
+ <point x="900" y="1114"/>
+ <point x="907" y="1166"/>
+ <point x="907" y="1210" type="curve" smooth="yes"/>
+ <point x="907" y="1373"/>
+ <point x="817" y="1450"/>
+ <point x="680" y="1450" type="curve" smooth="yes"/>
+ <point x="506" y="1450"/>
+ <point x="362" y="1343"/>
+ <point x="293" y="1066" type="curve" smooth="yes"/>
+ <point x="278" y="1005"/>
+ <point x="271" y="952"/>
+ <point x="271" y="906" type="curve" smooth="yes"/>
+ <point x="271" y="743"/>
+ <point x="360" y="671"/>
+ <point x="497" y="671" type="curve" smooth="yes"/>
+ <point x="672" y="671"/>
+ <point x="813" y="768"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/input/font-psf-test/source/PsfTest-Italic.ufo/glyphs/P_lusS_gn.glif b/tests/input/font-psf-test/source/PsfTest-Italic.ufo/glyphs/P_lusS_gn.glif
new file mode 100644
index 0000000..8c4577e
--- /dev/null
+++ b/tests/input/font-psf-test/source/PsfTest-Italic.ufo/glyphs/P_lusS_gn.glif
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="PlusSgn" format="2">
+ <advance width="1180"/>
+ <unicode hex="002B"/>
+ <outline>
+ <contour>
+ <point x="748" y="1156" type="line"/>
+ <point x="529" y="279" type="line"/>
+ <point x="684" y="279" type="line"/>
+ <point x="903" y="1156" type="line"/>
+ </contour>
+ <contour>
+ <point x="256" y="647" type="line"/>
+ <point x="1146" y="647" type="line"/>
+ <point x="1182" y="794" type="line"/>
+ <point x="292" y="794" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/input/font-psf-test/source/PsfTest-Italic.ufo/glyphs/Q_stnM_rk.glif b/tests/input/font-psf-test/source/PsfTest-Italic.ufo/glyphs/Q_stnM_rk.glif
new file mode 100644
index 0000000..8b14a6c
--- /dev/null
+++ b/tests/input/font-psf-test/source/PsfTest-Italic.ufo/glyphs/Q_stnM_rk.glif
@@ -0,0 +1,49 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="QstnMrk" format="2">
+ <advance width="1030"/>
+ <unicode hex="003F"/>
+ <outline>
+ <contour>
+ <point x="419" y="1226" type="line"/>
+ <point x="514" y="1303"/>
+ <point x="615" y="1338"/>
+ <point x="685" y="1338" type="curve" smooth="yes"/>
+ <point x="800" y="1338"/>
+ <point x="858" y="1294"/>
+ <point x="858" y="1222" type="curve" smooth="yes"/>
+ <point x="858" y="1122"/>
+ <point x="713" y="1017"/>
+ <point x="654" y="960" type="curve" smooth="yes"/>
+ <point x="538" y="850"/>
+ <point x="473" y="715"/>
+ <point x="402" y="431" type="curve"/>
+ <point x="587" y="431" type="line"/>
+ <point x="656" y="707"/>
+ <point x="697" y="778"/>
+ <point x="831" y="901" type="curve" smooth="yes"/>
+ <point x="949" y="1010"/>
+ <point x="1072" y="1146"/>
+ <point x="1072" y="1272" type="curve" smooth="yes"/>
+ <point x="1072" y="1409"/>
+ <point x="947" y="1509"/>
+ <point x="746" y="1509" type="curve" smooth="yes"/>
+ <point x="631" y="1509"/>
+ <point x="500" y="1463"/>
+ <point x="419" y="1401" type="curve"/>
+ </contour>
+ <contour>
+ <point x="278" y="90" type="curve" smooth="yes"/>
+ <point x="278" y="28"/>
+ <point x="328" y="-25"/>
+ <point x="393" y="-25" type="curve" smooth="yes"/>
+ <point x="477" y="-25"/>
+ <point x="554" y="45"/>
+ <point x="554" y="125" type="curve" smooth="yes"/>
+ <point x="554" y="186"/>
+ <point x="504" y="240"/>
+ <point x="439" y="240" type="curve" smooth="yes"/>
+ <point x="355" y="240"/>
+ <point x="278" y="170"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/input/font-psf-test/source/PsfTest-Italic.ufo/glyphs/Q_uotM_rk.glif b/tests/input/font-psf-test/source/PsfTest-Italic.ufo/glyphs/Q_uotM_rk.glif
new file mode 100644
index 0000000..4a8357b
--- /dev/null
+++ b/tests/input/font-psf-test/source/PsfTest-Italic.ufo/glyphs/Q_uotM_rk.glif
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="QuotMrk" format="2">
+ <advance width="1005"/>
+ <unicode hex="0022"/>
+ <outline>
+ <contour>
+ <point x="600" y="1024" type="line"/>
+ <point x="639" y="1162"/>
+ <point x="683" y="1312"/>
+ <point x="772" y="1553" type="curve"/>
+ <point x="567" y="1553" type="line"/>
+ <point x="538" y="1312"/>
+ <point x="505" y="1162"/>
+ <point x="475" y="1024" type="curve"/>
+ </contour>
+ <contour>
+ <point x="940" y="1024" type="line"/>
+ <point x="979" y="1162"/>
+ <point x="1023" y="1312"/>
+ <point x="1112" y="1553" type="curve"/>
+ <point x="907" y="1553" type="line"/>
+ <point x="878" y="1312"/>
+ <point x="845" y="1162"/>
+ <point x="815" y="1024" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/input/font-psf-test/source/PsfTest-Italic.ufo/glyphs/R_everseS_olidus.glif b/tests/input/font-psf-test/source/PsfTest-Italic.ufo/glyphs/R_everseS_olidus.glif
new file mode 100644
index 0000000..f146267
--- /dev/null
+++ b/tests/input/font-psf-test/source/PsfTest-Italic.ufo/glyphs/R_everseS_olidus.glif
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="ReverseSolidus" format="2">
+ <advance width="1005"/>
+ <unicode hex="005C"/>
+ <outline>
+ <contour>
+ <point x="473" y="1538" type="line"/>
+ <point x="656" y="-123" type="line"/>
+ <point x="799" y="-93" type="line"/>
+ <point x="620" y="1568" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/input/font-psf-test/source/PsfTest-Italic.ufo/glyphs/R_tC_urlyB_rac.glif b/tests/input/font-psf-test/source/PsfTest-Italic.ufo/glyphs/R_tC_urlyB_rac.glif
new file mode 100644
index 0000000..82df531
--- /dev/null
+++ b/tests/input/font-psf-test/source/PsfTest-Italic.ufo/glyphs/R_tC_urlyB_rac.glif
@@ -0,0 +1,50 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="RtCurlyBrac" format="2">
+ <advance width="980"/>
+ <unicode hex="007D"/>
+ <outline>
+ <contour>
+ <point x="466" y="1470" type="line"/>
+ <point x="513" y="1452"/>
+ <point x="653" y="1397"/>
+ <point x="653" y="1366" type="curve" smooth="yes"/>
+ <point x="653" y="1238"/>
+ <point x="531" y="801"/>
+ <point x="531" y="737" type="curve" smooth="yes"/>
+ <point x="531" y="701"/>
+ <point x="660" y="627"/>
+ <point x="660" y="603" type="curve" smooth="yes"/>
+ <point x="660" y="585"/>
+ <point x="496" y="511"/>
+ <point x="468" y="475" type="curve" smooth="yes"/>
+ <point x="439" y="438"/>
+ <point x="312" y="-121"/>
+ <point x="268" y="-167" type="curve" smooth="yes"/>
+ <point x="241" y="-194"/>
+ <point x="106" y="-242"/>
+ <point x="33" y="-265" type="curve"/>
+ <point x="39" y="-402" type="line"/>
+ <point x="150" y="-375"/>
+ <point x="324" y="-323"/>
+ <point x="375" y="-279" type="curve" smooth="yes"/>
+ <point x="465" y="-201"/>
+ <point x="608" y="410"/>
+ <point x="639" y="441" type="curve" smooth="yes"/>
+ <point x="675" y="476"/>
+ <point x="880" y="571"/>
+ <point x="880" y="607" type="curve" smooth="yes"/>
+ <point x="880" y="639"/>
+ <point x="719" y="740"/>
+ <point x="719" y="771" type="curve" smooth="yes"/>
+ <point x="719" y="839"/>
+ <point x="825" y="1259"/>
+ <point x="825" y="1425" type="curve" smooth="yes"/>
+ <point x="825" y="1453"/>
+ <point x="822" y="1474"/>
+ <point x="815" y="1485" type="curve" smooth="yes"/>
+ <point x="786" y="1529"/>
+ <point x="638" y="1581"/>
+ <point x="540" y="1607" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/input/font-psf-test/source/PsfTest-Italic.ufo/glyphs/R_tP_aren.glif b/tests/input/font-psf-test/source/PsfTest-Italic.ufo/glyphs/R_tP_aren.glif
new file mode 100644
index 0000000..3950e09
--- /dev/null
+++ b/tests/input/font-psf-test/source/PsfTest-Italic.ufo/glyphs/R_tP_aren.glif
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="RtParen" format="2">
+ <advance width="775"/>
+ <unicode hex="0029"/>
+ <outline>
+ <contour>
+ <point x="467" y="1455" type="line"/>
+ <point x="578" y="1327"/>
+ <point x="628" y="1146"/>
+ <point x="628" y="946" type="curve" smooth="yes"/>
+ <point x="628" y="832"/>
+ <point x="612" y="713"/>
+ <point x="582" y="593" type="curve" smooth="yes"/>
+ <point x="497" y="252"/>
+ <point x="328" y="-8"/>
+ <point x="40" y="-260" type="curve"/>
+ <point x="99" y="-402" type="line"/>
+ <point x="444" y="-123"/>
+ <point x="673" y="194"/>
+ <point x="772" y="593" type="curve" smooth="yes"/>
+ <point x="804" y="719"/>
+ <point x="819" y="843"/>
+ <point x="819" y="959" type="curve" smooth="yes"/>
+ <point x="819" y="1236"/>
+ <point x="733" y="1472"/>
+ <point x="580" y="1607" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/input/font-psf-test/source/PsfTest-Italic.ufo/glyphs/R_tS_qrB_rac.glif b/tests/input/font-psf-test/source/PsfTest-Italic.ufo/glyphs/R_tS_qrB_rac.glif
new file mode 100644
index 0000000..4c13a82
--- /dev/null
+++ b/tests/input/font-psf-test/source/PsfTest-Italic.ufo/glyphs/R_tS_qrB_rac.glif
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="RtSqrBrac" format="2">
+ <advance width="770"/>
+ <unicode hex="005D"/>
+ <outline>
+ <contour>
+ <point x="434" y="-402" type="line"/>
+ <point x="920" y="1568" type="line"/>
+ <point x="480" y="1568" type="line"/>
+ <point x="444" y="1421" type="line"/>
+ <point x="699" y="1421" type="line"/>
+ <point x="286" y="-255" type="line"/>
+ <point x="31" y="-255" type="line"/>
+ <point x="-6" y="-402" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/input/font-psf-test/source/PsfTest-Italic.ufo/glyphs/S_emicolon.glif b/tests/input/font-psf-test/source/PsfTest-Italic.ufo/glyphs/S_emicolon.glif
new file mode 100644
index 0000000..be971ac
--- /dev/null
+++ b/tests/input/font-psf-test/source/PsfTest-Italic.ufo/glyphs/S_emicolon.glif
@@ -0,0 +1,38 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="Semicolon" format="2">
+ <advance width="630"/>
+ <unicode hex="003B"/>
+ <outline>
+ <contour>
+ <point x="314" y="758" type="curve" smooth="yes"/>
+ <point x="314" y="696"/>
+ <point x="365" y="642"/>
+ <point x="430" y="642" type="curve" smooth="yes"/>
+ <point x="514" y="642"/>
+ <point x="590" y="712"/>
+ <point x="590" y="792" type="curve" smooth="yes"/>
+ <point x="590" y="854"/>
+ <point x="540" y="907"/>
+ <point x="476" y="907" type="curve" smooth="yes"/>
+ <point x="393" y="907"/>
+ <point x="314" y="837"/>
+ </contour>
+ <contour>
+ <point x="137" y="49" type="line"/>
+ <point x="277" y="49" type="line"/>
+ <point x="252" y="-50"/>
+ <point x="145" y="-169"/>
+ <point x="73" y="-225" type="curve"/>
+ <point x="163" y="-265" type="line"/>
+ <point x="280" y="-175"/>
+ <point x="431" y="-28"/>
+ <point x="431" y="118" type="curve" smooth="yes"/>
+ <point x="431" y="193"/>
+ <point x="378" y="245"/>
+ <point x="311" y="245" type="curve" smooth="yes"/>
+ <point x="254" y="245"/>
+ <point x="190" y="209"/>
+ <point x="161" y="147" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/input/font-psf-test/source/PsfTest-Italic.ufo/glyphs/S_olidus.glif b/tests/input/font-psf-test/source/PsfTest-Italic.ufo/glyphs/S_olidus.glif
new file mode 100644
index 0000000..589697b
--- /dev/null
+++ b/tests/input/font-psf-test/source/PsfTest-Italic.ufo/glyphs/S_olidus.glif
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="Solidus" format="2">
+ <advance width="980"/>
+ <unicode hex="002F"/>
+ <outline>
+ <contour>
+ <point x="1160" y="1568" type="line"/>
+ <point x="-119" y="-240" type="line"/>
+ <point x="50" y="-240" type="line"/>
+ <point x="1330" y="1568" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/input/font-psf-test/source/PsfTest-Italic.ufo/glyphs/S_pace.glif b/tests/input/font-psf-test/source/PsfTest-Italic.ufo/glyphs/S_pace.glif
new file mode 100644
index 0000000..c49f0f2
--- /dev/null
+++ b/tests/input/font-psf-test/source/PsfTest-Italic.ufo/glyphs/S_pace.glif
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="Space" format="2">
+ <advance width="530"/>
+ <unicode hex="0020"/>
+ <outline/>
+</glyph>
diff --git a/tests/input/font-psf-test/source/PsfTest-Italic.ufo/glyphs/T_ilde.glif b/tests/input/font-psf-test/source/PsfTest-Italic.ufo/glyphs/T_ilde.glif
new file mode 100644
index 0000000..bf260b8
--- /dev/null
+++ b/tests/input/font-psf-test/source/PsfTest-Italic.ufo/glyphs/T_ilde.glif
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="Tilde" format="2">
+ <advance width="1095"/>
+ <unicode hex="007E"/>
+ <outline>
+ <contour>
+ <point x="156" y="368" type="line"/>
+ <point x="173" y="416"/>
+ <point x="215" y="456"/>
+ <point x="293" y="456" type="curve" smooth="yes"/>
+ <point x="468" y="456"/>
+ <point x="643" y="353"/>
+ <point x="873" y="353" type="curve" smooth="yes"/>
+ <point x="1032" y="353"/>
+ <point x="1137" y="472"/>
+ <point x="1169" y="598" type="curve"/>
+ <point x="1064" y="598" type="line"/>
+ <point x="1045" y="553"/>
+ <point x="1002" y="500"/>
+ <point x="919" y="500" type="curve" smooth="yes"/>
+ <point x="683" y="500"/>
+ <point x="551" y="603"/>
+ <point x="330" y="603" type="curve" smooth="yes"/>
+ <point x="184" y="603"/>
+ <point x="81" y="487"/>
+ <point x="51" y="368" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/input/font-psf-test/source/PsfTest-Italic.ufo/glyphs/V_ertL_ine.glif b/tests/input/font-psf-test/source/PsfTest-Italic.ufo/glyphs/V_ertL_ine.glif
new file mode 100644
index 0000000..445d622
--- /dev/null
+++ b/tests/input/font-psf-test/source/PsfTest-Italic.ufo/glyphs/V_ertL_ine.glif
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="VertLine" format="2">
+ <advance width="670"/>
+ <unicode hex="007C"/>
+ <outline>
+ <contour>
+ <point x="602" y="1578" type="line"/>
+ <point x="112" y="-392" type="line"/>
+ <point x="262" y="-392" type="line"/>
+ <point x="752" y="1578" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/input/font-psf-test/source/PsfTest-Italic.ufo/glyphs/_notdef.glif b/tests/input/font-psf-test/source/PsfTest-Italic.ufo/glyphs/_notdef.glif
new file mode 100644
index 0000000..a3e9354
--- /dev/null
+++ b/tests/input/font-psf-test/source/PsfTest-Italic.ufo/glyphs/_notdef.glif
@@ -0,0 +1,18 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name=".notdef" format="2">
+ <advance width="1400"/>
+ <outline>
+ <contour>
+ <point x="100" y="0" type="line"/>
+ <point x="1300" y="0" type="line"/>
+ <point x="1300" y="1800" type="line"/>
+ <point x="100" y="1800" type="line"/>
+ </contour>
+ <contour>
+ <point x="150" y="1750" type="line"/>
+ <point x="1250" y="1750" type="line"/>
+ <point x="1250" y="50" type="line"/>
+ <point x="150" y="50" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/input/font-psf-test/source/PsfTest-Italic.ufo/glyphs/_null.glif b/tests/input/font-psf-test/source/PsfTest-Italic.ufo/glyphs/_null.glif
new file mode 100644
index 0000000..0b9caa6
--- /dev/null
+++ b/tests/input/font-psf-test/source/PsfTest-Italic.ufo/glyphs/_null.glif
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name=".null" format="2">
+ <outline/>
+</glyph>
diff --git a/tests/input/font-psf-test/source/PsfTest-Italic.ufo/glyphs/contents.plist b/tests/input/font-psf-test/source/PsfTest-Italic.ufo/glyphs/contents.plist
new file mode 100644
index 0000000..ad2aa41
--- /dev/null
+++ b/tests/input/font-psf-test/source/PsfTest-Italic.ufo/glyphs/contents.plist
@@ -0,0 +1,232 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+ <key>.notdef</key>
+ <string>_notdef.glif</string>
+ <key>.null</key>
+ <string>_null.glif</string>
+ <key>Ampersand</key>
+ <string>A_mpersand.glif</string>
+ <key>Apos</key>
+ <string>A_pos.glif</string>
+ <key>Asterisk</key>
+ <string>A_sterisk.glif</string>
+ <key>AtSgn</key>
+ <string>A_tS_gn.glif</string>
+ <key>CircumAccent</key>
+ <string>C_ircumA_ccent.glif</string>
+ <key>Colon</key>
+ <string>C_olon.glif</string>
+ <key>CombAcute</key>
+ <string>C_ombA_cute.glif</string>
+ <key>CombCircum</key>
+ <string>C_ombC_ircum.glif</string>
+ <key>CombDiaer</key>
+ <string>C_ombD_iaer.glif</string>
+ <key>CombGrave</key>
+ <string>C_ombG_rave.glif</string>
+ <key>CombRingAbv</key>
+ <string>C_ombR_ingA_bv.glif</string>
+ <key>CombTilde</key>
+ <string>C_ombT_ilde.glif</string>
+ <key>Comma</key>
+ <string>C_omma.glif</string>
+ <key>DigitEight</key>
+ <string>D_igitE_ight.glif</string>
+ <key>DigitFive</key>
+ <string>D_igitF_ive.glif</string>
+ <key>DigitFour</key>
+ <string>D_igitF_our.glif</string>
+ <key>DigitNine</key>
+ <string>D_igitN_ine.glif</string>
+ <key>DigitOne</key>
+ <string>D_igitO_ne.glif</string>
+ <key>DigitSeven</key>
+ <string>D_igitS_even.glif</string>
+ <key>DigitSix</key>
+ <string>D_igitS_ix.glif</string>
+ <key>DigitThree</key>
+ <string>D_igitT_hree.glif</string>
+ <key>DigitTwo</key>
+ <string>D_igitT_wo.glif</string>
+ <key>DigitZero</key>
+ <string>D_igitZ_ero.glif</string>
+ <key>DollarSgn</key>
+ <string>D_ollarS_gn.glif</string>
+ <key>DottedCirc</key>
+ <string>D_ottedC_irc.glif</string>
+ <key>EqSgn</key>
+ <string>E_qS_gn.glif</string>
+ <key>ExclamationMrk</key>
+ <string>E_xclamationM_rk.glif</string>
+ <key>FullStop</key>
+ <string>F_ullS_top.glif</string>
+ <key>GTSgn</key>
+ <string>G_T_S_gn.glif</string>
+ <key>GraveAccent</key>
+ <string>G_raveA_ccent.glif</string>
+ <key>Hyphen</key>
+ <string>H_yphen.glif</string>
+ <key>HyphenMinus</key>
+ <string>H_yphenM_inus.glif</string>
+ <key>Hyphen_Soft</key>
+ <string>H_yphen_S_oft.glif</string>
+ <key>LTSgn</key>
+ <string>L_T_S_gn.glif</string>
+ <key>LftCurlyBrac</key>
+ <string>L_ftC_urlyB_rac.glif</string>
+ <key>LftParen</key>
+ <string>L_ftP_aren.glif</string>
+ <key>LftSqrBrac</key>
+ <string>L_ftS_qrB_rac.glif</string>
+ <key>LowLine</key>
+ <string>L_owL_ine.glif</string>
+ <key>LtnCapA</key>
+ <string>L_tnC_apA_.glif</string>
+ <key>LtnCapADiaer</key>
+ <string>L_tnC_apA_D_iaer.glif</string>
+ <key>LtnCapB</key>
+ <string>L_tnC_apB_.glif</string>
+ <key>LtnCapC</key>
+ <string>L_tnC_apC_.glif</string>
+ <key>LtnCapD</key>
+ <string>L_tnC_apD_.glif</string>
+ <key>LtnCapE</key>
+ <string>L_tnC_apE_.glif</string>
+ <key>LtnCapF</key>
+ <string>L_tnC_apF_.glif</string>
+ <key>LtnCapG</key>
+ <string>L_tnC_apG_.glif</string>
+ <key>LtnCapH</key>
+ <string>L_tnC_apH_.glif</string>
+ <key>LtnCapI</key>
+ <string>L_tnC_apI_.glif</string>
+ <key>LtnCapJ</key>
+ <string>L_tnC_apJ_.glif</string>
+ <key>LtnCapK</key>
+ <string>L_tnC_apK_.glif</string>
+ <key>LtnCapL</key>
+ <string>L_tnC_apL_.glif</string>
+ <key>LtnCapM</key>
+ <string>L_tnC_apM_.glif</string>
+ <key>LtnCapN</key>
+ <string>L_tnC_apN_.glif</string>
+ <key>LtnCapO</key>
+ <string>L_tnC_apO_.glif</string>
+ <key>LtnCapP</key>
+ <string>L_tnC_apP_.glif</string>
+ <key>LtnCapQ</key>
+ <string>L_tnC_apQ_.glif</string>
+ <key>LtnCapR</key>
+ <string>L_tnC_apR_.glif</string>
+ <key>LtnCapS</key>
+ <string>L_tnC_apS_.glif</string>
+ <key>LtnCapT</key>
+ <string>L_tnC_apT_.glif</string>
+ <key>LtnCapU</key>
+ <string>L_tnC_apU_.glif</string>
+ <key>LtnCapV</key>
+ <string>L_tnC_apV_.glif</string>
+ <key>LtnCapW</key>
+ <string>L_tnC_apW_.glif</string>
+ <key>LtnCapX</key>
+ <string>L_tnC_apX_.glif</string>
+ <key>LtnCapY</key>
+ <string>L_tnC_apY_.glif</string>
+ <key>LtnSmA</key>
+ <string>L_tnS_mA_.glif</string>
+ <key>LtnSmAAcute</key>
+ <string>L_tnS_mA_A_cute.glif</string>
+ <key>LtnSmACircum</key>
+ <string>L_tnS_mA_C_ircum.glif</string>
+ <key>LtnSmADiaer</key>
+ <string>L_tnS_mA_D_iaer.glif</string>
+ <key>LtnSmAGrave</key>
+ <string>L_tnS_mA_G_rave.glif</string>
+ <key>LtnSmARingAbv</key>
+ <string>L_tnS_mA_R_ingA_bv.glif</string>
+ <key>LtnSmATilde</key>
+ <string>L_tnS_mA_T_ilde.glif</string>
+ <key>LtnSmB</key>
+ <string>L_tnS_mB_.glif</string>
+ <key>LtnSmC</key>
+ <string>L_tnS_mC_.glif</string>
+ <key>LtnSmD</key>
+ <string>L_tnS_mD_.glif</string>
+ <key>LtnSmE</key>
+ <string>L_tnS_mE_.glif</string>
+ <key>LtnSmF</key>
+ <string>L_tnS_mF_.glif</string>
+ <key>LtnSmG</key>
+ <string>L_tnS_mG_.glif</string>
+ <key>LtnSmH</key>
+ <string>L_tnS_mH_.glif</string>
+ <key>LtnSmI</key>
+ <string>L_tnS_mI_.glif</string>
+ <key>LtnSmJ</key>
+ <string>L_tnS_mJ_.glif</string>
+ <key>LtnSmK</key>
+ <string>L_tnS_mK_.glif</string>
+ <key>LtnSmL</key>
+ <string>L_tnS_mL_.glif</string>
+ <key>LtnSmM</key>
+ <string>L_tnS_mM_.glif</string>
+ <key>LtnSmN</key>
+ <string>L_tnS_mN_.glif</string>
+ <key>LtnSmO</key>
+ <string>L_tnS_mO_.glif</string>
+ <key>LtnSmP</key>
+ <string>L_tnS_mP_.glif</string>
+ <key>LtnSmQ</key>
+ <string>L_tnS_mQ_.glif</string>
+ <key>LtnSmR</key>
+ <string>L_tnS_mR_.glif</string>
+ <key>LtnSmS</key>
+ <string>L_tnS_mS_.glif</string>
+ <key>LtnSmT</key>
+ <string>L_tnS_mT_.glif</string>
+ <key>LtnSmU</key>
+ <string>L_tnS_mU_.glif</string>
+ <key>LtnSmV</key>
+ <string>L_tnS_mV_.glif</string>
+ <key>LtnSmW</key>
+ <string>L_tnS_mW_.glif</string>
+ <key>LtnSmX</key>
+ <string>L_tnS_mX_.glif</string>
+ <key>LtnSmY</key>
+ <string>L_tnS_mY_.glif</string>
+ <key>NonBreakingHyphen</key>
+ <string>N_onB_reakingH_yphen.glif</string>
+ <key>NumSgn</key>
+ <string>N_umS_gn.glif</string>
+ <key>PercentSgn</key>
+ <string>P_ercentS_gn.glif</string>
+ <key>PlusSgn</key>
+ <string>P_lusS_gn.glif</string>
+ <key>QstnMrk</key>
+ <string>Q_stnM_rk.glif</string>
+ <key>QuotMrk</key>
+ <string>Q_uotM_rk.glif</string>
+ <key>ReverseSolidus</key>
+ <string>R_everseS_olidus.glif</string>
+ <key>RtCurlyBrac</key>
+ <string>R_tC_urlyB_rac.glif</string>
+ <key>RtParen</key>
+ <string>R_tP_aren.glif</string>
+ <key>RtSqrBrac</key>
+ <string>R_tS_qrB_rac.glif</string>
+ <key>Semicolon</key>
+ <string>S_emicolon.glif</string>
+ <key>Solidus</key>
+ <string>S_olidus.glif</string>
+ <key>Space</key>
+ <string>S_pace.glif</string>
+ <key>Tilde</key>
+ <string>T_ilde.glif</string>
+ <key>VertLine</key>
+ <string>V_ertL_ine.glif</string>
+ <key>nonmarkingreturn</key>
+ <string>nonmarkingreturn.glif</string>
+</dict>
+</plist>
diff --git a/tests/input/font-psf-test/source/PsfTest-Italic.ufo/glyphs/nonmarkingreturn.glif b/tests/input/font-psf-test/source/PsfTest-Italic.ufo/glyphs/nonmarkingreturn.glif
new file mode 100644
index 0000000..9a63f06
--- /dev/null
+++ b/tests/input/font-psf-test/source/PsfTest-Italic.ufo/glyphs/nonmarkingreturn.glif
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="nonmarkingreturn" format="2">
+ <advance width="1004"/>
+ <outline/>
+</glyph>
diff --git a/tests/input/font-psf-test/source/PsfTest-Italic.ufo/layercontents.plist b/tests/input/font-psf-test/source/PsfTest-Italic.ufo/layercontents.plist
new file mode 100644
index 0000000..42b7482
--- /dev/null
+++ b/tests/input/font-psf-test/source/PsfTest-Italic.ufo/layercontents.plist
@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<array>
+ <array>
+ <string>public.default</string>
+ <string>glyphs</string>
+ </array>
+</array>
+</plist>
diff --git a/tests/input/font-psf-test/source/PsfTest-Italic.ufo/lib.plist b/tests/input/font-psf-test/source/PsfTest-Italic.ufo/lib.plist
new file mode 100644
index 0000000..43413a8
--- /dev/null
+++ b/tests/input/font-psf-test/source/PsfTest-Italic.ufo/lib.plist
@@ -0,0 +1,538 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+ <key>com.schriftgestaltung.Glyphs.fontUserData</key>
+ <dict/>
+ <key>com.schriftgestaltung.appVersion</key>
+ <string>1161</string>
+ <key>com.schriftgestaltung.customName</key>
+ <string>Italic</string>
+ <key>com.schriftgestaltung.customParameter.GSFont.DisplayStrings</key>
+ <string/>
+ <key>com.schriftgestaltung.customParameter.GSFont.disablesAutomaticAlignment</key>
+ <true/>
+ <key>com.schriftgestaltung.customParameter.GSFont.disablesLastChange</key>
+ <true/>
+ <key>com.schriftgestaltung.customParameter.GSFont.useNiceNames</key>
+ <integer>0</integer>
+ <key>com.schriftgestaltung.customParameter.GSFontMaster.customValue</key>
+ <integer>0</integer>
+ <key>com.schriftgestaltung.customParameter.GSFontMaster.customValue1</key>
+ <integer>0</integer>
+ <key>com.schriftgestaltung.customParameter.GSFontMaster.customValue2</key>
+ <integer>0</integer>
+ <key>com.schriftgestaltung.customParameter.GSFontMaster.customValue3</key>
+ <integer>0</integer>
+ <key>com.schriftgestaltung.customParameter.GSFontMaster.iconName</key>
+ <string/>
+ <key>com.schriftgestaltung.customParameter.GSFontMaster.weightValue</key>
+ <integer>400</integer>
+ <key>com.schriftgestaltung.customParameter.GSFontMaster.widthValue</key>
+ <integer>100</integer>
+ <key>com.schriftgestaltung.disablesAutomaticAlignment</key>
+ <true/>
+ <key>com.schriftgestaltung.disablesLastChange</key>
+ <true/>
+ <key>com.schriftgestaltung.fontMasterOrder</key>
+ <integer>0</integer>
+ <key>com.schriftgestaltung.glyphOrder</key>
+ <array>
+ <string>.notdef</string>
+ <string>.null</string>
+ <string>nonmarkingreturn</string>
+ <string>Space</string>
+ <string>ExclamationMrk</string>
+ <string>QuotMrk</string>
+ <string>NumSgn</string>
+ <string>DollarSgn</string>
+ <string>PercentSgn</string>
+ <string>Ampersand</string>
+ <string>Apos</string>
+ <string>LftParen</string>
+ <string>RtParen</string>
+ <string>Asterisk</string>
+ <string>PlusSgn</string>
+ <string>Comma</string>
+ <string>HyphenMinus</string>
+ <string>FullStop</string>
+ <string>Solidus</string>
+ <string>DigitZero</string>
+ <string>DigitOne</string>
+ <string>DigitTwo</string>
+ <string>DigitThree</string>
+ <string>DigitFour</string>
+ <string>DigitFive</string>
+ <string>DigitSix</string>
+ <string>DigitSeven</string>
+ <string>DigitEight</string>
+ <string>DigitNine</string>
+ <string>Colon</string>
+ <string>Semicolon</string>
+ <string>LTSgn</string>
+ <string>EqSgn</string>
+ <string>GTSgn</string>
+ <string>QstnMrk</string>
+ <string>AtSgn</string>
+ <string>LtnCapA</string>
+ <string>LtnCapA.alt</string>
+ <string>LtnCapB</string>
+ <string>LtnCapC</string>
+ <string>LtnCapD</string>
+ <string>LtnCapE</string>
+ <string>LtnCapF</string>
+ <string>LtnCapG</string>
+ <string>LtnCapH</string>
+ <string>LtnCapI</string>
+ <string>LtnCapJ</string>
+ <string>LtnCapK</string>
+ <string>LtnCapL</string>
+ <string>LtnCapM</string>
+ <string>LtnCapN</string>
+ <string>LtnCapO</string>
+ <string>LtnCapP</string>
+ <string>LtnCapQ</string>
+ <string>LtnCapR</string>
+ <string>LtnCapS</string>
+ <string>LtnCapT</string>
+ <string>LtnCapU</string>
+ <string>LtnCapV</string>
+ <string>LtnCapW</string>
+ <string>LtnCapX</string>
+ <string>LtnCapY</string>
+ <string>LftSqrBrac</string>
+ <string>ReverseSolidus</string>
+ <string>RtSqrBrac</string>
+ <string>CircumAccent</string>
+ <string>LowLine</string>
+ <string>GraveAccent</string>
+ <string>LtnSmA</string>
+ <string>LtnSmB</string>
+ <string>LtnSmC</string>
+ <string>LtnSmD</string>
+ <string>LtnSmE</string>
+ <string>LtnSmF</string>
+ <string>LtnSmG</string>
+ <string>LtnSmH</string>
+ <string>LtnSmI</string>
+ <string>LtnSmJ</string>
+ <string>LtnSmK</string>
+ <string>LtnSmL</string>
+ <string>LtnSmM</string>
+ <string>LtnSmN</string>
+ <string>LtnSmO</string>
+ <string>LtnSmP</string>
+ <string>LtnSmQ</string>
+ <string>LtnSmR</string>
+ <string>LtnSmS</string>
+ <string>LtnSmT</string>
+ <string>LtnSmU</string>
+ <string>LtnSmV</string>
+ <string>LtnSmW</string>
+ <string>LtnSmX</string>
+ <string>LtnSmY</string>
+ <string>LftCurlyBrac</string>
+ <string>VertLine</string>
+ <string>RtCurlyBrac</string>
+ <string>Tilde</string>
+ <string>LtnCapADiaer</string>
+ <string>LtnSmAAcute</string>
+ <string>LtnSmAGrave</string>
+ <string>LtnSmACircum</string>
+ <string>LtnSmADiaer</string>
+ <string>LtnSmATilde</string>
+ <string>LtnSmARingAbv</string>
+ <string>DottedCirc</string>
+ <string>Hyphen</string>
+ <string>NonBreakingHyphen</string>
+ <string>Hyphen_Soft</string>
+ <string>CombAcute</string>
+ <string>CombGrave</string>
+ <string>CombCircum</string>
+ <string>CombTilde</string>
+ <string>CombDiaer</string>
+ <string>CombRingAbv</string>
+ </array>
+ <key>com.schriftgestaltung.keyboardIncrement</key>
+ <integer>1</integer>
+ <key>com.schriftgestaltung.weight</key>
+ <string>Regular</string>
+ <key>com.schriftgestaltung.weightValue</key>
+ <integer>400</integer>
+ <key>com.schriftgestaltung.width</key>
+ <string>Regular</string>
+ <key>com.schriftgestaltung.widthValue</key>
+ <integer>100</integer>
+ <key>org.sil.lcg.toneLetters</key>
+ <dict>
+ <key>contourWidth</key>
+ <integer>480</integer>
+ <key>dotSize</key>
+ <integer>180</integer>
+ <key>dotSpacing</key>
+ <integer>200</integer>
+ <key>glyphDepth</key>
+ <integer>-25</integer>
+ <key>glyphHeight</key>
+ <integer>1600</integer>
+ <key>italicAngle</key>
+ <integer>14</integer>
+ <key>marginDotLeft</key>
+ <integer>120</integer>
+ <key>marginDotRight</key>
+ <integer>160</integer>
+ <key>marginFlatLeft</key>
+ <integer>120</integer>
+ <key>marginFlatRight</key>
+ <integer>160</integer>
+ <key>marginPointLeft</key>
+ <integer>100</integer>
+ <key>marginPointRight</key>
+ <integer>140</integer>
+ <key>strokeThickness</key>
+ <integer>120</integer>
+ </dict>
+ <key>public.glyphOrder</key>
+ <array>
+ <string>.notdef</string>
+ <string>.null</string>
+ <string>nonmarkingreturn</string>
+ <string>Space</string>
+ <string>ExclamationMrk</string>
+ <string>QuotMrk</string>
+ <string>NumSgn</string>
+ <string>DollarSgn</string>
+ <string>PercentSgn</string>
+ <string>Ampersand</string>
+ <string>Apos</string>
+ <string>LftParen</string>
+ <string>RtParen</string>
+ <string>Asterisk</string>
+ <string>PlusSgn</string>
+ <string>Comma</string>
+ <string>HyphenMinus</string>
+ <string>FullStop</string>
+ <string>Solidus</string>
+ <string>DigitZero</string>
+ <string>DigitOne</string>
+ <string>DigitTwo</string>
+ <string>DigitThree</string>
+ <string>DigitFour</string>
+ <string>DigitFive</string>
+ <string>DigitSix</string>
+ <string>DigitSeven</string>
+ <string>DigitEight</string>
+ <string>DigitNine</string>
+ <string>Colon</string>
+ <string>Semicolon</string>
+ <string>LTSgn</string>
+ <string>EqSgn</string>
+ <string>GTSgn</string>
+ <string>QstnMrk</string>
+ <string>AtSgn</string>
+ <string>LtnCapA</string>
+ <string>LtnCapA.alt</string>
+ <string>LtnCapB</string>
+ <string>LtnCapC</string>
+ <string>LtnCapD</string>
+ <string>LtnCapE</string>
+ <string>LtnCapF</string>
+ <string>LtnCapG</string>
+ <string>LtnCapH</string>
+ <string>LtnCapI</string>
+ <string>LtnCapJ</string>
+ <string>LtnCapK</string>
+ <string>LtnCapL</string>
+ <string>LtnCapM</string>
+ <string>LtnCapN</string>
+ <string>LtnCapO</string>
+ <string>LtnCapP</string>
+ <string>LtnCapQ</string>
+ <string>LtnCapR</string>
+ <string>LtnCapS</string>
+ <string>LtnCapT</string>
+ <string>LtnCapU</string>
+ <string>LtnCapV</string>
+ <string>LtnCapW</string>
+ <string>LtnCapX</string>
+ <string>LtnCapY</string>
+ <string>LftSqrBrac</string>
+ <string>ReverseSolidus</string>
+ <string>RtSqrBrac</string>
+ <string>CircumAccent</string>
+ <string>LowLine</string>
+ <string>GraveAccent</string>
+ <string>LtnSmA</string>
+ <string>LtnSmB</string>
+ <string>LtnSmC</string>
+ <string>LtnSmD</string>
+ <string>LtnSmE</string>
+ <string>LtnSmF</string>
+ <string>LtnSmG</string>
+ <string>LtnSmH</string>
+ <string>LtnSmI</string>
+ <string>LtnSmJ</string>
+ <string>LtnSmK</string>
+ <string>LtnSmL</string>
+ <string>LtnSmM</string>
+ <string>LtnSmN</string>
+ <string>LtnSmO</string>
+ <string>LtnSmP</string>
+ <string>LtnSmQ</string>
+ <string>LtnSmR</string>
+ <string>LtnSmS</string>
+ <string>LtnSmT</string>
+ <string>LtnSmU</string>
+ <string>LtnSmV</string>
+ <string>LtnSmW</string>
+ <string>LtnSmX</string>
+ <string>LtnSmY</string>
+ <string>LftCurlyBrac</string>
+ <string>VertLine</string>
+ <string>RtCurlyBrac</string>
+ <string>Tilde</string>
+ <string>LtnCapADiaer</string>
+ <string>LtnSmAAcute</string>
+ <string>LtnSmAGrave</string>
+ <string>LtnSmACircum</string>
+ <string>LtnSmADiaer</string>
+ <string>LtnSmATilde</string>
+ <string>LtnSmARingAbv</string>
+ <string>DottedCirc</string>
+ <string>Hyphen</string>
+ <string>NonBreakingHyphen</string>
+ <string>Hyphen_Soft</string>
+ <string>CombAcute</string>
+ <string>CombGrave</string>
+ <string>CombCircum</string>
+ <string>CombTilde</string>
+ <string>CombDiaer</string>
+ <string>CombRingAbv</string>
+ </array>
+ <key>public.postscriptNames</key>
+ <dict>
+ <key>Ampersand</key>
+ <string>ampersand</string>
+ <key>Apos</key>
+ <string>quotesingle</string>
+ <key>Asterisk</key>
+ <string>asterisk</string>
+ <key>AtSgn</key>
+ <string>at</string>
+ <key>CircumAccent</key>
+ <string>asciicircum</string>
+ <key>Colon</key>
+ <string>colon</string>
+ <key>CombAcute</key>
+ <string>acutecomb</string>
+ <key>CombCircum</key>
+ <string>uni0302</string>
+ <key>CombDiaer</key>
+ <string>uni0308</string>
+ <key>CombGrave</key>
+ <string>gravecomb</string>
+ <key>CombRingAbv</key>
+ <string>uni030A</string>
+ <key>CombTilde</key>
+ <string>tildecomb</string>
+ <key>Comma</key>
+ <string>comma</string>
+ <key>DigitEight</key>
+ <string>eight</string>
+ <key>DigitFive</key>
+ <string>five</string>
+ <key>DigitFour</key>
+ <string>four</string>
+ <key>DigitNine</key>
+ <string>nine</string>
+ <key>DigitOne</key>
+ <string>one</string>
+ <key>DigitSeven</key>
+ <string>seven</string>
+ <key>DigitSix</key>
+ <string>six</string>
+ <key>DigitThree</key>
+ <string>three</string>
+ <key>DigitTwo</key>
+ <string>two</string>
+ <key>DigitZero</key>
+ <string>zero</string>
+ <key>DollarSgn</key>
+ <string>dollar</string>
+ <key>DottedCirc</key>
+ <string>uni25CC</string>
+ <key>EqSgn</key>
+ <string>equal</string>
+ <key>ExclamationMrk</key>
+ <string>exclam</string>
+ <key>FullStop</key>
+ <string>period</string>
+ <key>GTSgn</key>
+ <string>greater</string>
+ <key>GraveAccent</key>
+ <string>grave</string>
+ <key>Hyphen</key>
+ <string>uni2010</string>
+ <key>HyphenMinus</key>
+ <string>hyphen</string>
+ <key>Hyphen_Soft</key>
+ <string>uni00AD</string>
+ <key>LTSgn</key>
+ <string>less</string>
+ <key>LftCurlyBrac</key>
+ <string>braceleft</string>
+ <key>LftParen</key>
+ <string>parenleft</string>
+ <key>LftSqrBrac</key>
+ <string>bracketleft</string>
+ <key>LowLine</key>
+ <string>underscore</string>
+ <key>LtnCapA</key>
+ <string>A</string>
+ <key>LtnCapA.alt</key>
+ <string>A</string>
+ <key>LtnCapADiaer</key>
+ <string>Adieresis</string>
+ <key>LtnCapB</key>
+ <string>B</string>
+ <key>LtnCapC</key>
+ <string>C</string>
+ <key>LtnCapD</key>
+ <string>D</string>
+ <key>LtnCapE</key>
+ <string>E</string>
+ <key>LtnCapF</key>
+ <string>F</string>
+ <key>LtnCapG</key>
+ <string>G</string>
+ <key>LtnCapH</key>
+ <string>H</string>
+ <key>LtnCapI</key>
+ <string>I</string>
+ <key>LtnCapJ</key>
+ <string>J</string>
+ <key>LtnCapK</key>
+ <string>K</string>
+ <key>LtnCapL</key>
+ <string>L</string>
+ <key>LtnCapM</key>
+ <string>M</string>
+ <key>LtnCapN</key>
+ <string>N</string>
+ <key>LtnCapO</key>
+ <string>O</string>
+ <key>LtnCapP</key>
+ <string>P</string>
+ <key>LtnCapQ</key>
+ <string>Q</string>
+ <key>LtnCapR</key>
+ <string>R</string>
+ <key>LtnCapS</key>
+ <string>S</string>
+ <key>LtnCapT</key>
+ <string>T</string>
+ <key>LtnCapU</key>
+ <string>U</string>
+ <key>LtnCapV</key>
+ <string>V</string>
+ <key>LtnCapW</key>
+ <string>W</string>
+ <key>LtnCapX</key>
+ <string>X</string>
+ <key>LtnCapY</key>
+ <string>Y</string>
+ <key>LtnSmA</key>
+ <string>a</string>
+ <key>LtnSmAAcute</key>
+ <string>aacute</string>
+ <key>LtnSmACircum</key>
+ <string>acircumflex</string>
+ <key>LtnSmADiaer</key>
+ <string>adieresis</string>
+ <key>LtnSmAGrave</key>
+ <string>agrave</string>
+ <key>LtnSmARingAbv</key>
+ <string>aring</string>
+ <key>LtnSmATilde</key>
+ <string>atilde</string>
+ <key>LtnSmB</key>
+ <string>b</string>
+ <key>LtnSmC</key>
+ <string>c</string>
+ <key>LtnSmD</key>
+ <string>d</string>
+ <key>LtnSmE</key>
+ <string>e</string>
+ <key>LtnSmF</key>
+ <string>f</string>
+ <key>LtnSmG</key>
+ <string>g</string>
+ <key>LtnSmH</key>
+ <string>h</string>
+ <key>LtnSmI</key>
+ <string>i</string>
+ <key>LtnSmJ</key>
+ <string>j</string>
+ <key>LtnSmK</key>
+ <string>k</string>
+ <key>LtnSmL</key>
+ <string>l</string>
+ <key>LtnSmM</key>
+ <string>m</string>
+ <key>LtnSmN</key>
+ <string>n</string>
+ <key>LtnSmO</key>
+ <string>o</string>
+ <key>LtnSmP</key>
+ <string>p</string>
+ <key>LtnSmQ</key>
+ <string>q</string>
+ <key>LtnSmR</key>
+ <string>r</string>
+ <key>LtnSmS</key>
+ <string>s</string>
+ <key>LtnSmT</key>
+ <string>t</string>
+ <key>LtnSmU</key>
+ <string>u</string>
+ <key>LtnSmV</key>
+ <string>v</string>
+ <key>LtnSmW</key>
+ <string>w</string>
+ <key>LtnSmX</key>
+ <string>x</string>
+ <key>LtnSmY</key>
+ <string>y</string>
+ <key>NonBreakingHyphen</key>
+ <string>uni2011</string>
+ <key>NumSgn</key>
+ <string>numbersign</string>
+ <key>PercentSgn</key>
+ <string>percent</string>
+ <key>PlusSgn</key>
+ <string>plus</string>
+ <key>QstnMrk</key>
+ <string>question</string>
+ <key>QuotMrk</key>
+ <string>quotedbl</string>
+ <key>ReverseSolidus</key>
+ <string>backslash</string>
+ <key>RtCurlyBrac</key>
+ <string>braceright</string>
+ <key>RtParen</key>
+ <string>parenright</string>
+ <key>RtSqrBrac</key>
+ <string>bracketright</string>
+ <key>Semicolon</key>
+ <string>semicolon</string>
+ <key>Solidus</key>
+ <string>slash</string>
+ <key>Space</key>
+ <string>space</string>
+ <key>Tilde</key>
+ <string>asciitilde</string>
+ <key>VertLine</key>
+ <string>bar</string>
+ </dict>
+</dict>
+</plist>
diff --git a/tests/input/font-psf-test/source/PsfTest-Italic.ufo/metainfo.plist b/tests/input/font-psf-test/source/PsfTest-Italic.ufo/metainfo.plist
new file mode 100644
index 0000000..aa10c5c
--- /dev/null
+++ b/tests/input/font-psf-test/source/PsfTest-Italic.ufo/metainfo.plist
@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+ <key>creator</key>
+ <string>org.sil.scripts.pysilfont</string>
+ <key>formatVersion</key>
+ <integer>3</integer>
+</dict>
+</plist>
diff --git a/tests/input/font-psf-test/source/PsfTest-Regular.ufo/fontinfo.plist b/tests/input/font-psf-test/source/PsfTest-Regular.ufo/fontinfo.plist
new file mode 100644
index 0000000..3f2d484
--- /dev/null
+++ b/tests/input/font-psf-test/source/PsfTest-Regular.ufo/fontinfo.plist
@@ -0,0 +1,260 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+ <key>ascender</key>
+ <integer>2100</integer>
+ <key>capHeight</key>
+ <real>1485</real>
+ <key>copyright</key>
+ <string>Copyright (c) 2004-2021 SIL International</string>
+ <key>descender</key>
+ <integer>-550</integer>
+ <key>familyName</key>
+ <string>Psf Test</string>
+ <key>guidelines</key>
+ <array>
+ <dict>
+ <key>angle</key>
+ <integer>0</integer>
+ <key>x</key>
+ <integer>1084</integer>
+ <key>y</key>
+ <integer>1040</integer>
+ </dict>
+ <dict>
+ <key>y</key>
+ <integer>1250</integer>
+ </dict>
+ </array>
+ <key>note</key>
+ <string>Test note
+Second line
+
+Third line
+</string>
+ <key>openTypeHeadCreated</key>
+ <string>2021/01/01 11:00:00</string>
+ <key>openTypeHheaAscender</key>
+ <integer>2100</integer>
+ <key>openTypeHheaDescender</key>
+ <integer>-550</integer>
+ <key>openTypeHheaLineGap</key>
+ <integer>0</integer>
+ <key>openTypeNameDescription</key>
+ <string>Copyright (c) 2004-2021 SIL International</string>
+ <key>openTypeNameDesigner</key>
+ <string>Victor Gaultney, Annie Olsen, Julie Remington, Don Collingsworth, Eric Hays, Becca Hirsbrunner</string>
+ <key>openTypeNameDesignerURL</key>
+ <string>http://scripts.sil.org/</string>
+ <key>openTypeNameLicense</key>
+ <string>Copyright (c) 2004-2021 SIL International (http://www.sil.org/) with Reserved Font Names "Andika" and "SIL".
+
+This Font Software is licensed under the SIL Open Font License, Version 1.1. This license is copied below, and is also available with a FAQ at: http://scripts.sil.org/OFL
+
+
+-----------------------------------------------------------
+SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007
+-----------------------------------------------------------
+
+PREAMBLE
+The goals of the Open Font License (OFL) are to stimulate worldwide development of collaborative font projects, to support the font creation efforts of academic and linguistic communities, and to provide a free and open framework in which fonts may be shared and improved in partnership with others.
+
+The OFL allows the licensed fonts to be used, studied, modified and redistributed freely as long as they are not sold by themselves. The fonts, including any derivative works, can be bundled, embedded, redistributed and/or sold with any software provided that any reserved names are not used by derivative works. The fonts and derivatives, however, cannot be released under any other type of license. The requirement for fonts to remain under this license does not apply to any document created using the fonts or their derivatives.
+
+DEFINITIONS
+"Font Software" refers to the set of files released by the Copyright Holder(s) under this license and clearly marked as such. This may include source files, build scripts and documentation.
+
+"Reserved Font Name" refers to any names specified as such after the copyright statement(s).
+
+"Original Version" refers to the collection of Font Software components as distributed by the Copyright Holder(s).
+
+"Modified Version" refers to any derivative made by adding to, deleting, or substituting -- in part or in whole -- any of the components of the Original Version, by changing formats or by porting the Font Software to a new environment.
+
+"Author" refers to any designer, engineer, programmer, technical writer or other person who contributed to the Font Software.
+
+PERMISSION &amp; CONDITIONS
+Permission is hereby granted, free of charge, to any person obtaining a copy of the Font Software, to use, study, copy, merge, embed, modify, redistribute, and sell modified and unmodified copies of the Font Software, subject to the following conditions:
+
+1) Neither the Font Software nor any of its individual components, in Original or Modified Versions, may be sold by itself.
+
+2) Original or Modified Versions of the Font Software may be bundled, redistributed and/or sold with any software, provided that each copy contains the above copyright notice and this license. These can be included either as stand-alone text files, human-readable headers or in the appropriate machine-readable metadata fields within text or binary files as long as those fields can be easily viewed by the user.
+
+3) No Modified Version of the Font Software may use the Reserved Font Name(s) unless explicit written permission is granted by the corresponding Copyright Holder. This restriction only applies to the primary font name as presented to the users.
+
+4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font Software shall not be used to promote, endorse or advertise any Modified Version, except to acknowledge the contribution(s) of the Copyright Holder(s) and the Author(s) or with their explicit written permission.
+
+5) The Font Software, modified or unmodified, in part or in whole, must be distributed entirely under this license, and must not be distributed under any other license. The requirement for fonts to remain under this license does not apply to any document created using the Font Software.
+
+TERMINATION
+This license becomes null and void if any of the above conditions are not met.
+
+DISCLAIMER
+THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM OTHER DEALINGS IN THE FONT SOFTWARE.</string>
+ <key>openTypeNameLicenseURL</key>
+ <string>http://scripts.sil.org/OFL</string>
+ <key>openTypeNameManufacturer</key>
+ <string>SIL International</string>
+ <key>openTypeNameManufacturerURL</key>
+ <string>http://scripts.sil.org</string>
+ <key>openTypeNamePreferredFamilyName</key>
+ <string>Psf Test</string>
+ <key>openTypeNamePreferredSubfamilyName</key>
+ <string>Regular</string>
+ <key>openTypeNameUniqueID</key>
+ <string>SIL International: Psf Test Regular: 2022</string>
+ <key>openTypeNameVersion</key>
+ <string>Version 5.550</string>
+ <key>openTypeOS2CodePageRanges</key>
+ <array>
+ <integer>0</integer>
+ <integer>1</integer>
+ <integer>2</integer>
+ <integer>4</integer>
+ <integer>7</integer>
+ <integer>8</integer>
+ </array>
+ <key>openTypeOS2FamilyClass</key>
+ <array>
+ <integer>0</integer>
+ <integer>0</integer>
+ </array>
+ <key>openTypeOS2Panose</key>
+ <array>
+ <integer>2</integer>
+ <integer>0</integer>
+ <integer>0</integer>
+ <integer>0</integer>
+ <integer>0</integer>
+ <integer>0</integer>
+ <integer>0</integer>
+ <integer>0</integer>
+ <integer>0</integer>
+ <integer>0</integer>
+ </array>
+ <key>openTypeOS2StrikeoutPosition</key>
+ <integer>700</integer>
+ <key>openTypeOS2StrikeoutSize</key>
+ <integer>100</integer>
+ <key>openTypeOS2SubscriptXOffset</key>
+ <integer>0</integer>
+ <key>openTypeOS2SubscriptXSize</key>
+ <integer>1433</integer>
+ <key>openTypeOS2SubscriptYOffset</key>
+ <integer>286</integer>
+ <key>openTypeOS2SubscriptYSize</key>
+ <integer>1331</integer>
+ <key>openTypeOS2SuperscriptXOffset</key>
+ <integer>0</integer>
+ <key>openTypeOS2SuperscriptXSize</key>
+ <integer>1433</integer>
+ <key>openTypeOS2SuperscriptYOffset</key>
+ <integer>976</integer>
+ <key>openTypeOS2SuperscriptYSize</key>
+ <integer>1331</integer>
+ <key>openTypeOS2Type</key>
+ <array/>
+ <key>openTypeOS2TypoAscender</key>
+ <integer>2100</integer>
+ <key>openTypeOS2TypoDescender</key>
+ <integer>-550</integer>
+ <key>openTypeOS2TypoLineGap</key>
+ <integer>0</integer>
+ <key>openTypeOS2UnicodeRanges</key>
+ <array>
+ <integer>0</integer>
+ <integer>1</integer>
+ <integer>6</integer>
+ <integer>7</integer>
+ <integer>31</integer>
+ <integer>33</integer>
+ <integer>35</integer>
+ <integer>36</integer>
+ <integer>37</integer>
+ <integer>38</integer>
+ <integer>39</integer>
+ <integer>40</integer>
+ <integer>45</integer>
+ <integer>46</integer>
+ <integer>47</integer>
+ <integer>57</integer>
+ <integer>60</integer>
+ <integer>62</integer>
+ <integer>64</integer>
+ <integer>67</integer>
+ <integer>69</integer>
+ <integer>89</integer>
+ </array>
+ <key>openTypeOS2VendorID</key>
+ <string>SIL</string>
+ <key>openTypeOS2WeightClass</key>
+ <integer>400</integer>
+ <key>openTypeOS2WidthClass</key>
+ <integer>5</integer>
+ <key>openTypeOS2WinAscent</key>
+ <integer>2100</integer>
+ <key>openTypeOS2WinDescent</key>
+ <integer>550</integer>
+ <key>postscriptBlueValues</key>
+ <array>
+ <integer>-490</integer>
+ <integer>-490</integer>
+ <integer>-25</integer>
+ <integer>0</integer>
+ <integer>1020</integer>
+ <integer>1040</integer>
+ <integer>1455</integer>
+ <integer>1485</integer>
+ <integer>1600</integer>
+ <integer>1620</integer>
+ </array>
+ <key>postscriptFontName</key>
+ <string>PsfTest-Regular</string>
+ <key>postscriptFullName</key>
+ <string>Psf Test Regular</string>
+ <key>postscriptStemSnapH</key>
+ <array>
+ <integer>140</integer>
+ <integer>145</integer>
+ <integer>150</integer>
+ <integer>155</integer>
+ <integer>160</integer>
+ <integer>165</integer>
+ <integer>170</integer>
+ <integer>175</integer>
+ <integer>185</integer>
+ <integer>270</integer>
+ </array>
+ <key>postscriptStemSnapV</key>
+ <array>
+ <integer>165</integer>
+ <integer>180</integer>
+ <integer>185</integer>
+ <integer>190</integer>
+ <integer>195</integer>
+ <integer>200</integer>
+ <integer>205</integer>
+ <integer>270</integer>
+ </array>
+ <key>postscriptUnderlinePosition</key>
+ <integer>-110</integer>
+ <key>postscriptUnderlineThickness</key>
+ <integer>80</integer>
+ <key>styleMapFamilyName</key>
+ <string>Psf Test</string>
+ <key>styleMapStyleName</key>
+ <string>regular</string>
+ <key>styleName</key>
+ <string>Regular</string>
+ <key>trademark</key>
+ <string>Andika is a trademark of SIL International.</string>
+ <key>unitsPerEm</key>
+ <integer>2048</integer>
+ <key>versionMajor</key>
+ <integer>5</integer>
+ <key>versionMinor</key>
+ <integer>550</integer>
+ <key>xHeight</key>
+ <integer>1040</integer>
+</dict>
+</plist>
diff --git a/tests/input/font-psf-test/source/PsfTest-Regular.ufo/glyphs/A_mpersand.glif b/tests/input/font-psf-test/source/PsfTest-Regular.ufo/glyphs/A_mpersand.glif
new file mode 100644
index 0000000..c2cef04
--- /dev/null
+++ b/tests/input/font-psf-test/source/PsfTest-Regular.ufo/glyphs/A_mpersand.glif
@@ -0,0 +1,61 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="Ampersand" format="2">
+ <advance width="1222"/>
+ <unicode hex="0026"/>
+ <outline>
+ <contour>
+ <point x="490" y="1485" type="curve" smooth="yes"/>
+ <point x="331" y="1485"/>
+ <point x="155" y="1412"/>
+ <point x="155" y="1190" type="curve" smooth="yes"/>
+ <point x="155" y="1010"/>
+ <point x="362" y="815"/>
+ <point x="535" y="570" type="curve" smooth="yes"/>
+ <point x="794" y="202"/>
+ <point x="973" y="-25"/>
+ <point x="1025" y="-25" type="curve" smooth="yes"/>
+ <point x="1060" y="-25"/>
+ <point x="1138" y="38"/>
+ <point x="1175" y="70" type="curve"/>
+ <point x="1080" y="110"/>
+ <point x="914" y="297"/>
+ <point x="650" y="680" type="curve" smooth="yes"/>
+ <point x="494" y="906"/>
+ <point x="315" y="1075"/>
+ <point x="315" y="1200" type="curve" smooth="yes"/>
+ <point x="315" y="1291"/>
+ <point x="398" y="1350"/>
+ <point x="475" y="1350" type="curve" smooth="yes"/>
+ <point x="555" y="1350"/>
+ <point x="630" y="1294"/>
+ <point x="630" y="1205" type="curve" smooth="yes"/>
+ <point x="630" y="1116"/>
+ <point x="523" y="1001"/>
+ <point x="350" y="840" type="curve" smooth="yes"/>
+ <point x="146" y="651"/>
+ <point x="55" y="527"/>
+ <point x="55" y="375" type="curve" smooth="yes"/>
+ <point x="55" y="151"/>
+ <point x="217" y="-25"/>
+ <point x="440" y="-25" type="curve" smooth="yes"/>
+ <point x="713" y="-25"/>
+ <point x="1002" y="274"/>
+ <point x="1080" y="435" type="curve"/>
+ <point x="975" y="570" type="line"/>
+ <point x="911" y="403"/>
+ <point x="630" y="150"/>
+ <point x="455" y="150" type="curve" smooth="yes"/>
+ <point x="310" y="150"/>
+ <point x="230" y="267"/>
+ <point x="230" y="380" type="curve" smooth="yes"/>
+ <point x="230" y="490"/>
+ <point x="296" y="587"/>
+ <point x="470" y="740" type="curve" smooth="yes"/>
+ <point x="651" y="899"/>
+ <point x="790" y="1068"/>
+ <point x="790" y="1200" type="curve" smooth="yes"/>
+ <point x="790" y="1382"/>
+ <point x="642" y="1485"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/input/font-psf-test/source/PsfTest-Regular.ufo/glyphs/A_pos.glif b/tests/input/font-psf-test/source/PsfTest-Regular.ufo/glyphs/A_pos.glif
new file mode 100644
index 0000000..5042901
--- /dev/null
+++ b/tests/input/font-psf-test/source/PsfTest-Regular.ufo/glyphs/A_pos.glif
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="Apos" format="2">
+ <advance width="605"/>
+ <unicode hex="0027"/>
+ <outline>
+ <contour>
+ <point x="365" y="1045" type="line"/>
+ <point x="370" y="1186"/>
+ <point x="376" y="1339"/>
+ <point x="405" y="1585" type="curve"/>
+ <point x="200" y="1585" type="line"/>
+ <point x="231" y="1339"/>
+ <point x="236" y="1186"/>
+ <point x="240" y="1045" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/input/font-psf-test/source/PsfTest-Regular.ufo/glyphs/A_sterisk.glif b/tests/input/font-psf-test/source/PsfTest-Regular.ufo/glyphs/A_sterisk.glif
new file mode 100644
index 0000000..850d344
--- /dev/null
+++ b/tests/input/font-psf-test/source/PsfTest-Regular.ufo/glyphs/A_sterisk.glif
@@ -0,0 +1,51 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="Asterisk" format="2">
+ <advance width="1028"/>
+ <unicode hex="002A"/>
+ <outline>
+ <contour>
+ <point x="560" y="1600" type="curve"/>
+ <point x="415" y="1600" type="line"/>
+ <point x="434" y="1467"/>
+ <point x="447" y="1387"/>
+ <point x="450" y="1300" type="curve"/>
+ <point x="376" y="1344"/>
+ <point x="309" y="1387"/>
+ <point x="200" y="1465" type="curve"/>
+ <point x="125" y="1340" type="line"/>
+ <point x="250" y="1290"/>
+ <point x="327" y="1261"/>
+ <point x="405" y="1220" type="curve"/>
+ <point x="329" y="1177"/>
+ <point x="256" y="1140"/>
+ <point x="135" y="1085" type="curve"/>
+ <point x="205" y="960" type="line"/>
+ <point x="310" y="1042"/>
+ <point x="377" y="1094"/>
+ <point x="450" y="1140" type="curve"/>
+ <point x="448" y="1055"/>
+ <point x="442" y="973"/>
+ <point x="430" y="840" type="curve"/>
+ <point x="570" y="840" type="line"/>
+ <point x="550" y="973"/>
+ <point x="544" y="1052"/>
+ <point x="540" y="1140" type="curve"/>
+ <point x="614" y="1095"/>
+ <point x="681" y="1053"/>
+ <point x="790" y="975" type="curve"/>
+ <point x="865" y="1100" type="line"/>
+ <point x="739" y="1149"/>
+ <point x="663" y="1179"/>
+ <point x="585" y="1220" type="curve"/>
+ <point x="661" y="1261"/>
+ <point x="733" y="1299"/>
+ <point x="855" y="1355" type="curve"/>
+ <point x="785" y="1480" type="line"/>
+ <point x="680" y="1396"/>
+ <point x="614" y="1348"/>
+ <point x="540" y="1300" type="curve"/>
+ <point x="541" y="1387"/>
+ <point x="547" y="1467"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/input/font-psf-test/source/PsfTest-Regular.ufo/glyphs/A_tS_gn.glif b/tests/input/font-psf-test/source/PsfTest-Regular.ufo/glyphs/A_tS_gn.glif
new file mode 100644
index 0000000..681014d
--- /dev/null
+++ b/tests/input/font-psf-test/source/PsfTest-Regular.ufo/glyphs/A_tS_gn.glif
@@ -0,0 +1,80 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="AtSgn" format="2">
+ <advance width="1702"/>
+ <unicode hex="0040"/>
+ <outline>
+ <contour>
+ <point x="1605" y="700" type="curve" smooth="yes"/>
+ <point x="1605" y="1127"/>
+ <point x="1307" y="1405"/>
+ <point x="880" y="1405" type="curve" smooth="yes"/>
+ <point x="465" y="1405"/>
+ <point x="95" y="1126"/>
+ <point x="95" y="575" type="curve" smooth="yes"/>
+ <point x="95" y="48"/>
+ <point x="464" y="-235"/>
+ <point x="855" y="-235" type="curve" smooth="yes"/>
+ <point x="990" y="-235"/>
+ <point x="1150" y="-188"/>
+ <point x="1250" y="-118" type="curve"/>
+ <point x="1145" y="-10" type="line"/>
+ <point x="1058" y="-70"/>
+ <point x="963" y="-95"/>
+ <point x="870" y="-95" type="curve" smooth="yes"/>
+ <point x="523" y="-95"/>
+ <point x="240" y="174"/>
+ <point x="240" y="605" type="curve" smooth="yes"/>
+ <point x="240" y="1003"/>
+ <point x="542" y="1270"/>
+ <point x="870" y="1270" type="curve" smooth="yes"/>
+ <point x="1263" y="1270"/>
+ <point x="1465" y="1002"/>
+ <point x="1465" y="670" type="curve" smooth="yes"/>
+ <point x="1465" y="432"/>
+ <point x="1348" y="315"/>
+ <point x="1280" y="315" type="curve" smooth="yes"/>
+ <point x="1221" y="315"/>
+ <point x="1175" y="410"/>
+ <point x="1175" y="630" type="curve" smooth="yes"/>
+ <point x="1175" y="980" type="line"/>
+ <point x="1088" y="1015"/>
+ <point x="961" y="1040"/>
+ <point x="880" y="1040" type="curve" smooth="yes"/>
+ <point x="716" y="1040"/>
+ <point x="613" y="971"/>
+ <point x="530" y="835" type="curve" smooth="yes"/>
+ <point x="483" y="756"/>
+ <point x="455" y="653"/>
+ <point x="455" y="530" type="curve" smooth="yes"/>
+ <point x="455" y="294"/>
+ <point x="601" y="183"/>
+ <point x="735" y="183" type="curve" smooth="yes"/>
+ <point x="852" y="183"/>
+ <point x="988" y="366"/>
+ <point x="1040" y="490" type="curve"/>
+ <point x="1050" y="322"/>
+ <point x="1128" y="180"/>
+ <point x="1250" y="180" type="curve" smooth="yes"/>
+ <point x="1425" y="180"/>
+ <point x="1605" y="368"/>
+ </contour>
+ <contour>
+ <point x="850" y="905" type="curve" smooth="yes"/>
+ <point x="924" y="905"/>
+ <point x="992" y="886"/>
+ <point x="1025" y="870" type="curve"/>
+ <point x="1025" y="720" type="line"/>
+ <point x="993" y="582"/>
+ <point x="838" y="320"/>
+ <point x="748" y="320" type="curve" smooth="yes"/>
+ <point x="676" y="320"/>
+ <point x="605" y="398"/>
+ <point x="605" y="575" type="curve" smooth="yes"/>
+ <point x="605" y="652"/>
+ <point x="621" y="731"/>
+ <point x="650" y="780" type="curve" smooth="yes"/>
+ <point x="706" y="876"/>
+ <point x="782" y="905"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/input/font-psf-test/source/PsfTest-Regular.ufo/glyphs/C_ircumA_ccent.glif b/tests/input/font-psf-test/source/PsfTest-Regular.ufo/glyphs/C_ircumA_ccent.glif
new file mode 100644
index 0000000..60bd1cf
--- /dev/null
+++ b/tests/input/font-psf-test/source/PsfTest-Regular.ufo/glyphs/C_ircumA_ccent.glif
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="CircumAccent" format="2">
+ <advance width="850"/>
+ <unicode hex="005E"/>
+ <outline>
+ <component base="CombCircum" xOffset="995"/>
+ </outline>
+</glyph>
diff --git a/tests/input/font-psf-test/source/PsfTest-Regular.ufo/glyphs/C_olon.glif b/tests/input/font-psf-test/source/PsfTest-Regular.ufo/glyphs/C_olon.glif
new file mode 100644
index 0000000..3cfbbc1
--- /dev/null
+++ b/tests/input/font-psf-test/source/PsfTest-Regular.ufo/glyphs/C_olon.glif
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="Colon" format="2">
+ <advance width="640"/>
+ <unicode hex="003A"/>
+ <outline>
+ <contour>
+ <point x="185" y="790" type="curve" smooth="yes"/>
+ <point x="185" y="716"/>
+ <point x="246" y="655"/>
+ <point x="320" y="655" type="curve" smooth="yes"/>
+ <point x="394" y="655"/>
+ <point x="455" y="716"/>
+ <point x="455" y="790" type="curve" smooth="yes"/>
+ <point x="455" y="864"/>
+ <point x="394" y="925"/>
+ <point x="320" y="925" type="curve" smooth="yes"/>
+ <point x="246" y="925"/>
+ <point x="185" y="864"/>
+ </contour>
+ <contour>
+ <point x="185" y="110" type="curve" smooth="yes"/>
+ <point x="185" y="36"/>
+ <point x="246" y="-25"/>
+ <point x="320" y="-25" type="curve" smooth="yes"/>
+ <point x="394" y="-25"/>
+ <point x="455" y="36"/>
+ <point x="455" y="110" type="curve" smooth="yes"/>
+ <point x="455" y="184"/>
+ <point x="394" y="245"/>
+ <point x="320" y="245" type="curve" smooth="yes"/>
+ <point x="246" y="245"/>
+ <point x="185" y="184"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/input/font-psf-test/source/PsfTest-Regular.ufo/glyphs/C_ombA_cute.glif b/tests/input/font-psf-test/source/PsfTest-Regular.ufo/glyphs/C_ombA_cute.glif
new file mode 100644
index 0000000..bb13221
--- /dev/null
+++ b/tests/input/font-psf-test/source/PsfTest-Regular.ufo/glyphs/C_ombA_cute.glif
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="CombAcute" format="2">
+ <unicode hex="0301"/>
+ <anchor x="-570" y="1635" name="U"/>
+ <anchor x="-570" y="1100" name="_U"/>
+ <outline>
+ <contour>
+ <point x="-400" y="1600" type="line"/>
+ <point x="-750" y="1170" type="line"/>
+ <point x="-590" y="1170" type="line"/>
+ <point x="-170" y="1600" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/input/font-psf-test/source/PsfTest-Regular.ufo/glyphs/C_ombC_ircum.glif b/tests/input/font-psf-test/source/PsfTest-Regular.ufo/glyphs/C_ombC_ircum.glif
new file mode 100644
index 0000000..fa444ec
--- /dev/null
+++ b/tests/input/font-psf-test/source/PsfTest-Regular.ufo/glyphs/C_ombC_ircum.glif
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="CombCircum" format="2">
+ <unicode hex="0302"/>
+ <anchor x="-570" y="1635" name="U"/>
+ <anchor x="-570" y="1100" name="_U"/>
+ <outline>
+ <contour>
+ <point x="-845" y="1170" type="line"/>
+ <point x="-570" y="1450" type="line"/>
+ <point x="-295" y="1170" type="line"/>
+ <point x="-145" y="1170" type="line"/>
+ <point x="-485" y="1600" type="line"/>
+ <point x="-655" y="1600" type="line"/>
+ <point x="-995" y="1170" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/input/font-psf-test/source/PsfTest-Regular.ufo/glyphs/C_ombD_iaer.glif b/tests/input/font-psf-test/source/PsfTest-Regular.ufo/glyphs/C_ombD_iaer.glif
new file mode 100644
index 0000000..f7540ef
--- /dev/null
+++ b/tests/input/font-psf-test/source/PsfTest-Regular.ufo/glyphs/C_ombD_iaer.glif
@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="CombDiaer" format="2">
+ <unicode hex="0308"/>
+ <anchor x="-570" y="1505" name="U"/>
+ <anchor x="-570" y="1100" name="_U"/>
+ <outline>
+ <contour>
+ <point x="-490" y="1345" type="curve" smooth="yes"/>
+ <point x="-490" y="1271"/>
+ <point x="-434" y="1210"/>
+ <point x="-360" y="1210" type="curve" smooth="yes"/>
+ <point x="-285" y="1210"/>
+ <point x="-230" y="1271"/>
+ <point x="-230" y="1345" type="curve" smooth="yes"/>
+ <point x="-230" y="1419"/>
+ <point x="-285" y="1480"/>
+ <point x="-360" y="1480" type="curve" smooth="yes"/>
+ <point x="-434" y="1480"/>
+ <point x="-490" y="1419"/>
+ </contour>
+ <contour>
+ <point x="-910" y="1345" type="curve" smooth="yes"/>
+ <point x="-910" y="1271"/>
+ <point x="-854" y="1210"/>
+ <point x="-780" y="1210" type="curve" smooth="yes"/>
+ <point x="-705" y="1210"/>
+ <point x="-650" y="1271"/>
+ <point x="-650" y="1345" type="curve" smooth="yes"/>
+ <point x="-650" y="1419"/>
+ <point x="-705" y="1480"/>
+ <point x="-780" y="1480" type="curve" smooth="yes"/>
+ <point x="-854" y="1480"/>
+ <point x="-910" y="1419"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/input/font-psf-test/source/PsfTest-Regular.ufo/glyphs/C_ombG_rave.glif b/tests/input/font-psf-test/source/PsfTest-Regular.ufo/glyphs/C_ombG_rave.glif
new file mode 100644
index 0000000..c33b56a
--- /dev/null
+++ b/tests/input/font-psf-test/source/PsfTest-Regular.ufo/glyphs/C_ombG_rave.glif
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="CombGrave" format="2">
+ <unicode hex="0300"/>
+ <anchor x="-550" y="1635" name="U"/>
+ <anchor x="-550" y="1100" name="_U"/>
+ <outline>
+ <contour>
+ <point x="-940" y="1600" type="line"/>
+ <point x="-520" y="1170" type="line"/>
+ <point x="-360" y="1170" type="line"/>
+ <point x="-710" y="1600" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/input/font-psf-test/source/PsfTest-Regular.ufo/glyphs/C_ombR_ingA_bv.glif b/tests/input/font-psf-test/source/PsfTest-Regular.ufo/glyphs/C_ombR_ingA_bv.glif
new file mode 100644
index 0000000..b019e05
--- /dev/null
+++ b/tests/input/font-psf-test/source/PsfTest-Regular.ufo/glyphs/C_ombR_ingA_bv.glif
@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="CombRingAbv" format="2">
+ <unicode hex="030A"/>
+ <anchor x="-570" y="1635" name="U"/>
+ <anchor x="-572" y="1100" name="_U"/>
+ <outline>
+ <contour>
+ <point x="-470" y="1385" type="curve" smooth="yes"/>
+ <point x="-470" y="1325"/>
+ <point x="-510" y="1285"/>
+ <point x="-570" y="1285" type="curve" smooth="yes"/>
+ <point x="-630" y="1285"/>
+ <point x="-670" y="1325"/>
+ <point x="-670" y="1385" type="curve" smooth="yes"/>
+ <point x="-670" y="1445"/>
+ <point x="-630" y="1485"/>
+ <point x="-570" y="1485" type="curve" smooth="yes"/>
+ <point x="-510" y="1485"/>
+ <point x="-470" y="1445"/>
+ </contour>
+ <contour>
+ <point x="-785" y="1385" type="curve" smooth="yes"/>
+ <point x="-785" y="1265"/>
+ <point x="-690" y="1170"/>
+ <point x="-570" y="1170" type="curve" smooth="yes"/>
+ <point x="-450" y="1170"/>
+ <point x="-355" y="1265"/>
+ <point x="-355" y="1385" type="curve" smooth="yes"/>
+ <point x="-355" y="1505"/>
+ <point x="-450" y="1600"/>
+ <point x="-570" y="1600" type="curve" smooth="yes"/>
+ <point x="-690" y="1600"/>
+ <point x="-785" y="1505"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/input/font-psf-test/source/PsfTest-Regular.ufo/glyphs/C_ombT_ilde.glif b/tests/input/font-psf-test/source/PsfTest-Regular.ufo/glyphs/C_ombT_ilde.glif
new file mode 100644
index 0000000..88d5ca7
--- /dev/null
+++ b/tests/input/font-psf-test/source/PsfTest-Regular.ufo/glyphs/C_ombT_ilde.glif
@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="CombTilde" format="2">
+ <unicode hex="0303"/>
+ <anchor x="-575" y="1475" name="U"/>
+ <anchor x="-575" y="1100" name="_U"/>
+ <outline>
+ <contour>
+ <point x="-820" y="1205" type="line"/>
+ <point x="-815" y="1254"/>
+ <point x="-784" y="1290"/>
+ <point x="-735" y="1290" type="curve" smooth="yes"/>
+ <point x="-698" y="1290"/>
+ <point x="-657" y="1274"/>
+ <point x="-580" y="1238" type="curve" smooth="yes"/>
+ <point x="-519" y="1210"/>
+ <point x="-466" y="1190"/>
+ <point x="-413" y="1190" type="curve" smooth="yes"/>
+ <point x="-290" y="1190"/>
+ <point x="-215" y="1312"/>
+ <point x="-215" y="1440" type="curve"/>
+ <point x="-320" y="1440" type="line"/>
+ <point x="-327" y="1394"/>
+ <point x="-358" y="1355"/>
+ <point x="-405" y="1355" type="curve" smooth="yes"/>
+ <point x="-447" y="1355"/>
+ <point x="-488" y="1374"/>
+ <point x="-560" y="1403" type="curve" smooth="yes"/>
+ <point x="-630" y="1431"/>
+ <point x="-677" y="1455"/>
+ <point x="-733" y="1455" type="curve" smooth="yes"/>
+ <point x="-852" y="1455"/>
+ <point x="-925" y="1327"/>
+ <point x="-925" y="1205" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/input/font-psf-test/source/PsfTest-Regular.ufo/glyphs/C_omma.glif b/tests/input/font-psf-test/source/PsfTest-Regular.ufo/glyphs/C_omma.glif
new file mode 100644
index 0000000..6e8f5a3
--- /dev/null
+++ b/tests/input/font-psf-test/source/PsfTest-Regular.ufo/glyphs/C_omma.glif
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="Comma" format="2">
+ <advance width="650"/>
+ <unicode hex="002C"/>
+ <outline>
+ <contour>
+ <point x="185" y="50" type="line"/>
+ <point x="325" y="50" type="line"/>
+ <point x="325" y="-51"/>
+ <point x="248" y="-172"/>
+ <point x="190" y="-230" type="curve"/>
+ <point x="290" y="-270" type="line"/>
+ <point x="407" y="-160"/>
+ <point x="465" y="-37"/>
+ <point x="465" y="85" type="curve" smooth="yes"/>
+ <point x="465" y="186"/>
+ <point x="400" y="250"/>
+ <point x="320" y="250" type="curve" smooth="yes"/>
+ <point x="263" y="250"/>
+ <point x="198" y="213"/>
+ <point x="185" y="150" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/input/font-psf-test/source/PsfTest-Regular.ufo/glyphs/D_igitE_ight.glif b/tests/input/font-psf-test/source/PsfTest-Regular.ufo/glyphs/D_igitE_ight.glif
new file mode 100644
index 0000000..b7e540a
--- /dev/null
+++ b/tests/input/font-psf-test/source/PsfTest-Regular.ufo/glyphs/D_igitE_ight.glif
@@ -0,0 +1,63 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="DigitEight" format="2">
+ <advance width="1200"/>
+ <unicode hex="0038"/>
+ <anchor x="600" y="-100" name="L"/>
+ <anchor x="600" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="600" y="-25" type="curve" smooth="yes"/>
+ <point x="857" y="-25"/>
+ <point x="1110" y="134"/>
+ <point x="1110" y="405" type="curve" smooth="yes"/>
+ <point x="1110" y="611"/>
+ <point x="965" y="739"/>
+ <point x="855" y="795" type="curve"/>
+ <point x="933" y="844"/>
+ <point x="1050" y="923"/>
+ <point x="1050" y="1105" type="curve" smooth="yes"/>
+ <point x="1050" y="1350"/>
+ <point x="840" y="1485"/>
+ <point x="610" y="1485" type="curve" smooth="yes"/>
+ <point x="381" y="1485"/>
+ <point x="150" y="1350"/>
+ <point x="150" y="1105" type="curve" smooth="yes"/>
+ <point x="150" y="923"/>
+ <point x="272" y="838"/>
+ <point x="350" y="795" type="curve"/>
+ <point x="221" y="725"/>
+ <point x="90" y="611"/>
+ <point x="90" y="405" type="curve" smooth="yes"/>
+ <point x="90" y="134"/>
+ <point x="344" y="-25"/>
+ </contour>
+ <contour>
+ <point x="860" y="1105" type="curve" smooth="yes"/>
+ <point x="860" y="949"/>
+ <point x="743" y="865"/>
+ <point x="600" y="865" type="curve" smooth="yes"/>
+ <point x="457" y="865"/>
+ <point x="340" y="949"/>
+ <point x="340" y="1105" type="curve" smooth="yes"/>
+ <point x="340" y="1252"/>
+ <point x="457" y="1325"/>
+ <point x="600" y="1325" type="curve" smooth="yes"/>
+ <point x="743" y="1325"/>
+ <point x="860" y="1252"/>
+ </contour>
+ <contour>
+ <point x="910" y="425" type="curve" smooth="yes"/>
+ <point x="910" y="250"/>
+ <point x="778" y="145"/>
+ <point x="600" y="145" type="curve" smooth="yes"/>
+ <point x="420" y="145"/>
+ <point x="290" y="250"/>
+ <point x="290" y="425" type="curve" smooth="yes"/>
+ <point x="290" y="592"/>
+ <point x="420" y="710"/>
+ <point x="600" y="710" type="curve" smooth="yes"/>
+ <point x="778" y="710"/>
+ <point x="910" y="592"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/input/font-psf-test/source/PsfTest-Regular.ufo/glyphs/D_igitF_ive.glif b/tests/input/font-psf-test/source/PsfTest-Regular.ufo/glyphs/D_igitF_ive.glif
new file mode 100644
index 0000000..cb2dd85
--- /dev/null
+++ b/tests/input/font-psf-test/source/PsfTest-Regular.ufo/glyphs/D_igitF_ive.glif
@@ -0,0 +1,44 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="DigitFive" format="2">
+ <advance width="1200"/>
+ <unicode hex="0035"/>
+ <anchor x="600" y="-100" name="L"/>
+ <anchor x="600" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="195" y="685" type="line"/>
+ <point x="319" y="733"/>
+ <point x="404" y="750"/>
+ <point x="510" y="750" type="curve" smooth="yes"/>
+ <point x="670" y="750"/>
+ <point x="870" y="672"/>
+ <point x="870" y="470" type="curve" smooth="yes"/>
+ <point x="870" y="268"/>
+ <point x="730" y="155"/>
+ <point x="530" y="155" type="curve" smooth="yes"/>
+ <point x="390" y="155"/>
+ <point x="294" y="182"/>
+ <point x="160" y="290" type="curve"/>
+ <point x="130" y="80" type="line"/>
+ <point x="255" y="2"/>
+ <point x="363" y="-25"/>
+ <point x="518" y="-25" type="curve" smooth="yes"/>
+ <point x="831" y="-25"/>
+ <point x="1060" y="163"/>
+ <point x="1060" y="475" type="curve" smooth="yes"/>
+ <point x="1060" y="742"/>
+ <point x="832" y="930"/>
+ <point x="545" y="930" type="curve" smooth="yes"/>
+ <point x="472" y="930"/>
+ <point x="411" y="924"/>
+ <point x="380" y="920" type="curve"/>
+ <point x="380" y="1290" type="line"/>
+ <point x="765" y="1290" type="line"/>
+ <point x="849" y="1290"/>
+ <point x="925" y="1286"/>
+ <point x="1000" y="1270" type="curve"/>
+ <point x="1000" y="1460" type="line"/>
+ <point x="195" y="1460" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/input/font-psf-test/source/PsfTest-Regular.ufo/glyphs/D_igitF_our.glif b/tests/input/font-psf-test/source/PsfTest-Regular.ufo/glyphs/D_igitF_our.glif
new file mode 100644
index 0000000..d9a5610
--- /dev/null
+++ b/tests/input/font-psf-test/source/PsfTest-Regular.ufo/glyphs/D_igitF_our.glif
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="DigitFour" format="2">
+ <advance width="1200"/>
+ <unicode hex="0034"/>
+ <anchor x="607" y="-100" name="L"/>
+ <anchor x="607" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="1125" y="395" type="line"/>
+ <point x="1125" y="550" type="line"/>
+ <point x="935" y="550" type="line"/>
+ <point x="935" y="1480" type="line"/>
+ <point x="745" y="1480" type="line"/>
+ <point x="90" y="550" type="line"/>
+ <point x="90" y="395" type="line"/>
+ <point x="745" y="395" type="line"/>
+ <point x="745" y="0" type="line"/>
+ <point x="935" y="0" type="line"/>
+ <point x="935" y="395" type="line"/>
+ </contour>
+ <contour>
+ <point x="745" y="1230" type="line"/>
+ <point x="745" y="550" type="line"/>
+ <point x="263" y="550" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/input/font-psf-test/source/PsfTest-Regular.ufo/glyphs/D_igitN_ine.glif b/tests/input/font-psf-test/source/PsfTest-Regular.ufo/glyphs/D_igitN_ine.glif
new file mode 100644
index 0000000..0ce656a
--- /dev/null
+++ b/tests/input/font-psf-test/source/PsfTest-Regular.ufo/glyphs/D_igitN_ine.glif
@@ -0,0 +1,49 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="DigitNine" format="2">
+ <advance width="1200"/>
+ <unicode hex="0039"/>
+ <anchor x="600" y="-100" name="L"/>
+ <anchor x="600" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="193" y="65" type="line"/>
+ <point x="297" y="-5"/>
+ <point x="383" y="-25"/>
+ <point x="501" y="-25" type="curve" smooth="yes"/>
+ <point x="976" y="-25"/>
+ <point x="1114" y="411"/>
+ <point x="1114" y="780" type="curve" smooth="yes"/>
+ <point x="1114" y="1198"/>
+ <point x="926" y="1485"/>
+ <point x="616" y="1485" type="curve" smooth="yes"/>
+ <point x="349" y="1485"/>
+ <point x="112" y="1306"/>
+ <point x="112" y="1002" type="curve" smooth="yes"/>
+ <point x="112" y="773"/>
+ <point x="281" y="586"/>
+ <point x="559" y="586" type="curve" smooth="yes"/>
+ <point x="750" y="586"/>
+ <point x="922" y="717"/>
+ <point x="1019" y="878" type="curve"/>
+ <point x="948" y="961" type="line"/>
+ <point x="874" y="847"/>
+ <point x="738" y="760"/>
+ <point x="583" y="760" type="curve" smooth="yes"/>
+ <point x="424" y="760"/>
+ <point x="306" y="860"/>
+ <point x="306" y="1036" type="curve" smooth="yes"/>
+ <point x="306" y="1196"/>
+ <point x="420" y="1310"/>
+ <point x="596" y="1310" type="curve" smooth="yes"/>
+ <point x="837" y="1310"/>
+ <point x="919" y="1065"/>
+ <point x="919" y="813" type="curve" smooth="yes"/>
+ <point x="919" y="326"/>
+ <point x="748" y="150"/>
+ <point x="511" y="150" type="curve" smooth="yes"/>
+ <point x="415" y="150"/>
+ <point x="323" y="174"/>
+ <point x="237" y="260" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/input/font-psf-test/source/PsfTest-Regular.ufo/glyphs/D_igitO_ne.glif b/tests/input/font-psf-test/source/PsfTest-Regular.ufo/glyphs/D_igitO_ne.glif
new file mode 100644
index 0000000..42c7708
--- /dev/null
+++ b/tests/input/font-psf-test/source/PsfTest-Regular.ufo/glyphs/D_igitO_ne.glif
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="DigitOne" format="2">
+ <advance width="1200"/>
+ <unicode hex="0031"/>
+ <anchor x="600" y="-100" name="L"/>
+ <anchor x="600" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="535" y="170" type="line"/>
+ <point x="220" y="170" type="line"/>
+ <point x="220" y="0" type="line"/>
+ <point x="1040" y="0" type="line"/>
+ <point x="1040" y="170" type="line"/>
+ <point x="725" y="170" type="line"/>
+ <point x="725" y="1480" type="line"/>
+ <point x="555" y="1480" type="line"/>
+ <point x="210" y="1268" type="line"/>
+ <point x="235" y="1088" type="line"/>
+ <point x="535" y="1260" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/input/font-psf-test/source/PsfTest-Regular.ufo/glyphs/D_igitS_even.glif b/tests/input/font-psf-test/source/PsfTest-Regular.ufo/glyphs/D_igitS_even.glif
new file mode 100644
index 0000000..c9ca97e
--- /dev/null
+++ b/tests/input/font-psf-test/source/PsfTest-Regular.ufo/glyphs/D_igitS_even.glif
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="DigitSeven" format="2">
+ <advance width="1200"/>
+ <unicode hex="0037"/>
+ <anchor x="600" y="-100" name="L"/>
+ <anchor x="600" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="460" y="0" type="line"/>
+ <point x="589" y="459"/>
+ <point x="794" y="895"/>
+ <point x="1090" y="1300" type="curve"/>
+ <point x="1090" y="1460" type="line"/>
+ <point x="100" y="1460" type="line"/>
+ <point x="100" y="1275" type="line"/>
+ <point x="176" y="1291"/>
+ <point x="292" y="1295"/>
+ <point x="480" y="1295" type="curve" smooth="yes"/>
+ <point x="870" y="1295" type="line"/>
+ <point x="612" y="912"/>
+ <point x="439" y="566"/>
+ <point x="275" y="0" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/input/font-psf-test/source/PsfTest-Regular.ufo/glyphs/D_igitS_ix.glif b/tests/input/font-psf-test/source/PsfTest-Regular.ufo/glyphs/D_igitS_ix.glif
new file mode 100644
index 0000000..ec0acdb
--- /dev/null
+++ b/tests/input/font-psf-test/source/PsfTest-Regular.ufo/glyphs/D_igitS_ix.glif
@@ -0,0 +1,49 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="DigitSix" format="2">
+ <advance width="1200"/>
+ <unicode hex="0036"/>
+ <anchor x="600" y="-100" name="L"/>
+ <anchor x="600" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="1033" y="1395" type="line"/>
+ <point x="929" y="1465"/>
+ <point x="843" y="1485"/>
+ <point x="725" y="1485" type="curve" smooth="yes"/>
+ <point x="250" y="1485"/>
+ <point x="110" y="1049"/>
+ <point x="110" y="680" type="curve" smooth="yes"/>
+ <point x="110" y="242"/>
+ <point x="290" y="-25"/>
+ <point x="600" y="-25" type="curve" smooth="yes"/>
+ <point x="907" y="-25"/>
+ <point x="1115" y="166"/>
+ <point x="1115" y="470" type="curve" smooth="yes"/>
+ <point x="1115" y="719"/>
+ <point x="943" y="895"/>
+ <point x="665" y="895" type="curve" smooth="yes"/>
+ <point x="474" y="895"/>
+ <point x="328" y="780"/>
+ <point x="215" y="625" type="curve"/>
+ <point x="280" y="550" type="line"/>
+ <point x="362" y="653"/>
+ <point x="490" y="720"/>
+ <point x="645" y="720" type="curve" smooth="yes"/>
+ <point x="824" y="720"/>
+ <point x="920" y="611"/>
+ <point x="920" y="435" type="curve" smooth="yes"/>
+ <point x="920" y="275"/>
+ <point x="806" y="150"/>
+ <point x="630" y="150" type="curve" smooth="yes"/>
+ <point x="409" y="150"/>
+ <point x="305" y="393"/>
+ <point x="305" y="645" type="curve" smooth="yes"/>
+ <point x="305" y="1132"/>
+ <point x="478" y="1310"/>
+ <point x="715" y="1310" type="curve" smooth="yes"/>
+ <point x="811" y="1310"/>
+ <point x="903" y="1286"/>
+ <point x="989" y="1200" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/input/font-psf-test/source/PsfTest-Regular.ufo/glyphs/D_igitT_hree.glif b/tests/input/font-psf-test/source/PsfTest-Regular.ufo/glyphs/D_igitT_hree.glif
new file mode 100644
index 0000000..3242c12
--- /dev/null
+++ b/tests/input/font-psf-test/source/PsfTest-Regular.ufo/glyphs/D_igitT_hree.glif
@@ -0,0 +1,52 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="DigitThree" format="2">
+ <advance width="1200"/>
+ <unicode hex="0033"/>
+ <anchor x="600" y="-100" name="L"/>
+ <anchor x="600" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="410" y="870" type="line"/>
+ <point x="410" y="700" type="line"/>
+ <point x="480" y="700" type="line"/>
+ <point x="716" y="700"/>
+ <point x="895" y="588"/>
+ <point x="895" y="425" type="curve" smooth="yes"/>
+ <point x="895" y="241"/>
+ <point x="718" y="150"/>
+ <point x="565" y="150" type="curve" smooth="yes"/>
+ <point x="385" y="150"/>
+ <point x="244" y="232"/>
+ <point x="135" y="355" type="curve"/>
+ <point x="110" y="140" type="line"/>
+ <point x="215" y="42"/>
+ <point x="368" y="-25"/>
+ <point x="545" y="-25" type="curve" smooth="yes"/>
+ <point x="834" y="-25"/>
+ <point x="1090" y="170"/>
+ <point x="1090" y="405" type="curve" smooth="yes"/>
+ <point x="1090" y="672"/>
+ <point x="862" y="776"/>
+ <point x="720" y="800" type="curve"/>
+ <point x="862" y="829"/>
+ <point x="1040" y="957"/>
+ <point x="1040" y="1140" type="curve" smooth="yes"/>
+ <point x="1040" y="1354"/>
+ <point x="828" y="1485"/>
+ <point x="580" y="1485" type="curve"/>
+ <point x="413" y="1485"/>
+ <point x="260" y="1416"/>
+ <point x="180" y="1325" type="curve"/>
+ <point x="215" y="1155" type="line"/>
+ <point x="328" y="1271"/>
+ <point x="436" y="1310"/>
+ <point x="590" y="1310" type="curve" smooth="yes"/>
+ <point x="711" y="1310"/>
+ <point x="850" y="1250"/>
+ <point x="850" y="1115" type="curve" smooth="yes"/>
+ <point x="850" y="991"/>
+ <point x="679" y="870"/>
+ <point x="480" y="870" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/input/font-psf-test/source/PsfTest-Regular.ufo/glyphs/D_igitT_wo.glif b/tests/input/font-psf-test/source/PsfTest-Regular.ufo/glyphs/D_igitT_wo.glif
new file mode 100644
index 0000000..c179477
--- /dev/null
+++ b/tests/input/font-psf-test/source/PsfTest-Regular.ufo/glyphs/D_igitT_wo.glif
@@ -0,0 +1,37 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="DigitTwo" format="2">
+ <advance width="1200"/>
+ <unicode hex="0032"/>
+ <anchor x="600" y="-100" name="L"/>
+ <anchor x="560" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="1080" y="180" type="line"/>
+ <point x="1000" y="166"/>
+ <point x="842" y="165"/>
+ <point x="645" y="165" type="curve" smooth="yes"/>
+ <point x="390" y="165" type="line"/>
+ <point x="609" y="352"/>
+ <point x="1010" y="729"/>
+ <point x="1010" y="1065" type="curve" smooth="yes"/>
+ <point x="1010" y="1323"/>
+ <point x="800" y="1485"/>
+ <point x="560" y="1485" type="curve" smooth="yes"/>
+ <point x="391" y="1485"/>
+ <point x="206" y="1402"/>
+ <point x="125" y="1290" type="curve"/>
+ <point x="170" y="1120" type="line"/>
+ <point x="259" y="1228"/>
+ <point x="402" y="1305"/>
+ <point x="525" y="1305" type="curve" smooth="yes"/>
+ <point x="668" y="1305"/>
+ <point x="810" y="1233"/>
+ <point x="810" y="1045" type="curve" smooth="yes"/>
+ <point x="810" y="768"/>
+ <point x="391" y="365"/>
+ <point x="120" y="170" type="curve"/>
+ <point x="120" y="0" type="line"/>
+ <point x="1080" y="0" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/input/font-psf-test/source/PsfTest-Regular.ufo/glyphs/D_igitZ_ero.glif b/tests/input/font-psf-test/source/PsfTest-Regular.ufo/glyphs/D_igitZ_ero.glif
new file mode 100644
index 0000000..d976d0f
--- /dev/null
+++ b/tests/input/font-psf-test/source/PsfTest-Regular.ufo/glyphs/D_igitZ_ero.glif
@@ -0,0 +1,37 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="DigitZero" format="2">
+ <advance width="1200"/>
+ <unicode hex="0030"/>
+ <anchor x="605" y="-100" name="L"/>
+ <anchor x="605" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="910" y="715" type="curve" smooth="yes"/>
+ <point x="910" y="308"/>
+ <point x="792" y="145"/>
+ <point x="600" y="145" type="curve" smooth="yes"/>
+ <point x="402" y="145"/>
+ <point x="290" y="305"/>
+ <point x="290" y="745" type="curve" smooth="yes"/>
+ <point x="290" y="1153"/>
+ <point x="407" y="1315"/>
+ <point x="600" y="1315" type="curve" smooth="yes"/>
+ <point x="802" y="1315"/>
+ <point x="910" y="1156"/>
+ </contour>
+ <contour>
+ <point x="1110" y="740" type="curve" smooth="yes"/>
+ <point x="1110" y="1286"/>
+ <point x="900" y="1485"/>
+ <point x="610" y="1485" type="curve" smooth="yes"/>
+ <point x="321" y="1485"/>
+ <point x="90" y="1283"/>
+ <point x="90" y="720" type="curve" smooth="yes"/>
+ <point x="90" y="155"/>
+ <point x="301" y="-25"/>
+ <point x="590" y="-25" type="curve" smooth="yes"/>
+ <point x="881" y="-25"/>
+ <point x="1110" y="151"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/input/font-psf-test/source/PsfTest-Regular.ufo/glyphs/D_ollarS_gn.glif b/tests/input/font-psf-test/source/PsfTest-Regular.ufo/glyphs/D_ollarS_gn.glif
new file mode 100644
index 0000000..52136d8
--- /dev/null
+++ b/tests/input/font-psf-test/source/PsfTest-Regular.ufo/glyphs/D_ollarS_gn.glif
@@ -0,0 +1,53 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="DollarSgn" format="2">
+ <advance width="1200"/>
+ <unicode hex="0024"/>
+ <outline>
+ <contour>
+ <point x="553" y="1600" type="line"/>
+ <point x="553" y="-220" type="line"/>
+ <point x="683" y="-220" type="line"/>
+ <point x="683" y="1600" type="line"/>
+ </contour>
+ <contour>
+ <point x="986" y="1306" type="line"/>
+ <point x="866" y="1364"/>
+ <point x="764" y="1389"/>
+ <point x="623" y="1389" type="curve" smooth="yes"/>
+ <point x="317" y="1389"/>
+ <point x="190" y="1173"/>
+ <point x="190" y="1017" type="curve" smooth="yes"/>
+ <point x="190" y="860"/>
+ <point x="253" y="739"/>
+ <point x="540" y="653" type="curve" smooth="yes"/>
+ <point x="827" y="567"/>
+ <point x="871" y="492"/>
+ <point x="871" y="396" type="curve" smooth="yes"/>
+ <point x="871" y="247"/>
+ <point x="734" y="161"/>
+ <point x="586" y="161" type="curve" smooth="yes"/>
+ <point x="450" y="161"/>
+ <point x="316" y="207"/>
+ <point x="195" y="313" type="curve"/>
+ <point x="153" y="124" type="line"/>
+ <point x="247" y="52"/>
+ <point x="408" y="0"/>
+ <point x="586" y="0" type="curve" smooth="yes"/>
+ <point x="837" y="0"/>
+ <point x="1046" y="167"/>
+ <point x="1046" y="414" type="curve" smooth="yes"/>
+ <point x="1046" y="613"/>
+ <point x="912" y="725"/>
+ <point x="669" y="796" type="curve" smooth="yes"/>
+ <point x="406" y="873"/>
+ <point x="365" y="929"/>
+ <point x="365" y="1030" type="curve" smooth="yes"/>
+ <point x="365" y="1132"/>
+ <point x="466" y="1228"/>
+ <point x="613" y="1228" type="curve" smooth="yes"/>
+ <point x="731" y="1228"/>
+ <point x="818" y="1200"/>
+ <point x="949" y="1127" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/input/font-psf-test/source/PsfTest-Regular.ufo/glyphs/D_ottedC_irc.glif b/tests/input/font-psf-test/source/PsfTest-Regular.ufo/glyphs/D_ottedC_irc.glif
new file mode 100644
index 0000000..4cf5cb4
--- /dev/null
+++ b/tests/input/font-psf-test/source/PsfTest-Regular.ufo/glyphs/D_ottedC_irc.glif
@@ -0,0 +1,235 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="DottedCirc" format="2">
+ <advance width="1106"/>
+ <unicode hex="25CC"/>
+ <anchor x="553" y="0" name="H"/>
+ <anchor x="553" y="-100" name="L"/>
+ <anchor x="810" y="0" name="O"/>
+ <anchor x="553" y="1000" name="U"/>
+ <outline>
+ <contour>
+ <point x="443" y="837" type="curve" smooth="yes"/>
+ <point x="443" y="864"/>
+ <point x="423" y="885"/>
+ <point x="398" y="885" type="curve" smooth="yes"/>
+ <point x="371" y="885"/>
+ <point x="348" y="861"/>
+ <point x="348" y="837" type="curve" smooth="yes"/>
+ <point x="348" y="809"/>
+ <point x="372" y="789"/>
+ <point x="398" y="789" type="curve" smooth="yes"/>
+ <point x="425" y="789"/>
+ <point x="443" y="812"/>
+ </contour>
+ <contour>
+ <point x="758" y="79" type="curve" smooth="yes"/>
+ <point x="758" y="106"/>
+ <point x="736" y="127"/>
+ <point x="710" y="127" type="curve" smooth="yes"/>
+ <point x="685" y="127"/>
+ <point x="662" y="103"/>
+ <point x="662" y="80" type="curve" smooth="yes"/>
+ <point x="662" y="52"/>
+ <point x="686" y="31"/>
+ <point x="710" y="31" type="curve" smooth="yes"/>
+ <point x="737" y="31"/>
+ <point x="758" y="55"/>
+ </contour>
+ <contour>
+ <point x="310" y="749" type="curve" smooth="yes"/>
+ <point x="310" y="775"/>
+ <point x="288" y="796"/>
+ <point x="263" y="796" type="curve" smooth="yes"/>
+ <point x="238" y="796"/>
+ <point x="215" y="774"/>
+ <point x="215" y="747" type="curve" smooth="yes"/>
+ <point x="215" y="722"/>
+ <point x="236" y="701"/>
+ <point x="263" y="701" type="curve" smooth="yes"/>
+ <point x="291" y="701"/>
+ <point x="310" y="720"/>
+ </contour>
+ <contour>
+ <point x="891" y="168" type="curve" smooth="yes"/>
+ <point x="891" y="197"/>
+ <point x="870" y="215"/>
+ <point x="843" y="215" type="curve" smooth="yes"/>
+ <point x="817" y="215"/>
+ <point x="795" y="194"/>
+ <point x="795" y="168" type="curve" smooth="yes"/>
+ <point x="795" y="143"/>
+ <point x="816" y="121"/>
+ <point x="843" y="121" type="curve" smooth="yes"/>
+ <point x="871" y="121"/>
+ <point x="891" y="143"/>
+ </contour>
+ <contour>
+ <point x="222" y="613" type="curve" smooth="yes"/>
+ <point x="222" y="640"/>
+ <point x="199" y="663"/>
+ <point x="173" y="663" type="curve" smooth="yes"/>
+ <point x="149" y="663"/>
+ <point x="126" y="642"/>
+ <point x="126" y="615" type="curve" smooth="yes"/>
+ <point x="126" y="591"/>
+ <point x="145" y="567"/>
+ <point x="173" y="567" type="curve" smooth="yes"/>
+ <point x="197" y="567"/>
+ <point x="222" y="587"/>
+ </contour>
+ <contour>
+ <point x="980" y="301" type="curve" smooth="yes"/>
+ <point x="980" y="327"/>
+ <point x="957" y="348"/>
+ <point x="932" y="348" type="curve" smooth="yes"/>
+ <point x="908" y="348"/>
+ <point x="884" y="332"/>
+ <point x="884" y="301" type="curve" smooth="yes"/>
+ <point x="884" y="277"/>
+ <point x="902" y="254"/>
+ <point x="932" y="254" type="curve" smooth="yes"/>
+ <point x="957" y="254"/>
+ <point x="980" y="274"/>
+ </contour>
+ <contour>
+ <point x="191" y="459" type="curve" smooth="yes"/>
+ <point x="191" y="484"/>
+ <point x="168" y="505"/>
+ <point x="143" y="505" type="curve" smooth="yes"/>
+ <point x="116" y="505"/>
+ <point x="95" y="484"/>
+ <point x="95" y="458" type="curve" smooth="yes"/>
+ <point x="95" y="433"/>
+ <point x="115" y="410"/>
+ <point x="143" y="410" type="curve" smooth="yes"/>
+ <point x="167" y="410"/>
+ <point x="191" y="432"/>
+ </contour>
+ <contour>
+ <point x="1011" y="458" type="curve" smooth="yes"/>
+ <point x="1011" y="484"/>
+ <point x="990" y="506"/>
+ <point x="964" y="506" type="curve" smooth="yes"/>
+ <point x="940" y="506"/>
+ <point x="915" y="484"/>
+ <point x="915" y="457" type="curve" smooth="yes"/>
+ <point x="915" y="433"/>
+ <point x="936" y="411"/>
+ <point x="964" y="411" type="curve" smooth="yes"/>
+ <point x="990" y="411"/>
+ <point x="1011" y="433"/>
+ </contour>
+ <contour>
+ <point x="222" y="302" type="curve" smooth="yes"/>
+ <point x="222" y="328"/>
+ <point x="200" y="348"/>
+ <point x="174" y="348" type="curve" smooth="yes"/>
+ <point x="147" y="348"/>
+ <point x="126" y="326"/>
+ <point x="126" y="302" type="curve" smooth="yes"/>
+ <point x="126" y="275"/>
+ <point x="149" y="253"/>
+ <point x="174" y="253" type="curve" smooth="yes"/>
+ <point x="201" y="253"/>
+ <point x="222" y="277"/>
+ </contour>
+ <contour>
+ <point x="980" y="615" type="curve" smooth="yes"/>
+ <point x="980" y="642"/>
+ <point x="955" y="663"/>
+ <point x="931" y="663" type="curve" smooth="yes"/>
+ <point x="904" y="663"/>
+ <point x="885" y="638"/>
+ <point x="885" y="614" type="curve" smooth="yes"/>
+ <point x="885" y="588"/>
+ <point x="907" y="567"/>
+ <point x="931" y="567" type="curve" smooth="yes"/>
+ <point x="959" y="567"/>
+ <point x="980" y="591"/>
+ </contour>
+ <contour>
+ <point x="310" y="168" type="curve" smooth="yes"/>
+ <point x="310" y="195"/>
+ <point x="291" y="215"/>
+ <point x="263" y="215" type="curve" smooth="yes"/>
+ <point x="238" y="215"/>
+ <point x="215" y="190"/>
+ <point x="215" y="168" type="curve" smooth="yes"/>
+ <point x="215" y="143"/>
+ <point x="238" y="120"/>
+ <point x="263" y="120" type="curve" smooth="yes"/>
+ <point x="289" y="120"/>
+ <point x="310" y="143"/>
+ </contour>
+ <contour>
+ <point x="890" y="748" type="curve" smooth="yes"/>
+ <point x="890" y="774"/>
+ <point x="870" y="796"/>
+ <point x="843" y="796" type="curve" smooth="yes"/>
+ <point x="815" y="796"/>
+ <point x="796" y="773"/>
+ <point x="796" y="748" type="curve" smooth="yes"/>
+ <point x="796" y="724"/>
+ <point x="817" y="700"/>
+ <point x="843" y="700" type="curve" smooth="yes"/>
+ <point x="869" y="700"/>
+ <point x="890" y="722"/>
+ </contour>
+ <contour>
+ <point x="444" y="78" type="curve" smooth="yes"/>
+ <point x="444" y="102"/>
+ <point x="423" y="126"/>
+ <point x="396" y="126" type="curve" smooth="yes"/>
+ <point x="370" y="126"/>
+ <point x="348" y="102"/>
+ <point x="348" y="78" type="curve" smooth="yes"/>
+ <point x="348" y="55"/>
+ <point x="370" y="31"/>
+ <point x="396" y="31" type="curve" smooth="yes"/>
+ <point x="420" y="31"/>
+ <point x="444" y="51"/>
+ </contour>
+ <contour>
+ <point x="758" y="836" type="curve" smooth="yes"/>
+ <point x="758" y="861"/>
+ <point x="737" y="885"/>
+ <point x="710" y="885" type="curve" smooth="yes"/>
+ <point x="684" y="885"/>
+ <point x="663" y="862"/>
+ <point x="663" y="838" type="curve" smooth="yes"/>
+ <point x="663" y="814"/>
+ <point x="683" y="789"/>
+ <point x="710" y="789" type="curve" smooth="yes"/>
+ <point x="734" y="789"/>
+ <point x="758" y="809"/>
+ </contour>
+ <contour>
+ <point x="601" y="47" type="curve" smooth="yes"/>
+ <point x="601" y="73"/>
+ <point x="579" y="95"/>
+ <point x="553" y="95" type="curve" smooth="yes"/>
+ <point x="527" y="95"/>
+ <point x="506" y="73"/>
+ <point x="506" y="47" type="curve" smooth="yes"/>
+ <point x="506" y="21"/>
+ <point x="527" y="0"/>
+ <point x="553" y="0" type="curve" smooth="yes"/>
+ <point x="579" y="0"/>
+ <point x="601" y="21"/>
+ </contour>
+ <contour>
+ <point x="601" y="868" type="curve" smooth="yes"/>
+ <point x="601" y="894"/>
+ <point x="579" y="916"/>
+ <point x="553" y="916" type="curve" smooth="yes"/>
+ <point x="527" y="916"/>
+ <point x="506" y="894"/>
+ <point x="506" y="868" type="curve" smooth="yes"/>
+ <point x="506" y="842"/>
+ <point x="527" y="821"/>
+ <point x="553" y="821" type="curve" smooth="yes"/>
+ <point x="579" y="821"/>
+ <point x="601" y="842"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/input/font-psf-test/source/PsfTest-Regular.ufo/glyphs/E_qS_gn.glif b/tests/input/font-psf-test/source/PsfTest-Regular.ufo/glyphs/E_qS_gn.glif
new file mode 100644
index 0000000..1315ffa
--- /dev/null
+++ b/tests/input/font-psf-test/source/PsfTest-Regular.ufo/glyphs/E_qS_gn.glif
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="EqSgn" format="2">
+ <advance width="1200"/>
+ <unicode hex="003D"/>
+ <outline>
+ <contour>
+ <point x="120" y="480" type="line"/>
+ <point x="1080" y="480" type="line"/>
+ <point x="1080" y="630" type="line"/>
+ <point x="120" y="630" type="line"/>
+ </contour>
+ <contour>
+ <point x="120" y="830" type="line"/>
+ <point x="1080" y="830" type="line"/>
+ <point x="1080" y="980" type="line"/>
+ <point x="120" y="980" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/input/font-psf-test/source/PsfTest-Regular.ufo/glyphs/E_xclamationM_rk.glif b/tests/input/font-psf-test/source/PsfTest-Regular.ufo/glyphs/E_xclamationM_rk.glif
new file mode 100644
index 0000000..e683644
--- /dev/null
+++ b/tests/input/font-psf-test/source/PsfTest-Regular.ufo/glyphs/E_xclamationM_rk.glif
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="ExclamationMrk" format="2">
+ <advance width="764"/>
+ <unicode hex="0021"/>
+ <outline>
+ <contour>
+ <point x="450" y="440" type="line"/>
+ <point x="456" y="730"/>
+ <point x="451" y="1076"/>
+ <point x="490" y="1510" type="curve"/>
+ <point x="235" y="1510" type="line"/>
+ <point x="273" y="1076"/>
+ <point x="268" y="730"/>
+ <point x="275" y="440" type="curve"/>
+ </contour>
+ <contour>
+ <point x="225" y="110" type="curve" smooth="yes"/>
+ <point x="225" y="36"/>
+ <point x="286" y="-25"/>
+ <point x="360" y="-25" type="curve" smooth="yes"/>
+ <point x="434" y="-25"/>
+ <point x="495" y="36"/>
+ <point x="495" y="110" type="curve" smooth="yes"/>
+ <point x="495" y="184"/>
+ <point x="434" y="245"/>
+ <point x="360" y="245" type="curve" smooth="yes"/>
+ <point x="286" y="245"/>
+ <point x="225" y="184"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/input/font-psf-test/source/PsfTest-Regular.ufo/glyphs/F_ullS_top.glif b/tests/input/font-psf-test/source/PsfTest-Regular.ufo/glyphs/F_ullS_top.glif
new file mode 100644
index 0000000..9f3a3f0
--- /dev/null
+++ b/tests/input/font-psf-test/source/PsfTest-Regular.ufo/glyphs/F_ullS_top.glif
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="FullStop" format="2">
+ <advance width="640"/>
+ <unicode hex="002E"/>
+ <outline>
+ <contour>
+ <point x="185" y="110" type="curve" smooth="yes"/>
+ <point x="185" y="36"/>
+ <point x="246" y="-25"/>
+ <point x="320" y="-25" type="curve" smooth="yes"/>
+ <point x="394" y="-25"/>
+ <point x="455" y="36"/>
+ <point x="455" y="110" type="curve" smooth="yes"/>
+ <point x="455" y="184"/>
+ <point x="394" y="245"/>
+ <point x="320" y="245" type="curve" smooth="yes"/>
+ <point x="246" y="245"/>
+ <point x="185" y="184"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/input/font-psf-test/source/PsfTest-Regular.ufo/glyphs/G_T_S_gn.glif b/tests/input/font-psf-test/source/PsfTest-Regular.ufo/glyphs/G_T_S_gn.glif
new file mode 100644
index 0000000..c591997
--- /dev/null
+++ b/tests/input/font-psf-test/source/PsfTest-Regular.ufo/glyphs/G_T_S_gn.glif
@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="GTSgn" format="2">
+ <advance width="1200"/>
+ <unicode hex="003E"/>
+ <outline>
+ <contour>
+ <point x="120" y="1035" type="line"/>
+ <point x="910" y="730" type="line"/>
+ <point x="120" y="425" type="line"/>
+ <point x="120" y="245" type="line"/>
+ <point x="1100" y="645" type="line"/>
+ <point x="1100" y="815" type="line"/>
+ <point x="120" y="1215" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/input/font-psf-test/source/PsfTest-Regular.ufo/glyphs/G_raveA_ccent.glif b/tests/input/font-psf-test/source/PsfTest-Regular.ufo/glyphs/G_raveA_ccent.glif
new file mode 100644
index 0000000..a0a0004
--- /dev/null
+++ b/tests/input/font-psf-test/source/PsfTest-Regular.ufo/glyphs/G_raveA_ccent.glif
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="GraveAccent" format="2">
+ <advance width="580"/>
+ <unicode hex="0060"/>
+ <outline>
+ <component base="CombGrave" xOffset="940"/>
+ </outline>
+</glyph>
diff --git a/tests/input/font-psf-test/source/PsfTest-Regular.ufo/glyphs/H_yphen.glif b/tests/input/font-psf-test/source/PsfTest-Regular.ufo/glyphs/H_yphen.glif
new file mode 100644
index 0000000..fabf6ce
--- /dev/null
+++ b/tests/input/font-psf-test/source/PsfTest-Regular.ufo/glyphs/H_yphen.glif
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="Hyphen" format="2">
+ <advance width="860"/>
+ <unicode hex="2010"/>
+ <anchor x="430" y="1100" name="U"/>
+ <outline>
+ <contour>
+ <point x="80" y="555" type="line"/>
+ <point x="780" y="555" type="line"/>
+ <point x="780" y="705" type="line"/>
+ <point x="80" y="705" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/input/font-psf-test/source/PsfTest-Regular.ufo/glyphs/H_yphenM_inus.glif b/tests/input/font-psf-test/source/PsfTest-Regular.ufo/glyphs/H_yphenM_inus.glif
new file mode 100644
index 0000000..bc3f4eb
--- /dev/null
+++ b/tests/input/font-psf-test/source/PsfTest-Regular.ufo/glyphs/H_yphenM_inus.glif
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="HyphenMinus" format="2">
+ <advance width="860"/>
+ <unicode hex="002D"/>
+ <anchor x="430" y="1100" name="U"/>
+ <outline>
+ <contour>
+ <point x="80" y="555" type="line"/>
+ <point x="780" y="555" type="line"/>
+ <point x="780" y="705" type="line"/>
+ <point x="80" y="705" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/input/font-psf-test/source/PsfTest-Regular.ufo/glyphs/H_yphen_S_oft.glif b/tests/input/font-psf-test/source/PsfTest-Regular.ufo/glyphs/H_yphen_S_oft.glif
new file mode 100644
index 0000000..293b653
--- /dev/null
+++ b/tests/input/font-psf-test/source/PsfTest-Regular.ufo/glyphs/H_yphen_S_oft.glif
@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="Hyphen_Soft" format="2">
+ <advance width="860"/>
+ <unicode hex="00AD"/>
+ <anchor x="430" y="1100" name="U"/>
+ <outline>
+ <component base="HyphenMinus"/>
+ </outline>
+</glyph>
diff --git a/tests/input/font-psf-test/source/PsfTest-Regular.ufo/glyphs/L_T_S_gn.glif b/tests/input/font-psf-test/source/PsfTest-Regular.ufo/glyphs/L_T_S_gn.glif
new file mode 100644
index 0000000..db9ae78
--- /dev/null
+++ b/tests/input/font-psf-test/source/PsfTest-Regular.ufo/glyphs/L_T_S_gn.glif
@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LTSgn" format="2">
+ <advance width="1200"/>
+ <unicode hex="003C"/>
+ <outline>
+ <contour>
+ <point x="1080" y="425" type="line"/>
+ <point x="290" y="730" type="line"/>
+ <point x="1080" y="1035" type="line"/>
+ <point x="1080" y="1215" type="line"/>
+ <point x="100" y="815" type="line"/>
+ <point x="100" y="645" type="line"/>
+ <point x="1080" y="245" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/input/font-psf-test/source/PsfTest-Regular.ufo/glyphs/L_ftC_urlyB_rac.glif b/tests/input/font-psf-test/source/PsfTest-Regular.ufo/glyphs/L_ftC_urlyB_rac.glif
new file mode 100644
index 0000000..bc7ef03
--- /dev/null
+++ b/tests/input/font-psf-test/source/PsfTest-Regular.ufo/glyphs/L_ftC_urlyB_rac.glif
@@ -0,0 +1,47 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LftCurlyBrac" format="2">
+ <advance width="1000"/>
+ <unicode hex="007B"/>
+ <outline>
+ <contour>
+ <point x="210" y="615" type="curve" smooth="yes"/>
+ <point x="210" y="583"/>
+ <point x="383" y="486"/>
+ <point x="410" y="450" type="curve" smooth="yes"/>
+ <point x="434" y="418"/>
+ <point x="424" y="-205"/>
+ <point x="495" y="-285" type="curve" smooth="yes"/>
+ <point x="535" y="-330"/>
+ <point x="696" y="-383"/>
+ <point x="800" y="-410" type="curve"/>
+ <point x="840" y="-270" type="line"/>
+ <point x="773" y="-247"/>
+ <point x="650" y="-198"/>
+ <point x="630" y="-170" type="curve" smooth="yes"/>
+ <point x="597" y="-123"/>
+ <point x="610" y="447"/>
+ <point x="590" y="485" type="curve" smooth="yes"/>
+ <point x="571" y="521"/>
+ <point x="434" y="593"/>
+ <point x="430" y="615" type="curve"/>
+ <point x="434" y="637"/>
+ <point x="571" y="709"/>
+ <point x="590" y="745" type="curve" smooth="yes"/>
+ <point x="610" y="783"/>
+ <point x="597" y="1353"/>
+ <point x="630" y="1400" type="curve" smooth="yes"/>
+ <point x="650" y="1428"/>
+ <point x="773" y="1477"/>
+ <point x="840" y="1500" type="curve"/>
+ <point x="800" y="1640" type="line"/>
+ <point x="696" y="1613"/>
+ <point x="535" y="1560"/>
+ <point x="495" y="1515" type="curve" smooth="yes"/>
+ <point x="424" y="1435"/>
+ <point x="434" y="812"/>
+ <point x="410" y="780" type="curve" smooth="yes"/>
+ <point x="383" y="744"/>
+ <point x="210" y="647"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/input/font-psf-test/source/PsfTest-Regular.ufo/glyphs/L_ftP_aren.glif b/tests/input/font-psf-test/source/PsfTest-Regular.ufo/glyphs/L_ftP_aren.glif
new file mode 100644
index 0000000..a4b9814
--- /dev/null
+++ b/tests/input/font-psf-test/source/PsfTest-Regular.ufo/glyphs/L_ftP_aren.glif
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LftParen" format="2">
+ <advance width="795"/>
+ <unicode hex="0028"/>
+ <outline>
+ <contour>
+ <point x="115" y="625" type="curve" smooth="yes"/>
+ <point x="115" y="218"/>
+ <point x="260" y="-125"/>
+ <point x="535" y="-410" type="curve"/>
+ <point x="630" y="-265" type="line"/>
+ <point x="395" y="-8"/>
+ <point x="305" y="278"/>
+ <point x="305" y="625" type="curve" smooth="yes"/>
+ <point x="305" y="982"/>
+ <point x="395" y="1280"/>
+ <point x="630" y="1485" type="curve"/>
+ <point x="555" y="1640" type="line"/>
+ <point x="290" y="1444"/>
+ <point x="115" y="1062"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/input/font-psf-test/source/PsfTest-Regular.ufo/glyphs/L_ftS_qrB_rac.glif b/tests/input/font-psf-test/source/PsfTest-Regular.ufo/glyphs/L_ftS_qrB_rac.glif
new file mode 100644
index 0000000..e97ed98
--- /dev/null
+++ b/tests/input/font-psf-test/source/PsfTest-Regular.ufo/glyphs/L_ftS_qrB_rac.glif
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LftSqrBrac" format="2">
+ <advance width="790"/>
+ <unicode hex="005B"/>
+ <outline>
+ <contour>
+ <point x="640" y="-410" type="line"/>
+ <point x="640" y="-260" type="line"/>
+ <point x="385" y="-260" type="line"/>
+ <point x="385" y="1450" type="line"/>
+ <point x="640" y="1450" type="line"/>
+ <point x="640" y="1600" type="line"/>
+ <point x="200" y="1600" type="line"/>
+ <point x="200" y="-410" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/input/font-psf-test/source/PsfTest-Regular.ufo/glyphs/L_owL_ine.glif b/tests/input/font-psf-test/source/PsfTest-Regular.ufo/glyphs/L_owL_ine.glif
new file mode 100644
index 0000000..2fc71eb
--- /dev/null
+++ b/tests/input/font-psf-test/source/PsfTest-Regular.ufo/glyphs/L_owL_ine.glif
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LowLine" format="2">
+ <advance width="1274"/>
+ <unicode hex="005F"/>
+ <outline>
+ <contour>
+ <point x="0" y="-320" type="line"/>
+ <point x="1274" y="-320" type="line"/>
+ <point x="1274" y="-170" type="line"/>
+ <point x="0" y="-170" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/input/font-psf-test/source/PsfTest-Regular.ufo/glyphs/L_tnC_apA_.alt.glif b/tests/input/font-psf-test/source/PsfTest-Regular.ufo/glyphs/L_tnC_apA_.alt.glif
new file mode 100644
index 0000000..fbdfff2
--- /dev/null
+++ b/tests/input/font-psf-test/source/PsfTest-Regular.ufo/glyphs/L_tnC_apA_.alt.glif
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnCapA.alt" format="2">
+ <advance width="1395"/>
+ <anchor x="668" y="1460" name="H"/>
+ <anchor x="688" y="1560" name="L"/>
+ <anchor x="-75" y="1460" name="O"/>
+ <anchor x="688" y="-70" name="U"/>
+ <outline>
+ <contour>
+ <point x="1130" y="1460" type="line"/>
+ <point x="996" y="1075" type="line"/>
+ <point x="381" y="1075" type="line"/>
+ <point x="245" y="1460" type="line"/>
+ <point x="40" y="1460" type="line"/>
+ <point x="75" y="1380"/>
+ <point x="113" y="1291"/>
+ <point x="180" y="1105" type="curve" smooth="yes"/>
+ <point x="580" y="0" type="line"/>
+ <point x="795" y="0" type="line"/>
+ <point x="1195" y="1105" type="line" smooth="yes"/>
+ <point x="1263" y="1292"/>
+ <point x="1299" y="1379"/>
+ <point x="1335" y="1460" type="curve"/>
+ </contour>
+ <contour>
+ <point x="435" y="920" type="line"/>
+ <point x="942" y="920" type="line"/>
+ <point x="690" y="195" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/input/font-psf-test/source/PsfTest-Regular.ufo/glyphs/L_tnC_apA_.glif b/tests/input/font-psf-test/source/PsfTest-Regular.ufo/glyphs/L_tnC_apA_.glif
new file mode 100644
index 0000000..3c64e18
--- /dev/null
+++ b/tests/input/font-psf-test/source/PsfTest-Regular.ufo/glyphs/L_tnC_apA_.glif
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnCapA" format="2">
+ <advance width="1395"/>
+ <unicode hex="0041"/>
+ <anchor x="707" y="0" name="H"/>
+ <anchor x="687" y="-100" name="L"/>
+ <anchor x="1450" y="0" name="O"/>
+ <anchor x="687" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="245" y="0" type="line"/>
+ <point x="379" y="385" type="line"/>
+ <point x="994" y="385" type="line"/>
+ <point x="1130" y="0" type="line"/>
+ <point x="1335" y="0" type="line"/>
+ <point x="1300" y="80"/>
+ <point x="1262" y="169"/>
+ <point x="1195" y="355" type="curve" smooth="yes"/>
+ <point x="795" y="1460" type="line"/>
+ <point x="580" y="1460" type="line"/>
+ <point x="180" y="355" type="line" smooth="yes"/>
+ <point x="112" y="168"/>
+ <point x="76" y="81"/>
+ <point x="40" y="0" type="curve"/>
+ </contour>
+ <contour>
+ <point x="940" y="540" type="line"/>
+ <point x="433" y="540" type="line"/>
+ <point x="685" y="1265" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/input/font-psf-test/source/PsfTest-Regular.ufo/glyphs/L_tnC_apA_D_iaer.glif b/tests/input/font-psf-test/source/PsfTest-Regular.ufo/glyphs/L_tnC_apA_D_iaer.glif
new file mode 100644
index 0000000..b74cc60
--- /dev/null
+++ b/tests/input/font-psf-test/source/PsfTest-Regular.ufo/glyphs/L_tnC_apA_D_iaer.glif
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnCapADiaer" format="2">
+ <advance width="1395"/>
+ <unicode hex="00C4"/>
+ <anchor x="707" y="0" name="H"/>
+ <anchor x="687" y="-100" name="L"/>
+ <anchor x="1450" y="0" name="O"/>
+ <anchor x="687" y="1935" name="U"/>
+ <outline>
+ <component base="LtnCapA"/>
+ <component base="CombDiaer" xOffset="1257" yOffset="430"/>
+ </outline>
+</glyph>
diff --git a/tests/input/font-psf-test/source/PsfTest-Regular.ufo/glyphs/L_tnC_apB_.glif b/tests/input/font-psf-test/source/PsfTest-Regular.ufo/glyphs/L_tnC_apB_.glif
new file mode 100644
index 0000000..415122e
--- /dev/null
+++ b/tests/input/font-psf-test/source/PsfTest-Regular.ufo/glyphs/L_tnC_apB_.glif
@@ -0,0 +1,62 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnCapB" format="2">
+ <advance width="1285"/>
+ <unicode hex="0042"/>
+ <anchor x="615" y="-100" name="L"/>
+ <anchor x="615" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="365" y="1310" type="line"/>
+ <point x="407" y="1312"/>
+ <point x="512" y="1315"/>
+ <point x="590" y="1315" type="curve" smooth="yes"/>
+ <point x="791" y="1315"/>
+ <point x="870" y="1239"/>
+ <point x="870" y="1090" type="curve" smooth="yes"/>
+ <point x="870" y="951"/>
+ <point x="774" y="855"/>
+ <point x="560" y="855" type="curve" smooth="yes"/>
+ <point x="365" y="855" type="line"/>
+ </contour>
+ <contour>
+ <point x="175" y="455" type="line"/>
+ <point x="175" y="257"/>
+ <point x="175" y="80"/>
+ <point x="160" y="0" type="curve"/>
+ <point x="213" y="-5"/>
+ <point x="402" y="-10"/>
+ <point x="605" y="-10" type="curve" smooth="yes"/>
+ <point x="988" y="-10"/>
+ <point x="1140" y="177"/>
+ <point x="1140" y="420" type="curve" smooth="yes"/>
+ <point x="1140" y="669"/>
+ <point x="974" y="759"/>
+ <point x="820" y="800" type="curve"/>
+ <point x="956" y="852"/>
+ <point x="1065" y="952"/>
+ <point x="1065" y="1120" type="curve" smooth="yes"/>
+ <point x="1065" y="1381"/>
+ <point x="897" y="1470"/>
+ <point x="600" y="1470" type="curve" smooth="yes"/>
+ <point x="431" y="1470"/>
+ <point x="248" y="1466"/>
+ <point x="160" y="1460" type="curve"/>
+ <point x="175" y="1380"/>
+ <point x="175" y="1196"/>
+ <point x="175" y="1000" type="curve" smooth="yes"/>
+ </contour>
+ <contour>
+ <point x="365" y="700" type="line"/>
+ <point x="600" y="700" type="line" smooth="yes"/>
+ <point x="833" y="700"/>
+ <point x="945" y="604"/>
+ <point x="945" y="420" type="curve" smooth="yes"/>
+ <point x="945" y="212"/>
+ <point x="781" y="150"/>
+ <point x="610" y="150" type="curve" smooth="yes"/>
+ <point x="498" y="150"/>
+ <point x="402" y="153"/>
+ <point x="365" y="155" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/input/font-psf-test/source/PsfTest-Regular.ufo/glyphs/L_tnC_apC_.glif b/tests/input/font-psf-test/source/PsfTest-Regular.ufo/glyphs/L_tnC_apC_.glif
new file mode 100644
index 0000000..daf4f2d
--- /dev/null
+++ b/tests/input/font-psf-test/source/PsfTest-Regular.ufo/glyphs/L_tnC_apC_.glif
@@ -0,0 +1,38 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnCapC" format="2">
+ <advance width="1355"/>
+ <unicode hex="0043"/>
+ <anchor x="750" y="0" name="H"/>
+ <anchor x="750" y="-100" name="L"/>
+ <anchor x="750" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="1190" y="335" type="line"/>
+ <point x="1078" y="223"/>
+ <point x="912" y="150"/>
+ <point x="760" y="150" type="curve" smooth="yes"/>
+ <point x="489" y="150"/>
+ <point x="290" y="376"/>
+ <point x="290" y="735" type="curve" smooth="yes"/>
+ <point x="290" y="1119"/>
+ <point x="491" y="1315"/>
+ <point x="770" y="1315" type="curve" smooth="yes"/>
+ <point x="891" y="1315"/>
+ <point x="1030" y="1278"/>
+ <point x="1155" y="1165" type="curve"/>
+ <point x="1215" y="1345" type="line"/>
+ <point x="1072" y="1452"/>
+ <point x="913" y="1485"/>
+ <point x="770" y="1485" type="curve" smooth="yes"/>
+ <point x="418" y="1485"/>
+ <point x="95" y="1225"/>
+ <point x="95" y="710" type="curve" smooth="yes"/>
+ <point x="95" y="260"/>
+ <point x="346" y="-25"/>
+ <point x="750" y="-25" type="curve" smooth="yes"/>
+ <point x="902" y="-25"/>
+ <point x="1114" y="32"/>
+ <point x="1230" y="140" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/input/font-psf-test/source/PsfTest-Regular.ufo/glyphs/L_tnC_apD_.glif b/tests/input/font-psf-test/source/PsfTest-Regular.ufo/glyphs/L_tnC_apD_.glif
new file mode 100644
index 0000000..9154a06
--- /dev/null
+++ b/tests/input/font-psf-test/source/PsfTest-Regular.ufo/glyphs/L_tnC_apD_.glif
@@ -0,0 +1,45 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnCapD" format="2">
+ <advance width="1435"/>
+ <unicode hex="0044"/>
+ <anchor x="715" y="-100" name="L"/>
+ <anchor x="715" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="175" y="455" type="line"/>
+ <point x="174" y="257"/>
+ <point x="175" y="80"/>
+ <point x="160" y="0" type="curve"/>
+ <point x="160" y="0"/>
+ <point x="467" y="-10"/>
+ <point x="595" y="-10" type="curve" smooth="yes"/>
+ <point x="888" y="-10"/>
+ <point x="1315" y="145"/>
+ <point x="1315" y="740" type="curve" smooth="yes"/>
+ <point x="1315" y="1394"/>
+ <point x="829" y="1470"/>
+ <point x="615" y="1470" type="curve" smooth="yes"/>
+ <point x="480" y="1470"/>
+ <point x="245" y="1466"/>
+ <point x="160" y="1460" type="curve"/>
+ <point x="175" y="1380"/>
+ <point x="175" y="1196"/>
+ <point x="175" y="1000" type="curve" smooth="yes"/>
+ </contour>
+ <contour>
+ <point x="365" y="1305" type="line"/>
+ <point x="415" y="1307"/>
+ <point x="524" y="1310"/>
+ <point x="590" y="1310" type="curve" smooth="yes"/>
+ <point x="878" y="1310"/>
+ <point x="1120" y="1167"/>
+ <point x="1120" y="720" type="curve" smooth="yes"/>
+ <point x="1120" y="308"/>
+ <point x="853" y="155"/>
+ <point x="585" y="155" type="curve" smooth="yes"/>
+ <point x="490" y="155"/>
+ <point x="412" y="161"/>
+ <point x="365" y="165" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/input/font-psf-test/source/PsfTest-Regular.ufo/glyphs/L_tnC_apE_.glif b/tests/input/font-psf-test/source/PsfTest-Regular.ufo/glyphs/L_tnC_apE_.glif
new file mode 100644
index 0000000..e5d0043
--- /dev/null
+++ b/tests/input/font-psf-test/source/PsfTest-Regular.ufo/glyphs/L_tnC_apE_.glif
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnCapE" format="2">
+ <advance width="1160"/>
+ <unicode hex="0045"/>
+ <anchor x="600" y="0" name="H"/>
+ <anchor x="600" y="-100" name="L"/>
+ <anchor x="917" y="0" name="O"/>
+ <anchor x="1160" y="1200" name="R"/>
+ <anchor x="600" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="365" y="845" type="line"/>
+ <point x="365" y="1295" type="line"/>
+ <point x="1010" y="1295" type="line"/>
+ <point x="1010" y="1460" type="line"/>
+ <point x="160" y="1460" type="line"/>
+ <point x="175" y="1380"/>
+ <point x="175" y="1222"/>
+ <point x="175" y="1025" type="curve" smooth="yes"/>
+ <point x="175" y="435" type="line" smooth="yes"/>
+ <point x="175" y="238"/>
+ <point x="175" y="80"/>
+ <point x="160" y="0" type="curve"/>
+ <point x="1040" y="0" type="line"/>
+ <point x="1040" y="180" type="line"/>
+ <point x="960" y="166"/>
+ <point x="826" y="165"/>
+ <point x="629" y="165" type="curve" smooth="yes"/>
+ <point x="365" y="165" type="line"/>
+ <point x="365" y="685" type="line"/>
+ <point x="935" y="685" type="line"/>
+ <point x="935" y="845" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/input/font-psf-test/source/PsfTest-Regular.ufo/glyphs/L_tnC_apF_.glif b/tests/input/font-psf-test/source/PsfTest-Regular.ufo/glyphs/L_tnC_apF_.glif
new file mode 100644
index 0000000..deb38fb
--- /dev/null
+++ b/tests/input/font-psf-test/source/PsfTest-Regular.ufo/glyphs/L_tnC_apF_.glif
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnCapF" format="2">
+ <advance width="1150"/>
+ <unicode hex="0046"/>
+ <anchor x="595" y="-100" name="L"/>
+ <anchor x="595" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="365" y="835" type="line"/>
+ <point x="365" y="1295" type="line"/>
+ <point x="1030" y="1295" type="line"/>
+ <point x="1030" y="1460" type="line"/>
+ <point x="160" y="1460" type="line"/>
+ <point x="175" y="1380"/>
+ <point x="175" y="1217"/>
+ <point x="175" y="1020" type="curve" smooth="yes"/>
+ <point x="175" y="435" type="line" smooth="yes"/>
+ <point x="175" y="238"/>
+ <point x="175" y="80"/>
+ <point x="160" y="0" type="curve"/>
+ <point x="380" y="0" type="line"/>
+ <point x="365" y="78"/>
+ <point x="365" y="237"/>
+ <point x="365" y="435" type="curve" smooth="yes"/>
+ <point x="365" y="675" type="line"/>
+ <point x="945" y="675" type="line"/>
+ <point x="945" y="835" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/input/font-psf-test/source/PsfTest-Regular.ufo/glyphs/L_tnC_apG_.glif b/tests/input/font-psf-test/source/PsfTest-Regular.ufo/glyphs/L_tnC_apG_.glif
new file mode 100644
index 0000000..477d223
--- /dev/null
+++ b/tests/input/font-psf-test/source/PsfTest-Regular.ufo/glyphs/L_tnC_apG_.glif
@@ -0,0 +1,42 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnCapG" format="2">
+ <advance width="1420"/>
+ <unicode hex="0047"/>
+ <anchor x="745" y="0" name="H"/>
+ <anchor x="745" y="-100" name="L"/>
+ <anchor x="745" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="1275" y="745" type="line"/>
+ <point x="735" y="745" type="line"/>
+ <point x="735" y="580" type="line"/>
+ <point x="1085" y="580" type="line"/>
+ <point x="1085" y="245" type="line"/>
+ <point x="963" y="171"/>
+ <point x="876" y="150"/>
+ <point x="757" y="150" type="curve" smooth="yes"/>
+ <point x="471" y="150"/>
+ <point x="290" y="377"/>
+ <point x="290" y="745" type="curve" smooth="yes"/>
+ <point x="290" y="1094"/>
+ <point x="480" y="1315"/>
+ <point x="785" y="1315" type="curve" smooth="yes"/>
+ <point x="918" y="1315"/>
+ <point x="1046" y="1286"/>
+ <point x="1195" y="1165" type="curve"/>
+ <point x="1260" y="1345" type="line"/>
+ <point x="1085" y="1462"/>
+ <point x="947" y="1485"/>
+ <point x="785" y="1485" type="curve" smooth="yes"/>
+ <point x="402" y="1485"/>
+ <point x="95" y="1199"/>
+ <point x="95" y="720" type="curve" smooth="yes"/>
+ <point x="95" y="241"/>
+ <point x="367" y="-25"/>
+ <point x="745" y="-25" type="curve" smooth="yes"/>
+ <point x="918" y="-25"/>
+ <point x="1070" y="11"/>
+ <point x="1275" y="155" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/input/font-psf-test/source/PsfTest-Regular.ufo/glyphs/L_tnC_apH_.glif b/tests/input/font-psf-test/source/PsfTest-Regular.ufo/glyphs/L_tnC_apH_.glif
new file mode 100644
index 0000000..5924270
--- /dev/null
+++ b/tests/input/font-psf-test/source/PsfTest-Regular.ufo/glyphs/L_tnC_apH_.glif
@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnCapH" format="2">
+ <advance width="1475"/>
+ <unicode hex="0048"/>
+ <anchor x="285" y="0" name="H"/>
+ <anchor x="725" y="-100" name="L"/>
+ <anchor x="725" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="1290" y="0" type="line"/>
+ <point x="1275" y="80"/>
+ <point x="1275" y="238"/>
+ <point x="1275" y="435" type="curve" smooth="yes"/>
+ <point x="1275" y="1025" type="line" smooth="yes"/>
+ <point x="1275" y="1222"/>
+ <point x="1275" y="1380"/>
+ <point x="1290" y="1460" type="curve"/>
+ <point x="1085" y="1460" type="line"/>
+ <point x="1085" y="835" type="line"/>
+ <point x="365" y="835" type="line"/>
+ <point x="365" y="1460" type="line"/>
+ <point x="160" y="1460" type="line"/>
+ <point x="175" y="1380"/>
+ <point x="175" y="1222"/>
+ <point x="175" y="1025" type="curve" smooth="yes"/>
+ <point x="175" y="435" type="line" smooth="yes"/>
+ <point x="175" y="238"/>
+ <point x="175" y="80"/>
+ <point x="160" y="0" type="curve"/>
+ <point x="365" y="0" type="line"/>
+ <point x="365" y="675" type="line"/>
+ <point x="1085" y="675" type="line"/>
+ <point x="1085" y="0" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/input/font-psf-test/source/PsfTest-Regular.ufo/glyphs/L_tnC_apI_.glif b/tests/input/font-psf-test/source/PsfTest-Regular.ufo/glyphs/L_tnC_apI_.glif
new file mode 100644
index 0000000..c6001c3
--- /dev/null
+++ b/tests/input/font-psf-test/source/PsfTest-Regular.ufo/glyphs/L_tnC_apI_.glif
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnCapI" format="2">
+ <advance width="975"/>
+ <unicode hex="0049"/>
+ <anchor x="477" y="0" name="H"/>
+ <anchor x="477" y="-100" name="L"/>
+ <anchor x="673" y="0" name="O"/>
+ <anchor x="975" y="1200" name="R"/>
+ <anchor x="477" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="140" y="1460" type="line"/>
+ <point x="140" y="1315" type="line"/>
+ <point x="380" y="1315" type="line"/>
+ <point x="380" y="145" type="line"/>
+ <point x="140" y="145" type="line"/>
+ <point x="140" y="0" type="line"/>
+ <point x="815" y="0" type="line"/>
+ <point x="815" y="145" type="line"/>
+ <point x="570" y="145" type="line"/>
+ <point x="570" y="1315" type="line"/>
+ <point x="815" y="1315" type="line"/>
+ <point x="815" y="1460" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/input/font-psf-test/source/PsfTest-Regular.ufo/glyphs/L_tnC_apJ_.glif b/tests/input/font-psf-test/source/PsfTest-Regular.ufo/glyphs/L_tnC_apJ_.glif
new file mode 100644
index 0000000..457e39d
--- /dev/null
+++ b/tests/input/font-psf-test/source/PsfTest-Regular.ufo/glyphs/L_tnC_apJ_.glif
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnCapJ" format="2">
+ <advance width="965"/>
+ <unicode hex="004A"/>
+ <anchor x="410" y="-100" name="L"/>
+ <anchor x="675" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="575" y="1460" type="line"/>
+ <point x="588" y="1354"/>
+ <point x="590" y="1175"/>
+ <point x="590" y="980" type="curve"/>
+ <point x="590" y="485" type="line" smooth="yes"/>
+ <point x="590" y="256"/>
+ <point x="487" y="155"/>
+ <point x="340" y="155" type="curve" smooth="yes"/>
+ <point x="248" y="155"/>
+ <point x="147" y="198"/>
+ <point x="80" y="275" type="curve"/>
+ <point x="35" y="90" type="line"/>
+ <point x="106" y="9"/>
+ <point x="250" y="-25"/>
+ <point x="345" y="-25" type="curve" smooth="yes"/>
+ <point x="602" y="-25"/>
+ <point x="780" y="119"/>
+ <point x="780" y="535" type="curve" smooth="yes"/>
+ <point x="780" y="1460" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/input/font-psf-test/source/PsfTest-Regular.ufo/glyphs/L_tnC_apK_.glif b/tests/input/font-psf-test/source/PsfTest-Regular.ufo/glyphs/L_tnC_apK_.glif
new file mode 100644
index 0000000..b3f4cdd
--- /dev/null
+++ b/tests/input/font-psf-test/source/PsfTest-Regular.ufo/glyphs/L_tnC_apK_.glif
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnCapK" format="2">
+ <advance width="1310"/>
+ <unicode hex="004B"/>
+ <anchor x="270" y="0" name="H"/>
+ <anchor x="695" y="-100" name="L"/>
+ <anchor x="650" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="925" y="1460" type="line"/>
+ <point x="295" y="703" type="line"/>
+ <point x="425" y="745" type="line"/>
+ <point x="530" y="740" type="line"/>
+ <point x="1165" y="1460" type="line"/>
+ </contour>
+ <contour>
+ <point x="350" y="735" type="line"/>
+ <point x="985" y="0" type="line"/>
+ <point x="1230" y="0" type="line"/>
+ <point x="485" y="860" type="line"/>
+ </contour>
+ <contour>
+ <point x="365" y="1460" type="line"/>
+ <point x="160" y="1460" type="line"/>
+ <point x="175" y="1380"/>
+ <point x="175" y="1222"/>
+ <point x="175" y="1025" type="curve" smooth="yes"/>
+ <point x="175" y="435" type="line" smooth="yes"/>
+ <point x="175" y="238"/>
+ <point x="175" y="80"/>
+ <point x="160" y="0" type="curve"/>
+ <point x="365" y="0" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/input/font-psf-test/source/PsfTest-Regular.ufo/glyphs/L_tnC_apL_.glif b/tests/input/font-psf-test/source/PsfTest-Regular.ufo/glyphs/L_tnC_apL_.glif
new file mode 100644
index 0000000..3d5883a
--- /dev/null
+++ b/tests/input/font-psf-test/source/PsfTest-Regular.ufo/glyphs/L_tnC_apL_.glif
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnCapL" format="2">
+ <advance width="1080"/>
+ <unicode hex="004C"/>
+ <anchor x="592" y="0" name="H"/>
+ <anchor x="592" y="-100" name="L"/>
+ <anchor x="540" y="1200" name="R"/>
+ <anchor x="592" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="365" y="165" type="line"/>
+ <point x="365" y="1460" type="line"/>
+ <point x="160" y="1460" type="line"/>
+ <point x="175" y="1380"/>
+ <point x="175" y="1222"/>
+ <point x="175" y="1025" type="curve" smooth="yes"/>
+ <point x="175" y="435" type="line" smooth="yes"/>
+ <point x="175" y="238"/>
+ <point x="175" y="80"/>
+ <point x="160" y="0" type="curve"/>
+ <point x="1025" y="0" type="line"/>
+ <point x="1025" y="180" type="line"/>
+ <point x="945" y="166"/>
+ <point x="786" y="165"/>
+ <point x="589" y="165" type="curve" smooth="yes"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/input/font-psf-test/source/PsfTest-Regular.ufo/glyphs/L_tnC_apM_.glif b/tests/input/font-psf-test/source/PsfTest-Regular.ufo/glyphs/L_tnC_apM_.glif
new file mode 100644
index 0000000..fbdf3b1
--- /dev/null
+++ b/tests/input/font-psf-test/source/PsfTest-Regular.ufo/glyphs/L_tnC_apM_.glif
@@ -0,0 +1,37 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnCapM" format="2">
+ <advance width="1795"/>
+ <unicode hex="004D"/>
+ <anchor x="1521" y="0" name="H"/>
+ <anchor x="885" y="-100" name="L"/>
+ <anchor x="885" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="885" y="205" type="line"/>
+ <point x="455" y="1460" type="line"/>
+ <point x="285" y="1460" type="line"/>
+ <point x="790" y="0" type="line"/>
+ <point x="985" y="0" type="line"/>
+ <point x="1487" y="1460" type="line"/>
+ <point x="1320" y="1460" type="line"/>
+ </contour>
+ <contour>
+ <point x="230" y="1460" type="line"/>
+ <point x="230" y="1460"/>
+ <point x="186" y="198"/>
+ <point x="160" y="0" type="curve"/>
+ <point x="345" y="0" type="line"/>
+ <point x="377" y="1205" type="line"/>
+ <point x="405" y="1460" type="line"/>
+ </contour>
+ <contour>
+ <point x="1610" y="0" type="line"/>
+ <point x="1581" y="198"/>
+ <point x="1540" y="1460"/>
+ <point x="1540" y="1460" type="curve"/>
+ <point x="1365" y="1460" type="line"/>
+ <point x="1397" y="1205" type="line"/>
+ <point x="1425" y="0" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/input/font-psf-test/source/PsfTest-Regular.ufo/glyphs/L_tnC_apN_.glif b/tests/input/font-psf-test/source/PsfTest-Regular.ufo/glyphs/L_tnC_apN_.glif
new file mode 100644
index 0000000..360e6e6
--- /dev/null
+++ b/tests/input/font-psf-test/source/PsfTest-Regular.ufo/glyphs/L_tnC_apN_.glif
@@ -0,0 +1,37 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnCapN" format="2">
+ <advance width="1500"/>
+ <unicode hex="004E"/>
+ <anchor x="1230" y="0" name="H"/>
+ <anchor x="737" y="-100" name="L"/>
+ <anchor x="737" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="200" y="1355" type="line"/>
+ <point x="1135" y="0" type="line"/>
+ <point x="1275" y="100" type="line"/>
+ <point x="340" y="1460" type="line"/>
+ </contour>
+ <contour>
+ <point x="1135" y="0" type="line"/>
+ <point x="1300" y="0" type="line"/>
+ <point x="1300" y="1025" type="line" smooth="yes"/>
+ <point x="1300" y="1222"/>
+ <point x="1301" y="1380"/>
+ <point x="1315" y="1460" type="curve"/>
+ <point x="1135" y="1460" type="line"/>
+ </contour>
+ <contour>
+ <point x="340" y="1460" type="line"/>
+ <point x="160" y="1460" type="line"/>
+ <point x="175" y="1380"/>
+ <point x="175" y="1222"/>
+ <point x="175" y="1025" type="curve" smooth="yes"/>
+ <point x="175" y="435" type="line" smooth="yes"/>
+ <point x="175" y="238"/>
+ <point x="175" y="80"/>
+ <point x="160" y="0" type="curve"/>
+ <point x="340" y="0" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/input/font-psf-test/source/PsfTest-Regular.ufo/glyphs/L_tnC_apO_.glif b/tests/input/font-psf-test/source/PsfTest-Regular.ufo/glyphs/L_tnC_apO_.glif
new file mode 100644
index 0000000..e351c3d
--- /dev/null
+++ b/tests/input/font-psf-test/source/PsfTest-Regular.ufo/glyphs/L_tnC_apO_.glif
@@ -0,0 +1,40 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnCapO" format="2">
+ <advance width="1460"/>
+ <unicode hex="004F"/>
+ <anchor x="717" y="0" name="H"/>
+ <anchor x="717" y="-100" name="L"/>
+ <anchor x="994" y="0" name="O"/>
+ <anchor x="1460" y="1200" name="R"/>
+ <anchor x="717" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="1145" y="715" type="curve" smooth="yes"/>
+ <point x="1145" y="360"/>
+ <point x="965" y="150"/>
+ <point x="720" y="150" type="curve" smooth="yes"/>
+ <point x="460" y="150"/>
+ <point x="290" y="380"/>
+ <point x="290" y="745" type="curve" smooth="yes"/>
+ <point x="290" y="1091"/>
+ <point x="467" y="1310"/>
+ <point x="720" y="1310" type="curve" smooth="yes"/>
+ <point x="974" y="1310"/>
+ <point x="1145" y="1084"/>
+ </contour>
+ <contour>
+ <point x="1340" y="740" type="curve" smooth="yes"/>
+ <point x="1340" y="1219"/>
+ <point x="1048" y="1485"/>
+ <point x="730" y="1485" type="curve" smooth="yes"/>
+ <point x="407" y="1485"/>
+ <point x="95" y="1199"/>
+ <point x="95" y="720" type="curve" smooth="yes"/>
+ <point x="95" y="241"/>
+ <point x="388" y="-25"/>
+ <point x="710" y="-25" type="curve" smooth="yes"/>
+ <point x="1029" y="-25"/>
+ <point x="1340" y="260"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/input/font-psf-test/source/PsfTest-Regular.ufo/glyphs/L_tnC_apP_.glif b/tests/input/font-psf-test/source/PsfTest-Regular.ufo/glyphs/L_tnC_apP_.glif
new file mode 100644
index 0000000..9f29954
--- /dev/null
+++ b/tests/input/font-psf-test/source/PsfTest-Regular.ufo/glyphs/L_tnC_apP_.glif
@@ -0,0 +1,50 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnCapP" format="2">
+ <advance width="1195"/>
+ <unicode hex="0050"/>
+ <anchor x="637" y="-100" name="L"/>
+ <anchor x="637" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="365" y="565" type="line"/>
+ <point x="430" y="558"/>
+ <point x="512" y="555"/>
+ <point x="585" y="555" type="curve" smooth="yes"/>
+ <point x="914" y="555"/>
+ <point x="1115" y="736"/>
+ <point x="1115" y="1030" type="curve" smooth="yes"/>
+ <point x="1115" y="1322"/>
+ <point x="908" y="1470"/>
+ <point x="585" y="1470" type="curve" smooth="yes"/>
+ <point x="372" y="1470"/>
+ <point x="160" y="1460"/>
+ <point x="160" y="1460" type="curve"/>
+ <point x="175" y="1380"/>
+ <point x="175" y="1196"/>
+ <point x="175" y="1000" type="curve"/>
+ <point x="175" y="435" type="line" smooth="yes"/>
+ <point x="175" y="238"/>
+ <point x="175" y="80"/>
+ <point x="160" y="0" type="curve"/>
+ <point x="380" y="0" type="line"/>
+ <point x="366" y="78"/>
+ <point x="365" y="237"/>
+ <point x="365" y="435" type="curve" smooth="yes"/>
+ </contour>
+ <contour>
+ <point x="365" y="1305" type="line"/>
+ <point x="433" y="1308"/>
+ <point x="481" y="1310"/>
+ <point x="575" y="1310" type="curve" smooth="yes"/>
+ <point x="841" y="1310"/>
+ <point x="925" y="1170"/>
+ <point x="925" y="1010" type="curve" smooth="yes"/>
+ <point x="925" y="849"/>
+ <point x="850" y="710"/>
+ <point x="570" y="710" type="curve" smooth="yes"/>
+ <point x="495" y="710"/>
+ <point x="428" y="712"/>
+ <point x="365" y="720" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/input/font-psf-test/source/PsfTest-Regular.ufo/glyphs/L_tnC_apQ_.glif b/tests/input/font-psf-test/source/PsfTest-Regular.ufo/glyphs/L_tnC_apQ_.glif
new file mode 100644
index 0000000..ddd0351
--- /dev/null
+++ b/tests/input/font-psf-test/source/PsfTest-Regular.ufo/glyphs/L_tnC_apQ_.glif
@@ -0,0 +1,49 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnCapQ" format="2">
+ <advance width="1475"/>
+ <unicode hex="0051"/>
+ <anchor x="717" y="-270" name="L"/>
+ <anchor x="717" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="1340" y="740" type="curve" smooth="yes"/>
+ <point x="1340" y="1219"/>
+ <point x="1053" y="1485"/>
+ <point x="730" y="1485" type="curve" smooth="yes"/>
+ <point x="407" y="1485"/>
+ <point x="95" y="1199"/>
+ <point x="95" y="720" type="curve" smooth="yes"/>
+ <point x="95" y="241"/>
+ <point x="383" y="-25"/>
+ <point x="705" y="-25" type="curve" smooth="yes"/>
+ <point x="767" y="-25"/>
+ <point x="818" y="-18"/>
+ <point x="875" y="0" type="curve"/>
+ <point x="944" y="0"/>
+ <point x="1236" y="-190"/>
+ <point x="1320" y="-190" type="curve" smooth="yes"/>
+ <point x="1374" y="-190"/>
+ <point x="1431" y="-81"/>
+ <point x="1455" y="-45" type="curve"/>
+ <point x="1321" y="-28"/>
+ <point x="1205" y="28"/>
+ <point x="1080" y="105" type="curve"/>
+ <point x="1256" y="236"/>
+ <point x="1340" y="479"/>
+ </contour>
+ <contour>
+ <point x="1145" y="715" type="curve" smooth="yes"/>
+ <point x="1145" y="360"/>
+ <point x="965" y="150"/>
+ <point x="720" y="150" type="curve" smooth="yes"/>
+ <point x="460" y="150"/>
+ <point x="290" y="380"/>
+ <point x="290" y="745" type="curve" smooth="yes"/>
+ <point x="290" y="1091"/>
+ <point x="467" y="1310"/>
+ <point x="720" y="1310" type="curve" smooth="yes"/>
+ <point x="974" y="1310"/>
+ <point x="1145" y="1084"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/input/font-psf-test/source/PsfTest-Regular.ufo/glyphs/L_tnC_apR_.glif b/tests/input/font-psf-test/source/PsfTest-Regular.ufo/glyphs/L_tnC_apR_.glif
new file mode 100644
index 0000000..cd9e037
--- /dev/null
+++ b/tests/input/font-psf-test/source/PsfTest-Regular.ufo/glyphs/L_tnC_apR_.glif
@@ -0,0 +1,55 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnCapR" format="2">
+ <advance width="1305"/>
+ <unicode hex="0052"/>
+ <anchor x="285" y="0" name="H"/>
+ <anchor x="610" y="-100" name="L"/>
+ <anchor x="610" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="365" y="625" type="line"/>
+ <point x="620" y="625" type="line"/>
+ <point x="805" y="625"/>
+ <point x="1090" y="743"/>
+ <point x="1090" y="1060" type="curve" smooth="yes"/>
+ <point x="1090" y="1349"/>
+ <point x="876" y="1470"/>
+ <point x="565" y="1470" type="curve" smooth="yes"/>
+ <point x="331" y="1470"/>
+ <point x="160" y="1460"/>
+ <point x="160" y="1460" type="curve"/>
+ <point x="175" y="1380"/>
+ <point x="175" y="1196"/>
+ <point x="175" y="1000" type="curve" smooth="yes"/>
+ <point x="175" y="435" type="line"/>
+ <point x="175" y="238"/>
+ <point x="175" y="80"/>
+ <point x="160" y="0" type="curve"/>
+ <point x="380" y="0" type="line"/>
+ <point x="366" y="78"/>
+ <point x="365" y="238"/>
+ <point x="365" y="435" type="curve"/>
+ </contour>
+ <contour>
+ <point x="365" y="1305" type="line"/>
+ <point x="418" y="1307"/>
+ <point x="485" y="1310"/>
+ <point x="555" y="1310" type="curve" smooth="yes"/>
+ <point x="800" y="1310"/>
+ <point x="900" y="1216"/>
+ <point x="900" y="1045" type="curve" smooth="yes"/>
+ <point x="900" y="879"/>
+ <point x="780" y="780"/>
+ <point x="555" y="780" type="curve"/>
+ <point x="365" y="780" type="line"/>
+ </contour>
+ <contour>
+ <point x="561" y="635" type="line"/>
+ <point x="990" y="0" type="line"/>
+ <point x="1245" y="0" type="line"/>
+ <point x="1178" y="73"/>
+ <point x="715" y="710"/>
+ <point x="715" y="710" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/input/font-psf-test/source/PsfTest-Regular.ufo/glyphs/L_tnC_apS_.glif b/tests/input/font-psf-test/source/PsfTest-Regular.ufo/glyphs/L_tnC_apS_.glif
new file mode 100644
index 0000000..92da6b0
--- /dev/null
+++ b/tests/input/font-psf-test/source/PsfTest-Regular.ufo/glyphs/L_tnC_apS_.glif
@@ -0,0 +1,50 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnCapS" format="2">
+ <advance width="1175"/>
+ <unicode hex="0053"/>
+ <anchor x="580" y="0" name="H"/>
+ <anchor x="580" y="-100" name="L"/>
+ <anchor x="580" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="1000" y="1395" type="line"/>
+ <point x="870" y="1458"/>
+ <point x="759" y="1485"/>
+ <point x="605" y="1485" type="curve" smooth="yes"/>
+ <point x="273" y="1485"/>
+ <point x="135" y="1250"/>
+ <point x="135" y="1080" type="curve" smooth="yes"/>
+ <point x="135" y="910"/>
+ <point x="203" y="778"/>
+ <point x="515" y="685" type="curve" smooth="yes"/>
+ <point x="827" y="591"/>
+ <point x="875" y="510"/>
+ <point x="875" y="405" type="curve" smooth="yes"/>
+ <point x="875" y="243"/>
+ <point x="726" y="150"/>
+ <point x="565" y="150" type="curve" smooth="yes"/>
+ <point x="417" y="150"/>
+ <point x="272" y="200"/>
+ <point x="140" y="315" type="curve"/>
+ <point x="95" y="110" type="line"/>
+ <point x="197" y="31"/>
+ <point x="372" y="-25"/>
+ <point x="565" y="-25" type="curve" smooth="yes"/>
+ <point x="838" y="-25"/>
+ <point x="1065" y="157"/>
+ <point x="1065" y="425" type="curve" smooth="yes"/>
+ <point x="1065" y="641"/>
+ <point x="920" y="762"/>
+ <point x="655" y="840" type="curve" smooth="yes"/>
+ <point x="370" y="923"/>
+ <point x="325" y="985"/>
+ <point x="325" y="1095" type="curve" smooth="yes"/>
+ <point x="325" y="1205"/>
+ <point x="435" y="1310"/>
+ <point x="595" y="1310" type="curve" smooth="yes"/>
+ <point x="723" y="1310"/>
+ <point x="817" y="1279"/>
+ <point x="960" y="1200" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/input/font-psf-test/source/PsfTest-Regular.ufo/glyphs/L_tnC_apT_.glif b/tests/input/font-psf-test/source/PsfTest-Regular.ufo/glyphs/L_tnC_apT_.glif
new file mode 100644
index 0000000..124138f
--- /dev/null
+++ b/tests/input/font-psf-test/source/PsfTest-Regular.ufo/glyphs/L_tnC_apT_.glif
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnCapT" format="2">
+ <advance width="1265"/>
+ <unicode hex="0054"/>
+ <anchor x="622" y="0" name="H"/>
+ <anchor x="622" y="-100" name="L"/>
+ <anchor x="622" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="45" y="1460" type="line"/>
+ <point x="45" y="1275" type="line"/>
+ <point x="125" y="1292"/>
+ <point x="201" y="1295"/>
+ <point x="290" y="1295" type="curve" smooth="yes"/>
+ <point x="525" y="1295" type="line"/>
+ <point x="525" y="435" type="line" smooth="yes"/>
+ <point x="525" y="238"/>
+ <point x="522" y="80"/>
+ <point x="505" y="0" type="curve"/>
+ <point x="735" y="0" type="line"/>
+ <point x="718" y="80"/>
+ <point x="715" y="238"/>
+ <point x="715" y="435" type="curve" smooth="yes"/>
+ <point x="715" y="1295" type="line"/>
+ <point x="955" y="1295" type="line" smooth="yes"/>
+ <point x="1045" y="1295"/>
+ <point x="1120" y="1292"/>
+ <point x="1200" y="1275" type="curve"/>
+ <point x="1200" y="1460" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/input/font-psf-test/source/PsfTest-Regular.ufo/glyphs/L_tnC_apU_.glif b/tests/input/font-psf-test/source/PsfTest-Regular.ufo/glyphs/L_tnC_apU_.glif
new file mode 100644
index 0000000..7afa08d
--- /dev/null
+++ b/tests/input/font-psf-test/source/PsfTest-Regular.ufo/glyphs/L_tnC_apU_.glif
@@ -0,0 +1,38 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnCapU" format="2">
+ <advance width="1440"/>
+ <unicode hex="0055"/>
+ <anchor x="707" y="0" name="H"/>
+ <anchor x="707" y="-100" name="L"/>
+ <anchor x="1026" y="0" name="O"/>
+ <anchor x="1400" y="1200" name="R"/>
+ <anchor x="707" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="1050" y="1460" type="line"/>
+ <point x="1050" y="560" type="line" smooth="yes"/>
+ <point x="1050" y="299"/>
+ <point x="968" y="135"/>
+ <point x="710" y="135" type="curve" smooth="yes"/>
+ <point x="447" y="135"/>
+ <point x="365" y="299"/>
+ <point x="365" y="560" type="curve" smooth="yes"/>
+ <point x="365" y="1460" type="line"/>
+ <point x="160" y="1460" type="line"/>
+ <point x="174" y="1380"/>
+ <point x="175" y="1222"/>
+ <point x="175" y="1025" type="curve" smooth="yes"/>
+ <point x="175" y="515" type="line"/>
+ <point x="175" y="190"/>
+ <point x="345" y="-25"/>
+ <point x="710" y="-25" type="curve" smooth="yes"/>
+ <point x="1071" y="-25"/>
+ <point x="1240" y="190"/>
+ <point x="1240" y="515" type="curve"/>
+ <point x="1240" y="1025" type="line" smooth="yes"/>
+ <point x="1240" y="1232"/>
+ <point x="1242" y="1380"/>
+ <point x="1255" y="1460" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/input/font-psf-test/source/PsfTest-Regular.ufo/glyphs/L_tnC_apV_.glif b/tests/input/font-psf-test/source/PsfTest-Regular.ufo/glyphs/L_tnC_apV_.glif
new file mode 100644
index 0000000..86c76b5
--- /dev/null
+++ b/tests/input/font-psf-test/source/PsfTest-Regular.ufo/glyphs/L_tnC_apV_.glif
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnCapV" format="2">
+ <advance width="1365"/>
+ <unicode hex="0056"/>
+ <anchor x="680" y="0" name="H"/>
+ <anchor x="672" y="-100" name="L"/>
+ <anchor x="880" y="0" name="O"/>
+ <anchor x="672" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="1095" y="1460" type="line"/>
+ <point x="672" y="195" type="line"/>
+ <point x="250" y="1460" type="line"/>
+ <point x="35" y="1460" type="line"/>
+ <point x="68" y="1378"/>
+ <point x="101" y="1288"/>
+ <point x="170" y="1095" type="curve" smooth="yes"/>
+ <point x="560" y="0" type="line"/>
+ <point x="785" y="0" type="line"/>
+ <point x="1170" y="1095" type="line" smooth="yes"/>
+ <point x="1238" y="1289"/>
+ <point x="1274" y="1378"/>
+ <point x="1310" y="1460" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/input/font-psf-test/source/PsfTest-Regular.ufo/glyphs/L_tnC_apW_.glif b/tests/input/font-psf-test/source/PsfTest-Regular.ufo/glyphs/L_tnC_apW_.glif
new file mode 100644
index 0000000..b1f4961
--- /dev/null
+++ b/tests/input/font-psf-test/source/PsfTest-Regular.ufo/glyphs/L_tnC_apW_.glif
@@ -0,0 +1,45 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnCapW" format="2">
+ <advance width="2080"/>
+ <unicode hex="0057"/>
+ <anchor x="1027" y="-100" name="L"/>
+ <anchor x="1027" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="1480" y="0" type="line"/>
+ <point x="1595" y="0" type="line"/>
+ <point x="1900" y="1095" type="line" smooth="yes"/>
+ <point x="1954" y="1289"/>
+ <point x="1983" y="1378"/>
+ <point x="2015" y="1460" type="curve"/>
+ <point x="1795" y="1460" type="line"/>
+ <point x="1470" y="130" type="line"/>
+ </contour>
+ <contour>
+ <point x="1120" y="1460" type="line"/>
+ <point x="935" y="1460" type="line"/>
+ <point x="990" y="1305" type="line"/>
+ <point x="1370" y="0" type="line"/>
+ <point x="1480" y="0" type="line"/>
+ <point x="1500" y="130" type="line"/>
+ </contour>
+ <contour>
+ <point x="580" y="0" type="line"/>
+ <point x="685" y="0" type="line"/>
+ <point x="1065" y="1305" type="line"/>
+ <point x="1120" y="1460" type="line"/>
+ <point x="935" y="1460" type="line"/>
+ <point x="560" y="130" type="line"/>
+ </contour>
+ <contour>
+ <point x="260" y="1460" type="line"/>
+ <point x="40" y="1460" type="line"/>
+ <point x="71" y="1381"/>
+ <point x="102" y="1286"/>
+ <point x="155" y="1095" type="curve" smooth="yes"/>
+ <point x="460" y="0" type="line"/>
+ <point x="580" y="0" type="line"/>
+ <point x="590" y="130" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/input/font-psf-test/source/PsfTest-Regular.ufo/glyphs/L_tnC_apX_.glif b/tests/input/font-psf-test/source/PsfTest-Regular.ufo/glyphs/L_tnC_apX_.glif
new file mode 100644
index 0000000..7472407
--- /dev/null
+++ b/tests/input/font-psf-test/source/PsfTest-Regular.ufo/glyphs/L_tnC_apX_.glif
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnCapX" format="2">
+ <advance width="1325"/>
+ <unicode hex="0058"/>
+ <anchor x="650" y="-100" name="L"/>
+ <anchor x="650" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="537" y="781" type="line"/>
+ <point x="265" y="340" type="line" smooth="yes"/>
+ <point x="136" y="132"/>
+ <point x="103" y="86"/>
+ <point x="40" y="0" type="curve"/>
+ <point x="270" y="0" type="line"/>
+ <point x="642" y="614" type="line"/>
+ <point x="1030" y="0" type="line"/>
+ <point x="1260" y="0" type="line"/>
+ <point x="1199" y="82"/>
+ <point x="1165" y="127"/>
+ <point x="1033" y="336" type="curve" smooth="yes"/>
+ <point x="761" y="767" type="line"/>
+ <point x="972" y="1110" type="line" smooth="yes"/>
+ <point x="1097" y="1313"/>
+ <point x="1148" y="1383"/>
+ <point x="1210" y="1460" type="curve"/>
+ <point x="975" y="1460" type="line"/>
+ <point x="656" y="934" type="line"/>
+ <point x="325" y="1460" type="line"/>
+ <point x="90" y="1460" type="line"/>
+ <point x="154" y="1376"/>
+ <point x="201" y="1315"/>
+ <point x="330" y="1110" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/input/font-psf-test/source/PsfTest-Regular.ufo/glyphs/L_tnC_apY_.glif b/tests/input/font-psf-test/source/PsfTest-Regular.ufo/glyphs/L_tnC_apY_.glif
new file mode 100644
index 0000000..c2c5f54
--- /dev/null
+++ b/tests/input/font-psf-test/source/PsfTest-Regular.ufo/glyphs/L_tnC_apY_.glif
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnCapY" format="2">
+ <advance width="1320"/>
+ <unicode hex="0059"/>
+ <anchor x="650" y="-100" name="L"/>
+ <anchor x="650" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="35" y="1460" type="line"/>
+ <point x="147" y="1311"/>
+ <point x="213" y="1197"/>
+ <point x="290" y="1065" type="curve" smooth="yes"/>
+ <point x="555" y="611" type="line"/>
+ <point x="555" y="435" type="line" smooth="yes"/>
+ <point x="555" y="238"/>
+ <point x="555" y="80"/>
+ <point x="540" y="0" type="curve"/>
+ <point x="760" y="0" type="line"/>
+ <point x="745" y="80"/>
+ <point x="745" y="238"/>
+ <point x="745" y="435" type="curve" smooth="yes"/>
+ <point x="745" y="603" type="line"/>
+ <point x="1015" y="1065" type="line" smooth="yes"/>
+ <point x="1091" y="1195"/>
+ <point x="1147" y="1291"/>
+ <point x="1265" y="1460" type="curve"/>
+ <point x="1035" y="1460" type="line"/>
+ <point x="660" y="799" type="line"/>
+ <point x="265" y="1460" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/input/font-psf-test/source/PsfTest-Regular.ufo/glyphs/L_tnS_mA_.glif b/tests/input/font-psf-test/source/PsfTest-Regular.ufo/glyphs/L_tnS_mA_.glif
new file mode 100644
index 0000000..20f7261
--- /dev/null
+++ b/tests/input/font-psf-test/source/PsfTest-Regular.ufo/glyphs/L_tnS_mA_.glif
@@ -0,0 +1,76 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmA" format="2">
+ <advance width="1120"/>
+ <unicode hex="0061"/>
+ <note>
+
+
+
+
+ GlyphNote A
+
+
+
+
+ </note>
+ <anchor x="540" y="0" name="H"/>
+ <anchor x="540" y="-100" name="L"/>
+ <anchor x="1125" y="0" name="O"/>
+ <anchor x="1120" y="1000" name="R"/>
+ <anchor x="540" y="1100" name="U"/>
+ <outline>
+ <contour>
+ <point x="950" y="760" type="line"/>
+ <point x="950" y="919"/>
+ <point x="800" y="1040"/>
+ <point x="570" y="1040" type="curve" smooth="yes"/>
+ <point x="418" y="1040"/>
+ <point x="312" y="994"/>
+ <point x="209" y="950" type="curve"/>
+ <point x="203" y="907"/>
+ <point x="200" y="799"/>
+ <point x="199" y="755" type="curve"/>
+ <point x="316" y="837"/>
+ <point x="419" y="880"/>
+ <point x="525" y="880" type="curve" smooth="yes"/>
+ <point x="675" y="880"/>
+ <point x="765" y="831"/>
+ <point x="765" y="710" type="curve" smooth="yes"/>
+ <point x="765" y="635" type="line"/>
+ <point x="724" y="632"/>
+ <point x="564" y="617"/>
+ <point x="495" y="610" type="curve" smooth="yes"/>
+ <point x="186" y="580"/>
+ <point x="95" y="407"/>
+ <point x="95" y="255" type="curve" smooth="yes"/>
+ <point x="95" y="107"/>
+ <point x="232" y="-25"/>
+ <point x="420" y="-25" type="curve" smooth="yes"/>
+ <point x="544" y="-25"/>
+ <point x="677" y="29"/>
+ <point x="795" y="155" type="curve"/>
+ <point x="809" y="91"/>
+ <point x="833" y="32"/>
+ <point x="845" y="0" type="curve"/>
+ <point x="1025" y="0" type="line"/>
+ <point x="981" y="112"/>
+ <point x="950" y="226"/>
+ <point x="950" y="370" type="curve"/>
+ </contour>
+ <contour>
+ <point x="765" y="325" type="line"/>
+ <point x="644" y="164"/>
+ <point x="552" y="140"/>
+ <point x="450" y="140" type="curve" smooth="yes"/>
+ <point x="340" y="140"/>
+ <point x="275" y="191"/>
+ <point x="275" y="280" type="curve" smooth="yes"/>
+ <point x="275" y="372"/>
+ <point x="335" y="450"/>
+ <point x="505" y="470" type="curve" smooth="yes"/>
+ <point x="568" y="478"/>
+ <point x="715" y="493"/>
+ <point x="765" y="495" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/input/font-psf-test/source/PsfTest-Regular.ufo/glyphs/L_tnS_mA_A_cute.glif b/tests/input/font-psf-test/source/PsfTest-Regular.ufo/glyphs/L_tnS_mA_A_cute.glif
new file mode 100644
index 0000000..2ab1b23
--- /dev/null
+++ b/tests/input/font-psf-test/source/PsfTest-Regular.ufo/glyphs/L_tnS_mA_A_cute.glif
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmAAcute" format="2">
+ <advance width="1120"/>
+ <unicode hex="00E1"/>
+ <anchor x="540" y="0" name="H"/>
+ <anchor x="540" y="-100" name="L"/>
+ <anchor x="1125" y="0" name="O"/>
+ <anchor x="1120" y="1000" name="R"/>
+ <anchor x="540" y="1635" name="U"/>
+ <outline>
+ <component base="LtnSmA"/>
+ <component base="CombAcute" xOffset="1110"/>
+ </outline>
+</glyph>
diff --git a/tests/input/font-psf-test/source/PsfTest-Regular.ufo/glyphs/L_tnS_mA_C_ircum.glif b/tests/input/font-psf-test/source/PsfTest-Regular.ufo/glyphs/L_tnS_mA_C_ircum.glif
new file mode 100644
index 0000000..6551c45
--- /dev/null
+++ b/tests/input/font-psf-test/source/PsfTest-Regular.ufo/glyphs/L_tnS_mA_C_ircum.glif
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmACircum" format="2">
+ <advance width="1120"/>
+ <unicode hex="00E2"/>
+ <anchor x="540" y="0" name="H"/>
+ <anchor x="540" y="-100" name="L"/>
+ <anchor x="1125" y="0" name="O"/>
+ <anchor x="1120" y="1000" name="R"/>
+ <anchor x="540" y="1635" name="U"/>
+ <outline>
+ <component base="LtnSmA"/>
+ <component base="CombCircum" xOffset="1110"/>
+ </outline>
+</glyph>
diff --git a/tests/input/font-psf-test/source/PsfTest-Regular.ufo/glyphs/L_tnS_mA_D_iaer.glif b/tests/input/font-psf-test/source/PsfTest-Regular.ufo/glyphs/L_tnS_mA_D_iaer.glif
new file mode 100644
index 0000000..61c5d3f
--- /dev/null
+++ b/tests/input/font-psf-test/source/PsfTest-Regular.ufo/glyphs/L_tnS_mA_D_iaer.glif
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmADiaer" format="2">
+ <advance width="1120"/>
+ <unicode hex="00E4"/>
+ <anchor x="540" y="0" name="H"/>
+ <anchor x="540" y="-100" name="L"/>
+ <anchor x="1125" y="0" name="O"/>
+ <anchor x="1120" y="1000" name="R"/>
+ <anchor x="540" y="1505" name="U"/>
+ <outline>
+ <component base="LtnSmA"/>
+ <component base="CombDiaer" xOffset="1110"/>
+ </outline>
+</glyph>
diff --git a/tests/input/font-psf-test/source/PsfTest-Regular.ufo/glyphs/L_tnS_mA_G_rave.glif b/tests/input/font-psf-test/source/PsfTest-Regular.ufo/glyphs/L_tnS_mA_G_rave.glif
new file mode 100644
index 0000000..9879252
--- /dev/null
+++ b/tests/input/font-psf-test/source/PsfTest-Regular.ufo/glyphs/L_tnS_mA_G_rave.glif
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmAGrave" format="2">
+ <advance width="1120"/>
+ <unicode hex="00E0"/>
+ <anchor x="540" y="0" name="H"/>
+ <anchor x="540" y="-100" name="L"/>
+ <anchor x="1125" y="0" name="O"/>
+ <anchor x="1120" y="1000" name="R"/>
+ <anchor x="540" y="1635" name="U"/>
+ <outline>
+ <component base="LtnSmA"/>
+ <component base="CombGrave" xOffset="1090"/>
+ </outline>
+</glyph>
diff --git a/tests/input/font-psf-test/source/PsfTest-Regular.ufo/glyphs/L_tnS_mA_R_ingA_bv.glif b/tests/input/font-psf-test/source/PsfTest-Regular.ufo/glyphs/L_tnS_mA_R_ingA_bv.glif
new file mode 100644
index 0000000..5a54e7e
--- /dev/null
+++ b/tests/input/font-psf-test/source/PsfTest-Regular.ufo/glyphs/L_tnS_mA_R_ingA_bv.glif
@@ -0,0 +1,41 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmARingAbv" format="2">
+ <advance width="1120"/>
+ <unicode hex="00E5"/>
+ <anchor x="540" y="0" name="H"/>
+ <anchor x="540" y="-100" name="L"/>
+ <anchor x="1125" y="0" name="O"/>
+ <anchor x="1120" y="1000" name="R"/>
+ <anchor x="542" y="1635" name="U"/>
+ <outline>
+ <contour>
+ <point x="642" y="1385" type="curve" smooth="yes"/>
+ <point x="642" y="1325"/>
+ <point x="602" y="1285"/>
+ <point x="542" y="1285" type="curve" smooth="yes"/>
+ <point x="482" y="1285"/>
+ <point x="442" y="1325"/>
+ <point x="442" y="1385" type="curve" smooth="yes"/>
+ <point x="442" y="1445"/>
+ <point x="482" y="1485"/>
+ <point x="542" y="1485" type="curve" smooth="yes"/>
+ <point x="602" y="1485"/>
+ <point x="642" y="1445"/>
+ </contour>
+ <contour>
+ <point x="327" y="1385" type="curve" smooth="yes"/>
+ <point x="327" y="1265"/>
+ <point x="422" y="1170"/>
+ <point x="542" y="1170" type="curve" smooth="yes"/>
+ <point x="662" y="1170"/>
+ <point x="757" y="1265"/>
+ <point x="757" y="1385" type="curve" smooth="yes"/>
+ <point x="757" y="1505"/>
+ <point x="662" y="1600"/>
+ <point x="542" y="1600" type="curve" smooth="yes"/>
+ <point x="422" y="1600"/>
+ <point x="327" y="1505"/>
+ </contour>
+ <component base="LtnSmA"/>
+ </outline>
+</glyph>
diff --git a/tests/input/font-psf-test/source/PsfTest-Regular.ufo/glyphs/L_tnS_mA_T_ilde.glif b/tests/input/font-psf-test/source/PsfTest-Regular.ufo/glyphs/L_tnS_mA_T_ilde.glif
new file mode 100644
index 0000000..72957bf
--- /dev/null
+++ b/tests/input/font-psf-test/source/PsfTest-Regular.ufo/glyphs/L_tnS_mA_T_ilde.glif
@@ -0,0 +1,41 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmATilde" format="2">
+ <advance width="1120"/>
+ <unicode hex="00E3"/>
+ <anchor x="540" y="0" name="H"/>
+ <anchor x="540" y="-100" name="L"/>
+ <anchor x="1125" y="0" name="O"/>
+ <anchor x="1120" y="1000" name="R"/>
+ <anchor x="540" y="1475" name="U"/>
+ <outline>
+ <contour>
+ <point x="295" y="1205" type="line"/>
+ <point x="300" y="1254"/>
+ <point x="331" y="1290"/>
+ <point x="380" y="1290" type="curve" smooth="yes"/>
+ <point x="417" y="1290"/>
+ <point x="458" y="1274"/>
+ <point x="535" y="1238" type="curve" smooth="yes"/>
+ <point x="596" y="1210"/>
+ <point x="649" y="1190"/>
+ <point x="702" y="1190" type="curve" smooth="yes"/>
+ <point x="825" y="1190"/>
+ <point x="900" y="1312"/>
+ <point x="900" y="1440" type="curve"/>
+ <point x="795" y="1440" type="line"/>
+ <point x="788" y="1394"/>
+ <point x="757" y="1355"/>
+ <point x="710" y="1355" type="curve" smooth="yes"/>
+ <point x="668" y="1355"/>
+ <point x="627" y="1374"/>
+ <point x="555" y="1403" type="curve" smooth="yes"/>
+ <point x="485" y="1431"/>
+ <point x="438" y="1455"/>
+ <point x="382" y="1455" type="curve" smooth="yes"/>
+ <point x="263" y="1455"/>
+ <point x="190" y="1327"/>
+ <point x="190" y="1205" type="curve"/>
+ </contour>
+ <component base="LtnSmA"/>
+ </outline>
+</glyph>
diff --git a/tests/input/font-psf-test/source/PsfTest-Regular.ufo/glyphs/L_tnS_mB_.glif b/tests/input/font-psf-test/source/PsfTest-Regular.ufo/glyphs/L_tnS_mB_.glif
new file mode 100644
index 0000000..67ff8ac
--- /dev/null
+++ b/tests/input/font-psf-test/source/PsfTest-Regular.ufo/glyphs/L_tnS_mB_.glif
@@ -0,0 +1,50 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmB" format="2">
+ <advance width="1155"/>
+ <unicode hex="0062"/>
+ <anchor x="590" y="0" name="H"/>
+ <anchor x="590" y="-100" name="L"/>
+ <anchor x="1155" y="1000" name="R"/>
+ <anchor x="590" y="1635" name="U"/>
+ <outline>
+ <contour>
+ <point x="130" y="1600" type="line"/>
+ <point x="145" y="1488"/>
+ <point x="145" y="1273"/>
+ <point x="145" y="1130" type="curve" smooth="yes"/>
+ <point x="145" y="936"/>
+ <point x="145" y="228"/>
+ <point x="145" y="65" type="curve"/>
+ <point x="272" y="26"/>
+ <point x="413" y="-25"/>
+ <point x="575" y="-25" type="curve" smooth="yes"/>
+ <point x="870" y="-25"/>
+ <point x="1060" y="197"/>
+ <point x="1060" y="540" type="curve" smooth="yes"/>
+ <point x="1060" y="832"/>
+ <point x="917" y="1040"/>
+ <point x="715" y="1040" type="curve" smooth="yes"/>
+ <point x="547" y="1040"/>
+ <point x="423" y="947"/>
+ <point x="330" y="825" type="curve"/>
+ <point x="330" y="916"/>
+ <point x="330" y="1600"/>
+ <point x="330" y="1600" type="curve"/>
+ </contour>
+ <contour>
+ <point x="330" y="585" type="line"/>
+ <point x="398" y="751"/>
+ <point x="531" y="865"/>
+ <point x="655" y="865" type="curve" smooth="yes"/>
+ <point x="799" y="865"/>
+ <point x="880" y="727"/>
+ <point x="880" y="505" type="curve" smooth="yes"/>
+ <point x="880" y="280"/>
+ <point x="752" y="130"/>
+ <point x="575" y="130" type="curve" smooth="yes"/>
+ <point x="489" y="130"/>
+ <point x="428" y="144"/>
+ <point x="330" y="185" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/input/font-psf-test/source/PsfTest-Regular.ufo/glyphs/L_tnS_mC_.glif b/tests/input/font-psf-test/source/PsfTest-Regular.ufo/glyphs/L_tnS_mC_.glif
new file mode 100644
index 0000000..7c403fb
--- /dev/null
+++ b/tests/input/font-psf-test/source/PsfTest-Regular.ufo/glyphs/L_tnS_mC_.glif
@@ -0,0 +1,39 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmC" format="2">
+ <advance width="1020"/>
+ <unicode hex="0063"/>
+ <anchor x="580" y="0" name="H"/>
+ <anchor x="580" y="-100" name="L"/>
+ <anchor x="1020" y="1000" name="R"/>
+ <anchor x="570" y="1100" name="U"/>
+ <outline>
+ <contour>
+ <point x="905" y="260" type="line"/>
+ <point x="818" y="183"/>
+ <point x="720" y="140"/>
+ <point x="600" y="140" type="curve" smooth="yes"/>
+ <point x="406" y="140"/>
+ <point x="285" y="285"/>
+ <point x="285" y="500" type="curve" smooth="yes"/>
+ <point x="285" y="736"/>
+ <point x="422" y="875"/>
+ <point x="600" y="875" type="curve" smooth="yes"/>
+ <point x="703" y="875"/>
+ <point x="790" y="841"/>
+ <point x="880" y="775" type="curve"/>
+ <point x="915" y="955" type="line"/>
+ <point x="842" y="1005"/>
+ <point x="748" y="1040"/>
+ <point x="615" y="1040" type="curve" smooth="yes"/>
+ <point x="297" y="1040"/>
+ <point x="95" y="792"/>
+ <point x="95" y="490" type="curve" smooth="yes"/>
+ <point x="95" y="171"/>
+ <point x="312" y="-25"/>
+ <point x="580" y="-25" type="curve" smooth="yes"/>
+ <point x="730" y="-25"/>
+ <point x="824" y="9"/>
+ <point x="925" y="85" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/input/font-psf-test/source/PsfTest-Regular.ufo/glyphs/L_tnS_mD_.glif b/tests/input/font-psf-test/source/PsfTest-Regular.ufo/glyphs/L_tnS_mD_.glif
new file mode 100644
index 0000000..13547d4
--- /dev/null
+++ b/tests/input/font-psf-test/source/PsfTest-Regular.ufo/glyphs/L_tnS_mD_.glif
@@ -0,0 +1,53 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmD" format="2">
+ <advance width="1190"/>
+ <unicode hex="0064"/>
+ <anchor x="605" y="0" name="H"/>
+ <anchor x="605" y="-100" name="L"/>
+ <anchor x="1190" y="1000" name="R"/>
+ <anchor x="605" y="1635" name="U"/>
+ <outline>
+ <contour>
+ <point x="1030" y="1600" type="line"/>
+ <point x="820" y="1600" type="line"/>
+ <point x="839" y="1516"/>
+ <point x="845" y="1395"/>
+ <point x="845" y="1235" type="curve"/>
+ <point x="845" y="955" type="line"/>
+ <point x="767" y="999"/>
+ <point x="665" y="1040"/>
+ <point x="580" y="1040" type="curve" smooth="yes"/>
+ <point x="312" y="1040"/>
+ <point x="105" y="814"/>
+ <point x="105" y="460" type="curve" smooth="yes"/>
+ <point x="105" y="167"/>
+ <point x="261" y="-25"/>
+ <point x="505" y="-25" type="curve" smooth="yes"/>
+ <point x="652" y="-25"/>
+ <point x="775" y="50"/>
+ <point x="870" y="185" type="curve"/>
+ <point x="887" y="111"/>
+ <point x="910" y="34"/>
+ <point x="925" y="0" type="curve"/>
+ <point x="1105" y="0" type="line"/>
+ <point x="1062" y="112"/>
+ <point x="1030" y="278"/>
+ <point x="1030" y="530" type="curve"/>
+ </contour>
+ <contour>
+ <point x="845" y="400" type="line"/>
+ <point x="790" y="268"/>
+ <point x="662" y="135"/>
+ <point x="540" y="135" type="curve" smooth="yes"/>
+ <point x="366" y="135"/>
+ <point x="290" y="258"/>
+ <point x="290" y="490" type="curve" smooth="yes"/>
+ <point x="290" y="727"/>
+ <point x="429" y="870"/>
+ <point x="580" y="870" type="curve" smooth="yes"/>
+ <point x="681" y="870"/>
+ <point x="746" y="848"/>
+ <point x="845" y="795" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/input/font-psf-test/source/PsfTest-Regular.ufo/glyphs/L_tnS_mE_.glif b/tests/input/font-psf-test/source/PsfTest-Regular.ufo/glyphs/L_tnS_mE_.glif
new file mode 100644
index 0000000..f231440
--- /dev/null
+++ b/tests/input/font-psf-test/source/PsfTest-Regular.ufo/glyphs/L_tnS_mE_.glif
@@ -0,0 +1,45 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmE" format="2">
+ <advance width="1095"/>
+ <unicode hex="0065"/>
+ <anchor x="545" y="0" name="H"/>
+ <anchor x="569" y="-100" name="L"/>
+ <anchor x="925" y="0" name="O"/>
+ <anchor x="1095" y="1000" name="R"/>
+ <anchor x="569" y="1100" name="U"/>
+ <outline>
+ <contour>
+ <point x="989" y="485" type="line"/>
+ <point x="990" y="503"/>
+ <point x="990" y="545"/>
+ <point x="990" y="563" type="curve" smooth="yes"/>
+ <point x="990" y="788"/>
+ <point x="905" y="1040"/>
+ <point x="575" y="1040" type="curve" smooth="yes"/>
+ <point x="279" y="1040"/>
+ <point x="95" y="826"/>
+ <point x="95" y="495" type="curve" smooth="yes"/>
+ <point x="95" y="155"/>
+ <point x="320" y="-25"/>
+ <point x="575" y="-25" type="curve" smooth="yes"/>
+ <point x="729" y="-25"/>
+ <point x="853" y="2"/>
+ <point x="995" y="75" type="curve"/>
+ <point x="975" y="240" type="line"/>
+ <point x="853" y="166"/>
+ <point x="729" y="140"/>
+ <point x="600" y="140" type="curve" smooth="yes"/>
+ <point x="414" y="140"/>
+ <point x="280" y="258"/>
+ <point x="280" y="505" type="curve" smooth="yes"/>
+ <point x="280" y="770"/>
+ <point x="385" y="890"/>
+ <point x="560" y="890" type="curve" smooth="yes"/>
+ <point x="705" y="890"/>
+ <point x="810" y="797"/>
+ <point x="810" y="625" type="curve"/>
+ <point x="245" y="625" type="line"/>
+ <point x="245" y="485" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/input/font-psf-test/source/PsfTest-Regular.ufo/glyphs/L_tnS_mF_.glif b/tests/input/font-psf-test/source/PsfTest-Regular.ufo/glyphs/L_tnS_mF_.glif
new file mode 100644
index 0000000..56c0b15
--- /dev/null
+++ b/tests/input/font-psf-test/source/PsfTest-Regular.ufo/glyphs/L_tnS_mF_.glif
@@ -0,0 +1,39 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmF" format="2">
+ <advance width="750"/>
+ <unicode hex="0066"/>
+ <anchor x="370" y="0" name="H"/>
+ <anchor x="335" y="-100" name="L"/>
+ <anchor x="560" y="1635" name="U"/>
+ <outline>
+ <contour>
+ <point x="40" y="850" type="line"/>
+ <point x="240" y="850" type="line"/>
+ <point x="240" y="0" type="line"/>
+ <point x="455" y="0" type="line"/>
+ <point x="433" y="105"/>
+ <point x="425" y="300"/>
+ <point x="425" y="494" type="curve" smooth="yes"/>
+ <point x="425" y="850" type="line"/>
+ <point x="695" y="850" type="line"/>
+ <point x="695" y="995" type="line"/>
+ <point x="425" y="995" type="line"/>
+ <point x="425" y="1210" type="line" smooth="yes"/>
+ <point x="425" y="1381"/>
+ <point x="481" y="1450"/>
+ <point x="585" y="1450" type="curve" smooth="yes"/>
+ <point x="643" y="1450"/>
+ <point x="710" y="1427"/>
+ <point x="760" y="1390" type="curve"/>
+ <point x="805" y="1550" type="line"/>
+ <point x="743" y="1594"/>
+ <point x="663" y="1620"/>
+ <point x="585" y="1620" type="curve" smooth="yes"/>
+ <point x="369" y="1620"/>
+ <point x="240" y="1470"/>
+ <point x="240" y="1170" type="curve" smooth="yes"/>
+ <point x="240" y="995" type="line"/>
+ <point x="40" y="995" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/input/font-psf-test/source/PsfTest-Regular.ufo/glyphs/L_tnS_mG_.glif b/tests/input/font-psf-test/source/PsfTest-Regular.ufo/glyphs/L_tnS_mG_.glif
new file mode 100644
index 0000000..236da64
--- /dev/null
+++ b/tests/input/font-psf-test/source/PsfTest-Regular.ufo/glyphs/L_tnS_mG_.glif
@@ -0,0 +1,91 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmG" format="2">
+ <advance width="1095"/>
+ <unicode hex="0067"/>
+ <anchor x="545" y="-432" name="H"/>
+ <anchor x="545" y="-535" name="L"/>
+ <anchor x="1095" y="1000" name="R"/>
+ <anchor x="515" y="1100" name="U"/>
+ <outline>
+ <contour>
+ <point x="330" y="395" type="line"/>
+ <point x="234" y="357"/>
+ <point x="180" y="275"/>
+ <point x="180" y="215" type="curve" smooth="yes"/>
+ <point x="180" y="121"/>
+ <point x="263" y="27"/>
+ <point x="545" y="-5" type="curve" smooth="yes"/>
+ <point x="805" y="-35"/>
+ <point x="880" y="-90"/>
+ <point x="880" y="-170" type="curve" smooth="yes"/>
+ <point x="880" y="-255"/>
+ <point x="731" y="-360"/>
+ <point x="550" y="-360" type="curve" smooth="yes"/>
+ <point x="323" y="-360"/>
+ <point x="215" y="-261"/>
+ <point x="215" y="-180" type="curve" smooth="yes"/>
+ <point x="215" y="-121"/>
+ <point x="244" y="-56"/>
+ <point x="465" y="20" type="curve"/>
+ <point x="459" y="49"/>
+ <point x="290" y="75"/>
+ <point x="290" y="75" type="curve"/>
+ <point x="113" y="2"/>
+ <point x="30" y="-89"/>
+ <point x="30" y="-200" type="curve" smooth="yes"/>
+ <point x="30" y="-409"/>
+ <point x="303" y="-505"/>
+ <point x="535" y="-505" type="curve" smooth="yes"/>
+ <point x="777" y="-505"/>
+ <point x="1065" y="-375"/>
+ <point x="1065" y="-160" type="curve" smooth="yes"/>
+ <point x="1065" y="-8"/>
+ <point x="967" y="90"/>
+ <point x="670" y="125" type="curve" smooth="yes"/>
+ <point x="410" y="156"/>
+ <point x="345" y="198"/>
+ <point x="345" y="235" type="curve" smooth="yes"/>
+ <point x="345" y="271"/>
+ <point x="384" y="316"/>
+ <point x="500" y="350" type="curve"/>
+ </contour>
+ <contour>
+ <point x="1050" y="1040" type="line"/>
+ <point x="951" y="1033"/>
+ <point x="819" y="997"/>
+ <point x="730" y="940" type="curve"/>
+ <point x="795" y="825" type="line"/>
+ <point x="887" y="863"/>
+ <point x="967" y="878"/>
+ <point x="1040" y="880" type="curve"/>
+ </contour>
+ <contour>
+ <point x="115" y="680" type="curve" smooth="yes"/>
+ <point x="115" y="476"/>
+ <point x="289" y="325"/>
+ <point x="515" y="325" type="curve" smooth="yes"/>
+ <point x="742" y="325"/>
+ <point x="915" y="476"/>
+ <point x="915" y="680" type="curve" smooth="yes"/>
+ <point x="915" y="884"/>
+ <point x="742" y="1040"/>
+ <point x="515" y="1040" type="curve" smooth="yes"/>
+ <point x="289" y="1040"/>
+ <point x="115" y="884"/>
+ </contour>
+ <contour>
+ <point x="285" y="680" type="curve" smooth="yes"/>
+ <point x="285" y="803"/>
+ <point x="382" y="895"/>
+ <point x="515" y="895" type="curve" smooth="yes"/>
+ <point x="649" y="895"/>
+ <point x="745" y="803"/>
+ <point x="745" y="680" type="curve" smooth="yes"/>
+ <point x="745" y="557"/>
+ <point x="649" y="465"/>
+ <point x="515" y="465" type="curve" smooth="yes"/>
+ <point x="382" y="465"/>
+ <point x="285" y="557"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/input/font-psf-test/source/PsfTest-Regular.ufo/glyphs/L_tnS_mH_.glif b/tests/input/font-psf-test/source/PsfTest-Regular.ufo/glyphs/L_tnS_mH_.glif
new file mode 100644
index 0000000..bad060c
--- /dev/null
+++ b/tests/input/font-psf-test/source/PsfTest-Regular.ufo/glyphs/L_tnS_mH_.glif
@@ -0,0 +1,43 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmH" format="2">
+ <advance width="1175"/>
+ <unicode hex="0068"/>
+ <anchor x="250" y="0" name="H"/>
+ <anchor x="585" y="-100" name="L"/>
+ <anchor x="585" y="1635" name="U"/>
+ <outline>
+ <contour>
+ <point x="1040" y="0" type="line"/>
+ <point x="1040" y="0"/>
+ <point x="1040" y="459"/>
+ <point x="1040" y="625" type="curve" smooth="yes"/>
+ <point x="1040" y="900"/>
+ <point x="923" y="1040"/>
+ <point x="710" y="1040" type="curve" smooth="yes"/>
+ <point x="570" y="1040"/>
+ <point x="428" y="969"/>
+ <point x="330" y="830" type="curve"/>
+ <point x="330" y="877"/>
+ <point x="330" y="1600"/>
+ <point x="330" y="1600" type="curve"/>
+ <point x="130" y="1600" type="line"/>
+ <point x="145" y="1514"/>
+ <point x="145" y="1345"/>
+ <point x="145" y="1130" type="curve" smooth="yes"/>
+ <point x="145" y="935"/>
+ <point x="145" y="0"/>
+ <point x="145" y="0" type="curve"/>
+ <point x="330" y="0" type="line"/>
+ <point x="330" y="580" type="line"/>
+ <point x="374" y="716"/>
+ <point x="511" y="865"/>
+ <point x="655" y="865" type="curve" smooth="yes"/>
+ <point x="789" y="865"/>
+ <point x="855" y="800"/>
+ <point x="855" y="550" type="curve" smooth="yes"/>
+ <point x="855" y="413"/>
+ <point x="855" y="0"/>
+ <point x="855" y="0" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/input/font-psf-test/source/PsfTest-Regular.ufo/glyphs/L_tnS_mI_.glif b/tests/input/font-psf-test/source/PsfTest-Regular.ufo/glyphs/L_tnS_mI_.glif
new file mode 100644
index 0000000..369347b
--- /dev/null
+++ b/tests/input/font-psf-test/source/PsfTest-Regular.ufo/glyphs/L_tnS_mI_.glif
@@ -0,0 +1,40 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmI" format="2">
+ <advance width="565"/>
+ <unicode hex="0069"/>
+ <anchor x="282" y="0" name="H"/>
+ <anchor x="285" y="-100" name="L"/>
+ <anchor x="500" y="0" name="O"/>
+ <anchor x="555" y="1000" name="R"/>
+ <anchor x="282" y="1100" name="U"/>
+ <outline>
+ <contour>
+ <point x="375" y="1020" type="line"/>
+ <point x="175" y="1020" type="line"/>
+ <point x="188" y="915"/>
+ <point x="190" y="725"/>
+ <point x="190" y="530" type="curve" smooth="yes"/>
+ <point x="190" y="336"/>
+ <point x="190" y="0"/>
+ <point x="190" y="0" type="curve"/>
+ <point x="395" y="0" type="line"/>
+ <point x="382" y="107"/>
+ <point x="375" y="346"/>
+ <point x="375" y="475" type="curve" smooth="yes"/>
+ </contour>
+ <contour>
+ <point x="155" y="1345" type="curve" smooth="yes"/>
+ <point x="155" y="1271"/>
+ <point x="206" y="1210"/>
+ <point x="280" y="1210" type="curve" smooth="yes"/>
+ <point x="355" y="1210"/>
+ <point x="410" y="1271"/>
+ <point x="410" y="1345" type="curve" smooth="yes"/>
+ <point x="410" y="1419"/>
+ <point x="355" y="1480"/>
+ <point x="280" y="1480" type="curve" smooth="yes"/>
+ <point x="206" y="1480"/>
+ <point x="155" y="1419"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/input/font-psf-test/source/PsfTest-Regular.ufo/glyphs/L_tnS_mJ_.glif b/tests/input/font-psf-test/source/PsfTest-Regular.ufo/glyphs/L_tnS_mJ_.glif
new file mode 100644
index 0000000..87f74c6
--- /dev/null
+++ b/tests/input/font-psf-test/source/PsfTest-Regular.ufo/glyphs/L_tnS_mJ_.glif
@@ -0,0 +1,44 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmJ" format="2">
+ <advance width="595"/>
+ <unicode hex="006A"/>
+ <anchor x="125" y="-500" name="L"/>
+ <anchor x="313" y="1100" name="U"/>
+ <outline>
+ <contour>
+ <point x="405" y="1020" type="line"/>
+ <point x="205" y="1020" type="line"/>
+ <point x="218" y="915"/>
+ <point x="220" y="725"/>
+ <point x="220" y="530" type="curve"/>
+ <point x="220" y="-25" type="line"/>
+ <point x="220" y="-222"/>
+ <point x="147" y="-300"/>
+ <point x="40" y="-300" type="curve" smooth="yes"/>
+ <point x="-16" y="-300"/>
+ <point x="-111" y="-273"/>
+ <point x="-155" y="-240" type="curve"/>
+ <point x="-190" y="-405" type="line"/>
+ <point x="-130" y="-446"/>
+ <point x="-26" y="-470"/>
+ <point x="30" y="-470" type="curve" smooth="yes"/>
+ <point x="258" y="-470"/>
+ <point x="405" y="-348"/>
+ <point x="405" y="25" type="curve" smooth="yes"/>
+ </contour>
+ <contour>
+ <point x="185" y="1345" type="curve" smooth="yes"/>
+ <point x="185" y="1271"/>
+ <point x="236" y="1210"/>
+ <point x="310" y="1210" type="curve" smooth="yes"/>
+ <point x="385" y="1210"/>
+ <point x="440" y="1271"/>
+ <point x="440" y="1345" type="curve" smooth="yes"/>
+ <point x="440" y="1419"/>
+ <point x="385" y="1480"/>
+ <point x="310" y="1480" type="curve" smooth="yes"/>
+ <point x="236" y="1480"/>
+ <point x="185" y="1419"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/input/font-psf-test/source/PsfTest-Regular.ufo/glyphs/L_tnS_mK_.glif b/tests/input/font-psf-test/source/PsfTest-Regular.ufo/glyphs/L_tnS_mK_.glif
new file mode 100644
index 0000000..d1b00cb
--- /dev/null
+++ b/tests/input/font-psf-test/source/PsfTest-Regular.ufo/glyphs/L_tnS_mK_.glif
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmK" format="2">
+ <advance width="1035"/>
+ <unicode hex="006B"/>
+ <guideline x="500" y="774" angle="314"/>
+ <anchor x="243" y="0" name="H"/>
+ <anchor x="572" y="-100" name="L"/>
+ <anchor x="1035" y="1000" name="R"/>
+ <anchor x="572" y="1635" name="U"/>
+ <outline>
+ <contour>
+ <point x="330" y="0" type="line"/>
+ <point x="330" y="1600" type="line"/>
+ <point x="130" y="1600" type="line"/>
+ <point x="145" y="1514"/>
+ <point x="145" y="1345"/>
+ <point x="145" y="1130" type="curve" smooth="yes"/>
+ <point x="145" y="934"/>
+ <point x="145" y="0"/>
+ <point x="145" y="0" type="curve"/>
+ </contour>
+ <contour>
+ <point x="735" y="1020" type="line"/>
+ <point x="280" y="550" type="line"/>
+ <point x="436" y="524" type="line"/>
+ <point x="985" y="1020" type="line"/>
+ </contour>
+ <contour>
+ <point x="305" y="550" type="line"/>
+ <point x="770" y="0" type="line"/>
+ <point x="1015" y="0" type="line"/>
+ <point x="410" y="660" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/input/font-psf-test/source/PsfTest-Regular.ufo/glyphs/L_tnS_mL_.glif b/tests/input/font-psf-test/source/PsfTest-Regular.ufo/glyphs/L_tnS_mL_.glif
new file mode 100644
index 0000000..4378793
--- /dev/null
+++ b/tests/input/font-psf-test/source/PsfTest-Regular.ufo/glyphs/L_tnS_mL_.glif
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmL" format="2">
+ <advance width="565"/>
+ <unicode hex="006C"/>
+ <guideline x="500" y="874" angle="340"/>
+ <anchor x="290" y="0" name="H"/>
+ <anchor x="290" y="-100" name="L"/>
+ <anchor x="550" y="1000" name="R"/>
+ <anchor x="282" y="1635" name="U"/>
+ <outline>
+ <contour>
+ <point x="375" y="1600" type="line"/>
+ <point x="170" y="1600" type="line"/>
+ <point x="183" y="1485"/>
+ <point x="190" y="1324"/>
+ <point x="190" y="1130" type="curve"/>
+ <point x="190" y="0" type="line"/>
+ <point x="395" y="0" type="line"/>
+ <point x="382" y="109"/>
+ <point x="375" y="346"/>
+ <point x="375" y="475" type="curve" smooth="yes"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/input/font-psf-test/source/PsfTest-Regular.ufo/glyphs/L_tnS_mM_.glif b/tests/input/font-psf-test/source/PsfTest-Regular.ufo/glyphs/L_tnS_mM_.glif
new file mode 100644
index 0000000..4498bb1
--- /dev/null
+++ b/tests/input/font-psf-test/source/PsfTest-Regular.ufo/glyphs/L_tnS_mM_.glif
@@ -0,0 +1,52 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmM" format="2">
+ <advance width="1685"/>
+ <unicode hex="006D"/>
+ <anchor x="1450" y="0" name="H"/>
+ <anchor x="865" y="-100" name="L"/>
+ <anchor x="865" y="1100" name="U"/>
+ <outline>
+ <contour>
+ <point x="945" y="660" type="line"/>
+ <point x="1003" y="785"/>
+ <point x="1102" y="865"/>
+ <point x="1200" y="865" type="curve" smooth="yes"/>
+ <point x="1312" y="865"/>
+ <point x="1345" y="808"/>
+ <point x="1345" y="550" type="curve" smooth="yes"/>
+ <point x="1345" y="0" type="line"/>
+ <point x="1530" y="0" type="line"/>
+ <point x="1530" y="660" type="line" smooth="yes"/>
+ <point x="1530" y="907"/>
+ <point x="1463" y="1040"/>
+ <point x="1260" y="1040" type="curve" smooth="yes"/>
+ <point x="1155" y="1040"/>
+ <point x="1046" y="1007"/>
+ <point x="921" y="872" type="curve"/>
+ <point x="888" y="960"/>
+ <point x="806" y="1040"/>
+ <point x="675" y="1040" type="curve" smooth="yes"/>
+ <point x="560" y="1040"/>
+ <point x="459" y="1006"/>
+ <point x="337" y="865" type="curve"/>
+ <point x="330" y="913"/>
+ <point x="320" y="978"/>
+ <point x="305" y="1020" type="curve"/>
+ <point x="125" y="1020" type="line"/>
+ <point x="146" y="951"/>
+ <point x="175" y="811"/>
+ <point x="175" y="615" type="curve" smooth="yes"/>
+ <point x="175" y="0" type="line"/>
+ <point x="360" y="0" type="line"/>
+ <point x="360" y="660" type="line"/>
+ <point x="413" y="780"/>
+ <point x="517" y="865"/>
+ <point x="615" y="865" type="curve" smooth="yes"/>
+ <point x="727" y="865"/>
+ <point x="760" y="818"/>
+ <point x="760" y="570" type="curve" smooth="yes"/>
+ <point x="760" y="0" type="line"/>
+ <point x="945" y="0" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/input/font-psf-test/source/PsfTest-Regular.ufo/glyphs/L_tnS_mN_.glif b/tests/input/font-psf-test/source/PsfTest-Regular.ufo/glyphs/L_tnS_mN_.glif
new file mode 100644
index 0000000..5534dd8
--- /dev/null
+++ b/tests/input/font-psf-test/source/PsfTest-Regular.ufo/glyphs/L_tnS_mN_.glif
@@ -0,0 +1,43 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmN" format="2">
+ <advance width="1185"/>
+ <unicode hex="006E"/>
+ <anchor x="970" y="0" name="H"/>
+ <anchor x="600" y="-100" name="L"/>
+ <anchor x="600" y="1100" name="U"/>
+ <outline>
+ <contour>
+ <point x="1050" y="0" type="line"/>
+ <point x="1050" y="0"/>
+ <point x="1050" y="459"/>
+ <point x="1050" y="625" type="curve" smooth="yes"/>
+ <point x="1050" y="900"/>
+ <point x="933" y="1040"/>
+ <point x="720" y="1040" type="curve" smooth="yes"/>
+ <point x="579" y="1040"/>
+ <point x="452" y="977"/>
+ <point x="325" y="825" type="curve"/>
+ <point x="318" y="873"/>
+ <point x="300" y="978"/>
+ <point x="285" y="1020" type="curve"/>
+ <point x="105" y="1020" type="line"/>
+ <point x="127" y="951"/>
+ <point x="155" y="811"/>
+ <point x="155" y="615" type="curve" smooth="yes"/>
+ <point x="155" y="420"/>
+ <point x="155" y="0"/>
+ <point x="155" y="0" type="curve"/>
+ <point x="340" y="0" type="line"/>
+ <point x="340" y="580" type="line"/>
+ <point x="384" y="716"/>
+ <point x="521" y="865"/>
+ <point x="665" y="865" type="curve" smooth="yes"/>
+ <point x="800" y="865"/>
+ <point x="865" y="800"/>
+ <point x="865" y="550" type="curve" smooth="yes"/>
+ <point x="865" y="413"/>
+ <point x="865" y="0"/>
+ <point x="865" y="0" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/input/font-psf-test/source/PsfTest-Regular.ufo/glyphs/L_tnS_mO_.glif b/tests/input/font-psf-test/source/PsfTest-Regular.ufo/glyphs/L_tnS_mO_.glif
new file mode 100644
index 0000000..ee9b6c6
--- /dev/null
+++ b/tests/input/font-psf-test/source/PsfTest-Regular.ufo/glyphs/L_tnS_mO_.glif
@@ -0,0 +1,40 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmO" format="2">
+ <advance width="1140"/>
+ <unicode hex="006F"/>
+ <anchor x="570" y="0" name="H"/>
+ <anchor x="570" y="-100" name="L"/>
+ <anchor x="835" y="0" name="O"/>
+ <anchor x="1140" y="1000" name="R"/>
+ <anchor x="570" y="1100" name="U"/>
+ <outline>
+ <contour>
+ <point x="95" y="505" type="curve" smooth="yes"/>
+ <point x="95" y="161"/>
+ <point x="286" y="-25"/>
+ <point x="560" y="-25" type="curve" smooth="yes"/>
+ <point x="823" y="-25"/>
+ <point x="1045" y="161"/>
+ <point x="1045" y="505" type="curve" smooth="yes"/>
+ <point x="1045" y="849"/>
+ <point x="855" y="1040"/>
+ <point x="580" y="1040" type="curve" smooth="yes"/>
+ <point x="317" y="1040"/>
+ <point x="95" y="849"/>
+ </contour>
+ <contour>
+ <point x="280" y="505" type="curve" smooth="yes"/>
+ <point x="280" y="739"/>
+ <point x="408" y="880"/>
+ <point x="570" y="880" type="curve" smooth="yes"/>
+ <point x="742" y="880"/>
+ <point x="860" y="739"/>
+ <point x="860" y="505" type="curve" smooth="yes"/>
+ <point x="860" y="272"/>
+ <point x="731" y="135"/>
+ <point x="570" y="135" type="curve" smooth="yes"/>
+ <point x="398" y="135"/>
+ <point x="280" y="272"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/input/font-psf-test/source/PsfTest-Regular.ufo/glyphs/L_tnS_mP_.glif b/tests/input/font-psf-test/source/PsfTest-Regular.ufo/glyphs/L_tnS_mP_.glif
new file mode 100644
index 0000000..e960bc9
--- /dev/null
+++ b/tests/input/font-psf-test/source/PsfTest-Regular.ufo/glyphs/L_tnS_mP_.glif
@@ -0,0 +1,56 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmP" format="2">
+ <advance width="1170"/>
+ <unicode hex="0070"/>
+ <guideline x="214" y="-490" angle="0"/>
+ <anchor x="265" y="-435" name="H"/>
+ <anchor x="590" y="-500" name="L"/>
+ <anchor x="1170" y="1000" name="R"/>
+ <anchor x="590" y="1100" name="U"/>
+ <outline>
+ <contour>
+ <point x="105" y="1020" type="line"/>
+ <point x="150" y="907"/>
+ <point x="155" y="734"/>
+ <point x="155" y="485" type="curve" smooth="yes"/>
+ <point x="155" y="291"/>
+ <point x="155" y="-490"/>
+ <point x="155" y="-490" type="curve"/>
+ <point x="365" y="-490" type="line"/>
+ <point x="348" y="-405"/>
+ <point x="340" y="-310"/>
+ <point x="340" y="-150" type="curve"/>
+ <point x="340" y="85" type="line"/>
+ <point x="435" y="18"/>
+ <point x="513" y="-25"/>
+ <point x="620" y="-25" type="curve" smooth="yes"/>
+ <point x="871" y="-25"/>
+ <point x="1075" y="193"/>
+ <point x="1075" y="535" type="curve" smooth="yes"/>
+ <point x="1075" y="828"/>
+ <point x="923" y="1040"/>
+ <point x="695" y="1040" type="curve" smooth="yes"/>
+ <point x="547" y="1040"/>
+ <point x="419" y="954"/>
+ <point x="325" y="830" type="curve"/>
+ <point x="316" y="922"/>
+ <point x="300" y="986"/>
+ <point x="285" y="1020" type="curve"/>
+ </contour>
+ <contour>
+ <point x="340" y="575" type="line"/>
+ <point x="414" y="768"/>
+ <point x="545" y="870"/>
+ <point x="660" y="870" type="curve" smooth="yes"/>
+ <point x="804" y="870"/>
+ <point x="890" y="727"/>
+ <point x="890" y="505" type="curve" smooth="yes"/>
+ <point x="890" y="279"/>
+ <point x="761" y="140"/>
+ <point x="620" y="140" type="curve" smooth="yes"/>
+ <point x="528" y="140"/>
+ <point x="477" y="164"/>
+ <point x="340" y="260" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/input/font-psf-test/source/PsfTest-Regular.ufo/glyphs/L_tnS_mQ_.glif b/tests/input/font-psf-test/source/PsfTest-Regular.ufo/glyphs/L_tnS_mQ_.glif
new file mode 100644
index 0000000..1da1d6a
--- /dev/null
+++ b/tests/input/font-psf-test/source/PsfTest-Regular.ufo/glyphs/L_tnS_mQ_.glif
@@ -0,0 +1,47 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmQ" format="2">
+ <advance width="1130"/>
+ <unicode hex="0071"/>
+ <anchor x="555" y="-500" name="L"/>
+ <anchor x="1130" y="1000" name="R"/>
+ <anchor x="555" y="1100" name="U"/>
+ <outline>
+ <contour>
+ <point x="795" y="-490" type="line"/>
+ <point x="1005" y="-490" type="line"/>
+ <point x="988" y="-405"/>
+ <point x="980" y="-310"/>
+ <point x="980" y="-150" type="curve" smooth="yes"/>
+ <point x="980" y="-26"/>
+ <point x="980" y="965"/>
+ <point x="980" y="965" type="curve"/>
+ <point x="872" y="1001"/>
+ <point x="746" y="1040"/>
+ <point x="625" y="1040" type="curve" smooth="yes"/>
+ <point x="260" y="1040"/>
+ <point x="105" y="742"/>
+ <point x="105" y="435" type="curve" smooth="yes"/>
+ <point x="105" y="117"/>
+ <point x="321" y="-25"/>
+ <point x="505" y="-25" type="curve" smooth="yes"/>
+ <point x="598" y="-25"/>
+ <point x="691" y="19"/>
+ <point x="795" y="140" type="curve"/>
+ </contour>
+ <contour>
+ <point x="795" y="365" type="line"/>
+ <point x="713" y="219"/>
+ <point x="612" y="145"/>
+ <point x="520" y="145" type="curve" smooth="yes"/>
+ <point x="412" y="145"/>
+ <point x="290" y="237"/>
+ <point x="290" y="485" type="curve" smooth="yes"/>
+ <point x="290" y="674"/>
+ <point x="376" y="870"/>
+ <point x="595" y="870" type="curve" smooth="yes"/>
+ <point x="656" y="870"/>
+ <point x="735" y="853"/>
+ <point x="795" y="830" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/input/font-psf-test/source/PsfTest-Regular.ufo/glyphs/L_tnS_mR_.glif b/tests/input/font-psf-test/source/PsfTest-Regular.ufo/glyphs/L_tnS_mR_.glif
new file mode 100644
index 0000000..0f090a4
--- /dev/null
+++ b/tests/input/font-psf-test/source/PsfTest-Regular.ufo/glyphs/L_tnS_mR_.glif
@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmR" format="2">
+ <advance width="890"/>
+ <unicode hex="0072"/>
+ <guideline x="214" y="500" angle="0"/>
+ <anchor x="270" y="0" name="H"/>
+ <anchor x="255" y="-100" name="L"/>
+ <anchor x="455" y="1100" name="U"/>
+ <outline>
+ <contour>
+ <point x="340" y="0" type="line"/>
+ <point x="340" y="580" type="line"/>
+ <point x="384" y="716"/>
+ <point x="521" y="860"/>
+ <point x="605" y="860" type="curve" smooth="yes"/>
+ <point x="684" y="860"/>
+ <point x="720" y="770"/>
+ <point x="720" y="670" type="curve"/>
+ <point x="880" y="705" type="line"/>
+ <point x="880" y="880"/>
+ <point x="817" y="1040"/>
+ <point x="650" y="1040" type="curve" smooth="yes"/>
+ <point x="559" y="1040"/>
+ <point x="422" y="964"/>
+ <point x="325" y="825" type="curve"/>
+ <point x="318" y="873"/>
+ <point x="300" y="978"/>
+ <point x="285" y="1020" type="curve"/>
+ <point x="105" y="1020" type="line"/>
+ <point x="127" y="951"/>
+ <point x="155" y="811"/>
+ <point x="155" y="615" type="curve" smooth="yes"/>
+ <point x="155" y="0" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/input/font-psf-test/source/PsfTest-Regular.ufo/glyphs/L_tnS_mS_.glif b/tests/input/font-psf-test/source/PsfTest-Regular.ufo/glyphs/L_tnS_mS_.glif
new file mode 100644
index 0000000..ea1e7ba
--- /dev/null
+++ b/tests/input/font-psf-test/source/PsfTest-Regular.ufo/glyphs/L_tnS_mS_.glif
@@ -0,0 +1,50 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmS" format="2">
+ <advance width="965"/>
+ <unicode hex="0073"/>
+ <anchor x="495" y="0" name="H"/>
+ <anchor x="495" y="-100" name="L"/>
+ <anchor x="495" y="1100" name="U"/>
+ <outline>
+ <contour>
+ <point x="835" y="960" type="line"/>
+ <point x="766" y="998"/>
+ <point x="660" y="1040"/>
+ <point x="515" y="1040" type="curve" smooth="yes"/>
+ <point x="211" y="1040"/>
+ <point x="130" y="832"/>
+ <point x="130" y="740" type="curve" smooth="yes"/>
+ <point x="130" y="616"/>
+ <point x="182" y="514"/>
+ <point x="425" y="455" type="curve" smooth="yes"/>
+ <point x="649" y="400"/>
+ <point x="700" y="345"/>
+ <point x="700" y="270" type="curve" smooth="yes"/>
+ <point x="700" y="201"/>
+ <point x="617" y="135"/>
+ <point x="500" y="135" type="curve" smooth="yes"/>
+ <point x="394" y="135"/>
+ <point x="250" y="189"/>
+ <point x="160" y="270" type="curve"/>
+ <point x="110" y="90" type="line"/>
+ <point x="189" y="28"/>
+ <point x="333" y="-25"/>
+ <point x="495" y="-25" type="curve" smooth="yes"/>
+ <point x="710" y="-25"/>
+ <point x="880" y="115"/>
+ <point x="880" y="295" type="curve" smooth="yes"/>
+ <point x="880" y="481"/>
+ <point x="731" y="559"/>
+ <point x="550" y="600" type="curve" smooth="yes"/>
+ <point x="340" y="648"/>
+ <point x="310" y="680"/>
+ <point x="310" y="750" type="curve" smooth="yes"/>
+ <point x="310" y="810"/>
+ <point x="358" y="880"/>
+ <point x="505" y="880" type="curve" smooth="yes"/>
+ <point x="629" y="880"/>
+ <point x="733" y="824"/>
+ <point x="800" y="785" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/input/font-psf-test/source/PsfTest-Regular.ufo/glyphs/L_tnS_mT_.glif b/tests/input/font-psf-test/source/PsfTest-Regular.ufo/glyphs/L_tnS_mT_.glif
new file mode 100644
index 0000000..45d6b50
--- /dev/null
+++ b/tests/input/font-psf-test/source/PsfTest-Regular.ufo/glyphs/L_tnS_mT_.glif
@@ -0,0 +1,39 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmT" format="2">
+ <advance width="835"/>
+ <unicode hex="0074"/>
+ <anchor x="475" y="0" name="H"/>
+ <anchor x="475" y="-100" name="L"/>
+ <anchor x="835" y="1000" name="R"/>
+ <anchor x="325" y="1360" name="U"/>
+ <outline>
+ <contour>
+ <point x="760" y="215" type="line"/>
+ <point x="672" y="166"/>
+ <point x="600" y="140"/>
+ <point x="543" y="140" type="curve" smooth="yes"/>
+ <point x="453" y="140"/>
+ <point x="415" y="184"/>
+ <point x="415" y="390" type="curve" smooth="yes"/>
+ <point x="415" y="528"/>
+ <point x="415" y="1320"/>
+ <point x="415" y="1320" type="curve"/>
+ <point x="230" y="1320" type="line"/>
+ <point x="230" y="1320"/>
+ <point x="230" y="435"/>
+ <point x="230" y="270" type="curve" smooth="yes"/>
+ <point x="230" y="39"/>
+ <point x="356" y="-25"/>
+ <point x="512" y="-25" type="curve" smooth="yes"/>
+ <point x="582" y="-25"/>
+ <point x="668" y="-4"/>
+ <point x="760" y="55" type="curve"/>
+ </contour>
+ <contour>
+ <point x="30" y="850" type="line"/>
+ <point x="740" y="850" type="line"/>
+ <point x="740" y="995" type="line"/>
+ <point x="30" y="995" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/input/font-psf-test/source/PsfTest-Regular.ufo/glyphs/L_tnS_mU_.glif b/tests/input/font-psf-test/source/PsfTest-Regular.ufo/glyphs/L_tnS_mU_.glif
new file mode 100644
index 0000000..39609ad
--- /dev/null
+++ b/tests/input/font-psf-test/source/PsfTest-Regular.ufo/glyphs/L_tnS_mU_.glif
@@ -0,0 +1,51 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmU" format="2">
+ <advance width="1185"/>
+ <unicode hex="0075"/>
+ <anchor x="589" y="0" name="H"/>
+ <anchor x="589" y="-100" name="L"/>
+ <anchor x="1192" y="0" name="O"/>
+ <anchor x="1185" y="1000" name="R"/>
+ <anchor x="589" y="1100" name="U"/>
+ <outline>
+ <contour>
+ <point x="1090" y="0" type="line"/>
+ <point x="1048" y="112"/>
+ <point x="1025" y="256"/>
+ <point x="1025" y="450" type="curve" smooth="yes"/>
+ <point x="1025" y="646"/>
+ <point x="1025" y="1020"/>
+ <point x="1025" y="1020" type="curve"/>
+ <point x="820" y="1020" type="line"/>
+ <point x="838" y="898"/>
+ <point x="840" y="832"/>
+ <point x="840" y="700" type="curve" smooth="yes"/>
+ <point x="840" y="420" type="line"/>
+ <point x="787" y="298"/>
+ <point x="628" y="140"/>
+ <point x="510" y="140" type="curve" smooth="yes"/>
+ <point x="383" y="140"/>
+ <point x="340" y="238"/>
+ <point x="340" y="465" type="curve" smooth="yes"/>
+ <point x="340" y="603"/>
+ <point x="340" y="1020"/>
+ <point x="340" y="1020" type="curve"/>
+ <point x="135" y="1020" type="line"/>
+ <point x="153" y="900"/>
+ <point x="155" y="827"/>
+ <point x="155" y="700" type="curve" smooth="yes"/>
+ <point x="155" y="681"/>
+ <point x="155" y="424"/>
+ <point x="155" y="405" type="curve" smooth="yes"/>
+ <point x="155" y="120"/>
+ <point x="262" y="-25"/>
+ <point x="475" y="-25" type="curve" smooth="yes"/>
+ <point x="615" y="-25"/>
+ <point x="744" y="53"/>
+ <point x="865" y="200" type="curve"/>
+ <point x="875" y="125"/>
+ <point x="901" y="46"/>
+ <point x="920" y="0" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/input/font-psf-test/source/PsfTest-Regular.ufo/glyphs/L_tnS_mV_.glif b/tests/input/font-psf-test/source/PsfTest-Regular.ufo/glyphs/L_tnS_mV_.glif
new file mode 100644
index 0000000..3097f4b
--- /dev/null
+++ b/tests/input/font-psf-test/source/PsfTest-Regular.ufo/glyphs/L_tnS_mV_.glif
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmV" format="2">
+ <advance width="1070"/>
+ <unicode hex="0076"/>
+ <anchor x="549" y="0" name="H"/>
+ <anchor x="535" y="-100" name="L"/>
+ <anchor x="725" y="0" name="O"/>
+ <anchor x="535" y="1100" name="U"/>
+ <outline>
+ <contour>
+ <point x="840" y="1020" type="line"/>
+ <point x="535" y="200" type="line"/>
+ <point x="230" y="1020" type="line"/>
+ <point x="20" y="1020" type="line"/>
+ <point x="75" y="905"/>
+ <point x="143" y="746"/>
+ <point x="175" y="665" type="curve" smooth="yes"/>
+ <point x="237" y="510"/>
+ <point x="440" y="0"/>
+ <point x="440" y="0" type="curve"/>
+ <point x="630" y="0" type="line"/>
+ <point x="630" y="0"/>
+ <point x="842" y="536"/>
+ <point x="895" y="665" type="curve" smooth="yes"/>
+ <point x="928" y="744"/>
+ <point x="993" y="905"/>
+ <point x="1050" y="1020" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/input/font-psf-test/source/PsfTest-Regular.ufo/glyphs/L_tnS_mW_.glif b/tests/input/font-psf-test/source/PsfTest-Regular.ufo/glyphs/L_tnS_mW_.glif
new file mode 100644
index 0000000..3557415
--- /dev/null
+++ b/tests/input/font-psf-test/source/PsfTest-Regular.ufo/glyphs/L_tnS_mW_.glif
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmW" format="2">
+ <advance width="1550"/>
+ <unicode hex="0077"/>
+ <anchor x="775" y="-100" name="L"/>
+ <anchor x="775" y="1100" name="U"/>
+ <outline>
+ <contour>
+ <point x="700" y="1020" type="line"/>
+ <point x="440" y="215" type="line"/>
+ <point x="230" y="1020" type="line"/>
+ <point x="45" y="1020" type="line"/>
+ <point x="92" y="867"/>
+ <point x="120" y="771"/>
+ <point x="150" y="665" type="curve" smooth="yes"/>
+ <point x="335" y="0" type="line"/>
+ <point x="525" y="0" type="line"/>
+ <point x="775" y="785" type="line"/>
+ <point x="1025" y="0" type="line"/>
+ <point x="1215" y="0" type="line"/>
+ <point x="1400" y="665" type="line" smooth="yes"/>
+ <point x="1434" y="785"/>
+ <point x="1458" y="868"/>
+ <point x="1505" y="1020" type="curve"/>
+ <point x="1320" y="1020" type="line"/>
+ <point x="1110" y="215" type="line"/>
+ <point x="850" y="1020" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/input/font-psf-test/source/PsfTest-Regular.ufo/glyphs/L_tnS_mX_.glif b/tests/input/font-psf-test/source/PsfTest-Regular.ufo/glyphs/L_tnS_mX_.glif
new file mode 100644
index 0000000..883cba4
--- /dev/null
+++ b/tests/input/font-psf-test/source/PsfTest-Regular.ufo/glyphs/L_tnS_mX_.glif
@@ -0,0 +1,40 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmX" format="2">
+ <advance width="1085"/>
+ <unicode hex="0078"/>
+ <anchor x="900" y="0" name="H"/>
+ <anchor x="542" y="-100" name="L"/>
+ <anchor x="542" y="1100" name="U"/>
+ <outline>
+ <contour>
+ <point x="805" y="0" type="line"/>
+ <point x="1035" y="0" type="line"/>
+ <point x="927" y="142"/>
+ <point x="902" y="170"/>
+ <point x="830" y="270" type="curve" smooth="yes"/>
+ <point x="290" y="1020" type="line"/>
+ <point x="60" y="1020" type="line"/>
+ <point x="168" y="887"/>
+ <point x="203" y="843"/>
+ <point x="270" y="750" type="curve"/>
+ </contour>
+ <contour>
+ <point x="489" y="616" type="line"/>
+ <point x="250" y="270" type="line" smooth="yes"/>
+ <point x="189" y="182"/>
+ <point x="160" y="143"/>
+ <point x="50" y="0" type="curve"/>
+ <point x="275" y="0" type="line"/>
+ <point x="556" y="404" type="line"/>
+ </contour>
+ <contour>
+ <point x="585" y="405" type="line"/>
+ <point x="820" y="750" type="line" smooth="yes"/>
+ <point x="883" y="842"/>
+ <point x="917" y="886"/>
+ <point x="1020" y="1020" type="curve"/>
+ <point x="795" y="1020" type="line"/>
+ <point x="520" y="615" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/input/font-psf-test/source/PsfTest-Regular.ufo/glyphs/L_tnS_mY_.glif b/tests/input/font-psf-test/source/PsfTest-Regular.ufo/glyphs/L_tnS_mY_.glif
new file mode 100644
index 0000000..cbe0f68
--- /dev/null
+++ b/tests/input/font-psf-test/source/PsfTest-Regular.ufo/glyphs/L_tnS_mY_.glif
@@ -0,0 +1,42 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmY" format="2">
+ <advance width="1060"/>
+ <unicode hex="0079"/>
+ <anchor x="795" y="-100" name="L"/>
+ <anchor x="1120" y="1000" name="R"/>
+ <anchor x="535" y="1100" name="U"/>
+ <outline>
+ <contour>
+ <point x="610" y="60" type="line"/>
+ <point x="230" y="1020" type="line"/>
+ <point x="30" y="1020" type="line"/>
+ <point x="107" y="864"/>
+ <point x="153" y="756"/>
+ <point x="190" y="665" type="curve" smooth="yes"/>
+ <point x="525" y="-165" type="line"/>
+ </contour>
+ <contour>
+ <point x="895" y="665" type="line"/>
+ <point x="928" y="758"/>
+ <point x="971" y="865"/>
+ <point x="1040" y="1020" type="curve"/>
+ <point x="840" y="1020" type="line"/>
+ <point x="840" y="1020"/>
+ <point x="564" y="230"/>
+ <point x="500" y="55" type="curve" smooth="yes"/>
+ <point x="391" y="-248"/>
+ <point x="315" y="-300"/>
+ <point x="225" y="-300" type="curve" smooth="yes"/>
+ <point x="159" y="-300"/>
+ <point x="82" y="-260"/>
+ <point x="40" y="-225" type="curve"/>
+ <point x="-20" y="-385" type="line"/>
+ <point x="53" y="-439"/>
+ <point x="134" y="-470"/>
+ <point x="225" y="-470" type="curve" smooth="yes"/>
+ <point x="395" y="-470"/>
+ <point x="516" y="-383"/>
+ <point x="655" y="0" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/input/font-psf-test/source/PsfTest-Regular.ufo/glyphs/N_onB_reakingH_yphen.glif b/tests/input/font-psf-test/source/PsfTest-Regular.ufo/glyphs/N_onB_reakingH_yphen.glif
new file mode 100644
index 0000000..14aff81
--- /dev/null
+++ b/tests/input/font-psf-test/source/PsfTest-Regular.ufo/glyphs/N_onB_reakingH_yphen.glif
@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="NonBreakingHyphen" format="2">
+ <advance width="860"/>
+ <unicode hex="2011"/>
+ <anchor x="430" y="1100" name="U"/>
+ <outline>
+ <component base="HyphenMinus"/>
+ </outline>
+</glyph>
diff --git a/tests/input/font-psf-test/source/PsfTest-Regular.ufo/glyphs/N_umS_gn.glif b/tests/input/font-psf-test/source/PsfTest-Regular.ufo/glyphs/N_umS_gn.glif
new file mode 100644
index 0000000..f4625db
--- /dev/null
+++ b/tests/input/font-psf-test/source/PsfTest-Regular.ufo/glyphs/N_umS_gn.glif
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="NumSgn" format="2">
+ <advance width="1200"/>
+ <unicode hex="0023"/>
+ <outline>
+ <contour>
+ <point x="487" y="1460" type="line"/>
+ <point x="127" y="200" type="line"/>
+ <point x="277" y="200" type="line"/>
+ <point x="637" y="1460" type="line"/>
+ </contour>
+ <contour>
+ <point x="25" y="575" type="line"/>
+ <point x="1116" y="575" type="line"/>
+ <point x="1116" y="725" type="line"/>
+ <point x="25" y="725" type="line"/>
+ </contour>
+ <contour>
+ <point x="84" y="960" type="line"/>
+ <point x="1175" y="960" type="line"/>
+ <point x="1175" y="1110" type="line"/>
+ <point x="84" y="1110" type="line"/>
+ </contour>
+ <contour>
+ <point x="912" y="1460" type="line"/>
+ <point x="552" y="200" type="line"/>
+ <point x="702" y="200" type="line"/>
+ <point x="1062" y="1460" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/input/font-psf-test/source/PsfTest-Regular.ufo/glyphs/P_ercentS_gn.glif b/tests/input/font-psf-test/source/PsfTest-Regular.ufo/glyphs/P_ercentS_gn.glif
new file mode 100644
index 0000000..e81f237
--- /dev/null
+++ b/tests/input/font-psf-test/source/PsfTest-Regular.ufo/glyphs/P_ercentS_gn.glif
@@ -0,0 +1,69 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="PercentSgn" format="2">
+ <advance width="1526"/>
+ <unicode hex="0025"/>
+ <outline>
+ <contour>
+ <point x="1261" y="366" type="curve" smooth="yes"/>
+ <point x="1261" y="182"/>
+ <point x="1216" y="115"/>
+ <point x="1130" y="115" type="curve" smooth="yes"/>
+ <point x="1041" y="115"/>
+ <point x="1001" y="181"/>
+ <point x="1001" y="381" type="curve" smooth="yes"/>
+ <point x="1001" y="565"/>
+ <point x="1043" y="630"/>
+ <point x="1130" y="630" type="curve" smooth="yes"/>
+ <point x="1221" y="630"/>
+ <point x="1261" y="566"/>
+ </contour>
+ <contour>
+ <point x="1426" y="379" type="curve" smooth="yes"/>
+ <point x="1426" y="652"/>
+ <point x="1310" y="770"/>
+ <point x="1135" y="770" type="curve" smooth="yes"/>
+ <point x="961" y="770"/>
+ <point x="836" y="650"/>
+ <point x="836" y="368" type="curve" smooth="yes"/>
+ <point x="836" y="86"/>
+ <point x="951" y="-25"/>
+ <point x="1126" y="-25" type="curve" smooth="yes"/>
+ <point x="1301" y="-25"/>
+ <point x="1426" y="84"/>
+ </contour>
+ <contour>
+ <point x="1073" y="1480" type="line"/>
+ <point x="291" y="-25" type="line"/>
+ <point x="459" y="-25" type="line"/>
+ <point x="1239" y="1480" type="line"/>
+ </contour>
+ <contour>
+ <point x="525" y="1076" type="curve" smooth="yes"/>
+ <point x="525" y="892"/>
+ <point x="480" y="825"/>
+ <point x="394" y="825" type="curve" smooth="yes"/>
+ <point x="305" y="825"/>
+ <point x="265" y="891"/>
+ <point x="265" y="1091" type="curve" smooth="yes"/>
+ <point x="265" y="1275"/>
+ <point x="307" y="1340"/>
+ <point x="394" y="1340" type="curve" smooth="yes"/>
+ <point x="485" y="1340"/>
+ <point x="525" y="1276"/>
+ </contour>
+ <contour>
+ <point x="690" y="1089" type="curve" smooth="yes"/>
+ <point x="690" y="1362"/>
+ <point x="574" y="1480"/>
+ <point x="399" y="1480" type="curve" smooth="yes"/>
+ <point x="225" y="1480"/>
+ <point x="100" y="1360"/>
+ <point x="100" y="1078" type="curve" smooth="yes"/>
+ <point x="100" y="796"/>
+ <point x="215" y="685"/>
+ <point x="390" y="685" type="curve" smooth="yes"/>
+ <point x="565" y="685"/>
+ <point x="690" y="794"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/input/font-psf-test/source/PsfTest-Regular.ufo/glyphs/P_lusS_gn.glif b/tests/input/font-psf-test/source/PsfTest-Regular.ufo/glyphs/P_lusS_gn.glif
new file mode 100644
index 0000000..de1f259
--- /dev/null
+++ b/tests/input/font-psf-test/source/PsfTest-Regular.ufo/glyphs/P_lusS_gn.glif
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="PlusSgn" format="2">
+ <advance width="1200"/>
+ <unicode hex="002B"/>
+ <outline>
+ <contour>
+ <point x="525" y="1180" type="line"/>
+ <point x="525" y="285" type="line"/>
+ <point x="675" y="285" type="line"/>
+ <point x="675" y="1180" type="line"/>
+ </contour>
+ <contour>
+ <point x="155" y="660" type="line"/>
+ <point x="1045" y="660" type="line"/>
+ <point x="1045" y="810" type="line"/>
+ <point x="155" y="810" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/input/font-psf-test/source/PsfTest-Regular.ufo/glyphs/Q_stnM_rk.glif b/tests/input/font-psf-test/source/PsfTest-Regular.ufo/glyphs/Q_stnM_rk.glif
new file mode 100644
index 0000000..5526aec
--- /dev/null
+++ b/tests/input/font-psf-test/source/PsfTest-Regular.ufo/glyphs/Q_stnM_rk.glif
@@ -0,0 +1,49 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="QstnMrk" format="2">
+ <advance width="1050"/>
+ <unicode hex="003F"/>
+ <outline>
+ <contour>
+ <point x="460" y="1540" type="curve" smooth="yes"/>
+ <point x="335" y="1540"/>
+ <point x="206" y="1493"/>
+ <point x="140" y="1430" type="curve"/>
+ <point x="185" y="1251" type="line"/>
+ <point x="261" y="1330"/>
+ <point x="352" y="1365"/>
+ <point x="432" y="1365" type="curve" smooth="yes"/>
+ <point x="579" y="1365"/>
+ <point x="625" y="1289"/>
+ <point x="625" y="1230" type="curve" smooth="yes"/>
+ <point x="625" y="1159"/>
+ <point x="572" y="1092"/>
+ <point x="485" y="980" type="curve" smooth="yes"/>
+ <point x="397" y="867"/>
+ <point x="355" y="730"/>
+ <point x="355" y="440" type="curve"/>
+ <point x="540" y="440" type="line"/>
+ <point x="540" y="721"/>
+ <point x="561" y="806"/>
+ <point x="665" y="927" type="curve" smooth="yes"/>
+ <point x="753" y="1028"/>
+ <point x="830" y="1117"/>
+ <point x="830" y="1240" type="curve" smooth="yes"/>
+ <point x="830" y="1422"/>
+ <point x="697" y="1540"/>
+ </contour>
+ <contour>
+ <point x="315" y="110" type="curve" smooth="yes"/>
+ <point x="315" y="36"/>
+ <point x="376" y="-25"/>
+ <point x="450" y="-25" type="curve" smooth="yes"/>
+ <point x="524" y="-25"/>
+ <point x="585" y="36"/>
+ <point x="585" y="110" type="curve" smooth="yes"/>
+ <point x="585" y="184"/>
+ <point x="524" y="245"/>
+ <point x="450" y="245" type="curve" smooth="yes"/>
+ <point x="376" y="245"/>
+ <point x="315" y="184"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/input/font-psf-test/source/PsfTest-Regular.ufo/glyphs/Q_uotM_rk.glif b/tests/input/font-psf-test/source/PsfTest-Regular.ufo/glyphs/Q_uotM_rk.glif
new file mode 100644
index 0000000..c9f06c6
--- /dev/null
+++ b/tests/input/font-psf-test/source/PsfTest-Regular.ufo/glyphs/Q_uotM_rk.glif
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="QuotMrk" format="2">
+ <advance width="1025"/>
+ <unicode hex="0022"/>
+ <outline>
+ <contour>
+ <point x="405" y="1045" type="line"/>
+ <point x="410" y="1186"/>
+ <point x="416" y="1339"/>
+ <point x="445" y="1585" type="curve"/>
+ <point x="240" y="1585" type="line"/>
+ <point x="271" y="1339"/>
+ <point x="276" y="1186"/>
+ <point x="280" y="1045" type="curve"/>
+ </contour>
+ <contour>
+ <point x="745" y="1045" type="line"/>
+ <point x="750" y="1186"/>
+ <point x="756" y="1339"/>
+ <point x="785" y="1585" type="curve"/>
+ <point x="580" y="1585" type="line"/>
+ <point x="611" y="1339"/>
+ <point x="616" y="1186"/>
+ <point x="620" y="1045" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/input/font-psf-test/source/PsfTest-Regular.ufo/glyphs/R_everseS_olidus.glif b/tests/input/font-psf-test/source/PsfTest-Regular.ufo/glyphs/R_everseS_olidus.glif
new file mode 100644
index 0000000..d145f26
--- /dev/null
+++ b/tests/input/font-psf-test/source/PsfTest-Regular.ufo/glyphs/R_everseS_olidus.glif
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="ReverseSolidus" format="2">
+ <advance width="1000"/>
+ <unicode hex="005C"/>
+ <outline>
+ <contour>
+ <point x="990" y="-245" type="line"/>
+ <point x="160" y="1600" type="line"/>
+ <point x="10" y="1600" type="line"/>
+ <point x="840" y="-245" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/input/font-psf-test/source/PsfTest-Regular.ufo/glyphs/R_tC_urlyB_rac.glif b/tests/input/font-psf-test/source/PsfTest-Regular.ufo/glyphs/R_tC_urlyB_rac.glif
new file mode 100644
index 0000000..288a75a
--- /dev/null
+++ b/tests/input/font-psf-test/source/PsfTest-Regular.ufo/glyphs/R_tC_urlyB_rac.glif
@@ -0,0 +1,47 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="RtCurlyBrac" format="2">
+ <advance width="1000"/>
+ <unicode hex="007D"/>
+ <outline>
+ <contour>
+ <point x="790" y="615" type="curve" smooth="yes"/>
+ <point x="790" y="647"/>
+ <point x="617" y="744"/>
+ <point x="590" y="780" type="curve" smooth="yes"/>
+ <point x="566" y="812"/>
+ <point x="576" y="1435"/>
+ <point x="505" y="1515" type="curve" smooth="yes"/>
+ <point x="465" y="1560"/>
+ <point x="304" y="1613"/>
+ <point x="200" y="1640" type="curve"/>
+ <point x="160" y="1500" type="line"/>
+ <point x="227" y="1477"/>
+ <point x="350" y="1428"/>
+ <point x="370" y="1400" type="curve" smooth="yes"/>
+ <point x="403" y="1353"/>
+ <point x="390" y="783"/>
+ <point x="410" y="745" type="curve" smooth="yes"/>
+ <point x="429" y="709"/>
+ <point x="566" y="637"/>
+ <point x="570" y="615" type="curve"/>
+ <point x="566" y="593"/>
+ <point x="429" y="521"/>
+ <point x="410" y="485" type="curve" smooth="yes"/>
+ <point x="390" y="447"/>
+ <point x="403" y="-123"/>
+ <point x="370" y="-170" type="curve" smooth="yes"/>
+ <point x="350" y="-198"/>
+ <point x="227" y="-247"/>
+ <point x="160" y="-270" type="curve"/>
+ <point x="200" y="-410" type="line"/>
+ <point x="304" y="-383"/>
+ <point x="465" y="-330"/>
+ <point x="505" y="-285" type="curve" smooth="yes"/>
+ <point x="576" y="-205"/>
+ <point x="566" y="418"/>
+ <point x="590" y="450" type="curve" smooth="yes"/>
+ <point x="617" y="486"/>
+ <point x="790" y="583"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/input/font-psf-test/source/PsfTest-Regular.ufo/glyphs/R_tP_aren.glif b/tests/input/font-psf-test/source/PsfTest-Regular.ufo/glyphs/R_tP_aren.glif
new file mode 100644
index 0000000..3983f6b
--- /dev/null
+++ b/tests/input/font-psf-test/source/PsfTest-Regular.ufo/glyphs/R_tP_aren.glif
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="RtParen" format="2">
+ <advance width="795"/>
+ <unicode hex="0029"/>
+ <outline>
+ <contour>
+ <point x="680" y="625" type="curve" smooth="yes"/>
+ <point x="680" y="1062"/>
+ <point x="505" y="1444"/>
+ <point x="240" y="1640" type="curve"/>
+ <point x="165" y="1485" type="line"/>
+ <point x="390" y="1280"/>
+ <point x="490" y="962"/>
+ <point x="490" y="625" type="curve" smooth="yes"/>
+ <point x="490" y="278"/>
+ <point x="390" y="-8"/>
+ <point x="165" y="-265" type="curve"/>
+ <point x="260" y="-410" type="line"/>
+ <point x="535" y="-125"/>
+ <point x="680" y="218"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/input/font-psf-test/source/PsfTest-Regular.ufo/glyphs/R_tS_qrB_rac.glif b/tests/input/font-psf-test/source/PsfTest-Regular.ufo/glyphs/R_tS_qrB_rac.glif
new file mode 100644
index 0000000..702689b
--- /dev/null
+++ b/tests/input/font-psf-test/source/PsfTest-Regular.ufo/glyphs/R_tS_qrB_rac.glif
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="RtSqrBrac" format="2">
+ <advance width="790"/>
+ <unicode hex="005D"/>
+ <outline>
+ <contour>
+ <point x="590" y="-410" type="line"/>
+ <point x="590" y="1600" type="line"/>
+ <point x="150" y="1600" type="line"/>
+ <point x="150" y="1450" type="line"/>
+ <point x="405" y="1450" type="line"/>
+ <point x="405" y="-260" type="line"/>
+ <point x="150" y="-260" type="line"/>
+ <point x="150" y="-410" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/input/font-psf-test/source/PsfTest-Regular.ufo/glyphs/S_emicolon.glif b/tests/input/font-psf-test/source/PsfTest-Regular.ufo/glyphs/S_emicolon.glif
new file mode 100644
index 0000000..247bed0
--- /dev/null
+++ b/tests/input/font-psf-test/source/PsfTest-Regular.ufo/glyphs/S_emicolon.glif
@@ -0,0 +1,38 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="Semicolon" format="2">
+ <advance width="650"/>
+ <unicode hex="003B"/>
+ <outline>
+ <contour>
+ <point x="185" y="790" type="curve" smooth="yes"/>
+ <point x="185" y="716"/>
+ <point x="246" y="655"/>
+ <point x="320" y="655" type="curve" smooth="yes"/>
+ <point x="394" y="655"/>
+ <point x="455" y="716"/>
+ <point x="455" y="790" type="curve" smooth="yes"/>
+ <point x="455" y="864"/>
+ <point x="394" y="925"/>
+ <point x="320" y="925" type="curve" smooth="yes"/>
+ <point x="246" y="925"/>
+ <point x="185" y="864"/>
+ </contour>
+ <contour>
+ <point x="185" y="50" type="line"/>
+ <point x="325" y="50" type="line"/>
+ <point x="325" y="-51"/>
+ <point x="248" y="-172"/>
+ <point x="190" y="-230" type="curve"/>
+ <point x="290" y="-270" type="line"/>
+ <point x="407" y="-160"/>
+ <point x="465" y="-37"/>
+ <point x="465" y="85" type="curve" smooth="yes"/>
+ <point x="465" y="186"/>
+ <point x="400" y="250"/>
+ <point x="320" y="250" type="curve" smooth="yes"/>
+ <point x="263" y="250"/>
+ <point x="198" y="213"/>
+ <point x="185" y="150" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/input/font-psf-test/source/PsfTest-Regular.ufo/glyphs/S_olidus.glif b/tests/input/font-psf-test/source/PsfTest-Regular.ufo/glyphs/S_olidus.glif
new file mode 100644
index 0000000..3edff5d
--- /dev/null
+++ b/tests/input/font-psf-test/source/PsfTest-Regular.ufo/glyphs/S_olidus.glif
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="Solidus" format="2">
+ <advance width="1000"/>
+ <unicode hex="002F"/>
+ <outline>
+ <contour>
+ <point x="840" y="1600" type="line"/>
+ <point x="10" y="-245" type="line"/>
+ <point x="160" y="-245" type="line"/>
+ <point x="990" y="1600" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/input/font-psf-test/source/PsfTest-Regular.ufo/glyphs/S_pace.glif b/tests/input/font-psf-test/source/PsfTest-Regular.ufo/glyphs/S_pace.glif
new file mode 100644
index 0000000..ef0bed7
--- /dev/null
+++ b/tests/input/font-psf-test/source/PsfTest-Regular.ufo/glyphs/S_pace.glif
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="Space" format="2">
+ <advance width="550"/>
+ <unicode hex="0020"/>
+ <outline/>
+</glyph>
diff --git a/tests/input/font-psf-test/source/PsfTest-Regular.ufo/glyphs/T_ilde.glif b/tests/input/font-psf-test/source/PsfTest-Regular.ufo/glyphs/T_ilde.glif
new file mode 100644
index 0000000..60ddaa7
--- /dev/null
+++ b/tests/input/font-psf-test/source/PsfTest-Regular.ufo/glyphs/T_ilde.glif
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="Tilde" format="2">
+ <advance width="1115"/>
+ <unicode hex="007E"/>
+ <outline>
+ <contour>
+ <point x="125" y="375" type="line"/>
+ <point x="130" y="424"/>
+ <point x="162" y="465"/>
+ <point x="240" y="465" type="curve" smooth="yes"/>
+ <point x="415" y="465"/>
+ <point x="615" y="360"/>
+ <point x="845" y="360" type="curve" smooth="yes"/>
+ <point x="1004" y="360"/>
+ <point x="1080" y="482"/>
+ <point x="1080" y="610" type="curve"/>
+ <point x="975" y="610" type="line"/>
+ <point x="968" y="564"/>
+ <point x="938" y="510"/>
+ <point x="855" y="510" type="curve" smooth="yes"/>
+ <point x="619" y="510"/>
+ <point x="461" y="615"/>
+ <point x="240" y="615" type="curve" smooth="yes"/>
+ <point x="94" y="615"/>
+ <point x="20" y="497"/>
+ <point x="20" y="375" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/input/font-psf-test/source/PsfTest-Regular.ufo/glyphs/V_ertL_ine.glif b/tests/input/font-psf-test/source/PsfTest-Regular.ufo/glyphs/V_ertL_ine.glif
new file mode 100644
index 0000000..c73e040
--- /dev/null
+++ b/tests/input/font-psf-test/source/PsfTest-Regular.ufo/glyphs/V_ertL_ine.glif
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="VertLine" format="2">
+ <advance width="690"/>
+ <unicode hex="007C"/>
+ <outline>
+ <contour>
+ <point x="270" y="1600" type="line"/>
+ <point x="270" y="-390" type="line"/>
+ <point x="420" y="-390" type="line"/>
+ <point x="420" y="1600" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/input/font-psf-test/source/PsfTest-Regular.ufo/glyphs/_notdef.glif b/tests/input/font-psf-test/source/PsfTest-Regular.ufo/glyphs/_notdef.glif
new file mode 100644
index 0000000..a3e9354
--- /dev/null
+++ b/tests/input/font-psf-test/source/PsfTest-Regular.ufo/glyphs/_notdef.glif
@@ -0,0 +1,18 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name=".notdef" format="2">
+ <advance width="1400"/>
+ <outline>
+ <contour>
+ <point x="100" y="0" type="line"/>
+ <point x="1300" y="0" type="line"/>
+ <point x="1300" y="1800" type="line"/>
+ <point x="100" y="1800" type="line"/>
+ </contour>
+ <contour>
+ <point x="150" y="1750" type="line"/>
+ <point x="1250" y="1750" type="line"/>
+ <point x="1250" y="50" type="line"/>
+ <point x="150" y="50" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/input/font-psf-test/source/PsfTest-Regular.ufo/glyphs/_null.glif b/tests/input/font-psf-test/source/PsfTest-Regular.ufo/glyphs/_null.glif
new file mode 100644
index 0000000..0b9caa6
--- /dev/null
+++ b/tests/input/font-psf-test/source/PsfTest-Regular.ufo/glyphs/_null.glif
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name=".null" format="2">
+ <outline/>
+</glyph>
diff --git a/tests/input/font-psf-test/source/PsfTest-Regular.ufo/glyphs/contents.plist b/tests/input/font-psf-test/source/PsfTest-Regular.ufo/glyphs/contents.plist
new file mode 100644
index 0000000..de3c0b3
--- /dev/null
+++ b/tests/input/font-psf-test/source/PsfTest-Regular.ufo/glyphs/contents.plist
@@ -0,0 +1,234 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+ <key>.notdef</key>
+ <string>_notdef.glif</string>
+ <key>.null</key>
+ <string>_null.glif</string>
+ <key>Ampersand</key>
+ <string>A_mpersand.glif</string>
+ <key>Apos</key>
+ <string>A_pos.glif</string>
+ <key>Asterisk</key>
+ <string>A_sterisk.glif</string>
+ <key>AtSgn</key>
+ <string>A_tS_gn.glif</string>
+ <key>CircumAccent</key>
+ <string>C_ircumA_ccent.glif</string>
+ <key>Colon</key>
+ <string>C_olon.glif</string>
+ <key>CombAcute</key>
+ <string>C_ombA_cute.glif</string>
+ <key>CombCircum</key>
+ <string>C_ombC_ircum.glif</string>
+ <key>CombDiaer</key>
+ <string>C_ombD_iaer.glif</string>
+ <key>CombGrave</key>
+ <string>C_ombG_rave.glif</string>
+ <key>CombRingAbv</key>
+ <string>C_ombR_ingA_bv.glif</string>
+ <key>CombTilde</key>
+ <string>C_ombT_ilde.glif</string>
+ <key>Comma</key>
+ <string>C_omma.glif</string>
+ <key>DigitEight</key>
+ <string>D_igitE_ight.glif</string>
+ <key>DigitFive</key>
+ <string>D_igitF_ive.glif</string>
+ <key>DigitFour</key>
+ <string>D_igitF_our.glif</string>
+ <key>DigitNine</key>
+ <string>D_igitN_ine.glif</string>
+ <key>DigitOne</key>
+ <string>D_igitO_ne.glif</string>
+ <key>DigitSeven</key>
+ <string>D_igitS_even.glif</string>
+ <key>DigitSix</key>
+ <string>D_igitS_ix.glif</string>
+ <key>DigitThree</key>
+ <string>D_igitT_hree.glif</string>
+ <key>DigitTwo</key>
+ <string>D_igitT_wo.glif</string>
+ <key>DigitZero</key>
+ <string>D_igitZ_ero.glif</string>
+ <key>DollarSgn</key>
+ <string>D_ollarS_gn.glif</string>
+ <key>DottedCirc</key>
+ <string>D_ottedC_irc.glif</string>
+ <key>EqSgn</key>
+ <string>E_qS_gn.glif</string>
+ <key>ExclamationMrk</key>
+ <string>E_xclamationM_rk.glif</string>
+ <key>FullStop</key>
+ <string>F_ullS_top.glif</string>
+ <key>GTSgn</key>
+ <string>G_T_S_gn.glif</string>
+ <key>GraveAccent</key>
+ <string>G_raveA_ccent.glif</string>
+ <key>Hyphen</key>
+ <string>H_yphen.glif</string>
+ <key>HyphenMinus</key>
+ <string>H_yphenM_inus.glif</string>
+ <key>Hyphen_Soft</key>
+ <string>H_yphen_S_oft.glif</string>
+ <key>LTSgn</key>
+ <string>L_T_S_gn.glif</string>
+ <key>LftCurlyBrac</key>
+ <string>L_ftC_urlyB_rac.glif</string>
+ <key>LftParen</key>
+ <string>L_ftP_aren.glif</string>
+ <key>LftSqrBrac</key>
+ <string>L_ftS_qrB_rac.glif</string>
+ <key>LowLine</key>
+ <string>L_owL_ine.glif</string>
+ <key>LtnCapA</key>
+ <string>L_tnC_apA_.glif</string>
+ <key>LtnCapA.alt</key>
+ <string>L_tnC_apA_.alt.glif</string>
+ <key>LtnCapADiaer</key>
+ <string>L_tnC_apA_D_iaer.glif</string>
+ <key>LtnCapB</key>
+ <string>L_tnC_apB_.glif</string>
+ <key>LtnCapC</key>
+ <string>L_tnC_apC_.glif</string>
+ <key>LtnCapD</key>
+ <string>L_tnC_apD_.glif</string>
+ <key>LtnCapE</key>
+ <string>L_tnC_apE_.glif</string>
+ <key>LtnCapF</key>
+ <string>L_tnC_apF_.glif</string>
+ <key>LtnCapG</key>
+ <string>L_tnC_apG_.glif</string>
+ <key>LtnCapH</key>
+ <string>L_tnC_apH_.glif</string>
+ <key>LtnCapI</key>
+ <string>L_tnC_apI_.glif</string>
+ <key>LtnCapJ</key>
+ <string>L_tnC_apJ_.glif</string>
+ <key>LtnCapK</key>
+ <string>L_tnC_apK_.glif</string>
+ <key>LtnCapL</key>
+ <string>L_tnC_apL_.glif</string>
+ <key>LtnCapM</key>
+ <string>L_tnC_apM_.glif</string>
+ <key>LtnCapN</key>
+ <string>L_tnC_apN_.glif</string>
+ <key>LtnCapO</key>
+ <string>L_tnC_apO_.glif</string>
+ <key>LtnCapP</key>
+ <string>L_tnC_apP_.glif</string>
+ <key>LtnCapQ</key>
+ <string>L_tnC_apQ_.glif</string>
+ <key>LtnCapR</key>
+ <string>L_tnC_apR_.glif</string>
+ <key>LtnCapS</key>
+ <string>L_tnC_apS_.glif</string>
+ <key>LtnCapT</key>
+ <string>L_tnC_apT_.glif</string>
+ <key>LtnCapU</key>
+ <string>L_tnC_apU_.glif</string>
+ <key>LtnCapV</key>
+ <string>L_tnC_apV_.glif</string>
+ <key>LtnCapW</key>
+ <string>L_tnC_apW_.glif</string>
+ <key>LtnCapX</key>
+ <string>L_tnC_apX_.glif</string>
+ <key>LtnCapY</key>
+ <string>L_tnC_apY_.glif</string>
+ <key>LtnSmA</key>
+ <string>L_tnS_mA_.glif</string>
+ <key>LtnSmAAcute</key>
+ <string>L_tnS_mA_A_cute.glif</string>
+ <key>LtnSmACircum</key>
+ <string>L_tnS_mA_C_ircum.glif</string>
+ <key>LtnSmADiaer</key>
+ <string>L_tnS_mA_D_iaer.glif</string>
+ <key>LtnSmAGrave</key>
+ <string>L_tnS_mA_G_rave.glif</string>
+ <key>LtnSmARingAbv</key>
+ <string>L_tnS_mA_R_ingA_bv.glif</string>
+ <key>LtnSmATilde</key>
+ <string>L_tnS_mA_T_ilde.glif</string>
+ <key>LtnSmB</key>
+ <string>L_tnS_mB_.glif</string>
+ <key>LtnSmC</key>
+ <string>L_tnS_mC_.glif</string>
+ <key>LtnSmD</key>
+ <string>L_tnS_mD_.glif</string>
+ <key>LtnSmE</key>
+ <string>L_tnS_mE_.glif</string>
+ <key>LtnSmF</key>
+ <string>L_tnS_mF_.glif</string>
+ <key>LtnSmG</key>
+ <string>L_tnS_mG_.glif</string>
+ <key>LtnSmH</key>
+ <string>L_tnS_mH_.glif</string>
+ <key>LtnSmI</key>
+ <string>L_tnS_mI_.glif</string>
+ <key>LtnSmJ</key>
+ <string>L_tnS_mJ_.glif</string>
+ <key>LtnSmK</key>
+ <string>L_tnS_mK_.glif</string>
+ <key>LtnSmL</key>
+ <string>L_tnS_mL_.glif</string>
+ <key>LtnSmM</key>
+ <string>L_tnS_mM_.glif</string>
+ <key>LtnSmN</key>
+ <string>L_tnS_mN_.glif</string>
+ <key>LtnSmO</key>
+ <string>L_tnS_mO_.glif</string>
+ <key>LtnSmP</key>
+ <string>L_tnS_mP_.glif</string>
+ <key>LtnSmQ</key>
+ <string>L_tnS_mQ_.glif</string>
+ <key>LtnSmR</key>
+ <string>L_tnS_mR_.glif</string>
+ <key>LtnSmS</key>
+ <string>L_tnS_mS_.glif</string>
+ <key>LtnSmT</key>
+ <string>L_tnS_mT_.glif</string>
+ <key>LtnSmU</key>
+ <string>L_tnS_mU_.glif</string>
+ <key>LtnSmV</key>
+ <string>L_tnS_mV_.glif</string>
+ <key>LtnSmW</key>
+ <string>L_tnS_mW_.glif</string>
+ <key>LtnSmX</key>
+ <string>L_tnS_mX_.glif</string>
+ <key>LtnSmY</key>
+ <string>L_tnS_mY_.glif</string>
+ <key>NonBreakingHyphen</key>
+ <string>N_onB_reakingH_yphen.glif</string>
+ <key>NumSgn</key>
+ <string>N_umS_gn.glif</string>
+ <key>PercentSgn</key>
+ <string>P_ercentS_gn.glif</string>
+ <key>PlusSgn</key>
+ <string>P_lusS_gn.glif</string>
+ <key>QstnMrk</key>
+ <string>Q_stnM_rk.glif</string>
+ <key>QuotMrk</key>
+ <string>Q_uotM_rk.glif</string>
+ <key>ReverseSolidus</key>
+ <string>R_everseS_olidus.glif</string>
+ <key>RtCurlyBrac</key>
+ <string>R_tC_urlyB_rac.glif</string>
+ <key>RtParen</key>
+ <string>R_tP_aren.glif</string>
+ <key>RtSqrBrac</key>
+ <string>R_tS_qrB_rac.glif</string>
+ <key>Semicolon</key>
+ <string>S_emicolon.glif</string>
+ <key>Solidus</key>
+ <string>S_olidus.glif</string>
+ <key>Space</key>
+ <string>S_pace.glif</string>
+ <key>Tilde</key>
+ <string>T_ilde.glif</string>
+ <key>VertLine</key>
+ <string>V_ertL_ine.glif</string>
+ <key>nonmarkingreturn</key>
+ <string>nonmarkingreturn.glif</string>
+</dict>
+</plist>
diff --git a/tests/input/font-psf-test/source/PsfTest-Regular.ufo/glyphs/nonmarkingreturn.glif b/tests/input/font-psf-test/source/PsfTest-Regular.ufo/glyphs/nonmarkingreturn.glif
new file mode 100644
index 0000000..ee41448
--- /dev/null
+++ b/tests/input/font-psf-test/source/PsfTest-Regular.ufo/glyphs/nonmarkingreturn.glif
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="nonmarkingreturn" format="2">
+ <advance width="1024"/>
+ <outline/>
+</glyph>
diff --git a/tests/input/font-psf-test/source/PsfTest-Regular.ufo/layercontents.plist b/tests/input/font-psf-test/source/PsfTest-Regular.ufo/layercontents.plist
new file mode 100644
index 0000000..42b7482
--- /dev/null
+++ b/tests/input/font-psf-test/source/PsfTest-Regular.ufo/layercontents.plist
@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<array>
+ <array>
+ <string>public.default</string>
+ <string>glyphs</string>
+ </array>
+</array>
+</plist>
diff --git a/tests/input/font-psf-test/source/PsfTest-Regular.ufo/lib.plist b/tests/input/font-psf-test/source/PsfTest-Regular.ufo/lib.plist
new file mode 100644
index 0000000..8b95204
--- /dev/null
+++ b/tests/input/font-psf-test/source/PsfTest-Regular.ufo/lib.plist
@@ -0,0 +1,536 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+ <key>com.schriftgestaltung.Glyphs.fontUserData</key>
+ <dict/>
+ <key>com.schriftgestaltung.appVersion</key>
+ <string>1161</string>
+ <key>com.schriftgestaltung.customParameter.GSFont.DisplayStrings</key>
+ <string/>
+ <key>com.schriftgestaltung.customParameter.GSFont.disablesAutomaticAlignment</key>
+ <true/>
+ <key>com.schriftgestaltung.customParameter.GSFont.disablesLastChange</key>
+ <true/>
+ <key>com.schriftgestaltung.customParameter.GSFont.useNiceNames</key>
+ <integer>0</integer>
+ <key>com.schriftgestaltung.customParameter.GSFontMaster.customValue</key>
+ <integer>0</integer>
+ <key>com.schriftgestaltung.customParameter.GSFontMaster.customValue1</key>
+ <integer>0</integer>
+ <key>com.schriftgestaltung.customParameter.GSFontMaster.customValue2</key>
+ <integer>0</integer>
+ <key>com.schriftgestaltung.customParameter.GSFontMaster.customValue3</key>
+ <integer>0</integer>
+ <key>com.schriftgestaltung.customParameter.GSFontMaster.iconName</key>
+ <string/>
+ <key>com.schriftgestaltung.customParameter.GSFontMaster.weightValue</key>
+ <integer>400</integer>
+ <key>com.schriftgestaltung.customParameter.GSFontMaster.widthValue</key>
+ <integer>100</integer>
+ <key>com.schriftgestaltung.disablesAutomaticAlignment</key>
+ <true/>
+ <key>com.schriftgestaltung.disablesLastChange</key>
+ <true/>
+ <key>com.schriftgestaltung.fontMasterOrder</key>
+ <integer>0</integer>
+ <key>com.schriftgestaltung.glyphOrder</key>
+ <array>
+ <string>.notdef</string>
+ <string>.null</string>
+ <string>nonmarkingreturn</string>
+ <string>Space</string>
+ <string>ExclamationMrk</string>
+ <string>QuotMrk</string>
+ <string>NumSgn</string>
+ <string>DollarSgn</string>
+ <string>PercentSgn</string>
+ <string>Ampersand</string>
+ <string>Apos</string>
+ <string>LftParen</string>
+ <string>RtParen</string>
+ <string>Asterisk</string>
+ <string>PlusSgn</string>
+ <string>Comma</string>
+ <string>HyphenMinus</string>
+ <string>FullStop</string>
+ <string>Solidus</string>
+ <string>DigitZero</string>
+ <string>DigitOne</string>
+ <string>DigitTwo</string>
+ <string>DigitThree</string>
+ <string>DigitFour</string>
+ <string>DigitFive</string>
+ <string>DigitSix</string>
+ <string>DigitSeven</string>
+ <string>DigitEight</string>
+ <string>DigitNine</string>
+ <string>Colon</string>
+ <string>Semicolon</string>
+ <string>LTSgn</string>
+ <string>EqSgn</string>
+ <string>GTSgn</string>
+ <string>QstnMrk</string>
+ <string>AtSgn</string>
+ <string>LtnCapA</string>
+ <string>LtnCapA.alt</string>
+ <string>LtnCapB</string>
+ <string>LtnCapC</string>
+ <string>LtnCapD</string>
+ <string>LtnCapE</string>
+ <string>LtnCapF</string>
+ <string>LtnCapG</string>
+ <string>LtnCapH</string>
+ <string>LtnCapI</string>
+ <string>LtnCapJ</string>
+ <string>LtnCapK</string>
+ <string>LtnCapL</string>
+ <string>LtnCapM</string>
+ <string>LtnCapN</string>
+ <string>LtnCapO</string>
+ <string>LtnCapP</string>
+ <string>LtnCapQ</string>
+ <string>LtnCapR</string>
+ <string>LtnCapS</string>
+ <string>LtnCapT</string>
+ <string>LtnCapU</string>
+ <string>LtnCapV</string>
+ <string>LtnCapW</string>
+ <string>LtnCapX</string>
+ <string>LtnCapY</string>
+ <string>LftSqrBrac</string>
+ <string>ReverseSolidus</string>
+ <string>RtSqrBrac</string>
+ <string>CircumAccent</string>
+ <string>LowLine</string>
+ <string>GraveAccent</string>
+ <string>LtnSmA</string>
+ <string>LtnSmB</string>
+ <string>LtnSmC</string>
+ <string>LtnSmD</string>
+ <string>LtnSmE</string>
+ <string>LtnSmF</string>
+ <string>LtnSmG</string>
+ <string>LtnSmH</string>
+ <string>LtnSmI</string>
+ <string>LtnSmJ</string>
+ <string>LtnSmK</string>
+ <string>LtnSmL</string>
+ <string>LtnSmM</string>
+ <string>LtnSmN</string>
+ <string>LtnSmO</string>
+ <string>LtnSmP</string>
+ <string>LtnSmQ</string>
+ <string>LtnSmR</string>
+ <string>LtnSmS</string>
+ <string>LtnSmT</string>
+ <string>LtnSmU</string>
+ <string>LtnSmV</string>
+ <string>LtnSmW</string>
+ <string>LtnSmX</string>
+ <string>LtnSmY</string>
+ <string>LftCurlyBrac</string>
+ <string>VertLine</string>
+ <string>RtCurlyBrac</string>
+ <string>Tilde</string>
+ <string>LtnCapADiaer</string>
+ <string>LtnSmAAcute</string>
+ <string>LtnSmAGrave</string>
+ <string>LtnSmACircum</string>
+ <string>LtnSmADiaer</string>
+ <string>LtnSmATilde</string>
+ <string>LtnSmARingAbv</string>
+ <string>DottedCirc</string>
+ <string>Hyphen</string>
+ <string>NonBreakingHyphen</string>
+ <string>Hyphen_Soft</string>
+ <string>CombAcute</string>
+ <string>CombGrave</string>
+ <string>CombCircum</string>
+ <string>CombTilde</string>
+ <string>CombDiaer</string>
+ <string>CombRingAbv</string>
+ </array>
+ <key>com.schriftgestaltung.keyboardIncrement</key>
+ <integer>1</integer>
+ <key>com.schriftgestaltung.weight</key>
+ <string>Regular</string>
+ <key>com.schriftgestaltung.weightValue</key>
+ <integer>400</integer>
+ <key>com.schriftgestaltung.width</key>
+ <string>Regular</string>
+ <key>com.schriftgestaltung.widthValue</key>
+ <integer>100</integer>
+ <key>org.sil.lcg.toneLetters</key>
+ <dict>
+ <key>contourWidth</key>
+ <integer>480</integer>
+ <key>dotSize</key>
+ <integer>180</integer>
+ <key>dotSpacing</key>
+ <integer>200</integer>
+ <key>glyphDepth</key>
+ <integer>-25</integer>
+ <key>glyphHeight</key>
+ <integer>1600</integer>
+ <key>italicAngle</key>
+ <integer>0</integer>
+ <key>marginDotLeft</key>
+ <integer>120</integer>
+ <key>marginDotRight</key>
+ <integer>160</integer>
+ <key>marginFlatLeft</key>
+ <integer>120</integer>
+ <key>marginFlatRight</key>
+ <integer>160</integer>
+ <key>marginPointLeft</key>
+ <integer>100</integer>
+ <key>marginPointRight</key>
+ <integer>140</integer>
+ <key>strokeThickness</key>
+ <integer>120</integer>
+ </dict>
+ <key>public.glyphOrder</key>
+ <array>
+ <string>.notdef</string>
+ <string>.null</string>
+ <string>nonmarkingreturn</string>
+ <string>Space</string>
+ <string>ExclamationMrk</string>
+ <string>QuotMrk</string>
+ <string>NumSgn</string>
+ <string>DollarSgn</string>
+ <string>PercentSgn</string>
+ <string>Ampersand</string>
+ <string>Apos</string>
+ <string>LftParen</string>
+ <string>RtParen</string>
+ <string>Asterisk</string>
+ <string>PlusSgn</string>
+ <string>Comma</string>
+ <string>HyphenMinus</string>
+ <string>FullStop</string>
+ <string>Solidus</string>
+ <string>DigitZero</string>
+ <string>DigitOne</string>
+ <string>DigitTwo</string>
+ <string>DigitThree</string>
+ <string>DigitFour</string>
+ <string>DigitFive</string>
+ <string>DigitSix</string>
+ <string>DigitSeven</string>
+ <string>DigitEight</string>
+ <string>DigitNine</string>
+ <string>Colon</string>
+ <string>Semicolon</string>
+ <string>LTSgn</string>
+ <string>EqSgn</string>
+ <string>GTSgn</string>
+ <string>QstnMrk</string>
+ <string>AtSgn</string>
+ <string>LtnCapA</string>
+ <string>LtnCapA.alt</string>
+ <string>LtnCapB</string>
+ <string>LtnCapC</string>
+ <string>LtnCapD</string>
+ <string>LtnCapE</string>
+ <string>LtnCapF</string>
+ <string>LtnCapG</string>
+ <string>LtnCapH</string>
+ <string>LtnCapI</string>
+ <string>LtnCapJ</string>
+ <string>LtnCapK</string>
+ <string>LtnCapL</string>
+ <string>LtnCapM</string>
+ <string>LtnCapN</string>
+ <string>LtnCapO</string>
+ <string>LtnCapP</string>
+ <string>LtnCapQ</string>
+ <string>LtnCapR</string>
+ <string>LtnCapS</string>
+ <string>LtnCapT</string>
+ <string>LtnCapU</string>
+ <string>LtnCapV</string>
+ <string>LtnCapW</string>
+ <string>LtnCapX</string>
+ <string>LtnCapY</string>
+ <string>LftSqrBrac</string>
+ <string>ReverseSolidus</string>
+ <string>RtSqrBrac</string>
+ <string>CircumAccent</string>
+ <string>LowLine</string>
+ <string>GraveAccent</string>
+ <string>LtnSmA</string>
+ <string>LtnSmB</string>
+ <string>LtnSmC</string>
+ <string>LtnSmD</string>
+ <string>LtnSmE</string>
+ <string>LtnSmF</string>
+ <string>LtnSmG</string>
+ <string>LtnSmH</string>
+ <string>LtnSmI</string>
+ <string>LtnSmJ</string>
+ <string>LtnSmK</string>
+ <string>LtnSmL</string>
+ <string>LtnSmM</string>
+ <string>LtnSmN</string>
+ <string>LtnSmO</string>
+ <string>LtnSmP</string>
+ <string>LtnSmQ</string>
+ <string>LtnSmR</string>
+ <string>LtnSmS</string>
+ <string>LtnSmT</string>
+ <string>LtnSmU</string>
+ <string>LtnSmV</string>
+ <string>LtnSmW</string>
+ <string>LtnSmX</string>
+ <string>LtnSmY</string>
+ <string>LftCurlyBrac</string>
+ <string>VertLine</string>
+ <string>RtCurlyBrac</string>
+ <string>Tilde</string>
+ <string>LtnCapADiaer</string>
+ <string>LtnSmAAcute</string>
+ <string>LtnSmAGrave</string>
+ <string>LtnSmACircum</string>
+ <string>LtnSmADiaer</string>
+ <string>LtnSmATilde</string>
+ <string>LtnSmARingAbv</string>
+ <string>DottedCirc</string>
+ <string>Hyphen</string>
+ <string>NonBreakingHyphen</string>
+ <string>Hyphen_Soft</string>
+ <string>CombAcute</string>
+ <string>CombGrave</string>
+ <string>CombCircum</string>
+ <string>CombTilde</string>
+ <string>CombDiaer</string>
+ <string>CombRingAbv</string>
+ </array>
+ <key>public.postscriptNames</key>
+ <dict>
+ <key>Ampersand</key>
+ <string>ampersand</string>
+ <key>Apos</key>
+ <string>quotesingle</string>
+ <key>Asterisk</key>
+ <string>asterisk</string>
+ <key>AtSgn</key>
+ <string>at</string>
+ <key>CircumAccent</key>
+ <string>asciicircum</string>
+ <key>Colon</key>
+ <string>colon</string>
+ <key>CombAcute</key>
+ <string>acutecomb</string>
+ <key>CombCircum</key>
+ <string>uni0302</string>
+ <key>CombDiaer</key>
+ <string>uni0308</string>
+ <key>CombGrave</key>
+ <string>gravecomb</string>
+ <key>CombRingAbv</key>
+ <string>uni030A</string>
+ <key>CombTilde</key>
+ <string>tildecomb</string>
+ <key>Comma</key>
+ <string>comma</string>
+ <key>DigitEight</key>
+ <string>eight</string>
+ <key>DigitFive</key>
+ <string>five</string>
+ <key>DigitFour</key>
+ <string>four</string>
+ <key>DigitNine</key>
+ <string>nine</string>
+ <key>DigitOne</key>
+ <string>one</string>
+ <key>DigitSeven</key>
+ <string>seven</string>
+ <key>DigitSix</key>
+ <string>six</string>
+ <key>DigitThree</key>
+ <string>three</string>
+ <key>DigitTwo</key>
+ <string>two</string>
+ <key>DigitZero</key>
+ <string>zero</string>
+ <key>DollarSgn</key>
+ <string>dollar</string>
+ <key>DottedCirc</key>
+ <string>uni25CC</string>
+ <key>EqSgn</key>
+ <string>equal</string>
+ <key>ExclamationMrk</key>
+ <string>exclam</string>
+ <key>FullStop</key>
+ <string>period</string>
+ <key>GTSgn</key>
+ <string>greater</string>
+ <key>GraveAccent</key>
+ <string>grave</string>
+ <key>Hyphen</key>
+ <string>uni2010</string>
+ <key>HyphenMinus</key>
+ <string>hyphen</string>
+ <key>Hyphen_Soft</key>
+ <string>uni00AD</string>
+ <key>LTSgn</key>
+ <string>less</string>
+ <key>LftCurlyBrac</key>
+ <string>braceleft</string>
+ <key>LftParen</key>
+ <string>parenleft</string>
+ <key>LftSqrBrac</key>
+ <string>bracketleft</string>
+ <key>LowLine</key>
+ <string>underscore</string>
+ <key>LtnCapA</key>
+ <string>A</string>
+ <key>LtnCapA.alt</key>
+ <string>A</string>
+ <key>LtnCapADiaer</key>
+ <string>Adieresis</string>
+ <key>LtnCapB</key>
+ <string>B</string>
+ <key>LtnCapC</key>
+ <string>C</string>
+ <key>LtnCapD</key>
+ <string>D</string>
+ <key>LtnCapE</key>
+ <string>E</string>
+ <key>LtnCapF</key>
+ <string>F</string>
+ <key>LtnCapG</key>
+ <string>G</string>
+ <key>LtnCapH</key>
+ <string>H</string>
+ <key>LtnCapI</key>
+ <string>I</string>
+ <key>LtnCapJ</key>
+ <string>J</string>
+ <key>LtnCapK</key>
+ <string>K</string>
+ <key>LtnCapL</key>
+ <string>L</string>
+ <key>LtnCapM</key>
+ <string>M</string>
+ <key>LtnCapN</key>
+ <string>N</string>
+ <key>LtnCapO</key>
+ <string>O</string>
+ <key>LtnCapP</key>
+ <string>P</string>
+ <key>LtnCapQ</key>
+ <string>Q</string>
+ <key>LtnCapR</key>
+ <string>R</string>
+ <key>LtnCapS</key>
+ <string>S</string>
+ <key>LtnCapT</key>
+ <string>T</string>
+ <key>LtnCapU</key>
+ <string>U</string>
+ <key>LtnCapV</key>
+ <string>V</string>
+ <key>LtnCapW</key>
+ <string>W</string>
+ <key>LtnCapX</key>
+ <string>X</string>
+ <key>LtnCapY</key>
+ <string>Y</string>
+ <key>LtnSmA</key>
+ <string>a</string>
+ <key>LtnSmAAcute</key>
+ <string>aacute</string>
+ <key>LtnSmACircum</key>
+ <string>acircumflex</string>
+ <key>LtnSmADiaer</key>
+ <string>adieresis</string>
+ <key>LtnSmAGrave</key>
+ <string>agrave</string>
+ <key>LtnSmARingAbv</key>
+ <string>aring</string>
+ <key>LtnSmATilde</key>
+ <string>atilde</string>
+ <key>LtnSmB</key>
+ <string>b</string>
+ <key>LtnSmC</key>
+ <string>c</string>
+ <key>LtnSmD</key>
+ <string>d</string>
+ <key>LtnSmE</key>
+ <string>e</string>
+ <key>LtnSmF</key>
+ <string>f</string>
+ <key>LtnSmG</key>
+ <string>g</string>
+ <key>LtnSmH</key>
+ <string>h</string>
+ <key>LtnSmI</key>
+ <string>i</string>
+ <key>LtnSmJ</key>
+ <string>j</string>
+ <key>LtnSmK</key>
+ <string>k</string>
+ <key>LtnSmL</key>
+ <string>l</string>
+ <key>LtnSmM</key>
+ <string>m</string>
+ <key>LtnSmN</key>
+ <string>n</string>
+ <key>LtnSmO</key>
+ <string>o</string>
+ <key>LtnSmP</key>
+ <string>p</string>
+ <key>LtnSmQ</key>
+ <string>q</string>
+ <key>LtnSmR</key>
+ <string>r</string>
+ <key>LtnSmS</key>
+ <string>s</string>
+ <key>LtnSmT</key>
+ <string>t</string>
+ <key>LtnSmU</key>
+ <string>u</string>
+ <key>LtnSmV</key>
+ <string>v</string>
+ <key>LtnSmW</key>
+ <string>w</string>
+ <key>LtnSmX</key>
+ <string>x</string>
+ <key>LtnSmY</key>
+ <string>y</string>
+ <key>NonBreakingHyphen</key>
+ <string>uni2011</string>
+ <key>NumSgn</key>
+ <string>numbersign</string>
+ <key>PercentSgn</key>
+ <string>percent</string>
+ <key>PlusSgn</key>
+ <string>plus</string>
+ <key>QstnMrk</key>
+ <string>question</string>
+ <key>QuotMrk</key>
+ <string>quotedbl</string>
+ <key>ReverseSolidus</key>
+ <string>backslash</string>
+ <key>RtCurlyBrac</key>
+ <string>braceright</string>
+ <key>RtParen</key>
+ <string>parenright</string>
+ <key>RtSqrBrac</key>
+ <string>bracketright</string>
+ <key>Semicolon</key>
+ <string>semicolon</string>
+ <key>Solidus</key>
+ <string>slash</string>
+ <key>Space</key>
+ <string>space</string>
+ <key>Tilde</key>
+ <string>asciitilde</string>
+ <key>VertLine</key>
+ <string>bar</string>
+ </dict>
+</dict>
+</plist>
diff --git a/tests/input/font-psf-test/source/PsfTest-Regular.ufo/metainfo.plist b/tests/input/font-psf-test/source/PsfTest-Regular.ufo/metainfo.plist
new file mode 100644
index 0000000..aa10c5c
--- /dev/null
+++ b/tests/input/font-psf-test/source/PsfTest-Regular.ufo/metainfo.plist
@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+ <key>creator</key>
+ <string>org.sil.scripts.pysilfont</string>
+ <key>formatVersion</key>
+ <integer>3</integer>
+</dict>
+</plist>
diff --git a/tests/input/font-psf-test/source/PsfTestItalic.designspace b/tests/input/font-psf-test/source/PsfTestItalic.designspace
new file mode 100644
index 0000000..701cfea
--- /dev/null
+++ b/tests/input/font-psf-test/source/PsfTestItalic.designspace
@@ -0,0 +1,58 @@
+<?xml version='1.0' encoding='utf-8'?>
+<designspace format="3">
+ <axes>
+ <axis default="400.0" maximum="700.0" minimum="400.0" name="weight" tag="wght">
+ <map input="400.0" output="400.0" />
+ <map input="700.0" output="700.0" />
+ <labelname xml:lang="en">Weight</labelname>
+ </axis>
+ <axis default="100.0" maximum="100.0" minimum="100.0" name="width" tag="wdth">
+ <map input="100.0" output="100.0" />
+ <labelname xml:lang="en">Width</labelname>
+ </axis>
+ <axis default="0.0" maximum="0.0" minimum="0.0" name="custom" tag="XXXX">
+ <map input="0.0" output="0.0" />
+ <labelname xml:lang="en">Custom</labelname>
+ </axis>
+ </axes>
+ <sources>
+ <source familyname="Psf Test" filename="PsfTest-Italic.ufo" name="Psf Test Italic" stylename="Italic">
+ <lib copy="1" />
+ <groups copy="1" />
+ <features copy="1" />
+ <info copy="1" />
+ <location>
+ <dimension name="weight" xvalue="400.000000" />
+ <dimension name="width" xvalue="100.000000" />
+ <dimension name="custom" xvalue="0.000000" />
+ </location>
+ </source>
+ <source familyname="Psf Test" filename="PsfTest-BoldItalic.ufo" name="Psf Test Bold Italic" stylename="Bold Italic">
+ <location>
+ <dimension name="weight" xvalue="700.000000" />
+ <dimension name="width" xvalue="100.000000" />
+ <dimension name="custom" xvalue="0.000000" />
+ </location>
+ </source>
+ </sources>
+ <instances>
+ <instance familyname="Psf Test" filename="PsfTest-Italic.ufo" name="Psf Test Italic" stylemapfamilyname="Psf Test" stylemapstylename="italic" stylename="Italic">
+ <location>
+ <dimension name="weight" xvalue="400.000000" />
+ <dimension name="width" xvalue="100.000000" />
+ <dimension name="custom" xvalue="0.000000" />
+ </location>
+ <info />
+ <kerning />
+ </instance>
+ <instance familyname="Psf Test" filename="PsfTest-BoldItalic.ufo" name="Psf Test Bold Italic" stylemapfamilyname="Psf Test" stylemapstylename="bold italic" stylename="Bold Italic">
+ <location>
+ <dimension name="weight" xvalue="700.000000" />
+ <dimension name="width" xvalue="100.000000" />
+ <dimension name="custom" xvalue="0.000000" />
+ </location>
+ <info />
+ <kerning />
+ </instance>
+ </instances>
+</designspace>
diff --git a/tests/input/font-psf-test/source/PsfTestItalic.glyphs b/tests/input/font-psf-test/source/PsfTestItalic.glyphs
new file mode 100644
index 0000000..d3c631c
--- /dev/null
+++ b/tests/input/font-psf-test/source/PsfTestItalic.glyphs
@@ -0,0 +1,12469 @@
+{
+.appVersion = "1165";
+copyright = "Copyright (c) 2004-2021 SIL International";
+customParameters = (
+{
+name = glyphOrder;
+value = (
+.notdef,
+.null,
+nonmarkingreturn,
+Space,
+ExclamationMrk,
+QuotMrk,
+NumSgn,
+DollarSgn,
+PercentSgn,
+Ampersand,
+Apos,
+LftParen,
+RtParen,
+Asterisk,
+PlusSgn,
+Comma,
+HyphenMinus,
+FullStop,
+Solidus,
+DigitZero,
+DigitOne,
+DigitTwo,
+DigitThree,
+DigitFour,
+DigitFive,
+DigitSix,
+DigitSeven,
+DigitEight,
+DigitNine,
+Colon,
+Semicolon,
+LTSgn,
+EqSgn,
+GTSgn,
+QstnMrk,
+AtSgn,
+LtnCapA,
+LtnCapA.alt,
+LtnCapB,
+LtnCapC,
+LtnCapD,
+LtnCapE,
+LtnCapF,
+LtnCapG,
+LtnCapH,
+LtnCapI,
+LtnCapJ,
+LtnCapK,
+LtnCapL,
+LtnCapM,
+LtnCapN,
+LtnCapO,
+LtnCapP,
+LtnCapQ,
+LtnCapR,
+LtnCapS,
+LtnCapT,
+LtnCapU,
+LtnCapV,
+LtnCapW,
+LtnCapX,
+LtnCapY,
+LftSqrBrac,
+ReverseSolidus,
+RtSqrBrac,
+CircumAccent,
+LowLine,
+GraveAccent,
+LtnSmA,
+LtnSmB,
+LtnSmC,
+LtnSmD,
+LtnSmE,
+LtnSmF,
+LtnSmG,
+LtnSmH,
+LtnSmI,
+LtnSmJ,
+LtnSmK,
+LtnSmL,
+LtnSmM,
+LtnSmN,
+LtnSmO,
+LtnSmP,
+LtnSmQ,
+LtnSmR,
+LtnSmS,
+LtnSmT,
+LtnSmU,
+LtnSmV,
+LtnSmW,
+LtnSmX,
+LtnSmY,
+LftCurlyBrac,
+VertLine,
+RtCurlyBrac,
+Tilde,
+LtnCapADiaer,
+LtnSmAAcute,
+LtnSmAGrave,
+LtnSmACircum,
+LtnSmADiaer,
+LtnSmATilde,
+LtnSmARingAbv,
+DottedCirc,
+Hyphen,
+NonBreakingHyphen,
+Hyphen_Soft,
+CombAcute,
+CombGrave,
+CombCircum,
+CombTilde,
+CombDiaer,
+CombRingAbv
+);
+},
+{
+name = "Disable Last Change";
+value = 1;
+},
+{
+name = description;
+value = "Copyright (c) 2004-2021 SIL International";
+},
+{
+name = openTypeNameLicense;
+value = "Copyright (c) 2004-2021 SIL International (http://www.sil.org/) with Reserved Font Names \"Andika\" and \"SIL\".\012\012This Font Software is licensed under the SIL Open Font License, Version 1.1. This license is copied below, and is also available with a FAQ at: http://scripts.sil.org/OFL\012\012\012-----------------------------------------------------------\012SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007\012-----------------------------------------------------------\012\012PREAMBLE\012The goals of the Open Font License (OFL) are to stimulate worldwide development of collaborative font projects, to support the font creation efforts of academic and linguistic communities, and to provide a free and open framework in which fonts may be shared and improved in partnership with others.\012\012The OFL allows the licensed fonts to be used, studied, modified and redistributed freely as long as they are not sold by themselves. The fonts, including any derivative works, can be bundled, embedded, redistributed and/or sold with any software provided that any reserved names are not used by derivative works. The fonts and derivatives, however, cannot be released under any other type of license. The requirement for fonts to remain under this license does not apply to any document created using the fonts or their derivatives.\012\012DEFINITIONS\012\"Font Software\" refers to the set of files released by the Copyright Holder(s) under this license and clearly marked as such. This may include source files, build scripts and documentation.\012\012\"Reserved Font Name\" refers to any names specified as such after the copyright statement(s).\012\012\"Original Version\" refers to the collection of Font Software components as distributed by the Copyright Holder(s).\012\012\"Modified Version\" refers to any derivative made by adding to, deleting, or substituting -- in part or in whole -- any of the components of the Original Version, by changing formats or by porting the Font Software to a new environment.\012\012\"Author\" refers to any designer, engineer, programmer, technical writer or other person who contributed to the Font Software.\012\012PERMISSION & CONDITIONS\012Permission is hereby granted, free of charge, to any person obtaining a copy of the Font Software, to use, study, copy, merge, embed, modify, redistribute, and sell modified and unmodified copies of the Font Software, subject to the following conditions:\012\0121) Neither the Font Software nor any of its individual components, in Original or Modified Versions, may be sold by itself.\012\0122) Original or Modified Versions of the Font Software may be bundled, redistributed and/or sold with any software, provided that each copy contains the above copyright notice and this license. These can be included either as stand-alone text files, human-readable headers or in the appropriate machine-readable metadata fields within text or binary files as long as those fields can be easily viewed by the user.\012\0123) No Modified Version of the Font Software may use the Reserved Font Name(s) unless explicit written permission is granted by the corresponding Copyright Holder. This restriction only applies to the primary font name as presented to the users.\012\0124) The name(s) of the Copyright Holder(s) or the Author(s) of the Font Software shall not be used to promote, endorse or advertise any Modified Version, except to acknowledge the contribution(s) of the Copyright Holder(s) and the Author(s) or with their explicit written permission.\012\0125) The Font Software, modified or unmodified, in part or in whole, must be distributed entirely under this license, and must not be distributed under any other license. The requirement for fonts to remain under this license does not apply to any document created using the Font Software.\012\012TERMINATION\012This license becomes null and void if any of the above conditions are not met.\012\012DISCLAIMER\012THE FONT SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM OTHER DEALINGS IN THE FONT SOFTWARE.";
+},
+{
+name = openTypeNameLicenseURL;
+value = "http://scripts.sil.org/OFL";
+},
+{
+name = openTypeNameUniqueID;
+value = "SIL International: Psf Test Italic: 2021";
+},
+{
+name = openTypeNameVersion;
+value = "Version 5.550";
+},
+{
+name = codePageRanges;
+value = (
+1252,
+1250,
+1251,
+1254,
+1257,
+1258
+);
+},
+{
+name = openTypeOS2FamilyClass;
+value = (
+0,
+0
+);
+},
+{
+name = openTypeOS2Panose;
+value = (
+2,
+0,
+0,
+0,
+0,
+0,
+0,
+0,
+0,
+0
+);
+},
+{
+name = openTypeOS2StrikeoutPosition;
+value = 700;
+},
+{
+name = openTypeOS2StrikeoutSize;
+value = 100;
+},
+{
+name = openTypeOS2SubscriptXOffset;
+value = 0;
+},
+{
+name = openTypeOS2SubscriptXSize;
+value = 1433;
+},
+{
+name = openTypeOS2SubscriptYOffset;
+value = 286;
+},
+{
+name = openTypeOS2SubscriptYSize;
+value = 1331;
+},
+{
+name = openTypeOS2SuperscriptXOffset;
+value = 0;
+},
+{
+name = openTypeOS2SuperscriptXSize;
+value = 1433;
+},
+{
+name = openTypeOS2SuperscriptYOffset;
+value = 976;
+},
+{
+name = openTypeOS2SuperscriptYSize;
+value = 1331;
+},
+{
+name = fsType;
+value = (
+);
+},
+{
+name = unicodeRanges;
+value = (
+0,
+1,
+6,
+7,
+31,
+33,
+35,
+36,
+37,
+38,
+39,
+40,
+45,
+46,
+47,
+57,
+60,
+62,
+64,
+67,
+69,
+89
+);
+},
+{
+name = vendorID;
+value = SIL;
+},
+{
+name = trademark;
+value = "Andika is a trademark of SIL International.";
+}
+);
+date = "2021-01-01 11:00:00 +0000";
+designer = "Victor Gaultney, Annie Olsen, Julie Remington, Don Collingsworth, Eric Hays, Becca Hirsbrunner";
+designerURL = "http://scripts.sil.org/";
+disablesAutomaticAlignment = 1;
+disablesNiceNames = 1;
+familyName = "Psf Test";
+fontMaster = (
+{
+alignmentZones = (
+"{1600, 20}",
+"{1455, 30}",
+"{1020, 20}",
+"{0, -25}",
+"{-490, 0}"
+);
+ascender = 2100;
+capHeight = 1485;
+custom = Italic;
+customParameters = (
+{
+name = typoAscender;
+value = 2100;
+},
+{
+name = typoDescender;
+value = -550;
+},
+{
+name = typoLineGap;
+value = 0;
+},
+{
+name = hheaAscender;
+value = 2100;
+},
+{
+name = hheaDescender;
+value = -550;
+},
+{
+name = hheaLineGap;
+value = 0;
+},
+{
+name = winAscent;
+value = 2100;
+},
+{
+name = winDescent;
+value = 550;
+},
+{
+name = underlineThickness;
+value = 80;
+},
+{
+name = underlinePosition;
+value = -110;
+}
+);
+descender = -550;
+horizontalStems = (
+140,
+145,
+150,
+155,
+160,
+165,
+170,
+175,
+185,
+270
+);
+id = master01;
+italicAngle = 14;
+verticalStems = (
+165,
+180,
+185,
+190,
+195,
+200,
+205,
+270
+);
+weightValue = 400;
+xHeight = 1040;
+},
+{
+alignmentZones = (
+"{1600, 20}",
+"{1455, 30}",
+"{1020, 20}",
+"{0, -25}",
+"{-490, 0}"
+);
+ascender = 2100;
+capHeight = 1485;
+custom = Italic;
+customParameters = (
+{
+name = typoAscender;
+value = 2100;
+},
+{
+name = typoDescender;
+value = -550;
+},
+{
+name = typoLineGap;
+value = 0;
+},
+{
+name = hheaAscender;
+value = 2100;
+},
+{
+name = hheaDescender;
+value = -550;
+},
+{
+name = hheaLineGap;
+value = 0;
+},
+{
+name = winAscent;
+value = 2100;
+},
+{
+name = winDescent;
+value = 550;
+},
+{
+name = underlineThickness;
+value = 80;
+},
+{
+name = underlinePosition;
+value = -110;
+}
+);
+descender = -550;
+horizontalStems = (
+140,
+145,
+150,
+155,
+160,
+165,
+170,
+175,
+185,
+270
+);
+id = master02;
+italicAngle = 14;
+verticalStems = (
+165,
+180,
+185,
+190,
+195,
+200,
+205,
+270
+);
+weight = Bold;
+weightValue = 700;
+xHeight = 1040;
+}
+);
+glyphs = (
+{
+glyphname = .notdef;
+layers = (
+{
+layerId = master01;
+paths = (
+{
+closed = 1;
+nodes = (
+"1300 0 LINE",
+"1300 1800 LINE",
+"100 1800 LINE",
+"100 0 LINE"
+);
+},
+{
+closed = 1;
+nodes = (
+"1250 1750 LINE",
+"1250 50 LINE",
+"150 50 LINE",
+"150 1750 LINE"
+);
+}
+);
+width = 1400;
+},
+{
+layerId = master02;
+paths = (
+{
+closed = 1;
+nodes = (
+"1300 0 LINE",
+"1300 1800 LINE",
+"100 1800 LINE",
+"100 0 LINE"
+);
+},
+{
+closed = 1;
+nodes = (
+"1250 1750 LINE",
+"1250 50 LINE",
+"150 50 LINE",
+"150 1750 LINE"
+);
+}
+);
+width = 1400;
+}
+);
+},
+{
+glyphname = .null;
+layers = (
+{
+layerId = master01;
+width = 0;
+},
+{
+layerId = master02;
+width = 0;
+}
+);
+},
+{
+glyphname = nonmarkingreturn;
+layers = (
+{
+layerId = master01;
+width = 1004;
+},
+{
+layerId = master02;
+width = 1004;
+}
+);
+},
+{
+glyphname = Space;
+layers = (
+{
+layerId = master01;
+width = 530;
+},
+{
+layerId = master02;
+width = 530;
+}
+);
+unicode = 0020;
+},
+{
+glyphname = ExclamationMrk;
+layers = (
+{
+layerId = master01;
+paths = (
+{
+closed = 1;
+nodes = (
+"574 715 OFFCURVE",
+"653 1054 OFFCURVE",
+"799 1480 CURVE",
+"544 1480 LINE",
+"475 1054 OFFCURVE",
+"386 715 OFFCURVE",
+"322 431 CURVE",
+"497 431 LINE"
+);
+},
+{
+closed = 1;
+nodes = (
+"188 28 OFFCURVE",
+"238 -25 OFFCURVE",
+"303 -25 CURVE SMOOTH",
+"387 -25 OFFCURVE",
+"464 45 OFFCURVE",
+"464 125 CURVE SMOOTH",
+"464 186 OFFCURVE",
+"414 240 OFFCURVE",
+"349 240 CURVE SMOOTH",
+"265 240 OFFCURVE",
+"188 170 OFFCURVE",
+"188 90 CURVE SMOOTH"
+);
+}
+);
+width = 744;
+},
+{
+layerId = master02;
+paths = (
+{
+closed = 1;
+nodes = (
+"670 782 OFFCURVE",
+"736 1065 OFFCURVE",
+"882 1495 CURVE",
+"547 1495 LINE",
+"478 1065 OFFCURVE",
+"402 782 OFFCURVE",
+"338 495 CURVE",
+"593 495 LINE"
+);
+},
+{
+closed = 1;
+nodes = (
+"201 35 OFFCURVE",
+"262 -25 OFFCURVE",
+"348 -25 CURVE SMOOTH",
+"466 -25 OFFCURVE",
+"561 71 OFFCURVE",
+"561 181 CURVE SMOOTH",
+"561 261 OFFCURVE",
+"502 322 OFFCURVE",
+"415 322 CURVE SMOOTH",
+"298 322 OFFCURVE",
+"201 226 OFFCURVE",
+"201 116 CURVE SMOOTH"
+);
+}
+);
+width = 760;
+}
+);
+unicode = 0021;
+},
+{
+glyphname = QuotMrk;
+layers = (
+{
+layerId = master01;
+paths = (
+{
+closed = 1;
+nodes = (
+"639 1162 OFFCURVE",
+"683 1312 OFFCURVE",
+"772 1553 CURVE",
+"567 1553 LINE",
+"538 1312 OFFCURVE",
+"505 1162 OFFCURVE",
+"475 1024 CURVE",
+"600 1024 LINE"
+);
+},
+{
+closed = 1;
+nodes = (
+"979 1162 OFFCURVE",
+"1023 1312 OFFCURVE",
+"1112 1553 CURVE",
+"907 1553 LINE",
+"878 1312 OFFCURVE",
+"845 1162 OFFCURVE",
+"815 1024 CURVE",
+"940 1024 LINE"
+);
+}
+);
+width = 1005;
+},
+{
+layerId = master02;
+paths = (
+{
+closed = 1;
+nodes = (
+"687 1174 OFFCURVE",
+"726 1326 OFFCURVE",
+"816 1569 CURVE",
+"571 1569 LINE",
+"541 1326 OFFCURVE",
+"503 1174 OFFCURVE",
+"473 1035 CURVE",
+"648 1035 LINE"
+);
+},
+{
+closed = 1;
+nodes = (
+"1047 1174 OFFCURVE",
+"1086 1326 OFFCURVE",
+"1176 1569 CURVE",
+"931 1569 LINE",
+"901 1326 OFFCURVE",
+"863 1174 OFFCURVE",
+"833 1035 CURVE",
+"1008 1035 LINE"
+);
+}
+);
+width = 1065;
+}
+);
+unicode = 0022;
+},
+{
+glyphname = NumSgn;
+layers = (
+{
+layerId = master01;
+paths = (
+{
+closed = 1;
+nodes = (
+"91 98 LINE",
+"261 98 LINE",
+"909 1333 LINE",
+"739 1333 LINE"
+);
+},
+{
+closed = 1;
+nodes = (
+"1171 465 LINE",
+"1208 612 LINE",
+"117 612 LINE",
+"80 465 LINE"
+);
+},
+{
+closed = 1;
+nodes = (
+"1325 843 LINE",
+"1361 990 LINE",
+"270 990 LINE",
+"234 843 LINE"
+);
+},
+{
+closed = 1;
+nodes = (
+"516 98 LINE",
+"686 98 LINE",
+"1334 1333 LINE",
+"1164 1333 LINE"
+);
+}
+);
+width = 1180;
+},
+{
+layerId = master02;
+paths = (
+{
+closed = 1;
+nodes = (
+"16 99 LINE",
+"256 99 LINE",
+"907 1346 LINE",
+"667 1346 LINE"
+);
+},
+{
+closed = 1;
+nodes = (
+"1145 421 LINE",
+"1197 629 LINE",
+"106 629 LINE",
+"54 421 LINE"
+);
+},
+{
+closed = 1;
+nodes = (
+"1309 841 LINE",
+"1361 1049 LINE",
+"270 1049 LINE",
+"218 841 LINE"
+);
+},
+{
+closed = 1;
+nodes = (
+"491 99 LINE",
+"731 99 LINE",
+"1382 1346 LINE",
+"1142 1346 LINE"
+);
+}
+);
+width = 1180;
+}
+);
+unicode = 0023;
+},
+{
+glyphname = DollarSgn;
+layers = (
+{
+layerId = master01;
+paths = (
+{
+closed = 1;
+nodes = (
+"1119 1337 OFFCURVE",
+"1023 1361 OFFCURVE",
+"882 1361 CURVE SMOOTH",
+"513 1361 OFFCURVE",
+"354 1182 OFFCURVE",
+"354 992 CURVE SMOOTH",
+"354 837 OFFCURVE",
+"446 771 OFFCURVE",
+"639 650 CURVE SMOOTH",
+"844 521 OFFCURVE",
+"919 439 OFFCURVE",
+"919 357 CURVE SMOOTH",
+"919 244 OFFCURVE",
+"826 158 OFFCURVE",
+"635 158 CURVE SMOOTH",
+"469 158 OFFCURVE",
+"314 266 OFFCURVE",
+"251 347 CURVE",
+"163 162 LINE",
+"304 58 OFFCURVE",
+"453 0 OFFCURVE",
+"606 0 CURVE SMOOTH",
+"872 0 OFFCURVE",
+"1102 119 OFFCURVE",
+"1102 381 CURVE SMOOTH",
+"1102 528 OFFCURVE",
+"981 657 OFFCURVE",
+"801 771 CURVE SMOOTH",
+"610 892 OFFCURVE",
+"535 943 OFFCURVE",
+"535 1024 CURVE SMOOTH",
+"535 1116 OFFCURVE",
+"657 1203 OFFCURVE",
+"832 1203 CURVE SMOOTH",
+"950 1203 OFFCURVE",
+"1031 1176 OFFCURVE",
+"1144 1104 CURVE",
+"1225 1280 LINE"
+);
+},
+{
+closed = 1;
+nodes = (
+"434 -216 LINE",
+"574 -216 LINE",
+"1018 1568 LINE",
+"878 1568 LINE"
+);
+}
+);
+width = 1180;
+},
+{
+layerId = master02;
+paths = (
+{
+closed = 1;
+nodes = (
+"679 780 LINE",
+"634 719 LINE",
+"400 -218 LINE",
+"576 -218 LINE",
+"795 661 LINE",
+"842 727 LINE",
+"1055 1584 LINE",
+"879 1584 LINE"
+);
+},
+{
+closed = 1;
+nodes = (
+"1145 1355 OFFCURVE",
+"1026 1375 OFFCURVE",
+"885 1375 CURVE SMOOTH",
+"537 1375 OFFCURVE",
+"345 1216 OFFCURVE",
+"345 984 CURVE SMOOTH",
+"345 841 OFFCURVE",
+"441 726 OFFCURVE",
+"638 622 CURVE SMOOTH",
+"832 519 OFFCURVE",
+"881 451 OFFCURVE",
+"881 381 CURVE SMOOTH",
+"881 274 OFFCURVE",
+"817 209 OFFCURVE",
+"613 209 CURVE SMOOTH",
+"462 209 OFFCURVE",
+"336 298 OFFCURVE",
+"259 389 CURVE",
+"133 143 LINE",
+"243 56 OFFCURVE",
+"378 0 OFFCURVE",
+"566 0 CURVE SMOOTH",
+"879 0 OFFCURVE",
+"1120 142 OFFCURVE",
+"1120 396 CURVE SMOOTH",
+"1120 562 OFFCURVE",
+"1028 682 OFFCURVE",
+"817 803 CURVE SMOOTH",
+"635 908 OFFCURVE",
+"592 958 OFFCURVE",
+"592 1016 CURVE SMOOTH",
+"592 1113 OFFCURVE",
+"649 1176 OFFCURVE",
+"826 1176 CURVE SMOOTH",
+"954 1176 OFFCURVE",
+"1048 1135 OFFCURVE",
+"1134 1066 CURVE",
+"1250 1303 LINE"
+);
+}
+);
+width = 1180;
+}
+);
+unicode = 0024;
+},
+{
+glyphname = PercentSgn;
+layers = (
+{
+layerId = master01;
+paths = (
+{
+closed = 1;
+nodes = (
+"1255 168 OFFCURVE",
+"1204 113 OFFCURVE",
+"1118 113 CURVE SMOOTH",
+"1056 113 OFFCURVE",
+"1021 148 OFFCURVE",
+"1021 235 CURVE SMOOTH",
+"1021 274 OFFCURVE",
+"1028 322 OFFCURVE",
+"1043 383 CURVE SMOOTH",
+"1088 564 OFFCURVE",
+"1136 617 OFFCURVE",
+"1223 617 CURVE SMOOTH",
+"1286 617 OFFCURVE",
+"1322 582 OFFCURVE",
+"1322 496 CURVE SMOOTH",
+"1322 458 OFFCURVE",
+"1315 409 OFFCURVE",
+"1300 349 CURVE SMOOTH"
+);
+},
+{
+closed = 1;
+nodes = (
+"1483 419 OFFCURVE",
+"1489 470 OFFCURVE",
+"1489 515 CURVE SMOOTH",
+"1489 677 OFFCURVE",
+"1400 755 OFFCURVE",
+"1263 755 CURVE SMOOTH",
+"1089 755 OFFCURVE",
+"945 647 OFFCURVE",
+"876 371 CURVE SMOOTH",
+"861 310 OFFCURVE",
+"854 256 OFFCURVE",
+"854 210 CURVE SMOOTH",
+"854 47 OFFCURVE",
+"943 -25 OFFCURVE",
+"1079 -25 CURVE SMOOTH",
+"1254 -25 OFFCURVE",
+"1396 72 OFFCURVE",
+"1468 361 CURVE SMOOTH"
+);
+},
+{
+closed = 1;
+nodes = (
+"219 -25 LINE",
+"397 -25 LINE",
+"1545 1450 LINE",
+"1369 1450 LINE"
+);
+},
+{
+closed = 1;
+nodes = (
+"672 864 OFFCURVE",
+"621 809 OFFCURVE",
+"535 809 CURVE SMOOTH",
+"474 809 OFFCURVE",
+"439 844 OFFCURVE",
+"439 930 CURVE SMOOTH",
+"439 969 OFFCURVE",
+"446 1018 OFFCURVE",
+"461 1079 CURVE SMOOTH",
+"506 1260 OFFCURVE",
+"554 1313 OFFCURVE",
+"641 1313 CURVE SMOOTH",
+"704 1313 OFFCURVE",
+"739 1278 OFFCURVE",
+"739 1192 CURVE SMOOTH",
+"739 1153 OFFCURVE",
+"732 1105 OFFCURVE",
+"717 1044 CURVE SMOOTH"
+);
+},
+{
+closed = 1;
+nodes = (
+"900 1114 OFFCURVE",
+"907 1166 OFFCURVE",
+"907 1210 CURVE SMOOTH",
+"907 1373 OFFCURVE",
+"817 1450 OFFCURVE",
+"680 1450 CURVE SMOOTH",
+"506 1450 OFFCURVE",
+"362 1343 OFFCURVE",
+"293 1066 CURVE SMOOTH",
+"278 1005 OFFCURVE",
+"271 952 OFFCURVE",
+"271 906 CURVE SMOOTH",
+"271 743 OFFCURVE",
+"360 671 OFFCURVE",
+"497 671 CURVE SMOOTH",
+"672 671 OFFCURVE",
+"813 768 OFFCURVE",
+"886 1057 CURVE SMOOTH"
+);
+}
+);
+width = 1506;
+},
+{
+layerId = master02;
+paths = (
+{
+closed = 1;
+nodes = (
+"221 -25 LINE",
+"435 -25 LINE",
+"1587 1465 LINE",
+"1375 1465 LINE"
+);
+},
+{
+closed = 1;
+nodes = (
+"669 861 OFFCURVE",
+"611 807 OFFCURVE",
+"535 807 CURVE SMOOTH",
+"486 807 OFFCURVE",
+"461 843 OFFCURVE",
+"461 917 CURVE SMOOTH",
+"461 963 OFFCURVE",
+"471 1023 OFFCURVE",
+"490 1099 CURVE SMOOTH",
+"535 1281 OFFCURVE",
+"580 1336 OFFCURVE",
+"657 1336 CURVE SMOOTH",
+"710 1336 OFFCURVE",
+"739 1296 OFFCURVE",
+"739 1212 CURVE SMOOTH",
+"739 1168 OFFCURVE",
+"731 1111 OFFCURVE",
+"714 1043 CURVE SMOOTH"
+);
+},
+{
+closed = 1;
+nodes = (
+"939 1107 OFFCURVE",
+"946 1156 OFFCURVE",
+"946 1199 CURVE SMOOTH",
+"946 1374 OFFCURVE",
+"842 1465 OFFCURVE",
+"694 1465 CURVE SMOOTH",
+"510 1465 OFFCURVE",
+"346 1369 OFFCURVE",
+"277 1090 CURVE SMOOTH",
+"262 1031 OFFCURVE",
+"255 979 OFFCURVE",
+"255 933 CURVE SMOOTH",
+"255 761 OFFCURVE",
+"353 678 OFFCURVE",
+"499 678 CURVE SMOOTH",
+"684 678 OFFCURVE",
+"853 762 OFFCURVE",
+"926 1054 CURVE SMOOTH"
+);
+},
+{
+closed = 1;
+nodes = (
+"1268 155 OFFCURVE",
+"1220 104 OFFCURVE",
+"1144 104 CURVE SMOOTH",
+"1093 104 OFFCURVE",
+"1065 144 OFFCURVE",
+"1065 227 CURVE SMOOTH",
+"1065 272 OFFCURVE",
+"1073 329 OFFCURVE",
+"1090 398 CURVE SMOOTH",
+"1136 580 OFFCURVE",
+"1190 634 OFFCURVE",
+"1267 634 CURVE SMOOTH",
+"1317 634 OFFCURVE",
+"1342 596 OFFCURVE",
+"1342 520 CURVE SMOOTH",
+"1342 473 OFFCURVE",
+"1333 412 OFFCURVE",
+"1314 337 CURVE SMOOTH"
+);
+},
+{
+closed = 1;
+nodes = (
+"1540 406 OFFCURVE",
+"1546 456 OFFCURVE",
+"1546 501 CURVE SMOOTH",
+"1546 673 OFFCURVE",
+"1450 762 OFFCURVE",
+"1303 762 CURVE SMOOTH",
+"1119 762 OFFCURVE",
+"946 665 OFFCURVE",
+"876 386 CURVE SMOOTH",
+"862 331 OFFCURVE",
+"856 281 OFFCURVE",
+"856 237 CURVE SMOOTH",
+"856 60 OFFCURVE",
+"960 -25 OFFCURVE",
+"1108 -25 CURVE SMOOTH",
+"1293 -25 OFFCURVE",
+"1453 58 OFFCURVE",
+"1526 350 CURVE SMOOTH"
+);
+}
+);
+width = 1545;
+}
+);
+unicode = 0025;
+},
+{
+glyphname = Ampersand;
+layers = (
+{
+layerId = master01;
+paths = (
+{
+closed = 1;
+nodes = (
+"949 395 OFFCURVE",
+"616 147 OFFCURVE",
+"441 147 CURVE SMOOTH",
+"318 147 OFFCURVE",
+"256 224 OFFCURVE",
+"256 314 CURVE SMOOTH",
+"256 453 OFFCURVE",
+"369 575 OFFCURVE",
+"590 725 CURVE SMOOTH",
+"836 892 OFFCURVE",
+"1022 1067 OFFCURVE",
+"1022 1223 CURVE SMOOTH",
+"1022 1363 OFFCURVE",
+"894 1455 OFFCURVE",
+"762 1455 CURVE SMOOTH",
+"504 1455 OFFCURVE",
+"378 1328 OFFCURVE",
+"378 1114 CURVE SMOOTH",
+"378 953 OFFCURVE",
+"514 771 OFFCURVE",
+"614 559 CURVE SMOOTH",
+"783 198 OFFCURVE",
+"906 -25 OFFCURVE",
+"958 -25 CURVE SMOOTH",
+"993 -25 OFFCURVE",
+"1087 37 OFFCURVE",
+"1132 69 CURVE",
+"1046 108 OFFCURVE",
+"926 291 OFFCURVE",
+"756 666 CURVE SMOOTH",
+"665 866 OFFCURVE",
+"544 1029 OFFCURVE",
+"544 1149 CURVE SMOOTH",
+"544 1252 OFFCURVE",
+"632 1323 OFFCURVE",
+"724 1323 CURVE SMOOTH",
+"794 1323 OFFCURVE",
+"858 1266 OFFCURVE",
+"858 1193 CURVE SMOOTH",
+"858 1107 OFFCURVE",
+"743 1004 OFFCURVE",
+"492 826 CURVE SMOOTH",
+"182 606 OFFCURVE",
+"73 439 OFFCURVE",
+"73 288 CURVE SMOOTH",
+"73 113 OFFCURVE",
+"195 -25 OFFCURVE",
+"383 -25 CURVE SMOOTH",
+"656 -25 OFFCURVE",
+"1009 269 OFFCURVE",
+"1126 426 CURVE",
+"1054 559 LINE"
+);
+}
+);
+width = 1202;
+},
+{
+layerId = master02;
+paths = (
+{
+closed = 1;
+nodes = (
+"1040 429 OFFCURVE",
+"712 198 OFFCURVE",
+"537 198 CURVE SMOOTH",
+"437 198 OFFCURVE",
+"363 257 OFFCURVE",
+"363 345 CURVE SMOOTH",
+"363 490 OFFCURVE",
+"474 535 OFFCURVE",
+"695 693 CURVE SMOOTH",
+"940 868 OFFCURVE",
+"1160 1032 OFFCURVE",
+"1160 1213 CURVE SMOOTH",
+"1160 1361 OFFCURVE",
+"1026 1470 OFFCURVE",
+"849 1470 CURVE SMOOTH",
+"637 1470 OFFCURVE",
+"414 1364 OFFCURVE",
+"414 1124 CURVE SMOOTH",
+"414 968 OFFCURVE",
+"552 751 OFFCURVE",
+"661 535 CURVE SMOOTH",
+"842 177 OFFCURVE",
+"969 -25 OFFCURVE",
+"1021 -25 CURVE SMOOTH",
+"1056 -25 OFFCURVE",
+"1205 57 OFFCURVE",
+"1250 89 CURVE",
+"1165 129 OFFCURVE",
+"1073 302 OFFCURVE",
+"890 673 CURVE SMOOTH",
+"788 881 OFFCURVE",
+"651 1063 OFFCURVE",
+"651 1163 CURVE SMOOTH",
+"651 1245 OFFCURVE",
+"729 1307 OFFCURVE",
+"803 1307 CURVE SMOOTH",
+"873 1307 OFFCURVE",
+"926 1250 OFFCURVE",
+"926 1184 CURVE SMOOTH",
+"926 1081 OFFCURVE",
+"821 997 OFFCURVE",
+"600 832 CURVE SMOOTH",
+"392 677 OFFCURVE",
+"108 540 OFFCURVE",
+"108 268 CURVE SMOOTH",
+"108 98 OFFCURVE",
+"229 -25 OFFCURVE",
+"466 -25 CURVE SMOOTH",
+"749 -25 OFFCURVE",
+"1120 261 OFFCURVE",
+"1237 421 CURVE",
+"1146 594 LINE"
+);
+}
+);
+width = 1333;
+}
+);
+unicode = 0026;
+},
+{
+glyphname = Apos;
+layers = (
+{
+layerId = master01;
+paths = (
+{
+closed = 1;
+nodes = (
+"599 1162 OFFCURVE",
+"643 1312 OFFCURVE",
+"732 1553 CURVE",
+"527 1553 LINE",
+"498 1312 OFFCURVE",
+"465 1162 OFFCURVE",
+"435 1024 CURVE",
+"560 1024 LINE"
+);
+}
+);
+width = 585;
+},
+{
+layerId = master02;
+paths = (
+{
+closed = 1;
+nodes = (
+"637 1174 OFFCURVE",
+"676 1326 OFFCURVE",
+"766 1569 CURVE",
+"521 1569 LINE",
+"491 1326 OFFCURVE",
+"453 1174 OFFCURVE",
+"423 1035 CURVE",
+"598 1035 LINE"
+);
+}
+);
+width = 605;
+}
+);
+unicode = 0027;
+},
+{
+glyphname = LftParen;
+layers = (
+{
+layerId = master01;
+paths = (
+{
+closed = 1;
+nodes = (
+"582 1415 OFFCURVE",
+"314 1061 OFFCURVE",
+"207 633 CURVE SMOOTH",
+"176 508 OFFCURVE",
+"161 386 OFFCURVE",
+"161 270 CURVE SMOOTH",
+"161 17 OFFCURVE",
+"233 -211 OFFCURVE",
+"374 -402 CURVE",
+"505 -260 LINE",
+"397 -102 OFFCURVE",
+"348 75 OFFCURVE",
+"348 270 CURVE SMOOTH",
+"348 385 OFFCURVE",
+"365 506 OFFCURVE",
+"397 633 CURVE SMOOTH",
+"484 982 OFFCURVE",
+"647 1254 OFFCURVE",
+"932 1455 CURVE",
+"895 1607 LINE"
+);
+}
+);
+width = 775;
+},
+{
+layerId = master02;
+paths = (
+{
+closed = 1;
+nodes = (
+"586 1430 OFFCURVE",
+"317 1081 OFFCURVE",
+"209 649 CURVE SMOOTH",
+"177 521 OFFCURVE",
+"161 397 OFFCURVE",
+"161 277 CURVE SMOOTH",
+"161 20 OFFCURVE",
+"234 -214 OFFCURVE",
+"373 -406 CURVE",
+"565 -198 LINE",
+"479 -42 OFFCURVE",
+"436 130 OFFCURVE",
+"436 315 CURVE SMOOTH",
+"436 422 OFFCURVE",
+"450 534 OFFCURVE",
+"479 649 CURVE SMOOTH",
+"559 972 OFFCURVE",
+"715 1216 OFFCURVE",
+"966 1411 CURVE",
+"899 1624 LINE"
+);
+}
+);
+width = 840;
+}
+);
+unicode = 0028;
+},
+{
+glyphname = RtParen;
+layers = (
+{
+layerId = master01;
+paths = (
+{
+closed = 1;
+nodes = (
+"578 1327 OFFCURVE",
+"628 1146 OFFCURVE",
+"628 946 CURVE SMOOTH",
+"628 832 OFFCURVE",
+"612 713 OFFCURVE",
+"582 593 CURVE SMOOTH",
+"497 252 OFFCURVE",
+"328 -8 OFFCURVE",
+"40 -260 CURVE",
+"99 -402 LINE",
+"444 -123 OFFCURVE",
+"673 194 OFFCURVE",
+"772 593 CURVE SMOOTH",
+"804 719 OFFCURVE",
+"819 843 OFFCURVE",
+"819 959 CURVE SMOOTH",
+"819 1236 OFFCURVE",
+"733 1472 OFFCURVE",
+"580 1607 CURVE",
+"467 1455 LINE"
+);
+}
+);
+width = 775;
+},
+{
+layerId = master02;
+paths = (
+{
+closed = 1;
+nodes = (
+"572 1290 OFFCURVE",
+"616 1127 OFFCURVE",
+"616 944 CURVE SMOOTH",
+"616 832 OFFCURVE",
+"599 712 OFFCURVE",
+"569 589 CURVE SMOOTH",
+"491 275 OFFCURVE",
+"333 48 OFFCURVE",
+"75 -198 CURVE",
+"163 -406 LINE",
+"509 -124 OFFCURVE",
+"743 206 OFFCURVE",
+"844 609 CURVE SMOOTH",
+"876 735 OFFCURVE",
+"891 858 OFFCURVE",
+"891 973 CURVE SMOOTH",
+"891 1252 OFFCURVE",
+"803 1487 OFFCURVE",
+"649 1624 CURVE",
+"476 1411 LINE"
+);
+}
+);
+width = 840;
+}
+);
+unicode = 0029;
+},
+{
+glyphname = Asterisk;
+layers = (
+{
+layerId = master01;
+paths = (
+{
+closed = 1;
+nodes = (
+"733 1438 OFFCURVE",
+"725 1359 OFFCURVE",
+"707 1274 CURVE",
+"644 1317 OFFCURVE",
+"587 1359 OFFCURVE",
+"498 1436 CURVE",
+"392 1313 LINE",
+"505 1264 OFFCURVE",
+"575 1236 OFFCURVE",
+"643 1196 CURVE",
+"556 1153 OFFCURVE",
+"474 1117 OFFCURVE",
+"340 1063 CURVE",
+"379 941 LINE",
+"504 1021 OFFCURVE",
+"584 1072 OFFCURVE",
+"668 1117 CURVE",
+"645 1034 OFFCURVE",
+"619 954 OFFCURVE",
+"575 823 CURVE",
+"715 823 LINE",
+"727 954 OFFCURVE",
+"741 1031 OFFCURVE",
+"758 1117 CURVE",
+"821 1073 OFFCURVE",
+"878 1032 OFFCURVE",
+"968 956 CURVE",
+"1073 1078 LINE",
+"959 1126 OFFCURVE",
+"890 1155 OFFCURVE",
+"823 1196 CURVE",
+"909 1236 OFFCURVE",
+"990 1273 OFFCURVE",
+"1126 1328 CURVE",
+"1086 1450 LINE",
+"961 1368 OFFCURVE",
+"883 1321 OFFCURVE",
+"797 1274 CURVE",
+"819 1359 OFFCURVE",
+"845 1438 OFFCURVE",
+"890 1568 CURVE",
+"745 1568 LINE"
+);
+}
+);
+width = 1008;
+},
+{
+layerId = master02;
+paths = (
+{
+closed = 1;
+nodes = (
+"1039 1412 OFFCURVE",
+"956 1353 OFFCURVE",
+"856 1295 CURVE",
+"885 1391 OFFCURVE",
+"915 1471 OFFCURVE",
+"958 1584 CURVE",
+"759 1584 LINE",
+"753 1482 OFFCURVE",
+"748 1398 OFFCURVE",
+"730 1295 CURVE",
+"658 1346 OFFCURVE",
+"599 1394 OFFCURVE",
+"532 1461 CURVE",
+"388 1293 LINE",
+"484 1258 OFFCURVE",
+"575 1222 OFFCURVE",
+"647 1184 CURVE",
+"552 1141 OFFCURVE",
+"459 1109 OFFCURVE",
+"341 1066 CURVE",
+"398 888 LINE",
+"494 958 OFFCURVE",
+"575 1016 OFFCURVE",
+"674 1076 CURVE",
+"641 973 OFFCURVE",
+"610 887 OFFCURVE",
+"566 785 CURVE",
+"767 785 LINE",
+"773 897 OFFCURVE",
+"785 977 OFFCURVE",
+"800 1073 CURVE",
+"875 1017 OFFCURVE",
+"929 971 OFFCURVE",
+"995 905 CURVE",
+"1144 1078 LINE",
+"1045 1116 OFFCURVE",
+"967 1143 OFFCURVE",
+"886 1184 CURVE",
+"984 1229 OFFCURVE",
+"1075 1264 OFFCURVE",
+"1190 1308 CURVE",
+"1135 1478 LINE"
+);
+}
+);
+width = 1020;
+}
+);
+unicode = 002A;
+},
+{
+glyphname = PlusSgn;
+layers = (
+{
+layerId = master01;
+paths = (
+{
+closed = 1;
+nodes = (
+"529 279 LINE",
+"684 279 LINE",
+"903 1156 LINE",
+"748 1156 LINE"
+);
+},
+{
+closed = 1;
+nodes = (
+"1146 647 LINE",
+"1182 794 LINE",
+"292 794 LINE",
+"256 647 LINE"
+);
+}
+);
+width = 1180;
+},
+{
+layerId = master02;
+paths = (
+{
+closed = 1;
+nodes = (
+"500 282 LINE",
+"715 282 LINE",
+"936 1168 LINE",
+"722 1168 LINE"
+);
+},
+{
+closed = 1;
+nodes = (
+"1140 624 LINE",
+"1192 832 LINE",
+"302 832 LINE",
+"250 624 LINE"
+);
+}
+);
+width = 1180;
+}
+);
+unicode = 002B;
+},
+{
+glyphname = Comma;
+layers = (
+{
+layerId = master01;
+paths = (
+{
+closed = 1;
+nodes = (
+"277 49 LINE",
+"252 -50 OFFCURVE",
+"145 -169 OFFCURVE",
+"73 -225 CURVE",
+"163 -265 LINE",
+"280 -175 OFFCURVE",
+"431 -28 OFFCURVE",
+"431 118 CURVE SMOOTH",
+"431 193 OFFCURVE",
+"378 245 OFFCURVE",
+"311 245 CURVE SMOOTH",
+"254 245 OFFCURVE",
+"190 209 OFFCURVE",
+"161 147 CURVE",
+"137 49 LINE"
+);
+}
+);
+width = 630;
+},
+{
+layerId = master02;
+paths = (
+{
+closed = 1;
+nodes = (
+"297 49 LINE",
+"276 -34 OFFCURVE",
+"192 -151 OFFCURVE",
+"59 -262 CURVE",
+"187 -332 LINE",
+"337 -222 OFFCURVE",
+"539 -11 OFFCURVE",
+"539 165 CURVE SMOOTH",
+"539 262 OFFCURVE",
+"495 337 OFFCURVE",
+"379 337 CURVE SMOOTH",
+"266 337 OFFCURVE",
+"187 252 OFFCURVE",
+"169 178 CURVE SMOOTH",
+"137 49 LINE"
+);
+}
+);
+width = 645;
+}
+);
+unicode = 002C;
+},
+{
+glyphname = HyphenMinus;
+layers = (
+{
+anchors = (
+{
+name = U;
+position = "{645, 1100}";
+}
+);
+layerId = master01;
+paths = (
+{
+closed = 1;
+nodes = (
+"855 544 LINE",
+"892 691 LINE",
+"192 691 LINE",
+"155 544 LINE"
+);
+}
+);
+width = 840;
+},
+{
+anchors = (
+{
+name = U;
+position = "{665, 1100}";
+}
+);
+layerId = master02;
+paths = (
+{
+closed = 1;
+nodes = (
+"884 520 LINE",
+"936 728 LINE",
+"201 728 LINE",
+"149 520 LINE"
+);
+}
+);
+width = 875;
+}
+);
+unicode = 002D;
+},
+{
+glyphname = FullStop;
+layers = (
+{
+layerId = master01;
+paths = (
+{
+closed = 1;
+nodes = (
+"148 28 OFFCURVE",
+"198 -25 OFFCURVE",
+"263 -25 CURVE SMOOTH",
+"347 -25 OFFCURVE",
+"424 45 OFFCURVE",
+"424 125 CURVE SMOOTH",
+"424 186 OFFCURVE",
+"374 240 OFFCURVE",
+"309 240 CURVE SMOOTH",
+"225 240 OFFCURVE",
+"148 170 OFFCURVE",
+"148 90 CURVE SMOOTH"
+);
+}
+);
+width = 620;
+},
+{
+layerId = master02;
+paths = (
+{
+closed = 1;
+nodes = (
+"171 35 OFFCURVE",
+"232 -25 OFFCURVE",
+"318 -25 CURVE SMOOTH",
+"436 -25 OFFCURVE",
+"531 71 OFFCURVE",
+"531 181 CURVE SMOOTH",
+"531 261 OFFCURVE",
+"472 322 OFFCURVE",
+"385 322 CURVE SMOOTH",
+"268 322 OFFCURVE",
+"171 226 OFFCURVE",
+"171 116 CURVE SMOOTH"
+);
+}
+);
+width = 690;
+}
+);
+unicode = 002E;
+},
+{
+glyphname = Solidus;
+layers = (
+{
+layerId = master01;
+paths = (
+{
+closed = 1;
+nodes = (
+"-119 -240 LINE",
+"50 -240 LINE",
+"1330 1568 LINE",
+"1160 1568 LINE"
+);
+}
+);
+width = 980;
+},
+{
+layerId = master02;
+paths = (
+{
+closed = 1;
+nodes = (
+"-120 -243 LINE",
+"129 -243 LINE",
+"1414 1584 LINE",
+"1164 1584 LINE"
+);
+}
+);
+width = 1060;
+}
+);
+unicode = 002F;
+},
+{
+glyphname = DigitZero;
+layers = (
+{
+anchors = (
+{
+name = L;
+position = "{520, -100}";
+},
+{
+name = U;
+position = "{927, 1530}";
+}
+);
+layerId = master01;
+paths = (
+{
+closed = 1;
+nodes = (
+"925 312 OFFCURVE",
+"747 142 OFFCURVE",
+"565 142 CURVE SMOOTH",
+"432 142 OFFCURVE",
+"360 218 OFFCURVE",
+"360 383 CURVE SMOOTH",
+"360 468 OFFCURVE",
+"377 579 OFFCURVE",
+"412 720 CURVE SMOOTH",
+"512 1120 OFFCURVE",
+"678 1289 OFFCURVE",
+"871 1289 CURVE SMOOTH",
+"1006 1289 OFFCURVE",
+"1077 1223 OFFCURVE",
+"1077 1051 CURVE SMOOTH",
+"1077 966 OFFCURVE",
+"1060 854 OFFCURVE",
+"1024 711 CURVE SMOOTH"
+);
+},
+{
+closed = 1;
+nodes = (
+"1262 841 OFFCURVE",
+"1276 949 OFFCURVE",
+"1276 1040 CURVE SMOOTH",
+"1276 1335 OFFCURVE",
+"1124 1455 OFFCURVE",
+"902 1455 CURVE SMOOTH",
+"613 1455 OFFCURVE",
+"344 1267 OFFCURVE",
+"206 716 CURVE SMOOTH",
+"173 584 OFFCURVE",
+"158 474 OFFCURVE",
+"158 381 CURVE SMOOTH",
+"158 104 OFFCURVE",
+"313 -25 OFFCURVE",
+"533 -25 CURVE SMOOTH",
+"804 -25 OFFCURVE",
+"1086 138 OFFCURVE",
+"1230 715 CURVE SMOOTH"
+);
+}
+);
+width = 1180;
+},
+{
+anchors = (
+{
+name = L;
+position = "{520, -100}";
+},
+{
+name = U;
+position = "{927, 1530}";
+}
+);
+layerId = master02;
+paths = (
+{
+closed = 1;
+nodes = (
+"873 339 OFFCURVE",
+"762 203 OFFCURVE",
+"600 203 CURVE SMOOTH",
+"469 203 OFFCURVE",
+"432 294 OFFCURVE",
+"432 454 CURVE SMOOTH",
+"432 537 OFFCURVE",
+"447 630 OFFCURVE",
+"478 755 CURVE SMOOTH",
+"564 1099 OFFCURVE",
+"676 1242 OFFCURVE",
+"839 1242 CURVE SMOOTH",
+"971 1242 OFFCURVE",
+"1010 1140 OFFCURVE",
+"1010 992 CURVE SMOOTH",
+"1010 907 OFFCURVE",
+"991 811 OFFCURVE",
+"959 683 CURVE SMOOTH"
+);
+},
+{
+closed = 1;
+nodes = (
+"1281 828 OFFCURVE",
+"1298 927 OFFCURVE",
+"1298 1028 CURVE SMOOTH",
+"1298 1317 OFFCURVE",
+"1158 1470 OFFCURVE",
+"906 1470 CURVE SMOOTH",
+"587 1470 OFFCURVE",
+"329 1302 OFFCURVE",
+"190 745 CURVE SMOOTH",
+"157 611 OFFCURVE",
+"141 516 OFFCURVE",
+"141 420 CURVE SMOOTH",
+"141 131 OFFCURVE",
+"292 -25 OFFCURVE",
+"533 -25 CURVE SMOOTH",
+"854 -25 OFFCURVE",
+"1103 115 OFFCURVE",
+"1246 689 CURVE SMOOTH"
+);
+}
+);
+width = 1180;
+}
+);
+unicode = 0030;
+},
+{
+glyphname = DigitOne;
+layers = (
+{
+anchors = (
+{
+name = L;
+position = "{515, -100}";
+},
+{
+name = U;
+position = "{922, 1530}";
+}
+);
+layerId = master01;
+paths = (
+{
+closed = 1;
+nodes = (
+"706 167 LINE",
+"1026 1450 LINE",
+"856 1450 LINE",
+"459 1243 LINE",
+"440 1066 LINE",
+"782 1235 LINE",
+"516 167 LINE",
+"201 167 LINE",
+"160 0 LINE",
+"980 0 LINE",
+"1021 167 LINE"
+);
+}
+);
+width = 1180;
+},
+{
+anchors = (
+{
+name = L;
+position = "{515, -100}";
+},
+{
+name = U;
+position = "{922, 1530}";
+}
+);
+layerId = master02;
+paths = (
+{
+closed = 1;
+nodes = (
+"183 233 LINE",
+"125 0 LINE",
+"1015 0 LINE",
+"1073 233 LINE",
+"765 233 LINE",
+"1067 1445 LINE",
+"792 1445 LINE",
+"432 1265 LINE",
+"403 1008 LINE",
+"720 1158 LINE",
+"490 233 LINE"
+);
+}
+);
+width = 1180;
+}
+);
+unicode = 0031;
+},
+{
+glyphname = DigitTwo;
+layers = (
+{
+anchors = (
+{
+name = L;
+position = "{515, -100}";
+},
+{
+name = U;
+position = "{882, 1530}";
+}
+);
+layerId = master01;
+paths = (
+{
+closed = 1;
+nodes = (
+"980 163 OFFCURVE",
+"822 162 OFFCURVE",
+"625 162 CURVE SMOOTH",
+"370 162 LINE",
+"783 393 OFFCURVE",
+"1210 830 OFFCURVE",
+"1210 1098 CURVE SMOOTH",
+"1210 1296 OFFCURVE",
+"1075 1455 OFFCURVE",
+"842 1455 CURVE SMOOTH",
+"673 1455 OFFCURVE",
+"488 1374 OFFCURVE",
+"380 1264 CURVE",
+"388 1098 LINE",
+"503 1203 OFFCURVE",
+"660 1279 OFFCURVE",
+"783 1279 CURVE SMOOTH",
+"915 1279 OFFCURVE",
+"1003 1199 OFFCURVE",
+"1003 1063 CURVE SMOOTH",
+"1003 848 OFFCURVE",
+"506 386 OFFCURVE",
+"101 167 CURVE",
+"60 0 LINE",
+"1020 0 LINE",
+"1063 176 LINE"
+);
+}
+);
+width = 1180;
+},
+{
+anchors = (
+{
+name = L;
+position = "{515, -100}";
+},
+{
+name = U;
+position = "{882, 1530}";
+}
+);
+layerId = master02;
+paths = (
+{
+closed = 1;
+nodes = (
+"1010 244 OFFCURVE",
+"942 243 OFFCURVE",
+"745 243 CURVE SMOOTH",
+"480 243 LINE",
+"875 492 OFFCURVE",
+"1255 786 OFFCURVE",
+"1255 1125 CURVE SMOOTH",
+"1255 1324 OFFCURVE",
+"1106 1470 OFFCURVE",
+"846 1470 CURVE SMOOTH",
+"667 1470 OFFCURVE",
+"472 1388 OFFCURVE",
+"363 1277 CURVE",
+"374 1039 LINE",
+"489 1146 OFFCURVE",
+"646 1223 OFFCURVE",
+"762 1223 CURVE SMOOTH",
+"890 1223 OFFCURVE",
+"949 1138 OFFCURVE",
+"949 1040 CURVE SMOOTH",
+"949 805 OFFCURVE",
+"500 440 OFFCURVE",
+"104 218 CURVE",
+"50 0 LINE",
+"1030 0 LINE",
+"1094 257 LINE"
+);
+}
+);
+width = 1180;
+}
+);
+unicode = 0032;
+},
+{
+glyphname = DigitThree;
+layers = (
+{
+anchors = (
+{
+name = L;
+position = "{515, -100}";
+},
+{
+name = U;
+position = "{922, 1530}";
+}
+);
+layerId = master01;
+paths = (
+{
+closed = 1;
+nodes = (
+"521 686 LINE",
+"591 686 LINE SMOOTH",
+"802 686 OFFCURVE",
+"944 606 OFFCURVE",
+"944 476 CURVE SMOOTH",
+"944 268 OFFCURVE",
+"738 147 OFFCURVE",
+"551 147 CURVE SMOOTH",
+"371 147 OFFCURVE",
+"260 227 OFFCURVE",
+"181 348 CURVE",
+"104 137 LINE",
+"185 41 OFFCURVE",
+"341 -25 OFFCURVE",
+"518 -25 CURVE SMOOTH",
+"815 -25 OFFCURVE",
+"1141 168 OFFCURVE",
+"1141 475 CURVE SMOOTH",
+"1141 670 OFFCURVE",
+"973 763 OFFCURVE",
+"855 784 CURVE",
+"1046 827 OFFCURVE",
+"1266 955 OFFCURVE",
+"1266 1163 CURVE SMOOTH",
+"1266 1338 OFFCURVE",
+"1073 1455 OFFCURVE",
+"852 1455 CURVE SMOOTH",
+"685 1455 OFFCURVE",
+"536 1388 OFFCURVE",
+"433 1299 CURVE",
+"427 1132 LINE",
+"568 1246 OFFCURVE",
+"696 1284 OFFCURVE",
+"850 1284 CURVE SMOOTH",
+"957 1284 OFFCURVE",
+"1068 1236 OFFCURVE",
+"1068 1137 CURVE SMOOTH",
+"1068 949 OFFCURVE",
+"781 853 OFFCURVE",
+"632 853 CURVE SMOOTH",
+"562 853 LINE"
+);
+}
+);
+width = 1180;
+},
+{
+anchors = (
+{
+name = L;
+position = "{515, -100}";
+},
+{
+name = U;
+position = "{922, 1530}";
+}
+);
+layerId = master02;
+paths = (
+{
+closed = 1;
+nodes = (
+"489 639 LINE",
+"579 639 LINE SMOOTH",
+"778 639 OFFCURVE",
+"880 555 OFFCURVE",
+"880 452 CURVE SMOOTH",
+"880 295 OFFCURVE",
+"726 208 OFFCURVE",
+"576 208 CURVE SMOOTH",
+"386 208 OFFCURVE",
+"253 279 OFFCURVE",
+"174 401 CURVE",
+"72 129 LINE",
+"162 32 OFFCURVE",
+"321 -25 OFFCURVE",
+"518 -25 CURVE SMOOTH",
+"867 -25 OFFCURVE",
+"1163 169 OFFCURVE",
+"1163 471 CURVE SMOOTH",
+"1163 644 OFFCURVE",
+"999 751 OFFCURVE",
+"882 772 CURVE",
+"1076 817 OFFCURVE",
+"1296 963 OFFCURVE",
+"1296 1172 CURVE SMOOTH",
+"1296 1348 OFFCURVE",
+"1112 1470 OFFCURVE",
+"856 1470 CURVE SMOOTH",
+"689 1470 OFFCURVE",
+"529 1402 OFFCURVE",
+"427 1312 CURVE",
+"405 1084 LINE",
+"546 1199 OFFCURVE",
+"664 1237 OFFCURVE",
+"818 1237 CURVE SMOOTH",
+"928 1237 OFFCURVE",
+"1001 1178 OFFCURVE",
+"1001 1100 CURVE SMOOTH",
+"1001 975 OFFCURVE",
+"819 876 OFFCURVE",
+"638 876 CURVE SMOOTH",
+"548 876 LINE"
+);
+}
+);
+width = 1180;
+}
+);
+unicode = 0033;
+},
+{
+glyphname = DigitFour;
+layers = (
+{
+anchors = (
+{
+name = L;
+position = "{522, -100}";
+},
+{
+name = U;
+position = "{929, 1530}";
+}
+);
+layerId = master01;
+paths = (
+{
+closed = 1;
+nodes = (
+"1199 539 LINE",
+"1009 539 LINE",
+"1236 1450 LINE",
+"1026 1450 LINE",
+"144 539 LINE",
+"106 387 LINE",
+"781 387 LINE",
+"685 0 LINE",
+"875 0 LINE",
+"971 387 LINE",
+"1161 387 LINE"
+);
+},
+{
+closed = 1;
+nodes = (
+"819 539 LINE",
+"337 539 LINE",
+"985 1205 LINE"
+);
+}
+);
+width = 1180;
+},
+{
+anchors = (
+{
+name = L;
+position = "{522, -100}";
+},
+{
+name = U;
+position = "{929, 1530}";
+}
+);
+layerId = master02;
+paths = (
+{
+closed = 1;
+nodes = (
+"1235 564 LINE",
+"1075 564 LINE",
+"1295 1445 LINE",
+"945 1445 LINE",
+"120 564 LINE",
+"65 342 LINE",
+"755 342 LINE",
+"670 0 LINE",
+"935 0 LINE",
+"1020 342 LINE",
+"1180 342 LINE"
+);
+},
+{
+closed = 1;
+nodes = (
+"810 564 LINE",
+"385 564 LINE",
+"954 1143 LINE"
+);
+}
+);
+width = 1180;
+}
+);
+unicode = 0034;
+},
+{
+glyphname = DigitFive;
+layers = (
+{
+anchors = (
+{
+name = L;
+position = "{515, -100}";
+},
+{
+name = U;
+position = "{922, 1530}";
+}
+);
+layerId = master01;
+paths = (
+{
+closed = 1;
+nodes = (
+"491 1431 LINE",
+"302 671 LINE",
+"438 718 OFFCURVE",
+"537 735 OFFCURVE",
+"643 735 CURVE SMOOTH",
+"784 735 OFFCURVE",
+"933 660 OFFCURVE",
+"933 508 CURVE SMOOTH",
+"933 273 OFFCURVE",
+"710 152 OFFCURVE",
+"497 152 CURVE SMOOTH",
+"357 152 OFFCURVE",
+"263 195 OFFCURVE",
+"170 284 CURVE",
+"89 78 LINE",
+"195 2 OFFCURVE",
+"326 -25 OFFCURVE",
+"481 -25 CURVE SMOOTH",
+"807 -25 OFFCURVE",
+"1129 190 OFFCURVE",
+"1129 546 CURVE SMOOTH",
+"1129 757 OFFCURVE",
+"951 911 OFFCURVE",
+"702 911 CURVE SMOOTH",
+"629 911 OFFCURVE",
+"576 906 OFFCURVE",
+"544 902 CURVE",
+"635 1264 LINE",
+"1020 1264 LINE SMOOTH",
+"1104 1264 OFFCURVE",
+"1179 1260 OFFCURVE",
+"1250 1245 CURVE",
+"1296 1431 LINE"
+);
+}
+);
+width = 1180;
+},
+{
+anchors = (
+{
+name = L;
+position = "{515, -100}";
+},
+{
+name = U;
+position = "{922, 1530}";
+}
+);
+layerId = master02;
+paths = (
+{
+closed = 1;
+nodes = (
+"475 1445 LINE",
+"274 639 LINE",
+"410 686 OFFCURVE",
+"519 703 OFFCURVE",
+"625 703 CURVE SMOOTH",
+"763 703 OFFCURVE",
+"867 630 OFFCURVE",
+"867 507 CURVE SMOOTH",
+"867 318 OFFCURVE",
+"680 213 OFFCURVE",
+"503 213 CURVE SMOOTH",
+"363 213 OFFCURVE",
+"255 260 OFFCURVE",
+"168 356 CURVE",
+"59 79 LINE",
+"165 2 OFFCURVE",
+"308 -25 OFFCURVE",
+"483 -25 CURVE SMOOTH",
+"841 -25 OFFCURVE",
+"1155 204 OFFCURVE",
+"1155 564 CURVE SMOOTH",
+"1155 774 OFFCURVE",
+"1007 921 OFFCURVE",
+"774 921 CURVE SMOOTH",
+"712 921 OFFCURVE",
+"632 902 OFFCURVE",
+"595 886 CURVE",
+"674 1203 LINE",
+"1004 1203 LINE SMOOTH",
+"1088 1203 OFFCURVE",
+"1193 1199 OFFCURVE",
+"1264 1183 CURVE",
+"1330 1445 LINE"
+);
+}
+);
+width = 1180;
+}
+);
+unicode = 0035;
+},
+{
+glyphname = DigitSix;
+layers = (
+{
+anchors = (
+{
+name = L;
+position = "{515, -100}";
+},
+{
+name = U;
+position = "{922, 1530}";
+}
+);
+layerId = master01;
+paths = (
+{
+closed = 1;
+nodes = (
+"1248 1418 OFFCURVE",
+"1135 1455 OFFCURVE",
+"1017 1455 CURVE SMOOTH",
+"481 1454 OFFCURVE",
+"208 915 OFFCURVE",
+"208 475 CURVE SMOOTH",
+"208 167 OFFCURVE",
+"392 -25 OFFCURVE",
+"623 -25 CURVE SMOOTH",
+"947 -25 OFFCURVE",
+"1183 169 OFFCURVE",
+"1183 517 CURVE SMOOTH",
+"1183 709 OFFCURVE",
+"1029 887 OFFCURVE",
+"793 887 CURVE SMOOTH",
+"636 887 OFFCURVE",
+"432 784 OFFCURVE",
+"317 633 CURVE",
+"364 559 LINE",
+"471 660 OFFCURVE",
+"596 716 OFFCURVE",
+"751 716 CURVE SMOOTH",
+"898 716 OFFCURVE",
+"987 614 OFFCURVE",
+"987 454 CURVE SMOOTH",
+"987 263 OFFCURVE",
+"816 147 OFFCURVE",
+"656 147 CURVE SMOOTH",
+"491 147 OFFCURVE",
+"403 284 OFFCURVE",
+"403 472 CURVE SMOOTH",
+"403 962 OFFCURVE",
+"664 1284 OFFCURVE",
+"985 1284 CURVE SMOOTH",
+"1081 1284 OFFCURVE",
+"1174 1235 OFFCURVE",
+"1222 1156 CURVE",
+"1313 1347 LINE"
+);
+}
+);
+width = 1180;
+},
+{
+anchors = (
+{
+name = L;
+position = "{525, -100}";
+},
+{
+name = U;
+position = "{932, 1530}";
+}
+);
+layerId = master02;
+paths = (
+{
+closed = 1;
+nodes = (
+"1260 1440 OFFCURVE",
+"1149 1470 OFFCURVE",
+"1011 1470 CURVE SMOOTH",
+"493 1470 OFFCURVE",
+"181 971 OFFCURVE",
+"181 500 CURVE SMOOTH",
+"181 188 OFFCURVE",
+"368 -25 OFFCURVE",
+"635 -25 CURVE SMOOTH",
+"954 -25 OFFCURVE",
+"1207 192 OFFCURVE",
+"1207 498 CURVE SMOOTH",
+"1207 714 OFFCURVE",
+"1058 916 OFFCURVE",
+"813 916 CURVE SMOOTH",
+"622 916 OFFCURVE",
+"477 802 OFFCURVE",
+"326 648 CURVE",
+"363 525 LINE",
+"470 637 OFFCURVE",
+"595 703 OFFCURVE",
+"750 703 CURVE SMOOTH",
+"882 703 OFFCURVE",
+"954 586 OFFCURVE",
+"954 466 CURVE SMOOTH",
+"954 325 OFFCURVE",
+"828 208 OFFCURVE",
+"677 208 CURVE SMOOTH",
+"526 208 OFFCURVE",
+"447 350 OFFCURVE",
+"447 533 CURVE SMOOTH",
+"447 978 OFFCURVE",
+"738 1237 OFFCURVE",
+"953 1237 CURVE SMOOTH",
+"1049 1237 OFFCURVE",
+"1155 1204 OFFCURVE",
+"1220 1119 CURVE",
+"1347 1371 LINE"
+);
+}
+);
+width = 1180;
+}
+);
+unicode = 0036;
+},
+{
+glyphname = DigitSeven;
+layers = (
+{
+anchors = (
+{
+name = L;
+position = "{515, -100}";
+},
+{
+name = U;
+position = "{922, 1530}";
+}
+);
+layerId = master01;
+paths = (
+{
+closed = 1;
+nodes = (
+"661 450 OFFCURVE",
+"972 877 OFFCURVE",
+"1367 1274 CURVE",
+"1406 1431 LINE",
+"386 1431 LINE",
+"341 1245 LINE",
+"421 1260 OFFCURVE",
+"538 1264 OFFCURVE",
+"726 1264 CURVE SMOOTH",
+"1126 1264 LINE",
+"774 889 OFFCURVE",
+"517 555 OFFCURVE",
+"215 0 CURVE",
+"420 0 LINE"
+);
+}
+);
+width = 1180;
+},
+{
+anchors = (
+{
+name = L;
+position = "{515, -100}";
+},
+{
+name = U;
+position = "{922, 1530}";
+}
+);
+layerId = master02;
+paths = (
+{
+closed = 1;
+nodes = (
+"722 454 OFFCURVE",
+"1004 846 OFFCURVE",
+"1400 1247 CURVE",
+"1450 1445 LINE",
+"390 1445 LINE",
+"324 1178 LINE",
+"404 1194 OFFCURVE",
+"521 1198 OFFCURVE",
+"709 1198 CURVE SMOOTH",
+"1039 1198 LINE",
+"689 829 OFFCURVE",
+"488 560 OFFCURVE",
+"175 0 CURVE",
+"480 0 LINE"
+);
+}
+);
+width = 1180;
+}
+);
+unicode = 0037;
+},
+{
+glyphname = DigitEight;
+layers = (
+{
+anchors = (
+{
+name = L;
+position = "{515, -100}";
+},
+{
+name = U;
+position = "{922, 1530}";
+}
+);
+layerId = master01;
+paths = (
+{
+closed = 1;
+nodes = (
+"839 -25 OFFCURVE",
+"1160 170 OFFCURVE",
+"1160 475 CURVE SMOOTH",
+"1160 626 OFFCURVE",
+"1068 733 OFFCURVE",
+"988 779 CURVE",
+"1155 860 OFFCURVE",
+"1270 970 OFFCURVE",
+"1270 1151 CURVE SMOOTH",
+"1270 1340 OFFCURVE",
+"1102 1455 OFFCURVE",
+"901 1455 CURVE SMOOTH",
+"620 1455 OFFCURVE",
+"348 1292 OFFCURVE",
+"348 1018 CURVE SMOOTH",
+"348 891 OFFCURVE",
+"427 814 OFFCURVE",
+"483 779 CURVE",
+"297 706 OFFCURVE",
+"115 549 OFFCURVE",
+"115 325 CURVE SMOOTH",
+"115 111 OFFCURVE",
+"317 -25 OFFCURVE",
+"542 -25 CURVE SMOOTH"
+);
+},
+{
+closed = 1;
+nodes = (
+"628 848 OFFCURVE",
+"541 917 OFFCURVE",
+"541 1029 CURVE SMOOTH",
+"541 1205 OFFCURVE",
+"704 1299 OFFCURVE",
+"862 1299 CURVE SMOOTH",
+"985 1299 OFFCURVE",
+"1076 1235 OFFCURVE",
+"1076 1128 CURVE SMOOTH",
+"1076 955 OFFCURVE",
+"907 848 OFFCURVE",
+"750 848 CURVE SMOOTH"
+);
+},
+{
+closed = 1;
+nodes = (
+"413 142 OFFCURVE",
+"322 225 OFFCURVE",
+"322 350 CURVE SMOOTH",
+"322 557 OFFCURVE",
+"520 696 OFFCURVE",
+"712 696 CURVE SMOOTH",
+"864 696 OFFCURVE",
+"961 602 OFFCURVE",
+"961 476 CURVE SMOOTH",
+"961 266 OFFCURVE",
+"753 142 OFFCURVE",
+"564 142 CURVE SMOOTH"
+);
+}
+);
+width = 1180;
+},
+{
+anchors = (
+{
+name = L;
+position = "{515, -100}";
+},
+{
+name = U;
+position = "{922, 1530}";
+}
+);
+layerId = master02;
+paths = (
+{
+closed = 1;
+nodes = (
+"860 -25 OFFCURVE",
+"1182 176 OFFCURVE",
+"1182 498 CURVE SMOOTH",
+"1182 642 OFFCURVE",
+"1090 742 OFFCURVE",
+"1011 787 CURVE",
+"1159 866 OFFCURVE",
+"1279 994 OFFCURVE",
+"1279 1163 CURVE SMOOTH",
+"1279 1342 OFFCURVE",
+"1123 1470 OFFCURVE",
+"906 1470 CURVE SMOOTH",
+"632 1470 OFFCURVE",
+"349 1310 OFFCURVE",
+"349 1028 CURVE SMOOTH",
+"349 904 OFFCURVE",
+"412 821 OFFCURVE",
+"466 787 CURVE",
+"270 703 OFFCURVE",
+"108 563 OFFCURVE",
+"108 341 CURVE SMOOTH",
+"108 123 OFFCURVE",
+"301 -25 OFFCURVE",
+"543 -25 CURVE SMOOTH"
+);
+},
+{
+closed = 1;
+nodes = (
+"651 886 OFFCURVE",
+"593 939 OFFCURVE",
+"593 1038 CURVE SMOOTH",
+"593 1175 OFFCURVE",
+"721 1277 OFFCURVE",
+"858 1277 CURVE SMOOTH",
+"976 1277 OFFCURVE",
+"1028 1221 OFFCURVE",
+"1028 1127 CURVE SMOOTH",
+"1028 993 OFFCURVE",
+"898 886 OFFCURVE",
+"760 886 CURVE SMOOTH"
+);
+},
+{
+closed = 1;
+nodes = (
+"458 183 OFFCURVE",
+"375 267 OFFCURVE",
+"375 384 CURVE SMOOTH",
+"375 549 OFFCURVE",
+"549 673 OFFCURVE",
+"707 673 CURVE SMOOTH",
+"833 673 OFFCURVE",
+"920 602 OFFCURVE",
+"920 477 CURVE SMOOTH",
+"920 317 OFFCURVE",
+"759 183 OFFCURVE",
+"595 183 CURVE SMOOTH"
+);
+}
+);
+width = 1180;
+}
+);
+unicode = 0038;
+},
+{
+glyphname = DigitNine;
+layers = (
+{
+anchors = (
+{
+name = L;
+position = "{515, -100}";
+},
+{
+name = U;
+position = "{922, 1530}";
+}
+);
+layerId = master01;
+paths = (
+{
+closed = 1;
+nodes = (
+"208 29 OFFCURVE",
+"355 -25 OFFCURVE",
+"473 -25 CURVE SMOOTH",
+"999 -25 OFFCURVE",
+"1267 520 OFFCURVE",
+"1267 982 CURVE SMOOTH",
+"1267 1248 OFFCURVE",
+"1127 1455 OFFCURVE",
+"866 1455 CURVE SMOOTH",
+"596 1455 OFFCURVE",
+"303 1269 OFFCURVE",
+"303 932 CURVE SMOOTH",
+"303 761 OFFCURVE",
+"425 574 OFFCURVE",
+"661 574 CURVE SMOOTH",
+"852 574 OFFCURVE",
+"1036 683 OFFCURVE",
+"1172 840 CURVE",
+"1121 922 LINE",
+"1019 810 OFFCURVE",
+"872 745 OFFCURVE",
+"717 745 CURVE SMOOTH",
+"584 745 OFFCURVE",
+"498 833 OFFCURVE",
+"498 956 CURVE SMOOTH",
+"498 1146 OFFCURVE",
+"638 1284 OFFCURVE",
+"821 1284 CURVE SMOOTH",
+"998 1284 OFFCURVE",
+"1073 1119 OFFCURVE",
+"1073 956 CURVE SMOOTH",
+"1073 455 OFFCURVE",
+"760 147 OFFCURVE",
+"496 147 CURVE SMOOTH",
+"410 147 OFFCURVE",
+"298 209 OFFCURVE",
+"249 285 CURVE",
+"157 94 LINE"
+);
+}
+);
+width = 1180;
+},
+{
+anchors = (
+{
+name = L;
+position = "{515, -100}";
+},
+{
+name = U;
+position = "{922, 1530}";
+}
+);
+layerId = master02;
+paths = (
+{
+closed = 1;
+nodes = (
+"199 25 OFFCURVE",
+"327 -25 OFFCURVE",
+"455 -25 CURVE SMOOTH",
+"979 -25 OFFCURVE",
+"1289 533 OFFCURVE",
+"1289 979 CURVE SMOOTH",
+"1289 1248 OFFCURVE",
+"1164 1470 OFFCURVE",
+"833 1470 CURVE SMOOTH",
+"554 1470 OFFCURVE",
+"255 1239 OFFCURVE",
+"255 932 CURVE SMOOTH",
+"255 736 OFFCURVE",
+"399 570 OFFCURVE",
+"644 570 CURVE SMOOTH",
+"833 570 OFFCURVE",
+"1027 700 OFFCURVE",
+"1164 859 CURVE",
+"1123 981 LINE",
+"1021 868 OFFCURVE",
+"863 782 OFFCURVE",
+"728 782 CURVE SMOOTH",
+"589 782 OFFCURVE",
+"519 845 OFFCURVE",
+"519 955 CURVE SMOOTH",
+"519 1133 OFFCURVE",
+"653 1237 OFFCURVE",
+"801 1237 CURVE SMOOTH",
+"951 1237 OFFCURVE",
+"1029 1136 OFFCURVE",
+"1029 965 CURVE SMOOTH",
+"1029 476 OFFCURVE",
+"710 208 OFFCURVE",
+"513 208 CURVE SMOOTH",
+"417 208 OFFCURVE",
+"301 252 OFFCURVE",
+"237 337 CURVE",
+"119 84 LINE"
+);
+}
+);
+width = 1180;
+}
+);
+unicode = 0039;
+},
+{
+glyphname = Colon;
+layers = (
+{
+layerId = master01;
+paths = (
+{
+closed = 1;
+nodes = (
+"314 696 OFFCURVE",
+"365 642 OFFCURVE",
+"430 642 CURVE SMOOTH",
+"514 642 OFFCURVE",
+"590 712 OFFCURVE",
+"590 792 CURVE SMOOTH",
+"590 854 OFFCURVE",
+"540 907 OFFCURVE",
+"476 907 CURVE SMOOTH",
+"393 907 OFFCURVE",
+"314 837 OFFCURVE",
+"314 758 CURVE SMOOTH"
+);
+},
+{
+closed = 1;
+nodes = (
+"148 28 OFFCURVE",
+"198 -25 OFFCURVE",
+"263 -25 CURVE SMOOTH",
+"347 -25 OFFCURVE",
+"424 45 OFFCURVE",
+"424 125 CURVE SMOOTH",
+"424 186 OFFCURVE",
+"374 240 OFFCURVE",
+"309 240 CURVE SMOOTH",
+"225 240 OFFCURVE",
+"148 170 OFFCURVE",
+"148 90 CURVE SMOOTH"
+);
+}
+);
+width = 620;
+},
+{
+layerId = master02;
+paths = (
+{
+closed = 1;
+nodes = (
+"171 35 OFFCURVE",
+"232 -25 OFFCURVE",
+"318 -25 CURVE SMOOTH",
+"436 -25 OFFCURVE",
+"531 71 OFFCURVE",
+"531 181 CURVE SMOOTH",
+"531 261 OFFCURVE",
+"472 322 OFFCURVE",
+"385 322 CURVE SMOOTH",
+"268 322 OFFCURVE",
+"171 226 OFFCURVE",
+"171 116 CURVE SMOOTH"
+);
+},
+{
+closed = 1;
+nodes = (
+"319 629 OFFCURVE",
+"380 569 OFFCURVE",
+"466 569 CURVE SMOOTH",
+"584 569 OFFCURVE",
+"679 665 OFFCURVE",
+"679 775 CURVE SMOOTH",
+"679 855 OFFCURVE",
+"620 916 OFFCURVE",
+"533 916 CURVE SMOOTH",
+"416 916 OFFCURVE",
+"319 820 OFFCURVE",
+"319 710 CURVE SMOOTH"
+);
+}
+);
+width = 690;
+}
+);
+unicode = 003A;
+},
+{
+glyphname = Semicolon;
+layers = (
+{
+layerId = master01;
+paths = (
+{
+closed = 1;
+nodes = (
+"314 696 OFFCURVE",
+"365 642 OFFCURVE",
+"430 642 CURVE SMOOTH",
+"514 642 OFFCURVE",
+"590 712 OFFCURVE",
+"590 792 CURVE SMOOTH",
+"590 854 OFFCURVE",
+"540 907 OFFCURVE",
+"476 907 CURVE SMOOTH",
+"393 907 OFFCURVE",
+"314 837 OFFCURVE",
+"314 758 CURVE SMOOTH"
+);
+},
+{
+closed = 1;
+nodes = (
+"277 49 LINE",
+"252 -50 OFFCURVE",
+"145 -169 OFFCURVE",
+"73 -225 CURVE",
+"163 -265 LINE",
+"280 -175 OFFCURVE",
+"431 -28 OFFCURVE",
+"431 118 CURVE SMOOTH",
+"431 193 OFFCURVE",
+"378 245 OFFCURVE",
+"311 245 CURVE SMOOTH",
+"254 245 OFFCURVE",
+"190 209 OFFCURVE",
+"161 147 CURVE",
+"137 49 LINE"
+);
+}
+);
+width = 630;
+},
+{
+layerId = master02;
+paths = (
+{
+closed = 1;
+nodes = (
+"297 49 LINE",
+"276 -34 OFFCURVE",
+"192 -151 OFFCURVE",
+"59 -262 CURVE",
+"187 -332 LINE",
+"337 -222 OFFCURVE",
+"539 -11 OFFCURVE",
+"539 165 CURVE SMOOTH",
+"539 262 OFFCURVE",
+"495 337 OFFCURVE",
+"379 337 CURVE SMOOTH",
+"266 337 OFFCURVE",
+"187 252 OFFCURVE",
+"169 178 CURVE SMOOTH",
+"137 49 LINE"
+);
+},
+{
+closed = 1;
+nodes = (
+"319 629 OFFCURVE",
+"380 569 OFFCURVE",
+"466 569 CURVE SMOOTH",
+"584 569 OFFCURVE",
+"679 665 OFFCURVE",
+"679 775 CURVE SMOOTH",
+"679 855 OFFCURVE",
+"620 916 OFFCURVE",
+"533 916 CURVE SMOOTH",
+"416 916 OFFCURVE",
+"319 820 OFFCURVE",
+"319 710 CURVE SMOOTH"
+);
+}
+);
+width = 690;
+}
+);
+unicode = 003B;
+},
+{
+glyphname = LTSgn;
+layers = (
+{
+layerId = master01;
+paths = (
+{
+closed = 1;
+nodes = (
+"408 705 LINE",
+"1272 1014 LINE",
+"1316 1191 LINE",
+"239 799 LINE",
+"197 632 LINE",
+"1079 240 LINE",
+"1123 417 LINE"
+);
+}
+);
+width = 1180;
+},
+{
+layerId = master02;
+paths = (
+{
+closed = 1;
+nodes = (
+"510 713 LINE",
+"1253 975 LINE",
+"1309 1203 LINE",
+"253 817 LINE",
+"206 629 LINE",
+"1070 243 LINE",
+"1127 470 LINE"
+);
+}
+);
+width = 1180;
+}
+);
+unicode = 003C;
+},
+{
+glyphname = EqSgn;
+layers = (
+{
+layerId = master01;
+paths = (
+{
+closed = 1;
+nodes = (
+"1137 470 LINE",
+"1173 617 LINE",
+"213 617 LINE",
+"177 470 LINE"
+);
+},
+{
+closed = 1;
+nodes = (
+"1222 813 LINE",
+"1259 960 LINE",
+"299 960 LINE",
+"262 813 LINE"
+);
+}
+);
+width = 1180;
+},
+{
+layerId = master02;
+paths = (
+{
+closed = 1;
+nodes = (
+"1128 436 LINE",
+"1180 643 LINE",
+"220 643 LINE",
+"168 436 LINE"
+);
+},
+{
+closed = 1;
+nodes = (
+"1219 802 LINE",
+"1271 1010 LINE",
+"311 1010 LINE",
+"259 802 LINE"
+);
+}
+);
+width = 1180;
+}
+);
+unicode = 003D;
+},
+{
+glyphname = GTSgn;
+layers = (
+{
+layerId = master01;
+paths = (
+{
+closed = 1;
+nodes = (
+"1028 725 LINE",
+"163 417 LINE",
+"119 240 LINE",
+"1197 632 LINE",
+"1239 799 LINE",
+"356 1191 LINE",
+"312 1014 LINE"
+);
+}
+);
+width = 1180;
+},
+{
+layerId = master02;
+paths = (
+{
+closed = 1;
+nodes = (
+"1186 629 LINE",
+"1233 817 LINE",
+"369 1203 LINE",
+"313 975 LINE",
+"930 733 LINE",
+"187 470 LINE",
+"130 243 LINE"
+);
+}
+);
+width = 1180;
+}
+);
+unicode = 003E;
+},
+{
+glyphname = QstnMrk;
+layers = (
+{
+layerId = master01;
+paths = (
+{
+closed = 1;
+nodes = (
+"514 1303 OFFCURVE",
+"615 1338 OFFCURVE",
+"685 1338 CURVE SMOOTH",
+"800 1338 OFFCURVE",
+"858 1294 OFFCURVE",
+"858 1222 CURVE SMOOTH",
+"858 1122 OFFCURVE",
+"713 1017 OFFCURVE",
+"654 960 CURVE SMOOTH",
+"538 850 OFFCURVE",
+"473 715 OFFCURVE",
+"402 431 CURVE",
+"587 431 LINE",
+"656 707 OFFCURVE",
+"697 778 OFFCURVE",
+"831 901 CURVE SMOOTH",
+"949 1010 OFFCURVE",
+"1072 1146 OFFCURVE",
+"1072 1272 CURVE SMOOTH",
+"1072 1409 OFFCURVE",
+"947 1509 OFFCURVE",
+"746 1509 CURVE SMOOTH",
+"631 1509 OFFCURVE",
+"500 1463 OFFCURVE",
+"419 1401 CURVE",
+"419 1226 LINE"
+);
+},
+{
+closed = 1;
+nodes = (
+"278 28 OFFCURVE",
+"328 -25 OFFCURVE",
+"393 -25 CURVE SMOOTH",
+"477 -25 OFFCURVE",
+"554 45 OFFCURVE",
+"554 125 CURVE SMOOTH",
+"554 186 OFFCURVE",
+"504 240 OFFCURVE",
+"439 240 CURVE SMOOTH",
+"355 240 OFFCURVE",
+"278 170 OFFCURVE",
+"278 90 CURVE SMOOTH"
+);
+}
+);
+width = 1030;
+},
+{
+layerId = master02;
+paths = (
+{
+closed = 1;
+nodes = (
+"745 664 OFFCURVE",
+"787 792 OFFCURVE",
+"931 933 CURVE SMOOTH",
+"1034 1033 OFFCURVE",
+"1143 1118 OFFCURVE",
+"1143 1256 CURVE SMOOTH",
+"1143 1404 OFFCURVE",
+"1022 1525 OFFCURVE",
+"800 1525 CURVE SMOOTH",
+"675 1525 OFFCURVE",
+"508 1455 OFFCURVE",
+"427 1393 CURVE",
+"413 1156 LINE",
+"508 1235 OFFCURVE",
+"621 1282 OFFCURVE",
+"721 1282 CURVE SMOOTH",
+"811 1282 OFFCURVE",
+"846 1238 OFFCURVE",
+"846 1189 CURVE SMOOTH",
+"846 1109 OFFCURVE",
+"760 1086 OFFCURVE",
+"650 956 CURVE SMOOTH",
+"564 855 OFFCURVE",
+"490 703 OFFCURVE",
+"438 495 CURVE",
+"703 495 LINE"
+);
+},
+{
+closed = 1;
+nodes = (
+"306 35 OFFCURVE",
+"367 -25 OFFCURVE",
+"453 -25 CURVE SMOOTH",
+"571 -25 OFFCURVE",
+"666 71 OFFCURVE",
+"666 181 CURVE SMOOTH",
+"666 261 OFFCURVE",
+"607 322 OFFCURVE",
+"520 322 CURVE SMOOTH",
+"403 322 OFFCURVE",
+"306 226 OFFCURVE",
+"306 116 CURVE SMOOTH"
+);
+}
+);
+width = 1070;
+}
+);
+unicode = 003F;
+},
+{
+glyphname = AtSgn;
+layers = (
+{
+layerId = master01;
+paths = (
+{
+closed = 1;
+nodes = (
+"980 -69 OFFCURVE",
+"889 -93 OFFCURVE",
+"796 -93 CURVE SMOOTH",
+"507 -93 OFFCURVE",
+"301 104 OFFCURVE",
+"301 414 CURVE SMOOTH",
+"301 476 OFFCURVE",
+"309 543 OFFCURVE",
+"327 613 CURVE SMOOTH",
+"425 1003 OFFCURVE",
+"782 1245 OFFCURVE",
+"1110 1245 CURVE SMOOTH",
+"1433 1245 OFFCURVE",
+"1590 1060 OFFCURVE",
+"1590 813 CURVE SMOOTH",
+"1590 760 OFFCURVE",
+"1582 705 OFFCURVE",
+"1568 647 CURVE SMOOTH",
+"1510 413 OFFCURVE",
+"1365 309 OFFCURVE",
+"1297 309 CURVE SMOOTH",
+"1261 309 OFFCURVE",
+"1238 344 OFFCURVE",
+"1238 420 CURVE SMOOTH",
+"1238 468 OFFCURVE",
+"1247 533 OFFCURVE",
+"1268 617 CURVE SMOOTH",
+"1354 960 LINE",
+"1276 995 OFFCURVE",
+"1155 1019 OFFCURVE",
+"1074 1019 CURVE SMOOTH",
+"910 1019 OFFCURVE",
+"790 962 OFFCURVE",
+"673 828 CURVE SMOOTH",
+"607 751 OFFCURVE",
+"554 650 OFFCURVE",
+"524 529 CURVE SMOOTH",
+"514 488 OFFCURVE",
+"509 450 OFFCURVE",
+"509 416 CURVE SMOOTH",
+"509 259 OFFCURVE",
+"609 179 OFFCURVE",
+"719 179 CURVE SMOOTH",
+"836 179 OFFCURVE",
+"1017 359 OFFCURVE",
+"1099 480 CURVE",
+"1093 446 OFFCURVE",
+"1089 413 OFFCURVE",
+"1089 382 CURVE SMOOTH",
+"1089 264 OFFCURVE",
+"1136 176 OFFCURVE",
+"1233 176 CURVE SMOOTH",
+"1408 176 OFFCURVE",
+"1635 331 OFFCURVE",
+"1716 656 CURVE SMOOTH",
+"1732 722 OFFCURVE",
+"1740 784 OFFCURVE",
+"1740 843 CURVE SMOOTH",
+"1740 1161 OFFCURVE",
+"1513 1377 OFFCURVE",
+"1153 1377 CURVE SMOOTH",
+"738 1377 OFFCURVE",
+"310 1143 OFFCURVE",
+"175 603 CURVE SMOOTH",
+"155 522 OFFCURVE",
+"145 446 OFFCURVE",
+"145 375 CURVE SMOOTH",
+"145 -5 OFFCURVE",
+"417 -230 OFFCURVE",
+"747 -230 CURVE SMOOTH",
+"882 -230 OFFCURVE",
+"1044 -184 OFFCURVE",
+"1161 -116 CURVE",
+"1082 -10 LINE"
+);
+},
+{
+closed = 1;
+nodes = (
+"1075 570 OFFCURVE",
+"856 314 OFFCURVE",
+"766 314 CURVE SMOOTH",
+"712 314 OFFCURVE",
+"669 362 OFFCURVE",
+"669 459 CURVE SMOOTH",
+"669 491 OFFCURVE",
+"674 530 OFFCURVE",
+"685 573 CURVE SMOOTH",
+"704 649 OFFCURVE",
+"739 726 OFFCURVE",
+"780 774 CURVE SMOOTH",
+"859 868 OFFCURVE",
+"943 887 OFFCURVE",
+"1011 887 CURVE SMOOTH",
+"1085 887 OFFCURVE",
+"1148 868 OFFCURVE",
+"1177 853 CURVE",
+"1141 706 LINE"
+);
+}
+);
+width = 1682;
+},
+{
+layerId = master02;
+paths = (
+{
+closed = 1;
+nodes = (
+"1008 -34 OFFCURVE",
+"933 -59 OFFCURVE",
+"840 -59 CURVE SMOOTH",
+"540 -59 OFFCURVE",
+"362 143 OFFCURVE",
+"362 434 CURVE SMOOTH",
+"362 498 OFFCURVE",
+"371 567 OFFCURVE",
+"389 639 CURVE SMOOTH",
+"480 1003 OFFCURVE",
+"783 1228 OFFCURVE",
+"1121 1228 CURVE SMOOTH",
+"1424 1228 OFFCURVE",
+"1581 1069 OFFCURVE",
+"1581 813 CURVE SMOOTH",
+"1581 753 OFFCURVE",
+"1572 688 OFFCURVE",
+"1555 619 CURVE SMOOTH",
+"1506 418 OFFCURVE",
+"1400 331 OFFCURVE",
+"1340 331 CURVE SMOOTH",
+"1307 331 OFFCURVE",
+"1287 362 OFFCURVE",
+"1287 432 CURVE SMOOTH",
+"1287 482 OFFCURVE",
+"1297 551 OFFCURVE",
+"1320 643 CURVE SMOOTH",
+"1401 970 LINE",
+"1323 1005 OFFCURVE",
+"1182 1030 OFFCURVE",
+"1101 1030 CURVE SMOOTH",
+"937 1030 OFFCURVE",
+"822 974 OFFCURVE",
+"710 862 CURVE SMOOTH",
+"637 789 OFFCURVE",
+"569 677 OFFCURVE",
+"539 556 CURVE SMOOTH",
+"529 518 OFFCURVE",
+"525 481 OFFCURVE",
+"525 447 CURVE SMOOTH",
+"525 279 OFFCURVE",
+"629 161 OFFCURVE",
+"740 161 CURVE SMOOTH",
+"867 161 OFFCURVE",
+"1034 328 OFFCURVE",
+"1117 450 CURVE",
+"1112 422 OFFCURVE",
+"1110 394 OFFCURVE",
+"1110 367 CURVE SMOOTH",
+"1110 252 OFFCURVE",
+"1157 155 OFFCURVE",
+"1291 155 CURVE SMOOTH",
+"1454 155 OFFCURVE",
+"1674 332 OFFCURVE",
+"1752 646 CURVE SMOOTH",
+"1768 710 OFFCURVE",
+"1775 771 OFFCURVE",
+"1775 829 CURVE SMOOTH",
+"1775 1169 OFFCURVE",
+"1520 1411 OFFCURVE",
+"1156 1411 CURVE SMOOTH",
+"731 1411 OFFCURVE",
+"322 1180 OFFCURVE",
+"183 624 CURVE SMOOTH",
+"163 544 OFFCURVE",
+"154 469 OFFCURVE",
+"154 398 CURVE SMOOTH",
+"154 -1 OFFCURVE",
+"448 -243 OFFCURVE",
+"789 -243 CURVE SMOOTH",
+"924 -243 OFFCURVE",
+"1076 -206 OFFCURVE",
+"1193 -137 CURVE",
+"1082 10 LINE"
+);
+},
+{
+closed = 1;
+nodes = (
+"1069 566 OFFCURVE",
+"899 346 OFFCURVE",
+"809 346 CURVE SMOOTH",
+"757 346 OFFCURVE",
+"726 386 OFFCURVE",
+"726 463 CURVE SMOOTH",
+"726 493 OFFCURVE",
+"731 528 OFFCURVE",
+"741 569 CURVE SMOOTH",
+"760 645 OFFCURVE",
+"803 731 OFFCURVE",
+"853 778 CURVE SMOOTH",
+"901 824 OFFCURVE",
+"957 846 OFFCURVE",
+"1025 846 CURVE SMOOTH",
+"1099 846 OFFCURVE",
+"1133 828 OFFCURVE",
+"1162 812 CURVE",
+"1135 703 LINE"
+);
+}
+);
+width = 1693;
+}
+);
+unicode = 0040;
+},
+{
+glyphname = LtnCapA;
+layers = (
+{
+anchors = (
+{
+name = H;
+position = "{1170, 0}";
+},
+{
+name = L;
+position = "{602, -100}";
+},
+{
+name = O;
+position = "{1390, 0}";
+},
+{
+name = U;
+position = "{1009, 1530}";
+}
+);
+layerId = master01;
+paths = (
+{
+closed = 1;
+nodes = (
+"1275 0 LINE",
+"1259 78 OFFCURVE",
+"1243 166 OFFCURVE",
+"1221 348 CURVE SMOOTH",
+"1091 1431 LINE",
+"876 1431 LINE",
+"206 348 LINE SMOOTH",
+"93 165 OFFCURVE",
+"35 79 OFFCURVE",
+"-20 0 CURVE",
+"195 0 LINE",
+"422 377 LINE",
+"1038 377 LINE",
+"1080 0 LINE"
+);
+},
+{
+closed = 1;
+nodes = (
+"1022 529 LINE",
+"514 529 LINE",
+"944 1240 LINE"
+);
+}
+);
+width = 1395;
+},
+{
+anchors = (
+{
+name = H;
+position = "{1215, 0}";
+},
+{
+name = L;
+position = "{647, -100}";
+},
+{
+name = O;
+position = "{1435, 0}";
+},
+{
+name = U;
+position = "{1054, 1530}";
+}
+);
+layerId = master02;
+paths = (
+{
+closed = 1;
+nodes = (
+"1338 0 LINE",
+"1322 79 OFFCURVE",
+"1312 166 OFFCURVE",
+"1295 351 CURVE SMOOTH",
+"1198 1445 LINE",
+"842 1445 LINE",
+"199 351 LINE SMOOTH",
+"89 164 OFFCURVE",
+"37 80 OFFCURVE",
+"-18 0 CURVE",
+"290 0 LINE",
+"487 351 LINE",
+"1031 351 LINE",
+"1055 0 LINE"
+);
+},
+{
+closed = 1;
+nodes = (
+"1016 564 LINE",
+"606 564 LINE",
+"973 1216 LINE"
+);
+}
+);
+width = 1465;
+}
+);
+unicode = 0041;
+},
+{
+glyphname = LtnCapB;
+layers = (
+{
+anchors = (
+{
+name = L;
+position = "{530, -100}";
+},
+{
+name = U;
+position = "{937, 1530}";
+}
+);
+layerId = master01;
+paths = (
+{
+closed = 1;
+nodes = (
+"667 1286 OFFCURVE",
+"733 1289 OFFCURVE",
+"811 1289 CURVE SMOOTH",
+"993 1289 OFFCURVE",
+"1080 1230 OFFCURVE",
+"1080 1105 CURVE SMOOTH",
+"1080 932 OFFCURVE",
+"931 838 OFFCURVE",
+"698 838 CURVE SMOOTH",
+"513 838 LINE",
+"625 1284 LINE"
+);
+},
+{
+closed = 1;
+nodes = (
+"178 252 OFFCURVE",
+"134 78 OFFCURVE",
+"100 0 CURVE",
+"151 -5 OFFCURVE",
+"359 -10 OFFCURVE",
+"562 -10 CURVE SMOOTH",
+"960 -10 OFFCURVE",
+"1201 149 OFFCURVE",
+"1201 453 CURVE SMOOTH",
+"1201 644 OFFCURVE",
+"1067 736 OFFCURVE",
+"955 764 CURVE",
+"1155 819 OFFCURVE",
+"1283 941 OFFCURVE",
+"1283 1140 CURVE SMOOTH",
+"1283 1310 OFFCURVE",
+"1136 1441 OFFCURVE",
+"869 1441 CURVE SMOOTH",
+"700 1441 OFFCURVE",
+"546 1437 OFFCURVE",
+"456 1431 CURVE",
+"452 1352 OFFCURVE",
+"407 1172 OFFCURVE",
+"359 980 CURVE SMOOTH",
+"226 446 LINE"
+);
+},
+{
+closed = 1;
+nodes = (
+"721 686 LINE SMOOTH",
+"892 686 OFFCURVE",
+"1011 598 OFFCURVE",
+"1011 450 CURVE SMOOTH",
+"1011 218 OFFCURVE",
+"806 147 OFFCURVE",
+"586 147 CURVE SMOOTH",
+"474 147 OFFCURVE",
+"379 150 OFFCURVE",
+"342 152 CURVE",
+"476 686 LINE"
+);
+}
+);
+width = 1271;
+},
+{
+anchors = (
+{
+name = L;
+position = "{585, -100}";
+},
+{
+name = U;
+position = "{992, 1530}";
+}
+);
+layerId = master02;
+paths = (
+{
+closed = 1;
+nodes = (
+"735 1237 OFFCURVE",
+"791 1240 OFFCURVE",
+"860 1240 CURVE SMOOTH",
+"1021 1240 OFFCURVE",
+"1101 1179 OFFCURVE",
+"1101 1087 CURVE SMOOTH",
+"1101 932 OFFCURVE",
+"962 866 OFFCURVE",
+"770 866 CURVE SMOOTH",
+"605 866 LINE",
+"698 1236 LINE"
+);
+},
+{
+closed = 1;
+nodes = (
+"168 254 OFFCURVE",
+"124 79 OFFCURVE",
+"90 0 CURVE",
+"161 -3 OFFCURVE",
+"368 -10 OFFCURVE",
+"598 -10 CURVE SMOOTH",
+"1055 -10 OFFCURVE",
+"1298 206 OFFCURVE",
+"1298 508 CURVE SMOOTH",
+"1298 673 OFFCURVE",
+"1188 759 OFFCURVE",
+"1072 792 CURVE",
+"1254 848 OFFCURVE",
+"1388 956 OFFCURVE",
+"1388 1155 CURVE SMOOTH",
+"1388 1359 OFFCURVE",
+"1181 1455 OFFCURVE",
+"897 1455 CURVE SMOOTH",
+"704 1455 OFFCURVE",
+"549 1451 OFFCURVE",
+"450 1445 CURVE",
+"445 1366 OFFCURVE",
+"399 1182 OFFCURVE",
+"351 990 CURVE SMOOTH",
+"217 450 LINE"
+);
+},
+{
+closed = 1;
+nodes = (
+"745 651 LINE SMOOTH",
+"927 651 OFFCURVE",
+"1019 577 OFFCURVE",
+"1019 468 CURVE SMOOTH",
+"1019 295 OFFCURVE",
+"879 213 OFFCURVE",
+"675 213 CURVE SMOOTH",
+"575 213 OFFCURVE",
+"476 216 OFFCURVE",
+"444 218 CURVE",
+"552 651 LINE"
+);
+}
+);
+width = 1367;
+}
+);
+unicode = 0042;
+},
+{
+glyphname = LtnCapC;
+layers = (
+{
+anchors = (
+{
+name = H;
+position = "{690, 0}";
+},
+{
+name = L;
+position = "{665, -100}";
+},
+{
+name = U;
+position = "{1072, 1530}";
+}
+);
+layerId = master01;
+paths = (
+{
+closed = 1;
+nodes = (
+"1115 222 OFFCURVE",
+"934 147 OFFCURVE",
+"752 147 CURVE SMOOTH",
+"537 147 OFFCURVE",
+"385 304 OFFCURVE",
+"385 532 CURVE SMOOTH",
+"385 964 OFFCURVE",
+"704 1289 OFFCURVE",
+"1037 1289 CURVE SMOOTH",
+"1168 1289 OFFCURVE",
+"1310 1235 OFFCURVE",
+"1385 1132 CURVE",
+"1489 1308 LINE",
+"1388 1408 OFFCURVE",
+"1201 1455 OFFCURVE",
+"1058 1455 CURVE SMOOTH",
+"645 1455 OFFCURVE",
+"185 1093 OFFCURVE",
+"185 513 CURVE SMOOTH",
+"185 202 OFFCURVE",
+"381 -25 OFFCURVE",
+"709 -25 CURVE SMOOTH",
+"896 -25 OFFCURVE",
+"1087 21 OFFCURVE",
+"1230 127 CURVE",
+"1237 318 LINE"
+);
+}
+);
+width = 1341;
+},
+{
+anchors = (
+{
+name = H;
+position = "{685, 0}";
+},
+{
+name = L;
+position = "{660, -100}";
+},
+{
+name = U;
+position = "{1067, 1530}";
+}
+);
+layerId = master02;
+paths = (
+{
+closed = 1;
+nodes = (
+"1149 280 OFFCURVE",
+"966 218 OFFCURVE",
+"816 218 CURVE SMOOTH",
+"594 218 OFFCURVE",
+"472 349 OFFCURVE",
+"472 588 CURVE SMOOTH",
+"472 922 OFFCURVE",
+"690 1230 OFFCURVE",
+"1039 1230 CURVE SMOOTH",
+"1170 1230 OFFCURVE",
+"1298 1188 OFFCURVE",
+"1385 1093 CURVE",
+"1515 1331 LINE",
+"1408 1418 OFFCURVE",
+"1247 1470 OFFCURVE",
+"1073 1470 CURVE SMOOTH",
+"545 1470 OFFCURVE",
+"191 1032 OFFCURVE",
+"191 544 CURVE SMOOTH",
+"191 210 OFFCURVE",
+"404 -25 OFFCURVE",
+"750 -25 CURVE SMOOTH",
+"921 -25 OFFCURVE",
+"1124 27 OFFCURVE",
+"1271 124 CURVE",
+"1286 391 LINE"
+);
+}
+);
+width = 1357;
+}
+);
+unicode = 0043;
+},
+{
+glyphname = LtnCapD;
+layers = (
+{
+anchors = (
+{
+name = L;
+position = "{630, -100}";
+},
+{
+name = U;
+position = "{1037, 1530}";
+}
+);
+layerId = master01;
+paths = (
+{
+closed = 1;
+nodes = (
+"176 252 OFFCURVE",
+"134 78 OFFCURVE",
+"100 0 CURVE",
+"100 0 OFFCURVE",
+"414 -10 OFFCURVE",
+"542 -10 CURVE SMOOTH",
+"985 -10 OFFCURVE",
+"1299 181 OFFCURVE",
+"1415 648 CURVE SMOOTH",
+"1437 738 OFFCURVE",
+"1447 819 OFFCURVE",
+"1447 891 CURVE SMOOTH",
+"1447 1279 OFFCURVE",
+"1188 1441 OFFCURVE",
+"894 1441 CURVE SMOOTH",
+"759 1441 OFFCURVE",
+"543 1437 OFFCURVE",
+"456 1431 CURVE",
+"452 1352 OFFCURVE",
+"407 1172 OFFCURVE",
+"359 980 CURVE SMOOTH",
+"226 446 LINE"
+);
+},
+{
+closed = 1;
+nodes = (
+"674 1281 OFFCURVE",
+"764 1284 OFFCURVE",
+"830 1284 CURVE SMOOTH",
+"1105 1284 OFFCURVE",
+"1246 1140 OFFCURVE",
+"1246 850 CURVE SMOOTH",
+"1246 784 OFFCURVE",
+"1236 710 OFFCURVE",
+"1216 629 CURVE SMOOTH",
+"1134 300 OFFCURVE",
+"925 152 OFFCURVE",
+"572 152 CURVE SMOOTH",
+"477 152 OFFCURVE",
+"391 158 OFFCURVE",
+"345 162 CURVE",
+"623 1279 LINE"
+);
+}
+);
+width = 1421;
+},
+{
+anchors = (
+{
+name = L;
+position = "{690, -100}";
+},
+{
+name = U;
+position = "{1122, 1530}";
+}
+);
+layerId = master02;
+paths = (
+{
+closed = 1;
+nodes = (
+"167 251 OFFCURVE",
+"124 79 OFFCURVE",
+"90 0 CURVE",
+"90 0 OFFCURVE",
+"431 -10 OFFCURVE",
+"566 -10 CURVE SMOOTH",
+"1036 -10 OFFCURVE",
+"1361 195 OFFCURVE",
+"1471 648 CURVE SMOOTH",
+"1494 742 OFFCURVE",
+"1505 827 OFFCURVE",
+"1505 902 CURVE SMOOTH",
+"1505 1325 OFFCURVE",
+"1172 1455 OFFCURVE",
+"912 1455 CURVE SMOOTH",
+"769 1455 OFFCURVE",
+"540 1451 OFFCURVE",
+"450 1445 CURVE",
+"445 1371 OFFCURVE",
+"404 1205 OFFCURVE",
+"359 1024 CURVE SMOOTH",
+"217 450 LINE SMOOTH"
+);
+},
+{
+closed = 1;
+nodes = (
+"738 1231 OFFCURVE",
+"809 1234 OFFCURVE",
+"864 1234 CURVE SMOOTH",
+"1077 1234 OFFCURVE",
+"1212 1104 OFFCURVE",
+"1212 871 CURVE SMOOTH",
+"1212 805 OFFCURVE",
+"1201 731 OFFCURVE",
+"1181 647 CURVE SMOOTH",
+"1108 346 OFFCURVE",
+"930 219 OFFCURVE",
+"647 219 CURVE SMOOTH",
+"568 219 OFFCURVE",
+"485 225 OFFCURVE",
+"447 229 CURVE",
+"696 1229 LINE"
+);
+}
+);
+width = 1465;
+}
+);
+unicode = 0044;
+},
+{
+glyphname = LtnCapE;
+layers = (
+{
+anchors = (
+{
+name = H;
+position = "{540, 0}";
+},
+{
+name = L;
+position = "{515, -100}";
+},
+{
+name = O;
+position = "{857, 0}";
+},
+{
+name = R;
+position = "{1400, 1200}";
+},
+{
+name = U;
+position = "{922, 1530}";
+}
+);
+layerId = master01;
+paths = (
+{
+closed = 1;
+nodes = (
+"621 1269 LINE",
+"1266 1269 LINE",
+"1306 1431 LINE",
+"456 1431 LINE",
+"452 1352 OFFCURVE",
+"413 1197 OFFCURVE",
+"365 1005 CURVE SMOOTH",
+"221 426 LINE SMOOTH",
+"173 233 OFFCURVE",
+"134 78 OFFCURVE",
+"100 0 CURVE",
+"980 0 LINE",
+"1023 176 LINE",
+"940 163 OFFCURVE",
+"806 162 OFFCURVE",
+"609 162 CURVE SMOOTH",
+"345 162 LINE",
+"472 671 LINE",
+"1042 671 LINE",
+"1081 828 LINE",
+"511 828 LINE"
+);
+}
+);
+width = 1140;
+},
+{
+anchors = (
+{
+name = H;
+position = "{550, 0}";
+},
+{
+name = L;
+position = "{525, -100}";
+},
+{
+name = O;
+position = "{944, 0}";
+},
+{
+name = R;
+position = "{1487, 1200}";
+},
+{
+name = U;
+position = "{932, 1530}";
+}
+);
+layerId = master02;
+paths = (
+{
+closed = 1;
+nodes = (
+"693 1217 LINE",
+"1315 1217 LINE",
+"1372 1445 LINE",
+"450 1445 LINE",
+"444 1366 OFFCURVE",
+"406 1210 OFFCURVE",
+"358 1015 CURVE SMOOTH",
+"212 431 LINE SMOOTH",
+"163 236 OFFCURVE",
+"123 79 OFFCURVE",
+"90 0 CURVE",
+"1042 0 LINE",
+"1102 243 LINE",
+"1021 229 OFFCURVE",
+"895 228 OFFCURVE",
+"704 228 CURVE SMOOTH",
+"446 228 LINE",
+"550 644 LINE",
+"1097 644 LINE",
+"1152 866 LINE",
+"605 866 LINE"
+);
+}
+);
+width = 1192;
+}
+);
+unicode = 0045;
+},
+{
+glyphname = LtnCapF;
+layers = (
+{
+anchors = (
+{
+name = L;
+position = "{510, -100}";
+},
+{
+name = U;
+position = "{917, 1530}";
+}
+);
+layerId = master01;
+paths = (
+{
+closed = 1;
+nodes = (
+"621 1269 LINE",
+"1286 1269 LINE",
+"1326 1431 LINE",
+"456 1431 LINE",
+"452 1352 OFFCURVE",
+"412 1193 OFFCURVE",
+"364 1000 CURVE SMOOTH",
+"221 426 LINE SMOOTH",
+"173 233 OFFCURVE",
+"134 78 OFFCURVE",
+"100 0 CURVE",
+"320 0 LINE",
+"323 76 OFFCURVE",
+"362 232 OFFCURVE",
+"411 426 CURVE SMOOTH",
+"470 662 LINE",
+"1050 662 LINE",
+"1088 818 LINE",
+"508 818 LINE"
+);
+}
+);
+width = 1130;
+},
+{
+anchors = (
+{
+name = L;
+position = "{545, -100}";
+},
+{
+name = U;
+position = "{952, 1530}";
+}
+);
+layerId = master02;
+paths = (
+{
+closed = 1;
+nodes = (
+"693 1217 LINE",
+"1333 1217 LINE",
+"1390 1445 LINE",
+"450 1445 LINE",
+"445 1366 OFFCURVE",
+"405 1205 OFFCURVE",
+"356 1010 CURVE SMOOTH",
+"212 431 LINE SMOOTH",
+"163 236 OFFCURVE",
+"123 79 OFFCURVE",
+"90 0 CURVE",
+"405 0 LINE",
+"407 72 OFFCURVE",
+"444 220 OFFCURVE",
+"490 404 CURVE SMOOTH",
+"546 629 LINE",
+"1101 629 LINE",
+"1157 851 LINE",
+"602 851 LINE"
+);
+}
+);
+width = 1180;
+}
+);
+unicode = 0046;
+},
+{
+glyphname = LtnCapG;
+layers = (
+{
+anchors = (
+{
+name = H;
+position = "{685, 0}";
+},
+{
+name = L;
+position = "{660, -100}";
+},
+{
+name = U;
+position = "{1067, 1530}";
+}
+);
+layerId = master01;
+paths = (
+{
+closed = 1;
+nodes = (
+"863 710 LINE",
+"822 548 LINE",
+"1172 548 LINE",
+"1090 220 LINE",
+"1012 176 OFFCURVE",
+"858 147 OFFCURVE",
+"739 147 CURVE SMOOTH",
+"520 147 OFFCURVE",
+"384 272 OFFCURVE",
+"384 493 CURVE SMOOTH",
+"384 560 OFFCURVE",
+"394 636 OFFCURVE",
+"415 720 CURVE SMOOTH",
+"500 1062 OFFCURVE",
+"747 1289 OFFCURVE",
+"1052 1289 CURVE SMOOTH",
+"1195 1289 OFFCURVE",
+"1335 1233 OFFCURVE",
+"1425 1122 CURVE",
+"1534 1298 LINE",
+"1409 1405 OFFCURVE",
+"1235 1455 OFFCURVE",
+"1063 1455 CURVE SMOOTH",
+"680 1455 OFFCURVE",
+"334 1195 OFFCURVE",
+"217 726 CURVE SMOOTH",
+"195 639 OFFCURVE",
+"185 559 OFFCURVE",
+"185 486 CURVE SMOOTH",
+"185 162 OFFCURVE",
+"406 -25 OFFCURVE",
+"714 -25 CURVE SMOOTH",
+"907 -25 OFFCURVE",
+"1149 50 OFFCURVE",
+"1258 132 CURVE",
+"1403 710 LINE"
+);
+}
+);
+width = 1406;
+},
+{
+anchors = (
+{
+name = H;
+position = "{747, 0}";
+},
+{
+name = L;
+position = "{722, -100}";
+},
+{
+name = U;
+position = "{1129, 1530}";
+}
+);
+layerId = master02;
+paths = (
+{
+closed = 1;
+nodes = (
+"910 767 LINE",
+"855 544 LINE",
+"1170 544 LINE",
+"1104 271 LINE",
+"1015 231 OFFCURVE",
+"916 218 OFFCURVE",
+"805 218 CURVE SMOOTH",
+"593 218 OFFCURVE",
+"475 352 OFFCURVE",
+"475 567 CURVE SMOOTH",
+"475 633 OFFCURVE",
+"484 708 OFFCURVE",
+"505 789 CURVE SMOOTH",
+"581 1079 OFFCURVE",
+"802 1230 OFFCURVE",
+"1067 1230 CURVE SMOOTH",
+"1220 1230 OFFCURVE",
+"1334 1193 OFFCURVE",
+"1449 1096 CURVE",
+"1594 1332 LINE",
+"1447 1437 OFFCURVE",
+"1275 1470 OFFCURVE",
+"1094 1470 CURVE SMOOTH",
+"709 1470 OFFCURVE",
+"345 1257 OFFCURVE",
+"227 783 CURVE SMOOTH",
+"205 694 OFFCURVE",
+"194 611 OFFCURVE",
+"194 534 CURVE SMOOTH",
+"194 176 OFFCURVE",
+"419 -25 OFFCURVE",
+"768 -25 CURVE SMOOTH",
+"940 -25 OFFCURVE",
+"1105 10 OFFCURVE",
+"1325 133 CURVE",
+"1480 767 LINE"
+);
+}
+);
+width = 1452;
+}
+);
+unicode = 0047;
+},
+{
+glyphname = LtnCapH;
+layers = (
+{
+anchors = (
+{
+name = H;
+position = "{225, 0}";
+},
+{
+name = L;
+position = "{640, -100}";
+},
+{
+name = U;
+position = "{1047, 1530}";
+}
+);
+layerId = master01;
+paths = (
+{
+closed = 1;
+nodes = (
+"1234 78 OFFCURVE",
+"1273 233 OFFCURVE",
+"1321 426 CURVE SMOOTH",
+"1465 1005 LINE SMOOTH",
+"1513 1198 OFFCURVE",
+"1552 1352 OFFCURVE",
+"1586 1431 CURVE",
+"1381 1431 LINE",
+"1228 818 LINE",
+"508 818 LINE",
+"661 1431 LINE",
+"456 1431 LINE",
+"452 1352 OFFCURVE",
+"413 1197 OFFCURVE",
+"365 1005 CURVE SMOOTH",
+"221 426 LINE SMOOTH",
+"173 233 OFFCURVE",
+"134 78 OFFCURVE",
+"100 0 CURVE",
+"305 0 LINE",
+"470 662 LINE",
+"1190 662 LINE",
+"1025 0 LINE",
+"1230 0 LINE"
+);
+}
+);
+width = 1455;
+},
+{
+anchors = (
+{
+name = H;
+position = "{245, 0}";
+},
+{
+name = L;
+position = "{660, -100}";
+},
+{
+name = U;
+position = "{1067, 1530}";
+}
+);
+layerId = master02;
+paths = (
+{
+closed = 1;
+nodes = (
+"1192 851 LINE",
+"602 851 LINE",
+"750 1445 LINE",
+"450 1445 LINE",
+"445 1366 OFFCURVE",
+"408 1215 OFFCURVE",
+"359 1020 CURVE SMOOTH",
+"211 426 LINE SMOOTH",
+"162 231 OFFCURVE",
+"124 79 OFFCURVE",
+"90 0 CURVE",
+"90 0 OFFCURVE",
+"390 0 OFFCURVE",
+"390 0 CURVE",
+"546 629 LINE",
+"1136 629 LINE",
+"980 0 LINE",
+"980 0 OFFCURVE",
+"1280 0 OFFCURVE",
+"1280 0 CURVE",
+"1284 79 OFFCURVE",
+"1322 231 OFFCURVE",
+"1371 426 CURVE SMOOTH",
+"1519 1020 LINE SMOOTH",
+"1567 1215 OFFCURVE",
+"1605 1366 OFFCURVE",
+"1640 1445 CURVE",
+"1340 1445 LINE"
+);
+}
+);
+width = 1495;
+}
+);
+unicode = 0048;
+},
+{
+glyphname = LtnCapI;
+layers = (
+{
+anchors = (
+{
+name = H;
+position = "{417, 0}";
+},
+{
+name = L;
+position = "{392, -100}";
+},
+{
+name = O;
+position = "{613, 0}";
+},
+{
+name = R;
+position = "{1215, 1200}";
+},
+{
+name = U;
+position = "{799, 1530}";
+}
+);
+layerId = master01;
+paths = (
+{
+closed = 1;
+nodes = (
+"401 1289 LINE",
+"641 1289 LINE",
+"355 142 LINE",
+"115 142 LINE",
+"80 0 LINE",
+"755 0 LINE",
+"790 142 LINE",
+"545 142 LINE",
+"831 1289 LINE",
+"1076 1289 LINE",
+"1111 1431 LINE",
+"436 1431 LINE"
+);
+}
+);
+width = 955;
+},
+{
+anchors = (
+{
+name = H;
+position = "{460, 0}";
+},
+{
+name = L;
+position = "{431, -100}";
+},
+{
+name = O;
+position = "{652, 0}";
+},
+{
+name = R;
+position = "{1254, 1200}";
+},
+{
+name = U;
+position = "{842, 1530}";
+}
+);
+layerId = master02;
+paths = (
+{
+closed = 1;
+nodes = (
+"379 1242 LINE",
+"619 1242 LINE",
+"360 203 LINE",
+"120 203 LINE",
+"70 0 LINE",
+"835 0 LINE",
+"885 203 LINE",
+"645 203 LINE",
+"904 1242 LINE",
+"1144 1242 LINE",
+"1195 1445 LINE",
+"430 1445 LINE"
+);
+}
+);
+width = 1025;
+}
+);
+unicode = 0049;
+},
+{
+glyphname = LtnCapJ;
+layers = (
+{
+anchors = (
+{
+name = L;
+position = "{325, -100}";
+},
+{
+name = U;
+position = "{997, 1530}";
+}
+);
+layerId = master01;
+paths = (
+{
+closed = 1;
+nodes = (
+"858 1327 OFFCURVE",
+"817 1151 OFFCURVE",
+"769 960 CURVE SMOOTH",
+"648 475 LINE SMOOTH",
+"592 251 OFFCURVE",
+"484 152 OFFCURVE",
+"337 152 CURVE SMOOTH",
+"245 152 OFFCURVE",
+"145 224 OFFCURVE",
+"97 299 CURVE",
+"6 118 LINE",
+"58 39 OFFCURVE",
+"193 -25 OFFCURVE",
+"298 -25 CURVE SMOOTH",
+"555 -25 OFFCURVE",
+"749 117 OFFCURVE",
+"850 524 CURVE SMOOTH",
+"1076 1431 LINE",
+"871 1431 LINE"
+);
+}
+);
+width = 996;
+},
+{
+anchors = (
+{
+name = L;
+position = "{330, -100}";
+},
+{
+name = U;
+position = "{1027, 1530}";
+}
+);
+layerId = master02;
+paths = (
+{
+closed = 1;
+nodes = (
+"842 1340 OFFCURVE",
+"799 1163 OFFCURVE",
+"751 970 CURVE SMOOTH",
+"647 552 LINE SMOOTH",
+"602 370 OFFCURVE",
+"516 225 OFFCURVE",
+"341 225 CURVE SMOOTH",
+"260 225 OFFCURVE",
+"159 267 OFFCURVE",
+"104 344 CURVE",
+"-8 89 LINE",
+"51 19 OFFCURVE",
+"191 -25 OFFCURVE",
+"326 -25 CURVE SMOOTH",
+"611 -25 OFFCURVE",
+"826 128 OFFCURVE",
+"927 530 CURVE SMOOTH",
+"947 612 OFFCURVE",
+"1155 1445 OFFCURVE",
+"1155 1445 CURVE",
+"855 1445 LINE"
+);
+}
+);
+width = 1010;
+}
+);
+unicode = 004A;
+},
+{
+glyphname = LtnCapK;
+layers = (
+{
+anchors = (
+{
+name = H;
+position = "{210, 0}";
+},
+{
+name = L;
+position = "{610, -100}";
+},
+{
+name = U;
+position = "{972, 1530}";
+}
+);
+layerId = master01;
+paths = (
+{
+closed = 1;
+nodes = (
+"406 689 LINE",
+"547 730 LINE",
+"660 725 LINE",
+"1461 1431 LINE",
+"1221 1431 LINE"
+);
+},
+{
+closed = 1;
+nodes = (
+"615 823 LINE",
+"469 720 LINE",
+"925 0 LINE",
+"1170 0 LINE"
+);
+},
+{
+closed = 1;
+nodes = (
+"456 1431 LINE",
+"452 1352 OFFCURVE",
+"413 1197 OFFCURVE",
+"365 1005 CURVE SMOOTH",
+"221 426 LINE SMOOTH",
+"173 233 OFFCURVE",
+"134 78 OFFCURVE",
+"100 0 CURVE",
+"305 0 LINE",
+"661 1431 LINE"
+);
+}
+);
+width = 1261;
+},
+{
+anchors = (
+{
+name = H;
+position = "{260, 0}";
+},
+{
+name = L;
+position = "{655, -100}";
+},
+{
+name = U;
+position = "{1047, 1530}";
+}
+);
+layerId = master02;
+paths = (
+{
+closed = 1;
+nodes = (
+"450 1445 LINE",
+"444 1366 OFFCURVE",
+"406 1210 OFFCURVE",
+"358 1015 CURVE SMOOTH",
+"212 431 LINE SMOOTH",
+"163 236 OFFCURVE",
+"123 79 OFFCURVE",
+"90 0 CURVE",
+"390 0 LINE",
+"750 1445 LINE"
+);
+},
+{
+closed = 1;
+nodes = (
+"461 697 LINE",
+"634 738 LINE",
+"758 724 LINE",
+"1580 1445 LINE",
+"1244 1445 LINE"
+);
+},
+{
+closed = 1;
+nodes = (
+"950 0 LINE",
+"1300 0 LINE",
+"738 801 LINE",
+"509 724 LINE"
+);
+}
+);
+width = 1410;
+}
+);
+unicode = 004B;
+},
+{
+glyphname = LtnCapL;
+layers = (
+{
+anchors = (
+{
+name = H;
+position = "{532, 0}";
+},
+{
+name = L;
+position = "{507, -100}";
+},
+{
+name = R;
+position = "{780, 1200}";
+},
+{
+name = U;
+position = "{914, 1530}";
+}
+);
+layerId = master01;
+paths = (
+{
+closed = 1;
+nodes = (
+"661 1431 LINE",
+"456 1431 LINE",
+"452 1352 OFFCURVE",
+"413 1197 OFFCURVE",
+"365 1005 CURVE SMOOTH",
+"221 426 LINE SMOOTH",
+"173 233 OFFCURVE",
+"134 78 OFFCURVE",
+"100 0 CURVE",
+"965 0 LINE",
+"1008 176 LINE",
+"925 163 OFFCURVE",
+"766 162 OFFCURVE",
+"569 162 CURVE SMOOTH",
+"345 162 LINE"
+);
+}
+);
+width = 1060;
+},
+{
+anchors = (
+{
+name = H;
+position = "{560, 0}";
+},
+{
+name = L;
+position = "{535, -100}";
+},
+{
+name = R;
+position = "{890, 1200}";
+},
+{
+name = U;
+position = "{942, 1530}";
+}
+);
+layerId = master02;
+paths = (
+{
+closed = 1;
+nodes = (
+"750 1445 LINE",
+"450 1445 LINE",
+"444 1366 OFFCURVE",
+"406 1210 OFFCURVE",
+"358 1015 CURVE SMOOTH",
+"212 431 LINE SMOOTH",
+"163 236 OFFCURVE",
+"123 79 OFFCURVE",
+"90 0 CURVE",
+"1025 0 LINE",
+"1085 243 LINE",
+"1005 229 OFFCURVE",
+"851 228 OFFCURVE",
+"662 228 CURVE SMOOTH",
+"446 228 LINE"
+);
+}
+);
+width = 1110;
+}
+);
+unicode = 004C;
+},
+{
+glyphname = LtnCapM;
+layers = (
+{
+anchors = (
+{
+name = L;
+position = "{800, -100}";
+},
+{
+name = U;
+position = "{1207, 1530}";
+}
+);
+layerId = master01;
+paths = (
+{
+closed = 1;
+nodes = (
+"751 1431 LINE",
+"591 1431 LINE",
+"740 0 LINE",
+"935 0 LINE",
+"1793 1431 LINE",
+"1616 1431 LINE",
+"880 201 LINE"
+);
+},
+{
+closed = 1;
+nodes = (
+"536 1431 OFFCURVE",
+"184 194 OFFCURVE",
+"110 0 CURVE",
+"295 0 LINE",
+"621 1181 LINE",
+"711 1431 LINE",
+"536 1431 LINE"
+);
+},
+{
+closed = 1;
+nodes = (
+"1579 194 OFFCURVE",
+"1846 1431 OFFCURVE",
+"1846 1431 CURVE",
+"1671 1431 LINE",
+"1641 1181 LINE",
+"1375 0 LINE",
+"1560 0 LINE"
+);
+}
+);
+width = 1785;
+},
+{
+anchors = (
+{
+name = L;
+position = "{830, -100}";
+},
+{
+name = U;
+position = "{1237, 1530}";
+}
+);
+layerId = master02;
+paths = (
+{
+closed = 1;
+nodes = (
+"865 1445 LINE",
+"615 1445 LINE",
+"664 1158 LINE",
+"710 0 LINE",
+"1005 0 LINE",
+"1625 1158 LINE",
+"1817 1445 LINE",
+"1550 1445 LINE",
+"919 272 LINE"
+);
+},
+{
+closed = 1;
+nodes = (
+"520 1445 OFFCURVE",
+"164 196 OFFCURVE",
+"90 0 CURVE",
+"360 0 LINE",
+"686 1193 LINE",
+"785 1445 LINE",
+"520 1445 LINE"
+);
+},
+{
+closed = 1;
+nodes = (
+"1649 196 OFFCURVE",
+"1910 1445 OFFCURVE",
+"1910 1445 CURVE",
+"1640 1445 LINE",
+"1622 1193 LINE",
+"1360 0 LINE",
+"1630 0 LINE"
+);
+}
+);
+width = 1835;
+}
+);
+unicode = 004D;
+},
+{
+glyphname = LtnCapN;
+layers = (
+{
+anchors = (
+{
+name = H;
+position = "{1170, 0}";
+},
+{
+name = L;
+position = "{652, -100}";
+},
+{
+name = U;
+position = "{1059, 1530}";
+}
+);
+layerId = master01;
+paths = (
+{
+closed = 1;
+nodes = (
+"1075 0 LINE",
+"1219 98 LINE",
+"636 1431 LINE",
+"491 1328 LINE"
+);
+},
+{
+closed = 1;
+nodes = (
+"1250 0 LINE",
+"1500 1005 LINE SMOOTH",
+"1548 1198 OFFCURVE",
+"1588 1352 OFFCURVE",
+"1621 1431 CURVE",
+"1431 1431 LINE",
+"1075 0 LINE"
+);
+},
+{
+closed = 1;
+nodes = (
+"446 1431 LINE",
+"442 1352 OFFCURVE",
+"403 1197 OFFCURVE",
+"355 1005 CURVE SMOOTH",
+"211 426 LINE SMOOTH",
+"163 233 OFFCURVE",
+"124 78 OFFCURVE",
+"90 0 CURVE",
+"280 0 LINE",
+"636 1431 LINE"
+);
+}
+);
+width = 1480;
+},
+{
+anchors = (
+{
+name = H;
+position = "{1180, 0}";
+},
+{
+name = L;
+position = "{680, -100}";
+},
+{
+name = U;
+position = "{1087, 1530}";
+}
+);
+layerId = master02;
+paths = (
+{
+closed = 1;
+nodes = (
+"1035 0 LINE",
+"1253 148 LINE",
+"725 1445 LINE",
+"506 1297 LINE"
+);
+},
+{
+closed = 1;
+nodes = (
+"1305 0 LINE",
+"1558 1015 LINE SMOOTH",
+"1606 1210 OFFCURVE",
+"1646 1366 OFFCURVE",
+"1680 1445 CURVE",
+"1395 1445 LINE",
+"1035 0 LINE"
+);
+},
+{
+closed = 1;
+nodes = (
+"440 1445 LINE",
+"434 1366 OFFCURVE",
+"396 1210 OFFCURVE",
+"348 1015 CURVE SMOOTH",
+"202 431 LINE SMOOTH",
+"153 236 OFFCURVE",
+"113 79 OFFCURVE",
+"80 0 CURVE",
+"365 0 LINE",
+"725 1445 LINE"
+);
+}
+);
+width = 1525;
+}
+);
+unicode = 004E;
+},
+{
+glyphname = LtnCapO;
+layers = (
+{
+anchors = (
+{
+name = H;
+position = "{657, 0}";
+},
+{
+name = L;
+position = "{632, -100}";
+},
+{
+name = O;
+position = "{896, 0}";
+},
+{
+name = R;
+position = "{1700, 1200}";
+},
+{
+name = U;
+position = "{1039, 1530}";
+}
+);
+layerId = master01;
+paths = (
+{
+closed = 1;
+nodes = (
+"514 147 OFFCURVE",
+"386 300 OFFCURVE",
+"386 541 CURVE SMOOTH",
+"386 871 OFFCURVE",
+"606 1284 OFFCURVE",
+"963 1284 CURVE SMOOTH",
+"1164 1284 OFFCURVE",
+"1291 1133 OFFCURVE",
+"1291 892 CURVE SMOOTH",
+"1291 563 OFFCURVE",
+"1077 147 OFFCURVE",
+"719 147 CURVE SMOOTH"
+);
+},
+{
+closed = 1;
+nodes = (
+"1492 1263 OFFCURVE",
+"1278 1455 OFFCURVE",
+"1015 1455 CURVE SMOOTH",
+"599 1455 OFFCURVE",
+"185 1036 OFFCURVE",
+"185 500 CURVE SMOOTH",
+"185 167 OFFCURVE",
+"400 -25 OFFCURVE",
+"666 -25 CURVE SMOOTH",
+"1078 -25 OFFCURVE",
+"1492 395 OFFCURVE",
+"1492 931 CURVE SMOOTH"
+);
+}
+);
+width = 1447;
+},
+{
+anchors = (
+{
+name = H;
+position = "{680, 0}";
+},
+{
+name = L;
+position = "{655, -100}";
+},
+{
+name = O;
+position = "{916, 0}";
+},
+{
+name = R;
+position = "{1720, 1200}";
+},
+{
+name = U;
+position = "{1062, 1530}";
+}
+);
+layerId = master02;
+paths = (
+{
+closed = 1;
+nodes = (
+"580 218 OFFCURVE",
+"471 345 OFFCURVE",
+"471 568 CURVE SMOOTH",
+"471 922 OFFCURVE",
+"664 1228 OFFCURVE",
+"966 1228 CURVE SMOOTH",
+"1134 1228 OFFCURVE",
+"1237 1106 OFFCURVE",
+"1237 891 CURVE SMOOTH",
+"1237 540 OFFCURVE",
+"1060 218 OFFCURVE",
+"754 218 CURVE SMOOTH"
+);
+},
+{
+closed = 1;
+nodes = (
+"1519 1249 OFFCURVE",
+"1350 1470 OFFCURVE",
+"1026 1470 CURVE SMOOTH",
+"510 1470 OFFCURVE",
+"191 1010 OFFCURVE",
+"191 539 CURVE SMOOTH",
+"191 199 OFFCURVE",
+"401 -25 OFFCURVE",
+"693 -25 CURVE SMOOTH",
+"1121 -25 OFFCURVE",
+"1519 337 OFFCURVE",
+"1519 911 CURVE SMOOTH"
+);
+}
+);
+width = 1480;
+}
+);
+unicode = 004F;
+},
+{
+glyphname = LtnCapP;
+layers = (
+{
+anchors = (
+{
+name = L;
+position = "{552, -100}";
+},
+{
+name = U;
+position = "{959, 1530}";
+}
+);
+layerId = master01;
+paths = (
+{
+closed = 1;
+nodes = (
+"506 547 OFFCURVE",
+"597 544 OFFCURVE",
+"670 544 CURVE SMOOTH",
+"1058 544 OFFCURVE",
+"1321 733 OFFCURVE",
+"1321 1084 CURVE SMOOTH",
+"1321 1302 OFFCURVE",
+"1141 1441 OFFCURVE",
+"864 1441 CURVE SMOOTH",
+"651 1441 OFFCURVE",
+"456 1431 OFFCURVE",
+"456 1431 CURVE",
+"452 1352 OFFCURVE",
+"407 1172 OFFCURVE",
+"359 980 CURVE",
+"221 426 LINE SMOOTH",
+"173 233 OFFCURVE",
+"134 78 OFFCURVE",
+"100 0 CURVE",
+"320 0 LINE",
+"324 76 OFFCURVE",
+"362 232 OFFCURVE",
+"411 426 CURVE SMOOTH",
+"443 554 LINE"
+);
+},
+{
+closed = 1;
+nodes = (
+"692 1282 OFFCURVE",
+"721 1284 OFFCURVE",
+"815 1284 CURVE SMOOTH",
+"1036 1284 OFFCURVE",
+"1121 1172 OFFCURVE",
+"1121 1048 CURVE SMOOTH",
+"1121 845 OFFCURVE",
+"968 696 OFFCURVE",
+"693 696 CURVE SMOOTH",
+"618 696 OFFCURVE",
+"542 698 OFFCURVE",
+"481 706 CURVE",
+"623 1279 LINE"
+);
+}
+);
+width = 1190;
+},
+{
+anchors = (
+{
+name = L;
+position = "{600, -100}";
+},
+{
+name = U;
+position = "{970, 1530}";
+}
+);
+layerId = master02;
+paths = (
+{
+closed = 1;
+nodes = (
+"582 511 OFFCURVE",
+"661 508 OFFCURVE",
+"734 508 CURVE SMOOTH",
+"1118 508 OFFCURVE",
+"1393 718 OFFCURVE",
+"1393 1076 CURVE SMOOTH",
+"1393 1306 OFFCURVE",
+"1215 1455 OFFCURVE",
+"940 1455 CURVE SMOOTH",
+"727 1455 OFFCURVE",
+"450 1445 OFFCURVE",
+"450 1445 CURVE",
+"445 1366 OFFCURVE",
+"400 1184 OFFCURVE",
+"351 990 CURVE SMOOTH",
+"212 431 LINE SMOOTH",
+"164 237 OFFCURVE",
+"124 79 OFFCURVE",
+"90 0 CURVE",
+"405 0 LINE",
+"410 77 OFFCURVE",
+"448 235 OFFCURVE",
+"497 431 CURVE SMOOTH",
+"519 518 LINE"
+);
+},
+{
+closed = 1;
+nodes = (
+"752 1231 OFFCURVE",
+"781 1233 OFFCURVE",
+"849 1233 CURVE SMOOTH",
+"1020 1233 OFFCURVE",
+"1103 1135 OFFCURVE",
+"1103 1020 CURVE SMOOTH",
+"1103 827 OFFCURVE",
+"965 723 OFFCURVE",
+"758 723 CURVE SMOOTH",
+"696 723 OFFCURVE",
+"614 726 OFFCURVE",
+"572 733 CURVE",
+"696 1228 LINE"
+);
+}
+);
+width = 1255;
+}
+);
+unicode = 0050;
+},
+{
+glyphname = LtnCapQ;
+layers = (
+{
+anchors = (
+{
+name = L;
+position = "{589, -270}";
+},
+{
+name = U;
+position = "{1039, 1530}";
+}
+);
+layerId = master01;
+paths = (
+{
+closed = 1;
+nodes = (
+"1495 1266 OFFCURVE",
+"1306 1455 OFFCURVE",
+"1026 1455 CURVE SMOOTH",
+"703 1455 OFFCURVE",
+"332 1195 OFFCURVE",
+"215 726 CURVE SMOOTH",
+"194 642 OFFCURVE",
+"185 564 OFFCURVE",
+"185 492 CURVE SMOOTH",
+"185 165 OFFCURVE",
+"388 -25 OFFCURVE",
+"652 -25 CURVE SMOOTH",
+"714 -25 OFFCURVE",
+"781 -17 OFFCURVE",
+"829 0 CURVE",
+"898 0 OFFCURVE",
+"1133 -186 OFFCURVE",
+"1217 -186 CURVE SMOOTH",
+"1271 -186 OFFCURVE",
+"1355 -79 OFFCURVE",
+"1388 -44 CURVE",
+"1258 -27 OFFCURVE",
+"1155 27 OFFCURVE",
+"1049 103 CURVE",
+"1253 217 OFFCURVE",
+"1495 528 OFFCURVE",
+"1495 939 CURVE SMOOTH"
+);
+},
+{
+closed = 1;
+nodes = (
+"492 147 OFFCURVE",
+"384 284 OFFCURVE",
+"384 508 CURVE SMOOTH",
+"384 856 OFFCURVE",
+"609 1284 OFFCURVE",
+"994 1284 CURVE SMOOTH",
+"1188 1284 OFFCURVE",
+"1295 1149 OFFCURVE",
+"1295 925 CURVE SMOOTH",
+"1295 490 OFFCURVE",
+"985 147 OFFCURVE",
+"690 147 CURVE SMOOTH"
+);
+}
+);
+width = 1459;
+},
+{
+anchors = (
+{
+name = L;
+position = "{619, -270}";
+},
+{
+name = U;
+position = "{1069, 1530}";
+}
+);
+layerId = master02;
+paths = (
+{
+closed = 1;
+nodes = (
+"1527 1259 OFFCURVE",
+"1324 1470 OFFCURVE",
+"1029 1470 CURVE SMOOTH",
+"663 1470 OFFCURVE",
+"339 1229 OFFCURVE",
+"221 755 CURVE SMOOTH",
+"201 673 OFFCURVE",
+"191 597 OFFCURVE",
+"191 526 CURVE SMOOTH",
+"191 185 OFFCURVE",
+"410 -25 OFFCURVE",
+"696 -25 CURVE SMOOTH",
+"743 -25 OFFCURVE",
+"787 -23 OFFCURVE",
+"838 -15 CURVE",
+"907 -15 OFFCURVE",
+"1162 -221 OFFCURVE",
+"1246 -221 CURVE SMOOTH",
+"1310 -221 OFFCURVE",
+"1422 -74 OFFCURVE",
+"1468 -22 CURVE",
+"1331 -6 OFFCURVE",
+"1227 60 OFFCURVE",
+"1115 134 CURVE",
+"1312 242 OFFCURVE",
+"1527 566 OFFCURVE",
+"1527 922 CURVE SMOOTH"
+);
+},
+{
+closed = 1;
+nodes = (
+"563 218 OFFCURVE",
+"471 355 OFFCURVE",
+"471 558 CURVE SMOOTH",
+"471 912 OFFCURVE",
+"677 1228 OFFCURVE",
+"969 1228 CURVE SMOOTH",
+"1147 1228 OFFCURVE",
+"1246 1106 OFFCURVE",
+"1246 891 CURVE SMOOTH",
+"1246 560 OFFCURVE",
+"1053 218 OFFCURVE",
+"757 218 CURVE SMOOTH"
+);
+}
+);
+width = 1488;
+}
+);
+unicode = 0051;
+},
+{
+glyphname = LtnCapR;
+layers = (
+{
+anchors = (
+{
+name = H;
+position = "{590, 0}";
+},
+{
+name = L;
+position = "{525, -100}";
+},
+{
+name = U;
+position = "{932, 1530}";
+}
+);
+layerId = master01;
+paths = (
+{
+closed = 1;
+nodes = (
+"712 613 LINE SMOOTH",
+"1010 613 OFFCURVE",
+"1303 784 OFFCURVE",
+"1303 1114 CURVE SMOOTH",
+"1303 1326 OFFCURVE",
+"1114 1441 OFFCURVE",
+"844 1441 CURVE SMOOTH",
+"610 1441 OFFCURVE",
+"456 1431 OFFCURVE",
+"456 1431 CURVE",
+"452 1352 OFFCURVE",
+"407 1172 OFFCURVE",
+"359 980 CURVE SMOOTH",
+"221 426 LINE",
+"173 233 OFFCURVE",
+"134 78 OFFCURVE",
+"100 0 CURVE",
+"320 0 LINE",
+"324 76 OFFCURVE",
+"363 233 OFFCURVE",
+"411 426 CURVE",
+"457 613 LINE"
+);
+},
+{
+closed = 1;
+nodes = (
+"677 1281 OFFCURVE",
+"725 1284 OFFCURVE",
+"795 1284 CURVE SMOOTH",
+"1003 1284 OFFCURVE",
+"1104 1203 OFFCURVE",
+"1104 1076 CURVE SMOOTH",
+"1104 856 OFFCURVE",
+"921 764 OFFCURVE",
+"685 764 CURVE SMOOTH",
+"495 764 LINE",
+"623 1279 LINE"
+);
+},
+{
+closed = 1;
+nodes = (
+"930 0 LINE",
+"1185 0 LINE",
+"1122 89 OFFCURVE",
+"864 602 OFFCURVE",
+"828 676 CURVE",
+"656 622 LINE"
+);
+}
+);
+width = 1295;
+},
+{
+anchors = (
+{
+name = H;
+position = "{630, 0}";
+},
+{
+name = L;
+position = "{605, -100}";
+},
+{
+name = U;
+position = "{982, 1530}";
+}
+);
+layerId = master02;
+paths = (
+{
+closed = 1;
+nodes = (
+"749 579 LINE SMOOTH",
+"1071 579 OFFCURVE",
+"1378 761 OFFCURVE",
+"1378 1117 CURVE SMOOTH",
+"1378 1332 OFFCURVE",
+"1199 1455 OFFCURVE",
+"932 1455 CURVE SMOOTH",
+"698 1455 OFFCURVE",
+"450 1445 OFFCURVE",
+"450 1445 CURVE",
+"445 1366 OFFCURVE",
+"400 1184 OFFCURVE",
+"351 990 CURVE SMOOTH",
+"212 431 LINE",
+"164 236 OFFCURVE",
+"124 79 OFFCURVE",
+"90 0 CURVE",
+"405 0 LINE",
+"410 77 OFFCURVE",
+"448 236 OFFCURVE",
+"497 431 CURVE",
+"534 579 LINE"
+);
+},
+{
+closed = 1;
+nodes = (
+"749 1231 OFFCURVE",
+"764 1233 OFFCURVE",
+"842 1233 CURVE SMOOTH",
+"995 1233 OFFCURVE",
+"1089 1167 OFFCURVE",
+"1089 1060 CURVE SMOOTH",
+"1089 899 OFFCURVE",
+"956 792 OFFCURVE",
+"782 792 CURVE SMOOTH",
+"587 792 LINE",
+"696 1228 LINE"
+);
+},
+{
+closed = 1;
+nodes = (
+"915 0 LINE",
+"1270 0 LINE",
+"1220 72 OFFCURVE",
+"962 623 OFFCURVE",
+"936 680 CURVE",
+"652 629 LINE"
+);
+}
+);
+width = 1360;
+}
+);
+unicode = 0052;
+},
+{
+glyphname = LtnCapS;
+layers = (
+{
+anchors = (
+{
+name = H;
+position = "{520, 0}";
+},
+{
+name = L;
+position = "{495, -100}";
+},
+{
+name = U;
+position = "{902, 1530}";
+}
+);
+layerId = master01;
+paths = (
+{
+closed = 1;
+nodes = (
+"1146 1419 OFFCURVE",
+"1021 1455 OFFCURVE",
+"867 1455 CURVE SMOOTH",
+"549 1455 OFFCURVE",
+"320 1303 OFFCURVE",
+"320 1040 CURVE SMOOTH",
+"320 901 OFFCURVE",
+"438 794 OFFCURVE",
+"622 691 CURVE SMOOTH",
+"877 549 OFFCURVE",
+"914 461 OFFCURVE",
+"914 378 CURVE SMOOTH",
+"914 256 OFFCURVE",
+"792 147 OFFCURVE",
+"621 147 CURVE SMOOTH",
+"473 147 OFFCURVE",
+"278 235 OFFCURVE",
+"161 378 CURVE",
+"65 187 LINE",
+"178 73 OFFCURVE",
+"365 -25 OFFCURVE",
+"558 -25 CURVE SMOOTH",
+"852 -25 OFFCURVE",
+"1114 115 OFFCURVE",
+"1114 414 CURVE SMOOTH",
+"1114 526 OFFCURVE",
+"1057 679 OFFCURVE",
+"800 828 CURVE SMOOTH",
+"597 946 OFFCURVE",
+"510 1005 OFFCURVE",
+"510 1079 CURVE SMOOTH",
+"510 1210 OFFCURVE",
+"659 1284 OFFCURVE",
+"845 1284 CURVE SMOOTH",
+"959 1284 OFFCURVE",
+"1075 1240 OFFCURVE",
+"1173 1156 CURVE",
+"1260 1347 LINE"
+);
+}
+);
+width = 1155;
+},
+{
+anchors = (
+{
+name = H;
+position = "{556, 0}";
+},
+{
+name = L;
+position = "{531, -100}";
+},
+{
+name = U;
+position = "{938, 1530}";
+}
+);
+layerId = master02;
+paths = (
+{
+closed = 1;
+nodes = (
+"1232 1430 OFFCURVE",
+"1086 1470 OFFCURVE",
+"916 1470 CURVE SMOOTH",
+"600 1470 OFFCURVE",
+"332 1333 OFFCURVE",
+"332 1053 CURVE SMOOTH",
+"332 889 OFFCURVE",
+"413 800 OFFCURVE",
+"621 658 CURVE SMOOTH",
+"829 516 OFFCURVE",
+"885 448 OFFCURVE",
+"885 374 CURVE SMOOTH",
+"885 276 OFFCURVE",
+"772 218 OFFCURVE",
+"624 218 CURVE SMOOTH",
+"463 218 OFFCURVE",
+"270 340 OFFCURVE",
+"184 461 CURVE",
+"67 189 LINE",
+"147 91 OFFCURVE",
+"394 -25 OFFCURVE",
+"573 -25 CURVE SMOOTH",
+"923 -25 OFFCURVE",
+"1182 124 OFFCURVE",
+"1182 419 CURVE SMOOTH",
+"1182 584 OFFCURVE",
+"1077 682 OFFCURVE",
+"881 831 CURVE SMOOTH",
+"728 947 OFFCURVE",
+"628 1010 OFFCURVE",
+"628 1082 CURVE SMOOTH",
+"628 1198 OFFCURVE",
+"790 1230 OFFCURVE",
+"877 1230 CURVE SMOOTH",
+"1018 1230 OFFCURVE",
+"1119 1189 OFFCURVE",
+"1228 1099 CURVE",
+"1339 1361 LINE"
+);
+}
+);
+width = 1223;
+}
+);
+unicode = 0053;
+},
+{
+glyphname = LtnCapT;
+layers = (
+{
+anchors = (
+{
+name = H;
+position = "{562, 0}";
+},
+{
+name = L;
+position = "{562, -100}";
+},
+{
+name = U;
+position = "{944, 1530}";
+}
+);
+layerId = master01;
+paths = (
+{
+closed = 1;
+nodes = (
+"296 1250 LINE",
+"380 1266 OFFCURVE",
+"457 1269 OFFCURVE",
+"546 1269 CURVE SMOOTH",
+"781 1269 LINE",
+"571 426 LINE SMOOTH",
+"523 233 OFFCURVE",
+"481 78 OFFCURVE",
+"445 0 CURVE",
+"675 0 LINE",
+"677 78 OFFCURVE",
+"713 233 OFFCURVE",
+"761 426 CURVE SMOOTH",
+"971 1269 LINE",
+"1211 1269 LINE SMOOTH",
+"1301 1269 OFFCURVE",
+"1375 1266 OFFCURVE",
+"1451 1250 CURVE",
+"1496 1431 LINE",
+"341 1431 LINE"
+);
+}
+);
+width = 1245;
+},
+{
+anchors = (
+{
+name = H;
+position = "{572, 0}";
+},
+{
+name = L;
+position = "{547, -100}";
+},
+{
+name = U;
+position = "{954, 1530}";
+}
+);
+layerId = master02;
+paths = (
+{
+closed = 1;
+nodes = (
+"283 1198 LINE",
+"359 1215 OFFCURVE",
+"439 1218 OFFCURVE",
+"519 1218 CURVE SMOOTH",
+"731 1218 LINE",
+"529 409 LINE SMOOTH",
+"483 224 OFFCURVE",
+"443 75 OFFCURVE",
+"408 0 CURVE",
+"733 0 LINE",
+"734 75 OFFCURVE",
+"768 224 OFFCURVE",
+"814 409 CURVE SMOOTH",
+"1016 1218 LINE",
+"1232 1218 LINE SMOOTH",
+"1313 1218 OFFCURVE",
+"1390 1215 OFFCURVE",
+"1458 1198 CURVE",
+"1520 1445 LINE",
+"345 1445 LINE"
+);
+}
+);
+width = 1255;
+}
+);
+unicode = 0054;
+},
+{
+glyphname = LtnCapU;
+layers = (
+{
+anchors = (
+{
+name = H;
+position = "{647, 0}";
+},
+{
+name = L;
+position = "{622, -100}";
+},
+{
+name = O;
+position = "{865, 0}";
+},
+{
+name = R;
+position = "{1640, 1200}";
+},
+{
+name = U;
+position = "{1029, 1530}";
+}
+);
+layerId = master01;
+paths = (
+{
+closed = 1;
+nodes = (
+"1126 549 LINE SMOOTH",
+"1055 264 OFFCURVE",
+"916 132 OFFCURVE",
+"682 132 CURVE SMOOTH",
+"485 132 OFFCURVE",
+"421 244 OFFCURVE",
+"421 391 CURVE SMOOTH",
+"421 451 OFFCURVE",
+"431 516 OFFCURVE",
+"448 582 CURVE SMOOTH",
+"661 1431 LINE",
+"456 1431 LINE",
+"451 1352 OFFCURVE",
+"414 1198 OFFCURVE",
+"365 1005 CURVE SMOOTH",
+"251 552 LINE SMOOTH",
+"236 493 OFFCURVE",
+"228 435 OFFCURVE",
+"228 379 CURVE SMOOTH",
+"228 157 OFFCURVE",
+"351 -25 OFFCURVE",
+"643 -25 CURVE SMOOTH",
+"1020 -25 OFFCURVE",
+"1223 177 OFFCURVE",
+"1299 480 CURVE SMOOTH",
+"1430 1005 LINE SMOOTH",
+"1480 1207 OFFCURVE",
+"1519 1352 OFFCURVE",
+"1551 1431 CURVE",
+"1346 1431 LINE"
+);
+}
+);
+width = 1420;
+},
+{
+anchors = (
+{
+name = H;
+position = "{672, 0}";
+},
+{
+name = L;
+position = "{647, -100}";
+},
+{
+name = O;
+position = "{890, 0}";
+},
+{
+name = R;
+position = "{1720, 1200}";
+},
+{
+name = U;
+position = "{1054, 1530}";
+}
+);
+layerId = master02;
+paths = (
+{
+closed = 1;
+nodes = (
+"1093 554 LINE SMOOTH",
+"1040 341 OFFCURVE",
+"952 202 OFFCURVE",
+"735 202 CURVE SMOOTH",
+"572 202 OFFCURVE",
+"515 305 OFFCURVE",
+"515 435 CURVE SMOOTH",
+"515 482 OFFCURVE",
+"523 533 OFFCURVE",
+"535 583 CURVE SMOOTH",
+"750 1445 LINE",
+"450 1445 LINE",
+"444 1366 OFFCURVE",
+"406 1210 OFFCURVE",
+"358 1015 CURVE SMOOTH",
+"249 570 LINE SMOOTH",
+"235 512 OFFCURVE",
+"228 457 OFFCURVE",
+"228 404 CURVE SMOOTH",
+"228 155 OFFCURVE",
+"385 -25 OFFCURVE",
+"698 -25 CURVE SMOOTH",
+"1063 -25 OFFCURVE",
+"1275 148 OFFCURVE",
+"1356 470 CURVE SMOOTH",
+"1493 1015 LINE SMOOTH",
+"1544 1220 OFFCURVE",
+"1582 1366 OFFCURVE",
+"1615 1445 CURVE",
+"1315 1445 LINE"
+);
+}
+);
+width = 1470;
+}
+);
+unicode = 0055;
+},
+{
+glyphname = LtnCapV;
+layers = (
+{
+anchors = (
+{
+name = H;
+position = "{620, 0}";
+},
+{
+name = L;
+position = "{587, -100}";
+},
+{
+name = O;
+position = "{820, 0}";
+},
+{
+name = U;
+position = "{994, 1530}";
+}
+);
+layerId = master01;
+paths = (
+{
+closed = 1;
+nodes = (
+"654 191 LINE",
+"536 1431 LINE",
+"331 1431 LINE",
+"344 1350 OFFCURVE",
+"355 1262 OFFCURVE",
+"377 1073 CURVE SMOOTH",
+"500 0 LINE",
+"725 0 LINE",
+"1377 1073 LINE SMOOTH",
+"1492 1263 OFFCURVE",
+"1550 1350 OFFCURVE",
+"1606 1431 CURVE",
+"1381 1431 LINE"
+);
+}
+);
+width = 1345;
+},
+{
+anchors = (
+{
+name = H;
+position = "{670, 0}";
+},
+{
+name = L;
+position = "{637, -100}";
+},
+{
+name = O;
+position = "{870, 0}";
+},
+{
+name = U;
+position = "{1044, 1530}";
+}
+);
+layerId = master02;
+paths = (
+{
+closed = 1;
+nodes = (
+"721 257 LINE",
+"620 1445 LINE",
+"325 1445 LINE",
+"339 1364 OFFCURVE",
+"354 1275 OFFCURVE",
+"375 1084 CURVE SMOOTH",
+"495 0 LINE",
+"830 0 LINE",
+"1490 1084 LINE SMOOTH",
+"1606 1276 OFFCURVE",
+"1664 1364 OFFCURVE",
+"1720 1445 CURVE",
+"1405 1445 LINE"
+);
+}
+);
+width = 1445;
+}
+);
+unicode = 0056;
+},
+{
+glyphname = LtnCapW;
+layers = (
+{
+anchors = (
+{
+name = L;
+position = "{942, -100}";
+},
+{
+name = U;
+position = "{1349, 1530}";
+}
+);
+layerId = master01;
+paths = (
+{
+closed = 1;
+nodes = (
+"2107 1073 LINE SMOOTH",
+"2208 1263 OFFCURVE",
+"2259 1350 OFFCURVE",
+"2311 1431 CURVE",
+"2081 1431 LINE",
+"1431 127 LINE",
+"1420 0 LINE",
+"1535 0 LINE"
+);
+},
+{
+closed = 1;
+nodes = (
+"1420 0 LINE",
+"1461 127 LINE",
+"1406 1431 LINE",
+"1231 1431 LINE",
+"1248 1279 LINE",
+"1310 0 LINE"
+);
+},
+{
+closed = 1;
+nodes = (
+"1406 1431 LINE",
+"1221 1431 LINE",
+"521 127 LINE",
+"521 0 LINE",
+"625 0 LINE"
+);
+},
+{
+closed = 1;
+nodes = (
+"336 1431 LINE",
+"348 1353 OFFCURVE",
+"355 1260 OFFCURVE",
+"362 1073 CURVE SMOOTH",
+"400 0 LINE",
+"521 0 LINE",
+"551 127 LINE",
+"546 1431 LINE"
+);
+}
+);
+width = 2060;
+},
+{
+anchors = (
+{
+name = L;
+position = "{967, -100}";
+},
+{
+name = U;
+position = "{1374, 1530}";
+}
+);
+layerId = master02;
+paths = (
+{
+closed = 1;
+nodes = (
+"1595 0 LINE",
+"2165 1084 LINE SMOOTH",
+"2266 1277 OFFCURVE",
+"2318 1364 OFFCURVE",
+"2370 1445 CURVE",
+"2050 1445 LINE",
+"1432 129 LINE",
+"1430 0 LINE"
+);
+},
+{
+closed = 1;
+nodes = (
+"1220 1445 LINE",
+"1257 1292 LINE",
+"1280 0 LINE",
+"1450 0 LINE",
+"1492 129 LINE",
+"1470 1445 LINE"
+);
+},
+{
+closed = 1;
+nodes = (
+"705 0 LINE",
+"1367 1292 LINE",
+"1470 1445 LINE",
+"1210 1445 LINE",
+"542 129 LINE",
+"540 0 LINE"
+);
+},
+{
+closed = 1;
+nodes = (
+"330 1445 LINE",
+"341 1367 OFFCURVE",
+"349 1273 OFFCURVE",
+"355 1084 CURVE SMOOTH",
+"390 0 LINE",
+"560 0 LINE",
+"602 129 LINE",
+"630 1445 LINE"
+);
+}
+);
+width = 2115;
+}
+);
+unicode = 0057;
+},
+{
+glyphname = LtnCapX;
+layers = (
+{
+anchors = (
+{
+name = L;
+position = "{565, -100}";
+},
+{
+name = U;
+position = "{972, 1530}";
+}
+);
+layerId = master01;
+paths = (
+{
+closed = 1;
+nodes = (
+"1190 0 LINE",
+"1148 80 OFFCURVE",
+"1125 124 OFFCURVE",
+"1045 329 CURVE SMOOTH",
+"611 1431 LINE",
+"386 1431 LINE",
+"430 1348 OFFCURVE",
+"462 1289 OFFCURVE",
+"541 1088 CURVE SMOOTH",
+"970 0 LINE"
+);
+},
+{
+closed = 1;
+nodes = (
+"278 333 LINE SMOOTH",
+"98 129 OFFCURVE",
+"53 84 OFFCURVE",
+"-30 0 CURVE",
+"210 0 LINE",
+"750 622 LINE",
+"752 872 LINE"
+);
+},
+{
+closed = 1;
+nodes = (
+"1183 1088 LINE SMOOTH",
+"1360 1285 OFFCURVE",
+"1425 1355 OFFCURVE",
+"1506 1431 CURVE",
+"1261 1431 LINE",
+"767 872 LINE",
+"765 622 LINE"
+);
+}
+);
+width = 1305;
+},
+{
+anchors = (
+{
+name = L;
+position = "{585, -100}";
+},
+{
+name = U;
+position = "{992, 1530}";
+}
+);
+layerId = master02;
+paths = (
+{
+closed = 1;
+nodes = (
+"1240 0 LINE",
+"1199 81 OFFCURVE",
+"1172 125 OFFCURVE",
+"1096 333 CURVE SMOOTH",
+"690 1445 LINE",
+"375 1445 LINE",
+"418 1362 OFFCURVE",
+"454 1304 OFFCURVE",
+"529 1099 CURVE SMOOTH",
+"930 0 LINE"
+);
+},
+{
+closed = 1;
+nodes = (
+"269 337 LINE SMOOTH",
+"94 126 OFFCURVE",
+"44 85 OFFCURVE",
+"-40 0 CURVE",
+"290 0 LINE",
+"790 603 LINE",
+"768 938 LINE"
+);
+},
+{
+closed = 1;
+nodes = (
+"1251 1099 LINE SMOOTH",
+"1423 1302 OFFCURVE",
+"1492 1369 OFFCURVE",
+"1575 1445 CURVE",
+"1240 1445 LINE",
+"808 938 LINE",
+"830 603 LINE"
+);
+}
+);
+width = 1345;
+}
+);
+unicode = 0058;
+},
+{
+glyphname = LtnCapY;
+layers = (
+{
+anchors = (
+{
+name = L;
+position = "{565, -100}";
+},
+{
+name = U;
+position = "{972, 1530}";
+}
+);
+layerId = master01;
+paths = (
+{
+closed = 1;
+nodes = (
+"407 1285 OFFCURVE",
+"446 1173 OFFCURVE",
+"490 1044 CURVE",
+"661 549 LINE",
+"829 661 LINE",
+"551 1431 LINE",
+"331 1431 LINE"
+);
+},
+{
+closed = 1;
+nodes = (
+"684 661 LINE",
+"796 549 LINE",
+"1215 1044 LINE SMOOTH",
+"1322 1171 OFFCURVE",
+"1402 1265 OFFCURVE",
+"1561 1431 CURVE",
+"1321 1431 LINE"
+);
+},
+{
+closed = 1;
+nodes = (
+"704 78 OFFCURVE",
+"743 233 OFFCURVE",
+"791 426 CURVE SMOOTH",
+"854 681 LINE",
+"664 681 LINE",
+"601 426 LINE SMOOTH",
+"553 233 OFFCURVE",
+"514 78 OFFCURVE",
+"480 0 CURVE",
+"700 0 LINE"
+);
+}
+);
+width = 1300;
+},
+{
+anchors = (
+{
+name = L;
+position = "{587, -100}";
+},
+{
+name = U;
+position = "{994, 1530}";
+}
+);
+layerId = master02;
+paths = (
+{
+closed = 1;
+nodes = (
+"400 1298 OFFCURVE",
+"438 1185 OFFCURVE",
+"482 1054 CURVE SMOOTH",
+"653 554 LINE",
+"868 668 LINE",
+"637 1445 LINE",
+"325 1445 LINE"
+);
+},
+{
+closed = 1;
+nodes = (
+"668 668 LINE",
+"848 554 LINE",
+"1271 1054 LINE SMOOTH",
+"1379 1183 OFFCURVE",
+"1459 1278 OFFCURVE",
+"1619 1445 CURVE",
+"1282 1445 LINE"
+);
+},
+{
+closed = 1;
+nodes = (
+"774 79 OFFCURVE",
+"813 236 OFFCURVE",
+"862 431 CURVE SMOOTH",
+"926 688 LINE",
+"641 688 LINE",
+"577 431 LINE SMOOTH",
+"528 236 OFFCURVE",
+"488 79 OFFCURVE",
+"455 0 CURVE",
+"770 0 LINE"
+);
+}
+);
+width = 1344;
+}
+);
+unicode = 0059;
+},
+{
+glyphname = LftSqrBrac;
+layers = (
+{
+layerId = master01;
+paths = (
+{
+closed = 1;
+nodes = (
+"521 -255 LINE",
+"266 -255 LINE",
+"679 1421 LINE",
+"934 1421 LINE",
+"970 1568 LINE",
+"530 1568 LINE",
+"44 -402 LINE",
+"484 -402 LINE"
+);
+}
+);
+width = 770;
+},
+{
+layerId = master02;
+paths = (
+{
+closed = 1;
+nodes = (
+"605 -198 LINE",
+"365 -198 LINE",
+"753 1376 LINE",
+"993 1376 LINE",
+"1044 1584 LINE",
+"524 1584 LINE",
+"33 -406 LINE",
+"553 -406 LINE"
+);
+}
+);
+width = 830;
+}
+);
+unicode = 005B;
+},
+{
+glyphname = ReverseSolidus;
+layers = (
+{
+layerId = master01;
+paths = (
+{
+closed = 1;
+nodes = (
+"656 -123 LINE",
+"799 -93 LINE",
+"620 1568 LINE",
+"473 1538 LINE"
+);
+}
+);
+width = 1005;
+},
+{
+layerId = master02;
+paths = (
+{
+closed = 1;
+nodes = (
+"719 -243 LINE",
+"949 -243 LINE",
+"574 1584 LINE",
+"344 1584 LINE"
+);
+}
+);
+width = 1060;
+}
+);
+unicode = 005C;
+},
+{
+glyphname = RtSqrBrac;
+layers = (
+{
+layerId = master01;
+paths = (
+{
+closed = 1;
+nodes = (
+"920 1568 LINE",
+"480 1568 LINE",
+"444 1421 LINE",
+"699 1421 LINE",
+"286 -255 LINE",
+"31 -255 LINE",
+"-6 -402 LINE",
+"434 -402 LINE"
+);
+}
+);
+width = 770;
+},
+{
+layerId = master02;
+paths = (
+{
+closed = 1;
+nodes = (
+"994 1584 LINE",
+"474 1584 LINE",
+"423 1376 LINE",
+"663 1376 LINE",
+"275 -198 LINE",
+"35 -198 LINE",
+"-17 -406 LINE",
+"503 -406 LINE"
+);
+}
+);
+width = 830;
+}
+);
+unicode = 005D;
+},
+{
+glyphname = CircumAccent;
+layers = (
+{
+anchors = (
+{
+name = U;
+position = "{705, 1635}";
+}
+);
+layerId = master01;
+paths = (
+{
+closed = 1;
+nodes = (
+"660 1421 LINE",
+"866 1147 LINE",
+"1015 1147 LINE",
+"761 1568 LINE",
+"591 1568 LINE",
+"166 1147 LINE",
+"316 1147 LINE"
+);
+}
+);
+width = 830;
+},
+{
+anchors = (
+{
+name = U;
+position = "{788, 1635}";
+}
+);
+layerId = master02;
+paths = (
+{
+closed = 1;
+nodes = (
+"845 1584 LINE",
+"545 1584 LINE",
+"177 1188 LINE",
+"417 1188 LINE",
+"674 1416 LINE",
+"817 1188 LINE",
+"1056 1188 LINE"
+);
+}
+);
+width = 860;
+}
+);
+unicode = 005E;
+},
+{
+glyphname = LowLine;
+layers = (
+{
+layerId = master01;
+paths = (
+{
+closed = 1;
+nodes = (
+"1135 -314 LINE",
+"1172 -167 LINE",
+"-101 -167 LINE",
+"-138 -314 LINE"
+);
+}
+);
+width = 1254;
+},
+{
+layerId = master02;
+paths = (
+{
+closed = 1;
+nodes = (
+"1127 -347 LINE",
+"1179 -139 LINE",
+"-94 -139 LINE",
+"-146 -347 LINE"
+);
+}
+);
+width = 1254;
+}
+);
+unicode = 005F;
+},
+{
+glyphname = GraveAccent;
+layers = (
+{
+anchors = (
+{
+name = U;
+position = "{738, 1635}";
+}
+);
+layerId = master01;
+paths = (
+{
+closed = 1;
+nodes = (
+"596 1147 LINE",
+"746 1147 LINE",
+"471 1568 LINE",
+"261 1568 LINE"
+);
+}
+);
+width = 560;
+},
+{
+anchors = (
+{
+name = U;
+position = "{848, 1635}";
+}
+);
+layerId = master02;
+paths = (
+{
+closed = 1;
+nodes = (
+"587 1188 LINE",
+"817 1188 LINE",
+"595 1584 LINE",
+"265 1584 LINE"
+);
+}
+);
+width = 620;
+}
+);
+unicode = 0060;
+},
+{
+glyphname = LtnSmA;
+layers = (
+{
+anchors = (
+{
+name = H;
+position = "{860, 0}";
+},
+{
+name = L;
+position = "{455, -100}";
+},
+{
+name = O;
+position = "{1065, 0}";
+},
+{
+name = R;
+position = "{1310, 1000}";
+},
+{
+name = U;
+position = "{755, 1100}";
+}
+);
+layerId = master01;
+paths = (
+{
+closed = 1;
+nodes = (
+"965 48 OFFCURVE",
+"960 98 OFFCURVE",
+"960 149 CURVE SMOOTH",
+"960 214 OFFCURVE",
+"967 284 OFFCURVE",
+"987 363 CURVE",
+"1077 726 LINE",
+"1081 744 OFFCURVE",
+"1084 762 OFFCURVE",
+"1084 779 CURVE SMOOTH",
+"1084 912 OFFCURVE",
+"955 1019 OFFCURVE",
+"751 1019 CURVE SMOOTH",
+"599 1019 OFFCURVE",
+"502 974 OFFCURVE",
+"389 931 CURVE",
+"373 889 OFFCURVE",
+"343 783 OFFCURVE",
+"331 740 CURVE",
+"468 820 OFFCURVE",
+"560 862 OFFCURVE",
+"666 862 CURVE SMOOTH",
+"798 862 OFFCURVE",
+"885 810 OFFCURVE",
+"885 718 CURVE SMOOTH",
+"885 705 OFFCURVE",
+"884 691 OFFCURVE",
+"880 677 CURVE SMOOTH",
+"867 622 LINE",
+"825 619 OFFCURVE",
+"661 605 OFFCURVE",
+"591 598 CURVE SMOOTH",
+"282 568 OFFCURVE",
+"102 415 OFFCURVE",
+"102 233 CURVE SMOOTH",
+"102 103 OFFCURVE",
+"223 -25 OFFCURVE",
+"390 -25 CURVE SMOOTH",
+"514 -25 OFFCURVE",
+"674 47 OFFCURVE",
+"779 152 CURVE",
+"779 89 OFFCURVE",
+"787 31 OFFCURVE",
+"792 0 CURVE",
+"972 0 LINE"
+);
+},
+{
+closed = 1;
+nodes = (
+"674 191 OFFCURVE",
+"553 137 OFFCURVE",
+"451 137 CURVE SMOOTH",
+"355 137 OFFCURVE",
+"290 192 OFFCURVE",
+"290 264 CURVE SMOOTH",
+"290 274 OFFCURVE",
+"291 285 OFFCURVE",
+"294 296 CURVE SMOOTH",
+"315 380 OFFCURVE",
+"432 450 OFFCURVE",
+"566 461 CURVE SMOOTH",
+"631 466 OFFCURVE",
+"782 483 OFFCURVE",
+"832 485 CURVE",
+"791 319 LINE"
+);
+}
+);
+width = 1107;
+},
+{
+anchors = (
+{
+name = H;
+position = "{925, 0}";
+},
+{
+name = L;
+position = "{525, -100}";
+},
+{
+name = O;
+position = "{1125, 0}";
+},
+{
+name = R;
+position = "{1335, 1000}";
+},
+{
+name = U;
+position = "{825, 1100}";
+}
+);
+layerId = master02;
+paths = (
+{
+closed = 1;
+nodes = (
+"1054 44 OFFCURVE",
+"1051 87 OFFCURVE",
+"1051 133 CURVE SMOOTH",
+"1051 204 OFFCURVE",
+"1059 280 OFFCURVE",
+"1081 366 CURVE",
+"1128 557 OFFCURVE",
+"1156 665 OFFCURVE",
+"1170 722 CURVE",
+"1174 738 OFFCURVE",
+"1176 754 OFFCURVE",
+"1176 770 CURVE SMOOTH",
+"1176 909 OFFCURVE",
+"1026 1030 OFFCURVE",
+"791 1030 CURVE SMOOTH",
+"632 1030 OFFCURVE",
+"514 994 OFFCURVE",
+"389 940 CURVE",
+"363 859 OFFCURVE",
+"327 728 OFFCURVE",
+"315 684 CURVE",
+"452 765 OFFCURVE",
+"565 808 OFFCURVE",
+"673 808 CURVE SMOOTH",
+"809 808 OFFCURVE",
+"885 760 OFFCURVE",
+"885 709 CURVE SMOOTH",
+"885 705 OFFCURVE",
+"884 700 OFFCURVE",
+"883 696 CURVE SMOOTH",
+"872 653 LINE",
+"831 652 OFFCURVE",
+"669 643 OFFCURVE",
+"598 636 CURVE SMOOTH",
+"367 614 OFFCURVE",
+"109 474 OFFCURVE",
+"109 236 CURVE SMOOTH",
+"109 97 OFFCURVE",
+"215 -25 OFFCURVE",
+"388 -25 CURVE SMOOTH",
+"505 -25 OFFCURVE",
+"633 23 OFFCURVE",
+"773 134 CURVE",
+"773 78 OFFCURVE",
+"784 28 OFFCURVE",
+"790 0 CURVE",
+"1060 0 LINE"
+);
+},
+{
+closed = 1;
+nodes = (
+"669 223 OFFCURVE",
+"590 203 OFFCURVE",
+"508 203 CURVE SMOOTH",
+"438 203 OFFCURVE",
+"398 246 OFFCURVE",
+"398 299 CURVE SMOOTH",
+"398 308 OFFCURVE",
+"399 317 OFFCURVE",
+"401 326 CURVE SMOOTH",
+"417 391 OFFCURVE",
+"471 438 OFFCURVE",
+"612 452 CURVE SMOOTH",
+"665 458 OFFCURVE",
+"786 469 OFFCURVE",
+"827 470 CURVE",
+"797 351 LINE"
+);
+}
+);
+width = 1185;
+}
+);
+unicode = 0061;
+},
+{
+glyphname = LtnSmB;
+layers = (
+{
+anchors = (
+{
+name = H;
+position = "{530, 0}";
+},
+{
+name = L;
+position = "{505, -100}";
+},
+{
+name = R;
+position = "{1345, 1000}";
+},
+{
+name = U;
+position = "{938, 1635}";
+}
+);
+layerId = master01;
+paths = (
+{
+closed = 1;
+nodes = (
+"437 1456 OFFCURVE",
+"402 1246 OFFCURVE",
+"367 1105 CURVE SMOOTH",
+"110 85 LINE",
+"198 44 OFFCURVE",
+"355 -25 OFFCURVE",
+"517 -25 CURVE SMOOTH",
+"675 -25 OFFCURVE",
+"795 24 OFFCURVE",
+"907 125 CURVE SMOOTH",
+"1050 255 OFFCURVE",
+"1162 466 OFFCURVE",
+"1162 695 CURVE SMOOTH",
+"1162 930 OFFCURVE",
+"1046 1020 OFFCURVE",
+"907 1020 CURVE SMOOTH",
+"754 1020 OFFCURVE",
+"584 878 OFFCURVE",
+"456 719 CURVE",
+"552 1105 LINE SMOOTH",
+"600 1296 OFFCURVE",
+"627 1508 OFFCURVE",
+"627 1570 CURVE",
+"437 1570 LINE"
+);
+},
+{
+closed = 1;
+nodes = (
+"485 617 OFFCURVE",
+"708 850 OFFCURVE",
+"822 850 CURVE SMOOTH",
+"913 850 OFFCURVE",
+"972 784 OFFCURVE",
+"972 635 CURVE SMOOTH",
+"972 469 OFFCURVE",
+"909 336 OFFCURVE",
+"822 250 CURVE SMOOTH",
+"741 169 OFFCURVE",
+"638 125 OFFCURVE",
+"552 125 CURVE SMOOTH",
+"466 125 OFFCURVE",
+"376 167 OFFCURVE",
+"325 200 CURVE",
+"382 429 LINE"
+);
+}
+);
+width = 1144;
+},
+{
+anchors = (
+{
+name = H;
+position = "{550, 0}";
+},
+{
+name = L;
+position = "{525, -100}";
+},
+{
+name = R;
+position = "{1405, 1000}";
+},
+{
+name = U;
+position = "{958, 1635}";
+}
+);
+layerId = master02;
+paths = (
+{
+closed = 1;
+nodes = (
+"576 610 OFFCURVE",
+"726 787 OFFCURVE",
+"829 787 CURVE SMOOTH",
+"911 787 OFFCURVE",
+"946 705 OFFCURVE",
+"946 590 CURVE SMOOTH",
+"946 465 OFFCURVE",
+"897 350 OFFCURVE",
+"823 275 CURVE SMOOTH",
+"769 221 OFFCURVE",
+"703 188 OFFCURVE",
+"631 188 CURVE SMOOTH",
+"564 188 OFFCURVE",
+"502 202 OFFCURVE",
+"434 238 CURVE",
+"482 432 LINE"
+);
+},
+{
+closed = 1;
+nodes = (
+"445 1439 OFFCURVE",
+"404 1242 OFFCURVE",
+"367 1095 CURVE SMOOTH",
+"110 64 LINE",
+"252 16 OFFCURVE",
+"400 -25 OFFCURVE",
+"593 -25 CURVE SMOOTH",
+"727 -25 OFFCURVE",
+"845 19 OFFCURVE",
+"942 91 CURVE SMOOTH",
+"1122 224 OFFCURVE",
+"1229 453 OFFCURVE",
+"1229 672 CURVE SMOOTH",
+"1229 906 OFFCURVE",
+"1138 1030 OFFCURVE",
+"985 1030 CURVE SMOOTH",
+"822 1030 OFFCURVE",
+"684 906 OFFCURVE",
+"562 756 CURVE",
+"646 1095 LINE SMOOTH",
+"686 1255 OFFCURVE",
+"725 1474 OFFCURVE",
+"725 1585 CURVE",
+"445 1585 LINE"
+);
+}
+);
+width = 1229;
+}
+);
+unicode = 0062;
+},
+{
+glyphname = LtnSmC;
+layers = (
+{
+anchors = (
+{
+name = H;
+position = "{520, 0}";
+},
+{
+name = L;
+position = "{495, -100}";
+},
+{
+name = R;
+position = "{1210, 1000}";
+},
+{
+name = U;
+position = "{785, 1100}";
+}
+);
+layerId = master01;
+paths = (
+{
+closed = 1;
+nodes = (
+"811 179 OFFCURVE",
+"703 137 OFFCURVE",
+"583 137 CURVE SMOOTH",
+"427 137 OFFCURVE",
+"331 239 OFFCURVE",
+"331 406 CURVE SMOOTH",
+"331 619 OFFCURVE",
+"499 858 OFFCURVE",
+"742 858 CURVE SMOOTH",
+"845 858 OFFCURVE",
+"924 824 OFFCURVE",
+"998 760 CURVE",
+"1077 936 LINE",
+"1016 985 OFFCURVE",
+"902 1020 OFFCURVE",
+"789 1020 CURVE SMOOTH",
+"420 1020 OFFCURVE",
+"139 737 OFFCURVE",
+"139 381 CURVE SMOOTH",
+"139 130 OFFCURVE",
+"309 -25 OFFCURVE",
+"532 -25 CURVE SMOOTH",
+"682 -25 OFFCURVE",
+"785 9 OFFCURVE",
+"904 83 CURVE",
+"917 255 LINE"
+);
+}
+);
+width = 989;
+},
+{
+anchors = (
+{
+name = H;
+position = "{495, 0}";
+},
+{
+name = L;
+position = "{490, -100}";
+},
+{
+name = R;
+position = "{1210, 1000}";
+},
+{
+name = U;
+position = "{790, 1100}";
+}
+);
+layerId = master02;
+paths = (
+{
+closed = 1;
+nodes = (
+"1035 997 OFFCURVE",
+"928 1030 OFFCURVE",
+"796 1030 CURVE SMOOTH",
+"446 1030 OFFCURVE",
+"150 774 OFFCURVE",
+"150 386 CURVE SMOOTH",
+"150 137 OFFCURVE",
+"341 -25 OFFCURVE",
+"569 -25 CURVE SMOOTH",
+"718 -25 OFFCURVE",
+"835 11 OFFCURVE",
+"927 69 CURVE",
+"937 311 LINE",
+"840 238 OFFCURVE",
+"755 203 OFFCURVE",
+"625 203 CURVE SMOOTH",
+"494 203 OFFCURVE",
+"417 302 OFFCURVE",
+"417 416 CURVE SMOOTH",
+"417 661 OFFCURVE",
+"588 802 OFFCURVE",
+"754 802 CURVE SMOOTH",
+"857 802 OFFCURVE",
+"918 781 OFFCURVE",
+"993 720 CURVE",
+"1099 959 LINE"
+);
+}
+);
+width = 1019;
+}
+);
+unicode = 0063;
+},
+{
+glyphname = LtnSmD;
+layers = (
+{
+anchors = (
+{
+name = H;
+position = "{545, 0}";
+},
+{
+name = L;
+position = "{520, -100}";
+},
+{
+name = R;
+position = "{1380, 1000}";
+},
+{
+name = U;
+position = "{953, 1635}";
+}
+);
+layerId = master01;
+paths = (
+{
+closed = 1;
+nodes = (
+"1144 1456 OFFCURVE",
+"1114 1327 OFFCURVE",
+"1079 1175 CURVE SMOOTH",
+"1024 935 LINE",
+"957 978 OFFCURVE",
+"854 1020 OFFCURVE",
+"759 1020 CURVE SMOOTH",
+"650 1020 OFFCURVE",
+"534 979 OFFCURVE",
+"429 895 CURVE SMOOTH",
+"262 761 OFFCURVE",
+"139 532 OFFCURVE",
+"139 288 CURVE SMOOTH",
+"139 94 OFFCURVE",
+"250 -25 OFFCURVE",
+"424 -25 CURVE SMOOTH",
+"563 -25 OFFCURVE",
+"791 141 OFFCURVE",
+"899 305 CURVE",
+"875 196 OFFCURVE",
+"869 93 OFFCURVE",
+"869 0 CURVE",
+"1052 0 LINE",
+"1048 23 OFFCURVE",
+"1047 53 OFFCURVE",
+"1047 90 CURVE SMOOTH",
+"1047 190 OFFCURVE",
+"1063 340 OFFCURVE",
+"1107 520 CURVE SMOOTH",
+"1267 1175 LINE SMOOTH",
+"1310 1351 OFFCURVE",
+"1337 1475 OFFCURVE",
+"1337 1570 CURVE",
+"1144 1570 LINE"
+);
+},
+{
+closed = 1;
+nodes = (
+"846 370 OFFCURVE",
+"592 130 OFFCURVE",
+"479 130 CURVE SMOOTH",
+"374 130 OFFCURVE",
+"330 195 OFFCURVE",
+"330 316 CURVE SMOOTH",
+"330 460 OFFCURVE",
+"397 649 OFFCURVE",
+"509 760 CURVE SMOOTH",
+"572 822 OFFCURVE",
+"643 855 OFFCURVE",
+"734 855 CURVE SMOOTH",
+"835 855 OFFCURVE",
+"898 832 OFFCURVE",
+"984 780 CURVE",
+"930 545 LINE"
+);
+}
+);
+width = 1197;
+},
+{
+anchors = (
+{
+name = H;
+position = "{535, 0}";
+},
+{
+name = L;
+position = "{540, -100}";
+},
+{
+name = R;
+position = "{1475, 1000}";
+},
+{
+name = U;
+position = "{958, 1635}";
+}
+);
+layerId = master02;
+paths = (
+{
+closed = 1;
+nodes = (
+"861 438 OFFCURVE",
+"666 200 OFFCURVE",
+"560 200 CURVE SMOOTH",
+"470 200 OFFCURVE",
+"427 263 OFFCURVE",
+"427 367 CURVE SMOOTH",
+"427 480 OFFCURVE",
+"469 626 OFFCURVE",
+"554 714 CURVE SMOOTH",
+"599 761 OFFCURVE",
+"657 792 OFFCURVE",
+"727 792 CURVE SMOOTH",
+"820 792 OFFCURVE",
+"876 775 OFFCURVE",
+"957 731 CURVE",
+"913 558 LINE"
+);
+},
+{
+closed = 1;
+nodes = (
+"1144 1471 OFFCURVE",
+"1116 1327 OFFCURVE",
+"1079 1175 CURVE SMOOTH",
+"1020 935 LINE",
+"949 989 OFFCURVE",
+"845 1030 OFFCURVE",
+"756 1030 CURVE SMOOTH",
+"630 1030 OFFCURVE",
+"518 987 OFFCURVE",
+"426 917 CURVE SMOOTH",
+"250 784 OFFCURVE",
+"145 553 OFFCURVE",
+"145 341 CURVE SMOOTH",
+"145 130 OFFCURVE",
+"258 -25 OFFCURVE",
+"448 -25 CURVE SMOOTH",
+"597 -25 OFFCURVE",
+"785 145 OFFCURVE",
+"867 267 CURVE",
+"855 181 OFFCURVE",
+"855 72 OFFCURVE",
+"855 0 CURVE",
+"1130 0 LINE",
+"1126 23 OFFCURVE",
+"1125 63 OFFCURVE",
+"1125 100 CURVE SMOOTH",
+"1125 200 OFFCURVE",
+"1142 340 OFFCURVE",
+"1185 520 CURVE SMOOTH",
+"1345 1190 LINE SMOOTH",
+"1387 1366 OFFCURVE",
+"1415 1490 OFFCURVE",
+"1415 1585 CURVE",
+"1144 1585 LINE"
+);
+}
+);
+width = 1265;
+}
+);
+unicode = 0064;
+},
+{
+glyphname = LtnSmE;
+layers = (
+{
+anchors = (
+{
+name = H;
+position = "{485, 0}";
+},
+{
+name = L;
+position = "{484, -100}";
+},
+{
+name = O;
+position = "{840, 0}";
+},
+{
+name = R;
+position = "{1285, 1000}";
+},
+{
+name = U;
+position = "{784, 1100}";
+}
+);
+layerId = master01;
+paths = (
+{
+closed = 1;
+nodes = (
+"854 189 OFFCURVE",
+"700 135 OFFCURVE",
+"567 135 CURVE SMOOTH",
+"386 135 OFFCURVE",
+"317 263 OFFCURVE",
+"317 420 CURVE SMOOTH",
+"317 686 OFFCURVE",
+"522 872 OFFCURVE",
+"720 872 CURVE SMOOTH",
+"813 872 OFFCURVE",
+"883 823 OFFCURVE",
+"883 753 CURVE SMOOTH",
+"883 660 OFFCURVE",
+"766 590 OFFCURVE",
+"539 590 CURVE SMOOTH",
+"468 590 OFFCURVE",
+"382 596 OFFCURVE",
+"279 610 CURVE",
+"279 477 LINE",
+"391 461 OFFCURVE",
+"487 453 OFFCURVE",
+"569 453 CURVE SMOOTH",
+"931 453 OFFCURVE",
+"1077 609 OFFCURVE",
+"1077 791 CURVE SMOOTH",
+"1077 899 OFFCURVE",
+"986 1020 OFFCURVE",
+"772 1020 CURVE SMOOTH",
+"399 1020 OFFCURVE",
+"137 710 OFFCURVE",
+"137 380 CURVE SMOOTH",
+"137 147 OFFCURVE",
+"258 -25 OFFCURVE",
+"523 -25 CURVE SMOOTH",
+"689 -25 OFFCURVE",
+"849 26 OFFCURVE",
+"955 83 CURVE",
+"967 270 LINE"
+);
+}
+);
+width = 1042;
+},
+{
+anchors = (
+{
+name = H;
+position = "{509, 0}";
+},
+{
+name = L;
+position = "{555, -100}";
+},
+{
+name = O;
+position = "{840, 0}";
+},
+{
+name = R;
+position = "{1320, 1000}";
+},
+{
+name = U;
+position = "{752, 1100}";
+}
+);
+layerId = master02;
+paths = (
+{
+closed = 1;
+nodes = (
+"871 230 OFFCURVE",
+"739 198 OFFCURVE",
+"608 198 CURVE SMOOTH",
+"459 198 OFFCURVE",
+"401 297 OFFCURVE",
+"401 428 CURVE SMOOTH",
+"401 683 OFFCURVE",
+"552 822 OFFCURVE",
+"713 822 CURVE SMOOTH",
+"811 822 OFFCURVE",
+"869 782 OFFCURVE",
+"869 720 CURVE SMOOTH",
+"869 635 OFFCURVE",
+"777 580 OFFCURVE",
+"533 580 CURVE SMOOTH",
+"461 580 OFFCURVE",
+"385 589 OFFCURVE",
+"283 610 CURVE",
+"283 437 LINE",
+"353 422 OFFCURVE",
+"487 413 OFFCURVE",
+"569 413 CURVE SMOOTH",
+"935 413 OFFCURVE",
+"1125 583 OFFCURVE",
+"1125 774 CURVE SMOOTH",
+"1125 922 OFFCURVE",
+"993 1030 OFFCURVE",
+"769 1030 CURVE SMOOTH",
+"435 1030 OFFCURVE",
+"148 775 OFFCURVE",
+"148 388 CURVE SMOOTH",
+"148 135 OFFCURVE",
+"332 -25 OFFCURVE",
+"556 -25 CURVE SMOOTH",
+"712 -25 OFFCURVE",
+"835 2 OFFCURVE",
+"997 74 CURVE",
+"1013 303 LINE"
+);
+}
+);
+width = 1087;
+}
+);
+unicode = 0065;
+},
+{
+glyphname = LtnSmF;
+layers = (
+{
+anchors = (
+{
+name = H;
+position = "{290, 0}";
+},
+{
+name = L;
+position = "{315, -100}";
+},
+{
+name = U;
+position = "{908, 1635}";
+}
+);
+layerId = master01;
+paths = (
+{
+closed = 1;
+nodes = (
+"835 833 LINE",
+"871 975 LINE",
+"216 975 LINE",
+"180 833 LINE"
+);
+},
+{
+closed = 1;
+nodes = (
+"1062 1555 OFFCURVE",
+"981 1588 OFFCURVE",
+"903 1588 CURVE SMOOTH",
+"687 1588 OFFCURVE",
+"533 1478 OFFCURVE",
+"448 1147 CURVE SMOOTH",
+"403 972 OFFCURVE",
+"244 334 OFFCURVE",
+"223 0 CURVE",
+"436 0 LINE",
+"430 28 OFFCURVE",
+"427 66 OFFCURVE",
+"427 110 CURVE SMOOTH",
+"427 213 OFFCURVE",
+"447 351 OFFCURVE",
+"476 484 CURVE SMOOTH",
+"510 641 OFFCURVE",
+"558 846 OFFCURVE",
+"641 1186 CURVE SMOOTH",
+"682 1353 OFFCURVE",
+"758 1421 OFFCURVE",
+"862 1421 CURVE SMOOTH",
+"920 1421 OFFCURVE",
+"988 1392 OFFCURVE",
+"1022 1362 CURVE",
+"1106 1519 LINE"
+);
+}
+);
+width = 756;
+},
+{
+anchors = (
+{
+name = H;
+position = "{320, 0}";
+},
+{
+name = L;
+position = "{400, -100}";
+},
+{
+name = U;
+position = "{948, 1635}";
+}
+);
+layerId = master02;
+paths = (
+{
+closed = 1;
+nodes = (
+"915 797 LINE",
+"965 995 LINE",
+"230 995 LINE",
+"180 797 LINE"
+);
+},
+{
+closed = 1;
+nodes = (
+"1139 1572 OFFCURVE",
+"1040 1604 OFFCURVE",
+"966 1604 CURVE SMOOTH",
+"719 1604 OFFCURVE",
+"535 1455 OFFCURVE",
+"460 1158 CURVE SMOOTH",
+"416 983 OFFCURVE",
+"253 334 OFFCURVE",
+"232 0 CURVE",
+"542 0 LINE",
+"536 28 OFFCURVE",
+"533 66 OFFCURVE",
+"533 110 CURVE SMOOTH",
+"533 213 OFFCURVE",
+"550 356 OFFCURVE",
+"581 489 CURVE SMOOTH",
+"649 784 OFFCURVE",
+"682 926 OFFCURVE",
+"735 1147 CURVE SMOOTH",
+"774 1309 OFFCURVE",
+"836 1373 OFFCURVE",
+"932 1373 CURVE SMOOTH",
+"981 1373 OFFCURVE",
+"1043 1348 OFFCURVE",
+"1076 1309 CURVE",
+"1189 1534 LINE"
+);
+}
+);
+width = 859;
+}
+);
+unicode = 0066;
+},
+{
+glyphname = LtnSmG;
+layers = (
+{
+anchors = (
+{
+name = H;
+position = "{368, -465}";
+},
+{
+name = L;
+position = "{351, -535}";
+},
+{
+name = R;
+position = "{1285, 1000}";
+},
+{
+name = U;
+position = "{730, 1100}";
+}
+);
+layerId = master01;
+paths = (
+{
+closed = 1;
+nodes = (
+"277 352 OFFCURVE",
+"168 266 OFFCURVE",
+"168 176 CURVE SMOOTH",
+"168 96 OFFCURVE",
+"246 33 OFFCURVE",
+"483 -5 CURVE SMOOTH",
+"707 -41 OFFCURVE",
+"781 -94 OFFCURVE",
+"781 -151 CURVE SMOOTH",
+"781 -256 OFFCURVE",
+"580 -353 OFFCURVE",
+"411 -353 CURVE SMOOTH",
+"202 -353 OFFCURVE",
+"104 -271 OFFCURVE",
+"104 -196 CURVE SMOOTH",
+"104 -189 OFFCURVE",
+"104 -183 OFFCURVE",
+"106 -176 CURVE SMOOTH",
+"120 -119 OFFCURVE",
+"170 -55 OFFCURVE",
+"409 20 CURVE",
+"410 48 OFFCURVE",
+"248 73 OFFCURVE",
+"248 73 CURVE",
+"53 12 OFFCURVE",
+"-51 -77 OFFCURVE",
+"-78 -186 CURVE SMOOTH",
+"-82 -201 OFFCURVE",
+"-84 -217 OFFCURVE",
+"-84 -231 CURVE SMOOTH",
+"-84 -396 OFFCURVE",
+"158 -495 OFFCURVE",
+"371 -495 CURVE SMOOTH",
+"632 -495 OFFCURVE",
+"972 -360 OFFCURVE",
+"972 -125 CURVE SMOOTH",
+"972 0 OFFCURVE",
+"849 90 OFFCURVE",
+"619 127 CURVE SMOOTH",
+"403 162 OFFCURVE",
+"341 184 OFFCURVE",
+"341 218 CURVE SMOOTH",
+"341 263 OFFCURVE",
+"447 325 OFFCURVE",
+"522 342 CURVE",
+"360 389 LINE"
+);
+},
+{
+closed = 1;
+nodes = (
+"1143 1012 OFFCURVE",
+"1002 977 OFFCURVE",
+"899 921 CURVE",
+"936 809 LINE",
+"1037 846 OFFCURVE",
+"1121 860 OFFCURVE",
+"1194 862 CURVE",
+"1244 1019 LINE"
+);
+},
+{
+closed = 1;
+nodes = (
+"212 449 OFFCURVE",
+"356 319 OFFCURVE",
+"554 319 CURVE SMOOTH",
+"791 319 OFFCURVE",
+"1030 495 OFFCURVE",
+"1030 729 CURVE SMOOTH",
+"1030 894 OFFCURVE",
+"887 1019 OFFCURVE",
+"689 1019 CURVE SMOOTH",
+"441 1019 OFFCURVE",
+"212 847 OFFCURVE",
+"212 613 CURVE SMOOTH"
+);
+},
+{
+closed = 1;
+nodes = (
+"857 555 OFFCURVE",
+"712 456 OFFCURVE",
+"578 456 CURVE SMOOTH",
+"463 456 OFFCURVE",
+"385 530 OFFCURVE",
+"385 628 CURVE SMOOTH",
+"385 643 OFFCURVE",
+"387 660 OFFCURVE",
+"391 676 CURVE SMOOTH",
+"421 797 OFFCURVE",
+"530 877 OFFCURVE",
+"663 877 CURVE SMOOTH",
+"779 877 OFFCURVE",
+"857 802 OFFCURVE",
+"857 704 CURVE SMOOTH"
+);
+}
+);
+width = 1075;
+},
+{
+anchors = (
+{
+name = H;
+position = "{420, -465}";
+},
+{
+name = L;
+position = "{403, -535}";
+},
+{
+name = R;
+position = "{1360, 1000}";
+},
+{
+name = U;
+position = "{782, 1100}";
+}
+);
+layerId = master02;
+paths = (
+{
+closed = 1;
+nodes = (
+"1027 8 OFFCURVE",
+"938 114 OFFCURVE",
+"702 163 CURVE SMOOTH",
+"473 210 OFFCURVE",
+"402 217 OFFCURVE",
+"402 249 CURVE SMOOTH",
+"402 279 OFFCURVE",
+"493 321 OFFCURVE",
+"584 346 CURVE",
+"359 391 LINE",
+"263 354 OFFCURVE",
+"161 283 OFFCURVE",
+"161 188 CURVE SMOOTH",
+"161 101 OFFCURVE",
+"230 4 OFFCURVE",
+"451 -23 CURVE SMOOTH",
+"669 -50 OFFCURVE",
+"740 -97 OFFCURVE",
+"740 -157 CURVE SMOOTH",
+"740 -245 OFFCURVE",
+"591 -299 OFFCURVE",
+"457 -299 CURVE SMOOTH",
+"286 -299 OFFCURVE",
+"197 -233 OFFCURVE",
+"197 -180 CURVE SMOOTH",
+"197 -74 OFFCURVE",
+"405 -4 OFFCURVE",
+"476 20 CURVE",
+"476 49 OFFCURVE",
+"250 74 OFFCURVE",
+"250 74 CURVE",
+"103 20 OFFCURVE",
+"-91 -65 OFFCURVE",
+"-91 -233 CURVE SMOOTH",
+"-91 -409 OFFCURVE",
+"166 -500 OFFCURVE",
+"392 -500 CURVE SMOOTH",
+"690 -500 OFFCURVE",
+"1027 -380 OFFCURVE",
+"1027 -117 CURVE SMOOTH"
+);
+},
+{
+closed = 1;
+nodes = (
+"1168 1023 OFFCURVE",
+"1027 987 OFFCURVE",
+"924 931 CURVE",
+"946 762 LINE",
+"1048 800 OFFCURVE",
+"1132 815 OFFCURVE",
+"1205 817 CURVE",
+"1268 1030 LINE"
+);
+},
+{
+closed = 1;
+nodes = (
+"198 450 OFFCURVE",
+"353 302 OFFCURVE",
+"572 302 CURVE SMOOTH",
+"824 302 OFFCURVE",
+"1087 444 OFFCURVE",
+"1087 702 CURVE SMOOTH",
+"1087 874 OFFCURVE",
+"955 1030 OFFCURVE",
+"703 1030 CURVE SMOOTH",
+"454 1030 OFFCURVE",
+"198 881 OFFCURVE",
+"198 627 CURVE SMOOTH"
+);
+},
+{
+closed = 1;
+nodes = (
+"761 829 OFFCURVE",
+"842 762 OFFCURVE",
+"842 675 CURVE SMOOTH",
+"842 559 OFFCURVE",
+"733 496 OFFCURVE",
+"620 496 CURVE SMOOTH",
+"524 496 OFFCURVE",
+"450 569 OFFCURVE",
+"450 653 CURVE SMOOTH",
+"450 769 OFFCURVE",
+"560 829 OFFCURVE",
+"663 829 CURVE SMOOTH"
+);
+}
+);
+width = 1120;
+}
+);
+unicode = 0067;
+},
+{
+glyphname = LtnSmH;
+layers = (
+{
+anchors = (
+{
+name = H;
+position = "{190, 0}";
+},
+{
+name = L;
+position = "{550, -100}";
+},
+{
+name = U;
+position = "{933, 1635}";
+}
+);
+layerId = master01;
+paths = (
+{
+closed = 1;
+nodes = (
+"1047 30 OFFCURVE",
+"1043 65 OFFCURVE",
+"1043 102 CURVE SMOOTH",
+"1043 143 OFFCURVE",
+"1048 188 OFFCURVE",
+"1055 238 CURVE SMOOTH",
+"1069 327 OFFCURVE",
+"1170 636 OFFCURVE",
+"1170 745 CURVE SMOOTH",
+"1170 917 OFFCURVE",
+"1095 1020 OFFCURVE",
+"930 1020 CURVE SMOOTH",
+"760 1020 OFFCURVE",
+"591 877 OFFCURVE",
+"475 723 CURVE",
+"571 1105 LINE SMOOTH",
+"609 1259 OFFCURVE",
+"645 1482 OFFCURVE",
+"645 1570 CURVE",
+"455 1570 LINE",
+"455 1456 OFFCURVE",
+"423 1257 OFFCURVE",
+"385 1105 CURVE SMOOTH",
+"110 0 LINE",
+"295 0 LINE",
+"397 408 LINE",
+"492 612 OFFCURVE",
+"717 850 OFFCURVE",
+"840 850 CURVE SMOOTH",
+"937 850 OFFCURVE",
+"970 798 OFFCURVE",
+"970 680 CURVE SMOOTH",
+"970 592 OFFCURVE",
+"886 319 OFFCURVE",
+"872 203 CURVE SMOOTH",
+"867 158 OFFCURVE",
+"864 115 OFFCURVE",
+"864 77 CURVE SMOOTH",
+"864 48 OFFCURVE",
+"866 21 OFFCURVE",
+"870 0 CURVE",
+"1055 0 LINE"
+);
+}
+);
+width = 1185;
+},
+{
+anchors = (
+{
+name = H;
+position = "{220, 0}";
+},
+{
+name = L;
+position = "{635, -100}";
+},
+{
+name = U;
+position = "{968, 1635}";
+}
+);
+layerId = master02;
+paths = (
+{
+closed = 1;
+nodes = (
+"1135 29 OFFCURVE",
+"1129 60 OFFCURVE",
+"1129 90 CURVE SMOOTH",
+"1129 135 OFFCURVE",
+"1134 170 OFFCURVE",
+"1141 215 CURVE SMOOTH",
+"1171 400 OFFCURVE",
+"1253 590 OFFCURVE",
+"1253 725 CURVE SMOOTH",
+"1253 900 OFFCURVE",
+"1183 1030 OFFCURVE",
+"990 1030 CURVE SMOOTH",
+"849 1030 OFFCURVE",
+"694 902 OFFCURVE",
+"566 740 CURVE",
+"656 1095 LINE SMOOTH",
+"696 1255 OFFCURVE",
+"735 1474 OFFCURVE",
+"735 1585 CURVE",
+"455 1585 LINE",
+"455 1439 OFFCURVE",
+"413 1242 OFFCURVE",
+"377 1095 CURVE SMOOTH",
+"105 0 LINE",
+"385 0 LINE",
+"485 400 LINE",
+"580 596 OFFCURVE",
+"745 787 OFFCURVE",
+"850 787 CURVE SMOOTH",
+"937 787 OFFCURVE",
+"953 722 OFFCURVE",
+"953 625 CURVE SMOOTH",
+"953 529 OFFCURVE",
+"889 374 OFFCURVE",
+"863 213 CURVE SMOOTH",
+"857 174 OFFCURVE",
+"853 134 OFFCURVE",
+"853 95 CURVE SMOOTH",
+"853 63 OFFCURVE",
+"854 31 OFFCURVE",
+"860 0 CURVE",
+"1140 0 LINE"
+);
+}
+);
+width = 1273;
+}
+);
+unicode = 0068;
+},
+{
+glyphname = LtnSmI;
+layers = (
+{
+anchors = (
+{
+name = H;
+position = "{235, 0}";
+},
+{
+name = L;
+position = "{250, -100}";
+},
+{
+name = O;
+position = "{455, 0}";
+},
+{
+name = R;
+position = "{745, 1000}";
+},
+{
+name = U;
+position = "{472, 1100}";
+}
+);
+layerId = master01;
+paths = (
+{
+closed = 1;
+nodes = (
+"361 1237 OFFCURVE",
+"404 1186 OFFCURVE",
+"467 1186 CURVE SMOOTH",
+"552 1186 OFFCURVE",
+"624 1259 OFFCURVE",
+"624 1338 CURVE SMOOTH",
+"624 1399 OFFCURVE",
+"578 1450 OFFCURVE",
+"513 1450 CURVE SMOOTH",
+"428 1450 OFFCURVE",
+"361 1375 OFFCURVE",
+"361 1297 CURVE SMOOTH"
+);
+},
+{
+closed = 1;
+nodes = (
+"335 886 OFFCURVE",
+"286 688 OFFCURVE",
+"246 537 CURVE SMOOTH",
+"207 388 LINE SMOOTH",
+"180 284 OFFCURVE",
+"165 172 OFFCURVE",
+"165 87 CURVE SMOOTH",
+"165 53 OFFCURVE",
+"167 24 OFFCURVE",
+"172 0 CURVE",
+"372 0 LINE",
+"365 37 OFFCURVE",
+"360 85 OFFCURVE",
+"360 136 CURVE SMOOTH",
+"360 208 OFFCURVE",
+"368 287 OFFCURVE",
+"386 357 CURVE SMOOTH",
+"431 536 LINE SMOOTH",
+"476 712 OFFCURVE",
+"525 912 OFFCURVE",
+"525 1000 CURVE",
+"335 1000 LINE"
+);
+}
+);
+width = 554;
+},
+{
+anchors = (
+{
+name = H;
+position = "{260, 0}";
+},
+{
+name = L;
+position = "{335, -100}";
+},
+{
+name = O;
+position = "{520, 0}";
+},
+{
+name = R;
+position = "{830, 1000}";
+},
+{
+name = U;
+position = "{535, 1100}";
+}
+);
+layerId = master02;
+paths = (
+{
+closed = 1;
+nodes = (
+"341 877 OFFCURVE",
+"290 698 OFFCURVE",
+"252 547 CURVE SMOOTH",
+"213 390 LINE SMOOTH",
+"193 309 OFFCURVE",
+"170 191 OFFCURVE",
+"170 88 CURVE SMOOTH",
+"170 57 OFFCURVE",
+"172 27 OFFCURVE",
+"177 0 CURVE",
+"472 0 LINE",
+"463 39 OFFCURVE",
+"459 82 OFFCURVE",
+"459 126 CURVE SMOOTH",
+"459 217 OFFCURVE",
+"475 310 OFFCURVE",
+"486 358 CURVE SMOOTH",
+"531 546 LINE SMOOTH",
+"572 719 OFFCURVE",
+"621 875 OFFCURVE",
+"625 1010 CURVE",
+"341 1010 LINE"
+);
+},
+{
+closed = 1;
+nodes = (
+"404 1259 OFFCURVE",
+"462 1197 OFFCURVE",
+"548 1197 CURVE SMOOTH",
+"668 1197 OFFCURVE",
+"759 1292 OFFCURVE",
+"759 1403 CURVE SMOOTH",
+"759 1483 OFFCURVE",
+"701 1544 OFFCURVE",
+"614 1544 CURVE SMOOTH",
+"496 1544 OFFCURVE",
+"404 1451 OFFCURVE",
+"404 1341 CURVE SMOOTH"
+);
+}
+);
+width = 625;
+}
+);
+unicode = 0069;
+},
+{
+glyphname = LtnSmJ;
+layers = (
+{
+anchors = (
+{
+name = L;
+position = "{-60, -500}";
+},
+{
+name = U;
+position = "{510, 1100}";
+}
+);
+layerId = master01;
+paths = (
+{
+closed = 1;
+nodes = (
+"370 856 OFFCURVE",
+"288 374 OFFCURVE",
+"214 77 CURVE SMOOTH",
+"152 -173 OFFCURVE",
+"29 -295 OFFCURVE",
+"-77 -295 CURVE SMOOTH",
+"-133 -295 OFFCURVE",
+"-217 -264 OFFCURVE",
+"-253 -229 CURVE",
+"-328 -397 LINE",
+"-278 -437 OFFCURVE",
+"-170 -465 OFFCURVE",
+"-114 -465 CURVE SMOOTH",
+"103 -465 OFFCURVE",
+"303 -314 OFFCURVE",
+"396 66 CURVE SMOOTH",
+"455 307 OFFCURVE",
+"560 872 OFFCURVE",
+"560 1000 CURVE",
+"370 1000 LINE"
+);
+},
+{
+closed = 1;
+nodes = (
+"397 1237 OFFCURVE",
+"440 1186 OFFCURVE",
+"503 1186 CURVE SMOOTH",
+"588 1186 OFFCURVE",
+"660 1259 OFFCURVE",
+"660 1338 CURVE SMOOTH",
+"660 1399 OFFCURVE",
+"614 1450 OFFCURVE",
+"549 1450 CURVE SMOOTH",
+"464 1450 OFFCURVE",
+"397 1375 OFFCURVE",
+"397 1297 CURVE SMOOTH"
+);
+}
+);
+width = 602;
+},
+{
+anchors = (
+{
+name = L;
+position = "{-45, -500}";
+},
+{
+name = U;
+position = "{565, 1100}";
+}
+);
+layerId = master02;
+paths = (
+{
+closed = 1;
+nodes = (
+"361 866 OFFCURVE",
+"284 395 OFFCURVE",
+"205 87 CURVE SMOOTH",
+"148 -136 OFFCURVE",
+"54 -221 OFFCURVE",
+"-56 -221 CURVE SMOOTH",
+"-137 -221 OFFCURVE",
+"-217 -187 OFFCURVE",
+"-252 -150 CURVE",
+"-355 -385 LINE",
+"-321 -417 OFFCURVE",
+"-172 -465 OFFCURVE",
+"-79 -465 CURVE SMOOTH",
+"170 -465 OFFCURVE",
+"388 -295 OFFCURVE",
+"481 75 CURVE SMOOTH",
+"501 157 OFFCURVE",
+"646 882 OFFCURVE",
+"646 1010 CURVE",
+"361 1010 LINE"
+);
+},
+{
+closed = 1;
+nodes = (
+"395 1259 OFFCURVE",
+"453 1197 OFFCURVE",
+"539 1197 CURVE SMOOTH",
+"659 1197 OFFCURVE",
+"750 1292 OFFCURVE",
+"750 1403 CURVE SMOOTH",
+"750 1483 OFFCURVE",
+"692 1544 OFFCURVE",
+"605 1544 CURVE SMOOTH",
+"487 1544 OFFCURVE",
+"395 1451 OFFCURVE",
+"395 1341 CURVE SMOOTH"
+);
+}
+);
+width = 695;
+}
+);
+unicode = 006A;
+},
+{
+glyphname = LtnSmK;
+layers = (
+{
+anchors = (
+{
+name = H;
+position = "{840, 0}";
+},
+{
+name = L;
+position = "{537, -100}";
+},
+{
+name = R;
+position = "{1225, 1000}";
+},
+{
+name = U;
+position = "{920, 1635}";
+}
+);
+layerId = master01;
+paths = (
+{
+closed = 1;
+nodes = (
+"570 1105 LINE SMOOTH",
+"614 1280 OFFCURVE",
+"645 1482 OFFCURVE",
+"645 1570 CURVE",
+"455 1570 LINE",
+"455 1456 OFFCURVE",
+"424 1259 OFFCURVE",
+"386 1107 CURVE SMOOTH",
+"338 915 OFFCURVE",
+"110 0 OFFCURVE",
+"110 0 CURVE",
+"295 0 LINE"
+);
+},
+{
+closed = 1;
+nodes = (
+"885 863 OFFCURVE",
+"654 700 OFFCURVE",
+"379 539 CURVE",
+"386 540 OFFCURVE",
+"393 540 OFFCURVE",
+"400 540 CURVE SMOOTH",
+"467 540 OFFCURVE",
+"559 514 OFFCURVE",
+"559 514 CURVE",
+"902 702 OFFCURVE",
+"1134 884 OFFCURVE",
+"1134 1000 CURVE",
+"909 1000 LINE"
+);
+},
+{
+closed = 1;
+nodes = (
+"863 238 OFFCURVE",
+"718 600 OFFCURVE",
+"527 600 CURVE",
+"385 529 LINE",
+"540 529 OFFCURVE",
+"667 246 OFFCURVE",
+"775 0 CURVE",
+"1010 0 LINE"
+);
+}
+);
+width = 1059;
+},
+{
+anchors = (
+{
+name = H;
+position = "{880, 0}";
+},
+{
+name = L;
+position = "{600, -100}";
+},
+{
+name = R;
+position = "{1330, 1000}";
+},
+{
+name = U;
+position = "{943, 1635}";
+}
+);
+layerId = master02;
+paths = (
+{
+closed = 1;
+nodes = (
+"920 864 OFFCURVE",
+"682 702 OFFCURVE",
+"483 576 CURVE",
+"676 518 LINE",
+"915 662 OFFCURVE",
+"1289 867 OFFCURVE",
+"1289 1010 CURVE",
+"964 1010 LINE"
+);
+},
+{
+closed = 1;
+nodes = (
+"992 302 OFFCURVE",
+"856 620 OFFCURVE",
+"633 620 CURVE",
+"442 529 LINE",
+"606 529 OFFCURVE",
+"722 252 OFFCURVE",
+"831 0 CURVE",
+"1168 0 LINE"
+);
+},
+{
+closed = 1;
+nodes = (
+"669 1105 LINE SMOOTH",
+"713 1280 OFFCURVE",
+"744 1497 OFFCURVE",
+"744 1585 CURVE",
+"462 1585 LINE",
+"462 1471 OFFCURVE",
+"431 1274 OFFCURVE",
+"393 1122 CURVE SMOOTH",
+"345 928 OFFCURVE",
+"115 0 OFFCURVE",
+"115 0 CURVE",
+"394 0 LINE"
+);
+}
+);
+width = 1209;
+}
+);
+unicode = 006B;
+},
+{
+glyphname = LtnSmL;
+layers = (
+{
+anchors = (
+{
+name = H;
+position = "{230, 0}";
+},
+{
+name = L;
+position = "{255, -100}";
+},
+{
+name = R;
+position = "{740, 1000}";
+},
+{
+name = U;
+position = "{630, 1635}";
+}
+);
+layerId = master01;
+paths = (
+{
+closed = 1;
+nodes = (
+"465 1456 OFFCURVE",
+"434 1259 OFFCURVE",
+"396 1107 CURVE SMOOTH",
+"241 489 LINE SMOOTH",
+"204 343 OFFCURVE",
+"186 220 OFFCURVE",
+"186 104 CURVE SMOOTH",
+"186 69 OFFCURVE",
+"188 34 OFFCURVE",
+"191 0 CURVE",
+"391 0 LINE",
+"386 32 OFFCURVE",
+"384 70 OFFCURVE",
+"384 112 CURVE SMOOTH",
+"384 230 OFFCURVE",
+"402 380 OFFCURVE",
+"436 517 CURVE SMOOTH",
+"580 1105 LINE SMOOTH",
+"623 1280 OFFCURVE",
+"655 1482 OFFCURVE",
+"655 1570 CURVE",
+"465 1570 LINE"
+);
+}
+);
+width = 575;
+},
+{
+anchors = (
+{
+name = H;
+position = "{275, 0}";
+},
+{
+name = L;
+position = "{350, -100}";
+},
+{
+name = R;
+position = "{850, 1000}";
+},
+{
+name = U;
+position = "{630, 1635}";
+}
+);
+layerId = master02;
+paths = (
+{
+closed = 1;
+nodes = (
+"461 1439 OFFCURVE",
+"420 1242 OFFCURVE",
+"383 1095 CURVE SMOOTH",
+"232 488 LINE SMOOTH",
+"208 394 OFFCURVE",
+"175 269 OFFCURVE",
+"175 116 CURVE SMOOTH",
+"175 89 OFFCURVE",
+"178 30 OFFCURVE",
+"180 0 CURVE",
+"470 0 LINE",
+"464 39 OFFCURVE",
+"461 80 OFFCURVE",
+"461 121 CURVE SMOOTH",
+"461 277 OFFCURVE",
+"498 434 OFFCURVE",
+"518 515 CURVE SMOOTH",
+"662 1095 LINE SMOOTH",
+"702 1255 OFFCURVE",
+"741 1474 OFFCURVE",
+"741 1585 CURVE",
+"461 1585 LINE"
+);
+}
+);
+width = 641;
+}
+);
+unicode = 006C;
+},
+{
+glyphname = LtnSmM;
+layers = (
+{
+anchors = (
+{
+name = H;
+position = "{805, 0}";
+},
+{
+name = L;
+position = "{780, -100}";
+},
+{
+name = U;
+position = "{1080, 1100}";
+}
+);
+layerId = master01;
+paths = (
+{
+closed = 1;
+nodes = (
+"1512 30 OFFCURVE",
+"1510 65 OFFCURVE",
+"1510 102 CURVE SMOOTH",
+"1510 143 OFFCURVE",
+"1515 188 OFFCURVE",
+"1522 238 CURVE SMOOTH",
+"1536 327 OFFCURVE",
+"1655 691 OFFCURVE",
+"1655 800 CURVE SMOOTH",
+"1655 930 OFFCURVE",
+"1594 1020 OFFCURVE",
+"1445 1020 CURVE SMOOTH",
+"1292 1020 OFFCURVE",
+"1124 867 OFFCURVE",
+"1026 680 CURVE",
+"1030 704 OFFCURVE",
+"1045 778 OFFCURVE",
+"1045 800 CURVE SMOOTH",
+"1045 932 OFFCURVE",
+"982 1020 OFFCURVE",
+"860 1020 CURVE SMOOTH",
+"717 1020 OFFCURVE",
+"563 879 OFFCURVE",
+"446 680 CURVE",
+"466 753 OFFCURVE",
+"476 880 OFFCURVE",
+"476 961 CURVE SMOOTH",
+"476 976 OFFCURVE",
+"476 989 OFFCURVE",
+"475 1000 CURVE",
+"295 1000 LINE",
+"296 983 OFFCURVE",
+"296 964 OFFCURVE",
+"296 945 CURVE SMOOTH",
+"296 825 OFFCURVE",
+"283 680 OFFCURVE",
+"262 595 CURVE SMOOTH",
+"115 0 LINE",
+"300 0 LINE",
+"389 359 LINE",
+"475 573 OFFCURVE",
+"685 850 OFFCURVE",
+"775 850 CURVE SMOOTH",
+"833 850 OFFCURVE",
+"865 813 OFFCURVE",
+"865 720 CURVE SMOOTH",
+"865 679 OFFCURVE",
+"846 583 OFFCURVE",
+"822 486 CURVE SMOOTH",
+"700 0 LINE",
+"885 0 LINE",
+"974 359 LINE",
+"1032 531 OFFCURVE",
+"1242 850 OFFCURVE",
+"1357 850 CURVE SMOOTH",
+"1425 850 OFFCURVE",
+"1457 813 OFFCURVE",
+"1457 720 CURVE SMOOTH",
+"1457 632 OFFCURVE",
+"1349 319 OFFCURVE",
+"1335 203 CURVE SMOOTH",
+"1330 158 OFFCURVE",
+"1327 115 OFFCURVE",
+"1327 77 CURVE SMOOTH",
+"1327 48 OFFCURVE",
+"1331 21 OFFCURVE",
+"1335 0 CURVE",
+"1520 0 LINE"
+);
+}
+);
+width = 1680;
+},
+{
+anchors = (
+{
+name = H;
+position = "{830, 0}";
+},
+{
+name = L;
+position = "{805, -100}";
+},
+{
+name = U;
+position = "{1105, 1100}";
+}
+);
+layerId = master02;
+paths = (
+{
+closed = 1;
+nodes = (
+"1604 29 OFFCURVE",
+"1602 60 OFFCURVE",
+"1602 90 CURVE SMOOTH",
+"1602 136 OFFCURVE",
+"1606 181 OFFCURVE",
+"1613 228 CURVE SMOOTH",
+"1628 333 OFFCURVE",
+"1747 670 OFFCURVE",
+"1747 822 CURVE SMOOTH",
+"1747 958 OFFCURVE",
+"1681 1030 OFFCURVE",
+"1547 1030 CURVE SMOOTH",
+"1391 1030 OFFCURVE",
+"1227 876 OFFCURVE",
+"1120 705 CURVE",
+"1125 738 OFFCURVE",
+"1127 769 OFFCURVE",
+"1127 798 CURVE SMOOTH",
+"1127 944 OFFCURVE",
+"1067 1030 OFFCURVE",
+"941 1030 CURVE SMOOTH",
+"815 1030 OFFCURVE",
+"664 911 OFFCURVE",
+"537 715 CURVE",
+"553 840 OFFCURVE",
+"556 911 OFFCURVE",
+"556 955 CURVE SMOOTH",
+"556 981 OFFCURVE",
+"554 998 OFFCURVE",
+"551 1010 CURVE",
+"291 1010 LINE",
+"293 999 OFFCURVE",
+"294 975 OFFCURVE",
+"294 942 CURVE SMOOTH",
+"294 855 OFFCURVE",
+"286 710 OFFCURVE",
+"261 609 CURVE SMOOTH",
+"110 0 LINE",
+"390 0 LINE",
+"479 370 LINE",
+"541 552 OFFCURVE",
+"711 787 OFFCURVE",
+"791 787 CURVE SMOOTH",
+"843 787 OFFCURVE",
+"857 741 OFFCURVE",
+"857 688 CURVE SMOOTH",
+"857 625 OFFCURVE",
+"832 535 OFFCURVE",
+"819 483 CURVE SMOOTH",
+"695 0 LINE",
+"975 0 LINE",
+"1067 370 LINE",
+"1139 556 OFFCURVE",
+"1300 787 OFFCURVE",
+"1381 787 CURVE SMOOTH",
+"1434 787 OFFCURVE",
+"1450 762 OFFCURVE",
+"1450 706 CURVE SMOOTH",
+"1450 592 OFFCURVE",
+"1350 331 OFFCURVE",
+"1330 205 CURVE SMOOTH",
+"1324 168 OFFCURVE",
+"1321 132 OFFCURVE",
+"1321 95 CURVE SMOOTH",
+"1321 63 OFFCURVE",
+"1323 31 OFFCURVE",
+"1329 0 CURVE",
+"1609 0 LINE"
+);
+}
+);
+width = 1770;
+}
+);
+unicode = 006D;
+},
+{
+glyphname = LtnSmN;
+layers = (
+{
+anchors = (
+{
+name = H;
+position = "{540, 0}";
+},
+{
+name = L;
+position = "{565, -100}";
+},
+{
+name = U;
+position = "{815, 1100}";
+}
+);
+layerId = master01;
+paths = (
+{
+closed = 1;
+nodes = (
+"1052 30 OFFCURVE",
+"1050 65 OFFCURVE",
+"1050 102 CURVE SMOOTH",
+"1050 143 OFFCURVE",
+"1055 188 OFFCURVE",
+"1062 238 CURVE SMOOTH",
+"1075 327 OFFCURVE",
+"1175 636 OFFCURVE",
+"1175 745 CURVE SMOOTH",
+"1175 917 OFFCURVE",
+"1100 1020 OFFCURVE",
+"935 1020 CURVE SMOOTH",
+"755 1020 OFFCURVE",
+"581 870 OFFCURVE",
+"445 672 CURVE",
+"463 740 OFFCURVE",
+"477 873 OFFCURVE",
+"477 957 CURVE SMOOTH",
+"477 973 OFFCURVE",
+"476 988 OFFCURVE",
+"475 1000 CURVE",
+"295 1000 LINE",
+"295 961 LINE SMOOTH",
+"295 833 OFFCURVE",
+"283 679 OFFCURVE",
+"262 595 CURVE SMOOTH",
+"115 0 LINE",
+"300 0 LINE",
+"392 370 LINE",
+"478 573 OFFCURVE",
+"708 850 OFFCURVE",
+"835 850 CURVE SMOOTH",
+"927 850 OFFCURVE",
+"975 798 OFFCURVE",
+"975 680 CURVE SMOOTH",
+"975 592 OFFCURVE",
+"888 319 OFFCURVE",
+"875 203 CURVE SMOOTH",
+"870 158 OFFCURVE",
+"867 115 OFFCURVE",
+"867 77 CURVE SMOOTH",
+"867 48 OFFCURVE",
+"871 21 OFFCURVE",
+"875 0 CURVE",
+"1060 0 LINE"
+);
+}
+);
+width = 1195;
+},
+{
+anchors = (
+{
+name = H;
+position = "{560, 0}";
+},
+{
+name = L;
+position = "{635, -100}";
+},
+{
+name = U;
+position = "{835, 1100}";
+}
+);
+layerId = master02;
+paths = (
+{
+closed = 1;
+nodes = (
+"1140 29 OFFCURVE",
+"1138 60 OFFCURVE",
+"1138 90 CURVE SMOOTH",
+"1138 136 OFFCURVE",
+"1141 182 OFFCURVE",
+"1149 228 CURVE SMOOTH",
+"1173 366 OFFCURVE",
+"1258 591 OFFCURVE",
+"1258 725 CURVE SMOOTH",
+"1258 890 OFFCURVE",
+"1188 1030 OFFCURVE",
+"995 1030 CURVE SMOOTH",
+"844 1030 OFFCURVE",
+"685 903 OFFCURVE",
+"546 715 CURVE",
+"555 771 OFFCURVE",
+"569 875 OFFCURVE",
+"569 933 CURVE SMOOTH",
+"569 962 OFFCURVE",
+"568 988 OFFCURVE",
+"565 1010 CURVE",
+"290 1010 LINE",
+"290 962 LINE SMOOTH",
+"290 859 OFFCURVE",
+"280 685 OFFCURVE",
+"261 609 CURVE SMOOTH",
+"110 0 LINE",
+"388 0 LINE",
+"490 405 LINE",
+"569 569 OFFCURVE",
+"740 787 OFFCURVE",
+"835 787 CURVE SMOOTH",
+"922 787 OFFCURVE",
+"958 732 OFFCURVE",
+"958 625 CURVE SMOOTH",
+"958 527 OFFCURVE",
+"891 369 OFFCURVE",
+"866 205 CURVE SMOOTH",
+"860 168 OFFCURVE",
+"857 132 OFFCURVE",
+"857 95 CURVE SMOOTH",
+"857 63 OFFCURVE",
+"859 31 OFFCURVE",
+"865 0 CURVE",
+"1145 0 LINE"
+);
+}
+);
+width = 1281;
+}
+);
+unicode = 006E;
+},
+{
+glyphname = LtnSmO;
+layers = (
+{
+anchors = (
+{
+name = H;
+position = "{510, 0}";
+},
+{
+name = L;
+position = "{505, -100}";
+},
+{
+name = O;
+position = "{800, 0}";
+},
+{
+name = R;
+position = "{1330, 1000}";
+},
+{
+name = U;
+position = "{785, 1100}";
+}
+);
+layerId = master01;
+paths = (
+{
+closed = 1;
+nodes = (
+"142 114 OFFCURVE",
+"306 -25 OFFCURVE",
+"530 -25 CURVE SMOOTH",
+"896 -25 OFFCURVE",
+"1138 314 OFFCURVE",
+"1138 648 CURVE SMOOTH",
+"1138 879 OFFCURVE",
+"985 1020 OFFCURVE",
+"761 1020 CURVE SMOOTH",
+"387 1020 OFFCURVE",
+"142 677 OFFCURVE",
+"142 344 CURVE SMOOTH"
+);
+},
+{
+closed = 1;
+nodes = (
+"859 862 OFFCURVE",
+"947 767 OFFCURVE",
+"947 611 CURVE SMOOTH",
+"947 391 OFFCURVE",
+"795 132 OFFCURVE",
+"559 132 CURVE SMOOTH",
+"421 132 OFFCURVE",
+"333 226 OFFCURVE",
+"333 380 CURVE SMOOTH",
+"333 599 OFFCURVE",
+"486 862 OFFCURVE",
+"721 862 CURVE SMOOTH"
+);
+}
+);
+width = 1133;
+},
+{
+anchors = (
+{
+name = H;
+position = "{518, 0}";
+},
+{
+name = L;
+position = "{530, -100}";
+},
+{
+name = O;
+position = "{730, 0}";
+},
+{
+name = R;
+position = "{1350, 1000}";
+},
+{
+name = U;
+position = "{795, 1100}";
+}
+);
+layerId = master02;
+paths = (
+{
+closed = 1;
+nodes = (
+"140 128 OFFCURVE",
+"289 -25 OFFCURVE",
+"520 -25 CURVE SMOOTH",
+"906 -25 OFFCURVE",
+"1144 295 OFFCURVE",
+"1144 641 CURVE SMOOTH",
+"1144 880 OFFCURVE",
+"1003 1030 OFFCURVE",
+"773 1030 CURVE SMOOTH",
+"390 1030 OFFCURVE",
+"140 718 OFFCURVE",
+"140 370 CURVE SMOOTH"
+);
+},
+{
+closed = 1;
+nodes = (
+"826 807 OFFCURVE",
+"879 737 OFFCURVE",
+"879 612 CURVE SMOOTH",
+"879 413 OFFCURVE",
+"764 198 OFFCURVE",
+"566 198 CURVE SMOOTH",
+"464 198 OFFCURVE",
+"404 264 OFFCURVE",
+"404 385 CURVE SMOOTH",
+"404 570 OFFCURVE",
+"512 807 OFFCURVE",
+"718 807 CURVE SMOOTH"
+);
+}
+);
+width = 1139;
+}
+);
+unicode = 006F;
+},
+{
+glyphname = LtnSmP;
+layers = (
+{
+anchors = (
+{
+name = H;
+position = "{105, -435}";
+},
+{
+name = L;
+position = "{405, -500}";
+},
+{
+name = R;
+position = "{1360, 1000}";
+},
+{
+name = U;
+position = "{805, 1100}";
+}
+);
+layerId = master01;
+paths = (
+{
+closed = 1;
+nodes = (
+"215 -388 OFFCURVE",
+"229 -282 OFFCURVE",
+"255 -175 CURVE SMOOTH",
+"320 85 LINE",
+"399 20 OFFCURVE",
+"468 -25 OFFCURVE",
+"575 -25 CURVE SMOOTH",
+"685 -25 OFFCURVE",
+"797 9 OFFCURVE",
+"895 85 CURVE SMOOTH",
+"1063 215 OFFCURVE",
+"1185 438 OFFCURVE",
+"1185 680 CURVE SMOOTH",
+"1185 878 OFFCURVE",
+"1101 1020 OFFCURVE",
+"920 1020 CURVE SMOOTH",
+"757 1020 OFFCURVE",
+"559 842 OFFCURVE",
+"452 680 CURVE",
+"468 760 OFFCURVE",
+"477 860 OFFCURVE",
+"477 940 CURVE SMOOTH",
+"477 962 OFFCURVE",
+"477 982 OFFCURVE",
+"475 1000 CURVE",
+"295 1000 LINE",
+"295 971 LINE SMOOTH",
+"295 819 OFFCURVE",
+"273 625 OFFCURVE",
+"235 475 CURVE SMOOTH",
+"70 -175 LINE SMOOTH",
+"43 -281 OFFCURVE",
+"20 -398 OFFCURVE",
+"20 -480 CURVE",
+"215 -480 LINE"
+);
+},
+{
+closed = 1;
+nodes = (
+"544 656 OFFCURVE",
+"732 850 OFFCURVE",
+"840 850 CURVE SMOOTH",
+"939 850 OFFCURVE",
+"990 763 OFFCURVE",
+"990 630 CURVE SMOOTH",
+"990 491 OFFCURVE",
+"926 322 OFFCURVE",
+"815 220 CURVE SMOOTH",
+"759 168 OFFCURVE",
+"693 135 OFFCURVE",
+"615 135 CURVE SMOOTH",
+"523 135 OFFCURVE",
+"479 161 OFFCURVE",
+"365 255 CURVE",
+"407 432 LINE"
+);
+}
+);
+width = 1185;
+},
+{
+anchors = (
+{
+name = H;
+position = "{121, -435}";
+},
+{
+name = L;
+position = "{555, -500}";
+},
+{
+name = R;
+position = "{1425, 1000}";
+},
+{
+name = U;
+position = "{855, 1100}";
+}
+);
+layerId = master02;
+paths = (
+{
+closed = 1;
+nodes = (
+"605 650 OFFCURVE",
+"765 794 OFFCURVE",
+"854 794 CURVE SMOOTH",
+"932 794 OFFCURVE",
+"975 719 OFFCURVE",
+"975 609 CURVE SMOOTH",
+"975 478 OFFCURVE",
+"924 334 OFFCURVE",
+"823 258 CURVE SMOOTH",
+"778 224 OFFCURVE",
+"723 204 OFFCURVE",
+"658 204 CURVE SMOOTH",
+"589 204 OFFCURVE",
+"517 243 OFFCURVE",
+"473 297 CURVE",
+"523 500 LINE"
+);
+},
+{
+closed = 1;
+nodes = (
+"300 962 LINE SMOOTH",
+"300 859 OFFCURVE",
+"290 685 OFFCURVE",
+"271 609 CURVE SMOOTH",
+"75 -180 LINE SMOOTH",
+"49 -286 OFFCURVE",
+"25 -403 OFFCURVE",
+"25 -485 CURVE",
+"314 -485 LINE",
+"314 -393 OFFCURVE",
+"328 -287 OFFCURVE",
+"362 -149 CURVE SMOOTH",
+"415 64 LINE",
+"495 10 OFFCURVE",
+"562 -25 OFFCURVE",
+"667 -25 CURVE SMOOTH",
+"750 -25 OFFCURVE",
+"833 -2 OFFCURVE",
+"909 40 CURVE SMOOTH",
+"1112 152 OFFCURVE",
+"1267 398 OFFCURVE",
+"1267 685 CURVE SMOOTH",
+"1267 884 OFFCURVE",
+"1176 1030 OFFCURVE",
+"1004 1030 CURVE SMOOTH",
+"849 1030 OFFCURVE",
+"677 901 OFFCURVE",
+"565 752 CURVE",
+"574 808 OFFCURVE",
+"579 875 OFFCURVE",
+"579 933 CURVE SMOOTH",
+"579 962 OFFCURVE",
+"578 988 OFFCURVE",
+"575 1010 CURVE",
+"300 1010 LINE"
+);
+}
+);
+width = 1272;
+}
+);
+unicode = 0070;
+},
+{
+glyphname = LtnSmQ;
+layers = (
+{
+anchors = (
+{
+name = L;
+position = "{370, -500}";
+},
+{
+name = R;
+position = "{1320, 1000}";
+},
+{
+name = U;
+position = "{770, 1100}";
+}
+);
+layerId = master01;
+paths = (
+{
+closed = 1;
+nodes = (
+"843 -391 OFFCURVE",
+"858 -294 OFFCURVE",
+"885 -185 CURVE SMOOTH",
+"1165 945 LINE",
+"1066 980 OFFCURVE",
+"946 1020 OFFCURVE",
+"825 1020 CURVE SMOOTH",
+"675 1020 OFFCURVE",
+"550 977 OFFCURVE",
+"440 890 CURVE SMOOTH",
+"260 747 OFFCURVE",
+"135 505 OFFCURVE",
+"135 285 CURVE SMOOTH",
+"135 73 OFFCURVE",
+"261 -25 OFFCURVE",
+"380 -25 CURVE SMOOTH",
+"524 -25 OFFCURVE",
+"751 172 OFFCURVE",
+"825 300 CURVE",
+"693 -180 LINE SMOOTH",
+"662 -294 OFFCURVE",
+"648 -414 OFFCURVE",
+"648 -480 CURVE",
+"843 -480 LINE"
+);
+},
+{
+closed = 1;
+nodes = (
+"807 413 OFFCURVE",
+"550 140 OFFCURVE",
+"455 140 CURVE SMOOTH",
+"376 140 OFFCURVE",
+"330 199 OFFCURVE",
+"330 330 CURVE SMOOTH",
+"330 481 OFFCURVE",
+"400 658 OFFCURVE",
+"515 760 CURVE SMOOTH",
+"580 817 OFFCURVE",
+"658 855 OFFCURVE",
+"750 855 CURVE SMOOTH",
+"811 855 OFFCURVE",
+"893 840 OFFCURVE",
+"947 817 CURVE",
+"885 565 LINE"
+);
+}
+);
+width = 1115;
+},
+{
+anchors = (
+{
+name = L;
+position = "{415, -500}";
+},
+{
+name = R;
+position = "{1400, 1000}";
+},
+{
+name = U;
+position = "{815, 1100}";
+}
+);
+layerId = master02;
+paths = (
+{
+closed = 1;
+nodes = (
+"832 467 OFFCURVE",
+"615 211 OFFCURVE",
+"520 211 CURVE SMOOTH",
+"457 211 OFFCURVE",
+"429 263 OFFCURVE",
+"429 362 CURVE SMOOTH",
+"429 484 OFFCURVE",
+"469 616 OFFCURVE",
+"551 702 CURVE SMOOTH",
+"605 758 OFFCURVE",
+"676 794 OFFCURVE",
+"765 794 CURVE SMOOTH",
+"806 794 OFFCURVE",
+"897 781 OFFCURVE",
+"933 762 CURVE",
+"889 583 LINE"
+);
+},
+{
+closed = 1;
+nodes = (
+"936 -396 OFFCURVE",
+"951 -299 OFFCURVE",
+"978 -190 CURVE SMOOTH",
+"1261 955 LINE",
+"1134 991 OFFCURVE",
+"972 1030 OFFCURVE",
+"819 1030 CURVE SMOOTH",
+"678 1030 OFFCURVE",
+"516 969 OFFCURVE",
+"403 874 CURVE SMOOTH",
+"244 739 OFFCURVE",
+"145 535 OFFCURVE",
+"145 331 CURVE SMOOTH",
+"145 105 OFFCURVE",
+"275 -25 OFFCURVE",
+"391 -25 CURVE SMOOTH",
+"529 -25 OFFCURVE",
+"729 134 OFFCURVE",
+"838 300 CURVE",
+"706 -185 LINE SMOOTH",
+"675 -299 OFFCURVE",
+"661 -419 OFFCURVE",
+"661 -485 CURVE",
+"936 -485 LINE"
+);
+}
+);
+width = 1206;
+}
+);
+unicode = 0071;
+},
+{
+glyphname = LtnSmR;
+layers = (
+{
+anchors = (
+{
+name = H;
+position = "{210, 0}";
+},
+{
+name = L;
+position = "{220, -100}";
+},
+{
+name = U;
+position = "{670, 1100}";
+}
+);
+layerId = master01;
+paths = (
+{
+closed = 1;
+nodes = (
+"402 415 LINE",
+"502 602 OFFCURVE",
+"703 850 OFFCURVE",
+"785 850 CURVE SMOOTH",
+"831 850 OFFCURVE",
+"855 801 OFFCURVE",
+"855 740 CURVE SMOOTH",
+"855 715 OFFCURVE",
+"852 689 OFFCURVE",
+"845 660 CURVE",
+"1010 690 LINE",
+"1022 737 OFFCURVE",
+"1030 783 OFFCURVE",
+"1030 825 CURVE SMOOTH",
+"1030 935 OFFCURVE",
+"986 1020 OFFCURVE",
+"865 1020 CURVE SMOOTH",
+"735 1020 OFFCURVE",
+"575 867 OFFCURVE",
+"445 675 CURVE",
+"467 773 OFFCURVE",
+"475 929 OFFCURVE",
+"475 1000 CURVE",
+"295 1000 LINE",
+"295 961 LINE SMOOTH",
+"295 833 OFFCURVE",
+"283 679 OFFCURVE",
+"262 595 CURVE SMOOTH",
+"115 0 LINE",
+"300 0 LINE"
+);
+}
+);
+width = 910;
+},
+{
+anchors = (
+{
+name = H;
+position = "{225, 0}";
+},
+{
+name = L;
+position = "{255, -100}";
+},
+{
+name = U;
+position = "{765, 1100}";
+}
+);
+layerId = master02;
+paths = (
+{
+closed = 1;
+nodes = (
+"494 420 LINE",
+"555 557 OFFCURVE",
+"727 773 OFFCURVE",
+"810 773 CURVE SMOOTH",
+"864 773 OFFCURVE",
+"887 737 OFFCURVE",
+"887 678 CURVE SMOOTH",
+"887 662 OFFCURVE",
+"885 644 OFFCURVE",
+"882 624 CURVE",
+"1114 658 LINE",
+"1123 706 OFFCURVE",
+"1136 752 OFFCURVE",
+"1136 794 CURVE SMOOTH",
+"1136 931 OFFCURVE",
+"1084 1030 OFFCURVE",
+"963 1030 CURVE SMOOTH",
+"828 1030 OFFCURVE",
+"670 883 OFFCURVE",
+"544 716 CURVE",
+"555 787 OFFCURVE",
+"570 960 OFFCURVE",
+"570 1010 CURVE",
+"295 1010 LINE",
+"295 962 LINE SMOOTH",
+"295 894 OFFCURVE",
+"281 689 OFFCURVE",
+"261 609 CURVE SMOOTH",
+"110 0 LINE",
+"390 0 LINE"
+);
+}
+);
+width = 1021;
+}
+);
+unicode = 0072;
+},
+{
+glyphname = LtnSmS;
+layers = (
+{
+anchors = (
+{
+name = H;
+position = "{435, 0}";
+},
+{
+name = L;
+position = "{440, -100}";
+},
+{
+name = U;
+position = "{710, 1100}";
+}
+);
+layerId = master01;
+paths = (
+{
+closed = 1;
+nodes = (
+"930 978 OFFCURVE",
+"815 1020 OFFCURVE",
+"640 1020 CURVE SMOOTH",
+"384 1020 OFFCURVE",
+"230 881 OFFCURVE",
+"230 716 CURVE SMOOTH",
+"230 614 OFFCURVE",
+"320 533 OFFCURVE",
+"466 461 CURVE SMOOTH",
+"638 376 OFFCURVE",
+"700 333 OFFCURVE",
+"700 265 CURVE SMOOTH",
+"700 188 OFFCURVE",
+"621 132 OFFCURVE",
+"532 132 CURVE SMOOTH",
+"376 132 OFFCURVE",
+"244 216 OFFCURVE",
+"159 325 CURVE",
+"71 158 LINE",
+"160 60 OFFCURVE",
+"296 -25 OFFCURVE",
+"488 -25 CURVE SMOOTH",
+"713 -25 OFFCURVE",
+"891 106 OFFCURVE",
+"891 306 CURVE SMOOTH",
+"891 432 OFFCURVE",
+"774 515 OFFCURVE",
+"626 593 CURVE SMOOTH",
+"476 672 OFFCURVE",
+"418 695 OFFCURVE",
+"418 753 CURVE SMOOTH",
+"418 822 OFFCURVE",
+"494 862 OFFCURVE",
+"619 862 CURVE SMOOTH",
+"743 862 OFFCURVE",
+"854 808 OFFCURVE",
+"911 769 CURVE",
+"990 941 LINE"
+);
+}
+);
+width = 945;
+},
+{
+anchors = (
+{
+name = H;
+position = "{455, 0}";
+},
+{
+name = L;
+position = "{530, -100}";
+},
+{
+name = U;
+position = "{745, 1100}";
+}
+);
+layerId = master02;
+paths = (
+{
+closed = 1;
+nodes = (
+"990 990 OFFCURVE",
+"854 1030 OFFCURVE",
+"691 1030 CURVE SMOOTH",
+"457 1030 OFFCURVE",
+"217 936 OFFCURVE",
+"217 722 CURVE SMOOTH",
+"217 593 OFFCURVE",
+"306 517 OFFCURVE",
+"501 430 CURVE SMOOTH",
+"648 364 OFFCURVE",
+"710 345 OFFCURVE",
+"710 288 CURVE SMOOTH",
+"710 224 OFFCURVE",
+"649 197 OFFCURVE",
+"549 197 CURVE SMOOTH",
+"392 197 OFFCURVE",
+"276 280 OFFCURVE",
+"197 371 CURVE",
+"72 129 LINE",
+"143 68 OFFCURVE",
+"319 -25 OFFCURVE",
+"498 -25 CURVE SMOOTH",
+"767 -25 OFFCURVE",
+"979 104 OFFCURVE",
+"979 315 CURVE SMOOTH",
+"979 440 OFFCURVE",
+"884 513 OFFCURVE",
+"695 600 CURVE SMOOTH",
+"581 652 OFFCURVE",
+"477 688 OFFCURVE",
+"477 743 CURVE SMOOTH",
+"477 785 OFFCURVE",
+"548 808 OFFCURVE",
+"646 808 CURVE SMOOTH",
+"785 808 OFFCURVE",
+"895 764 OFFCURVE",
+"961 716 CURVE",
+"1058 952 LINE"
+);
+}
+);
+width = 1015;
+}
+);
+unicode = 0073;
+},
+{
+glyphname = LtnSmT;
+layers = (
+{
+anchors = (
+{
+name = H;
+position = "{455, 0}";
+},
+{
+name = L;
+position = "{390, -100}";
+},
+{
+name = R;
+position = "{1025, 1000}";
+},
+{
+name = U;
+position = "{605, 1360}";
+}
+);
+layerId = master01;
+paths = (
+{
+closed = 1;
+nodes = (
+"665 169 OFFCURVE",
+"593 134 OFFCURVE",
+"527 134 CURVE SMOOTH",
+"448 134 OFFCURVE",
+"425 188 OFFCURVE",
+"425 247 CURVE SMOOTH",
+"425 274 OFFCURVE",
+"429 301 OFFCURVE",
+"434 326 CURVE SMOOTH",
+"470 519 OFFCURVE",
+"564 843 OFFCURVE",
+"677 1294 CURVE",
+"492 1294 LINE",
+"377 841 OFFCURVE",
+"263 429 OFFCURVE",
+"243 301 CURVE SMOOTH",
+"238 269 OFFCURVE",
+"236 240 OFFCURVE",
+"236 213 CURVE SMOOTH",
+"236 41 OFFCURVE",
+"330 -25 OFFCURVE",
+"465 -25 CURVE SMOOTH",
+"535 -25 OFFCURVE",
+"634 -6 OFFCURVE",
+"740 52 CURVE",
+"752 211 LINE"
+);
+},
+{
+closed = 1;
+nodes = (
+"887 833 LINE",
+"923 975 LINE",
+"213 975 LINE",
+"177 833 LINE"
+);
+}
+);
+width = 815;
+},
+{
+anchors = (
+{
+name = H;
+position = "{470, 0}";
+},
+{
+name = L;
+position = "{520, -100}";
+},
+{
+name = R;
+position = "{1075, 1000}";
+},
+{
+name = U;
+position = "{640, 1360}";
+}
+);
+layerId = master02;
+paths = (
+{
+closed = 1;
+nodes = (
+"740 230 OFFCURVE",
+"670 204 OFFCURVE",
+"619 204 CURVE SMOOTH",
+"556 204 OFFCURVE",
+"536 250 OFFCURVE",
+"536 318 CURVE SMOOTH",
+"536 347 OFFCURVE",
+"539 380 OFFCURVE",
+"545 415 CURVE SMOOTH",
+"567 549 OFFCURVE",
+"700 1039 OFFCURVE",
+"767 1307 CURVE",
+"487 1307 LINE",
+"419 1038 OFFCURVE",
+"265 471 OFFCURVE",
+"243 328 CURVE SMOOTH",
+"239 302 OFFCURVE",
+"237 277 OFFCURVE",
+"237 253 CURVE SMOOTH",
+"237 73 OFFCURVE",
+"351 -25 OFFCURVE",
+"518 -25 CURVE SMOOTH",
+"590 -25 OFFCURVE",
+"703 -4 OFFCURVE",
+"812 55 CURVE",
+"831 278 LINE"
+);
+},
+{
+closed = 1;
+nodes = (
+"995 995 LINE",
+"220 995 LINE",
+"170 797 LINE",
+"945 797 LINE"
+);
+}
+);
+width = 900;
+}
+);
+unicode = 0074;
+},
+{
+glyphname = LtnSmU;
+layers = (
+{
+anchors = (
+{
+name = H;
+position = "{465, 0}";
+},
+{
+name = L;
+position = "{504, -100}";
+},
+{
+name = O;
+position = "{640, 0}";
+},
+{
+name = R;
+position = "{1375, 1000}";
+},
+{
+name = U;
+position = "{804, 1100}";
+}
+);
+layerId = master01;
+paths = (
+{
+closed = 1;
+nodes = (
+"1036 29 OFFCURVE",
+"1035 62 OFFCURVE",
+"1035 100 CURVE SMOOTH",
+"1035 206 OFFCURVE",
+"1054 341 OFFCURVE",
+"1080 455 CURVE SMOOTH",
+"1135 689 OFFCURVE",
+"1197 895 OFFCURVE",
+"1205 1000 CURVE",
+"1010 1000 LINE",
+"1003 882 OFFCURVE",
+"971 769 OFFCURVE",
+"920 565 CURVE",
+"827 376 OFFCURVE",
+"573 135 OFFCURVE",
+"475 135 CURVE SMOOTH",
+"409 135 OFFCURVE",
+"365 181 OFFCURVE",
+"365 280 CURVE SMOOTH",
+"365 347 OFFCURVE",
+"407 500 OFFCURVE",
+"459 702 CURVE SMOOTH",
+"494 837 OFFCURVE",
+"515 925 OFFCURVE",
+"520 1000 CURVE",
+"325 1000 LINE",
+"313 882 OFFCURVE",
+"295 809 OFFCURVE",
+"265 685 CURVE SMOOTH",
+"195 395 LINE SMOOTH",
+"179 330 OFFCURVE",
+"170 275 OFFCURVE",
+"170 225 CURVE SMOOTH",
+"170 60 OFFCURVE",
+"257 -25 OFFCURVE",
+"410 -25 CURVE SMOOTH",
+"551 -25 OFFCURVE",
+"745 118 OFFCURVE",
+"880 305 CURVE",
+"861 196 OFFCURVE",
+"860 98 OFFCURVE",
+"860 0 CURVE",
+"1040 0 LINE"
+);
+}
+);
+width = 1175;
+},
+{
+anchors = (
+{
+name = H;
+position = "{455, 0}";
+},
+{
+name = L;
+position = "{530, -100}";
+},
+{
+name = O;
+position = "{630, 0}";
+},
+{
+name = R;
+position = "{1448, 1000}";
+},
+{
+name = U;
+position = "{830, 1100}";
+}
+);
+layerId = master02;
+paths = (
+{
+closed = 1;
+nodes = (
+"1113 29 OFFCURVE",
+"1112 62 OFFCURVE",
+"1112 100 CURVE SMOOTH",
+"1112 206 OFFCURVE",
+"1131 341 OFFCURVE",
+"1157 455 CURVE SMOOTH",
+"1212 689 OFFCURVE",
+"1274 905 OFFCURVE",
+"1282 1010 CURVE",
+"993 1010 LINE",
+"981 889 OFFCURVE",
+"992 918 OFFCURVE",
+"910 595 CURVE",
+"835 427 OFFCURVE",
+"618 205 OFFCURVE",
+"537 205 CURVE SMOOTH",
+"491 205 OFFCURVE",
+"462 236 OFFCURVE",
+"462 308 CURVE SMOOTH",
+"462 405 OFFCURVE",
+"536 663 OFFCURVE",
+"549 712 CURVE SMOOTH",
+"583 847 OFFCURVE",
+"605 935 OFFCURVE",
+"610 1010 CURVE",
+"323 1010 LINE",
+"312 891 OFFCURVE",
+"296 819 OFFCURVE",
+"264 693 CURVE SMOOTH",
+"191 401 LINE SMOOTH",
+"173 330 OFFCURVE",
+"165 267 OFFCURVE",
+"165 214 CURVE SMOOTH",
+"165 55 OFFCURVE",
+"252 -25 OFFCURVE",
+"381 -25 CURVE SMOOTH",
+"545 -25 OFFCURVE",
+"769 160 OFFCURVE",
+"860 295 CURVE",
+"850 227 OFFCURVE",
+"842 53 OFFCURVE",
+"842 0 CURVE",
+"1117 0 LINE"
+);
+}
+);
+width = 1257;
+}
+);
+unicode = 0075;
+},
+{
+glyphname = LtnSmV;
+layers = (
+{
+anchors = (
+{
+name = H;
+position = "{359, 0}";
+},
+{
+name = L;
+position = "{350, -100}";
+},
+{
+name = O;
+position = "{565, 0}";
+},
+{
+name = U;
+position = "{650, 1100}";
+}
+);
+layerId = master01;
+paths = (
+{
+closed = 1;
+nodes = (
+"232 825 OFFCURVE",
+"256 602 OFFCURVE",
+"256 354 CURVE SMOOTH",
+"256 241 OFFCURVE",
+"251 122 OFFCURVE",
+"241 0 CURVE",
+"441 0 LINE",
+"744 336 OFFCURVE",
+"1056 765 OFFCURVE",
+"1056 1000 CURVE",
+"856 1000 LINE",
+"856 769 OFFCURVE",
+"606 394 OFFCURVE",
+"404 176 CURVE",
+"421 277 OFFCURVE",
+"429 402 OFFCURVE",
+"429 526 CURVE SMOOTH",
+"429 707 OFFCURVE",
+"412 887 OFFCURVE",
+"380 1000 CURVE",
+"180 1000 LINE"
+);
+}
+);
+width = 941;
+},
+{
+anchors = (
+{
+name = H;
+position = "{505, 0}";
+},
+{
+name = L;
+position = "{410, -100}";
+},
+{
+name = O;
+position = "{690, 0}";
+},
+{
+name = U;
+position = "{695, 1100}";
+}
+);
+layerId = master02;
+paths = (
+{
+closed = 1;
+nodes = (
+"881 788 OFFCURVE",
+"719 534 OFFCURVE",
+"507 270 CURVE",
+"516 353 OFFCURVE",
+"521 457 OFFCURVE",
+"521 564 CURVE SMOOTH",
+"521 730 OFFCURVE",
+"507 903 OFFCURVE",
+"472 1010 CURVE",
+"195 1010 LINE",
+"259 758 OFFCURVE",
+"282 509 OFFCURVE",
+"282 262 CURVE SMOOTH",
+"282 174 OFFCURVE",
+"279 87 OFFCURVE",
+"274 0 CURVE",
+"535 0 LINE",
+"823 314 OFFCURVE",
+"1159 766 OFFCURVE",
+"1159 1010 CURVE",
+"881 1010 LINE"
+);
+}
+);
+width = 1049;
+}
+);
+unicode = 0076;
+},
+{
+glyphname = LtnSmW;
+layers = (
+{
+anchors = (
+{
+name = L;
+position = "{690, -100}";
+},
+{
+name = U;
+position = "{990, 1100}";
+}
+);
+layerId = master01;
+paths = (
+{
+closed = 1;
+nodes = (
+"743 739 OFFCURVE",
+"588 466 OFFCURVE",
+"388 181 CURVE",
+"417 339 OFFCURVE",
+"430 500 OFFCURVE",
+"430 644 CURVE SMOOTH",
+"430 784 OFFCURVE",
+"418 908 OFFCURVE",
+"395 1000 CURVE",
+"195 1000 LINE",
+"234 873 OFFCURVE",
+"256 688 OFFCURVE",
+"256 472 CURVE SMOOTH",
+"256 326 OFFCURVE",
+"246 166 OFFCURVE",
+"225 0 CURVE",
+"425 0 LINE",
+"632 298 OFFCURVE",
+"825 583 OFFCURVE",
+"896 765 CURVE",
+"920 478 OFFCURVE",
+"912 233 OFFCURVE",
+"915 0 CURVE",
+"1115 0 LINE",
+"1362 330 OFFCURVE",
+"1642 777 OFFCURVE",
+"1645 1000 CURVE",
+"1445 1000 LINE",
+"1445 990 LINE",
+"1445 797 OFFCURVE",
+"1242 417 OFFCURVE",
+"1063 181 CURVE",
+"1064 221 OFFCURVE",
+"1064 260 OFFCURVE",
+"1064 298 CURVE SMOOTH",
+"1064 577 OFFCURVE",
+"1046 811 OFFCURVE",
+"1020 1000 CURVE",
+"858 1000 LINE"
+);
+}
+);
+width = 1555;
+},
+{
+anchors = (
+{
+name = L;
+position = "{700, -100}";
+},
+{
+name = U;
+position = "{1000, 1100}";
+}
+);
+layerId = master02;
+paths = (
+{
+closed = 1;
+nodes = (
+"758 793 OFFCURVE",
+"592 496 OFFCURVE",
+"438 242 CURVE",
+"459 351 OFFCURVE",
+"476 509 OFFCURVE",
+"476 669 CURVE SMOOTH",
+"476 788 OFFCURVE",
+"468 908 OFFCURVE",
+"448 1010 CURVE",
+"190 1010 LINE",
+"230 831 OFFCURVE",
+"236 678 OFFCURVE",
+"236 494 CURVE SMOOTH",
+"236 364 OFFCURVE",
+"228 211 OFFCURVE",
+"209 0 CURVE",
+"499 0 LINE",
+"624 181 OFFCURVE",
+"838 560 OFFCURVE",
+"901 690 CURVE",
+"919 477 OFFCURVE",
+"919 212 OFFCURVE",
+"919 0 CURVE",
+"1179 0 LINE",
+"1430 328 OFFCURVE",
+"1710 775 OFFCURVE",
+"1710 1010 CURVE",
+"1432 1010 LINE",
+"1432 995 LINE SMOOTH",
+"1432 797 OFFCURVE",
+"1245 435 OFFCURVE",
+"1106 242 CURVE",
+"1108 298 OFFCURVE",
+"1108 355 OFFCURVE",
+"1108 411 CURVE SMOOTH",
+"1108 637 OFFCURVE",
+"1096 860 OFFCURVE",
+"1070 1010 CURVE",
+"850 1010 LINE"
+);
+}
+);
+width = 1620;
+}
+);
+unicode = 0077;
+},
+{
+glyphname = LtnSmX;
+layers = (
+{
+anchors = (
+{
+name = H;
+position = "{840, 0}";
+},
+{
+name = L;
+position = "{457, -100}";
+},
+{
+name = U;
+position = "{657, 1100}";
+}
+);
+layerId = master01;
+paths = (
+{
+closed = 1;
+nodes = (
+"765 133 OFFCURVE",
+"558 867 OFFCURVE",
+"439 1000 CURVE",
+"181 1000 LINE",
+"410 832 OFFCURVE",
+"578 141 OFFCURVE",
+"698 0 CURVE",
+"945 0 LINE"
+);
+},
+{
+closed = 1;
+nodes = (
+"286 463 OFFCURVE",
+"57 230 OFFCURVE",
+"30 0 CURVE",
+"230 0 LINE",
+"231 156 OFFCURVE",
+"375 380 OFFCURVE",
+"563 467 CURVE",
+"504 572 LINE"
+);
+},
+{
+closed = 1;
+nodes = (
+"838 591 OFFCURVE",
+"1092 798 OFFCURVE",
+"1099 1000 CURVE",
+"889 1000 LINE",
+"883 842 OFFCURVE",
+"758 675 OFFCURVE",
+"601 581 CURVE",
+"659 471 LINE"
+);
+}
+);
+width = 1009;
+},
+{
+anchors = (
+{
+name = H;
+position = "{900, 0}";
+},
+{
+name = L;
+position = "{505, -100}";
+},
+{
+name = U;
+position = "{730, 1100}";
+}
+);
+layerId = master02;
+paths = (
+{
+closed = 1;
+nodes = (
+"860 133 OFFCURVE",
+"655 882 OFFCURVE",
+"524 1010 CURVE",
+"186 1010 LINE",
+"425 832 OFFCURVE",
+"593 141 OFFCURVE",
+"713 0 CURVE",
+"1040 0 LINE"
+);
+},
+{
+closed = 1;
+nodes = (
+"291 463 OFFCURVE",
+"62 230 OFFCURVE",
+"35 0 CURVE",
+"335 0 LINE",
+"336 156 OFFCURVE",
+"470 390 OFFCURVE",
+"658 477 CURVE",
+"509 572 LINE"
+);
+},
+{
+closed = 1;
+nodes = (
+"943 591 OFFCURVE",
+"1197 808 OFFCURVE",
+"1204 1010 CURVE",
+"894 1010 LINE",
+"894 852 OFFCURVE",
+"773 665 OFFCURVE",
+"616 571 CURVE",
+"764 471 LINE"
+);
+}
+);
+width = 1104;
+}
+);
+unicode = 0078;
+},
+{
+glyphname = LtnSmY;
+layers = (
+{
+anchors = (
+{
+name = L;
+position = "{710, -100}";
+},
+{
+name = R;
+position = "{1270, 1000}";
+},
+{
+name = U;
+position = "{630, 1100}";
+}
+);
+layerId = master01;
+paths = (
+{
+closed = 1;
+nodes = (
+"270 825 OFFCURVE",
+"398 406 OFFCURVE",
+"403 -16 CURVE",
+"263 -232 OFFCURVE",
+"145 -295 OFFCURVE",
+"64 -295 CURVE SMOOTH",
+"-2 -295 OFFCURVE",
+"-69 -254 OFFCURVE",
+"-102 -220 CURVE",
+"-200 -377 LINE",
+"-141 -430 OFFCURVE",
+"-68 -465 OFFCURVE",
+"23 -465 CURVE SMOOTH",
+"193 -465 OFFCURVE",
+"369 -371 OFFCURVE",
+"609 0 CURVE SMOOTH",
+"877 414 OFFCURVE",
+"1056 808 OFFCURVE",
+"1056 964 CURVE SMOOTH",
+"1056 978 OFFCURVE",
+"1055 990 OFFCURVE",
+"1052 1000 CURVE",
+"852 1000 LINE",
+"856 984 OFFCURVE",
+"858 967 OFFCURVE",
+"858 946 CURVE SMOOTH",
+"858 783 OFFCURVE",
+"722 472 OFFCURVE",
+"548 189 CURVE",
+"548 484 OFFCURVE",
+"447 866 OFFCURVE",
+"347 1000 CURVE",
+"132 1000 LINE"
+);
+}
+);
+width = 976;
+},
+{
+anchors = (
+{
+name = L;
+position = "{810, -100}";
+},
+{
+name = R;
+position = "{1325, 1000}";
+},
+{
+name = U;
+position = "{640, 1100}";
+}
+);
+layerId = master02;
+paths = (
+{
+closed = 1;
+nodes = (
+"851 994 OFFCURVE",
+"852 977 OFFCURVE",
+"852 958 CURVE SMOOTH",
+"852 786 OFFCURVE",
+"713 473 OFFCURVE",
+"596 260 CURVE",
+"596 478 OFFCURVE",
+"503 877 OFFCURVE",
+"403 1010 CURVE",
+"120 1010 LINE",
+"259 811 OFFCURVE",
+"401 401 OFFCURVE",
+"409 -18 CURVE",
+"283 -207 OFFCURVE",
+"183 -250 OFFCURVE",
+"114 -250 CURVE SMOOTH",
+"48 -250 OFFCURVE",
+"-33 -201 OFFCURVE",
+"-63 -165 CURVE",
+"-195 -381 LINE",
+"-136 -435 OFFCURVE",
+"-13 -465 OFFCURVE",
+"78 -465 CURVE SMOOTH",
+"260 -465 OFFCURVE",
+"447 -385 OFFCURVE",
+"684 0 CURVE SMOOTH",
+"919 381 OFFCURVE",
+"1116 766 OFFCURVE",
+"1116 960 CURVE SMOOTH",
+"1116 978 OFFCURVE",
+"1114 995 OFFCURVE",
+"1110 1010 CURVE",
+"847 1010 LINE"
+);
+}
+);
+width = 1041;
+}
+);
+unicode = 0079;
+},
+{
+glyphname = LftCurlyBrac;
+layers = (
+{
+layerId = master01;
+paths = (
+{
+closed = 1;
+nodes = (
+"660 -250 OFFCURVE",
+"526 -188 OFFCURVE",
+"526 -158 CURVE SMOOTH",
+"526 -59 OFFCURVE",
+"649 404 OFFCURVE",
+"649 469 CURVE SMOOTH",
+"649 509 OFFCURVE",
+"520 577 OFFCURVE",
+"520 602 CURVE SMOOTH",
+"520 620 OFFCURVE",
+"688 700 OFFCURVE",
+"712 730 CURVE SMOOTH",
+"741 767 OFFCURVE",
+"867 1326 OFFCURVE",
+"912 1372 CURVE SMOOTH",
+"938 1399 OFFCURVE",
+"1073 1447 OFFCURVE",
+"1146 1470 CURVE",
+"1140 1607 LINE",
+"1030 1581 OFFCURVE",
+"856 1529 OFFCURVE",
+"805 1485 CURVE SMOOTH",
+"714 1406 OFFCURVE",
+"572 796 OFFCURVE",
+"540 764 CURVE SMOOTH",
+"504 729 OFFCURVE",
+"300 633 OFFCURVE",
+"300 601 CURVE SMOOTH",
+"300 560 OFFCURVE",
+"460 468 OFFCURVE",
+"460 432 CURVE SMOOTH",
+"460 362 OFFCURVE",
+"355 -53 OFFCURVE",
+"355 -219 CURVE SMOOTH",
+"355 -247 OFFCURVE",
+"358 -268 OFFCURVE",
+"365 -279 CURVE SMOOTH",
+"394 -323 OFFCURVE",
+"542 -375 OFFCURVE",
+"639 -402 CURVE",
+"713 -265 LINE"
+);
+}
+);
+width = 980;
+},
+{
+layerId = master02;
+paths = (
+{
+closed = 1;
+nodes = (
+"717 -149 OFFCURVE",
+"597 -129 OFFCURVE",
+"597 -79 CURVE SMOOTH",
+"597 16 OFFCURVE",
+"695 378 OFFCURVE",
+"695 435 CURVE SMOOTH",
+"695 476 OFFCURVE",
+"574 568 OFFCURVE",
+"574 605 CURVE SMOOTH",
+"574 644 OFFCURVE",
+"742 733 OFFCURVE",
+"776 777 CURVE SMOOTH",
+"803 812 OFFCURVE",
+"908 1276 OFFCURVE",
+"953 1317 CURVE SMOOTH",
+"975 1337 OFFCURVE",
+"1090 1376 OFFCURVE",
+"1157 1395 CURVE",
+"1165 1624 LINE",
+"1031 1597 OFFCURVE",
+"827 1546 OFFCURVE",
+"768 1500 CURVE SMOOTH",
+"677 1428 OFFCURVE",
+"542 843 OFFCURVE",
+"512 812 CURVE SMOOTH",
+"472 770 OFFCURVE",
+"260 659 OFFCURVE",
+"260 601 CURVE SMOOTH",
+"260 540 OFFCURVE",
+"412 434 OFFCURVE",
+"412 399 CURVE SMOOTH",
+"412 337 OFFCURVE",
+"311 -52 OFFCURVE",
+"311 -216 CURVE SMOOTH",
+"311 -248 OFFCURVE",
+"315 -271 OFFCURVE",
+"324 -282 CURVE SMOOTH",
+"362 -330 OFFCURVE",
+"554 -379 OFFCURVE",
+"683 -406 CURVE",
+"790 -177 LINE"
+);
+}
+);
+width = 1020;
+}
+);
+unicode = 007B;
+},
+{
+glyphname = VertLine;
+layers = (
+{
+layerId = master01;
+paths = (
+{
+closed = 1;
+nodes = (
+"112 -392 LINE",
+"262 -392 LINE",
+"752 1578 LINE",
+"602 1578 LINE"
+);
+}
+);
+width = 670;
+},
+{
+layerId = master02;
+paths = (
+{
+closed = 1;
+nodes = (
+"83 -396 LINE",
+"293 -396 LINE",
+"784 1594 LINE",
+"574 1594 LINE"
+);
+}
+);
+width = 670;
+}
+);
+unicode = 007C;
+},
+{
+glyphname = RtCurlyBrac;
+layers = (
+{
+layerId = master01;
+paths = (
+{
+closed = 1;
+nodes = (
+"513 1452 OFFCURVE",
+"653 1397 OFFCURVE",
+"653 1366 CURVE SMOOTH",
+"653 1238 OFFCURVE",
+"531 801 OFFCURVE",
+"531 737 CURVE SMOOTH",
+"531 701 OFFCURVE",
+"660 627 OFFCURVE",
+"660 603 CURVE SMOOTH",
+"660 585 OFFCURVE",
+"496 511 OFFCURVE",
+"468 475 CURVE SMOOTH",
+"439 438 OFFCURVE",
+"312 -121 OFFCURVE",
+"268 -167 CURVE SMOOTH",
+"241 -194 OFFCURVE",
+"106 -242 OFFCURVE",
+"33 -265 CURVE",
+"39 -402 LINE",
+"150 -375 OFFCURVE",
+"324 -323 OFFCURVE",
+"375 -279 CURVE SMOOTH",
+"465 -201 OFFCURVE",
+"608 410 OFFCURVE",
+"639 441 CURVE SMOOTH",
+"675 476 OFFCURVE",
+"880 571 OFFCURVE",
+"880 607 CURVE SMOOTH",
+"880 639 OFFCURVE",
+"719 740 OFFCURVE",
+"719 771 CURVE SMOOTH",
+"719 839 OFFCURVE",
+"825 1259 OFFCURVE",
+"825 1425 CURVE SMOOTH",
+"825 1453 OFFCURVE",
+"822 1474 OFFCURVE",
+"815 1485 CURVE SMOOTH",
+"786 1529 OFFCURVE",
+"638 1581 OFFCURVE",
+"540 1607 CURVE",
+"466 1470 LINE"
+);
+}
+);
+width = 980;
+},
+{
+layerId = master02;
+paths = (
+{
+closed = 1;
+nodes = (
+"513 1366 OFFCURVE",
+"611 1344 OFFCURVE",
+"611 1296 CURVE SMOOTH",
+"611 1200 OFFCURVE",
+"515 837 OFFCURVE",
+"515 782 CURVE SMOOTH",
+"515 743 OFFCURVE",
+"633 649 OFFCURVE",
+"633 613 CURVE SMOOTH",
+"633 573 OFFCURVE",
+"465 486 OFFCURVE",
+"429 441 CURVE SMOOTH",
+"403 407 OFFCURVE",
+"300 -59 OFFCURVE",
+"255 -99 CURVE SMOOTH",
+"230 -121 OFFCURVE",
+"97 -158 OFFCURVE",
+"25 -177 CURVE",
+"17 -406 LINE",
+"160 -379 OFFCURVE",
+"377 -330 OFFCURVE",
+"439 -282 CURVE SMOOTH",
+"532 -211 OFFCURVE",
+"666 374 OFFCURVE",
+"696 406 CURVE SMOOTH",
+"734 446 OFFCURVE",
+"947 559 OFFCURVE",
+"947 616 CURVE SMOOTH",
+"947 676 OFFCURVE",
+"796 783 OFFCURVE",
+"796 819 CURVE SMOOTH",
+"796 880 OFFCURVE",
+"896 1288 OFFCURVE",
+"896 1453 CURVE SMOOTH",
+"896 1529 OFFCURVE",
+"709 1591 OFFCURVE",
+"549 1624 CURVE",
+"442 1395 LINE"
+);
+}
+);
+width = 1020;
+}
+);
+unicode = 007D;
+},
+{
+glyphname = Tilde;
+layers = (
+{
+layerId = master01;
+paths = (
+{
+closed = 1;
+nodes = (
+"173 416 OFFCURVE",
+"215 456 OFFCURVE",
+"293 456 CURVE SMOOTH",
+"468 456 OFFCURVE",
+"643 353 OFFCURVE",
+"873 353 CURVE SMOOTH",
+"1032 353 OFFCURVE",
+"1137 472 OFFCURVE",
+"1169 598 CURVE",
+"1064 598 LINE",
+"1045 553 OFFCURVE",
+"1002 500 OFFCURVE",
+"919 500 CURVE SMOOTH",
+"683 500 OFFCURVE",
+"551 603 OFFCURVE",
+"330 603 CURVE SMOOTH",
+"184 603 OFFCURVE",
+"81 487 OFFCURVE",
+"51 368 CURVE",
+"156 368 LINE"
+);
+}
+);
+width = 1095;
+},
+{
+layerId = master02;
+paths = (
+{
+closed = 1;
+nodes = (
+"207 390 OFFCURVE",
+"249 431 OFFCURVE",
+"327 431 CURVE SMOOTH",
+"502 431 OFFCURVE",
+"676 327 OFFCURVE",
+"906 327 CURVE SMOOTH",
+"1065 327 OFFCURVE",
+"1206 507 OFFCURVE",
+"1238 634 CURVE",
+"1093 634 LINE",
+"1074 588 OFFCURVE",
+"1031 535 OFFCURVE",
+"948 535 CURVE SMOOTH",
+"712 535 OFFCURVE",
+"580 639 OFFCURVE",
+"359 639 CURVE SMOOTH",
+"203 639 OFFCURVE",
+"75 462 OFFCURVE",
+"45 342 CURVE",
+"190 342 LINE"
+);
+}
+);
+width = 1155;
+}
+);
+unicode = 007E;
+},
+{
+glyphname = LtnCapADiaer;
+layers = (
+{
+anchors = (
+{
+name = H;
+position = "{1170, 0}";
+},
+{
+name = L;
+position = "{602, -100}";
+},
+{
+name = O;
+position = "{1390, 0}";
+},
+{
+name = U;
+position = "{1106, 1935}";
+}
+);
+components = (
+{
+name = LtnCapA;
+},
+{
+name = CombDiaer;
+transform = "{1, 0, 0, 1, 1359, 430}";
+}
+);
+layerId = master01;
+width = 1395;
+},
+{
+anchors = (
+{
+name = H;
+position = "{1215, 0}";
+},
+{
+name = L;
+position = "{647, -100}";
+},
+{
+name = O;
+position = "{1435, 0}";
+},
+{
+name = U;
+position = "{1176, 2015}";
+}
+);
+components = (
+{
+name = LtnCapA;
+},
+{
+name = CombDiaer;
+transform = "{1, 0, 0, 1, 1419, 430}";
+}
+);
+layerId = master02;
+width = 1465;
+}
+);
+unicode = 00C4;
+},
+{
+glyphname = LtnSmAAcute;
+layers = (
+{
+anchors = (
+{
+name = H;
+position = "{860, 0}";
+},
+{
+name = L;
+position = "{455, -100}";
+},
+{
+name = O;
+position = "{1065, 0}";
+},
+{
+name = R;
+position = "{1310, 1000}";
+},
+{
+name = U;
+position = "{889, 1635}";
+}
+);
+components = (
+{
+name = LtnSmA;
+},
+{
+name = CombAcute;
+transform = "{1, 0, 0, 1, 1110, 0}";
+}
+);
+layerId = master01;
+width = 1107;
+},
+{
+anchors = (
+{
+name = H;
+position = "{925, 0}";
+},
+{
+name = L;
+position = "{525, -100}";
+},
+{
+name = O;
+position = "{1125, 0}";
+},
+{
+name = R;
+position = "{1335, 1000}";
+},
+{
+name = U;
+position = "{899, 1635}";
+}
+);
+components = (
+{
+name = LtnSmA;
+},
+{
+name = CombAcute;
+transform = "{1, 0, 0, 1, 1150, 0}";
+}
+);
+layerId = master02;
+width = 1185;
+}
+);
+unicode = 00E1;
+},
+{
+glyphname = LtnSmAGrave;
+layers = (
+{
+anchors = (
+{
+name = H;
+position = "{860, 0}";
+},
+{
+name = L;
+position = "{455, -100}";
+},
+{
+name = O;
+position = "{1065, 0}";
+},
+{
+name = R;
+position = "{1310, 1000}";
+},
+{
+name = U;
+position = "{889, 1635}";
+}
+);
+components = (
+{
+name = LtnSmA;
+},
+{
+name = CombGrave;
+transform = "{1, 0, 0, 1, 1090, 0}";
+}
+);
+layerId = master01;
+width = 1107;
+},
+{
+anchors = (
+{
+name = H;
+position = "{925, 0}";
+},
+{
+name = L;
+position = "{525, -100}";
+},
+{
+name = O;
+position = "{1125, 0}";
+},
+{
+name = R;
+position = "{1335, 1000}";
+},
+{
+name = U;
+position = "{999, 1635}";
+}
+);
+components = (
+{
+name = LtnSmA;
+},
+{
+name = CombGrave;
+transform = "{1, 0, 0, 1, 1240, 0}";
+}
+);
+layerId = master02;
+width = 1185;
+}
+);
+unicode = 00E0;
+},
+{
+glyphname = LtnSmACircum;
+layers = (
+{
+anchors = (
+{
+name = H;
+position = "{860, 0}";
+},
+{
+name = L;
+position = "{455, -100}";
+},
+{
+name = O;
+position = "{1065, 0}";
+},
+{
+name = R;
+position = "{1310, 1000}";
+},
+{
+name = U;
+position = "{854, 1635}";
+}
+);
+components = (
+{
+name = LtnSmA;
+},
+{
+name = CombCircum;
+transform = "{1, 0, 0, 1, 1075, 0}";
+}
+);
+layerId = master01;
+width = 1107;
+},
+{
+anchors = (
+{
+name = H;
+position = "{925, 0}";
+},
+{
+name = L;
+position = "{525, -100}";
+},
+{
+name = O;
+position = "{1125, 0}";
+},
+{
+name = R;
+position = "{1335, 1000}";
+},
+{
+name = U;
+position = "{916, 1635}";
+}
+);
+components = (
+{
+name = LtnSmA;
+},
+{
+name = CombCircum;
+transform = "{1, 0, 0, 1, 1155, 0}";
+}
+);
+layerId = master02;
+width = 1185;
+}
+);
+unicode = 00E2;
+},
+{
+glyphname = LtnSmADiaer;
+layers = (
+{
+anchors = (
+{
+name = H;
+position = "{860, 0}";
+},
+{
+name = L;
+position = "{455, -100}";
+},
+{
+name = O;
+position = "{1065, 0}";
+},
+{
+name = R;
+position = "{1310, 1000}";
+},
+{
+name = U;
+position = "{852, 1505}";
+}
+);
+components = (
+{
+name = LtnSmA;
+},
+{
+name = CombDiaer;
+transform = "{1, 0, 0, 1, 1105, 0}";
+}
+);
+layerId = master01;
+width = 1107;
+},
+{
+anchors = (
+{
+name = H;
+position = "{925, 0}";
+},
+{
+name = L;
+position = "{525, -100}";
+},
+{
+name = O;
+position = "{1125, 0}";
+},
+{
+name = R;
+position = "{1335, 1000}";
+},
+{
+name = U;
+position = "{947, 1585}";
+}
+);
+components = (
+{
+name = LtnSmA;
+},
+{
+name = CombDiaer;
+transform = "{1, 0, 0, 1, 1190, 0}";
+}
+);
+layerId = master02;
+width = 1185;
+}
+);
+unicode = 00E4;
+},
+{
+glyphname = LtnSmATilde;
+layers = (
+{
+anchors = (
+{
+name = H;
+position = "{860, 0}";
+},
+{
+name = L;
+position = "{455, -100}";
+},
+{
+name = O;
+position = "{1065, 0}";
+},
+{
+name = R;
+position = "{1310, 1000}";
+},
+{
+name = U;
+position = "{850, 1475}";
+}
+);
+components = (
+{
+name = LtnSmA;
+},
+{
+name = CombTilde;
+transform = "{1, 0, 0, 1, 1140, 0}";
+}
+);
+layerId = master01;
+width = 1107;
+},
+{
+anchors = (
+{
+name = H;
+position = "{925, 0}";
+},
+{
+name = L;
+position = "{525, -100}";
+},
+{
+name = O;
+position = "{1125, 0}";
+},
+{
+name = R;
+position = "{1335, 1000}";
+},
+{
+name = U;
+position = "{860, 1490}";
+}
+);
+components = (
+{
+name = LtnSmA;
+},
+{
+name = CombTilde;
+transform = "{1, 0, 0, 1, 1215, 0}";
+}
+);
+layerId = master02;
+width = 1185;
+}
+);
+unicode = 00E3;
+},
+{
+glyphname = LtnSmARingAbv;
+layers = (
+{
+anchors = (
+{
+name = H;
+position = "{860, 0}";
+},
+{
+name = L;
+position = "{455, -100}";
+},
+{
+name = O;
+position = "{1065, 0}";
+},
+{
+name = R;
+position = "{1310, 1000}";
+},
+{
+name = U;
+position = "{919, 1635}";
+}
+);
+components = (
+{
+name = LtnSmA;
+},
+{
+name = CombRingAbv;
+transform = "{1, 0, 0, 1, 1140, 0}";
+}
+);
+layerId = master01;
+width = 1107;
+},
+{
+anchors = (
+{
+name = H;
+position = "{925, 0}";
+},
+{
+name = L;
+position = "{525, -100}";
+},
+{
+name = O;
+position = "{1125, 0}";
+},
+{
+name = R;
+position = "{1335, 1000}";
+},
+{
+name = U;
+position = "{961, 1635}";
+}
+);
+components = (
+{
+name = LtnSmA;
+},
+{
+name = CombRingAbv;
+transform = "{1, 0, 0, 1, 1182, 0}";
+}
+);
+layerId = master02;
+width = 1185;
+}
+);
+unicode = 00E5;
+},
+{
+glyphname = DottedCirc;
+layers = (
+{
+anchors = (
+{
+name = H;
+position = "{493, 0}";
+},
+{
+name = L;
+position = "{468, -100}";
+},
+{
+name = O;
+position = "{750, 0}";
+},
+{
+name = U;
+position = "{743, 1000}";
+}
+);
+layerId = master01;
+paths = (
+{
+closed = 1;
+nodes = (
+"588 858 OFFCURVE",
+"571 867 OFFCURVE",
+"553 867 CURVE SMOOTH",
+"521 867 OFFCURVE",
+"491 837 OFFCURVE",
+"491 809 CURVE SMOOTH",
+"491 788 OFFCURVE",
+"508 773 OFFCURVE",
+"530 773 CURVE SMOOTH",
+"564 773 OFFCURVE",
+"588 805 OFFCURVE",
+"588 834 CURVE SMOOTH"
+);
+},
+{
+closed = 1;
+nodes = (
+"647 124 OFFCURVE",
+"620 93 OFFCURVE",
+"620 67 CURVE SMOOTH",
+"620 46 OFFCURVE",
+"636 30 OFFCURVE",
+"657 30 CURVE SMOOTH",
+"687 30 OFFCURVE",
+"718 60 OFFCURVE",
+"718 86 CURVE SMOOTH",
+"718 109 OFFCURVE",
+"700 124 OFFCURVE",
+"677 124 CURVE SMOOTH"
+);
+},
+{
+closed = 1;
+nodes = (
+"369 780 OFFCURVE",
+"336 753 OFFCURVE",
+"336 722 CURVE SMOOTH",
+"336 702 OFFCURVE",
+"351 687 OFFCURVE",
+"374 687 CURVE SMOOTH",
+"403 687 OFFCURVE",
+"434 711 OFFCURVE",
+"434 744 CURVE SMOOTH",
+"434 764 OFFCURVE",
+"414 780 OFFCURVE",
+"396 780 CURVE SMOOTH"
+);
+},
+{
+closed = 1;
+nodes = (
+"872 199 OFFCURVE",
+"854 211 OFFCURVE",
+"833 211 CURVE SMOOTH",
+"803 211 OFFCURVE",
+"774 183 OFFCURVE",
+"774 153 CURVE SMOOTH",
+"774 133 OFFCURVE",
+"789 119 OFFCURVE",
+"812 119 CURVE SMOOTH",
+"843 119 OFFCURVE",
+"873 146 OFFCURVE",
+"873 175 CURVE SMOOTH"
+);
+},
+{
+closed = 1;
+nodes = (
+"312 633 OFFCURVE",
+"296 650 OFFCURVE",
+"275 650 CURVE SMOOTH",
+"247 650 OFFCURVE",
+"215 623 OFFCURVE",
+"215 592 CURVE SMOOTH",
+"215 573 OFFCURVE",
+"227 556 OFFCURVE",
+"251 556 CURVE SMOOTH",
+"278 556 OFFCURVE",
+"313 581 OFFCURVE",
+"313 612 CURVE SMOOTH"
+);
+},
+{
+closed = 1;
+nodes = (
+"993 327 OFFCURVE",
+"978 341 OFFCURVE",
+"958 341 CURVE SMOOTH",
+"933 341 OFFCURVE",
+"896 321 OFFCURVE",
+"896 284 CURVE SMOOTH",
+"896 265 OFFCURVE",
+"909 249 OFFCURVE",
+"934 249 CURVE SMOOTH",
+"963 249 OFFCURVE",
+"994 275 OFFCURVE",
+"994 306 CURVE SMOOTH"
+);
+},
+{
+closed = 1;
+nodes = (
+"175 495 OFFCURVE",
+"145 468 OFFCURVE",
+"145 438 CURVE SMOOTH",
+"145 418 OFFCURVE",
+"159 402 OFFCURVE",
+"183 402 CURVE SMOOTH",
+"208 402 OFFCURVE",
+"244 428 OFFCURVE",
+"244 459 CURVE SMOOTH",
+"244 479 OFFCURVE",
+"227 495 OFFCURVE",
+"205 495 CURVE SMOOTH"
+);
+},
+{
+closed = 1;
+nodes = (
+"999 496 OFFCURVE",
+"965 469 OFFCURVE",
+"965 438 CURVE SMOOTH",
+"965 418 OFFCURVE",
+"979 403 OFFCURVE",
+"1004 403 CURVE SMOOTH",
+"1033 403 OFFCURVE",
+"1064 431 OFFCURVE",
+"1064 460 CURVE SMOOTH",
+"1064 480 OFFCURVE",
+"1048 496 OFFCURVE",
+"1026 496 CURVE SMOOTH"
+);
+},
+{
+closed = 1;
+nodes = (
+"237 327 OFFCURVE",
+"221 341 OFFCURVE",
+"199 341 CURVE SMOOTH",
+"169 341 OFFCURVE",
+"138 314 OFFCURVE",
+"138 285 CURVE SMOOTH",
+"138 263 OFFCURVE",
+"153 248 OFFCURVE",
+"175 248 CURVE SMOOTH",
+"206 248 OFFCURVE",
+"237 278 OFFCURVE",
+"237 307 CURVE SMOOTH"
+);
+},
+{
+closed = 1;
+nodes = (
+"1071 634 OFFCURVE",
+"1055 650 OFFCURVE",
+"1034 650 CURVE SMOOTH",
+"1003 650 OFFCURVE",
+"973 619 OFFCURVE",
+"973 590 CURVE SMOOTH",
+"973 570 OFFCURVE",
+"989 556 OFFCURVE",
+"1009 556 CURVE SMOOTH",
+"1041 556 OFFCURVE",
+"1071 585 OFFCURVE",
+"1071 613 CURVE SMOOTH"
+);
+},
+{
+closed = 1;
+nodes = (
+"292 197 OFFCURVE",
+"277 211 OFFCURVE",
+"253 211 CURVE SMOOTH",
+"224 211 OFFCURVE",
+"194 181 OFFCURVE",
+"194 154 CURVE SMOOTH",
+"194 134 OFFCURVE",
+"211 118 OFFCURVE",
+"232 118 CURVE SMOOTH",
+"262 118 OFFCURVE",
+"292 148 OFFCURVE",
+"292 177 CURVE SMOOTH"
+);
+},
+{
+closed = 1;
+nodes = (
+"917 704 OFFCURVE",
+"931 686 OFFCURVE",
+"954 686 CURVE SMOOTH",
+"984 686 OFFCURVE",
+"1014 716 OFFCURVE",
+"1014 745 CURVE SMOOTH",
+"1014 765 OFFCURVE",
+"1000 780 OFFCURVE",
+"977 780 CURVE SMOOTH",
+"947 780 OFFCURVE",
+"917 753 OFFCURVE",
+"917 724 CURVE SMOOTH"
+);
+},
+{
+closed = 1;
+nodes = (
+"403 107 OFFCURVE",
+"390 123 OFFCURVE",
+"367 123 CURVE SMOOTH",
+"339 123 OFFCURVE",
+"305 96 OFFCURVE",
+"305 68 CURVE SMOOTH",
+"305 49 OFFCURVE",
+"320 30 OFFCURVE",
+"343 30 CURVE SMOOTH",
+"371 30 OFFCURVE",
+"403 56 OFFCURVE",
+"403 87 CURVE SMOOTH"
+);
+},
+{
+closed = 1;
+nodes = (
+"806 791 OFFCURVE",
+"819 773 OFFCURVE",
+"842 773 CURVE SMOOTH",
+"869 773 OFFCURVE",
+"903 799 OFFCURVE",
+"903 830 CURVE SMOOTH",
+"903 850 OFFCURVE",
+"889 867 OFFCURVE",
+"866 867 CURVE SMOOTH",
+"836 867 OFFCURVE",
+"806 839 OFFCURVE",
+"806 810 CURVE SMOOTH"
+);
+},
+{
+closed = 1;
+nodes = (
+"553 78 OFFCURVE",
+"538 93 OFFCURVE",
+"516 93 CURVE SMOOTH",
+"485 93 OFFCURVE",
+"456 65 OFFCURVE",
+"456 36 CURVE SMOOTH",
+"456 16 OFFCURVE",
+"471 0 OFFCURVE",
+"493 0 CURVE SMOOTH",
+"523 0 OFFCURVE",
+"553 27 OFFCURVE",
+"553 57 CURVE SMOOTH"
+);
+},
+{
+closed = 1;
+nodes = (
+"656 819 OFFCURVE",
+"671 805 OFFCURVE",
+"693 805 CURVE SMOOTH",
+"721 805 OFFCURVE",
+"754 830 OFFCURVE",
+"754 861 CURVE SMOOTH",
+"754 882 OFFCURVE",
+"738 898 OFFCURVE",
+"716 898 CURVE SMOOTH",
+"685 898 OFFCURVE",
+"656 868 OFFCURVE",
+"656 839 CURVE SMOOTH"
+);
+}
+);
+width = 1086;
+},
+{
+anchors = (
+{
+name = H;
+position = "{493, 0}";
+},
+{
+name = L;
+position = "{545, -100}";
+},
+{
+name = O;
+position = "{750, 0}";
+},
+{
+name = U;
+position = "{645, 1000}";
+}
+);
+layerId = master02;
+paths = (
+{
+closed = 1;
+nodes = (
+"443 864 OFFCURVE",
+"423 885 OFFCURVE",
+"398 885 CURVE SMOOTH",
+"371 885 OFFCURVE",
+"348 861 OFFCURVE",
+"348 837 CURVE SMOOTH",
+"348 809 OFFCURVE",
+"372 789 OFFCURVE",
+"398 789 CURVE SMOOTH",
+"425 789 OFFCURVE",
+"443 812 OFFCURVE",
+"443 837 CURVE SMOOTH"
+);
+},
+{
+closed = 1;
+nodes = (
+"758 106 OFFCURVE",
+"736 127 OFFCURVE",
+"710 127 CURVE SMOOTH",
+"685 127 OFFCURVE",
+"662 103 OFFCURVE",
+"662 80 CURVE SMOOTH",
+"662 52 OFFCURVE",
+"686 31 OFFCURVE",
+"710 31 CURVE SMOOTH",
+"737 31 OFFCURVE",
+"758 55 OFFCURVE",
+"758 79 CURVE SMOOTH"
+);
+},
+{
+closed = 1;
+nodes = (
+"310 775 OFFCURVE",
+"288 796 OFFCURVE",
+"263 796 CURVE SMOOTH",
+"238 796 OFFCURVE",
+"215 774 OFFCURVE",
+"215 747 CURVE SMOOTH",
+"215 722 OFFCURVE",
+"236 701 OFFCURVE",
+"263 701 CURVE SMOOTH",
+"291 701 OFFCURVE",
+"310 720 OFFCURVE",
+"310 749 CURVE SMOOTH"
+);
+},
+{
+closed = 1;
+nodes = (
+"891 197 OFFCURVE",
+"870 215 OFFCURVE",
+"843 215 CURVE SMOOTH",
+"817 215 OFFCURVE",
+"795 194 OFFCURVE",
+"795 168 CURVE SMOOTH",
+"795 143 OFFCURVE",
+"816 121 OFFCURVE",
+"843 121 CURVE SMOOTH",
+"871 121 OFFCURVE",
+"891 143 OFFCURVE",
+"891 168 CURVE SMOOTH"
+);
+},
+{
+closed = 1;
+nodes = (
+"222 640 OFFCURVE",
+"199 663 OFFCURVE",
+"173 663 CURVE SMOOTH",
+"149 663 OFFCURVE",
+"126 642 OFFCURVE",
+"126 615 CURVE SMOOTH",
+"126 591 OFFCURVE",
+"145 567 OFFCURVE",
+"173 567 CURVE SMOOTH",
+"197 567 OFFCURVE",
+"222 587 OFFCURVE",
+"222 613 CURVE SMOOTH"
+);
+},
+{
+closed = 1;
+nodes = (
+"980 327 OFFCURVE",
+"957 348 OFFCURVE",
+"932 348 CURVE SMOOTH",
+"908 348 OFFCURVE",
+"884 332 OFFCURVE",
+"884 301 CURVE SMOOTH",
+"884 277 OFFCURVE",
+"902 254 OFFCURVE",
+"932 254 CURVE SMOOTH",
+"957 254 OFFCURVE",
+"980 274 OFFCURVE",
+"980 301 CURVE SMOOTH"
+);
+},
+{
+closed = 1;
+nodes = (
+"191 484 OFFCURVE",
+"168 505 OFFCURVE",
+"143 505 CURVE SMOOTH",
+"116 505 OFFCURVE",
+"95 484 OFFCURVE",
+"95 458 CURVE SMOOTH",
+"95 433 OFFCURVE",
+"115 410 OFFCURVE",
+"143 410 CURVE SMOOTH",
+"167 410 OFFCURVE",
+"191 432 OFFCURVE",
+"191 459 CURVE SMOOTH"
+);
+},
+{
+closed = 1;
+nodes = (
+"1011 484 OFFCURVE",
+"990 506 OFFCURVE",
+"964 506 CURVE SMOOTH",
+"940 506 OFFCURVE",
+"915 484 OFFCURVE",
+"915 457 CURVE SMOOTH",
+"915 433 OFFCURVE",
+"936 411 OFFCURVE",
+"964 411 CURVE SMOOTH",
+"990 411 OFFCURVE",
+"1011 433 OFFCURVE",
+"1011 458 CURVE SMOOTH"
+);
+},
+{
+closed = 1;
+nodes = (
+"222 328 OFFCURVE",
+"200 348 OFFCURVE",
+"174 348 CURVE SMOOTH",
+"147 348 OFFCURVE",
+"126 326 OFFCURVE",
+"126 302 CURVE SMOOTH",
+"126 275 OFFCURVE",
+"149 253 OFFCURVE",
+"174 253 CURVE SMOOTH",
+"201 253 OFFCURVE",
+"222 277 OFFCURVE",
+"222 302 CURVE SMOOTH"
+);
+},
+{
+closed = 1;
+nodes = (
+"980 642 OFFCURVE",
+"955 663 OFFCURVE",
+"931 663 CURVE SMOOTH",
+"904 663 OFFCURVE",
+"885 638 OFFCURVE",
+"885 614 CURVE SMOOTH",
+"885 588 OFFCURVE",
+"907 567 OFFCURVE",
+"931 567 CURVE SMOOTH",
+"959 567 OFFCURVE",
+"980 591 OFFCURVE",
+"980 615 CURVE SMOOTH"
+);
+},
+{
+closed = 1;
+nodes = (
+"310 195 OFFCURVE",
+"291 215 OFFCURVE",
+"263 215 CURVE SMOOTH",
+"238 215 OFFCURVE",
+"215 190 OFFCURVE",
+"215 168 CURVE SMOOTH",
+"215 143 OFFCURVE",
+"238 120 OFFCURVE",
+"263 120 CURVE SMOOTH",
+"289 120 OFFCURVE",
+"310 143 OFFCURVE",
+"310 168 CURVE SMOOTH"
+);
+},
+{
+closed = 1;
+nodes = (
+"890 774 OFFCURVE",
+"870 796 OFFCURVE",
+"843 796 CURVE SMOOTH",
+"815 796 OFFCURVE",
+"796 773 OFFCURVE",
+"796 748 CURVE SMOOTH",
+"796 724 OFFCURVE",
+"817 700 OFFCURVE",
+"843 700 CURVE SMOOTH",
+"869 700 OFFCURVE",
+"890 722 OFFCURVE",
+"890 748 CURVE SMOOTH"
+);
+},
+{
+closed = 1;
+nodes = (
+"444 102 OFFCURVE",
+"423 126 OFFCURVE",
+"396 126 CURVE SMOOTH",
+"370 126 OFFCURVE",
+"348 102 OFFCURVE",
+"348 78 CURVE SMOOTH",
+"348 55 OFFCURVE",
+"370 31 OFFCURVE",
+"396 31 CURVE SMOOTH",
+"420 31 OFFCURVE",
+"444 51 OFFCURVE",
+"444 78 CURVE SMOOTH"
+);
+},
+{
+closed = 1;
+nodes = (
+"758 861 OFFCURVE",
+"737 885 OFFCURVE",
+"710 885 CURVE SMOOTH",
+"684 885 OFFCURVE",
+"663 862 OFFCURVE",
+"663 838 CURVE SMOOTH",
+"663 814 OFFCURVE",
+"683 789 OFFCURVE",
+"710 789 CURVE SMOOTH",
+"734 789 OFFCURVE",
+"758 809 OFFCURVE",
+"758 836 CURVE SMOOTH"
+);
+},
+{
+closed = 1;
+nodes = (
+"601 73 OFFCURVE",
+"579 95 OFFCURVE",
+"553 95 CURVE SMOOTH",
+"527 95 OFFCURVE",
+"506 73 OFFCURVE",
+"506 47 CURVE SMOOTH",
+"506 21 OFFCURVE",
+"527 0 OFFCURVE",
+"553 0 CURVE SMOOTH",
+"579 0 OFFCURVE",
+"601 21 OFFCURVE",
+"601 47 CURVE SMOOTH"
+);
+},
+{
+closed = 1;
+nodes = (
+"601 894 OFFCURVE",
+"579 916 OFFCURVE",
+"553 916 CURVE SMOOTH",
+"527 916 OFFCURVE",
+"506 894 OFFCURVE",
+"506 868 CURVE SMOOTH",
+"506 842 OFFCURVE",
+"527 821 OFFCURVE",
+"553 821 CURVE SMOOTH",
+"579 821 OFFCURVE",
+"601 842 OFFCURVE",
+"601 868 CURVE SMOOTH"
+);
+}
+);
+width = 1086;
+}
+);
+unicode = 25CC;
+},
+{
+glyphname = Hyphen;
+layers = (
+{
+anchors = (
+{
+name = U;
+position = "{645, 1100}";
+}
+);
+layerId = master01;
+paths = (
+{
+closed = 1;
+nodes = (
+"855 544 LINE",
+"892 691 LINE",
+"192 691 LINE",
+"155 544 LINE"
+);
+}
+);
+width = 840;
+},
+{
+anchors = (
+{
+name = U;
+position = "{655, 1100}";
+}
+);
+layerId = master02;
+paths = (
+{
+closed = 1;
+nodes = (
+"879 520 LINE",
+"931 728 LINE",
+"191 728 LINE",
+"139 520 LINE"
+);
+}
+);
+width = 860;
+}
+);
+unicode = 2010;
+},
+{
+glyphname = NonBreakingHyphen;
+layers = (
+{
+anchors = (
+{
+name = U;
+position = "{645, 1100}";
+}
+);
+components = (
+{
+name = HyphenMinus;
+}
+);
+layerId = master01;
+width = 840;
+},
+{
+anchors = (
+{
+name = U;
+position = "{665, 1100}";
+}
+);
+components = (
+{
+name = HyphenMinus;
+}
+);
+layerId = master02;
+width = 875;
+}
+);
+unicode = 2011;
+},
+{
+glyphname = Hyphen_Soft;
+layers = (
+{
+anchors = (
+{
+name = U;
+position = "{645, 1100}";
+}
+);
+components = (
+{
+name = HyphenMinus;
+}
+);
+layerId = master01;
+width = 840;
+},
+{
+anchors = (
+{
+name = U;
+position = "{665, 1100}";
+}
+);
+components = (
+{
+name = HyphenMinus;
+}
+);
+layerId = master02;
+width = 875;
+}
+);
+unicode = 00AD;
+},
+{
+glyphname = CombAcute;
+layers = (
+{
+anchors = (
+{
+name = U;
+position = "{-221, 1635}";
+},
+{
+name = _U;
+position = "{-355, 1100}";
+}
+);
+layerId = master01;
+paths = (
+{
+closed = 1;
+nodes = (
+"-524 1147 LINE",
+"-354 1147 LINE",
+"150 1568 LINE",
+"-99 1568 LINE"
+);
+}
+);
+width = 0;
+},
+{
+anchors = (
+{
+name = U;
+position = "{-251, 1635}";
+},
+{
+name = _U;
+position = "{-325, 1100}";
+}
+);
+layerId = master02;
+paths = (
+{
+closed = 1;
+nodes = (
+"-523 1188 LINE",
+"-283 1188 LINE",
+"204 1584 LINE",
+"-165 1584 LINE"
+);
+}
+);
+width = 0;
+}
+);
+unicode = 0301;
+},
+{
+glyphname = CombGrave;
+layers = (
+{
+anchors = (
+{
+name = U;
+position = "{-201, 1635}";
+},
+{
+name = _U;
+position = "{-335, 1100}";
+}
+);
+layerId = master01;
+paths = (
+{
+closed = 1;
+nodes = (
+"-284 1147 LINE",
+"-134 1147 LINE",
+"-409 1568 LINE",
+"-619 1568 LINE"
+);
+}
+);
+width = 0;
+},
+{
+anchors = (
+{
+name = U;
+position = "{-241, 1635}";
+},
+{
+name = _U;
+position = "{-415, 1100}";
+}
+);
+layerId = master02;
+paths = (
+{
+closed = 1;
+nodes = (
+"-403 1188 LINE",
+"-173 1188 LINE",
+"-395 1584 LINE",
+"-725 1584 LINE"
+);
+}
+);
+width = 0;
+}
+);
+unicode = 0300;
+},
+{
+glyphname = CombCircum;
+layers = (
+{
+anchors = (
+{
+name = U;
+position = "{-221, 1635}";
+},
+{
+name = _U;
+position = "{-320, 1100}";
+}
+);
+layerId = master01;
+paths = (
+{
+closed = 1;
+nodes = (
+"-275 1421 LINE",
+"-69 1147 LINE",
+"80 1147 LINE",
+"-174 1568 LINE",
+"-344 1568 LINE",
+"-769 1147 LINE",
+"-619 1147 LINE"
+);
+}
+);
+width = 0;
+},
+{
+anchors = (
+{
+name = U;
+position = "{-239, 1635}";
+},
+{
+name = _U;
+position = "{-330, 1100}";
+}
+);
+layerId = master02;
+paths = (
+{
+closed = 1;
+nodes = (
+"-123 1584 LINE",
+"-423 1584 LINE",
+"-791 1188 LINE",
+"-551 1188 LINE",
+"-294 1416 LINE",
+"-151 1188 LINE",
+"88 1188 LINE"
+);
+}
+);
+width = 0;
+}
+);
+unicode = 0302;
+},
+{
+glyphname = CombTilde;
+layers = (
+{
+anchors = (
+{
+name = U;
+position = "{-290, 1475}";
+},
+{
+name = _U;
+position = "{-385, 1100}";
+}
+);
+layerId = master01;
+paths = (
+{
+closed = 1;
+nodes = (
+"-629 1229 OFFCURVE",
+"-589 1269 OFFCURVE",
+"-540 1269 CURVE SMOOTH",
+"-503 1269 OFFCURVE",
+"-466 1253 OFFCURVE",
+"-398 1218 CURVE SMOOTH",
+"-344 1190 OFFCURVE",
+"-296 1171 OFFCURVE",
+"-243 1171 CURVE SMOOTH",
+"-120 1171 OFFCURVE",
+"-15 1286 OFFCURVE",
+"16 1411 CURVE",
+"-89 1411 LINE",
+"-107 1366 OFFCURVE",
+"-147 1323 OFFCURVE",
+"-194 1323 CURVE SMOOTH",
+"-236 1323 OFFCURVE",
+"-273 1342 OFFCURVE",
+"-338 1370 CURVE SMOOTH",
+"-401 1397 OFFCURVE",
+"-442 1421 OFFCURVE",
+"-498 1421 CURVE SMOOTH",
+"-617 1421 OFFCURVE",
+"-721 1300 OFFCURVE",
+"-751 1181 CURVE",
+"-646 1181 LINE"
+);
+}
+);
+width = 0;
+},
+{
+anchors = (
+{
+name = U;
+position = "{-355, 1490}";
+},
+{
+name = _U;
+position = "{-390, 1100}";
+}
+);
+layerId = master02;
+paths = (
+{
+closed = 1;
+nodes = (
+"-673 1232 OFFCURVE",
+"-628 1271 OFFCURVE",
+"-584 1271 CURVE SMOOTH",
+"-546 1271 OFFCURVE",
+"-498 1247 OFFCURVE",
+"-437 1217 CURVE SMOOTH",
+"-375 1187 OFFCURVE",
+"-327 1168 OFFCURVE",
+"-265 1168 CURVE SMOOTH",
+"-129 1168 OFFCURVE",
+"-13 1294 OFFCURVE",
+"30 1465 CURVE",
+"-125 1465 LINE",
+"-138 1415 OFFCURVE",
+"-190 1373 OFFCURVE",
+"-235 1373 CURVE SMOOTH",
+"-272 1373 OFFCURVE",
+"-306 1399 OFFCURVE",
+"-366 1423 CURVE SMOOTH",
+"-438 1452 OFFCURVE",
+"-498 1475 OFFCURVE",
+"-563 1475 CURVE SMOOTH",
+"-695 1475 OFFCURVE",
+"-802 1336 OFFCURVE",
+"-842 1178 CURVE",
+"-687 1178 LINE"
+);
+}
+);
+width = 0;
+}
+);
+unicode = 0303;
+},
+{
+glyphname = CombDiaer;
+layers = (
+{
+anchors = (
+{
+name = U;
+position = "{-253, 1505}";
+},
+{
+name = _U;
+position = "{-350, 1100}";
+}
+);
+layerId = master01;
+paths = (
+{
+closed = 1;
+nodes = (
+"39 1399 OFFCURVE",
+"-7 1450 OFFCURVE",
+"-72 1450 CURVE SMOOTH",
+"-167 1450 OFFCURVE",
+"-229 1372 OFFCURVE",
+"-229 1299 CURVE SMOOTH",
+"-229 1238 OFFCURVE",
+"-182 1186 OFFCURVE",
+"-118 1186 CURVE SMOOTH",
+"-33 1186 OFFCURVE",
+"39 1259 OFFCURVE",
+"39 1338 CURVE SMOOTH"
+);
+},
+{
+closed = 1;
+nodes = (
+"-381 1399 OFFCURVE",
+"-427 1450 OFFCURVE",
+"-492 1450 CURVE SMOOTH",
+"-587 1450 OFFCURVE",
+"-649 1372 OFFCURVE",
+"-649 1299 CURVE SMOOTH",
+"-649 1238 OFFCURVE",
+"-602 1186 OFFCURVE",
+"-538 1186 CURVE SMOOTH",
+"-453 1186 OFFCURVE",
+"-381 1259 OFFCURVE",
+"-381 1338 CURVE SMOOTH"
+);
+}
+);
+width = 0;
+},
+{
+anchors = (
+{
+name = U;
+position = "{-243, 1585}";
+},
+{
+name = _U;
+position = "{-365, 1100}";
+}
+);
+layerId = master02;
+paths = (
+{
+closed = 1;
+nodes = (
+"-233 1256 OFFCURVE",
+"-172 1198 OFFCURVE",
+"-86 1198 CURVE SMOOTH",
+"32 1198 OFFCURVE",
+"126 1294 OFFCURVE",
+"126 1404 CURVE SMOOTH",
+"126 1484 OFFCURVE",
+"66 1544 OFFCURVE",
+"-21 1544 CURVE SMOOTH",
+"-139 1544 OFFCURVE",
+"-233 1447 OFFCURVE",
+"-233 1338 CURVE SMOOTH"
+);
+},
+{
+closed = 1;
+nodes = (
+"-723 1256 OFFCURVE",
+"-662 1198 OFFCURVE",
+"-576 1198 CURVE SMOOTH",
+"-457 1198 OFFCURVE",
+"-363 1293 OFFCURVE",
+"-363 1404 CURVE SMOOTH",
+"-363 1484 OFFCURVE",
+"-423 1544 OFFCURVE",
+"-510 1544 CURVE SMOOTH",
+"-628 1544 OFFCURVE",
+"-723 1448 OFFCURVE",
+"-723 1338 CURVE SMOOTH"
+);
+}
+);
+width = 0;
+}
+);
+unicode = 0308;
+},
+{
+glyphname = CombRingAbv;
+layers = (
+{
+anchors = (
+{
+name = U;
+position = "{-221, 1635}";
+},
+{
+name = _U;
+position = "{-385, 1100}";
+}
+);
+layerId = master01;
+paths = (
+{
+closed = 1;
+nodes = (
+"-427 1259 OFFCURVE",
+"-456 1287 OFFCURVE",
+"-456 1329 CURVE SMOOTH",
+"-456 1400 OFFCURVE",
+"-393 1455 OFFCURVE",
+"-328 1455 CURVE SMOOTH",
+"-278 1455 OFFCURVE",
+"-248 1428 OFFCURVE",
+"-248 1385 CURVE SMOOTH",
+"-248 1314 OFFCURVE",
+"-312 1259 OFFCURVE",
+"-377 1259 CURVE SMOOTH"
+);
+},
+{
+closed = 1;
+nodes = (
+"-573 1224 OFFCURVE",
+"-498 1147 OFFCURVE",
+"-395 1147 CURVE SMOOTH",
+"-257 1147 OFFCURVE",
+"-131 1263 OFFCURVE",
+"-131 1394 CURVE SMOOTH",
+"-131 1491 OFFCURVE",
+"-206 1568 OFFCURVE",
+"-310 1568 CURVE SMOOTH",
+"-448 1568 OFFCURVE",
+"-573 1451 OFFCURVE",
+"-573 1320 CURVE SMOOTH"
+);
+}
+);
+width = 0;
+},
+{
+anchors = (
+{
+name = U;
+position = "{-221, 1635}";
+},
+{
+name = _U;
+position = "{-357, 1100}";
+}
+);
+layerId = master02;
+paths = (
+{
+closed = 1;
+nodes = (
+"-406 1292 OFFCURVE",
+"-442 1330 OFFCURVE",
+"-442 1375 CURVE SMOOTH",
+"-442 1440 OFFCURVE",
+"-385 1480 OFFCURVE",
+"-331 1480 CURVE SMOOTH",
+"-283 1480 OFFCURVE",
+"-247 1443 OFFCURVE",
+"-247 1398 CURVE SMOOTH",
+"-247 1335 OFFCURVE",
+"-301 1292 OFFCURVE",
+"-358 1292 CURVE SMOOTH"
+);
+},
+{
+closed = 1;
+nodes = (
+"-598 1238 OFFCURVE",
+"-504 1148 OFFCURVE",
+"-384 1148 CURVE SMOOTH",
+"-223 1148 OFFCURVE",
+"-92 1271 OFFCURVE",
+"-92 1424 CURVE SMOOTH",
+"-92 1534 OFFCURVE",
+"-186 1624 OFFCURVE",
+"-306 1624 CURVE SMOOTH",
+"-467 1624 OFFCURVE",
+"-598 1501 OFFCURVE",
+"-598 1348 CURVE SMOOTH"
+);
+}
+);
+width = 0;
+}
+);
+unicode = 030A;
+}
+);
+instances = (
+{
+interpolationWeight = 400;
+instanceInterpolations = {
+master01 = 1;
+};
+name = Italic;
+},
+{
+interpolationWeight = 700;
+instanceInterpolations = {
+master02 = 1;
+};
+name = "Bold Italic";
+}
+);
+manufacturer = "SIL International";
+manufacturerURL = "http://scripts.sil.org";
+unitsPerEm = 2048;
+versionMajor = 5;
+versionMinor = 550;
+}
diff --git a/tests/input/font-psf-test/source/PsfTestRoman.designspace b/tests/input/font-psf-test/source/PsfTestRoman.designspace
new file mode 100644
index 0000000..a93e3bd
--- /dev/null
+++ b/tests/input/font-psf-test/source/PsfTestRoman.designspace
@@ -0,0 +1,58 @@
+<?xml version='1.0' encoding='utf-8'?>
+<designspace format="3">
+ <axes>
+ <axis default="400.0" maximum="700.0" minimum="400.0" name="weight" tag="wght">
+ <map input="400.0" output="400.0" />
+ <map input="700.0" output="700.0" />
+ <labelname xml:lang="en">Weight</labelname>
+ </axis>
+ <axis default="100.0" maximum="100.0" minimum="100.0" name="width" tag="wdth">
+ <map input="100.0" output="100.0" />
+ <labelname xml:lang="en">Width</labelname>
+ </axis>
+ <axis default="0.0" maximum="0.0" minimum="0.0" name="custom" tag="XXXX">
+ <map input="0.0" output="0.0" />
+ <labelname xml:lang="en">Custom</labelname>
+ </axis>
+ </axes>
+ <sources>
+ <source familyname="Psf Test" filename="PsfTest-Regular.ufo" name="Psf Test Regular" stylename="Regular">
+ <lib copy="1" />
+ <groups copy="1" />
+ <features copy="1" />
+ <info copy="1" />
+ <location>
+ <dimension name="weight" xvalue="400.000000" />
+ <dimension name="width" xvalue="100.000000" />
+ <dimension name="custom" xvalue="0.000000" />
+ </location>
+ </source>
+ <source familyname="Psf Test" filename="PsfTest-Bold.ufo" name="Psf Test Bold" stylename="Bold">
+ <location>
+ <dimension name="weight" xvalue="700.000000" />
+ <dimension name="width" xvalue="100.000000" />
+ <dimension name="custom" xvalue="0.000000" />
+ </location>
+ </source>
+ </sources>
+ <instances>
+ <instance familyname="Psf Test" filename="PsfTest-Regular.ufo" name="Psf Test Regular" stylemapfamilyname="Psf Test" stylemapstylename="regular" stylename="Regular">
+ <location>
+ <dimension name="weight" xvalue="400.000000" />
+ <dimension name="width" xvalue="100.000000" />
+ <dimension name="custom" xvalue="0.000000" />
+ </location>
+ <info />
+ <kerning />
+ </instance>
+ <instance familyname="Psf Test" filename="PsfTest-Bold.ufo" name="Psf Test Bold" stylemapfamilyname="Psf Test" stylemapstylename="bold" stylename="Bold">
+ <location>
+ <dimension name="weight" xvalue="700.000000" />
+ <dimension name="width" xvalue="100.000000" />
+ <dimension name="custom" xvalue="0.000000" />
+ </location>
+ <info />
+ <kerning />
+ </instance>
+ </instances>
+</designspace>
diff --git a/tests/input/font-psf-test/source/PsfTestRoman.glyphs b/tests/input/font-psf-test/source/PsfTestRoman.glyphs
new file mode 100644
index 0000000..3767f74
--- /dev/null
+++ b/tests/input/font-psf-test/source/PsfTestRoman.glyphs
@@ -0,0 +1,12025 @@
+{
+.appVersion = "1165";
+copyright = "Copyright (c) 2004-2021 SIL International";
+customParameters = (
+{
+name = glyphOrder;
+value = (
+.notdef,
+.null,
+nonmarkingreturn,
+Space,
+ExclamationMrk,
+QuotMrk,
+NumSgn,
+DollarSgn,
+PercentSgn,
+Ampersand,
+Apos,
+LftParen,
+RtParen,
+Asterisk,
+PlusSgn,
+Comma,
+HyphenMinus,
+FullStop,
+Solidus,
+DigitZero,
+DigitOne,
+DigitTwo,
+DigitThree,
+DigitFour,
+DigitFive,
+DigitSix,
+DigitSeven,
+DigitEight,
+DigitNine,
+Colon,
+Semicolon,
+LTSgn,
+EqSgn,
+GTSgn,
+QstnMrk,
+AtSgn,
+LtnCapA,
+LtnCapA.alt,
+LtnCapB,
+LtnCapC,
+LtnCapD,
+LtnCapE,
+LtnCapF,
+LtnCapG,
+LtnCapH,
+LtnCapI,
+LtnCapJ,
+LtnCapK,
+LtnCapL,
+LtnCapM,
+LtnCapN,
+LtnCapO,
+LtnCapP,
+LtnCapQ,
+LtnCapR,
+LtnCapS,
+LtnCapT,
+LtnCapU,
+LtnCapV,
+LtnCapW,
+LtnCapX,
+LtnCapY,
+LftSqrBrac,
+ReverseSolidus,
+RtSqrBrac,
+CircumAccent,
+LowLine,
+GraveAccent,
+LtnSmA,
+LtnSmB,
+LtnSmC,
+LtnSmD,
+LtnSmE,
+LtnSmF,
+LtnSmG,
+LtnSmH,
+LtnSmI,
+LtnSmJ,
+LtnSmK,
+LtnSmL,
+LtnSmM,
+LtnSmN,
+LtnSmO,
+LtnSmP,
+LtnSmQ,
+LtnSmR,
+LtnSmS,
+LtnSmT,
+LtnSmU,
+LtnSmV,
+LtnSmW,
+LtnSmX,
+LtnSmY,
+LftCurlyBrac,
+VertLine,
+RtCurlyBrac,
+Tilde,
+LtnCapADiaer,
+LtnSmAAcute,
+LtnSmAGrave,
+LtnSmACircum,
+LtnSmADiaer,
+LtnSmATilde,
+LtnSmARingAbv,
+DottedCirc,
+Hyphen,
+NonBreakingHyphen,
+Hyphen_Soft,
+CombAcute,
+CombGrave,
+CombCircum,
+CombTilde,
+CombDiaer,
+CombRingAbv
+);
+},
+{
+name = "Disable Last Change";
+value = 1;
+},
+{
+name = note;
+value = "Test note\012Second line\012\012Third line\012";
+},
+{
+name = description;
+value = "Copyright (c) 2004-2021 SIL International";
+},
+{
+name = openTypeNameLicense;
+value = "Copyright (c) 2004-2021 SIL International (http://www.sil.org/) with Reserved Font Names \"Andika\" and \"SIL\".\012\012This Font Software is licensed under the SIL Open Font License, Version 1.1. This license is copied below, and is also available with a FAQ at: http://scripts.sil.org/OFL\012\012\012-----------------------------------------------------------\012SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007\012-----------------------------------------------------------\012\012PREAMBLE\012The goals of the Open Font License (OFL) are to stimulate worldwide development of collaborative font projects, to support the font creation efforts of academic and linguistic communities, and to provide a free and open framework in which fonts may be shared and improved in partnership with others.\012\012The OFL allows the licensed fonts to be used, studied, modified and redistributed freely as long as they are not sold by themselves. The fonts, including any derivative works, can be bundled, embedded, redistributed and/or sold with any software provided that any reserved names are not used by derivative works. The fonts and derivatives, however, cannot be released under any other type of license. The requirement for fonts to remain under this license does not apply to any document created using the fonts or their derivatives.\012\012DEFINITIONS\012\"Font Software\" refers to the set of files released by the Copyright Holder(s) under this license and clearly marked as such. This may include source files, build scripts and documentation.\012\012\"Reserved Font Name\" refers to any names specified as such after the copyright statement(s).\012\012\"Original Version\" refers to the collection of Font Software components as distributed by the Copyright Holder(s).\012\012\"Modified Version\" refers to any derivative made by adding to, deleting, or substituting -- in part or in whole -- any of the components of the Original Version, by changing formats or by porting the Font Software to a new environment.\012\012\"Author\" refers to any designer, engineer, programmer, technical writer or other person who contributed to the Font Software.\012\012PERMISSION & CONDITIONS\012Permission is hereby granted, free of charge, to any person obtaining a copy of the Font Software, to use, study, copy, merge, embed, modify, redistribute, and sell modified and unmodified copies of the Font Software, subject to the following conditions:\012\0121) Neither the Font Software nor any of its individual components, in Original or Modified Versions, may be sold by itself.\012\0122) Original or Modified Versions of the Font Software may be bundled, redistributed and/or sold with any software, provided that each copy contains the above copyright notice and this license. These can be included either as stand-alone text files, human-readable headers or in the appropriate machine-readable metadata fields within text or binary files as long as those fields can be easily viewed by the user.\012\0123) No Modified Version of the Font Software may use the Reserved Font Name(s) unless explicit written permission is granted by the corresponding Copyright Holder. This restriction only applies to the primary font name as presented to the users.\012\0124) The name(s) of the Copyright Holder(s) or the Author(s) of the Font Software shall not be used to promote, endorse or advertise any Modified Version, except to acknowledge the contribution(s) of the Copyright Holder(s) and the Author(s) or with their explicit written permission.\012\0125) The Font Software, modified or unmodified, in part or in whole, must be distributed entirely under this license, and must not be distributed under any other license. The requirement for fonts to remain under this license does not apply to any document created using the Font Software.\012\012TERMINATION\012This license becomes null and void if any of the above conditions are not met.\012\012DISCLAIMER\012THE FONT SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM OTHER DEALINGS IN THE FONT SOFTWARE.";
+},
+{
+name = openTypeNameLicenseURL;
+value = "http://scripts.sil.org/OFL";
+},
+{
+name = openTypeNameUniqueID;
+value = "SIL International: Psf Test Regular: 2021";
+},
+{
+name = openTypeNameVersion;
+value = "Version 5.550";
+},
+{
+name = codePageRanges;
+value = (
+1252,
+1250,
+1251,
+1254,
+1257,
+1258
+);
+},
+{
+name = openTypeOS2FamilyClass;
+value = (
+0,
+0
+);
+},
+{
+name = openTypeOS2Panose;
+value = (
+2,
+0,
+0,
+0,
+0,
+0,
+0,
+0,
+0,
+0
+);
+},
+{
+name = openTypeOS2StrikeoutPosition;
+value = 700;
+},
+{
+name = openTypeOS2StrikeoutSize;
+value = 100;
+},
+{
+name = openTypeOS2SubscriptXOffset;
+value = 0;
+},
+{
+name = openTypeOS2SubscriptXSize;
+value = 1433;
+},
+{
+name = openTypeOS2SubscriptYOffset;
+value = 286;
+},
+{
+name = openTypeOS2SubscriptYSize;
+value = 1331;
+},
+{
+name = openTypeOS2SuperscriptXOffset;
+value = 0;
+},
+{
+name = openTypeOS2SuperscriptXSize;
+value = 1433;
+},
+{
+name = openTypeOS2SuperscriptYOffset;
+value = 976;
+},
+{
+name = openTypeOS2SuperscriptYSize;
+value = 1331;
+},
+{
+name = fsType;
+value = (
+);
+},
+{
+name = unicodeRanges;
+value = (
+0,
+1,
+6,
+7,
+31,
+33,
+35,
+36,
+37,
+38,
+39,
+40,
+45,
+46,
+47,
+57,
+60,
+62,
+64,
+67,
+69,
+89
+);
+},
+{
+name = vendorID;
+value = SIL;
+},
+{
+name = trademark;
+value = "Andika is a trademark of SIL International.";
+}
+);
+date = "2021-01-01 11:00:00 +0000";
+designer = "Victor Gaultney, Annie Olsen, Julie Remington, Don Collingsworth, Eric Hays, Becca Hirsbrunner";
+designerURL = "http://scripts.sil.org/";
+disablesAutomaticAlignment = 1;
+disablesNiceNames = 1;
+familyName = "Psf Test";
+fontMaster = (
+{
+alignmentZones = (
+"{1600, 20}",
+"{1455, 30}",
+"{1020, 20}",
+"{0, -25}",
+"{-490, 0}"
+);
+ascender = 2100;
+capHeight = 1485;
+customParameters = (
+{
+name = typoAscender;
+value = 2100;
+},
+{
+name = typoDescender;
+value = -550;
+},
+{
+name = typoLineGap;
+value = 0;
+},
+{
+name = hheaAscender;
+value = 2100;
+},
+{
+name = hheaDescender;
+value = -550;
+},
+{
+name = hheaLineGap;
+value = 0;
+},
+{
+name = winAscent;
+value = 2100;
+},
+{
+name = winDescent;
+value = 550;
+},
+{
+name = underlineThickness;
+value = 80;
+},
+{
+name = underlinePosition;
+value = -110;
+}
+);
+descender = -550;
+guideLines = (
+{
+position = "{1084, 1040}";
+},
+{
+position = "{0, 1250}";
+}
+);
+horizontalStems = (
+140,
+145,
+150,
+155,
+160,
+165,
+170,
+175,
+185,
+270
+);
+id = master01;
+verticalStems = (
+165,
+180,
+185,
+190,
+195,
+200,
+205,
+270
+);
+weightValue = 400;
+xHeight = 1040;
+},
+{
+alignmentZones = (
+"{1600, 20}",
+"{1455, 30}",
+"{1020, 20}",
+"{0, -25}",
+"{-490, 0}"
+);
+ascender = 2100;
+capHeight = 1485;
+customParameters = (
+{
+name = typoAscender;
+value = 2100;
+},
+{
+name = typoDescender;
+value = -550;
+},
+{
+name = typoLineGap;
+value = 0;
+},
+{
+name = hheaAscender;
+value = 2100;
+},
+{
+name = hheaDescender;
+value = -550;
+},
+{
+name = hheaLineGap;
+value = 0;
+},
+{
+name = winAscent;
+value = 2100;
+},
+{
+name = winDescent;
+value = 550;
+},
+{
+name = underlineThickness;
+value = 80;
+},
+{
+name = underlinePosition;
+value = -110;
+}
+);
+descender = -550;
+horizontalStems = (
+140,
+145,
+150,
+155,
+160,
+165,
+170,
+175,
+185,
+270
+);
+id = master02;
+verticalStems = (
+165,
+180,
+185,
+190,
+195,
+200,
+205,
+270
+);
+weight = Bold;
+weightValue = 700;
+xHeight = 1040;
+}
+);
+glyphs = (
+{
+glyphname = .notdef;
+layers = (
+{
+layerId = master01;
+paths = (
+{
+closed = 1;
+nodes = (
+"1300 0 LINE",
+"1300 1800 LINE",
+"100 1800 LINE",
+"100 0 LINE"
+);
+},
+{
+closed = 1;
+nodes = (
+"1250 1750 LINE",
+"1250 50 LINE",
+"150 50 LINE",
+"150 1750 LINE"
+);
+}
+);
+width = 1400;
+},
+{
+layerId = master02;
+paths = (
+{
+closed = 1;
+nodes = (
+"1300 0 LINE",
+"1300 1800 LINE",
+"100 1800 LINE",
+"100 0 LINE"
+);
+},
+{
+closed = 1;
+nodes = (
+"1250 1750 LINE",
+"1250 50 LINE",
+"150 50 LINE",
+"150 1750 LINE"
+);
+}
+);
+width = 1400;
+}
+);
+},
+{
+glyphname = .null;
+layers = (
+{
+layerId = master01;
+width = 0;
+},
+{
+layerId = master02;
+width = 0;
+}
+);
+},
+{
+glyphname = nonmarkingreturn;
+layers = (
+{
+layerId = master01;
+width = 1024;
+},
+{
+layerId = master02;
+width = 1024;
+}
+);
+},
+{
+glyphname = Space;
+layers = (
+{
+layerId = master01;
+width = 550;
+},
+{
+layerId = master02;
+width = 550;
+}
+);
+unicode = 0020;
+},
+{
+glyphname = ExclamationMrk;
+layers = (
+{
+layerId = master01;
+paths = (
+{
+closed = 1;
+nodes = (
+"456 730 OFFCURVE",
+"451 1076 OFFCURVE",
+"490 1510 CURVE",
+"235 1510 LINE",
+"273 1076 OFFCURVE",
+"268 730 OFFCURVE",
+"275 440 CURVE",
+"450 440 LINE"
+);
+},
+{
+closed = 1;
+nodes = (
+"225 36 OFFCURVE",
+"286 -25 OFFCURVE",
+"360 -25 CURVE SMOOTH",
+"434 -25 OFFCURVE",
+"495 36 OFFCURVE",
+"495 110 CURVE SMOOTH",
+"495 184 OFFCURVE",
+"434 245 OFFCURVE",
+"360 245 CURVE SMOOTH",
+"286 245 OFFCURVE",
+"225 184 OFFCURVE",
+"225 110 CURVE SMOOTH"
+);
+}
+);
+width = 764;
+},
+{
+layerId = master02;
+paths = (
+{
+closed = 1;
+nodes = (
+"536 790 OFFCURVE",
+"531 1076 OFFCURVE",
+"570 1510 CURVE",
+"235 1510 LINE",
+"273 1076 OFFCURVE",
+"268 790 OFFCURVE",
+"275 500 CURVE",
+"530 500 LINE"
+);
+},
+{
+closed = 1;
+nodes = (
+"230 46 OFFCURVE",
+"304 -25 OFFCURVE",
+"405 -25 CURVE SMOOTH",
+"507 -25 OFFCURVE",
+"580 46 OFFCURVE",
+"580 150 CURVE SMOOTH",
+"580 252 OFFCURVE",
+"507 325 OFFCURVE",
+"405 325 CURVE SMOOTH",
+"304 325 OFFCURVE",
+"230 252 OFFCURVE",
+"230 150 CURVE SMOOTH"
+);
+}
+);
+width = 780;
+}
+);
+unicode = 0021;
+},
+{
+glyphname = QuotMrk;
+layers = (
+{
+layerId = master01;
+paths = (
+{
+closed = 1;
+nodes = (
+"410 1186 OFFCURVE",
+"416 1339 OFFCURVE",
+"445 1585 CURVE",
+"240 1585 LINE",
+"271 1339 OFFCURVE",
+"276 1186 OFFCURVE",
+"280 1045 CURVE",
+"405 1045 LINE"
+);
+},
+{
+closed = 1;
+nodes = (
+"750 1186 OFFCURVE",
+"756 1339 OFFCURVE",
+"785 1585 CURVE",
+"580 1585 LINE",
+"611 1339 OFFCURVE",
+"616 1186 OFFCURVE",
+"620 1045 CURVE",
+"745 1045 LINE"
+);
+}
+);
+width = 1025;
+},
+{
+layerId = master02;
+paths = (
+{
+closed = 1;
+nodes = (
+"455 1186 OFFCURVE",
+"456 1339 OFFCURVE",
+"485 1585 CURVE",
+"240 1585 LINE",
+"271 1339 OFFCURVE",
+"271 1186 OFFCURVE",
+"275 1045 CURVE",
+"450 1045 LINE"
+);
+},
+{
+closed = 1;
+nodes = (
+"815 1186 OFFCURVE",
+"816 1339 OFFCURVE",
+"845 1585 CURVE",
+"600 1585 LINE",
+"631 1339 OFFCURVE",
+"631 1186 OFFCURVE",
+"635 1045 CURVE",
+"810 1045 LINE"
+);
+}
+);
+width = 1085;
+}
+);
+unicode = 0022;
+},
+{
+glyphname = NumSgn;
+layers = (
+{
+layerId = master01;
+paths = (
+{
+closed = 1;
+nodes = (
+"127 200 LINE",
+"277 200 LINE",
+"637 1460 LINE",
+"487 1460 LINE"
+);
+},
+{
+closed = 1;
+nodes = (
+"1116 575 LINE",
+"1116 725 LINE",
+"25 725 LINE",
+"25 575 LINE"
+);
+},
+{
+closed = 1;
+nodes = (
+"1175 960 LINE",
+"1175 1110 LINE",
+"84 1110 LINE",
+"84 960 LINE"
+);
+},
+{
+closed = 1;
+nodes = (
+"552 200 LINE",
+"702 200 LINE",
+"1062 1460 LINE",
+"912 1460 LINE"
+);
+}
+);
+width = 1200;
+},
+{
+layerId = master02;
+paths = (
+{
+closed = 1;
+nodes = (
+"52 100 LINE",
+"272 100 LINE",
+"632 1360 LINE",
+"412 1360 LINE"
+);
+},
+{
+closed = 1;
+nodes = (
+"1101 425 LINE",
+"1101 635 LINE",
+"10 635 LINE",
+"10 425 LINE"
+);
+},
+{
+closed = 1;
+nodes = (
+"1160 850 LINE",
+"1160 1060 LINE",
+"69 1060 LINE",
+"69 850 LINE"
+);
+},
+{
+closed = 1;
+nodes = (
+"527 100 LINE",
+"747 100 LINE",
+"1107 1360 LINE",
+"887 1360 LINE"
+);
+}
+);
+width = 1200;
+}
+);
+unicode = 0023;
+},
+{
+glyphname = DollarSgn;
+layers = (
+{
+layerId = master01;
+paths = (
+{
+closed = 1;
+nodes = (
+"553 -220 LINE",
+"683 -220 LINE",
+"683 1600 LINE",
+"553 1600 LINE"
+);
+},
+{
+closed = 1;
+nodes = (
+"866 1364 OFFCURVE",
+"764 1389 OFFCURVE",
+"623 1389 CURVE SMOOTH",
+"317 1389 OFFCURVE",
+"190 1173 OFFCURVE",
+"190 1017 CURVE SMOOTH",
+"190 860 OFFCURVE",
+"253 739 OFFCURVE",
+"540 653 CURVE SMOOTH",
+"827 567 OFFCURVE",
+"871 492 OFFCURVE",
+"871 396 CURVE SMOOTH",
+"871 247 OFFCURVE",
+"734 161 OFFCURVE",
+"586 161 CURVE SMOOTH",
+"450 161 OFFCURVE",
+"316 207 OFFCURVE",
+"195 313 CURVE",
+"153 124 LINE",
+"247 52 OFFCURVE",
+"408 0 OFFCURVE",
+"586 0 CURVE SMOOTH",
+"837 0 OFFCURVE",
+"1046 167 OFFCURVE",
+"1046 414 CURVE SMOOTH",
+"1046 613 OFFCURVE",
+"912 725 OFFCURVE",
+"669 796 CURVE SMOOTH",
+"406 873 OFFCURVE",
+"365 929 OFFCURVE",
+"365 1030 CURVE SMOOTH",
+"365 1132 OFFCURVE",
+"466 1228 OFFCURVE",
+"613 1228 CURVE SMOOTH",
+"731 1228 OFFCURVE",
+"818 1200 OFFCURVE",
+"949 1127 CURVE",
+"986 1306 LINE"
+);
+}
+);
+width = 1200;
+},
+{
+layerId = master02;
+paths = (
+{
+closed = 1;
+nodes = (
+"886 1374 OFFCURVE",
+"764 1389 OFFCURVE",
+"623 1389 CURVE SMOOTH",
+"317 1389 OFFCURVE",
+"150 1203 OFFCURVE",
+"150 1017 CURVE SMOOTH",
+"150 830 OFFCURVE",
+"275 730 OFFCURVE",
+"540 623 CURVE SMOOTH",
+"802 517 OFFCURVE",
+"851 472 OFFCURVE",
+"851 386 CURVE SMOOTH",
+"851 267 OFFCURVE",
+"744 211 OFFCURVE",
+"586 211 CURVE SMOOTH",
+"440 211 OFFCURVE",
+"297 281 OFFCURVE",
+"195 383 CURVE",
+"123 124 LINE",
+"216 49 OFFCURVE",
+"388 0 OFFCURVE",
+"586 0 CURVE SMOOTH",
+"847 0 OFFCURVE",
+"1086 147 OFFCURVE",
+"1086 414 CURVE SMOOTH",
+"1086 633 OFFCURVE",
+"927 723 OFFCURVE",
+"679 826 CURVE SMOOTH",
+"431 929 OFFCURVE",
+"385 969 OFFCURVE",
+"385 1040 CURVE SMOOTH",
+"385 1132 OFFCURVE",
+"466 1188 OFFCURVE",
+"613 1188 CURVE SMOOTH",
+"741 1188 OFFCURVE",
+"876 1154 OFFCURVE",
+"949 1077 CURVE",
+"1006 1316 LINE"
+);
+},
+{
+closed = 1;
+nodes = (
+"548 788 LINE",
+"518 726 LINE",
+"518 -220 LINE",
+"688 -220 LINE",
+"688 668 LINE",
+"718 734 LINE",
+"718 1600 LINE",
+"548 1600 LINE"
+);
+}
+);
+width = 1200;
+}
+);
+unicode = 0024;
+},
+{
+glyphname = PercentSgn;
+layers = (
+{
+layerId = master01;
+paths = (
+{
+closed = 1;
+nodes = (
+"1261 182 OFFCURVE",
+"1216 115 OFFCURVE",
+"1130 115 CURVE SMOOTH",
+"1041 115 OFFCURVE",
+"1001 181 OFFCURVE",
+"1001 381 CURVE SMOOTH",
+"1001 565 OFFCURVE",
+"1043 630 OFFCURVE",
+"1130 630 CURVE SMOOTH",
+"1221 630 OFFCURVE",
+"1261 566 OFFCURVE",
+"1261 366 CURVE SMOOTH"
+);
+},
+{
+closed = 1;
+nodes = (
+"1426 652 OFFCURVE",
+"1310 770 OFFCURVE",
+"1135 770 CURVE SMOOTH",
+"961 770 OFFCURVE",
+"836 650 OFFCURVE",
+"836 368 CURVE SMOOTH",
+"836 86 OFFCURVE",
+"951 -25 OFFCURVE",
+"1126 -25 CURVE SMOOTH",
+"1301 -25 OFFCURVE",
+"1426 84 OFFCURVE",
+"1426 379 CURVE SMOOTH"
+);
+},
+{
+closed = 1;
+nodes = (
+"291 -25 LINE",
+"459 -25 LINE",
+"1239 1480 LINE",
+"1073 1480 LINE"
+);
+},
+{
+closed = 1;
+nodes = (
+"525 892 OFFCURVE",
+"480 825 OFFCURVE",
+"394 825 CURVE SMOOTH",
+"305 825 OFFCURVE",
+"265 891 OFFCURVE",
+"265 1091 CURVE SMOOTH",
+"265 1275 OFFCURVE",
+"307 1340 OFFCURVE",
+"394 1340 CURVE SMOOTH",
+"485 1340 OFFCURVE",
+"525 1276 OFFCURVE",
+"525 1076 CURVE SMOOTH"
+);
+},
+{
+closed = 1;
+nodes = (
+"690 1362 OFFCURVE",
+"574 1480 OFFCURVE",
+"399 1480 CURVE SMOOTH",
+"225 1480 OFFCURVE",
+"100 1360 OFFCURVE",
+"100 1078 CURVE SMOOTH",
+"100 796 OFFCURVE",
+"215 685 OFFCURVE",
+"390 685 CURVE SMOOTH",
+"565 685 OFFCURVE",
+"690 794 OFFCURVE",
+"690 1089 CURVE SMOOTH"
+);
+}
+);
+width = 1526;
+},
+{
+layerId = master02;
+paths = (
+{
+closed = 1;
+nodes = (
+"291 -25 LINE",
+"499 -25 LINE",
+"1279 1480 LINE",
+"1073 1480 LINE"
+);
+},
+{
+closed = 1;
+nodes = (
+"511 892 OFFCURVE",
+"470 815 OFFCURVE",
+"394 815 CURVE SMOOTH",
+"315 815 OFFCURVE",
+"279 891 OFFCURVE",
+"279 1091 CURVE SMOOTH",
+"279 1275 OFFCURVE",
+"317 1350 OFFCURVE",
+"394 1350 CURVE SMOOTH",
+"475 1350 OFFCURVE",
+"511 1276 OFFCURVE",
+"511 1076 CURVE SMOOTH"
+);
+},
+{
+closed = 1;
+nodes = (
+"721 1362 OFFCURVE",
+"584 1480 OFFCURVE",
+"399 1480 CURVE SMOOTH",
+"215 1480 OFFCURVE",
+"69 1360 OFFCURVE",
+"69 1078 CURVE SMOOTH",
+"69 796 OFFCURVE",
+"205 685 OFFCURVE",
+"390 685 CURVE SMOOTH",
+"575 685 OFFCURVE",
+"721 794 OFFCURVE",
+"721 1089 CURVE SMOOTH"
+);
+},
+{
+closed = 1;
+nodes = (
+"1286 182 OFFCURVE",
+"1245 105 OFFCURVE",
+"1169 105 CURVE SMOOTH",
+"1090 105 OFFCURVE",
+"1054 181 OFFCURVE",
+"1054 381 CURVE SMOOTH",
+"1054 565 OFFCURVE",
+"1092 640 OFFCURVE",
+"1169 640 CURVE SMOOTH",
+"1250 640 OFFCURVE",
+"1286 566 OFFCURVE",
+"1286 366 CURVE SMOOTH"
+);
+},
+{
+closed = 1;
+nodes = (
+"1496 652 OFFCURVE",
+"1359 770 OFFCURVE",
+"1174 770 CURVE SMOOTH",
+"990 770 OFFCURVE",
+"844 650 OFFCURVE",
+"844 368 CURVE SMOOTH",
+"844 86 OFFCURVE",
+"980 -25 OFFCURVE",
+"1165 -25 CURVE SMOOTH",
+"1350 -25 OFFCURVE",
+"1496 84 OFFCURVE",
+"1496 379 CURVE SMOOTH"
+);
+}
+);
+width = 1565;
+}
+);
+unicode = 0025;
+},
+{
+glyphname = Ampersand;
+layers = (
+{
+layerId = master01;
+paths = (
+{
+closed = 1;
+nodes = (
+"331 1485 OFFCURVE",
+"155 1412 OFFCURVE",
+"155 1190 CURVE SMOOTH",
+"155 1010 OFFCURVE",
+"362 815 OFFCURVE",
+"535 570 CURVE SMOOTH",
+"794 202 OFFCURVE",
+"973 -25 OFFCURVE",
+"1025 -25 CURVE SMOOTH",
+"1060 -25 OFFCURVE",
+"1138 38 OFFCURVE",
+"1175 70 CURVE",
+"1080 110 OFFCURVE",
+"914 297 OFFCURVE",
+"650 680 CURVE SMOOTH",
+"494 906 OFFCURVE",
+"315 1075 OFFCURVE",
+"315 1200 CURVE SMOOTH",
+"315 1291 OFFCURVE",
+"398 1350 OFFCURVE",
+"475 1350 CURVE SMOOTH",
+"555 1350 OFFCURVE",
+"630 1294 OFFCURVE",
+"630 1205 CURVE SMOOTH",
+"630 1116 OFFCURVE",
+"523 1001 OFFCURVE",
+"350 840 CURVE SMOOTH",
+"146 651 OFFCURVE",
+"55 527 OFFCURVE",
+"55 375 CURVE SMOOTH",
+"55 151 OFFCURVE",
+"217 -25 OFFCURVE",
+"440 -25 CURVE SMOOTH",
+"713 -25 OFFCURVE",
+"1002 274 OFFCURVE",
+"1080 435 CURVE",
+"975 570 LINE",
+"911 403 OFFCURVE",
+"630 150 OFFCURVE",
+"455 150 CURVE SMOOTH",
+"310 150 OFFCURVE",
+"230 267 OFFCURVE",
+"230 380 CURVE SMOOTH",
+"230 490 OFFCURVE",
+"296 587 OFFCURVE",
+"470 740 CURVE SMOOTH",
+"651 899 OFFCURVE",
+"790 1068 OFFCURVE",
+"790 1200 CURVE SMOOTH",
+"790 1382 OFFCURVE",
+"642 1485 OFFCURVE",
+"490 1485 CURVE SMOOTH"
+);
+}
+);
+width = 1222;
+},
+{
+layerId = master02;
+paths = (
+{
+closed = 1;
+nodes = (
+"996 433 OFFCURVE",
+"715 190 OFFCURVE",
+"540 190 CURVE SMOOTH",
+"425 190 OFFCURVE",
+"335 257 OFFCURVE",
+"335 370 CURVE SMOOTH",
+"335 480 OFFCURVE",
+"411 547 OFFCURVE",
+"585 700 CURVE SMOOTH",
+"766 859 OFFCURVE",
+"925 1048 OFFCURVE",
+"925 1190 CURVE SMOOTH",
+"925 1372 OFFCURVE",
+"777 1485 OFFCURVE",
+"575 1485 CURVE SMOOTH",
+"366 1485 OFFCURVE",
+"190 1372 OFFCURVE",
+"190 1160 CURVE SMOOTH",
+"190 1000 OFFCURVE",
+"407 785 OFFCURVE",
+"590 540 CURVE SMOOTH",
+"859 179 OFFCURVE",
+"1038 -25 OFFCURVE",
+"1090 -25 CURVE SMOOTH",
+"1125 -25 OFFCURVE",
+"1253 58 OFFCURVE",
+"1290 90 CURVE",
+"1195 130 OFFCURVE",
+"1060 305 OFFCURVE",
+"785 680 CURVE SMOOTH",
+"619 906 OFFCURVE",
+"420 1085 OFFCURVE",
+"420 1170 CURVE SMOOTH",
+"420 1241 OFFCURVE",
+"483 1310 OFFCURVE",
+"560 1310 CURVE SMOOTH",
+"640 1310 OFFCURVE",
+"695 1254 OFFCURVE",
+"695 1175 CURVE SMOOTH",
+"695 1106 OFFCURVE",
+"628 1001 OFFCURVE",
+"455 840 CURVE SMOOTH",
+"251 651 OFFCURVE",
+"90 527 OFFCURVE",
+"90 344 CURVE SMOOTH",
+"90 121 OFFCURVE",
+"242 -25 OFFCURVE",
+"525 -25 CURVE SMOOTH",
+"808 -25 OFFCURVE",
+"1117 264 OFFCURVE",
+"1195 425 CURVE",
+"1060 600 LINE"
+);
+}
+);
+width = 1355;
+}
+);
+unicode = 0026;
+},
+{
+glyphname = Apos;
+layers = (
+{
+layerId = master01;
+paths = (
+{
+closed = 1;
+nodes = (
+"370 1186 OFFCURVE",
+"376 1339 OFFCURVE",
+"405 1585 CURVE",
+"200 1585 LINE",
+"231 1339 OFFCURVE",
+"236 1186 OFFCURVE",
+"240 1045 CURVE",
+"365 1045 LINE"
+);
+}
+);
+width = 605;
+},
+{
+layerId = master02;
+paths = (
+{
+closed = 1;
+nodes = (
+"405 1186 OFFCURVE",
+"406 1339 OFFCURVE",
+"435 1585 CURVE",
+"190 1585 LINE",
+"221 1339 OFFCURVE",
+"221 1186 OFFCURVE",
+"225 1045 CURVE",
+"400 1045 LINE"
+);
+}
+);
+width = 625;
+}
+);
+unicode = 0027;
+},
+{
+glyphname = LftParen;
+layers = (
+{
+layerId = master01;
+paths = (
+{
+closed = 1;
+nodes = (
+"115 218 OFFCURVE",
+"260 -125 OFFCURVE",
+"535 -410 CURVE",
+"630 -265 LINE",
+"395 -8 OFFCURVE",
+"305 278 OFFCURVE",
+"305 625 CURVE SMOOTH",
+"305 982 OFFCURVE",
+"395 1280 OFFCURVE",
+"630 1485 CURVE",
+"555 1640 LINE",
+"290 1444 OFFCURVE",
+"115 1062 OFFCURVE",
+"115 625 CURVE SMOOTH"
+);
+}
+);
+width = 795;
+},
+{
+layerId = master02;
+paths = (
+{
+closed = 1;
+nodes = (
+"290 1444 OFFCURVE",
+"115 1062 OFFCURVE",
+"115 625 CURVE SMOOTH",
+"115 218 OFFCURVE",
+"260 -125 OFFCURVE",
+"535 -410 CURVE",
+"686 -240 LINE",
+"462 11 OFFCURVE",
+"376 335 OFFCURVE",
+"376 635 CURVE SMOOTH",
+"376 938 OFFCURVE",
+"466 1261 OFFCURVE",
+"676 1455 CURVE",
+"555 1640 LINE"
+);
+}
+);
+width = 860;
+}
+);
+unicode = 0028;
+},
+{
+glyphname = RtParen;
+layers = (
+{
+layerId = master01;
+paths = (
+{
+closed = 1;
+nodes = (
+"680 1062 OFFCURVE",
+"505 1444 OFFCURVE",
+"240 1640 CURVE",
+"165 1485 LINE",
+"390 1280 OFFCURVE",
+"490 962 OFFCURVE",
+"490 625 CURVE SMOOTH",
+"490 278 OFFCURVE",
+"390 -8 OFFCURVE",
+"165 -265 CURVE",
+"260 -410 LINE",
+"535 -125 OFFCURVE",
+"680 218 OFFCURVE",
+"680 625 CURVE SMOOTH"
+);
+}
+);
+width = 795;
+},
+{
+layerId = master02;
+paths = (
+{
+closed = 1;
+nodes = (
+"395 1261 OFFCURVE",
+"485 938 OFFCURVE",
+"485 635 CURVE SMOOTH",
+"485 335 OFFCURVE",
+"399 11 OFFCURVE",
+"175 -240 CURVE",
+"326 -410 LINE",
+"601 -125 OFFCURVE",
+"746 218 OFFCURVE",
+"746 625 CURVE SMOOTH",
+"746 1062 OFFCURVE",
+"571 1444 OFFCURVE",
+"306 1640 CURVE",
+"185 1455 LINE"
+);
+}
+);
+width = 860;
+}
+);
+unicode = 0029;
+},
+{
+glyphname = Asterisk;
+layers = (
+{
+layerId = master01;
+paths = (
+{
+closed = 1;
+nodes = (
+"415 1600 LINE",
+"434 1467 OFFCURVE",
+"447 1387 OFFCURVE",
+"450 1300 CURVE",
+"376 1344 OFFCURVE",
+"309 1387 OFFCURVE",
+"200 1465 CURVE",
+"125 1340 LINE",
+"250 1290 OFFCURVE",
+"327 1261 OFFCURVE",
+"405 1220 CURVE",
+"329 1177 OFFCURVE",
+"256 1140 OFFCURVE",
+"135 1085 CURVE",
+"205 960 LINE",
+"310 1042 OFFCURVE",
+"377 1094 OFFCURVE",
+"450 1140 CURVE",
+"448 1055 OFFCURVE",
+"442 973 OFFCURVE",
+"430 840 CURVE",
+"570 840 LINE",
+"550 973 OFFCURVE",
+"544 1052 OFFCURVE",
+"540 1140 CURVE",
+"614 1095 OFFCURVE",
+"681 1053 OFFCURVE",
+"790 975 CURVE",
+"865 1100 LINE",
+"739 1149 OFFCURVE",
+"663 1179 OFFCURVE",
+"585 1220 CURVE",
+"661 1261 OFFCURVE",
+"733 1299 OFFCURVE",
+"855 1355 CURVE",
+"785 1480 LINE",
+"680 1396 OFFCURVE",
+"614 1348 OFFCURVE",
+"540 1300 CURVE",
+"541 1387 OFFCURVE",
+"547 1467 OFFCURVE",
+"560 1600 CURVE"
+);
+}
+);
+width = 1028;
+},
+{
+layerId = master02;
+paths = (
+{
+closed = 1;
+nodes = (
+"747 1426 OFFCURVE",
+"679 1367 OFFCURVE",
+"594 1308 CURVE",
+"599 1405 OFFCURVE",
+"609 1486 OFFCURVE",
+"624 1600 CURVE",
+"425 1600 LINE",
+"444 1497 OFFCURVE",
+"460 1412 OFFCURVE",
+"468 1308 CURVE",
+"383 1360 OFFCURVE",
+"312 1408 OFFCURVE",
+"228 1476 CURVE",
+"126 1306 LINE",
+"231 1271 OFFCURVE",
+"331 1234 OFFCURVE",
+"412 1196 CURVE",
+"328 1153 OFFCURVE",
+"243 1120 OFFCURVE",
+"136 1077 CURVE",
+"237 897 LINE",
+"316 968 OFFCURVE",
+"382 1026 OFFCURVE",
+"466 1087 CURVE",
+"459 983 OFFCURVE",
+"449 896 OFFCURVE",
+"431 793 CURVE",
+"632 793 LINE",
+"610 906 OFFCURVE",
+"602 987 OFFCURVE",
+"593 1084 CURVE",
+"682 1027 OFFCURVE",
+"747 981 OFFCURVE",
+"830 914 CURVE",
+"936 1089 LINE",
+"827 1127 OFFCURVE",
+"743 1155 OFFCURVE",
+"651 1196 CURVE",
+"738 1241 OFFCURVE",
+"820 1277 OFFCURVE",
+"924 1321 CURVE",
+"827 1493 LINE"
+);
+}
+);
+width = 1040;
+}
+);
+unicode = 002A;
+},
+{
+glyphname = PlusSgn;
+layers = (
+{
+layerId = master01;
+paths = (
+{
+closed = 1;
+nodes = (
+"525 285 LINE",
+"675 285 LINE",
+"675 1180 LINE",
+"525 1180 LINE"
+);
+},
+{
+closed = 1;
+nodes = (
+"1045 660 LINE",
+"1045 810 LINE",
+"155 810 LINE",
+"155 660 LINE"
+);
+}
+);
+width = 1200;
+},
+{
+layerId = master02;
+paths = (
+{
+closed = 1;
+nodes = (
+"495 285 LINE",
+"705 285 LINE",
+"705 1180 LINE",
+"495 1180 LINE"
+);
+},
+{
+closed = 1;
+nodes = (
+"1045 630 LINE",
+"1045 840 LINE",
+"155 840 LINE",
+"155 630 LINE"
+);
+}
+);
+width = 1200;
+}
+);
+unicode = 002B;
+},
+{
+glyphname = Comma;
+layers = (
+{
+layerId = master01;
+paths = (
+{
+closed = 1;
+nodes = (
+"325 50 LINE",
+"325 -51 OFFCURVE",
+"248 -172 OFFCURVE",
+"190 -230 CURVE",
+"290 -270 LINE",
+"407 -160 OFFCURVE",
+"465 -37 OFFCURVE",
+"465 85 CURVE SMOOTH",
+"465 186 OFFCURVE",
+"400 250 OFFCURVE",
+"320 250 CURVE SMOOTH",
+"263 250 OFFCURVE",
+"198 213 OFFCURVE",
+"185 150 CURVE",
+"185 50 LINE"
+);
+}
+);
+width = 650;
+},
+{
+layerId = master02;
+paths = (
+{
+closed = 1;
+nodes = (
+"345 50 LINE",
+"345 -34 OFFCURVE",
+"290 -153 OFFCURVE",
+"185 -265 CURVE",
+"330 -335 LINE",
+"454 -228 OFFCURVE",
+"560 -49 OFFCURVE",
+"560 130 CURVE SMOOTH",
+"560 254 OFFCURVE",
+"489 340 OFFCURVE",
+"375 340 CURVE SMOOTH",
+"262 340 OFFCURVE",
+"185 255 OFFCURVE",
+"185 180 CURVE SMOOTH",
+"185 50 LINE"
+);
+}
+);
+width = 665;
+}
+);
+unicode = 002C;
+},
+{
+glyphname = HyphenMinus;
+layers = (
+{
+anchors = (
+{
+name = U;
+position = "{430, 1100}";
+}
+);
+layerId = master01;
+paths = (
+{
+closed = 1;
+nodes = (
+"780 555 LINE",
+"780 705 LINE",
+"80 705 LINE",
+"80 555 LINE"
+);
+}
+);
+width = 860;
+},
+{
+anchors = (
+{
+name = U;
+position = "{450, 1100}";
+}
+);
+layerId = master02;
+paths = (
+{
+closed = 1;
+nodes = (
+"815 525 LINE",
+"815 735 LINE",
+"80 735 LINE",
+"80 525 LINE"
+);
+}
+);
+width = 895;
+}
+);
+unicode = 002D;
+},
+{
+glyphname = FullStop;
+layers = (
+{
+layerId = master01;
+paths = (
+{
+closed = 1;
+nodes = (
+"185 36 OFFCURVE",
+"246 -25 OFFCURVE",
+"320 -25 CURVE SMOOTH",
+"394 -25 OFFCURVE",
+"455 36 OFFCURVE",
+"455 110 CURVE SMOOTH",
+"455 184 OFFCURVE",
+"394 245 OFFCURVE",
+"320 245 CURVE SMOOTH",
+"246 245 OFFCURVE",
+"185 184 OFFCURVE",
+"185 110 CURVE SMOOTH"
+);
+}
+);
+width = 640;
+},
+{
+layerId = master02;
+paths = (
+{
+closed = 1;
+nodes = (
+"200 46 OFFCURVE",
+"274 -25 OFFCURVE",
+"375 -25 CURVE SMOOTH",
+"477 -25 OFFCURVE",
+"550 46 OFFCURVE",
+"550 150 CURVE SMOOTH",
+"550 252 OFFCURVE",
+"477 325 OFFCURVE",
+"375 325 CURVE SMOOTH",
+"274 325 OFFCURVE",
+"200 252 OFFCURVE",
+"200 150 CURVE SMOOTH"
+);
+}
+);
+width = 710;
+}
+);
+unicode = 002E;
+},
+{
+glyphname = Solidus;
+layers = (
+{
+layerId = master01;
+paths = (
+{
+closed = 1;
+nodes = (
+"10 -245 LINE",
+"160 -245 LINE",
+"990 1600 LINE",
+"840 1600 LINE"
+);
+}
+);
+width = 1000;
+},
+{
+layerId = master02;
+paths = (
+{
+closed = 1;
+nodes = (
+"10 -245 LINE",
+"240 -245 LINE",
+"1070 1600 LINE",
+"840 1600 LINE"
+);
+}
+);
+width = 1080;
+}
+);
+unicode = 002F;
+},
+{
+glyphname = DigitZero;
+layers = (
+{
+anchors = (
+{
+name = L;
+position = "{605, -100}";
+},
+{
+name = U;
+position = "{605, 1530}";
+}
+);
+layerId = master01;
+paths = (
+{
+closed = 1;
+nodes = (
+"910 308 OFFCURVE",
+"792 145 OFFCURVE",
+"600 145 CURVE SMOOTH",
+"402 145 OFFCURVE",
+"290 305 OFFCURVE",
+"290 745 CURVE SMOOTH",
+"290 1153 OFFCURVE",
+"407 1315 OFFCURVE",
+"600 1315 CURVE SMOOTH",
+"802 1315 OFFCURVE",
+"910 1156 OFFCURVE",
+"910 715 CURVE SMOOTH"
+);
+},
+{
+closed = 1;
+nodes = (
+"1110 1286 OFFCURVE",
+"900 1485 OFFCURVE",
+"610 1485 CURVE SMOOTH",
+"321 1485 OFFCURVE",
+"90 1283 OFFCURVE",
+"90 720 CURVE SMOOTH",
+"90 155 OFFCURVE",
+"301 -25 OFFCURVE",
+"590 -25 CURVE SMOOTH",
+"881 -25 OFFCURVE",
+"1110 151 OFFCURVE",
+"1110 740 CURVE SMOOTH"
+);
+}
+);
+width = 1200;
+},
+{
+anchors = (
+{
+name = L;
+position = "{605, -100}";
+},
+{
+name = U;
+position = "{605, 1530}";
+}
+);
+layerId = master02;
+paths = (
+{
+closed = 1;
+nodes = (
+"850 368 OFFCURVE",
+"762 205 OFFCURVE",
+"600 205 CURVE SMOOTH",
+"432 205 OFFCURVE",
+"350 375 OFFCURVE",
+"350 745 CURVE SMOOTH",
+"350 1093 OFFCURVE",
+"437 1255 OFFCURVE",
+"600 1255 CURVE SMOOTH",
+"772 1255 OFFCURVE",
+"850 1086 OFFCURVE",
+"850 715 CURVE SMOOTH"
+);
+},
+{
+closed = 1;
+nodes = (
+"1135 1286 OFFCURVE",
+"950 1485 OFFCURVE",
+"610 1485 CURVE SMOOTH",
+"291 1485 OFFCURVE",
+"65 1283 OFFCURVE",
+"65 720 CURVE SMOOTH",
+"65 165 OFFCURVE",
+"271 -25 OFFCURVE",
+"590 -25 CURVE SMOOTH",
+"911 -25 OFFCURVE",
+"1135 161 OFFCURVE",
+"1135 740 CURVE SMOOTH"
+);
+}
+);
+width = 1200;
+}
+);
+unicode = 0030;
+},
+{
+glyphname = DigitOne;
+layers = (
+{
+anchors = (
+{
+name = L;
+position = "{600, -100}";
+},
+{
+name = U;
+position = "{600, 1530}";
+}
+);
+layerId = master01;
+paths = (
+{
+closed = 1;
+nodes = (
+"220 170 LINE",
+"220 0 LINE",
+"1040 0 LINE",
+"1040 170 LINE",
+"725 170 LINE",
+"725 1480 LINE",
+"555 1480 LINE",
+"210 1268 LINE",
+"235 1088 LINE",
+"535 1260 LINE",
+"535 170 LINE"
+);
+}
+);
+width = 1200;
+},
+{
+anchors = (
+{
+name = L;
+position = "{600, -100}";
+},
+{
+name = U;
+position = "{600, 1530}";
+}
+);
+layerId = master02;
+paths = (
+{
+closed = 1;
+nodes = (
+"1075 235 LINE",
+"767 235 LINE",
+"767 1460 LINE",
+"492 1460 LINE",
+"177 1278 LINE",
+"212 1018 LINE",
+"492 1170 LINE",
+"492 235 LINE",
+"185 235 LINE",
+"185 0 LINE",
+"1075 0 LINE"
+);
+}
+);
+width = 1200;
+}
+);
+unicode = 0031;
+},
+{
+glyphname = DigitTwo;
+layers = (
+{
+anchors = (
+{
+name = L;
+position = "{600, -100}";
+},
+{
+name = U;
+position = "{560, 1530}";
+}
+);
+layerId = master01;
+paths = (
+{
+closed = 1;
+nodes = (
+"1000 166 OFFCURVE",
+"842 165 OFFCURVE",
+"645 165 CURVE SMOOTH",
+"390 165 LINE",
+"609 352 OFFCURVE",
+"1010 729 OFFCURVE",
+"1010 1065 CURVE SMOOTH",
+"1010 1323 OFFCURVE",
+"800 1485 OFFCURVE",
+"560 1485 CURVE SMOOTH",
+"391 1485 OFFCURVE",
+"206 1402 OFFCURVE",
+"125 1290 CURVE",
+"170 1120 LINE",
+"259 1228 OFFCURVE",
+"402 1305 OFFCURVE",
+"525 1305 CURVE SMOOTH",
+"668 1305 OFFCURVE",
+"810 1233 OFFCURVE",
+"810 1045 CURVE SMOOTH",
+"810 768 OFFCURVE",
+"391 365 OFFCURVE",
+"120 170 CURVE",
+"120 0 LINE",
+"1080 0 LINE",
+"1080 180 LINE"
+);
+}
+);
+width = 1200;
+},
+{
+anchors = (
+{
+name = L;
+position = "{600, -100}";
+},
+{
+name = U;
+position = "{560, 1530}";
+}
+);
+layerId = master02;
+paths = (
+{
+closed = 1;
+nodes = (
+"1010 246 OFFCURVE",
+"942 245 OFFCURVE",
+"745 245 CURVE SMOOTH",
+"480 245 LINE",
+"699 422 OFFCURVE",
+"1046 739 OFFCURVE",
+"1046 1065 CURVE SMOOTH",
+"1046 1323 OFFCURVE",
+"850 1485 OFFCURVE",
+"560 1485 CURVE SMOOTH",
+"391 1485 OFFCURVE",
+"196 1402 OFFCURVE",
+"105 1290 CURVE",
+"170 1050 LINE",
+"259 1158 OFFCURVE",
+"412 1235 OFFCURVE",
+"535 1235 CURVE SMOOTH",
+"688 1235 OFFCURVE",
+"758 1133 OFFCURVE",
+"758 1015 CURVE SMOOTH",
+"758 758 OFFCURVE",
+"381 415 OFFCURVE",
+"110 220 CURVE",
+"110 0 LINE",
+"1090 0 LINE",
+"1090 260 LINE"
+);
+}
+);
+width = 1200;
+}
+);
+unicode = 0032;
+},
+{
+glyphname = DigitThree;
+layers = (
+{
+anchors = (
+{
+name = L;
+position = "{600, -100}";
+},
+{
+name = U;
+position = "{600, 1530}";
+}
+);
+layerId = master01;
+paths = (
+{
+closed = 1;
+nodes = (
+"410 700 LINE",
+"480 700 LINE",
+"716 700 OFFCURVE",
+"895 588 OFFCURVE",
+"895 425 CURVE SMOOTH",
+"895 241 OFFCURVE",
+"718 150 OFFCURVE",
+"565 150 CURVE SMOOTH",
+"385 150 OFFCURVE",
+"244 232 OFFCURVE",
+"135 355 CURVE",
+"110 140 LINE",
+"215 42 OFFCURVE",
+"368 -25 OFFCURVE",
+"545 -25 CURVE SMOOTH",
+"834 -25 OFFCURVE",
+"1090 170 OFFCURVE",
+"1090 405 CURVE SMOOTH",
+"1090 672 OFFCURVE",
+"862 776 OFFCURVE",
+"720 800 CURVE",
+"862 829 OFFCURVE",
+"1040 957 OFFCURVE",
+"1040 1140 CURVE SMOOTH",
+"1040 1354 OFFCURVE",
+"828 1485 OFFCURVE",
+"580 1485 CURVE",
+"413 1485 OFFCURVE",
+"260 1416 OFFCURVE",
+"180 1325 CURVE",
+"215 1155 LINE",
+"328 1271 OFFCURVE",
+"436 1310 OFFCURVE",
+"590 1310 CURVE SMOOTH",
+"711 1310 OFFCURVE",
+"850 1250 OFFCURVE",
+"850 1115 CURVE SMOOTH",
+"850 991 OFFCURVE",
+"679 870 OFFCURVE",
+"480 870 CURVE",
+"410 870 LINE"
+);
+}
+);
+width = 1200;
+},
+{
+anchors = (
+{
+name = L;
+position = "{600, -100}";
+},
+{
+name = U;
+position = "{600, 1530}";
+}
+);
+layerId = master02;
+paths = (
+{
+closed = 1;
+nodes = (
+"390 645 LINE",
+"480 645 LINE SMOOTH",
+"706 645 OFFCURVE",
+"835 548 OFFCURVE",
+"835 425 CURVE SMOOTH",
+"835 291 OFFCURVE",
+"708 210 OFFCURVE",
+"565 210 CURVE SMOOTH",
+"405 210 OFFCURVE",
+"244 282 OFFCURVE",
+"135 405 CURVE",
+"100 130 LINE",
+"205 32 OFFCURVE",
+"368 -25 OFFCURVE",
+"545 -25 CURVE SMOOTH",
+"874 -25 OFFCURVE",
+"1120 170 OFFCURVE",
+"1120 405 CURVE SMOOTH",
+"1120 672 OFFCURVE",
+"892 756 OFFCURVE",
+"750 780 CURVE",
+"892 809 OFFCURVE",
+"1070 957 OFFCURVE",
+"1070 1140 CURVE SMOOTH",
+"1070 1354 OFFCURVE",
+"868 1485 OFFCURVE",
+"580 1485 CURVE SMOOTH",
+"413 1485 OFFCURVE",
+"240 1416 OFFCURVE",
+"160 1325 CURVE",
+"195 1095 LINE",
+"308 1211 OFFCURVE",
+"436 1250 OFFCURVE",
+"590 1250 CURVE SMOOTH",
+"689 1250 OFFCURVE",
+"791 1193 OFFCURVE",
+"791 1102 CURVE SMOOTH",
+"791 994 OFFCURVE",
+"662 885 OFFCURVE",
+"480 885 CURVE SMOOTH",
+"390 885 LINE"
+);
+}
+);
+width = 1200;
+}
+);
+unicode = 0033;
+},
+{
+glyphname = DigitFour;
+layers = (
+{
+anchors = (
+{
+name = L;
+position = "{607, -100}";
+},
+{
+name = U;
+position = "{607, 1530}";
+}
+);
+layerId = master01;
+paths = (
+{
+closed = 1;
+nodes = (
+"1125 550 LINE",
+"935 550 LINE",
+"935 1480 LINE",
+"745 1480 LINE",
+"90 550 LINE",
+"90 395 LINE",
+"745 395 LINE",
+"745 0 LINE",
+"935 0 LINE",
+"935 395 LINE",
+"1125 395 LINE"
+);
+},
+{
+closed = 1;
+nodes = (
+"745 550 LINE",
+"263 550 LINE",
+"745 1230 LINE"
+);
+}
+);
+width = 1200;
+},
+{
+anchors = (
+{
+name = L;
+position = "{607, -100}";
+},
+{
+name = U;
+position = "{607, 1530}";
+}
+);
+layerId = master02;
+paths = (
+{
+closed = 1;
+nodes = (
+"1155 570 LINE",
+"995 570 LINE",
+"995 1460 LINE",
+"695 1460 LINE",
+"60 570 LINE",
+"60 345 LINE",
+"730 345 LINE",
+"730 0 LINE",
+"995 0 LINE",
+"995 345 LINE",
+"1155 345 LINE"
+);
+},
+{
+closed = 1;
+nodes = (
+"730 570 LINE",
+"305 570 LINE",
+"730 1145 LINE"
+);
+}
+);
+width = 1200;
+}
+);
+unicode = 0034;
+},
+{
+glyphname = DigitFive;
+layers = (
+{
+anchors = (
+{
+name = L;
+position = "{600, -100}";
+},
+{
+name = U;
+position = "{600, 1530}";
+}
+);
+layerId = master01;
+paths = (
+{
+closed = 1;
+nodes = (
+"319 733 OFFCURVE",
+"404 750 OFFCURVE",
+"510 750 CURVE SMOOTH",
+"670 750 OFFCURVE",
+"870 672 OFFCURVE",
+"870 470 CURVE SMOOTH",
+"870 268 OFFCURVE",
+"730 155 OFFCURVE",
+"530 155 CURVE SMOOTH",
+"390 155 OFFCURVE",
+"294 182 OFFCURVE",
+"160 290 CURVE",
+"130 80 LINE",
+"255 2 OFFCURVE",
+"363 -25 OFFCURVE",
+"518 -25 CURVE SMOOTH",
+"831 -25 OFFCURVE",
+"1060 163 OFFCURVE",
+"1060 475 CURVE SMOOTH",
+"1060 742 OFFCURVE",
+"832 930 OFFCURVE",
+"545 930 CURVE SMOOTH",
+"472 930 OFFCURVE",
+"411 924 OFFCURVE",
+"380 920 CURVE",
+"380 1290 LINE",
+"765 1290 LINE",
+"849 1290 OFFCURVE",
+"925 1286 OFFCURVE",
+"1000 1270 CURVE",
+"1000 1460 LINE",
+"195 1460 LINE",
+"195 685 LINE"
+);
+}
+);
+width = 1200;
+},
+{
+anchors = (
+{
+name = L;
+position = "{600, -100}";
+},
+{
+name = U;
+position = "{600, 1530}";
+}
+);
+layerId = master02;
+paths = (
+{
+closed = 1;
+nodes = (
+"299 693 OFFCURVE",
+"404 710 OFFCURVE",
+"510 710 CURVE SMOOTH",
+"670 710 OFFCURVE",
+"810 632 OFFCURVE",
+"810 470 CURVE SMOOTH",
+"810 318 OFFCURVE",
+"690 215 OFFCURVE",
+"530 215 CURVE SMOOTH",
+"390 215 OFFCURVE",
+"274 252 OFFCURVE",
+"140 360 CURVE",
+"100 80 LINE",
+"225 2 OFFCURVE",
+"365 -25 OFFCURVE",
+"520 -25 CURVE SMOOTH",
+"833 -25 OFFCURVE",
+"1090 163 OFFCURVE",
+"1090 475 CURVE SMOOTH",
+"1090 752 OFFCURVE",
+"882 930 OFFCURVE",
+"605 930 CURVE SMOOTH",
+"543 930 OFFCURVE",
+"468 911 OFFCURVE",
+"435 895 CURVE",
+"435 1215 LINE",
+"765 1215 LINE SMOOTH",
+"849 1215 OFFCURVE",
+"955 1211 OFFCURVE",
+"1030 1195 CURVE",
+"1030 1460 LINE",
+"175 1460 LINE",
+"175 645 LINE"
+);
+}
+);
+width = 1200;
+}
+);
+unicode = 0035;
+},
+{
+glyphname = DigitSix;
+layers = (
+{
+anchors = (
+{
+name = L;
+position = "{600, -100}";
+},
+{
+name = U;
+position = "{600, 1530}";
+}
+);
+layerId = master01;
+paths = (
+{
+closed = 1;
+nodes = (
+"929 1465 OFFCURVE",
+"843 1485 OFFCURVE",
+"725 1485 CURVE SMOOTH",
+"250 1485 OFFCURVE",
+"110 1049 OFFCURVE",
+"110 680 CURVE SMOOTH",
+"110 242 OFFCURVE",
+"290 -25 OFFCURVE",
+"600 -25 CURVE SMOOTH",
+"907 -25 OFFCURVE",
+"1115 166 OFFCURVE",
+"1115 470 CURVE SMOOTH",
+"1115 719 OFFCURVE",
+"943 895 OFFCURVE",
+"665 895 CURVE SMOOTH",
+"474 895 OFFCURVE",
+"328 780 OFFCURVE",
+"215 625 CURVE",
+"280 550 LINE",
+"362 653 OFFCURVE",
+"490 720 OFFCURVE",
+"645 720 CURVE SMOOTH",
+"824 720 OFFCURVE",
+"920 611 OFFCURVE",
+"920 435 CURVE SMOOTH",
+"920 275 OFFCURVE",
+"806 150 OFFCURVE",
+"630 150 CURVE SMOOTH",
+"409 150 OFFCURVE",
+"305 393 OFFCURVE",
+"305 645 CURVE SMOOTH",
+"305 1132 OFFCURVE",
+"478 1310 OFFCURVE",
+"715 1310 CURVE SMOOTH",
+"811 1310 OFFCURVE",
+"903 1286 OFFCURVE",
+"989 1200 CURVE",
+"1033 1395 LINE"
+);
+}
+);
+width = 1200;
+},
+{
+anchors = (
+{
+name = L;
+position = "{610, -100}";
+},
+{
+name = U;
+position = "{610, 1530}";
+}
+);
+layerId = master02;
+paths = (
+{
+closed = 1;
+nodes = (
+"969 1465 OFFCURVE",
+"873 1485 OFFCURVE",
+"735 1485 CURVE SMOOTH",
+"260 1485 OFFCURVE",
+"90 1069 OFFCURVE",
+"90 680 CURVE SMOOTH",
+"90 223 OFFCURVE",
+"297 -25 OFFCURVE",
+"652 -25 CURVE SMOOTH",
+"955 -25 OFFCURVE",
+"1155 179 OFFCURVE",
+"1155 470 CURVE SMOOTH",
+"1155 729 OFFCURVE",
+"963 925 OFFCURVE",
+"675 925 CURVE SMOOTH",
+"484 925 OFFCURVE",
+"338 810 OFFCURVE",
+"225 655 CURVE",
+"290 540 LINE",
+"372 643 OFFCURVE",
+"500 710 OFFCURVE",
+"655 710 CURVE SMOOTH",
+"814 710 OFFCURVE",
+"900 601 OFFCURVE",
+"900 455 CURVE SMOOTH",
+"900 329 OFFCURVE",
+"803 210 OFFCURVE",
+"656 210 CURVE SMOOTH",
+"474 210 OFFCURVE",
+"355 386 OFFCURVE",
+"355 645 CURVE SMOOTH",
+"355 1132 OFFCURVE",
+"528 1250 OFFCURVE",
+"725 1250 CURVE SMOOTH",
+"821 1250 OFFCURVE",
+"923 1226 OFFCURVE",
+"1009 1140 CURVE",
+"1073 1395 LINE"
+);
+}
+);
+width = 1200;
+}
+);
+unicode = 0036;
+},
+{
+glyphname = DigitSeven;
+layers = (
+{
+anchors = (
+{
+name = L;
+position = "{600, -100}";
+},
+{
+name = U;
+position = "{600, 1530}";
+}
+);
+layerId = master01;
+paths = (
+{
+closed = 1;
+nodes = (
+"589 459 OFFCURVE",
+"794 895 OFFCURVE",
+"1090 1300 CURVE",
+"1090 1460 LINE",
+"100 1460 LINE",
+"100 1275 LINE",
+"176 1291 OFFCURVE",
+"292 1295 OFFCURVE",
+"480 1295 CURVE SMOOTH",
+"870 1295 LINE",
+"612 912 OFFCURVE",
+"439 566 OFFCURVE",
+"275 0 CURVE",
+"460 0 LINE"
+);
+}
+);
+width = 1200;
+},
+{
+anchors = (
+{
+name = L;
+position = "{600, -100}";
+},
+{
+name = U;
+position = "{600, 1530}";
+}
+);
+layerId = master02;
+paths = (
+{
+closed = 1;
+nodes = (
+"649 459 OFFCURVE",
+"834 855 OFFCURVE",
+"1130 1260 CURVE",
+"1130 1460 LINE",
+"100 1460 LINE",
+"100 1195 LINE",
+"176 1211 OFFCURVE",
+"292 1215 OFFCURVE",
+"480 1215 CURVE SMOOTH",
+"800 1215 LINE",
+"542 842 OFFCURVE",
+"409 566 OFFCURVE",
+"235 0 CURVE",
+"520 0 LINE"
+);
+}
+);
+width = 1200;
+}
+);
+unicode = 0037;
+},
+{
+glyphname = DigitEight;
+layers = (
+{
+anchors = (
+{
+name = L;
+position = "{600, -100}";
+},
+{
+name = U;
+position = "{600, 1530}";
+}
+);
+layerId = master01;
+paths = (
+{
+closed = 1;
+nodes = (
+"857 -25 OFFCURVE",
+"1110 134 OFFCURVE",
+"1110 405 CURVE SMOOTH",
+"1110 611 OFFCURVE",
+"965 739 OFFCURVE",
+"855 795 CURVE",
+"933 844 OFFCURVE",
+"1050 923 OFFCURVE",
+"1050 1105 CURVE SMOOTH",
+"1050 1350 OFFCURVE",
+"840 1485 OFFCURVE",
+"610 1485 CURVE SMOOTH",
+"381 1485 OFFCURVE",
+"150 1350 OFFCURVE",
+"150 1105 CURVE SMOOTH",
+"150 923 OFFCURVE",
+"272 838 OFFCURVE",
+"350 795 CURVE",
+"221 725 OFFCURVE",
+"90 611 OFFCURVE",
+"90 405 CURVE SMOOTH",
+"90 134 OFFCURVE",
+"344 -25 OFFCURVE",
+"600 -25 CURVE SMOOTH"
+);
+},
+{
+closed = 1;
+nodes = (
+"860 949 OFFCURVE",
+"743 865 OFFCURVE",
+"600 865 CURVE SMOOTH",
+"457 865 OFFCURVE",
+"340 949 OFFCURVE",
+"340 1105 CURVE SMOOTH",
+"340 1252 OFFCURVE",
+"457 1325 OFFCURVE",
+"600 1325 CURVE SMOOTH",
+"743 1325 OFFCURVE",
+"860 1252 OFFCURVE",
+"860 1105 CURVE SMOOTH"
+);
+},
+{
+closed = 1;
+nodes = (
+"910 250 OFFCURVE",
+"778 145 OFFCURVE",
+"600 145 CURVE SMOOTH",
+"420 145 OFFCURVE",
+"290 250 OFFCURVE",
+"290 425 CURVE SMOOTH",
+"290 592 OFFCURVE",
+"420 710 OFFCURVE",
+"600 710 CURVE SMOOTH",
+"778 710 OFFCURVE",
+"910 592 OFFCURVE",
+"910 425 CURVE SMOOTH"
+);
+}
+);
+width = 1200;
+},
+{
+anchors = (
+{
+name = L;
+position = "{600, -100}";
+},
+{
+name = U;
+position = "{600, 1530}";
+}
+);
+layerId = master02;
+paths = (
+{
+closed = 1;
+nodes = (
+"877 -25 OFFCURVE",
+"1130 144 OFFCURVE",
+"1130 415 CURVE SMOOTH",
+"1130 641 OFFCURVE",
+"985 739 OFFCURVE",
+"875 795 CURVE",
+"953 841 OFFCURVE",
+"1060 923 OFFCURVE",
+"1060 1105 CURVE SMOOTH",
+"1060 1350 OFFCURVE",
+"860 1485 OFFCURVE",
+"610 1485 CURVE SMOOTH",
+"361 1485 OFFCURVE",
+"140 1350 OFFCURVE",
+"140 1105 CURVE SMOOTH",
+"140 923 OFFCURVE",
+"252 838 OFFCURVE",
+"330 795 CURVE",
+"201 725 OFFCURVE",
+"70 631 OFFCURVE",
+"70 405 CURVE SMOOTH",
+"70 134 OFFCURVE",
+"324 -25 OFFCURVE",
+"600 -25 CURVE SMOOTH"
+);
+},
+{
+closed = 1;
+nodes = (
+"810 974 OFFCURVE",
+"733 895 OFFCURVE",
+"600 895 CURVE SMOOTH",
+"467 895 OFFCURVE",
+"390 974 OFFCURVE",
+"390 1100 CURVE SMOOTH",
+"390 1217 OFFCURVE",
+"477 1290 OFFCURVE",
+"600 1290 CURVE SMOOTH",
+"743 1290 OFFCURVE",
+"810 1207 OFFCURVE",
+"810 1100 CURVE SMOOTH"
+);
+},
+{
+closed = 1;
+nodes = (
+"865 300 OFFCURVE",
+"768 185 OFFCURVE",
+"600 185 CURVE SMOOTH",
+"440 185 OFFCURVE",
+"335 300 OFFCURVE",
+"335 435 CURVE SMOOTH",
+"335 582 OFFCURVE",
+"450 680 OFFCURVE",
+"600 680 CURVE SMOOTH",
+"748 680 OFFCURVE",
+"865 582 OFFCURVE",
+"865 435 CURVE SMOOTH"
+);
+}
+);
+width = 1200;
+}
+);
+unicode = 0038;
+},
+{
+glyphname = DigitNine;
+layers = (
+{
+anchors = (
+{
+name = L;
+position = "{600, -100}";
+},
+{
+name = U;
+position = "{600, 1530}";
+}
+);
+layerId = master01;
+paths = (
+{
+closed = 1;
+nodes = (
+"297 -5 OFFCURVE",
+"383 -25 OFFCURVE",
+"501 -25 CURVE SMOOTH",
+"976 -25 OFFCURVE",
+"1114 411 OFFCURVE",
+"1114 780 CURVE SMOOTH",
+"1114 1198 OFFCURVE",
+"926 1485 OFFCURVE",
+"616 1485 CURVE SMOOTH",
+"349 1485 OFFCURVE",
+"112 1306 OFFCURVE",
+"112 1002 CURVE SMOOTH",
+"112 773 OFFCURVE",
+"281 586 OFFCURVE",
+"559 586 CURVE SMOOTH",
+"750 586 OFFCURVE",
+"922 717 OFFCURVE",
+"1019 878 CURVE",
+"948 961 LINE",
+"874 847 OFFCURVE",
+"738 760 OFFCURVE",
+"583 760 CURVE SMOOTH",
+"424 760 OFFCURVE",
+"306 860 OFFCURVE",
+"306 1036 CURVE SMOOTH",
+"306 1196 OFFCURVE",
+"420 1310 OFFCURVE",
+"596 1310 CURVE SMOOTH",
+"837 1310 OFFCURVE",
+"919 1065 OFFCURVE",
+"919 813 CURVE SMOOTH",
+"919 326 OFFCURVE",
+"748 150 OFFCURVE",
+"511 150 CURVE SMOOTH",
+"415 150 OFFCURVE",
+"323 174 OFFCURVE",
+"237 260 CURVE",
+"193 65 LINE"
+);
+}
+);
+width = 1200;
+},
+{
+anchors = (
+{
+name = L;
+position = "{600, -100}";
+},
+{
+name = U;
+position = "{600, 1530}";
+}
+);
+layerId = master02;
+paths = (
+{
+closed = 1;
+nodes = (
+"248 5 OFFCURVE",
+"364 -25 OFFCURVE",
+"492 -25 CURVE SMOOTH",
+"967 -25 OFFCURVE",
+"1135 411 OFFCURVE",
+"1135 780 CURVE SMOOTH",
+"1135 1150 OFFCURVE",
+"977 1485 OFFCURVE",
+"589 1485 CURVE SMOOTH",
+"310 1485 OFFCURVE",
+"70 1300 OFFCURVE",
+"70 1002 CURVE SMOOTH",
+"70 763 OFFCURVE",
+"272 576 OFFCURVE",
+"550 576 CURVE SMOOTH",
+"741 576 OFFCURVE",
+"913 707 OFFCURVE",
+"1010 868 CURVE",
+"939 991 LINE",
+"865 877 OFFCURVE",
+"729 790 OFFCURVE",
+"574 790 CURVE SMOOTH",
+"425 790 OFFCURVE",
+"326 890 OFFCURVE",
+"326 1036 CURVE SMOOTH",
+"326 1153 OFFCURVE",
+"425 1250 OFFCURVE",
+"573 1250 CURVE SMOOTH",
+"773 1250 OFFCURVE",
+"870 1102 OFFCURVE",
+"870 813 CURVE SMOOTH",
+"870 326 OFFCURVE",
+"699 210 OFFCURVE",
+"502 210 CURVE SMOOTH",
+"406 210 OFFCURVE",
+"294 234 OFFCURVE",
+"208 320 CURVE",
+"154 65 LINE"
+);
+}
+);
+width = 1200;
+}
+);
+unicode = 0039;
+},
+{
+glyphname = Colon;
+layers = (
+{
+layerId = master01;
+paths = (
+{
+closed = 1;
+nodes = (
+"185 716 OFFCURVE",
+"246 655 OFFCURVE",
+"320 655 CURVE SMOOTH",
+"394 655 OFFCURVE",
+"455 716 OFFCURVE",
+"455 790 CURVE SMOOTH",
+"455 864 OFFCURVE",
+"394 925 OFFCURVE",
+"320 925 CURVE SMOOTH",
+"246 925 OFFCURVE",
+"185 864 OFFCURVE",
+"185 790 CURVE SMOOTH"
+);
+},
+{
+closed = 1;
+nodes = (
+"185 36 OFFCURVE",
+"246 -25 OFFCURVE",
+"320 -25 CURVE SMOOTH",
+"394 -25 OFFCURVE",
+"455 36 OFFCURVE",
+"455 110 CURVE SMOOTH",
+"455 184 OFFCURVE",
+"394 245 OFFCURVE",
+"320 245 CURVE SMOOTH",
+"246 245 OFFCURVE",
+"185 184 OFFCURVE",
+"185 110 CURVE SMOOTH"
+);
+}
+);
+width = 640;
+},
+{
+layerId = master02;
+paths = (
+{
+closed = 1;
+nodes = (
+"200 46 OFFCURVE",
+"274 -25 OFFCURVE",
+"375 -25 CURVE SMOOTH",
+"477 -25 OFFCURVE",
+"550 46 OFFCURVE",
+"550 150 CURVE SMOOTH",
+"550 252 OFFCURVE",
+"477 325 OFFCURVE",
+"375 325 CURVE SMOOTH",
+"274 325 OFFCURVE",
+"200 252 OFFCURVE",
+"200 150 CURVE SMOOTH"
+);
+},
+{
+closed = 1;
+nodes = (
+"200 646 OFFCURVE",
+"274 575 OFFCURVE",
+"375 575 CURVE SMOOTH",
+"477 575 OFFCURVE",
+"550 646 OFFCURVE",
+"550 750 CURVE SMOOTH",
+"550 852 OFFCURVE",
+"477 925 OFFCURVE",
+"375 925 CURVE SMOOTH",
+"274 925 OFFCURVE",
+"200 852 OFFCURVE",
+"200 750 CURVE SMOOTH"
+);
+}
+);
+width = 710;
+}
+);
+unicode = 003A;
+},
+{
+glyphname = Semicolon;
+layers = (
+{
+layerId = master01;
+paths = (
+{
+closed = 1;
+nodes = (
+"185 716 OFFCURVE",
+"246 655 OFFCURVE",
+"320 655 CURVE SMOOTH",
+"394 655 OFFCURVE",
+"455 716 OFFCURVE",
+"455 790 CURVE SMOOTH",
+"455 864 OFFCURVE",
+"394 925 OFFCURVE",
+"320 925 CURVE SMOOTH",
+"246 925 OFFCURVE",
+"185 864 OFFCURVE",
+"185 790 CURVE SMOOTH"
+);
+},
+{
+closed = 1;
+nodes = (
+"325 50 LINE",
+"325 -51 OFFCURVE",
+"248 -172 OFFCURVE",
+"190 -230 CURVE",
+"290 -270 LINE",
+"407 -160 OFFCURVE",
+"465 -37 OFFCURVE",
+"465 85 CURVE SMOOTH",
+"465 186 OFFCURVE",
+"400 250 OFFCURVE",
+"320 250 CURVE SMOOTH",
+"263 250 OFFCURVE",
+"198 213 OFFCURVE",
+"185 150 CURVE",
+"185 50 LINE"
+);
+}
+);
+width = 650;
+},
+{
+layerId = master02;
+paths = (
+{
+closed = 1;
+nodes = (
+"200 646 OFFCURVE",
+"274 575 OFFCURVE",
+"375 575 CURVE SMOOTH",
+"477 575 OFFCURVE",
+"550 646 OFFCURVE",
+"550 750 CURVE SMOOTH",
+"550 852 OFFCURVE",
+"477 925 OFFCURVE",
+"375 925 CURVE SMOOTH",
+"274 925 OFFCURVE",
+"200 852 OFFCURVE",
+"200 750 CURVE SMOOTH"
+);
+},
+{
+closed = 1;
+nodes = (
+"345 50 LINE",
+"345 -34 OFFCURVE",
+"290 -153 OFFCURVE",
+"185 -265 CURVE",
+"330 -335 LINE",
+"454 -228 OFFCURVE",
+"560 -49 OFFCURVE",
+"560 130 CURVE SMOOTH",
+"560 254 OFFCURVE",
+"489 340 OFFCURVE",
+"375 340 CURVE SMOOTH",
+"262 340 OFFCURVE",
+"185 255 OFFCURVE",
+"185 180 CURVE SMOOTH",
+"185 50 LINE"
+);
+}
+);
+width = 710;
+}
+);
+unicode = 003B;
+},
+{
+glyphname = LTSgn;
+layers = (
+{
+layerId = master01;
+paths = (
+{
+closed = 1;
+nodes = (
+"290 730 LINE",
+"1080 1035 LINE",
+"1080 1215 LINE",
+"100 815 LINE",
+"100 645 LINE",
+"1080 245 LINE",
+"1080 425 LINE"
+);
+}
+);
+width = 1200;
+},
+{
+layerId = master02;
+paths = (
+{
+closed = 1;
+nodes = (
+"390 730 LINE",
+"1070 985 LINE",
+"1070 1215 LINE",
+"110 825 LINE",
+"110 635 LINE",
+"1070 245 LINE",
+"1070 475 LINE"
+);
+}
+);
+width = 1200;
+}
+);
+unicode = 003C;
+},
+{
+glyphname = EqSgn;
+layers = (
+{
+layerId = master01;
+paths = (
+{
+closed = 1;
+nodes = (
+"1080 480 LINE",
+"1080 630 LINE",
+"120 630 LINE",
+"120 480 LINE"
+);
+},
+{
+closed = 1;
+nodes = (
+"1080 830 LINE",
+"1080 980 LINE",
+"120 980 LINE",
+"120 830 LINE"
+);
+}
+);
+width = 1200;
+},
+{
+layerId = master02;
+paths = (
+{
+closed = 1;
+nodes = (
+"1080 440 LINE",
+"1080 650 LINE",
+"120 650 LINE",
+"120 440 LINE"
+);
+},
+{
+closed = 1;
+nodes = (
+"1080 810 LINE",
+"1080 1020 LINE",
+"120 1020 LINE",
+"120 810 LINE"
+);
+}
+);
+width = 1200;
+}
+);
+unicode = 003D;
+},
+{
+glyphname = GTSgn;
+layers = (
+{
+layerId = master01;
+paths = (
+{
+closed = 1;
+nodes = (
+"910 730 LINE",
+"120 425 LINE",
+"120 245 LINE",
+"1100 645 LINE",
+"1100 815 LINE",
+"120 1215 LINE",
+"120 1035 LINE"
+);
+}
+);
+width = 1200;
+},
+{
+layerId = master02;
+paths = (
+{
+closed = 1;
+nodes = (
+"1090 635 LINE",
+"1090 825 LINE",
+"130 1215 LINE",
+"130 985 LINE",
+"810 730 LINE",
+"130 475 LINE",
+"130 245 LINE"
+);
+}
+);
+width = 1200;
+}
+);
+unicode = 003E;
+},
+{
+glyphname = QstnMrk;
+layers = (
+{
+layerId = master01;
+paths = (
+{
+closed = 1;
+nodes = (
+"335 1540 OFFCURVE",
+"206 1493 OFFCURVE",
+"140 1430 CURVE",
+"185 1251 LINE",
+"261 1330 OFFCURVE",
+"352 1365 OFFCURVE",
+"432 1365 CURVE SMOOTH",
+"579 1365 OFFCURVE",
+"625 1289 OFFCURVE",
+"625 1230 CURVE SMOOTH",
+"625 1159 OFFCURVE",
+"572 1092 OFFCURVE",
+"485 980 CURVE SMOOTH",
+"397 867 OFFCURVE",
+"355 730 OFFCURVE",
+"355 440 CURVE",
+"540 440 LINE",
+"540 721 OFFCURVE",
+"561 806 OFFCURVE",
+"665 927 CURVE SMOOTH",
+"753 1028 OFFCURVE",
+"830 1117 OFFCURVE",
+"830 1240 CURVE SMOOTH",
+"830 1422 OFFCURVE",
+"697 1540 OFFCURVE",
+"460 1540 CURVE SMOOTH"
+);
+},
+{
+closed = 1;
+nodes = (
+"315 36 OFFCURVE",
+"376 -25 OFFCURVE",
+"450 -25 CURVE SMOOTH",
+"524 -25 OFFCURVE",
+"585 36 OFFCURVE",
+"585 110 CURVE SMOOTH",
+"585 184 OFFCURVE",
+"524 245 OFFCURVE",
+"450 245 CURVE SMOOTH",
+"376 245 OFFCURVE",
+"315 184 OFFCURVE",
+"315 110 CURVE SMOOTH"
+);
+}
+);
+width = 1050;
+},
+{
+layerId = master02;
+paths = (
+{
+closed = 1;
+nodes = (
+"640 671 OFFCURVE",
+"668 805 OFFCURVE",
+"767 956 CURVE SMOOTH",
+"837 1063 OFFCURVE",
+"900 1117 OFFCURVE",
+"900 1220 CURVE SMOOTH",
+"900 1402 OFFCURVE",
+"757 1540 OFFCURVE",
+"500 1540 CURVE SMOOTH",
+"355 1540 OFFCURVE",
+"206 1470 OFFCURVE",
+"140 1407 CURVE",
+"185 1168 LINE",
+"261 1247 OFFCURVE",
+"372 1295 OFFCURVE",
+"472 1295 CURVE SMOOTH",
+"569 1295 OFFCURVE",
+"615 1249 OFFCURVE",
+"615 1190 CURVE SMOOTH",
+"615 1139 OFFCURVE",
+"565 1096 OFFCURVE",
+"495 980 CURVE SMOOTH",
+"434 879 OFFCURVE",
+"375 710 OFFCURVE",
+"375 500 CURVE",
+"640 500 LINE"
+);
+},
+{
+closed = 1;
+nodes = (
+"335 46 OFFCURVE",
+"409 -25 OFFCURVE",
+"510 -25 CURVE SMOOTH",
+"612 -25 OFFCURVE",
+"685 46 OFFCURVE",
+"685 150 CURVE SMOOTH",
+"685 252 OFFCURVE",
+"612 325 OFFCURVE",
+"510 325 CURVE SMOOTH",
+"409 325 OFFCURVE",
+"335 252 OFFCURVE",
+"335 150 CURVE SMOOTH"
+);
+}
+);
+width = 1090;
+}
+);
+unicode = 003F;
+},
+{
+glyphname = AtSgn;
+layers = (
+{
+layerId = master01;
+paths = (
+{
+closed = 1;
+nodes = (
+"1605 1127 OFFCURVE",
+"1307 1405 OFFCURVE",
+"880 1405 CURVE SMOOTH",
+"465 1405 OFFCURVE",
+"95 1126 OFFCURVE",
+"95 575 CURVE SMOOTH",
+"95 48 OFFCURVE",
+"464 -235 OFFCURVE",
+"855 -235 CURVE SMOOTH",
+"990 -235 OFFCURVE",
+"1150 -188 OFFCURVE",
+"1250 -118 CURVE",
+"1145 -10 LINE",
+"1058 -70 OFFCURVE",
+"963 -95 OFFCURVE",
+"870 -95 CURVE SMOOTH",
+"523 -95 OFFCURVE",
+"240 174 OFFCURVE",
+"240 605 CURVE SMOOTH",
+"240 1003 OFFCURVE",
+"542 1270 OFFCURVE",
+"870 1270 CURVE SMOOTH",
+"1263 1270 OFFCURVE",
+"1465 1002 OFFCURVE",
+"1465 670 CURVE SMOOTH",
+"1465 432 OFFCURVE",
+"1348 315 OFFCURVE",
+"1280 315 CURVE SMOOTH",
+"1221 315 OFFCURVE",
+"1175 410 OFFCURVE",
+"1175 630 CURVE SMOOTH",
+"1175 980 LINE",
+"1088 1015 OFFCURVE",
+"961 1040 OFFCURVE",
+"880 1040 CURVE SMOOTH",
+"716 1040 OFFCURVE",
+"613 971 OFFCURVE",
+"530 835 CURVE SMOOTH",
+"483 756 OFFCURVE",
+"455 653 OFFCURVE",
+"455 530 CURVE SMOOTH",
+"455 294 OFFCURVE",
+"601 183 OFFCURVE",
+"735 183 CURVE SMOOTH",
+"852 183 OFFCURVE",
+"988 366 OFFCURVE",
+"1040 490 CURVE",
+"1050 322 OFFCURVE",
+"1128 180 OFFCURVE",
+"1250 180 CURVE SMOOTH",
+"1425 180 OFFCURVE",
+"1605 368 OFFCURVE",
+"1605 700 CURVE SMOOTH"
+);
+},
+{
+closed = 1;
+nodes = (
+"924 905 OFFCURVE",
+"992 886 OFFCURVE",
+"1025 870 CURVE",
+"1025 720 LINE",
+"993 582 OFFCURVE",
+"838 320 OFFCURVE",
+"748 320 CURVE SMOOTH",
+"676 320 OFFCURVE",
+"605 398 OFFCURVE",
+"605 575 CURVE SMOOTH",
+"605 652 OFFCURVE",
+"621 731 OFFCURVE",
+"650 780 CURVE SMOOTH",
+"706 876 OFFCURVE",
+"782 905 OFFCURVE",
+"850 905 CURVE SMOOTH"
+);
+}
+);
+width = 1702;
+},
+{
+layerId = master02;
+paths = (
+{
+closed = 1;
+nodes = (
+"1077 -34 OFFCURVE",
+"988 -60 OFFCURVE",
+"895 -60 CURVE SMOOTH",
+"558 -60 OFFCURVE",
+"290 204 OFFCURVE",
+"290 605 CURVE SMOOTH",
+"290 973 OFFCURVE",
+"557 1240 OFFCURVE",
+"895 1240 CURVE SMOOTH",
+"1278 1240 OFFCURVE",
+"1460 992 OFFCURVE",
+"1460 670 CURVE SMOOTH",
+"1460 452 OFFCURVE",
+"1363 335 OFFCURVE",
+"1305 335 CURVE SMOOTH",
+"1256 335 OFFCURVE",
+"1220 430 OFFCURVE",
+"1220 650 CURVE SMOOTH",
+"1220 980 LINE",
+"1133 1015 OFFCURVE",
+"986 1040 OFFCURVE",
+"905 1040 CURVE SMOOTH",
+"741 1040 OFFCURVE",
+"618 961 OFFCURVE",
+"535 825 CURVE SMOOTH",
+"488 746 OFFCURVE",
+"460 653 OFFCURVE",
+"460 530 CURVE SMOOTH",
+"460 304 OFFCURVE",
+"606 163 OFFCURVE",
+"740 163 CURVE SMOOTH",
+"867 163 OFFCURVE",
+"1013 331 OFFCURVE",
+"1065 455 CURVE",
+"1075 287 OFFCURVE",
+"1153 160 OFFCURVE",
+"1275 160 CURVE SMOOTH",
+"1450 160 OFFCURVE",
+"1650 358 OFFCURVE",
+"1650 700 CURVE SMOOTH",
+"1650 1137 OFFCURVE",
+"1342 1425 OFFCURVE",
+"905 1425 CURVE SMOOTH",
+"480 1425 OFFCURVE",
+"90 1136 OFFCURVE",
+"90 575 CURVE SMOOTH",
+"90 38 OFFCURVE",
+"479 -245 OFFCURVE",
+"880 -245 CURVE SMOOTH",
+"1015 -245 OFFCURVE",
+"1175 -198 OFFCURVE",
+"1275 -128 CURVE",
+"1140 10 LINE"
+);
+},
+{
+closed = 1;
+nodes = (
+"988 572 OFFCURVE",
+"863 350 OFFCURVE",
+"773 350 CURVE SMOOTH",
+"701 350 OFFCURVE",
+"660 428 OFFCURVE",
+"660 575 CURVE SMOOTH",
+"660 652 OFFCURVE",
+"682 737 OFFCURVE",
+"720 786 CURVE SMOOTH",
+"756 831 OFFCURVE",
+"807 855 OFFCURVE",
+"875 855 CURVE SMOOTH",
+"949 855 OFFCURVE",
+"987 836 OFFCURVE",
+"1020 820 CURVE",
+"1020 710 LINE"
+);
+}
+);
+width = 1742;
+}
+);
+unicode = 0040;
+},
+{
+glyphname = LtnCapA;
+layers = (
+{
+anchors = (
+{
+name = H;
+position = "{707, 0}";
+},
+{
+name = L;
+position = "{687, -100}";
+},
+{
+name = O;
+position = "{1450, 0}";
+},
+{
+name = U;
+position = "{687, 1530}";
+}
+);
+layerId = master01;
+paths = (
+{
+closed = 1;
+nodes = (
+"379 385 LINE",
+"994 385 LINE",
+"1130 0 LINE",
+"1335 0 LINE",
+"1300 80 OFFCURVE",
+"1262 169 OFFCURVE",
+"1195 355 CURVE SMOOTH",
+"795 1460 LINE",
+"580 1460 LINE",
+"180 355 LINE SMOOTH",
+"112 168 OFFCURVE",
+"76 81 OFFCURVE",
+"40 0 CURVE",
+"245 0 LINE"
+);
+},
+{
+closed = 1;
+nodes = (
+"433 540 LINE",
+"685 1265 LINE",
+"940 540 LINE"
+);
+}
+);
+width = 1395;
+},
+{
+anchors = (
+{
+name = H;
+position = "{1275, 0}";
+},
+{
+name = L;
+position = "{732, -100}";
+},
+{
+name = O;
+position = "{1495, 0}";
+},
+{
+name = U;
+position = "{732, 1530}";
+}
+);
+layerId = master02;
+paths = (
+{
+closed = 1;
+nodes = (
+"1408 0 LINE",
+"1373 80 OFFCURVE",
+"1341 168 OFFCURVE",
+"1278 355 CURVE SMOOTH",
+"908 1460 LINE",
+"552 1460 LINE",
+"182 355 LINE SMOOTH",
+"119 166 OFFCURVE",
+"88 81 OFFCURVE",
+"52 0 CURVE",
+"350 0 LINE",
+"460 355 LINE",
+"1004 355 LINE",
+"1115 0 LINE"
+);
+},
+{
+closed = 1;
+nodes = (
+"936 570 LINE",
+"526 570 LINE",
+"730 1228 LINE"
+);
+}
+);
+width = 1485;
+}
+);
+unicode = 0041;
+},
+{
+glyphname = LtnCapA.alt;
+layers = (
+{
+anchors = (
+{
+name = H;
+position = "{668, 1460}";
+},
+{
+name = L;
+position = "{688, 1560}";
+},
+{
+name = O;
+position = "{-75, 1460}";
+},
+{
+name = U;
+position = "{688, -70}";
+}
+);
+layerId = master01;
+paths = (
+{
+closed = 1;
+nodes = (
+"996 1075 LINE",
+"381 1075 LINE",
+"245 1460 LINE",
+"40 1460 LINE",
+"75 1380 OFFCURVE",
+"113 1291 OFFCURVE",
+"180 1105 CURVE SMOOTH",
+"580 0 LINE",
+"795 0 LINE",
+"1195 1105 LINE SMOOTH",
+"1263 1292 OFFCURVE",
+"1299 1379 OFFCURVE",
+"1335 1460 CURVE",
+"1130 1460 LINE"
+);
+},
+{
+closed = 1;
+nodes = (
+"942 920 LINE",
+"690 195 LINE",
+"435 920 LINE"
+);
+}
+);
+width = 1395;
+},
+{
+anchors = (
+{
+name = H;
+position = "{1275, 0}";
+},
+{
+name = L;
+position = "{732, -100}";
+},
+{
+name = O;
+position = "{1495, 0}";
+},
+{
+name = U;
+position = "{732, 1530}";
+}
+);
+layerId = master02;
+paths = (
+{
+closed = 1;
+nodes = (
+"1408 0 LINE",
+"1373 80 OFFCURVE",
+"1341 168 OFFCURVE",
+"1278 355 CURVE SMOOTH",
+"908 1460 LINE",
+"552 1460 LINE",
+"182 355 LINE SMOOTH",
+"119 166 OFFCURVE",
+"88 81 OFFCURVE",
+"52 0 CURVE",
+"350 0 LINE",
+"460 355 LINE",
+"1004 355 LINE",
+"1115 0 LINE"
+);
+},
+{
+closed = 1;
+nodes = (
+"936 570 LINE",
+"526 570 LINE",
+"730 1228 LINE"
+);
+}
+);
+width = 1485;
+}
+);
+},
+{
+glyphname = LtnCapB;
+layers = (
+{
+anchors = (
+{
+name = L;
+position = "{615, -100}";
+},
+{
+name = U;
+position = "{615, 1530}";
+}
+);
+layerId = master01;
+paths = (
+{
+closed = 1;
+nodes = (
+"407 1312 OFFCURVE",
+"512 1315 OFFCURVE",
+"590 1315 CURVE SMOOTH",
+"791 1315 OFFCURVE",
+"870 1239 OFFCURVE",
+"870 1090 CURVE SMOOTH",
+"870 951 OFFCURVE",
+"774 855 OFFCURVE",
+"560 855 CURVE SMOOTH",
+"365 855 LINE",
+"365 1310 LINE"
+);
+},
+{
+closed = 1;
+nodes = (
+"175 257 OFFCURVE",
+"175 80 OFFCURVE",
+"160 0 CURVE",
+"213 -5 OFFCURVE",
+"402 -10 OFFCURVE",
+"605 -10 CURVE SMOOTH",
+"988 -10 OFFCURVE",
+"1140 177 OFFCURVE",
+"1140 420 CURVE SMOOTH",
+"1140 669 OFFCURVE",
+"974 759 OFFCURVE",
+"820 800 CURVE",
+"956 852 OFFCURVE",
+"1065 952 OFFCURVE",
+"1065 1120 CURVE SMOOTH",
+"1065 1381 OFFCURVE",
+"897 1470 OFFCURVE",
+"600 1470 CURVE SMOOTH",
+"431 1470 OFFCURVE",
+"248 1466 OFFCURVE",
+"160 1460 CURVE",
+"175 1380 OFFCURVE",
+"175 1196 OFFCURVE",
+"175 1000 CURVE SMOOTH",
+"175 455 LINE"
+);
+},
+{
+closed = 1;
+nodes = (
+"600 700 LINE SMOOTH",
+"833 700 OFFCURVE",
+"945 604 OFFCURVE",
+"945 420 CURVE SMOOTH",
+"945 212 OFFCURVE",
+"781 150 OFFCURVE",
+"610 150 CURVE SMOOTH",
+"498 150 OFFCURVE",
+"402 153 OFFCURVE",
+"365 155 CURVE",
+"365 700 LINE"
+);
+}
+);
+width = 1285;
+},
+{
+anchors = (
+{
+name = L;
+position = "{670, -100}";
+},
+{
+name = U;
+position = "{670, 1530}";
+}
+);
+layerId = master02;
+paths = (
+{
+closed = 1;
+nodes = (
+"487 1250 OFFCURVE",
+"562 1253 OFFCURVE",
+"631 1253 CURVE SMOOTH",
+"818 1253 OFFCURVE",
+"897 1196 OFFCURVE",
+"897 1077 CURVE SMOOTH",
+"897 951 OFFCURVE",
+"794 875 OFFCURVE",
+"605 875 CURVE SMOOTH",
+"450 875 LINE",
+"450 1248 LINE"
+);
+},
+{
+closed = 1;
+nodes = (
+"1245 672 OFFCURVE",
+"1084 760 OFFCURVE",
+"935 800 CURVE",
+"1065 850 OFFCURVE",
+"1170 947 OFFCURVE",
+"1170 1110 CURVE SMOOTH",
+"1170 1378 OFFCURVE",
+"937 1470 OFFCURVE",
+"615 1470 CURVE SMOOTH",
+"422 1470 OFFCURVE",
+"248 1466 OFFCURVE",
+"150 1460 CURVE",
+"165 1380 OFFCURVE",
+"165 1196 OFFCURVE",
+"165 1000 CURVE SMOOTH",
+"165 455 LINE SMOOTH",
+"165 257 OFFCURVE",
+"165 80 OFFCURVE",
+"150 0 CURVE",
+"150 0 OFFCURVE",
+"401 -10 OFFCURVE",
+"631 -10 CURVE SMOOTH",
+"1055 -10 OFFCURVE",
+"1245 181 OFFCURVE",
+"1245 430 CURVE SMOOTH"
+);
+},
+{
+closed = 1;
+nodes = (
+"643 658 LINE SMOOTH",
+"853 658 OFFCURVE",
+"972 587 OFFCURVE",
+"972 450 CURVE SMOOTH",
+"972 269 OFFCURVE",
+"826 215 OFFCURVE",
+"652 215 CURVE SMOOTH",
+"552 215 OFFCURVE",
+"483 218 OFFCURVE",
+"450 220 CURVE",
+"450 658 LINE"
+);
+}
+);
+width = 1385;
+}
+);
+unicode = 0042;
+},
+{
+glyphname = LtnCapC;
+layers = (
+{
+anchors = (
+{
+name = H;
+position = "{750, 0}";
+},
+{
+name = L;
+position = "{750, -100}";
+},
+{
+name = U;
+position = "{750, 1530}";
+}
+);
+layerId = master01;
+paths = (
+{
+closed = 1;
+nodes = (
+"1078 223 OFFCURVE",
+"912 150 OFFCURVE",
+"760 150 CURVE SMOOTH",
+"489 150 OFFCURVE",
+"290 376 OFFCURVE",
+"290 735 CURVE SMOOTH",
+"290 1119 OFFCURVE",
+"491 1315 OFFCURVE",
+"770 1315 CURVE SMOOTH",
+"891 1315 OFFCURVE",
+"1030 1278 OFFCURVE",
+"1155 1165 CURVE",
+"1215 1345 LINE",
+"1072 1452 OFFCURVE",
+"913 1485 OFFCURVE",
+"770 1485 CURVE SMOOTH",
+"418 1485 OFFCURVE",
+"95 1225 OFFCURVE",
+"95 710 CURVE SMOOTH",
+"95 260 OFFCURVE",
+"346 -25 OFFCURVE",
+"750 -25 CURVE SMOOTH",
+"902 -25 OFFCURVE",
+"1114 32 OFFCURVE",
+"1230 140 CURVE",
+"1190 335 LINE"
+);
+}
+);
+width = 1355;
+},
+{
+anchors = (
+{
+name = H;
+position = "{745, 0}";
+},
+{
+name = L;
+position = "{745, -100}";
+},
+{
+name = U;
+position = "{745, 1530}";
+}
+);
+layerId = master02;
+paths = (
+{
+closed = 1;
+nodes = (
+"1105 293 OFFCURVE",
+"940 220 OFFCURVE",
+"790 220 CURVE SMOOTH",
+"531 220 OFFCURVE",
+"375 413 OFFCURVE",
+"375 735 CURVE SMOOTH",
+"375 1074 OFFCURVE",
+"557 1245 OFFCURVE",
+"800 1245 CURVE SMOOTH",
+"931 1245 OFFCURVE",
+"1053 1205 OFFCURVE",
+"1180 1105 CURVE",
+"1250 1345 LINE",
+"1106 1449 OFFCURVE",
+"969 1485 OFFCURVE",
+"785 1485 CURVE SMOOTH",
+"413 1485 OFFCURVE",
+"90 1225 OFFCURVE",
+"90 710 CURVE SMOOTH",
+"90 260 OFFCURVE",
+"341 -25 OFFCURVE",
+"755 -25 CURVE SMOOTH",
+"926 -25 OFFCURVE",
+"1142 42 OFFCURVE",
+"1265 140 CURVE",
+"1215 405 LINE"
+);
+}
+);
+width = 1385;
+}
+);
+unicode = 0043;
+},
+{
+glyphname = LtnCapD;
+layers = (
+{
+anchors = (
+{
+name = L;
+position = "{715, -100}";
+},
+{
+name = U;
+position = "{715, 1530}";
+}
+);
+layerId = master01;
+paths = (
+{
+closed = 1;
+nodes = (
+"174 257 OFFCURVE",
+"175 80 OFFCURVE",
+"160 0 CURVE",
+"160 0 OFFCURVE",
+"467 -10 OFFCURVE",
+"595 -10 CURVE SMOOTH",
+"888 -10 OFFCURVE",
+"1315 145 OFFCURVE",
+"1315 740 CURVE SMOOTH",
+"1315 1394 OFFCURVE",
+"829 1470 OFFCURVE",
+"615 1470 CURVE SMOOTH",
+"480 1470 OFFCURVE",
+"245 1466 OFFCURVE",
+"160 1460 CURVE",
+"175 1380 OFFCURVE",
+"175 1196 OFFCURVE",
+"175 1000 CURVE SMOOTH",
+"175 455 LINE"
+);
+},
+{
+closed = 1;
+nodes = (
+"415 1307 OFFCURVE",
+"524 1310 OFFCURVE",
+"590 1310 CURVE SMOOTH",
+"878 1310 OFFCURVE",
+"1120 1167 OFFCURVE",
+"1120 720 CURVE SMOOTH",
+"1120 308 OFFCURVE",
+"853 155 OFFCURVE",
+"585 155 CURVE SMOOTH",
+"490 155 OFFCURVE",
+"412 161 OFFCURVE",
+"365 165 CURVE",
+"365 1305 LINE"
+);
+}
+);
+width = 1435;
+},
+{
+anchors = (
+{
+name = L;
+position = "{800, -100}";
+},
+{
+name = U;
+position = "{800, 1530}";
+}
+);
+layerId = master02;
+paths = (
+{
+closed = 1;
+nodes = (
+"164 257 OFFCURVE",
+"165 80 OFFCURVE",
+"150 0 CURVE",
+"150 0 OFFCURVE",
+"474 -10 OFFCURVE",
+"609 -10 CURVE SMOOTH",
+"919 -10 OFFCURVE",
+"1370 145 OFFCURVE",
+"1370 740 CURVE SMOOTH",
+"1370 1374 OFFCURVE",
+"906 1470 OFFCURVE",
+"630 1470 CURVE SMOOTH",
+"487 1470 OFFCURVE",
+"239 1466 OFFCURVE",
+"150 1460 CURVE",
+"165 1380 OFFCURVE",
+"165 1196 OFFCURVE",
+"165 1000 CURVE SMOOTH",
+"165 455 LINE"
+);
+},
+{
+closed = 1;
+nodes = (
+"492 1243 OFFCURVE",
+"582 1246 OFFCURVE",
+"637 1246 CURVE SMOOTH",
+"897 1246 OFFCURVE",
+"1078 1118 OFFCURVE",
+"1078 720 CURVE SMOOTH",
+"1078 357 OFFCURVE",
+"856 221 OFFCURVE",
+"633 221 CURVE SMOOTH",
+"554 221 OFFCURVE",
+"489 227 OFFCURVE",
+"450 231 CURVE",
+"450 1241 LINE"
+);
+}
+);
+width = 1485;
+}
+);
+unicode = 0044;
+},
+{
+glyphname = LtnCapE;
+layers = (
+{
+anchors = (
+{
+name = H;
+position = "{600, 0}";
+},
+{
+name = L;
+position = "{600, -100}";
+},
+{
+name = O;
+position = "{917, 0}";
+},
+{
+name = R;
+position = "{1160, 1200}";
+},
+{
+name = U;
+position = "{600, 1530}";
+}
+);
+layerId = master01;
+paths = (
+{
+closed = 1;
+nodes = (
+"365 1295 LINE",
+"1010 1295 LINE",
+"1010 1460 LINE",
+"160 1460 LINE",
+"175 1380 OFFCURVE",
+"175 1222 OFFCURVE",
+"175 1025 CURVE SMOOTH",
+"175 435 LINE SMOOTH",
+"175 238 OFFCURVE",
+"175 80 OFFCURVE",
+"160 0 CURVE",
+"1040 0 LINE",
+"1040 180 LINE",
+"960 166 OFFCURVE",
+"826 165 OFFCURVE",
+"629 165 CURVE SMOOTH",
+"365 165 LINE",
+"365 685 LINE",
+"935 685 LINE",
+"935 845 LINE",
+"365 845 LINE"
+);
+}
+);
+width = 1160;
+},
+{
+anchors = (
+{
+name = H;
+position = "{610, 0}";
+},
+{
+name = L;
+position = "{610, -100}";
+},
+{
+name = O;
+position = "{1004, 0}";
+},
+{
+name = R;
+position = "{1247, 1200}";
+},
+{
+name = U;
+position = "{610, 1530}";
+}
+);
+layerId = master02;
+paths = (
+{
+closed = 1;
+nodes = (
+"450 1230 LINE",
+"1072 1230 LINE",
+"1072 1460 LINE",
+"150 1460 LINE",
+"165 1380 OFFCURVE",
+"165 1222 OFFCURVE",
+"165 1025 CURVE SMOOTH",
+"165 435 LINE SMOOTH",
+"165 238 OFFCURVE",
+"165 80 OFFCURVE",
+"150 0 CURVE",
+"1102 0 LINE",
+"1102 245 LINE",
+"1024 231 OFFCURVE",
+"899 230 OFFCURVE",
+"708 230 CURVE SMOOTH",
+"450 230 LINE",
+"450 650 LINE",
+"997 650 LINE",
+"997 875 LINE",
+"450 875 LINE"
+);
+}
+);
+width = 1212;
+}
+);
+unicode = 0045;
+},
+{
+glyphname = LtnCapF;
+layers = (
+{
+anchors = (
+{
+name = L;
+position = "{595, -100}";
+},
+{
+name = U;
+position = "{595, 1530}";
+}
+);
+layerId = master01;
+paths = (
+{
+closed = 1;
+nodes = (
+"365 1295 LINE",
+"1030 1295 LINE",
+"1030 1460 LINE",
+"160 1460 LINE",
+"175 1380 OFFCURVE",
+"175 1217 OFFCURVE",
+"175 1020 CURVE SMOOTH",
+"175 435 LINE SMOOTH",
+"175 238 OFFCURVE",
+"175 80 OFFCURVE",
+"160 0 CURVE",
+"380 0 LINE",
+"365 78 OFFCURVE",
+"365 237 OFFCURVE",
+"365 435 CURVE SMOOTH",
+"365 675 LINE",
+"945 675 LINE",
+"945 835 LINE",
+"365 835 LINE"
+);
+}
+);
+width = 1150;
+},
+{
+anchors = (
+{
+name = L;
+position = "{630, -100}";
+},
+{
+name = U;
+position = "{630, 1530}";
+}
+);
+layerId = master02;
+paths = (
+{
+closed = 1;
+nodes = (
+"450 1230 LINE",
+"1090 1230 LINE",
+"1090 1460 LINE",
+"150 1460 LINE",
+"165 1380 OFFCURVE",
+"165 1217 OFFCURVE",
+"165 1020 CURVE SMOOTH",
+"165 435 LINE SMOOTH",
+"165 238 OFFCURVE",
+"165 80 OFFCURVE",
+"150 0 CURVE",
+"465 0 LINE",
+"450 73 OFFCURVE",
+"450 222 OFFCURVE",
+"450 408 CURVE SMOOTH",
+"450 635 LINE",
+"1005 635 LINE",
+"1005 860 LINE",
+"450 860 LINE"
+);
+}
+);
+width = 1200;
+}
+);
+unicode = 0046;
+},
+{
+glyphname = LtnCapG;
+layers = (
+{
+anchors = (
+{
+name = H;
+position = "{745, 0}";
+},
+{
+name = L;
+position = "{745, -100}";
+},
+{
+name = U;
+position = "{745, 1530}";
+}
+);
+layerId = master01;
+paths = (
+{
+closed = 1;
+nodes = (
+"735 745 LINE",
+"735 580 LINE",
+"1085 580 LINE",
+"1085 245 LINE",
+"963 171 OFFCURVE",
+"876 150 OFFCURVE",
+"757 150 CURVE SMOOTH",
+"471 150 OFFCURVE",
+"290 377 OFFCURVE",
+"290 745 CURVE SMOOTH",
+"290 1094 OFFCURVE",
+"480 1315 OFFCURVE",
+"785 1315 CURVE SMOOTH",
+"918 1315 OFFCURVE",
+"1046 1286 OFFCURVE",
+"1195 1165 CURVE",
+"1260 1345 LINE",
+"1085 1462 OFFCURVE",
+"947 1485 OFFCURVE",
+"785 1485 CURVE SMOOTH",
+"402 1485 OFFCURVE",
+"95 1199 OFFCURVE",
+"95 720 CURVE SMOOTH",
+"95 241 OFFCURVE",
+"367 -25 OFFCURVE",
+"745 -25 CURVE SMOOTH",
+"918 -25 OFFCURVE",
+"1070 11 OFFCURVE",
+"1275 155 CURVE",
+"1275 745 LINE"
+);
+}
+);
+width = 1420;
+},
+{
+anchors = (
+{
+name = H;
+position = "{807, 0}";
+},
+{
+name = L;
+position = "{807, -100}";
+},
+{
+name = U;
+position = "{807, 1530}";
+}
+);
+layerId = master02;
+paths = (
+{
+closed = 1;
+nodes = (
+"767 785 LINE",
+"767 560 LINE",
+"1082 560 LINE",
+"1082 294 LINE",
+"966 236 OFFCURVE",
+"883 220 OFFCURVE",
+"769 220 CURVE SMOOTH",
+"532 220 OFFCURVE",
+"375 420 OFFCURVE",
+"375 745 CURVE SMOOTH",
+"375 1048 OFFCURVE",
+"545 1245 OFFCURVE",
+"810 1245 CURVE SMOOTH",
+"953 1245 OFFCURVE",
+"1097 1205 OFFCURVE",
+"1236 1107 CURVE",
+"1322 1345 LINE",
+"1137 1462 OFFCURVE",
+"989 1485 OFFCURVE",
+"818 1485 CURVE SMOOTH",
+"403 1485 OFFCURVE",
+"90 1199 OFFCURVE",
+"90 720 CURVE SMOOTH",
+"90 241 OFFCURVE",
+"377 -25 OFFCURVE",
+"777 -25 CURVE SMOOTH",
+"960 -25 OFFCURVE",
+"1120 11 OFFCURVE",
+"1337 155 CURVE",
+"1337 785 LINE"
+);
+}
+);
+width = 1472;
+}
+);
+unicode = 0047;
+},
+{
+glyphname = LtnCapH;
+layers = (
+{
+anchors = (
+{
+name = H;
+position = "{285, 0}";
+},
+{
+name = L;
+position = "{725, -100}";
+},
+{
+name = U;
+position = "{725, 1530}";
+}
+);
+layerId = master01;
+paths = (
+{
+closed = 1;
+nodes = (
+"1275 80 OFFCURVE",
+"1275 238 OFFCURVE",
+"1275 435 CURVE SMOOTH",
+"1275 1025 LINE SMOOTH",
+"1275 1222 OFFCURVE",
+"1275 1380 OFFCURVE",
+"1290 1460 CURVE",
+"1085 1460 LINE",
+"1085 835 LINE",
+"365 835 LINE",
+"365 1460 LINE",
+"160 1460 LINE",
+"175 1380 OFFCURVE",
+"175 1222 OFFCURVE",
+"175 1025 CURVE SMOOTH",
+"175 435 LINE SMOOTH",
+"175 238 OFFCURVE",
+"175 80 OFFCURVE",
+"160 0 CURVE",
+"365 0 LINE",
+"365 675 LINE",
+"1085 675 LINE",
+"1085 0 LINE",
+"1290 0 LINE"
+);
+}
+);
+width = 1475;
+},
+{
+anchors = (
+{
+name = H;
+position = "{305, 0}";
+},
+{
+name = L;
+position = "{745, -100}";
+},
+{
+name = U;
+position = "{745, 1530}";
+}
+);
+layerId = master02;
+paths = (
+{
+closed = 1;
+nodes = (
+"1040 860 LINE",
+"450 860 LINE",
+"450 1460 LINE",
+"150 1460 LINE",
+"165 1380 OFFCURVE",
+"165 1227 OFFCURVE",
+"165 1030 CURVE SMOOTH",
+"165 430 LINE SMOOTH",
+"165 233 OFFCURVE",
+"165 80 OFFCURVE",
+"150 0 CURVE",
+"150 0 OFFCURVE",
+"450 0 OFFCURVE",
+"450 0 CURVE",
+"450 635 LINE",
+"1040 635 LINE",
+"1040 0 LINE",
+"1040 0 OFFCURVE",
+"1340 0 OFFCURVE",
+"1340 0 CURVE",
+"1325 80 OFFCURVE",
+"1325 233 OFFCURVE",
+"1325 430 CURVE SMOOTH",
+"1325 1030 LINE SMOOTH",
+"1325 1227 OFFCURVE",
+"1325 1380 OFFCURVE",
+"1340 1460 CURVE",
+"1040 1460 LINE"
+);
+}
+);
+width = 1515;
+}
+);
+unicode = 0048;
+},
+{
+glyphname = LtnCapI;
+layers = (
+{
+anchors = (
+{
+name = H;
+position = "{477, 0}";
+},
+{
+name = L;
+position = "{477, -100}";
+},
+{
+name = O;
+position = "{673, 0}";
+},
+{
+name = R;
+position = "{975, 1200}";
+},
+{
+name = U;
+position = "{477, 1530}";
+}
+);
+layerId = master01;
+paths = (
+{
+closed = 1;
+nodes = (
+"140 1315 LINE",
+"380 1315 LINE",
+"380 145 LINE",
+"140 145 LINE",
+"140 0 LINE",
+"815 0 LINE",
+"815 145 LINE",
+"570 145 LINE",
+"570 1315 LINE",
+"815 1315 LINE",
+"815 1460 LINE",
+"140 1460 LINE"
+);
+}
+);
+width = 975;
+},
+{
+anchors = (
+{
+name = H;
+position = "{520, 0}";
+},
+{
+name = L;
+position = "{516, -100}";
+},
+{
+name = O;
+position = "{712, 0}";
+},
+{
+name = R;
+position = "{1014, 1200}";
+},
+{
+name = U;
+position = "{520, 1530}";
+}
+);
+layerId = master02;
+paths = (
+{
+closed = 1;
+nodes = (
+"130 1255 LINE",
+"370 1255 LINE",
+"370 205 LINE",
+"130 205 LINE",
+"130 0 LINE",
+"895 0 LINE",
+"895 205 LINE",
+"655 205 LINE",
+"655 1255 LINE",
+"895 1255 LINE",
+"895 1460 LINE",
+"130 1460 LINE"
+);
+}
+);
+width = 1045;
+}
+);
+unicode = 0049;
+},
+{
+glyphname = LtnCapJ;
+layers = (
+{
+anchors = (
+{
+name = L;
+position = "{410, -100}";
+},
+{
+name = U;
+position = "{675, 1530}";
+}
+);
+layerId = master01;
+paths = (
+{
+closed = 1;
+nodes = (
+"588 1354 OFFCURVE",
+"590 1175 OFFCURVE",
+"590 980 CURVE",
+"590 485 LINE SMOOTH",
+"590 256 OFFCURVE",
+"487 155 OFFCURVE",
+"340 155 CURVE SMOOTH",
+"248 155 OFFCURVE",
+"147 198 OFFCURVE",
+"80 275 CURVE",
+"35 90 LINE",
+"106 9 OFFCURVE",
+"250 -25 OFFCURVE",
+"345 -25 CURVE SMOOTH",
+"602 -25 OFFCURVE",
+"780 119 OFFCURVE",
+"780 535 CURVE SMOOTH",
+"780 1460 LINE",
+"575 1460 LINE"
+);
+}
+);
+width = 965;
+},
+{
+anchors = (
+{
+name = L;
+position = "{415, -100}";
+},
+{
+name = U;
+position = "{705, 1530}";
+}
+);
+layerId = master02;
+paths = (
+{
+closed = 1;
+nodes = (
+"568 1354 OFFCURVE",
+"570 1175 OFFCURVE",
+"570 980 CURVE SMOOTH",
+"570 558 LINE SMOOTH",
+"570 383 OFFCURVE",
+"540 227 OFFCURVE",
+"365 227 CURVE SMOOTH",
+"264 227 OFFCURVE",
+"153 270 OFFCURVE",
+"79 347 CURVE",
+"30 90 LINE",
+"109 9 OFFCURVE",
+"258 -25 OFFCURVE",
+"363 -25 CURVE SMOOTH",
+"658 -25 OFFCURVE",
+"855 129 OFFCURVE",
+"855 535 CURVE SMOOTH",
+"855 618 OFFCURVE",
+"855 1460 OFFCURVE",
+"855 1460 CURVE",
+"555 1460 LINE"
+);
+}
+);
+width = 1030;
+}
+);
+unicode = 004A;
+},
+{
+glyphname = LtnCapK;
+layers = (
+{
+anchors = (
+{
+name = H;
+position = "{270, 0}";
+},
+{
+name = L;
+position = "{695, -100}";
+},
+{
+name = U;
+position = "{650, 1530}";
+}
+);
+layerId = master01;
+paths = (
+{
+closed = 1;
+nodes = (
+"295 703 LINE",
+"425 745 LINE",
+"530 740 LINE",
+"1165 1460 LINE",
+"925 1460 LINE"
+);
+},
+{
+closed = 1;
+nodes = (
+"985 0 LINE",
+"1230 0 LINE",
+"485 860 LINE",
+"350 735 LINE"
+);
+},
+{
+closed = 1;
+nodes = (
+"160 1460 LINE",
+"175 1380 OFFCURVE",
+"175 1222 OFFCURVE",
+"175 1025 CURVE SMOOTH",
+"175 435 LINE SMOOTH",
+"175 238 OFFCURVE",
+"175 80 OFFCURVE",
+"160 0 CURVE",
+"365 0 LINE",
+"365 1460 LINE"
+);
+}
+);
+width = 1310;
+},
+{
+anchors = (
+{
+name = H;
+position = "{320, 0}";
+},
+{
+name = L;
+position = "{740, -100}";
+},
+{
+name = U;
+position = "{725, 1530}";
+}
+);
+layerId = master02;
+paths = (
+{
+closed = 1;
+nodes = (
+"371 732 LINE",
+"579 676 LINE",
+"1280 1460 LINE",
+"944 1460 LINE"
+);
+},
+{
+closed = 1;
+nodes = (
+"990 0 LINE",
+"1360 0 LINE",
+"614 829 LINE",
+"389 731 LINE"
+);
+},
+{
+closed = 1;
+nodes = (
+"150 1460 LINE",
+"165 1380 OFFCURVE",
+"165 1222 OFFCURVE",
+"165 1025 CURVE SMOOTH",
+"165 435 LINE SMOOTH",
+"165 238 OFFCURVE",
+"165 80 OFFCURVE",
+"150 0 CURVE",
+"450 0 LINE",
+"450 1460 LINE"
+);
+}
+);
+width = 1430;
+}
+);
+unicode = 004B;
+},
+{
+glyphname = LtnCapL;
+layers = (
+{
+anchors = (
+{
+name = H;
+position = "{592, 0}";
+},
+{
+name = L;
+position = "{592, -100}";
+},
+{
+name = R;
+position = "{540, 1200}";
+},
+{
+name = U;
+position = "{592, 1530}";
+}
+);
+layerId = master01;
+paths = (
+{
+closed = 1;
+nodes = (
+"365 1460 LINE",
+"160 1460 LINE",
+"175 1380 OFFCURVE",
+"175 1222 OFFCURVE",
+"175 1025 CURVE SMOOTH",
+"175 435 LINE SMOOTH",
+"175 238 OFFCURVE",
+"175 80 OFFCURVE",
+"160 0 CURVE",
+"1025 0 LINE",
+"1025 180 LINE",
+"945 166 OFFCURVE",
+"786 165 OFFCURVE",
+"589 165 CURVE SMOOTH",
+"365 165 LINE"
+);
+}
+);
+width = 1080;
+},
+{
+anchors = (
+{
+name = H;
+position = "{620, 0}";
+},
+{
+name = L;
+position = "{620, -100}";
+},
+{
+name = R;
+position = "{650, 1200}";
+},
+{
+name = U;
+position = "{620, 1530}";
+}
+);
+layerId = master02;
+paths = (
+{
+closed = 1;
+nodes = (
+"450 1460 LINE",
+"150 1460 LINE",
+"165 1380 OFFCURVE",
+"165 1222 OFFCURVE",
+"165 1025 CURVE SMOOTH",
+"165 435 LINE SMOOTH",
+"165 238 OFFCURVE",
+"165 80 OFFCURVE",
+"150 0 CURVE",
+"1085 0 LINE",
+"1085 245 LINE",
+"1008 231 OFFCURVE",
+"855 230 OFFCURVE",
+"666 230 CURVE SMOOTH",
+"450 230 LINE"
+);
+}
+);
+width = 1130;
+}
+);
+unicode = 004C;
+},
+{
+glyphname = LtnCapM;
+layers = (
+{
+anchors = (
+{
+name = H;
+position = "{1521, 0}";
+},
+{
+name = L;
+position = "{885, -100}";
+},
+{
+name = U;
+position = "{885, 1530}";
+}
+);
+layerId = master01;
+paths = (
+{
+closed = 1;
+nodes = (
+"455 1460 LINE",
+"285 1460 LINE",
+"790 0 LINE",
+"985 0 LINE",
+"1487 1460 LINE",
+"1320 1460 LINE",
+"885 205 LINE"
+);
+},
+{
+closed = 1;
+nodes = (
+"230 1460 OFFCURVE",
+"186 198 OFFCURVE",
+"160 0 CURVE",
+"345 0 LINE",
+"377 1205 LINE",
+"405 1460 LINE",
+"230 1460 LINE"
+);
+},
+{
+closed = 1;
+nodes = (
+"1581 198 OFFCURVE",
+"1540 1460 OFFCURVE",
+"1540 1460 CURVE",
+"1365 1460 LINE",
+"1397 1205 LINE",
+"1425 0 LINE",
+"1610 0 LINE"
+);
+}
+);
+width = 1795;
+},
+{
+anchors = (
+{
+name = L;
+position = "{915, -100}";
+},
+{
+name = U;
+position = "{915, 1530}";
+}
+);
+layerId = master02;
+paths = (
+{
+closed = 1;
+nodes = (
+"575 1460 LINE",
+"315 1460 LINE",
+"436 1170 LINE",
+"770 0 LINE",
+"1065 0 LINE",
+"1397 1170 LINE",
+"1517 1460 LINE",
+"1260 1460 LINE",
+"917 275 LINE"
+);
+},
+{
+closed = 1;
+nodes = (
+"220 1460 OFFCURVE",
+"176 198 OFFCURVE",
+"150 0 CURVE",
+"420 0 LINE",
+"449 1205 LINE",
+"485 1460 LINE",
+"220 1460 LINE"
+);
+},
+{
+closed = 1;
+nodes = (
+"1651 198 OFFCURVE",
+"1610 1460 OFFCURVE",
+"1610 1460 CURVE",
+"1340 1460 LINE",
+"1385 1205 LINE",
+"1410 0 LINE",
+"1680 0 LINE"
+);
+}
+);
+width = 1855;
+}
+);
+unicode = 004D;
+},
+{
+glyphname = LtnCapN;
+layers = (
+{
+anchors = (
+{
+name = H;
+position = "{1230, 0}";
+},
+{
+name = L;
+position = "{737, -100}";
+},
+{
+name = U;
+position = "{737, 1530}";
+}
+);
+layerId = master01;
+paths = (
+{
+closed = 1;
+nodes = (
+"1135 0 LINE",
+"1275 100 LINE",
+"340 1460 LINE",
+"200 1355 LINE"
+);
+},
+{
+closed = 1;
+nodes = (
+"1300 0 LINE",
+"1300 1025 LINE SMOOTH",
+"1300 1222 OFFCURVE",
+"1301 1380 OFFCURVE",
+"1315 1460 CURVE",
+"1135 1460 LINE",
+"1135 0 LINE"
+);
+},
+{
+closed = 1;
+nodes = (
+"160 1460 LINE",
+"175 1380 OFFCURVE",
+"175 1222 OFFCURVE",
+"175 1025 CURVE SMOOTH",
+"175 435 LINE SMOOTH",
+"175 238 OFFCURVE",
+"175 80 OFFCURVE",
+"160 0 CURVE",
+"340 0 LINE",
+"340 1460 LINE"
+);
+}
+);
+width = 1500;
+},
+{
+anchors = (
+{
+name = H;
+position = "{1240, 0}";
+},
+{
+name = L;
+position = "{765, -100}";
+},
+{
+name = U;
+position = "{765, 1530}";
+}
+);
+layerId = master02;
+paths = (
+{
+closed = 1;
+nodes = (
+"1095 0 LINE",
+"1297 150 LINE",
+"425 1460 LINE",
+"223 1310 LINE"
+);
+},
+{
+closed = 1;
+nodes = (
+"1355 0 LINE",
+"1355 1025 LINE SMOOTH",
+"1355 1222 OFFCURVE",
+"1356 1380 OFFCURVE",
+"1370 1460 CURVE",
+"1095 1460 LINE",
+"1095 0 LINE"
+);
+},
+{
+closed = 1;
+nodes = (
+"150 1460 LINE",
+"165 1380 OFFCURVE",
+"165 1222 OFFCURVE",
+"165 1025 CURVE SMOOTH",
+"165 435 LINE SMOOTH",
+"165 238 OFFCURVE",
+"165 80 OFFCURVE",
+"150 0 CURVE",
+"425 0 LINE",
+"425 1460 LINE"
+);
+}
+);
+width = 1545;
+}
+);
+unicode = 004E;
+},
+{
+glyphname = LtnCapO;
+layers = (
+{
+anchors = (
+{
+name = H;
+position = "{717, 0}";
+},
+{
+name = L;
+position = "{717, -100}";
+},
+{
+name = O;
+position = "{994, 0}";
+},
+{
+name = R;
+position = "{1460, 1200}";
+},
+{
+name = U;
+position = "{717, 1530}";
+}
+);
+layerId = master01;
+paths = (
+{
+closed = 1;
+nodes = (
+"1145 360 OFFCURVE",
+"965 150 OFFCURVE",
+"720 150 CURVE SMOOTH",
+"460 150 OFFCURVE",
+"290 380 OFFCURVE",
+"290 745 CURVE SMOOTH",
+"290 1091 OFFCURVE",
+"467 1310 OFFCURVE",
+"720 1310 CURVE SMOOTH",
+"974 1310 OFFCURVE",
+"1145 1084 OFFCURVE",
+"1145 715 CURVE SMOOTH"
+);
+},
+{
+closed = 1;
+nodes = (
+"1340 1219 OFFCURVE",
+"1048 1485 OFFCURVE",
+"730 1485 CURVE SMOOTH",
+"407 1485 OFFCURVE",
+"95 1199 OFFCURVE",
+"95 720 CURVE SMOOTH",
+"95 241 OFFCURVE",
+"388 -25 OFFCURVE",
+"710 -25 CURVE SMOOTH",
+"1029 -25 OFFCURVE",
+"1340 260 OFFCURVE",
+"1340 740 CURVE SMOOTH"
+);
+}
+);
+width = 1460;
+},
+{
+anchors = (
+{
+name = H;
+position = "{740, 0}";
+},
+{
+name = L;
+position = "{740, -100}";
+},
+{
+name = O;
+position = "{976, 0}";
+},
+{
+name = R;
+position = "{1480, 1200}";
+},
+{
+name = U;
+position = "{740, 1530}";
+}
+);
+layerId = master02;
+paths = (
+{
+closed = 1;
+nodes = (
+"1100 404 OFFCURVE",
+"940 220 OFFCURVE",
+"740 220 CURVE SMOOTH",
+"524 220 OFFCURVE",
+"375 423 OFFCURVE",
+"375 745 CURVE SMOOTH",
+"375 1048 OFFCURVE",
+"529 1240 OFFCURVE",
+"740 1240 CURVE SMOOTH",
+"951 1240 OFFCURVE",
+"1100 1041 OFFCURVE",
+"1100 715 CURVE SMOOTH"
+);
+},
+{
+closed = 1;
+nodes = (
+"1385 1219 OFFCURVE",
+"1091 1485 OFFCURVE",
+"750 1485 CURVE SMOOTH",
+"404 1485 OFFCURVE",
+"90 1199 OFFCURVE",
+"90 720 CURVE SMOOTH",
+"90 241 OFFCURVE",
+"385 -25 OFFCURVE",
+"730 -25 CURVE SMOOTH",
+"1072 -25 OFFCURVE",
+"1385 260 OFFCURVE",
+"1385 740 CURVE SMOOTH"
+);
+}
+);
+width = 1500;
+}
+);
+unicode = 004F;
+},
+{
+glyphname = LtnCapP;
+layers = (
+{
+anchors = (
+{
+name = L;
+position = "{637, -100}";
+},
+{
+name = U;
+position = "{637, 1530}";
+}
+);
+layerId = master01;
+paths = (
+{
+closed = 1;
+nodes = (
+"430 558 OFFCURVE",
+"512 555 OFFCURVE",
+"585 555 CURVE SMOOTH",
+"914 555 OFFCURVE",
+"1115 736 OFFCURVE",
+"1115 1030 CURVE SMOOTH",
+"1115 1322 OFFCURVE",
+"908 1470 OFFCURVE",
+"585 1470 CURVE SMOOTH",
+"372 1470 OFFCURVE",
+"160 1460 OFFCURVE",
+"160 1460 CURVE",
+"175 1380 OFFCURVE",
+"175 1196 OFFCURVE",
+"175 1000 CURVE",
+"175 435 LINE SMOOTH",
+"175 238 OFFCURVE",
+"175 80 OFFCURVE",
+"160 0 CURVE",
+"380 0 LINE",
+"366 78 OFFCURVE",
+"365 237 OFFCURVE",
+"365 435 CURVE SMOOTH",
+"365 565 LINE"
+);
+},
+{
+closed = 1;
+nodes = (
+"433 1308 OFFCURVE",
+"481 1310 OFFCURVE",
+"575 1310 CURVE SMOOTH",
+"841 1310 OFFCURVE",
+"925 1170 OFFCURVE",
+"925 1010 CURVE SMOOTH",
+"925 849 OFFCURVE",
+"850 710 OFFCURVE",
+"570 710 CURVE SMOOTH",
+"495 710 OFFCURVE",
+"428 712 OFFCURVE",
+"365 720 CURVE",
+"365 1305 LINE"
+);
+}
+);
+width = 1195;
+},
+{
+anchors = (
+{
+name = L;
+position = "{685, -100}";
+},
+{
+name = U;
+position = "{685, 1530}";
+}
+);
+layerId = master02;
+paths = (
+{
+closed = 1;
+nodes = (
+"515 516 OFFCURVE",
+"575 513 OFFCURVE",
+"648 513 CURVE SMOOTH",
+"977 513 OFFCURVE",
+"1200 702 OFFCURVE",
+"1200 1010 CURVE SMOOTH",
+"1200 1316 OFFCURVE",
+"981 1470 OFFCURVE",
+"658 1470 CURVE SMOOTH",
+"445 1470 OFFCURVE",
+"150 1460 OFFCURVE",
+"150 1460 CURVE",
+"165 1380 OFFCURVE",
+"165 1196 OFFCURVE",
+"165 1000 CURVE SMOOTH",
+"165 435 LINE SMOOTH",
+"165 238 OFFCURVE",
+"165 80 OFFCURVE",
+"150 0 CURVE",
+"465 0 LINE",
+"451 78 OFFCURVE",
+"450 237 OFFCURVE",
+"450 435 CURVE SMOOTH",
+"450 523 LINE"
+);
+},
+{
+closed = 1;
+nodes = (
+"506 1243 OFFCURVE",
+"544 1245 OFFCURVE",
+"622 1245 CURVE SMOOTH",
+"833 1245 OFFCURVE",
+"915 1145 OFFCURVE",
+"915 1000 CURVE SMOOTH",
+"915 820 OFFCURVE",
+"811 730 OFFCURVE",
+"618 730 CURVE SMOOTH",
+"556 730 OFFCURVE",
+"493 733 OFFCURVE",
+"450 740 CURVE",
+"450 1240 LINE"
+);
+}
+);
+width = 1275;
+}
+);
+unicode = 0050;
+},
+{
+glyphname = LtnCapQ;
+layers = (
+{
+anchors = (
+{
+name = L;
+position = "{717, -270}";
+},
+{
+name = U;
+position = "{717, 1530}";
+}
+);
+layerId = master01;
+paths = (
+{
+closed = 1;
+nodes = (
+"1340 1219 OFFCURVE",
+"1053 1485 OFFCURVE",
+"730 1485 CURVE SMOOTH",
+"407 1485 OFFCURVE",
+"95 1199 OFFCURVE",
+"95 720 CURVE SMOOTH",
+"95 241 OFFCURVE",
+"383 -25 OFFCURVE",
+"705 -25 CURVE SMOOTH",
+"767 -25 OFFCURVE",
+"818 -18 OFFCURVE",
+"875 0 CURVE",
+"944 0 OFFCURVE",
+"1236 -190 OFFCURVE",
+"1320 -190 CURVE SMOOTH",
+"1374 -190 OFFCURVE",
+"1431 -81 OFFCURVE",
+"1455 -45 CURVE",
+"1321 -28 OFFCURVE",
+"1205 28 OFFCURVE",
+"1080 105 CURVE",
+"1256 236 OFFCURVE",
+"1340 479 OFFCURVE",
+"1340 740 CURVE SMOOTH"
+);
+},
+{
+closed = 1;
+nodes = (
+"1145 360 OFFCURVE",
+"965 150 OFFCURVE",
+"720 150 CURVE SMOOTH",
+"460 150 OFFCURVE",
+"290 380 OFFCURVE",
+"290 745 CURVE SMOOTH",
+"290 1091 OFFCURVE",
+"467 1310 OFFCURVE",
+"720 1310 CURVE SMOOTH",
+"974 1310 OFFCURVE",
+"1145 1084 OFFCURVE",
+"1145 715 CURVE SMOOTH"
+);
+}
+);
+width = 1475;
+},
+{
+anchors = (
+{
+name = L;
+position = "{747, -270}";
+},
+{
+name = U;
+position = "{747, 1530}";
+}
+);
+layerId = master02;
+paths = (
+{
+closed = 1;
+nodes = (
+"1385 1219 OFFCURVE",
+"1091 1485 OFFCURVE",
+"750 1485 CURVE SMOOTH",
+"404 1485 OFFCURVE",
+"90 1199 OFFCURVE",
+"90 720 CURVE SMOOTH",
+"90 241 OFFCURVE",
+"385 -25 OFFCURVE",
+"730 -25 CURVE SMOOTH",
+"807 -25 OFFCURVE",
+"840 -23 OFFCURVE",
+"889 -15 CURVE",
+"958 -15 OFFCURVE",
+"1266 -228 OFFCURVE",
+"1350 -228 CURVE SMOOTH",
+"1424 -228 OFFCURVE",
+"1502 -68 OFFCURVE",
+"1535 -15 CURVE",
+"1394 1 OFFCURVE",
+"1277 68 OFFCURVE",
+"1146 142 CURVE",
+"1294 283 OFFCURVE",
+"1385 471 OFFCURVE",
+"1385 740 CURVE SMOOTH"
+);
+},
+{
+closed = 1;
+nodes = (
+"1100 404 OFFCURVE",
+"943 220 OFFCURVE",
+"740 220 CURVE SMOOTH",
+"524 220 OFFCURVE",
+"375 423 OFFCURVE",
+"375 745 CURVE SMOOTH",
+"375 1048 OFFCURVE",
+"529 1240 OFFCURVE",
+"740 1240 CURVE SMOOTH",
+"951 1240 OFFCURVE",
+"1100 1041 OFFCURVE",
+"1100 715 CURVE SMOOTH"
+);
+}
+);
+width = 1545;
+}
+);
+unicode = 0051;
+},
+{
+glyphname = LtnCapR;
+layers = (
+{
+anchors = (
+{
+name = H;
+position = "{285, 0}";
+},
+{
+name = L;
+position = "{610, -100}";
+},
+{
+name = U;
+position = "{610, 1530}";
+}
+);
+layerId = master01;
+paths = (
+{
+closed = 1;
+nodes = (
+"620 625 LINE",
+"805 625 OFFCURVE",
+"1090 743 OFFCURVE",
+"1090 1060 CURVE SMOOTH",
+"1090 1349 OFFCURVE",
+"876 1470 OFFCURVE",
+"565 1470 CURVE SMOOTH",
+"331 1470 OFFCURVE",
+"160 1460 OFFCURVE",
+"160 1460 CURVE",
+"175 1380 OFFCURVE",
+"175 1196 OFFCURVE",
+"175 1000 CURVE SMOOTH",
+"175 435 LINE",
+"175 238 OFFCURVE",
+"175 80 OFFCURVE",
+"160 0 CURVE",
+"380 0 LINE",
+"366 78 OFFCURVE",
+"365 238 OFFCURVE",
+"365 435 CURVE",
+"365 625 LINE"
+);
+},
+{
+closed = 1;
+nodes = (
+"418 1307 OFFCURVE",
+"485 1310 OFFCURVE",
+"555 1310 CURVE SMOOTH",
+"800 1310 OFFCURVE",
+"900 1216 OFFCURVE",
+"900 1045 CURVE SMOOTH",
+"900 879 OFFCURVE",
+"780 780 OFFCURVE",
+"555 780 CURVE",
+"365 780 LINE",
+"365 1305 LINE"
+);
+},
+{
+closed = 1;
+nodes = (
+"990 0 LINE",
+"1245 0 LINE",
+"1178 73 OFFCURVE",
+"715 710 OFFCURVE",
+"715 710 CURVE",
+"561 635 LINE"
+);
+}
+);
+width = 1305;
+},
+{
+anchors = (
+{
+name = H;
+position = "{690, 0}";
+},
+{
+name = L;
+position = "{690, -100}";
+},
+{
+name = U;
+position = "{660, 1530}";
+}
+);
+layerId = master02;
+paths = (
+{
+closed = 1;
+nodes = (
+"625 585 LINE SMOOTH",
+"910 585 OFFCURVE",
+"1175 723 OFFCURVE",
+"1175 1040 CURVE SMOOTH",
+"1175 1329 OFFCURVE",
+"961 1470 OFFCURVE",
+"650 1470 CURVE SMOOTH",
+"416 1470 OFFCURVE",
+"150 1460 OFFCURVE",
+"150 1460 CURVE",
+"165 1380 OFFCURVE",
+"165 1196 OFFCURVE",
+"165 1000 CURVE SMOOTH",
+"165 435 LINE SMOOTH",
+"165 238 OFFCURVE",
+"165 80 OFFCURVE",
+"150 0 CURVE",
+"465 0 LINE",
+"451 78 OFFCURVE",
+"450 238 OFFCURVE",
+"450 435 CURVE SMOOTH",
+"450 585 LINE"
+);
+},
+{
+closed = 1;
+nodes = (
+"503 1243 OFFCURVE",
+"537 1245 OFFCURVE",
+"615 1245 CURVE SMOOTH",
+"792 1245 OFFCURVE",
+"890 1186 OFFCURVE",
+"890 1035 CURVE SMOOTH",
+"890 859 OFFCURVE",
+"780 800 OFFCURVE",
+"605 800 CURVE SMOOTH",
+"450 800 LINE",
+"450 1240 LINE"
+);
+},
+{
+closed = 1;
+nodes = (
+"975 0 LINE",
+"1330 0 LINE",
+"1263 73 OFFCURVE",
+"827 687 OFFCURVE",
+"827 687 CURVE",
+"556 635 LINE"
+);
+}
+);
+width = 1380;
+}
+);
+unicode = 0052;
+},
+{
+glyphname = LtnCapS;
+layers = (
+{
+anchors = (
+{
+name = H;
+position = "{580, 0}";
+},
+{
+name = L;
+position = "{580, -100}";
+},
+{
+name = U;
+position = "{580, 1530}";
+}
+);
+layerId = master01;
+paths = (
+{
+closed = 1;
+nodes = (
+"870 1458 OFFCURVE",
+"759 1485 OFFCURVE",
+"605 1485 CURVE SMOOTH",
+"273 1485 OFFCURVE",
+"135 1250 OFFCURVE",
+"135 1080 CURVE SMOOTH",
+"135 910 OFFCURVE",
+"203 778 OFFCURVE",
+"515 685 CURVE SMOOTH",
+"827 591 OFFCURVE",
+"875 510 OFFCURVE",
+"875 405 CURVE SMOOTH",
+"875 243 OFFCURVE",
+"726 150 OFFCURVE",
+"565 150 CURVE SMOOTH",
+"417 150 OFFCURVE",
+"272 200 OFFCURVE",
+"140 315 CURVE",
+"95 110 LINE",
+"197 31 OFFCURVE",
+"372 -25 OFFCURVE",
+"565 -25 CURVE SMOOTH",
+"838 -25 OFFCURVE",
+"1065 157 OFFCURVE",
+"1065 425 CURVE SMOOTH",
+"1065 641 OFFCURVE",
+"920 762 OFFCURVE",
+"655 840 CURVE SMOOTH",
+"370 923 OFFCURVE",
+"325 985 OFFCURVE",
+"325 1095 CURVE SMOOTH",
+"325 1205 OFFCURVE",
+"435 1310 OFFCURVE",
+"595 1310 CURVE SMOOTH",
+"723 1310 OFFCURVE",
+"817 1279 OFFCURVE",
+"960 1200 CURVE",
+"1000 1395 LINE"
+);
+}
+);
+width = 1175;
+},
+{
+anchors = (
+{
+name = H;
+position = "{616, 0}";
+},
+{
+name = L;
+position = "{616, -100}";
+},
+{
+name = U;
+position = "{616, 1530}";
+}
+);
+layerId = master02;
+paths = (
+{
+closed = 1;
+nodes = (
+"932 1458 OFFCURVE",
+"810 1485 OFFCURVE",
+"640 1485 CURVE SMOOTH",
+"280 1485 OFFCURVE",
+"130 1239 OFFCURVE",
+"130 1060 CURVE SMOOTH",
+"130 882 OFFCURVE",
+"196 754 OFFCURVE",
+"510 655 CURVE SMOOTH",
+"800 563 OFFCURVE",
+"851 504 OFFCURVE",
+"851 420 CURVE SMOOTH",
+"851 293 OFFCURVE",
+"730 220 OFFCURVE",
+"600 220 CURVE SMOOTH",
+"439 220 OFFCURVE",
+"283 270 OFFCURVE",
+"140 385 CURVE",
+"90 110 LINE",
+"201 31 OFFCURVE",
+"391 -25 OFFCURVE",
+"600 -25 CURVE SMOOTH",
+"895 -25 OFFCURVE",
+"1138 169 OFFCURVE",
+"1138 455 CURVE SMOOTH",
+"1138 666 OFFCURVE",
+"994 787 OFFCURVE",
+"727 870 CURVE SMOOTH",
+"464 952 OFFCURVE",
+"416 994 OFFCURVE",
+"416 1080 CURVE SMOOTH",
+"416 1162 OFFCURVE",
+"506 1245 OFFCURVE",
+"630 1245 CURVE SMOOTH",
+"771 1245 OFFCURVE",
+"873 1209 OFFCURVE",
+"1030 1130 CURVE",
+"1075 1395 LINE"
+);
+}
+);
+width = 1243;
+}
+);
+unicode = 0053;
+},
+{
+glyphname = LtnCapT;
+layers = (
+{
+anchors = (
+{
+name = H;
+position = "{622, 0}";
+},
+{
+name = L;
+position = "{622, -100}";
+},
+{
+name = U;
+position = "{622, 1530}";
+}
+);
+layerId = master01;
+paths = (
+{
+closed = 1;
+nodes = (
+"45 1275 LINE",
+"125 1292 OFFCURVE",
+"201 1295 OFFCURVE",
+"290 1295 CURVE SMOOTH",
+"525 1295 LINE",
+"525 435 LINE SMOOTH",
+"525 238 OFFCURVE",
+"522 80 OFFCURVE",
+"505 0 CURVE",
+"735 0 LINE",
+"718 80 OFFCURVE",
+"715 238 OFFCURVE",
+"715 435 CURVE SMOOTH",
+"715 1295 LINE",
+"955 1295 LINE SMOOTH",
+"1045 1295 OFFCURVE",
+"1120 1292 OFFCURVE",
+"1200 1275 CURVE",
+"1200 1460 LINE",
+"45 1460 LINE"
+);
+}
+);
+width = 1265;
+},
+{
+anchors = (
+{
+name = H;
+position = "{632, 0}";
+},
+{
+name = L;
+position = "{632, -100}";
+},
+{
+name = U;
+position = "{632, 1530}";
+}
+);
+layerId = master02;
+paths = (
+{
+closed = 1;
+nodes = (
+"45 1210 LINE",
+"117 1227 OFFCURVE",
+"196 1230 OFFCURVE",
+"276 1230 CURVE SMOOTH",
+"488 1230 LINE",
+"488 413 LINE SMOOTH",
+"488 226 OFFCURVE",
+"485 76 OFFCURVE",
+"468 0 CURVE",
+"793 0 LINE",
+"776 76 OFFCURVE",
+"773 226 OFFCURVE",
+"773 413 CURVE SMOOTH",
+"773 1230 LINE",
+"989 1230 LINE SMOOTH",
+"1070 1230 OFFCURVE",
+"1148 1227 OFFCURVE",
+"1220 1210 CURVE",
+"1220 1460 LINE",
+"45 1460 LINE"
+);
+}
+);
+width = 1275;
+}
+);
+unicode = 0054;
+},
+{
+glyphname = LtnCapU;
+layers = (
+{
+anchors = (
+{
+name = H;
+position = "{707, 0}";
+},
+{
+name = L;
+position = "{707, -100}";
+},
+{
+name = O;
+position = "{1026, 0}";
+},
+{
+name = R;
+position = "{1400, 1200}";
+},
+{
+name = U;
+position = "{707, 1530}";
+}
+);
+layerId = master01;
+paths = (
+{
+closed = 1;
+nodes = (
+"1050 560 LINE SMOOTH",
+"1050 299 OFFCURVE",
+"968 135 OFFCURVE",
+"710 135 CURVE SMOOTH",
+"447 135 OFFCURVE",
+"365 299 OFFCURVE",
+"365 560 CURVE SMOOTH",
+"365 1460 LINE",
+"160 1460 LINE",
+"174 1380 OFFCURVE",
+"175 1222 OFFCURVE",
+"175 1025 CURVE SMOOTH",
+"175 515 LINE",
+"175 190 OFFCURVE",
+"345 -25 OFFCURVE",
+"710 -25 CURVE SMOOTH",
+"1071 -25 OFFCURVE",
+"1240 190 OFFCURVE",
+"1240 515 CURVE",
+"1240 1025 LINE SMOOTH",
+"1240 1232 OFFCURVE",
+"1242 1380 OFFCURVE",
+"1255 1460 CURVE",
+"1050 1460 LINE"
+);
+}
+);
+width = 1440;
+},
+{
+anchors = (
+{
+name = H;
+position = "{732, 0}";
+},
+{
+name = L;
+position = "{732, -100}";
+},
+{
+name = O;
+position = "{950, 0}";
+},
+{
+name = R;
+position = "{1480, 1200}";
+},
+{
+name = U;
+position = "{732, 1530}";
+}
+);
+layerId = master02;
+paths = (
+{
+closed = 1;
+nodes = (
+"1015 560 LINE SMOOTH",
+"1015 344 OFFCURVE",
+"952 204 OFFCURVE",
+"735 204 CURVE SMOOTH",
+"513 204 OFFCURVE",
+"450 344 OFFCURVE",
+"450 560 CURVE SMOOTH",
+"450 1460 LINE",
+"150 1460 LINE",
+"164 1380 OFFCURVE",
+"165 1222 OFFCURVE",
+"165 1025 CURVE SMOOTH",
+"165 515 LINE SMOOTH",
+"165 190 OFFCURVE",
+"356 -25 OFFCURVE",
+"735 -25 CURVE SMOOTH",
+"1110 -25 OFFCURVE",
+"1300 190 OFFCURVE",
+"1300 515 CURVE SMOOTH",
+"1300 1025 LINE SMOOTH",
+"1300 1232 OFFCURVE",
+"1302 1380 OFFCURVE",
+"1315 1460 CURVE",
+"1015 1460 LINE"
+);
+}
+);
+width = 1490;
+}
+);
+unicode = 0055;
+},
+{
+glyphname = LtnCapV;
+layers = (
+{
+anchors = (
+{
+name = H;
+position = "{680, 0}";
+},
+{
+name = L;
+position = "{672, -100}";
+},
+{
+name = O;
+position = "{880, 0}";
+},
+{
+name = U;
+position = "{672, 1530}";
+}
+);
+layerId = master01;
+paths = (
+{
+closed = 1;
+nodes = (
+"672 195 LINE",
+"250 1460 LINE",
+"35 1460 LINE",
+"68 1378 OFFCURVE",
+"101 1288 OFFCURVE",
+"170 1095 CURVE SMOOTH",
+"560 0 LINE",
+"785 0 LINE",
+"1170 1095 LINE SMOOTH",
+"1238 1289 OFFCURVE",
+"1274 1378 OFFCURVE",
+"1310 1460 CURVE",
+"1095 1460 LINE"
+);
+}
+);
+width = 1365;
+},
+{
+anchors = (
+{
+name = H;
+position = "{730, 0}";
+},
+{
+name = L;
+position = "{722, -100}";
+},
+{
+name = O;
+position = "{930, 0}";
+},
+{
+name = U;
+position = "{722, 1530}";
+}
+);
+layerId = master02;
+paths = (
+{
+closed = 1;
+nodes = (
+"722 260 LINE",
+"330 1460 LINE",
+"25 1460 LINE",
+"58 1378 OFFCURVE",
+"96 1288 OFFCURVE",
+"165 1095 CURVE SMOOTH",
+"555 0 LINE",
+"890 0 LINE",
+"1280 1095 LINE SMOOTH",
+"1348 1289 OFFCURVE",
+"1384 1378 OFFCURVE",
+"1420 1460 CURVE",
+"1115 1460 LINE"
+);
+}
+);
+width = 1465;
+}
+);
+unicode = 0056;
+},
+{
+glyphname = LtnCapW;
+layers = (
+{
+anchors = (
+{
+name = L;
+position = "{1027, -100}";
+},
+{
+name = U;
+position = "{1027, 1530}";
+}
+);
+layerId = master01;
+paths = (
+{
+closed = 1;
+nodes = (
+"1595 0 LINE",
+"1900 1095 LINE SMOOTH",
+"1954 1289 OFFCURVE",
+"1983 1378 OFFCURVE",
+"2015 1460 CURVE",
+"1795 1460 LINE",
+"1470 130 LINE",
+"1480 0 LINE"
+);
+},
+{
+closed = 1;
+nodes = (
+"935 1460 LINE",
+"990 1305 LINE",
+"1370 0 LINE",
+"1480 0 LINE",
+"1500 130 LINE",
+"1120 1460 LINE"
+);
+},
+{
+closed = 1;
+nodes = (
+"685 0 LINE",
+"1065 1305 LINE",
+"1120 1460 LINE",
+"935 1460 LINE",
+"560 130 LINE",
+"580 0 LINE"
+);
+},
+{
+closed = 1;
+nodes = (
+"40 1460 LINE",
+"71 1381 OFFCURVE",
+"102 1286 OFFCURVE",
+"155 1095 CURVE SMOOTH",
+"460 0 LINE",
+"580 0 LINE",
+"590 130 LINE",
+"260 1460 LINE"
+);
+}
+);
+width = 2080;
+},
+{
+anchors = (
+{
+name = L;
+position = "{1052, -100}";
+},
+{
+name = U;
+position = "{1052, 1530}";
+}
+);
+layerId = master02;
+paths = (
+{
+closed = 1;
+nodes = (
+"1655 0 LINE",
+"1965 1095 LINE SMOOTH",
+"2020 1289 OFFCURVE",
+"2048 1378 OFFCURVE",
+"2080 1460 CURVE",
+"1770 1460 LINE",
+"1470 130 LINE",
+"1490 0 LINE"
+);
+},
+{
+closed = 1;
+nodes = (
+"920 1460 LINE",
+"995 1305 LINE",
+"1340 0 LINE",
+"1510 0 LINE",
+"1530 130 LINE",
+"1180 1460 LINE"
+);
+},
+{
+closed = 1;
+nodes = (
+"765 0 LINE",
+"1105 1305 LINE",
+"1180 1460 LINE",
+"920 1460 LINE",
+"580 130 LINE",
+"600 0 LINE"
+);
+},
+{
+closed = 1;
+nodes = (
+"30 1460 LINE",
+"61 1381 OFFCURVE",
+"92 1286 OFFCURVE",
+"145 1095 CURVE SMOOTH",
+"450 0 LINE",
+"620 0 LINE",
+"640 130 LINE",
+"340 1460 LINE"
+);
+}
+);
+width = 2135;
+}
+);
+unicode = 0057;
+},
+{
+glyphname = LtnCapX;
+layers = (
+{
+anchors = (
+{
+name = L;
+position = "{650, -100}";
+},
+{
+name = U;
+position = "{650, 1530}";
+}
+);
+layerId = master01;
+paths = (
+{
+closed = 1;
+nodes = (
+"265 340 LINE SMOOTH",
+"136 132 OFFCURVE",
+"103 86 OFFCURVE",
+"40 0 CURVE",
+"270 0 LINE",
+"642 614 LINE",
+"1030 0 LINE",
+"1260 0 LINE",
+"1199 82 OFFCURVE",
+"1165 127 OFFCURVE",
+"1033 336 CURVE SMOOTH",
+"761 767 LINE",
+"972 1110 LINE SMOOTH",
+"1097 1313 OFFCURVE",
+"1148 1383 OFFCURVE",
+"1210 1460 CURVE",
+"975 1460 LINE",
+"656 934 LINE",
+"325 1460 LINE",
+"90 1460 LINE",
+"154 1376 OFFCURVE",
+"201 1315 OFFCURVE",
+"330 1110 CURVE",
+"537 781 LINE"
+);
+}
+);
+width = 1325;
+},
+{
+anchors = (
+{
+name = L;
+position = "{670, -100}";
+},
+{
+name = U;
+position = "{670, 1530}";
+}
+);
+layerId = master02;
+paths = (
+{
+closed = 1;
+nodes = (
+"1310 0 LINE",
+"1249 82 OFFCURVE",
+"1211 125 OFFCURVE",
+"1083 336 CURVE SMOOTH",
+"400 1460 LINE",
+"75 1460 LINE",
+"139 1376 OFFCURVE",
+"189 1317 OFFCURVE",
+"315 1110 CURVE",
+"990 0 LINE"
+);
+},
+{
+closed = 1;
+nodes = (
+"255 340 LINE SMOOTH",
+"133 128 OFFCURVE",
+"93 86 OFFCURVE",
+"30 0 CURVE",
+"350 0 LINE",
+"700 609 LINE",
+"605 947 LINE"
+);
+},
+{
+closed = 1;
+nodes = (
+"1040 1110 LINE SMOOTH",
+"1153 1306 OFFCURVE",
+"1211 1383 OFFCURVE",
+"1275 1460 CURVE",
+"950 1460 LINE",
+"655 947 LINE",
+"750 609 LINE"
+);
+}
+);
+width = 1365;
+}
+);
+unicode = 0058;
+},
+{
+glyphname = LtnCapY;
+layers = (
+{
+anchors = (
+{
+name = L;
+position = "{650, -100}";
+},
+{
+name = U;
+position = "{650, 1530}";
+}
+);
+layerId = master01;
+paths = (
+{
+closed = 1;
+nodes = (
+"147 1311 OFFCURVE",
+"213 1197 OFFCURVE",
+"290 1065 CURVE SMOOTH",
+"555 611 LINE",
+"555 435 LINE SMOOTH",
+"555 238 OFFCURVE",
+"555 80 OFFCURVE",
+"540 0 CURVE",
+"760 0 LINE",
+"745 80 OFFCURVE",
+"745 238 OFFCURVE",
+"745 435 CURVE SMOOTH",
+"745 603 LINE",
+"1015 1065 LINE SMOOTH",
+"1091 1195 OFFCURVE",
+"1147 1291 OFFCURVE",
+"1265 1460 CURVE",
+"1035 1460 LINE",
+"660 799 LINE",
+"265 1460 LINE",
+"35 1460 LINE"
+);
+}
+);
+width = 1320;
+},
+{
+anchors = (
+{
+name = L;
+position = "{672, -100}";
+},
+{
+name = U;
+position = "{672, 1530}";
+}
+);
+layerId = master02;
+paths = (
+{
+closed = 1;
+nodes = (
+"782 675 LINE",
+"357 1460 LINE",
+"25 1460 LINE",
+"137 1311 OFFCURVE",
+"203 1197 OFFCURVE",
+"280 1065 CURVE SMOOTH",
+"575 560 LINE"
+);
+},
+{
+closed = 1;
+nodes = (
+"1069 1065 LINE SMOOTH",
+"1145 1195 OFFCURVE",
+"1201 1291 OFFCURVE",
+"1319 1460 CURVE",
+"997 1460 LINE",
+"577 675 LINE",
+"770 560 LINE"
+);
+},
+{
+closed = 1;
+nodes = (
+"530 435 LINE SMOOTH",
+"530 238 OFFCURVE",
+"530 80 OFFCURVE",
+"515 0 CURVE",
+"830 0 LINE",
+"815 80 OFFCURVE",
+"815 238 OFFCURVE",
+"815 435 CURVE SMOOTH",
+"815 695 LINE",
+"530 695 LINE"
+);
+}
+);
+width = 1364;
+}
+);
+unicode = 0059;
+},
+{
+glyphname = LftSqrBrac;
+layers = (
+{
+layerId = master01;
+paths = (
+{
+closed = 1;
+nodes = (
+"640 -260 LINE",
+"385 -260 LINE",
+"385 1450 LINE",
+"640 1450 LINE",
+"640 1600 LINE",
+"200 1600 LINE",
+"200 -410 LINE",
+"640 -410 LINE"
+);
+}
+);
+width = 790;
+},
+{
+layerId = master02;
+paths = (
+{
+closed = 1;
+nodes = (
+"710 -200 LINE",
+"470 -200 LINE",
+"470 1390 LINE",
+"710 1390 LINE",
+"710 1600 LINE",
+"190 1600 LINE",
+"190 -410 LINE",
+"710 -410 LINE"
+);
+}
+);
+width = 850;
+}
+);
+unicode = 005B;
+},
+{
+glyphname = ReverseSolidus;
+layers = (
+{
+layerId = master01;
+paths = (
+{
+closed = 1;
+nodes = (
+"160 1600 LINE",
+"10 1600 LINE",
+"840 -245 LINE",
+"990 -245 LINE"
+);
+}
+);
+width = 1000;
+},
+{
+layerId = master02;
+paths = (
+{
+closed = 1;
+nodes = (
+"840 -245 LINE",
+"1070 -245 LINE",
+"240 1600 LINE",
+"10 1600 LINE"
+);
+}
+);
+width = 1080;
+}
+);
+unicode = 005C;
+},
+{
+glyphname = RtSqrBrac;
+layers = (
+{
+layerId = master01;
+paths = (
+{
+closed = 1;
+nodes = (
+"590 1600 LINE",
+"150 1600 LINE",
+"150 1450 LINE",
+"405 1450 LINE",
+"405 -260 LINE",
+"150 -260 LINE",
+"150 -410 LINE",
+"590 -410 LINE"
+);
+}
+);
+width = 790;
+},
+{
+layerId = master02;
+paths = (
+{
+closed = 1;
+nodes = (
+"660 1600 LINE",
+"140 1600 LINE",
+"140 1390 LINE",
+"380 1390 LINE",
+"380 -200 LINE",
+"140 -200 LINE",
+"140 -410 LINE",
+"660 -410 LINE"
+);
+}
+);
+width = 850;
+}
+);
+unicode = 005D;
+},
+{
+glyphname = CircumAccent;
+layers = (
+{
+components = (
+{
+name = CombCircum;
+transform = "{1, 0, 0, 1, 995, 0}";
+}
+);
+layerId = master01;
+width = 850;
+},
+{
+anchors = (
+{
+name = U;
+position = "{440, 1635}";
+}
+);
+layerId = master02;
+paths = (
+{
+closed = 1;
+nodes = (
+"598 1600 LINE",
+"298 1600 LINE",
+"8 1200 LINE",
+"248 1200 LINE",
+"448 1430 LINE",
+"648 1200 LINE",
+"888 1200 LINE"
+);
+}
+);
+width = 880;
+}
+);
+unicode = 005E;
+},
+{
+glyphname = LowLine;
+layers = (
+{
+layerId = master01;
+paths = (
+{
+closed = 1;
+nodes = (
+"1274 -320 LINE",
+"1274 -170 LINE",
+"0 -170 LINE",
+"0 -320 LINE"
+);
+}
+);
+width = 1274;
+},
+{
+layerId = master02;
+paths = (
+{
+closed = 1;
+nodes = (
+"1274 -350 LINE",
+"1274 -140 LINE",
+"0 -140 LINE",
+"0 -350 LINE"
+);
+}
+);
+width = 1274;
+}
+);
+unicode = 005F;
+},
+{
+glyphname = GraveAccent;
+layers = (
+{
+components = (
+{
+name = CombGrave;
+transform = "{1, 0, 0, 1, 940, 0}";
+}
+);
+layerId = master01;
+width = 580;
+},
+{
+anchors = (
+{
+name = U;
+position = "{500, 1635}";
+}
+);
+layerId = master02;
+paths = (
+{
+closed = 1;
+nodes = (
+"400 1200 LINE",
+"640 1200 LINE",
+"350 1600 LINE",
+"0 1600 LINE"
+);
+}
+);
+width = 640;
+}
+);
+unicode = 0060;
+},
+{
+glyphname = LtnSmA;
+layers = (
+{
+anchors = (
+{
+name = H;
+position = "{540, 0}";
+},
+{
+name = L;
+position = "{540, -100}";
+},
+{
+name = O;
+position = "{1125, 0}";
+},
+{
+name = R;
+position = "{1120, 1000}";
+},
+{
+name = U;
+position = "{540, 1100}";
+}
+);
+layerId = master01;
+paths = (
+{
+closed = 1;
+nodes = (
+"950 919 OFFCURVE",
+"800 1040 OFFCURVE",
+"570 1040 CURVE SMOOTH",
+"418 1040 OFFCURVE",
+"312 994 OFFCURVE",
+"209 950 CURVE",
+"203 907 OFFCURVE",
+"200 799 OFFCURVE",
+"199 755 CURVE",
+"316 837 OFFCURVE",
+"419 880 OFFCURVE",
+"525 880 CURVE SMOOTH",
+"675 880 OFFCURVE",
+"765 831 OFFCURVE",
+"765 710 CURVE SMOOTH",
+"765 635 LINE",
+"724 632 OFFCURVE",
+"564 617 OFFCURVE",
+"495 610 CURVE SMOOTH",
+"186 580 OFFCURVE",
+"95 407 OFFCURVE",
+"95 255 CURVE SMOOTH",
+"95 107 OFFCURVE",
+"232 -25 OFFCURVE",
+"420 -25 CURVE SMOOTH",
+"544 -25 OFFCURVE",
+"677 29 OFFCURVE",
+"795 155 CURVE",
+"809 91 OFFCURVE",
+"833 32 OFFCURVE",
+"845 0 CURVE",
+"1025 0 LINE",
+"981 112 OFFCURVE",
+"950 226 OFFCURVE",
+"950 370 CURVE",
+"950 760 LINE"
+);
+},
+{
+closed = 1;
+nodes = (
+"644 164 OFFCURVE",
+"552 140 OFFCURVE",
+"450 140 CURVE SMOOTH",
+"340 140 OFFCURVE",
+"275 191 OFFCURVE",
+"275 280 CURVE SMOOTH",
+"275 372 OFFCURVE",
+"335 450 OFFCURVE",
+"505 470 CURVE SMOOTH",
+"568 478 OFFCURVE",
+"715 493 OFFCURVE",
+"765 495 CURVE",
+"765 325 LINE"
+);
+}
+);
+width = 1120;
+},
+{
+anchors = (
+{
+name = H;
+position = "{985, 0}";
+},
+{
+name = L;
+position = "{610, -100}";
+},
+{
+name = O;
+position = "{1185, 0}";
+},
+{
+name = R;
+position = "{1145, 1000}";
+},
+{
+name = U;
+position = "{610, 1100}";
+}
+);
+layerId = master02;
+paths = (
+{
+closed = 1;
+nodes = (
+"1078 112 OFFCURVE",
+"1050 226 OFFCURVE",
+"1050 370 CURVE",
+"1050 760 LINE",
+"1050 919 OFFCURVE",
+"877 1040 OFFCURVE",
+"615 1040 CURVE SMOOTH",
+"446 1040 OFFCURVE",
+"330 994 OFFCURVE",
+"216 950 CURVE",
+"210 868 OFFCURVE",
+"207 735 OFFCURVE",
+"206 691 CURVE",
+"323 773 OFFCURVE",
+"424 816 OFFCURVE",
+"530 816 CURVE SMOOTH",
+"680 816 OFFCURVE",
+"770 785 OFFCURVE",
+"770 710 CURVE SMOOTH",
+"770 660 LINE",
+"729 659 OFFCURVE",
+"569 649 OFFCURVE",
+"500 642 CURVE SMOOTH",
+"191 612 OFFCURVE",
+"100 438 OFFCURVE",
+"100 285 CURVE SMOOTH",
+"100 121 OFFCURVE",
+"245 -25 OFFCURVE",
+"445 -25 CURVE SMOOTH",
+"562 -25 OFFCURVE",
+"688 23 OFFCURVE",
+"800 135 CURVE",
+"814 79 OFFCURVE",
+"838 28 OFFCURVE",
+"850 0 CURVE",
+"1120 0 LINE"
+);
+},
+{
+closed = 1;
+nodes = (
+"674 225 OFFCURVE",
+"600 205 OFFCURVE",
+"518 205 CURVE SMOOTH",
+"436 205 OFFCURVE",
+"380 256 OFFCURVE",
+"380 320 CURVE SMOOTH",
+"380 386 OFFCURVE",
+"422 442 OFFCURVE",
+"560 457 CURVE SMOOTH",
+"611 463 OFFCURVE",
+"730 474 OFFCURVE",
+"770 475 CURVE",
+"770 355 LINE"
+);
+}
+);
+width = 1205;
+}
+);
+note = "\012 \012 \012 \012 \012 GlyphNote A\012 \012 \012 \012 \012 ";
+unicode = 0061;
+},
+{
+glyphname = LtnSmB;
+layers = (
+{
+anchors = (
+{
+name = H;
+position = "{590, 0}";
+},
+{
+name = L;
+position = "{590, -100}";
+},
+{
+name = R;
+position = "{1155, 1000}";
+},
+{
+name = U;
+position = "{590, 1635}";
+}
+);
+layerId = master01;
+paths = (
+{
+closed = 1;
+nodes = (
+"145 1488 OFFCURVE",
+"145 1273 OFFCURVE",
+"145 1130 CURVE SMOOTH",
+"145 936 OFFCURVE",
+"145 228 OFFCURVE",
+"145 65 CURVE",
+"272 26 OFFCURVE",
+"413 -25 OFFCURVE",
+"575 -25 CURVE SMOOTH",
+"870 -25 OFFCURVE",
+"1060 197 OFFCURVE",
+"1060 540 CURVE SMOOTH",
+"1060 832 OFFCURVE",
+"917 1040 OFFCURVE",
+"715 1040 CURVE SMOOTH",
+"547 1040 OFFCURVE",
+"423 947 OFFCURVE",
+"330 825 CURVE",
+"330 916 OFFCURVE",
+"330 1600 OFFCURVE",
+"330 1600 CURVE",
+"130 1600 LINE"
+);
+},
+{
+closed = 1;
+nodes = (
+"398 751 OFFCURVE",
+"531 865 OFFCURVE",
+"655 865 CURVE SMOOTH",
+"799 865 OFFCURVE",
+"880 727 OFFCURVE",
+"880 505 CURVE SMOOTH",
+"880 280 OFFCURVE",
+"752 130 OFFCURVE",
+"575 130 CURVE SMOOTH",
+"489 130 OFFCURVE",
+"428 144 OFFCURVE",
+"330 185 CURVE",
+"330 585 LINE"
+);
+}
+);
+width = 1155;
+},
+{
+anchors = (
+{
+name = H;
+position = "{610, 0}";
+},
+{
+name = L;
+position = "{610, -100}";
+},
+{
+name = R;
+position = "{1215, 1000}";
+},
+{
+name = U;
+position = "{610, 1635}";
+}
+);
+layerId = master02;
+paths = (
+{
+closed = 1;
+nodes = (
+"135 1488 OFFCURVE",
+"135 1273 OFFCURVE",
+"135 1130 CURVE SMOOTH",
+"135 936 OFFCURVE",
+"135 228 OFFCURVE",
+"135 65 CURVE",
+"286 26 OFFCURVE",
+"457 -25 OFFCURVE",
+"650 -25 CURVE SMOOTH",
+"939 -25 OFFCURVE",
+"1125 197 OFFCURVE",
+"1125 540 CURVE SMOOTH",
+"1125 832 OFFCURVE",
+"986 1040 OFFCURVE",
+"789 1040 CURVE SMOOTH",
+"626 1040 OFFCURVE",
+"505 956 OFFCURVE",
+"415 845 CURVE",
+"415 934 OFFCURVE",
+"415 1600 OFFCURVE",
+"415 1600 CURVE",
+"120 1600 LINE"
+);
+},
+{
+closed = 1;
+nodes = (
+"471 709 OFFCURVE",
+"580 795 OFFCURVE",
+"683 795 CURVE SMOOTH",
+"793 795 OFFCURVE",
+"855 684 OFFCURVE",
+"855 505 CURVE SMOOTH",
+"855 317 OFFCURVE",
+"750 190 OFFCURVE",
+"605 190 CURVE SMOOTH",
+"538 190 OFFCURVE",
+"492 204 OFFCURVE",
+"415 240 CURVE",
+"415 585 LINE"
+);
+}
+);
+width = 1215;
+}
+);
+unicode = 0062;
+},
+{
+glyphname = LtnSmC;
+layers = (
+{
+anchors = (
+{
+name = H;
+position = "{580, 0}";
+},
+{
+name = L;
+position = "{580, -100}";
+},
+{
+name = R;
+position = "{1020, 1000}";
+},
+{
+name = U;
+position = "{570, 1100}";
+}
+);
+layerId = master01;
+paths = (
+{
+closed = 1;
+nodes = (
+"818 183 OFFCURVE",
+"720 140 OFFCURVE",
+"600 140 CURVE SMOOTH",
+"406 140 OFFCURVE",
+"285 285 OFFCURVE",
+"285 500 CURVE SMOOTH",
+"285 736 OFFCURVE",
+"422 875 OFFCURVE",
+"600 875 CURVE SMOOTH",
+"703 875 OFFCURVE",
+"790 841 OFFCURVE",
+"880 775 CURVE",
+"915 955 LINE",
+"842 1005 OFFCURVE",
+"748 1040 OFFCURVE",
+"615 1040 CURVE SMOOTH",
+"297 1040 OFFCURVE",
+"95 792 OFFCURVE",
+"95 490 CURVE SMOOTH",
+"95 171 OFFCURVE",
+"312 -25 OFFCURVE",
+"580 -25 CURVE SMOOTH",
+"730 -25 OFFCURVE",
+"824 9 OFFCURVE",
+"925 85 CURVE",
+"905 260 LINE"
+);
+}
+);
+width = 1020;
+},
+{
+anchors = (
+{
+name = H;
+position = "{555, 0}";
+},
+{
+name = L;
+position = "{575, -100}";
+},
+{
+name = R;
+position = "{1020, 1000}";
+},
+{
+name = U;
+position = "{575, 1100}";
+}
+);
+layerId = master02;
+paths = (
+{
+closed = 1;
+nodes = (
+"849 1007 OFFCURVE",
+"744 1040 OFFCURVE",
+"612 1040 CURVE SMOOTH",
+"295 1040 OFFCURVE",
+"90 802 OFFCURVE",
+"90 490 CURVE SMOOTH",
+"90 161 OFFCURVE",
+"309 -25 OFFCURVE",
+"578 -25 CURVE SMOOTH",
+"727 -25 OFFCURVE",
+"831 8 OFFCURVE",
+"932 70 CURVE",
+"902 314 LINE",
+"815 245 OFFCURVE",
+"737 205 OFFCURVE",
+"617 205 CURVE SMOOTH",
+"467 205 OFFCURVE",
+"370 324 OFFCURVE",
+"370 500 CURVE SMOOTH",
+"370 694 OFFCURVE",
+"478 810 OFFCURVE",
+"617 810 CURVE SMOOTH",
+"720 810 OFFCURVE",
+"788 779 OFFCURVE",
+"878 717 CURVE",
+"922 969 LINE"
+);
+}
+);
+width = 1022;
+}
+);
+unicode = 0063;
+},
+{
+glyphname = LtnSmD;
+layers = (
+{
+anchors = (
+{
+name = H;
+position = "{605, 0}";
+},
+{
+name = L;
+position = "{605, -100}";
+},
+{
+name = R;
+position = "{1190, 1000}";
+},
+{
+name = U;
+position = "{605, 1635}";
+}
+);
+layerId = master01;
+paths = (
+{
+closed = 1;
+nodes = (
+"820 1600 LINE",
+"839 1516 OFFCURVE",
+"845 1395 OFFCURVE",
+"845 1235 CURVE",
+"845 955 LINE",
+"767 999 OFFCURVE",
+"665 1040 OFFCURVE",
+"580 1040 CURVE SMOOTH",
+"312 1040 OFFCURVE",
+"105 814 OFFCURVE",
+"105 460 CURVE SMOOTH",
+"105 167 OFFCURVE",
+"261 -25 OFFCURVE",
+"505 -25 CURVE SMOOTH",
+"652 -25 OFFCURVE",
+"775 50 OFFCURVE",
+"870 185 CURVE",
+"887 111 OFFCURVE",
+"910 34 OFFCURVE",
+"925 0 CURVE",
+"1105 0 LINE",
+"1062 112 OFFCURVE",
+"1030 278 OFFCURVE",
+"1030 530 CURVE",
+"1030 1600 LINE"
+);
+},
+{
+closed = 1;
+nodes = (
+"790 268 OFFCURVE",
+"662 135 OFFCURVE",
+"540 135 CURVE SMOOTH",
+"366 135 OFFCURVE",
+"290 258 OFFCURVE",
+"290 490 CURVE SMOOTH",
+"290 727 OFFCURVE",
+"429 870 OFFCURVE",
+"580 870 CURVE SMOOTH",
+"681 870 OFFCURVE",
+"746 848 OFFCURVE",
+"845 795 CURVE",
+"845 400 LINE"
+);
+}
+);
+width = 1190;
+},
+{
+anchors = (
+{
+name = H;
+position = "{595, 0}";
+},
+{
+name = L;
+position = "{595, -100}";
+},
+{
+name = R;
+position = "{1285, 1000}";
+},
+{
+name = U;
+position = "{610, 1635}";
+}
+);
+layerId = master02;
+paths = (
+{
+closed = 1;
+nodes = (
+"810 1600 LINE",
+"829 1516 OFFCURVE",
+"835 1395 OFFCURVE",
+"835 1235 CURVE SMOOTH",
+"835 955 LINE",
+"763 999 OFFCURVE",
+"669 1040 OFFCURVE",
+"590 1040 CURVE SMOOTH",
+"319 1040 OFFCURVE",
+"100 814 OFFCURVE",
+"100 460 CURVE SMOOTH",
+"100 167 OFFCURVE",
+"268 -25 OFFCURVE",
+"515 -25 CURVE SMOOTH",
+"654 -25 OFFCURVE",
+"770 47 OFFCURVE",
+"860 175 CURVE",
+"877 105 OFFCURVE",
+"900 32 OFFCURVE",
+"915 0 CURVE",
+"1190 0 LINE",
+"1147 112 OFFCURVE",
+"1115 278 OFFCURVE",
+"1115 530 CURVE SMOOTH",
+"1115 1600 LINE"
+);
+},
+{
+closed = 1;
+nodes = (
+"787 300 OFFCURVE",
+"676 200 OFFCURVE",
+"570 200 CURVE SMOOTH",
+"443 200 OFFCURVE",
+"380 300 OFFCURVE",
+"380 490 CURVE SMOOTH",
+"380 685 OFFCURVE",
+"485 800 OFFCURVE",
+"590 800 CURVE SMOOTH",
+"683 800 OFFCURVE",
+"743 783 OFFCURVE",
+"835 738 CURVE",
+"835 400 LINE"
+);
+}
+);
+width = 1265;
+}
+);
+unicode = 0064;
+},
+{
+glyphname = LtnSmE;
+layers = (
+{
+anchors = (
+{
+name = H;
+position = "{545, 0}";
+},
+{
+name = L;
+position = "{569, -100}";
+},
+{
+name = O;
+position = "{925, 0}";
+},
+{
+name = R;
+position = "{1095, 1000}";
+},
+{
+name = U;
+position = "{569, 1100}";
+}
+);
+layerId = master01;
+paths = (
+{
+closed = 1;
+nodes = (
+"990 503 OFFCURVE",
+"990 545 OFFCURVE",
+"990 563 CURVE SMOOTH",
+"990 788 OFFCURVE",
+"905 1040 OFFCURVE",
+"575 1040 CURVE SMOOTH",
+"279 1040 OFFCURVE",
+"95 826 OFFCURVE",
+"95 495 CURVE SMOOTH",
+"95 155 OFFCURVE",
+"320 -25 OFFCURVE",
+"575 -25 CURVE SMOOTH",
+"729 -25 OFFCURVE",
+"853 2 OFFCURVE",
+"995 75 CURVE",
+"975 240 LINE",
+"853 166 OFFCURVE",
+"729 140 OFFCURVE",
+"600 140 CURVE SMOOTH",
+"414 140 OFFCURVE",
+"280 258 OFFCURVE",
+"280 505 CURVE SMOOTH",
+"280 770 OFFCURVE",
+"385 890 OFFCURVE",
+"560 890 CURVE SMOOTH",
+"705 890 OFFCURVE",
+"810 797 OFFCURVE",
+"810 625 CURVE",
+"245 625 LINE",
+"245 485 LINE",
+"989 485 LINE"
+);
+}
+);
+width = 1095;
+},
+{
+anchors = (
+{
+name = H;
+position = "{569, 0}";
+},
+{
+name = L;
+position = "{589, -100}";
+},
+{
+name = O;
+position = "{900, 0}";
+},
+{
+name = R;
+position = "{1130, 1000}";
+},
+{
+name = U;
+position = "{537, 1100}";
+}
+);
+layerId = master02;
+paths = (
+{
+closed = 1;
+nodes = (
+"1010 469 OFFCURVE",
+"1009 513 OFFCURVE",
+"1009 532 CURVE SMOOTH",
+"1009 782 OFFCURVE",
+"924 1040 OFFCURVE",
+"589 1040 CURVE SMOOTH",
+"281 1040 OFFCURVE",
+"90 826 OFFCURVE",
+"90 495 CURVE SMOOTH",
+"90 155 OFFCURVE",
+"324 -25 OFFCURVE",
+"589 -25 CURVE SMOOTH",
+"745 -25 OFFCURVE",
+"871 2 OFFCURVE",
+"1015 75 CURVE",
+"994 306 LINE",
+"870 232 OFFCURVE",
+"745 205 OFFCURVE",
+"614 205 CURVE SMOOTH",
+"448 205 OFFCURVE",
+"362 293 OFFCURVE",
+"362 505 CURVE SMOOTH",
+"362 739 OFFCURVE",
+"431 830 OFFCURVE",
+"575 830 CURVE SMOOTH",
+"693 830 OFFCURVE",
+"755 770 OFFCURVE",
+"755 630 CURVE",
+"242 630 LINE",
+"242 450 LINE",
+"1010 450 LINE"
+);
+}
+);
+width = 1110;
+}
+);
+unicode = 0065;
+},
+{
+glyphname = LtnSmF;
+layers = (
+{
+anchors = (
+{
+name = H;
+position = "{370, 0}";
+},
+{
+name = L;
+position = "{335, -100}";
+},
+{
+name = U;
+position = "{560, 1635}";
+}
+);
+layerId = master01;
+paths = (
+{
+closed = 1;
+nodes = (
+"240 850 LINE",
+"240 0 LINE",
+"455 0 LINE",
+"433 105 OFFCURVE",
+"425 300 OFFCURVE",
+"425 494 CURVE SMOOTH",
+"425 850 LINE",
+"695 850 LINE",
+"695 995 LINE",
+"425 995 LINE",
+"425 1210 LINE SMOOTH",
+"425 1381 OFFCURVE",
+"481 1450 OFFCURVE",
+"585 1450 CURVE SMOOTH",
+"643 1450 OFFCURVE",
+"710 1427 OFFCURVE",
+"760 1390 CURVE",
+"805 1550 LINE",
+"743 1594 OFFCURVE",
+"663 1620 OFFCURVE",
+"585 1620 CURVE SMOOTH",
+"369 1620 OFFCURVE",
+"240 1470 OFFCURVE",
+"240 1170 CURVE SMOOTH",
+"240 995 LINE",
+"40 995 LINE",
+"40 850 LINE"
+);
+}
+);
+width = 750;
+},
+{
+anchors = (
+{
+name = H;
+position = "{380, 0}";
+},
+{
+name = L;
+position = "{400, -100}";
+},
+{
+name = U;
+position = "{600, 1635}";
+}
+);
+layerId = master02;
+paths = (
+{
+closed = 1;
+nodes = (
+"230 805 LINE",
+"230 0 LINE",
+"540 0 LINE",
+"518 105 OFFCURVE",
+"510 300 OFFCURVE",
+"510 494 CURVE SMOOTH",
+"510 805 LINE",
+"765 805 LINE",
+"765 1005 LINE",
+"510 1005 LINE",
+"510 1159 LINE SMOOTH",
+"510 1322 OFFCURVE",
+"552 1387 OFFCURVE",
+"648 1387 CURVE SMOOTH",
+"697 1387 OFFCURVE",
+"765 1362 OFFCURVE",
+"808 1322 CURVE",
+"865 1550 LINE",
+"806 1588 OFFCURVE",
+"699 1620 OFFCURVE",
+"625 1620 CURVE SMOOTH",
+"378 1620 OFFCURVE",
+"230 1470 OFFCURVE",
+"230 1170 CURVE SMOOTH",
+"230 1005 LINE",
+"30 1005 LINE",
+"30 805 LINE"
+);
+}
+);
+width = 800;
+}
+);
+unicode = 0066;
+},
+{
+glyphname = LtnSmG;
+layers = (
+{
+anchors = (
+{
+name = H;
+position = "{545, -432}";
+},
+{
+name = L;
+position = "{545, -535}";
+},
+{
+name = R;
+position = "{1095, 1000}";
+},
+{
+name = U;
+position = "{515, 1100}";
+}
+);
+layerId = master01;
+paths = (
+{
+closed = 1;
+nodes = (
+"234 357 OFFCURVE",
+"180 275 OFFCURVE",
+"180 215 CURVE SMOOTH",
+"180 121 OFFCURVE",
+"263 27 OFFCURVE",
+"545 -5 CURVE SMOOTH",
+"805 -35 OFFCURVE",
+"880 -90 OFFCURVE",
+"880 -170 CURVE SMOOTH",
+"880 -255 OFFCURVE",
+"731 -360 OFFCURVE",
+"550 -360 CURVE SMOOTH",
+"323 -360 OFFCURVE",
+"215 -261 OFFCURVE",
+"215 -180 CURVE SMOOTH",
+"215 -121 OFFCURVE",
+"244 -56 OFFCURVE",
+"465 20 CURVE",
+"459 49 OFFCURVE",
+"290 75 OFFCURVE",
+"290 75 CURVE",
+"113 2 OFFCURVE",
+"30 -89 OFFCURVE",
+"30 -200 CURVE SMOOTH",
+"30 -409 OFFCURVE",
+"303 -505 OFFCURVE",
+"535 -505 CURVE SMOOTH",
+"777 -505 OFFCURVE",
+"1065 -375 OFFCURVE",
+"1065 -160 CURVE SMOOTH",
+"1065 -8 OFFCURVE",
+"967 90 OFFCURVE",
+"670 125 CURVE SMOOTH",
+"410 156 OFFCURVE",
+"345 198 OFFCURVE",
+"345 235 CURVE SMOOTH",
+"345 271 OFFCURVE",
+"384 316 OFFCURVE",
+"500 350 CURVE",
+"330 395 LINE"
+);
+},
+{
+closed = 1;
+nodes = (
+"951 1033 OFFCURVE",
+"819 997 OFFCURVE",
+"730 940 CURVE",
+"795 825 LINE",
+"887 863 OFFCURVE",
+"967 878 OFFCURVE",
+"1040 880 CURVE",
+"1050 1040 LINE"
+);
+},
+{
+closed = 1;
+nodes = (
+"115 476 OFFCURVE",
+"289 325 OFFCURVE",
+"515 325 CURVE SMOOTH",
+"742 325 OFFCURVE",
+"915 476 OFFCURVE",
+"915 680 CURVE SMOOTH",
+"915 884 OFFCURVE",
+"742 1040 OFFCURVE",
+"515 1040 CURVE SMOOTH",
+"289 1040 OFFCURVE",
+"115 884 OFFCURVE",
+"115 680 CURVE SMOOTH"
+);
+},
+{
+closed = 1;
+nodes = (
+"285 803 OFFCURVE",
+"382 895 OFFCURVE",
+"515 895 CURVE SMOOTH",
+"649 895 OFFCURVE",
+"745 803 OFFCURVE",
+"745 680 CURVE SMOOTH",
+"745 557 OFFCURVE",
+"649 465 OFFCURVE",
+"515 465 CURVE SMOOTH",
+"382 465 OFFCURVE",
+"285 557 OFFCURVE",
+"285 680 CURVE SMOOTH"
+);
+}
+);
+width = 1095;
+},
+{
+anchors = (
+{
+name = H;
+position = "{597, -465}";
+},
+{
+name = L;
+position = "{597, -535}";
+},
+{
+name = R;
+position = "{1187, 1000}";
+},
+{
+name = U;
+position = "{567, 1100}";
+}
+);
+layerId = master02;
+paths = (
+{
+closed = 1;
+nodes = (
+"256 357 OFFCURVE",
+"202 275 OFFCURVE",
+"202 215 CURVE SMOOTH",
+"202 113 OFFCURVE",
+"280 12 OFFCURVE",
+"547 -23 CURVE SMOOTH",
+"797 -50 OFFCURVE",
+"870 -99 OFFCURVE",
+"870 -170 CURVE SMOOTH",
+"870 -229 OFFCURVE",
+"748 -302 OFFCURVE",
+"602 -302 CURVE SMOOTH",
+"418 -302 OFFCURVE",
+"330 -235 OFFCURVE",
+"330 -180 CURVE SMOOTH",
+"330 -121 OFFCURVE",
+"357 -56 OFFCURVE",
+"562 20 CURVE",
+"554 49 OFFCURVE",
+"322 75 OFFCURVE",
+"322 75 CURVE",
+"138 2 OFFCURVE",
+"50 -89 OFFCURVE",
+"50 -200 CURVE SMOOTH",
+"50 -409 OFFCURVE",
+"341 -505 OFFCURVE",
+"587 -505 CURVE SMOOTH",
+"843 -505 OFFCURVE",
+"1150 -375 OFFCURVE",
+"1150 -160 CURVE SMOOTH",
+"1150 13 OFFCURVE",
+"1049 125 OFFCURVE",
+"752 165 CURVE SMOOTH",
+"497 191 OFFCURVE",
+"433 216 OFFCURVE",
+"433 255 CURVE SMOOTH",
+"433 285 OFFCURVE",
+"472 322 OFFCURVE",
+"588 350 CURVE",
+"352 395 LINE"
+);
+},
+{
+closed = 1;
+nodes = (
+"1003 1033 OFFCURVE",
+"871 997 OFFCURVE",
+"782 940 CURVE",
+"847 770 LINE",
+"939 808 OFFCURVE",
+"1019 823 OFFCURVE",
+"1092 825 CURVE",
+"1102 1040 LINE"
+);
+},
+{
+closed = 1;
+nodes = (
+"122 455 OFFCURVE",
+"316 305 OFFCURVE",
+"567 305 CURVE SMOOTH",
+"820 305 OFFCURVE",
+"1012 465 OFFCURVE",
+"1012 680 CURVE SMOOTH",
+"1012 884 OFFCURVE",
+"820 1040 OFFCURVE",
+"567 1040 CURVE SMOOTH",
+"316 1040 OFFCURVE",
+"122 874 OFFCURVE",
+"122 670 CURVE SMOOTH"
+);
+},
+{
+closed = 1;
+nodes = (
+"377 770 OFFCURVE",
+"457 847 OFFCURVE",
+"567 847 CURVE SMOOTH",
+"678 847 OFFCURVE",
+"757 770 OFFCURVE",
+"757 680 CURVE SMOOTH",
+"757 578 OFFCURVE",
+"678 501 OFFCURVE",
+"567 501 CURVE SMOOTH",
+"457 501 OFFCURVE",
+"377 578 OFFCURVE",
+"377 680 CURVE SMOOTH"
+);
+}
+);
+width = 1170;
+}
+);
+unicode = 0067;
+},
+{
+glyphname = LtnSmH;
+layers = (
+{
+anchors = (
+{
+name = H;
+position = "{250, 0}";
+},
+{
+name = L;
+position = "{585, -100}";
+},
+{
+name = U;
+position = "{585, 1635}";
+}
+);
+layerId = master01;
+paths = (
+{
+closed = 1;
+nodes = (
+"1040 0 OFFCURVE",
+"1040 459 OFFCURVE",
+"1040 625 CURVE SMOOTH",
+"1040 900 OFFCURVE",
+"923 1040 OFFCURVE",
+"710 1040 CURVE SMOOTH",
+"570 1040 OFFCURVE",
+"428 969 OFFCURVE",
+"330 830 CURVE",
+"330 877 OFFCURVE",
+"330 1600 OFFCURVE",
+"330 1600 CURVE",
+"130 1600 LINE",
+"145 1514 OFFCURVE",
+"145 1345 OFFCURVE",
+"145 1130 CURVE SMOOTH",
+"145 935 OFFCURVE",
+"145 0 OFFCURVE",
+"145 0 CURVE",
+"330 0 LINE",
+"330 580 LINE",
+"374 716 OFFCURVE",
+"511 865 OFFCURVE",
+"655 865 CURVE SMOOTH",
+"789 865 OFFCURVE",
+"855 800 OFFCURVE",
+"855 550 CURVE SMOOTH",
+"855 413 OFFCURVE",
+"855 0 OFFCURVE",
+"855 0 CURVE",
+"1040 0 LINE"
+);
+}
+);
+width = 1175;
+},
+{
+anchors = (
+{
+name = H;
+position = "{280, 0}";
+},
+{
+name = L;
+position = "{620, -100}";
+},
+{
+name = U;
+position = "{620, 1635}";
+}
+);
+layerId = master02;
+paths = (
+{
+closed = 1;
+nodes = (
+"450 683 OFFCURVE",
+"560 795 OFFCURVE",
+"675 795 CURVE SMOOTH",
+"782 795 OFFCURVE",
+"830 744 OFFCURVE",
+"830 550 CURVE SMOOTH",
+"830 413 OFFCURVE",
+"830 0 OFFCURVE",
+"830 0 CURVE",
+"1110 0 LINE",
+"1110 0 OFFCURVE",
+"1110 459 OFFCURVE",
+"1110 625 CURVE SMOOTH",
+"1110 900 OFFCURVE",
+"1008 1040 OFFCURVE",
+"805 1040 CURVE SMOOTH",
+"662 1040 OFFCURVE",
+"513 976 OFFCURVE",
+"415 850 CURVE",
+"415 894 OFFCURVE",
+"415 1600 OFFCURVE",
+"415 1600 CURVE",
+"120 1600 LINE",
+"135 1514 OFFCURVE",
+"135 1345 OFFCURVE",
+"135 1130 CURVE SMOOTH",
+"135 935 OFFCURVE",
+"135 0 OFFCURVE",
+"135 0 CURVE",
+"415 0 LINE",
+"415 580 LINE"
+);
+}
+);
+width = 1235;
+}
+);
+unicode = 0068;
+},
+{
+glyphname = LtnSmI;
+layers = (
+{
+anchors = (
+{
+name = H;
+position = "{282, 0}";
+},
+{
+name = L;
+position = "{285, -100}";
+},
+{
+name = O;
+position = "{500, 0}";
+},
+{
+name = R;
+position = "{555, 1000}";
+},
+{
+name = U;
+position = "{282, 1100}";
+}
+);
+layerId = master01;
+paths = (
+{
+closed = 1;
+nodes = (
+"175 1020 LINE",
+"188 915 OFFCURVE",
+"190 725 OFFCURVE",
+"190 530 CURVE SMOOTH",
+"190 336 OFFCURVE",
+"190 0 OFFCURVE",
+"190 0 CURVE",
+"395 0 LINE",
+"382 107 OFFCURVE",
+"375 346 OFFCURVE",
+"375 475 CURVE SMOOTH",
+"375 1020 LINE"
+);
+},
+{
+closed = 1;
+nodes = (
+"155 1271 OFFCURVE",
+"206 1210 OFFCURVE",
+"280 1210 CURVE SMOOTH",
+"355 1210 OFFCURVE",
+"410 1271 OFFCURVE",
+"410 1345 CURVE SMOOTH",
+"410 1419 OFFCURVE",
+"355 1480 OFFCURVE",
+"280 1480 CURVE SMOOTH",
+"206 1480 OFFCURVE",
+"155 1419 OFFCURVE",
+"155 1345 CURVE SMOOTH"
+);
+}
+);
+width = 565;
+},
+{
+anchors = (
+{
+name = H;
+position = "{320, 0}";
+},
+{
+name = L;
+position = "{320, -100}";
+},
+{
+name = O;
+position = "{580, 0}";
+},
+{
+name = R;
+position = "{640, 1000}";
+},
+{
+name = U;
+position = "{320, 1100}";
+}
+);
+layerId = master02;
+paths = (
+{
+closed = 1;
+nodes = (
+"178 915 OFFCURVE",
+"180 725 OFFCURVE",
+"180 530 CURVE SMOOTH",
+"180 336 OFFCURVE",
+"180 0 OFFCURVE",
+"180 0 CURVE",
+"480 0 LINE",
+"467 107 OFFCURVE",
+"460 346 OFFCURVE",
+"460 475 CURVE SMOOTH",
+"460 558 OFFCURVE",
+"460 1020 OFFCURVE",
+"460 1020 CURVE",
+"165 1020 LINE"
+);
+},
+{
+closed = 1;
+nodes = (
+"145 1281 OFFCURVE",
+"219 1210 OFFCURVE",
+"320 1210 CURVE SMOOTH",
+"422 1210 OFFCURVE",
+"495 1281 OFFCURVE",
+"495 1385 CURVE SMOOTH",
+"495 1487 OFFCURVE",
+"422 1560 OFFCURVE",
+"320 1560 CURVE SMOOTH",
+"219 1560 OFFCURVE",
+"145 1487 OFFCURVE",
+"145 1385 CURVE SMOOTH"
+);
+}
+);
+width = 640;
+}
+);
+unicode = 0069;
+},
+{
+glyphname = LtnSmJ;
+layers = (
+{
+anchors = (
+{
+name = L;
+position = "{125, -500}";
+},
+{
+name = U;
+position = "{313, 1100}";
+}
+);
+layerId = master01;
+paths = (
+{
+closed = 1;
+nodes = (
+"205 1020 LINE",
+"218 915 OFFCURVE",
+"220 725 OFFCURVE",
+"220 530 CURVE",
+"220 -25 LINE",
+"220 -222 OFFCURVE",
+"147 -300 OFFCURVE",
+"40 -300 CURVE SMOOTH",
+"-16 -300 OFFCURVE",
+"-111 -273 OFFCURVE",
+"-155 -240 CURVE",
+"-190 -405 LINE",
+"-130 -446 OFFCURVE",
+"-26 -470 OFFCURVE",
+"30 -470 CURVE SMOOTH",
+"258 -470 OFFCURVE",
+"405 -348 OFFCURVE",
+"405 25 CURVE SMOOTH",
+"405 1020 LINE"
+);
+},
+{
+closed = 1;
+nodes = (
+"185 1271 OFFCURVE",
+"236 1210 OFFCURVE",
+"310 1210 CURVE SMOOTH",
+"385 1210 OFFCURVE",
+"440 1271 OFFCURVE",
+"440 1345 CURVE SMOOTH",
+"440 1419 OFFCURVE",
+"385 1480 OFFCURVE",
+"310 1480 CURVE SMOOTH",
+"236 1480 OFFCURVE",
+"185 1419 OFFCURVE",
+"185 1345 CURVE SMOOTH"
+);
+}
+);
+width = 595;
+},
+{
+anchors = (
+{
+name = L;
+position = "{140, -500}";
+},
+{
+name = U;
+position = "{355, 1100}";
+}
+);
+layerId = master02;
+paths = (
+{
+closed = 1;
+nodes = (
+"185 1281 OFFCURVE",
+"259 1210 OFFCURVE",
+"360 1210 CURVE SMOOTH",
+"462 1210 OFFCURVE",
+"535 1281 OFFCURVE",
+"535 1385 CURVE SMOOTH",
+"535 1487 OFFCURVE",
+"462 1560 OFFCURVE",
+"360 1560 CURVE SMOOTH",
+"259 1560 OFFCURVE",
+"185 1487 OFFCURVE",
+"185 1385 CURVE SMOOTH"
+);
+},
+{
+closed = 1;
+nodes = (
+"205 1020 LINE",
+"218 915 OFFCURVE",
+"220 725 OFFCURVE",
+"220 530 CURVE",
+"220 20 LINE",
+"220 -150 OFFCURVE",
+"165 -232 OFFCURVE",
+"48 -232 CURVE SMOOTH",
+"-20 -232 OFFCURVE",
+"-101 -195 OFFCURVE",
+"-145 -152 CURVE",
+"-190 -389 LINE",
+"-148 -421 OFFCURVE",
+"-37 -470 OFFCURVE",
+"56 -470 CURVE SMOOTH",
+"306 -470 OFFCURVE",
+"500 -348 OFFCURVE",
+"500 25 CURVE SMOOTH",
+"500 1020 LINE"
+);
+}
+);
+width = 670;
+}
+);
+unicode = 006A;
+},
+{
+glyphname = LtnSmK;
+layers = (
+{
+anchors = (
+{
+name = H;
+position = "{243, 0}";
+},
+{
+name = L;
+position = "{572, -100}";
+},
+{
+name = R;
+position = "{1035, 1000}";
+},
+{
+name = U;
+position = "{572, 1635}";
+}
+);
+guideLines = (
+{
+angle = 314;
+position = "{500, 774}";
+}
+);
+layerId = master01;
+paths = (
+{
+closed = 1;
+nodes = (
+"330 1600 LINE",
+"130 1600 LINE",
+"145 1514 OFFCURVE",
+"145 1345 OFFCURVE",
+"145 1130 CURVE SMOOTH",
+"145 934 OFFCURVE",
+"145 0 OFFCURVE",
+"145 0 CURVE",
+"330 0 LINE"
+);
+},
+{
+closed = 1;
+nodes = (
+"280 550 LINE",
+"436 524 LINE",
+"985 1020 LINE",
+"735 1020 LINE"
+);
+},
+{
+closed = 1;
+nodes = (
+"770 0 LINE",
+"1015 0 LINE",
+"410 660 LINE",
+"305 550 LINE"
+);
+}
+);
+width = 1035;
+},
+{
+anchors = (
+{
+name = H;
+position = "{940, 0}";
+},
+{
+name = L;
+position = "{585, -100}";
+},
+{
+name = R;
+position = "{1140, 1000}";
+},
+{
+name = U;
+position = "{595, 1635}";
+}
+);
+layerId = master02;
+paths = (
+{
+closed = 1;
+nodes = (
+"415 1600 LINE",
+"120 1600 LINE",
+"135 1514 OFFCURVE",
+"135 1345 OFFCURVE",
+"135 1130 CURVE SMOOTH",
+"135 934 OFFCURVE",
+"135 0 OFFCURVE",
+"135 0 CURVE",
+"415 0 LINE"
+);
+},
+{
+closed = 1;
+nodes = (
+"353 570 LINE",
+"572 528 LINE",
+"1098 1020 LINE",
+"723 1020 LINE"
+);
+},
+{
+closed = 1;
+nodes = (
+"761 0 LINE",
+"1128 0 LINE",
+"540 664 LINE",
+"350 570 LINE"
+);
+}
+);
+width = 1138;
+}
+);
+unicode = 006B;
+},
+{
+glyphname = LtnSmL;
+layers = (
+{
+anchors = (
+{
+name = H;
+position = "{290, 0}";
+},
+{
+name = L;
+position = "{290, -100}";
+},
+{
+name = R;
+position = "{550, 1000}";
+},
+{
+name = U;
+position = "{282, 1635}";
+}
+);
+guideLines = (
+{
+angle = 340;
+position = "{500, 874}";
+}
+);
+layerId = master01;
+paths = (
+{
+closed = 1;
+nodes = (
+"170 1600 LINE",
+"183 1485 OFFCURVE",
+"190 1324 OFFCURVE",
+"190 1130 CURVE",
+"190 0 LINE",
+"395 0 LINE",
+"382 109 OFFCURVE",
+"375 346 OFFCURVE",
+"375 475 CURVE SMOOTH",
+"375 1600 LINE"
+);
+}
+);
+width = 565;
+},
+{
+anchors = (
+{
+name = H;
+position = "{335, 0}";
+},
+{
+name = L;
+position = "{335, -100}";
+},
+{
+name = R;
+position = "{660, 1000}";
+},
+{
+name = U;
+position = "{320, 1635}";
+}
+);
+layerId = master02;
+paths = (
+{
+closed = 1;
+nodes = (
+"160 1600 LINE",
+"173 1485 OFFCURVE",
+"180 1324 OFFCURVE",
+"180 1130 CURVE SMOOTH",
+"180 0 LINE",
+"480 0 LINE",
+"467 109 OFFCURVE",
+"460 346 OFFCURVE",
+"460 475 CURVE SMOOTH",
+"460 1600 LINE"
+);
+}
+);
+width = 640;
+}
+);
+unicode = 006C;
+},
+{
+glyphname = LtnSmM;
+layers = (
+{
+anchors = (
+{
+name = H;
+position = "{1450, 0}";
+},
+{
+name = L;
+position = "{865, -100}";
+},
+{
+name = U;
+position = "{865, 1100}";
+}
+);
+layerId = master01;
+paths = (
+{
+closed = 1;
+nodes = (
+"1003 785 OFFCURVE",
+"1102 865 OFFCURVE",
+"1200 865 CURVE SMOOTH",
+"1312 865 OFFCURVE",
+"1345 808 OFFCURVE",
+"1345 550 CURVE SMOOTH",
+"1345 0 LINE",
+"1530 0 LINE",
+"1530 660 LINE SMOOTH",
+"1530 907 OFFCURVE",
+"1463 1040 OFFCURVE",
+"1260 1040 CURVE SMOOTH",
+"1155 1040 OFFCURVE",
+"1046 1007 OFFCURVE",
+"921 872 CURVE",
+"888 960 OFFCURVE",
+"806 1040 OFFCURVE",
+"675 1040 CURVE SMOOTH",
+"560 1040 OFFCURVE",
+"459 1006 OFFCURVE",
+"337 865 CURVE",
+"330 913 OFFCURVE",
+"320 978 OFFCURVE",
+"305 1020 CURVE",
+"125 1020 LINE",
+"146 951 OFFCURVE",
+"175 811 OFFCURVE",
+"175 615 CURVE SMOOTH",
+"175 0 LINE",
+"360 0 LINE",
+"360 660 LINE",
+"413 780 OFFCURVE",
+"517 865 OFFCURVE",
+"615 865 CURVE SMOOTH",
+"727 865 OFFCURVE",
+"760 818 OFFCURVE",
+"760 570 CURVE SMOOTH",
+"760 0 LINE",
+"945 0 LINE",
+"945 660 LINE"
+);
+}
+);
+width = 1685;
+},
+{
+anchors = (
+{
+name = H;
+position = "{890, 0}";
+},
+{
+name = L;
+position = "{890, -100}";
+},
+{
+name = U;
+position = "{890, 1100}";
+}
+);
+layerId = master02;
+paths = (
+{
+closed = 1;
+nodes = (
+"136 951 OFFCURVE",
+"165 811 OFFCURVE",
+"165 615 CURVE SMOOTH",
+"165 0 LINE",
+"445 0 LINE",
+"445 640 LINE",
+"484 731 OFFCURVE",
+"560 795 OFFCURVE",
+"635 795 CURVE SMOOTH",
+"723 795 OFFCURVE",
+"750 759 OFFCURVE",
+"750 570 CURVE SMOOTH",
+"750 0 LINE",
+"1030 0 LINE",
+"1030 660 LINE",
+"1073 742 OFFCURVE",
+"1147 795 OFFCURVE",
+"1220 795 CURVE SMOOTH",
+"1310 795 OFFCURVE",
+"1335 751 OFFCURVE",
+"1335 550 CURVE SMOOTH",
+"1335 0 LINE",
+"1615 0 LINE",
+"1615 660 LINE SMOOTH",
+"1615 907 OFFCURVE",
+"1548 1040 OFFCURVE",
+"1345 1040 CURVE SMOOTH",
+"1240 1040 OFFCURVE",
+"1131 1007 OFFCURVE",
+"1006 872 CURVE",
+"973 960 OFFCURVE",
+"891 1040 OFFCURVE",
+"760 1040 CURVE SMOOTH",
+"644 1040 OFFCURVE",
+"544 1008 OFFCURVE",
+"422 875 CURVE",
+"412 920 OFFCURVE",
+"397 981 OFFCURVE",
+"375 1020 CURVE",
+"115 1020 LINE"
+);
+}
+);
+width = 1760;
+}
+);
+unicode = 006D;
+},
+{
+glyphname = LtnSmN;
+layers = (
+{
+anchors = (
+{
+name = H;
+position = "{970, 0}";
+},
+{
+name = L;
+position = "{600, -100}";
+},
+{
+name = U;
+position = "{600, 1100}";
+}
+);
+layerId = master01;
+paths = (
+{
+closed = 1;
+nodes = (
+"1050 0 OFFCURVE",
+"1050 459 OFFCURVE",
+"1050 625 CURVE SMOOTH",
+"1050 900 OFFCURVE",
+"933 1040 OFFCURVE",
+"720 1040 CURVE SMOOTH",
+"579 1040 OFFCURVE",
+"452 977 OFFCURVE",
+"325 825 CURVE",
+"318 873 OFFCURVE",
+"300 978 OFFCURVE",
+"285 1020 CURVE",
+"105 1020 LINE",
+"127 951 OFFCURVE",
+"155 811 OFFCURVE",
+"155 615 CURVE SMOOTH",
+"155 420 OFFCURVE",
+"155 0 OFFCURVE",
+"155 0 CURVE",
+"340 0 LINE",
+"340 580 LINE",
+"384 716 OFFCURVE",
+"521 865 OFFCURVE",
+"665 865 CURVE SMOOTH",
+"800 865 OFFCURVE",
+"865 800 OFFCURVE",
+"865 550 CURVE SMOOTH",
+"865 413 OFFCURVE",
+"865 0 OFFCURVE",
+"865 0 CURVE",
+"1050 0 LINE"
+);
+}
+);
+width = 1185;
+},
+{
+anchors = (
+{
+name = H;
+position = "{620, 0}";
+},
+{
+name = L;
+position = "{620, -100}";
+},
+{
+name = U;
+position = "{620, 1100}";
+}
+);
+layerId = master02;
+paths = (
+{
+closed = 1;
+nodes = (
+"1120 0 OFFCURVE",
+"1120 459 OFFCURVE",
+"1120 625 CURVE SMOOTH",
+"1120 900 OFFCURVE",
+"998 1040 OFFCURVE",
+"795 1040 CURVE SMOOTH",
+"654 1040 OFFCURVE",
+"537 980 OFFCURVE",
+"410 835 CURVE",
+"403 881 OFFCURVE",
+"385 980 OFFCURVE",
+"370 1020 CURVE",
+"95 1020 LINE",
+"117 951 OFFCURVE",
+"145 811 OFFCURVE",
+"145 615 CURVE SMOOTH",
+"145 420 OFFCURVE",
+"145 0 OFFCURVE",
+"145 0 CURVE",
+"425 0 LINE",
+"425 580 LINE",
+"460 683 OFFCURVE",
+"570 795 OFFCURVE",
+"685 795 CURVE SMOOTH",
+"792 795 OFFCURVE",
+"840 734 OFFCURVE",
+"840 550 CURVE SMOOTH",
+"840 413 OFFCURVE",
+"840 0 OFFCURVE",
+"840 0 CURVE",
+"1120 0 LINE"
+);
+}
+);
+width = 1245;
+}
+);
+unicode = 006E;
+},
+{
+glyphname = LtnSmO;
+layers = (
+{
+anchors = (
+{
+name = H;
+position = "{570, 0}";
+},
+{
+name = L;
+position = "{570, -100}";
+},
+{
+name = O;
+position = "{835, 0}";
+},
+{
+name = R;
+position = "{1140, 1000}";
+},
+{
+name = U;
+position = "{570, 1100}";
+}
+);
+layerId = master01;
+paths = (
+{
+closed = 1;
+nodes = (
+"95 161 OFFCURVE",
+"286 -25 OFFCURVE",
+"560 -25 CURVE SMOOTH",
+"823 -25 OFFCURVE",
+"1045 161 OFFCURVE",
+"1045 505 CURVE SMOOTH",
+"1045 849 OFFCURVE",
+"855 1040 OFFCURVE",
+"580 1040 CURVE SMOOTH",
+"317 1040 OFFCURVE",
+"95 849 OFFCURVE",
+"95 505 CURVE SMOOTH"
+);
+},
+{
+closed = 1;
+nodes = (
+"280 739 OFFCURVE",
+"408 880 OFFCURVE",
+"570 880 CURVE SMOOTH",
+"742 880 OFFCURVE",
+"860 739 OFFCURVE",
+"860 505 CURVE SMOOTH",
+"860 272 OFFCURVE",
+"731 135 OFFCURVE",
+"570 135 CURVE SMOOTH",
+"398 135 OFFCURVE",
+"280 272 OFFCURVE",
+"280 505 CURVE SMOOTH"
+);
+}
+);
+width = 1140;
+},
+{
+anchors = (
+{
+name = H;
+position = "{578, 0}";
+},
+{
+name = L;
+position = "{580, -100}";
+},
+{
+name = O;
+position = "{790, 0}";
+},
+{
+name = R;
+position = "{1160, 1000}";
+},
+{
+name = U;
+position = "{580, 1100}";
+}
+);
+layerId = master02;
+paths = (
+{
+closed = 1;
+nodes = (
+"90 163 OFFCURVE",
+"288 -25 OFFCURVE",
+"570 -25 CURVE SMOOTH",
+"840 -25 OFFCURVE",
+"1070 163 OFFCURVE",
+"1070 507 CURVE SMOOTH",
+"1070 851 OFFCURVE",
+"873 1040 OFFCURVE",
+"590 1040 CURVE SMOOTH",
+"320 1040 OFFCURVE",
+"90 851 OFFCURVE",
+"90 507 CURVE SMOOTH"
+);
+},
+{
+closed = 1;
+nodes = (
+"370 699 OFFCURVE",
+"451 815 OFFCURVE",
+"580 815 CURVE SMOOTH",
+"717 815 OFFCURVE",
+"790 699 OFFCURVE",
+"790 507 CURVE SMOOTH",
+"790 316 OFFCURVE",
+"709 200 OFFCURVE",
+"580 200 CURVE SMOOTH",
+"443 200 OFFCURVE",
+"370 316 OFFCURVE",
+"370 507 CURVE SMOOTH"
+);
+}
+);
+width = 1160;
+}
+);
+unicode = 006F;
+},
+{
+glyphname = LtnSmP;
+layers = (
+{
+anchors = (
+{
+name = H;
+position = "{265, -435}";
+},
+{
+name = L;
+position = "{590, -500}";
+},
+{
+name = R;
+position = "{1170, 1000}";
+},
+{
+name = U;
+position = "{590, 1100}";
+}
+);
+guideLines = (
+{
+position = "{214, -490}";
+}
+);
+layerId = master01;
+paths = (
+{
+closed = 1;
+nodes = (
+"150 907 OFFCURVE",
+"155 734 OFFCURVE",
+"155 485 CURVE SMOOTH",
+"155 291 OFFCURVE",
+"155 -490 OFFCURVE",
+"155 -490 CURVE",
+"365 -490 LINE",
+"348 -405 OFFCURVE",
+"340 -310 OFFCURVE",
+"340 -150 CURVE",
+"340 85 LINE",
+"435 18 OFFCURVE",
+"513 -25 OFFCURVE",
+"620 -25 CURVE SMOOTH",
+"871 -25 OFFCURVE",
+"1075 193 OFFCURVE",
+"1075 535 CURVE SMOOTH",
+"1075 828 OFFCURVE",
+"923 1040 OFFCURVE",
+"695 1040 CURVE SMOOTH",
+"547 1040 OFFCURVE",
+"419 954 OFFCURVE",
+"325 830 CURVE",
+"316 922 OFFCURVE",
+"300 986 OFFCURVE",
+"285 1020 CURVE",
+"105 1020 LINE"
+);
+},
+{
+closed = 1;
+nodes = (
+"414 768 OFFCURVE",
+"545 870 OFFCURVE",
+"660 870 CURVE SMOOTH",
+"804 870 OFFCURVE",
+"890 727 OFFCURVE",
+"890 505 CURVE SMOOTH",
+"890 279 OFFCURVE",
+"761 140 OFFCURVE",
+"620 140 CURVE SMOOTH",
+"528 140 OFFCURVE",
+"477 164 OFFCURVE",
+"340 260 CURVE",
+"340 575 LINE"
+);
+}
+);
+width = 1170;
+},
+{
+anchors = (
+{
+name = H;
+position = "{290, -435}";
+},
+{
+name = L;
+position = "{640, -500}";
+},
+{
+name = R;
+position = "{1235, 1000}";
+},
+{
+name = U;
+position = "{640, 1100}";
+}
+);
+layerId = master02;
+paths = (
+{
+closed = 1;
+nodes = (
+"433 -405 OFFCURVE",
+"425 -310 OFFCURVE",
+"425 -150 CURVE SMOOTH",
+"425 -71 OFFCURVE",
+"425 -41 OFFCURVE",
+"425 65 CURVE",
+"518 10 OFFCURVE",
+"594 -25 OFFCURVE",
+"699 -25 CURVE SMOOTH",
+"945 -25 OFFCURVE",
+"1145 193 OFFCURVE",
+"1145 535 CURVE SMOOTH",
+"1145 828 OFFCURVE",
+"996 1040 OFFCURVE",
+"773 1040 CURVE SMOOTH",
+"628 1040 OFFCURVE",
+"502 962 OFFCURVE",
+"410 850 CURVE",
+"401 932 OFFCURVE",
+"385 990 OFFCURVE",
+"370 1020 CURVE",
+"95 1020 LINE",
+"140 907 OFFCURVE",
+"145 734 OFFCURVE",
+"145 485 CURVE SMOOTH",
+"145 291 OFFCURVE",
+"145 -345 OFFCURVE",
+"145 -490 CURVE",
+"450 -490 LINE"
+);
+},
+{
+closed = 1;
+nodes = (
+"564 206 OFFCURVE",
+"527 225 OFFCURVE",
+"425 300 CURVE",
+"425 390 OFFCURVE",
+"425 507 OFFCURVE",
+"425 585 CURVE",
+"482 726 OFFCURVE",
+"583 802 OFFCURVE",
+"672 802 CURVE SMOOTH",
+"793 802 OFFCURVE",
+"865 686 OFFCURVE",
+"865 505 CURVE SMOOTH",
+"865 320 OFFCURVE",
+"755 206 OFFCURVE",
+"633 206 CURVE SMOOTH"
+);
+}
+);
+width = 1235;
+}
+);
+unicode = 0070;
+},
+{
+glyphname = LtnSmQ;
+layers = (
+{
+anchors = (
+{
+name = L;
+position = "{555, -500}";
+},
+{
+name = R;
+position = "{1130, 1000}";
+},
+{
+name = U;
+position = "{555, 1100}";
+}
+);
+layerId = master01;
+paths = (
+{
+closed = 1;
+nodes = (
+"1005 -490 LINE",
+"988 -405 OFFCURVE",
+"980 -310 OFFCURVE",
+"980 -150 CURVE SMOOTH",
+"980 -26 OFFCURVE",
+"980 965 OFFCURVE",
+"980 965 CURVE",
+"872 1001 OFFCURVE",
+"746 1040 OFFCURVE",
+"625 1040 CURVE SMOOTH",
+"260 1040 OFFCURVE",
+"105 742 OFFCURVE",
+"105 435 CURVE SMOOTH",
+"105 117 OFFCURVE",
+"321 -25 OFFCURVE",
+"505 -25 CURVE SMOOTH",
+"598 -25 OFFCURVE",
+"691 19 OFFCURVE",
+"795 140 CURVE",
+"795 -490 LINE"
+);
+},
+{
+closed = 1;
+nodes = (
+"713 219 OFFCURVE",
+"612 145 OFFCURVE",
+"520 145 CURVE SMOOTH",
+"412 145 OFFCURVE",
+"290 237 OFFCURVE",
+"290 485 CURVE SMOOTH",
+"290 674 OFFCURVE",
+"376 870 OFFCURVE",
+"595 870 CURVE SMOOTH",
+"656 870 OFFCURVE",
+"735 853 OFFCURVE",
+"795 830 CURVE",
+"795 365 LINE"
+);
+}
+);
+width = 1130;
+},
+{
+anchors = (
+{
+name = L;
+position = "{600, -500}";
+},
+{
+name = R;
+position = "{1210, 1000}";
+},
+{
+name = U;
+position = "{600, 1100}";
+}
+);
+layerId = master02;
+paths = (
+{
+closed = 1;
+nodes = (
+"1095 -490 LINE",
+"1078 -405 OFFCURVE",
+"1070 -310 OFFCURVE",
+"1070 -150 CURVE SMOOTH",
+"1070 -26 OFFCURVE",
+"1070 965 OFFCURVE",
+"1070 965 CURVE",
+"934 1001 OFFCURVE",
+"773 1040 OFFCURVE",
+"620 1040 CURVE SMOOTH",
+"255 1040 OFFCURVE",
+"100 742 OFFCURVE",
+"100 435 CURVE SMOOTH",
+"100 117 OFFCURVE",
+"316 -25 OFFCURVE",
+"500 -25 CURVE SMOOTH",
+"593 -25 OFFCURVE",
+"686 14 OFFCURVE",
+"790 120 CURVE",
+"790 -490 LINE"
+);
+},
+{
+closed = 1;
+nodes = (
+"727 258 OFFCURVE",
+"650 203 OFFCURVE",
+"580 203 CURVE SMOOTH",
+"475 203 OFFCURVE",
+"380 287 OFFCURVE",
+"380 485 CURVE SMOOTH",
+"380 641 OFFCURVE",
+"456 802 OFFCURVE",
+"655 802 CURVE SMOOTH",
+"696 802 OFFCURVE",
+"749 789 OFFCURVE",
+"790 770 CURVE",
+"790 368 LINE"
+);
+}
+);
+width = 1210;
+}
+);
+unicode = 0071;
+},
+{
+glyphname = LtnSmR;
+layers = (
+{
+anchors = (
+{
+name = H;
+position = "{270, 0}";
+},
+{
+name = L;
+position = "{255, -100}";
+},
+{
+name = U;
+position = "{455, 1100}";
+}
+);
+guideLines = (
+{
+position = "{214, 500}";
+}
+);
+layerId = master01;
+paths = (
+{
+closed = 1;
+nodes = (
+"340 580 LINE",
+"384 716 OFFCURVE",
+"521 860 OFFCURVE",
+"605 860 CURVE SMOOTH",
+"684 860 OFFCURVE",
+"720 770 OFFCURVE",
+"720 670 CURVE",
+"880 705 LINE",
+"880 880 OFFCURVE",
+"817 1040 OFFCURVE",
+"650 1040 CURVE SMOOTH",
+"559 1040 OFFCURVE",
+"422 964 OFFCURVE",
+"325 825 CURVE",
+"318 873 OFFCURVE",
+"300 978 OFFCURVE",
+"285 1020 CURVE",
+"105 1020 LINE",
+"127 951 OFFCURVE",
+"155 811 OFFCURVE",
+"155 615 CURVE SMOOTH",
+"155 0 LINE",
+"340 0 LINE"
+);
+}
+);
+width = 890;
+},
+{
+anchors = (
+{
+name = H;
+position = "{285, 0}";
+},
+{
+name = L;
+position = "{275, -100}";
+},
+{
+name = U;
+position = "{550, 1100}";
+}
+);
+layerId = master02;
+paths = (
+{
+closed = 1;
+nodes = (
+"425 530 LINE",
+"460 654 OFFCURVE",
+"570 781 OFFCURVE",
+"637 781 CURVE SMOOTH",
+"722 781 OFFCURVE",
+"755 721 OFFCURVE",
+"762 630 CURVE",
+"985 665 LINE",
+"985 868 OFFCURVE",
+"913 1040 OFFCURVE",
+"725 1040 CURVE SMOOTH",
+"634 1040 OFFCURVE",
+"507 964 OFFCURVE",
+"410 825 CURVE",
+"403 873 OFFCURVE",
+"385 978 OFFCURVE",
+"370 1020 CURVE",
+"95 1020 LINE",
+"117 951 OFFCURVE",
+"145 811 OFFCURVE",
+"145 615 CURVE SMOOTH",
+"145 0 LINE",
+"425 0 LINE"
+);
+}
+);
+width = 995;
+}
+);
+unicode = 0072;
+},
+{
+glyphname = LtnSmS;
+layers = (
+{
+anchors = (
+{
+name = H;
+position = "{495, 0}";
+},
+{
+name = L;
+position = "{495, -100}";
+},
+{
+name = U;
+position = "{495, 1100}";
+}
+);
+layerId = master01;
+paths = (
+{
+closed = 1;
+nodes = (
+"766 998 OFFCURVE",
+"660 1040 OFFCURVE",
+"515 1040 CURVE SMOOTH",
+"211 1040 OFFCURVE",
+"130 832 OFFCURVE",
+"130 740 CURVE SMOOTH",
+"130 616 OFFCURVE",
+"182 514 OFFCURVE",
+"425 455 CURVE SMOOTH",
+"649 400 OFFCURVE",
+"700 345 OFFCURVE",
+"700 270 CURVE SMOOTH",
+"700 201 OFFCURVE",
+"617 135 OFFCURVE",
+"500 135 CURVE SMOOTH",
+"394 135 OFFCURVE",
+"250 189 OFFCURVE",
+"160 270 CURVE",
+"110 90 LINE",
+"189 28 OFFCURVE",
+"333 -25 OFFCURVE",
+"495 -25 CURVE SMOOTH",
+"710 -25 OFFCURVE",
+"880 115 OFFCURVE",
+"880 295 CURVE SMOOTH",
+"880 481 OFFCURVE",
+"731 559 OFFCURVE",
+"550 600 CURVE SMOOTH",
+"340 648 OFFCURVE",
+"310 680 OFFCURVE",
+"310 750 CURVE SMOOTH",
+"310 810 OFFCURVE",
+"358 880 OFFCURVE",
+"505 880 CURVE SMOOTH",
+"629 880 OFFCURVE",
+"733 824 OFFCURVE",
+"800 785 CURVE",
+"835 960 LINE"
+);
+}
+);
+width = 965;
+},
+{
+anchors = (
+{
+name = H;
+position = "{515, 0}";
+},
+{
+name = L;
+position = "{515, -100}";
+},
+{
+name = U;
+position = "{530, 1100}";
+}
+);
+layerId = master02;
+paths = (
+{
+closed = 1;
+nodes = (
+"827 998 OFFCURVE",
+"708 1040 OFFCURVE",
+"545 1040 CURVE SMOOTH",
+"202 1040 OFFCURVE",
+"110 818 OFFCURVE",
+"110 720 CURVE SMOOTH",
+"110 594 OFFCURVE",
+"171 491 OFFCURVE",
+"455 432 CURVE SMOOTH",
+"646 390 OFFCURVE",
+"690 348 OFFCURVE",
+"690 290 CURVE SMOOTH",
+"690 243 OFFCURVE",
+"624 199 OFFCURVE",
+"530 199 CURVE SMOOTH",
+"413 199 OFFCURVE",
+"254 253 OFFCURVE",
+"155 334 CURVE",
+"100 90 LINE",
+"187 28 OFFCURVE",
+"346 -25 OFFCURVE",
+"525 -25 CURVE SMOOTH",
+"768 -25 OFFCURVE",
+"960 123 OFFCURVE",
+"960 315 CURVE SMOOTH",
+"960 504 OFFCURVE",
+"788 583 OFFCURVE",
+"580 625 CURVE SMOOTH",
+"405 659 OFFCURVE",
+"380 681 OFFCURVE",
+"380 730 CURVE SMOOTH",
+"380 770 OFFCURVE",
+"418 816 OFFCURVE",
+"535 816 CURVE SMOOTH",
+"674 816 OFFCURVE",
+"791 760 OFFCURVE",
+"866 721 CURVE",
+"905 960 LINE"
+);
+}
+);
+width = 1035;
+}
+);
+unicode = 0073;
+},
+{
+glyphname = LtnSmT;
+layers = (
+{
+anchors = (
+{
+name = H;
+position = "{475, 0}";
+},
+{
+name = L;
+position = "{475, -100}";
+},
+{
+name = R;
+position = "{835, 1000}";
+},
+{
+name = U;
+position = "{325, 1360}";
+}
+);
+layerId = master01;
+paths = (
+{
+closed = 1;
+nodes = (
+"672 166 OFFCURVE",
+"600 140 OFFCURVE",
+"543 140 CURVE SMOOTH",
+"453 140 OFFCURVE",
+"415 184 OFFCURVE",
+"415 390 CURVE SMOOTH",
+"415 528 OFFCURVE",
+"415 1320 OFFCURVE",
+"415 1320 CURVE",
+"230 1320 LINE",
+"230 1320 OFFCURVE",
+"230 435 OFFCURVE",
+"230 270 CURVE SMOOTH",
+"230 39 OFFCURVE",
+"356 -25 OFFCURVE",
+"512 -25 CURVE SMOOTH",
+"582 -25 OFFCURVE",
+"668 -4 OFFCURVE",
+"760 55 CURVE",
+"760 215 LINE"
+);
+},
+{
+closed = 1;
+nodes = (
+"740 850 LINE",
+"740 995 LINE",
+"30 995 LINE",
+"30 850 LINE"
+);
+}
+);
+width = 835;
+},
+{
+anchors = (
+{
+name = H;
+position = "{530, 0}";
+},
+{
+name = L;
+position = "{530, -100}";
+},
+{
+name = R;
+position = "{885, 1000}";
+},
+{
+name = U;
+position = "{360, 1360}";
+}
+);
+layerId = master02;
+paths = (
+{
+closed = 1;
+nodes = (
+"220 39 OFFCURVE",
+"374 -25 OFFCURVE",
+"563 -25 CURVE SMOOTH",
+"635 -25 OFFCURVE",
+"725 -3 OFFCURVE",
+"820 57 CURVE",
+"820 281 LINE",
+"741 232 OFFCURVE",
+"678 206 OFFCURVE",
+"627 206 CURVE SMOOTH",
+"537 206 OFFCURVE",
+"500 235 OFFCURVE",
+"500 462 CURVE SMOOTH",
+"500 1320 LINE",
+"220 1320 LINE",
+"220 270 LINE"
+);
+},
+{
+closed = 1;
+nodes = (
+"805 1005 LINE",
+"30 1005 LINE",
+"30 805 LINE",
+"805 805 LINE"
+);
+}
+);
+width = 885;
+}
+);
+unicode = 0074;
+},
+{
+glyphname = LtnSmU;
+layers = (
+{
+anchors = (
+{
+name = H;
+position = "{589, 0}";
+},
+{
+name = L;
+position = "{589, -100}";
+},
+{
+name = O;
+position = "{1192, 0}";
+},
+{
+name = R;
+position = "{1185, 1000}";
+},
+{
+name = U;
+position = "{589, 1100}";
+}
+);
+layerId = master01;
+paths = (
+{
+closed = 1;
+nodes = (
+"1048 112 OFFCURVE",
+"1025 256 OFFCURVE",
+"1025 450 CURVE SMOOTH",
+"1025 646 OFFCURVE",
+"1025 1020 OFFCURVE",
+"1025 1020 CURVE",
+"820 1020 LINE",
+"838 898 OFFCURVE",
+"840 832 OFFCURVE",
+"840 700 CURVE SMOOTH",
+"840 420 LINE",
+"787 298 OFFCURVE",
+"628 140 OFFCURVE",
+"510 140 CURVE SMOOTH",
+"383 140 OFFCURVE",
+"340 238 OFFCURVE",
+"340 465 CURVE SMOOTH",
+"340 603 OFFCURVE",
+"340 1020 OFFCURVE",
+"340 1020 CURVE",
+"135 1020 LINE",
+"153 900 OFFCURVE",
+"155 827 OFFCURVE",
+"155 700 CURVE SMOOTH",
+"155 681 OFFCURVE",
+"155 424 OFFCURVE",
+"155 405 CURVE SMOOTH",
+"155 120 OFFCURVE",
+"262 -25 OFFCURVE",
+"475 -25 CURVE SMOOTH",
+"615 -25 OFFCURVE",
+"744 53 OFFCURVE",
+"865 200 CURVE",
+"875 125 OFFCURVE",
+"901 46 OFFCURVE",
+"920 0 CURVE",
+"1090 0 LINE"
+);
+}
+);
+width = 1185;
+},
+{
+anchors = (
+{
+name = H;
+position = "{515, 0}";
+},
+{
+name = L;
+position = "{615, -100}";
+},
+{
+name = O;
+position = "{690, 0}";
+},
+{
+name = R;
+position = "{1258, 1000}";
+},
+{
+name = U;
+position = "{615, 1100}";
+}
+);
+layerId = master02;
+paths = (
+{
+closed = 1;
+nodes = (
+"1118 112 OFFCURVE",
+"1095 256 OFFCURVE",
+"1095 450 CURVE SMOOTH",
+"1095 646 OFFCURVE",
+"1095 1020 OFFCURVE",
+"1095 1020 CURVE",
+"795 1020 LINE",
+"813 898 OFFCURVE",
+"815 832 OFFCURVE",
+"815 700 CURVE SMOOTH",
+"815 418 LINE",
+"774 326 OFFCURVE",
+"651 206 OFFCURVE",
+"560 206 CURVE SMOOTH",
+"458 206 OFFCURVE",
+"425 284 OFFCURVE",
+"425 465 CURVE SMOOTH",
+"425 603 OFFCURVE",
+"425 1020 OFFCURVE",
+"425 1020 CURVE",
+"125 1020 LINE",
+"143 900 OFFCURVE",
+"145 827 OFFCURVE",
+"145 700 CURVE SMOOTH",
+"145 681 OFFCURVE",
+"145 424 OFFCURVE",
+"145 405 CURVE SMOOTH",
+"145 120 OFFCURVE",
+"250 -25 OFFCURVE",
+"458 -25 CURVE SMOOTH",
+"595 -25 OFFCURVE",
+"722 48 OFFCURVE",
+"840 185 CURVE",
+"850 116 OFFCURVE",
+"876 43 OFFCURVE",
+"895 0 CURVE",
+"1160 0 LINE"
+);
+}
+);
+width = 1245;
+}
+);
+unicode = 0075;
+},
+{
+glyphname = LtnSmV;
+layers = (
+{
+anchors = (
+{
+name = H;
+position = "{549, 0}";
+},
+{
+name = L;
+position = "{535, -100}";
+},
+{
+name = O;
+position = "{725, 0}";
+},
+{
+name = U;
+position = "{535, 1100}";
+}
+);
+layerId = master01;
+paths = (
+{
+closed = 1;
+nodes = (
+"535 200 LINE",
+"230 1020 LINE",
+"20 1020 LINE",
+"75 905 OFFCURVE",
+"143 746 OFFCURVE",
+"175 665 CURVE SMOOTH",
+"237 510 OFFCURVE",
+"440 0 OFFCURVE",
+"440 0 CURVE",
+"630 0 LINE",
+"630 0 OFFCURVE",
+"842 536 OFFCURVE",
+"895 665 CURVE SMOOTH",
+"928 744 OFFCURVE",
+"993 905 OFFCURVE",
+"1050 1020 CURVE",
+"840 1020 LINE"
+);
+}
+);
+width = 1070;
+},
+{
+anchors = (
+{
+name = H;
+position = "{565, 0}";
+},
+{
+name = L;
+position = "{565, -100}";
+},
+{
+name = O;
+position = "{750, 0}";
+},
+{
+name = U;
+position = "{565, 1100}";
+}
+);
+layerId = master02;
+paths = (
+{
+closed = 1;
+nodes = (
+"556 290 LINE",
+"322 1020 LINE",
+"10 1020 LINE",
+"65 905 OFFCURVE",
+"133 746 OFFCURVE",
+"165 665 CURVE SMOOTH",
+"227 510 OFFCURVE",
+"430 0 OFFCURVE",
+"430 0 CURVE",
+"674 0 LINE",
+"674 0 OFFCURVE",
+"886 536 OFFCURVE",
+"939 665 CURVE SMOOTH",
+"972 744 OFFCURVE",
+"1037 905 OFFCURVE",
+"1094 1020 CURVE",
+"786 1020 LINE"
+);
+}
+);
+width = 1104;
+}
+);
+unicode = 0076;
+},
+{
+glyphname = LtnSmW;
+layers = (
+{
+anchors = (
+{
+name = L;
+position = "{775, -100}";
+},
+{
+name = U;
+position = "{775, 1100}";
+}
+);
+layerId = master01;
+paths = (
+{
+closed = 1;
+nodes = (
+"440 215 LINE",
+"230 1020 LINE",
+"45 1020 LINE",
+"92 867 OFFCURVE",
+"120 771 OFFCURVE",
+"150 665 CURVE SMOOTH",
+"335 0 LINE",
+"525 0 LINE",
+"775 785 LINE",
+"1025 0 LINE",
+"1215 0 LINE",
+"1400 665 LINE SMOOTH",
+"1434 785 OFFCURVE",
+"1458 868 OFFCURVE",
+"1505 1020 CURVE",
+"1320 1020 LINE",
+"1110 215 LINE",
+"850 1020 LINE",
+"700 1020 LINE"
+);
+}
+);
+width = 1550;
+},
+{
+anchors = (
+{
+name = L;
+position = "{785, -100}";
+},
+{
+name = U;
+position = "{785, 1100}";
+}
+);
+layerId = master02;
+paths = (
+{
+closed = 1;
+nodes = (
+"480 285 LINE",
+"323 1020 LINE",
+"35 1020 LINE",
+"82 867 OFFCURVE",
+"110 771 OFFCURVE",
+"140 665 CURVE SMOOTH",
+"325 0 LINE",
+"615 0 LINE",
+"785 695 LINE",
+"955 0 LINE",
+"1245 0 LINE",
+"1430 665 LINE SMOOTH",
+"1464 785 OFFCURVE",
+"1488 868 OFFCURVE",
+"1535 1020 CURVE",
+"1247 1020 LINE",
+"1090 285 LINE",
+"905 1020 LINE",
+"665 1020 LINE"
+);
+}
+);
+width = 1570;
+}
+);
+unicode = 0077;
+},
+{
+glyphname = LtnSmX;
+layers = (
+{
+anchors = (
+{
+name = H;
+position = "{900, 0}";
+},
+{
+name = L;
+position = "{542, -100}";
+},
+{
+name = U;
+position = "{542, 1100}";
+}
+);
+layerId = master01;
+paths = (
+{
+closed = 1;
+nodes = (
+"1035 0 LINE",
+"927 142 OFFCURVE",
+"902 170 OFFCURVE",
+"830 270 CURVE SMOOTH",
+"290 1020 LINE",
+"60 1020 LINE",
+"168 887 OFFCURVE",
+"203 843 OFFCURVE",
+"270 750 CURVE",
+"805 0 LINE"
+);
+},
+{
+closed = 1;
+nodes = (
+"250 270 LINE SMOOTH",
+"189 182 OFFCURVE",
+"160 143 OFFCURVE",
+"50 0 CURVE",
+"275 0 LINE",
+"556 404 LINE",
+"489 616 LINE"
+);
+},
+{
+closed = 1;
+nodes = (
+"820 750 LINE SMOOTH",
+"883 842 OFFCURVE",
+"917 886 OFFCURVE",
+"1020 1020 CURVE",
+"795 1020 LINE",
+"520 615 LINE",
+"585 405 LINE"
+);
+}
+);
+width = 1085;
+},
+{
+anchors = (
+{
+name = H;
+position = "{960, 0}";
+},
+{
+name = L;
+position = "{590, -100}";
+},
+{
+name = U;
+position = "{615, 1100}";
+}
+);
+layerId = master02;
+paths = (
+{
+closed = 1;
+nodes = (
+"1145 0 LINE",
+"1037 129 OFFCURVE",
+"989 190 OFFCURVE",
+"930 270 CURVE SMOOTH",
+"380 1020 LINE",
+"50 1020 LINE",
+"158 887 OFFCURVE",
+"192 842 OFFCURVE",
+"260 750 CURVE SMOOTH",
+"815 0 LINE"
+);
+},
+{
+closed = 1;
+nodes = (
+"245 270 LINE SMOOTH",
+"195 201 OFFCURVE",
+"150 143 OFFCURVE",
+"40 0 CURVE",
+"345 0 LINE",
+"584 359 LINE",
+"499 616 LINE"
+);
+},
+{
+closed = 1;
+nodes = (
+"925 750 LINE SMOOTH",
+"980 826 OFFCURVE",
+"1027 886 OFFCURVE",
+"1130 1020 CURVE",
+"825 1020 LINE",
+"595 668 LINE",
+"675 405 LINE"
+);
+}
+);
+width = 1185;
+}
+);
+unicode = 0078;
+},
+{
+glyphname = LtnSmY;
+layers = (
+{
+anchors = (
+{
+name = L;
+position = "{795, -100}";
+},
+{
+name = R;
+position = "{1120, 1000}";
+},
+{
+name = U;
+position = "{535, 1100}";
+}
+);
+layerId = master01;
+paths = (
+{
+closed = 1;
+nodes = (
+"230 1020 LINE",
+"30 1020 LINE",
+"107 864 OFFCURVE",
+"153 756 OFFCURVE",
+"190 665 CURVE SMOOTH",
+"525 -165 LINE",
+"610 60 LINE"
+);
+},
+{
+closed = 1;
+nodes = (
+"928 758 OFFCURVE",
+"971 865 OFFCURVE",
+"1040 1020 CURVE",
+"840 1020 LINE",
+"840 1020 OFFCURVE",
+"564 230 OFFCURVE",
+"500 55 CURVE SMOOTH",
+"391 -248 OFFCURVE",
+"315 -300 OFFCURVE",
+"225 -300 CURVE SMOOTH",
+"159 -300 OFFCURVE",
+"82 -260 OFFCURVE",
+"40 -225 CURVE",
+"-20 -385 LINE",
+"53 -439 OFFCURVE",
+"134 -470 OFFCURVE",
+"225 -470 CURVE SMOOTH",
+"395 -470 OFFCURVE",
+"516 -383 OFFCURVE",
+"655 0 CURVE",
+"895 665 LINE"
+);
+}
+);
+width = 1060;
+},
+{
+anchors = (
+{
+name = L;
+position = "{845, -100}";
+},
+{
+name = R;
+position = "{1155, 1000}";
+},
+{
+name = U;
+position = "{565, 1100}";
+}
+);
+layerId = master02;
+paths = (
+{
+closed = 1;
+nodes = (
+"978 758 OFFCURVE",
+"1021 865 OFFCURVE",
+"1090 1020 CURVE",
+"777 1020 LINE",
+"777 1020 OFFCURVE",
+"646 549 OFFCURVE",
+"573 293 CURVE",
+"333 1020 LINE",
+"20 1020 LINE",
+"97 864 OFFCURVE",
+"144 757 OFFCURVE",
+"180 665 CURVE SMOOTH",
+"445 -18 LINE",
+"366 -209 OFFCURVE",
+"304 -242 OFFCURVE",
+"245 -242 CURVE SMOOTH",
+"179 -242 OFFCURVE",
+"102 -202 OFFCURVE",
+"60 -167 CURVE",
+"-10 -385 LINE",
+"63 -439 OFFCURVE",
+"154 -470 OFFCURVE",
+"245 -470 CURVE SMOOTH",
+"427 -470 OFFCURVE",
+"565 -387 OFFCURVE",
+"705 0 CURVE SMOOTH",
+"945 665 LINE SMOOTH"
+);
+}
+);
+width = 1100;
+}
+);
+unicode = 0079;
+},
+{
+glyphname = LftCurlyBrac;
+layers = (
+{
+layerId = master01;
+paths = (
+{
+closed = 1;
+nodes = (
+"210 583 OFFCURVE",
+"383 486 OFFCURVE",
+"410 450 CURVE SMOOTH",
+"434 418 OFFCURVE",
+"424 -205 OFFCURVE",
+"495 -285 CURVE SMOOTH",
+"535 -330 OFFCURVE",
+"696 -383 OFFCURVE",
+"800 -410 CURVE",
+"840 -270 LINE",
+"773 -247 OFFCURVE",
+"650 -198 OFFCURVE",
+"630 -170 CURVE SMOOTH",
+"597 -123 OFFCURVE",
+"610 447 OFFCURVE",
+"590 485 CURVE SMOOTH",
+"571 521 OFFCURVE",
+"434 593 OFFCURVE",
+"430 615 CURVE",
+"434 637 OFFCURVE",
+"571 709 OFFCURVE",
+"590 745 CURVE SMOOTH",
+"610 783 OFFCURVE",
+"597 1353 OFFCURVE",
+"630 1400 CURVE SMOOTH",
+"650 1428 OFFCURVE",
+"773 1477 OFFCURVE",
+"840 1500 CURVE",
+"800 1640 LINE",
+"696 1613 OFFCURVE",
+"535 1560 OFFCURVE",
+"495 1515 CURVE SMOOTH",
+"424 1435 OFFCURVE",
+"434 812 OFFCURVE",
+"410 780 CURVE SMOOTH",
+"383 744 OFFCURVE",
+"210 647 OFFCURVE",
+"210 615 CURVE SMOOTH"
+);
+}
+);
+width = 1000;
+},
+{
+layerId = master02;
+paths = (
+{
+closed = 1;
+nodes = (
+"828 -160 OFFCURVE",
+"704 -122 OFFCURVE",
+"685 -100 CURVE SMOOTH",
+"650 -60 OFFCURVE",
+"663 411 OFFCURVE",
+"645 445 CURVE SMOOTH",
+"621 491 OFFCURVE",
+"483 580 OFFCURVE",
+"483 615 CURVE SMOOTH",
+"483 650 OFFCURVE",
+"620 740 OFFCURVE",
+"643 785 CURVE SMOOTH",
+"661 820 OFFCURVE",
+"650 1289 OFFCURVE",
+"685 1330 CURVE SMOOTH",
+"702 1351 OFFCURVE",
+"807 1390 OFFCURVE",
+"870 1409 CURVE",
+"820 1640 LINE",
+"692 1613 OFFCURVE",
+"502 1562 OFFCURVE",
+"455 1515 CURVE SMOOTH",
+"381 1442 OFFCURVE",
+"392 852 OFFCURVE",
+"370 820 CURVE SMOOTH",
+"340 777 OFFCURVE",
+"170 670 OFFCURVE",
+"170 615 CURVE SMOOTH",
+"170 560 OFFCURVE",
+"340 453 OFFCURVE",
+"370 410 CURVE SMOOTH",
+"392 378 OFFCURVE",
+"380 -213 OFFCURVE",
+"455 -285 CURVE SMOOTH",
+"505 -333 OFFCURVE",
+"709 -383 OFFCURVE",
+"845 -410 CURVE",
+"895 -179 LINE"
+);
+}
+);
+width = 1040;
+}
+);
+unicode = 007B;
+},
+{
+glyphname = VertLine;
+layers = (
+{
+layerId = master01;
+paths = (
+{
+closed = 1;
+nodes = (
+"270 -390 LINE",
+"420 -390 LINE",
+"420 1600 LINE",
+"270 1600 LINE"
+);
+}
+);
+width = 690;
+},
+{
+layerId = master02;
+paths = (
+{
+closed = 1;
+nodes = (
+"240 -390 LINE",
+"450 -390 LINE",
+"450 1600 LINE",
+"240 1600 LINE"
+);
+}
+);
+width = 690;
+}
+);
+unicode = 007C;
+},
+{
+glyphname = RtCurlyBrac;
+layers = (
+{
+layerId = master01;
+paths = (
+{
+closed = 1;
+nodes = (
+"790 647 OFFCURVE",
+"617 744 OFFCURVE",
+"590 780 CURVE SMOOTH",
+"566 812 OFFCURVE",
+"576 1435 OFFCURVE",
+"505 1515 CURVE SMOOTH",
+"465 1560 OFFCURVE",
+"304 1613 OFFCURVE",
+"200 1640 CURVE",
+"160 1500 LINE",
+"227 1477 OFFCURVE",
+"350 1428 OFFCURVE",
+"370 1400 CURVE SMOOTH",
+"403 1353 OFFCURVE",
+"390 783 OFFCURVE",
+"410 745 CURVE SMOOTH",
+"429 709 OFFCURVE",
+"566 637 OFFCURVE",
+"570 615 CURVE",
+"566 593 OFFCURVE",
+"429 521 OFFCURVE",
+"410 485 CURVE SMOOTH",
+"390 447 OFFCURVE",
+"403 -123 OFFCURVE",
+"370 -170 CURVE SMOOTH",
+"350 -198 OFFCURVE",
+"227 -247 OFFCURVE",
+"160 -270 CURVE",
+"200 -410 LINE",
+"304 -383 OFFCURVE",
+"465 -330 OFFCURVE",
+"505 -285 CURVE SMOOTH",
+"576 -205 OFFCURVE",
+"566 418 OFFCURVE",
+"590 450 CURVE SMOOTH",
+"617 486 OFFCURVE",
+"790 583 OFFCURVE",
+"790 615 CURVE SMOOTH"
+);
+}
+);
+width = 1000;
+},
+{
+layerId = master02;
+paths = (
+{
+closed = 1;
+nodes = (
+"316 -383 OFFCURVE",
+"520 -333 OFFCURVE",
+"570 -285 CURVE SMOOTH",
+"645 -213 OFFCURVE",
+"633 378 OFFCURVE",
+"655 410 CURVE SMOOTH",
+"685 453 OFFCURVE",
+"855 560 OFFCURVE",
+"855 615 CURVE SMOOTH",
+"855 670 OFFCURVE",
+"685 777 OFFCURVE",
+"655 820 CURVE SMOOTH",
+"633 852 OFFCURVE",
+"644 1442 OFFCURVE",
+"570 1515 CURVE SMOOTH",
+"523 1562 OFFCURVE",
+"333 1613 OFFCURVE",
+"205 1640 CURVE",
+"155 1409 LINE",
+"218 1390 OFFCURVE",
+"323 1351 OFFCURVE",
+"340 1330 CURVE SMOOTH",
+"375 1289 OFFCURVE",
+"364 820 OFFCURVE",
+"382 785 CURVE SMOOTH",
+"405 740 OFFCURVE",
+"542 650 OFFCURVE",
+"542 615 CURVE SMOOTH",
+"542 580 OFFCURVE",
+"404 491 OFFCURVE",
+"380 445 CURVE SMOOTH",
+"362 411 OFFCURVE",
+"375 -60 OFFCURVE",
+"340 -100 CURVE SMOOTH",
+"321 -122 OFFCURVE",
+"197 -160 OFFCURVE",
+"130 -179 CURVE",
+"180 -410 LINE"
+);
+}
+);
+width = 1040;
+}
+);
+unicode = 007D;
+},
+{
+glyphname = Tilde;
+layers = (
+{
+layerId = master01;
+paths = (
+{
+closed = 1;
+nodes = (
+"130 424 OFFCURVE",
+"162 465 OFFCURVE",
+"240 465 CURVE SMOOTH",
+"415 465 OFFCURVE",
+"615 360 OFFCURVE",
+"845 360 CURVE SMOOTH",
+"1004 360 OFFCURVE",
+"1080 482 OFFCURVE",
+"1080 610 CURVE",
+"975 610 LINE",
+"968 564 OFFCURVE",
+"938 510 OFFCURVE",
+"855 510 CURVE SMOOTH",
+"619 510 OFFCURVE",
+"461 615 OFFCURVE",
+"240 615 CURVE SMOOTH",
+"94 615 OFFCURVE",
+"20 497 OFFCURVE",
+"20 375 CURVE",
+"125 375 LINE"
+);
+}
+);
+width = 1115;
+},
+{
+layerId = master02;
+paths = (
+{
+closed = 1;
+nodes = (
+"170 394 OFFCURVE",
+"202 435 OFFCURVE",
+"280 435 CURVE SMOOTH",
+"435 435 OFFCURVE",
+"615 330 OFFCURVE",
+"825 330 CURVE SMOOTH",
+"984 330 OFFCURVE",
+"1080 512 OFFCURVE",
+"1080 640 CURVE",
+"935 640 LINE",
+"928 594 OFFCURVE",
+"898 540 OFFCURVE",
+"815 540 CURVE SMOOTH",
+"599 540 OFFCURVE",
+"461 645 OFFCURVE",
+"260 645 CURVE SMOOTH",
+"104 645 OFFCURVE",
+"20 467 OFFCURVE",
+"20 345 CURVE",
+"165 345 LINE"
+);
+}
+);
+width = 1115;
+}
+);
+unicode = 007E;
+},
+{
+glyphname = LtnCapADiaer;
+layers = (
+{
+anchors = (
+{
+name = H;
+position = "{707, 0}";
+},
+{
+name = L;
+position = "{687, -100}";
+},
+{
+name = O;
+position = "{1450, 0}";
+},
+{
+name = U;
+position = "{687, 1935}";
+}
+);
+components = (
+{
+name = LtnCapA;
+},
+{
+name = CombDiaer;
+transform = "{1, 0, 0, 1, 1257, 430}";
+}
+);
+layerId = master01;
+width = 1395;
+},
+{
+anchors = (
+{
+name = H;
+position = "{1275, 0}";
+},
+{
+name = L;
+position = "{732, -100}";
+},
+{
+name = O;
+position = "{1495, 0}";
+},
+{
+name = U;
+position = "{732, 2015}";
+}
+);
+components = (
+{
+name = LtnCapA;
+},
+{
+name = CombDiaer;
+transform = "{1, 0, 0, 1, 1312, 430}";
+}
+);
+layerId = master02;
+width = 1485;
+}
+);
+unicode = 00C4;
+},
+{
+glyphname = LtnSmAAcute;
+layers = (
+{
+anchors = (
+{
+name = H;
+position = "{540, 0}";
+},
+{
+name = L;
+position = "{540, -100}";
+},
+{
+name = O;
+position = "{1125, 0}";
+},
+{
+name = R;
+position = "{1120, 1000}";
+},
+{
+name = U;
+position = "{540, 1635}";
+}
+);
+components = (
+{
+name = LtnSmA;
+},
+{
+name = CombAcute;
+transform = "{1, 0, 0, 1, 1110, 0}";
+}
+);
+layerId = master01;
+width = 1120;
+},
+{
+anchors = (
+{
+name = H;
+position = "{985, 0}";
+},
+{
+name = L;
+position = "{610, -100}";
+},
+{
+name = O;
+position = "{1185, 0}";
+},
+{
+name = R;
+position = "{1145, 1000}";
+},
+{
+name = U;
+position = "{550, 1635}";
+}
+);
+components = (
+{
+name = LtnSmA;
+},
+{
+name = CombAcute;
+transform = "{1, 0, 0, 1, 1150, 0}";
+}
+);
+layerId = master02;
+width = 1205;
+}
+);
+unicode = 00E1;
+},
+{
+glyphname = LtnSmAGrave;
+layers = (
+{
+anchors = (
+{
+name = H;
+position = "{540, 0}";
+},
+{
+name = L;
+position = "{540, -100}";
+},
+{
+name = O;
+position = "{1125, 0}";
+},
+{
+name = R;
+position = "{1120, 1000}";
+},
+{
+name = U;
+position = "{540, 1635}";
+}
+);
+components = (
+{
+name = LtnSmA;
+},
+{
+name = CombGrave;
+transform = "{1, 0, 0, 1, 1090, 0}";
+}
+);
+layerId = master01;
+width = 1120;
+},
+{
+anchors = (
+{
+name = H;
+position = "{985, 0}";
+},
+{
+name = L;
+position = "{610, -100}";
+},
+{
+name = O;
+position = "{1185, 0}";
+},
+{
+name = R;
+position = "{1145, 1000}";
+},
+{
+name = U;
+position = "{650, 1635}";
+}
+);
+components = (
+{
+name = LtnSmA;
+},
+{
+name = CombGrave;
+transform = "{1, 0, 0, 1, 1240, 0}";
+}
+);
+layerId = master02;
+width = 1205;
+}
+);
+unicode = 00E0;
+},
+{
+glyphname = LtnSmACircum;
+layers = (
+{
+anchors = (
+{
+name = H;
+position = "{540, 0}";
+},
+{
+name = L;
+position = "{540, -100}";
+},
+{
+name = O;
+position = "{1125, 0}";
+},
+{
+name = R;
+position = "{1120, 1000}";
+},
+{
+name = U;
+position = "{540, 1635}";
+}
+);
+components = (
+{
+name = LtnSmA;
+},
+{
+name = CombCircum;
+transform = "{1, 0, 0, 1, 1110, 0}";
+}
+);
+layerId = master01;
+width = 1120;
+},
+{
+anchors = (
+{
+name = H;
+position = "{985, 0}";
+},
+{
+name = L;
+position = "{610, -100}";
+},
+{
+name = O;
+position = "{1185, 0}";
+},
+{
+name = R;
+position = "{1145, 1000}";
+},
+{
+name = U;
+position = "{602, 1635}";
+}
+);
+components = (
+{
+name = LtnSmA;
+},
+{
+name = CombCircum;
+transform = "{1, 0, 0, 1, 1190, 0}";
+}
+);
+layerId = master02;
+width = 1205;
+}
+);
+unicode = 00E2;
+},
+{
+glyphname = LtnSmADiaer;
+layers = (
+{
+anchors = (
+{
+name = H;
+position = "{540, 0}";
+},
+{
+name = L;
+position = "{540, -100}";
+},
+{
+name = O;
+position = "{1125, 0}";
+},
+{
+name = R;
+position = "{1120, 1000}";
+},
+{
+name = U;
+position = "{540, 1505}";
+}
+);
+components = (
+{
+name = LtnSmA;
+},
+{
+name = CombDiaer;
+transform = "{1, 0, 0, 1, 1110, 0}";
+}
+);
+layerId = master01;
+width = 1120;
+},
+{
+anchors = (
+{
+name = H;
+position = "{985, 0}";
+},
+{
+name = L;
+position = "{610, -100}";
+},
+{
+name = O;
+position = "{1185, 0}";
+},
+{
+name = R;
+position = "{1145, 1000}";
+},
+{
+name = U;
+position = "{610, 1585}";
+}
+);
+components = (
+{
+name = LtnSmA;
+},
+{
+name = CombDiaer;
+transform = "{1, 0, 0, 1, 1190, 0}";
+}
+);
+layerId = master02;
+width = 1205;
+}
+);
+unicode = 00E4;
+},
+{
+glyphname = LtnSmATilde;
+layers = (
+{
+anchors = (
+{
+name = H;
+position = "{540, 0}";
+},
+{
+name = L;
+position = "{540, -100}";
+},
+{
+name = O;
+position = "{1125, 0}";
+},
+{
+name = R;
+position = "{1120, 1000}";
+},
+{
+name = U;
+position = "{540, 1475}";
+}
+);
+components = (
+{
+name = LtnSmA;
+}
+);
+layerId = master01;
+paths = (
+{
+closed = 1;
+nodes = (
+"300 1254 OFFCURVE",
+"331 1290 OFFCURVE",
+"380 1290 CURVE SMOOTH",
+"417 1290 OFFCURVE",
+"458 1274 OFFCURVE",
+"535 1238 CURVE SMOOTH",
+"596 1210 OFFCURVE",
+"649 1190 OFFCURVE",
+"702 1190 CURVE SMOOTH",
+"825 1190 OFFCURVE",
+"900 1312 OFFCURVE",
+"900 1440 CURVE",
+"795 1440 LINE",
+"788 1394 OFFCURVE",
+"757 1355 OFFCURVE",
+"710 1355 CURVE SMOOTH",
+"668 1355 OFFCURVE",
+"627 1374 OFFCURVE",
+"555 1403 CURVE SMOOTH",
+"485 1431 OFFCURVE",
+"438 1455 OFFCURVE",
+"382 1455 CURVE SMOOTH",
+"263 1455 OFFCURVE",
+"190 1327 OFFCURVE",
+"190 1205 CURVE",
+"295 1205 LINE"
+);
+}
+);
+width = 1120;
+},
+{
+anchors = (
+{
+name = H;
+position = "{985, 0}";
+},
+{
+name = L;
+position = "{610, -100}";
+},
+{
+name = O;
+position = "{1185, 0}";
+},
+{
+name = R;
+position = "{1145, 1000}";
+},
+{
+name = U;
+position = "{610, 1490}";
+}
+);
+components = (
+{
+name = LtnSmA;
+},
+{
+name = CombTilde;
+transform = "{1, 0, 0, 1, 1190, 0}";
+}
+);
+layerId = master02;
+width = 1205;
+}
+);
+unicode = 00E3;
+},
+{
+glyphname = LtnSmARingAbv;
+layers = (
+{
+anchors = (
+{
+name = H;
+position = "{540, 0}";
+},
+{
+name = L;
+position = "{540, -100}";
+},
+{
+name = O;
+position = "{1125, 0}";
+},
+{
+name = R;
+position = "{1120, 1000}";
+},
+{
+name = U;
+position = "{542, 1635}";
+}
+);
+components = (
+{
+name = LtnSmA;
+}
+);
+layerId = master01;
+paths = (
+{
+closed = 1;
+nodes = (
+"642 1325 OFFCURVE",
+"602 1285 OFFCURVE",
+"542 1285 CURVE SMOOTH",
+"482 1285 OFFCURVE",
+"442 1325 OFFCURVE",
+"442 1385 CURVE SMOOTH",
+"442 1445 OFFCURVE",
+"482 1485 OFFCURVE",
+"542 1485 CURVE SMOOTH",
+"602 1485 OFFCURVE",
+"642 1445 OFFCURVE",
+"642 1385 CURVE SMOOTH"
+);
+},
+{
+closed = 1;
+nodes = (
+"327 1265 OFFCURVE",
+"422 1170 OFFCURVE",
+"542 1170 CURVE SMOOTH",
+"662 1170 OFFCURVE",
+"757 1265 OFFCURVE",
+"757 1385 CURVE SMOOTH",
+"757 1505 OFFCURVE",
+"662 1600 OFFCURVE",
+"542 1600 CURVE SMOOTH",
+"422 1600 OFFCURVE",
+"327 1505 OFFCURVE",
+"327 1385 CURVE SMOOTH"
+);
+}
+);
+width = 1120;
+},
+{
+anchors = (
+{
+name = H;
+position = "{985, 0}";
+},
+{
+name = L;
+position = "{610, -100}";
+},
+{
+name = O;
+position = "{1185, 0}";
+},
+{
+name = R;
+position = "{1145, 1000}";
+},
+{
+name = U;
+position = "{612, 1635}";
+}
+);
+components = (
+{
+name = LtnSmA;
+},
+{
+name = CombRingAbv;
+transform = "{1, 0, 0, 1, 1182, 0}";
+}
+);
+layerId = master02;
+width = 1205;
+}
+);
+unicode = 00E5;
+},
+{
+glyphname = DottedCirc;
+layers = (
+{
+anchors = (
+{
+name = H;
+position = "{553, 0}";
+},
+{
+name = L;
+position = "{553, -100}";
+},
+{
+name = O;
+position = "{810, 0}";
+},
+{
+name = U;
+position = "{553, 1000}";
+}
+);
+layerId = master01;
+paths = (
+{
+closed = 1;
+nodes = (
+"443 864 OFFCURVE",
+"423 885 OFFCURVE",
+"398 885 CURVE SMOOTH",
+"371 885 OFFCURVE",
+"348 861 OFFCURVE",
+"348 837 CURVE SMOOTH",
+"348 809 OFFCURVE",
+"372 789 OFFCURVE",
+"398 789 CURVE SMOOTH",
+"425 789 OFFCURVE",
+"443 812 OFFCURVE",
+"443 837 CURVE SMOOTH"
+);
+},
+{
+closed = 1;
+nodes = (
+"758 106 OFFCURVE",
+"736 127 OFFCURVE",
+"710 127 CURVE SMOOTH",
+"685 127 OFFCURVE",
+"662 103 OFFCURVE",
+"662 80 CURVE SMOOTH",
+"662 52 OFFCURVE",
+"686 31 OFFCURVE",
+"710 31 CURVE SMOOTH",
+"737 31 OFFCURVE",
+"758 55 OFFCURVE",
+"758 79 CURVE SMOOTH"
+);
+},
+{
+closed = 1;
+nodes = (
+"310 775 OFFCURVE",
+"288 796 OFFCURVE",
+"263 796 CURVE SMOOTH",
+"238 796 OFFCURVE",
+"215 774 OFFCURVE",
+"215 747 CURVE SMOOTH",
+"215 722 OFFCURVE",
+"236 701 OFFCURVE",
+"263 701 CURVE SMOOTH",
+"291 701 OFFCURVE",
+"310 720 OFFCURVE",
+"310 749 CURVE SMOOTH"
+);
+},
+{
+closed = 1;
+nodes = (
+"891 197 OFFCURVE",
+"870 215 OFFCURVE",
+"843 215 CURVE SMOOTH",
+"817 215 OFFCURVE",
+"795 194 OFFCURVE",
+"795 168 CURVE SMOOTH",
+"795 143 OFFCURVE",
+"816 121 OFFCURVE",
+"843 121 CURVE SMOOTH",
+"871 121 OFFCURVE",
+"891 143 OFFCURVE",
+"891 168 CURVE SMOOTH"
+);
+},
+{
+closed = 1;
+nodes = (
+"222 640 OFFCURVE",
+"199 663 OFFCURVE",
+"173 663 CURVE SMOOTH",
+"149 663 OFFCURVE",
+"126 642 OFFCURVE",
+"126 615 CURVE SMOOTH",
+"126 591 OFFCURVE",
+"145 567 OFFCURVE",
+"173 567 CURVE SMOOTH",
+"197 567 OFFCURVE",
+"222 587 OFFCURVE",
+"222 613 CURVE SMOOTH"
+);
+},
+{
+closed = 1;
+nodes = (
+"980 327 OFFCURVE",
+"957 348 OFFCURVE",
+"932 348 CURVE SMOOTH",
+"908 348 OFFCURVE",
+"884 332 OFFCURVE",
+"884 301 CURVE SMOOTH",
+"884 277 OFFCURVE",
+"902 254 OFFCURVE",
+"932 254 CURVE SMOOTH",
+"957 254 OFFCURVE",
+"980 274 OFFCURVE",
+"980 301 CURVE SMOOTH"
+);
+},
+{
+closed = 1;
+nodes = (
+"191 484 OFFCURVE",
+"168 505 OFFCURVE",
+"143 505 CURVE SMOOTH",
+"116 505 OFFCURVE",
+"95 484 OFFCURVE",
+"95 458 CURVE SMOOTH",
+"95 433 OFFCURVE",
+"115 410 OFFCURVE",
+"143 410 CURVE SMOOTH",
+"167 410 OFFCURVE",
+"191 432 OFFCURVE",
+"191 459 CURVE SMOOTH"
+);
+},
+{
+closed = 1;
+nodes = (
+"1011 484 OFFCURVE",
+"990 506 OFFCURVE",
+"964 506 CURVE SMOOTH",
+"940 506 OFFCURVE",
+"915 484 OFFCURVE",
+"915 457 CURVE SMOOTH",
+"915 433 OFFCURVE",
+"936 411 OFFCURVE",
+"964 411 CURVE SMOOTH",
+"990 411 OFFCURVE",
+"1011 433 OFFCURVE",
+"1011 458 CURVE SMOOTH"
+);
+},
+{
+closed = 1;
+nodes = (
+"222 328 OFFCURVE",
+"200 348 OFFCURVE",
+"174 348 CURVE SMOOTH",
+"147 348 OFFCURVE",
+"126 326 OFFCURVE",
+"126 302 CURVE SMOOTH",
+"126 275 OFFCURVE",
+"149 253 OFFCURVE",
+"174 253 CURVE SMOOTH",
+"201 253 OFFCURVE",
+"222 277 OFFCURVE",
+"222 302 CURVE SMOOTH"
+);
+},
+{
+closed = 1;
+nodes = (
+"980 642 OFFCURVE",
+"955 663 OFFCURVE",
+"931 663 CURVE SMOOTH",
+"904 663 OFFCURVE",
+"885 638 OFFCURVE",
+"885 614 CURVE SMOOTH",
+"885 588 OFFCURVE",
+"907 567 OFFCURVE",
+"931 567 CURVE SMOOTH",
+"959 567 OFFCURVE",
+"980 591 OFFCURVE",
+"980 615 CURVE SMOOTH"
+);
+},
+{
+closed = 1;
+nodes = (
+"310 195 OFFCURVE",
+"291 215 OFFCURVE",
+"263 215 CURVE SMOOTH",
+"238 215 OFFCURVE",
+"215 190 OFFCURVE",
+"215 168 CURVE SMOOTH",
+"215 143 OFFCURVE",
+"238 120 OFFCURVE",
+"263 120 CURVE SMOOTH",
+"289 120 OFFCURVE",
+"310 143 OFFCURVE",
+"310 168 CURVE SMOOTH"
+);
+},
+{
+closed = 1;
+nodes = (
+"890 774 OFFCURVE",
+"870 796 OFFCURVE",
+"843 796 CURVE SMOOTH",
+"815 796 OFFCURVE",
+"796 773 OFFCURVE",
+"796 748 CURVE SMOOTH",
+"796 724 OFFCURVE",
+"817 700 OFFCURVE",
+"843 700 CURVE SMOOTH",
+"869 700 OFFCURVE",
+"890 722 OFFCURVE",
+"890 748 CURVE SMOOTH"
+);
+},
+{
+closed = 1;
+nodes = (
+"444 102 OFFCURVE",
+"423 126 OFFCURVE",
+"396 126 CURVE SMOOTH",
+"370 126 OFFCURVE",
+"348 102 OFFCURVE",
+"348 78 CURVE SMOOTH",
+"348 55 OFFCURVE",
+"370 31 OFFCURVE",
+"396 31 CURVE SMOOTH",
+"420 31 OFFCURVE",
+"444 51 OFFCURVE",
+"444 78 CURVE SMOOTH"
+);
+},
+{
+closed = 1;
+nodes = (
+"758 861 OFFCURVE",
+"737 885 OFFCURVE",
+"710 885 CURVE SMOOTH",
+"684 885 OFFCURVE",
+"663 862 OFFCURVE",
+"663 838 CURVE SMOOTH",
+"663 814 OFFCURVE",
+"683 789 OFFCURVE",
+"710 789 CURVE SMOOTH",
+"734 789 OFFCURVE",
+"758 809 OFFCURVE",
+"758 836 CURVE SMOOTH"
+);
+},
+{
+closed = 1;
+nodes = (
+"601 73 OFFCURVE",
+"579 95 OFFCURVE",
+"553 95 CURVE SMOOTH",
+"527 95 OFFCURVE",
+"506 73 OFFCURVE",
+"506 47 CURVE SMOOTH",
+"506 21 OFFCURVE",
+"527 0 OFFCURVE",
+"553 0 CURVE SMOOTH",
+"579 0 OFFCURVE",
+"601 21 OFFCURVE",
+"601 47 CURVE SMOOTH"
+);
+},
+{
+closed = 1;
+nodes = (
+"601 894 OFFCURVE",
+"579 916 OFFCURVE",
+"553 916 CURVE SMOOTH",
+"527 916 OFFCURVE",
+"506 894 OFFCURVE",
+"506 868 CURVE SMOOTH",
+"506 842 OFFCURVE",
+"527 821 OFFCURVE",
+"553 821 CURVE SMOOTH",
+"579 821 OFFCURVE",
+"601 842 OFFCURVE",
+"601 868 CURVE SMOOTH"
+);
+}
+);
+width = 1106;
+},
+{
+anchors = (
+{
+name = H;
+position = "{553, 0}";
+},
+{
+name = L;
+position = "{553, -100}";
+},
+{
+name = O;
+position = "{810, 0}";
+},
+{
+name = U;
+position = "{553, 1000}";
+}
+);
+layerId = master02;
+paths = (
+{
+closed = 1;
+nodes = (
+"443 864 OFFCURVE",
+"423 885 OFFCURVE",
+"398 885 CURVE SMOOTH",
+"371 885 OFFCURVE",
+"348 861 OFFCURVE",
+"348 837 CURVE SMOOTH",
+"348 809 OFFCURVE",
+"372 789 OFFCURVE",
+"398 789 CURVE SMOOTH",
+"425 789 OFFCURVE",
+"443 812 OFFCURVE",
+"443 837 CURVE SMOOTH"
+);
+},
+{
+closed = 1;
+nodes = (
+"758 106 OFFCURVE",
+"736 127 OFFCURVE",
+"710 127 CURVE SMOOTH",
+"685 127 OFFCURVE",
+"662 103 OFFCURVE",
+"662 80 CURVE SMOOTH",
+"662 52 OFFCURVE",
+"686 31 OFFCURVE",
+"710 31 CURVE SMOOTH",
+"737 31 OFFCURVE",
+"758 55 OFFCURVE",
+"758 79 CURVE SMOOTH"
+);
+},
+{
+closed = 1;
+nodes = (
+"310 775 OFFCURVE",
+"288 796 OFFCURVE",
+"263 796 CURVE SMOOTH",
+"238 796 OFFCURVE",
+"215 774 OFFCURVE",
+"215 747 CURVE SMOOTH",
+"215 722 OFFCURVE",
+"236 701 OFFCURVE",
+"263 701 CURVE SMOOTH",
+"291 701 OFFCURVE",
+"310 720 OFFCURVE",
+"310 749 CURVE SMOOTH"
+);
+},
+{
+closed = 1;
+nodes = (
+"891 197 OFFCURVE",
+"870 215 OFFCURVE",
+"843 215 CURVE SMOOTH",
+"817 215 OFFCURVE",
+"795 194 OFFCURVE",
+"795 168 CURVE SMOOTH",
+"795 143 OFFCURVE",
+"816 121 OFFCURVE",
+"843 121 CURVE SMOOTH",
+"871 121 OFFCURVE",
+"891 143 OFFCURVE",
+"891 168 CURVE SMOOTH"
+);
+},
+{
+closed = 1;
+nodes = (
+"222 640 OFFCURVE",
+"199 663 OFFCURVE",
+"173 663 CURVE SMOOTH",
+"149 663 OFFCURVE",
+"126 642 OFFCURVE",
+"126 615 CURVE SMOOTH",
+"126 591 OFFCURVE",
+"145 567 OFFCURVE",
+"173 567 CURVE SMOOTH",
+"197 567 OFFCURVE",
+"222 587 OFFCURVE",
+"222 613 CURVE SMOOTH"
+);
+},
+{
+closed = 1;
+nodes = (
+"980 327 OFFCURVE",
+"957 348 OFFCURVE",
+"932 348 CURVE SMOOTH",
+"908 348 OFFCURVE",
+"884 332 OFFCURVE",
+"884 301 CURVE SMOOTH",
+"884 277 OFFCURVE",
+"902 254 OFFCURVE",
+"932 254 CURVE SMOOTH",
+"957 254 OFFCURVE",
+"980 274 OFFCURVE",
+"980 301 CURVE SMOOTH"
+);
+},
+{
+closed = 1;
+nodes = (
+"191 484 OFFCURVE",
+"168 505 OFFCURVE",
+"143 505 CURVE SMOOTH",
+"116 505 OFFCURVE",
+"95 484 OFFCURVE",
+"95 458 CURVE SMOOTH",
+"95 433 OFFCURVE",
+"115 410 OFFCURVE",
+"143 410 CURVE SMOOTH",
+"167 410 OFFCURVE",
+"191 432 OFFCURVE",
+"191 459 CURVE SMOOTH"
+);
+},
+{
+closed = 1;
+nodes = (
+"1011 484 OFFCURVE",
+"990 506 OFFCURVE",
+"964 506 CURVE SMOOTH",
+"940 506 OFFCURVE",
+"915 484 OFFCURVE",
+"915 457 CURVE SMOOTH",
+"915 433 OFFCURVE",
+"936 411 OFFCURVE",
+"964 411 CURVE SMOOTH",
+"990 411 OFFCURVE",
+"1011 433 OFFCURVE",
+"1011 458 CURVE SMOOTH"
+);
+},
+{
+closed = 1;
+nodes = (
+"222 328 OFFCURVE",
+"200 348 OFFCURVE",
+"174 348 CURVE SMOOTH",
+"147 348 OFFCURVE",
+"126 326 OFFCURVE",
+"126 302 CURVE SMOOTH",
+"126 275 OFFCURVE",
+"149 253 OFFCURVE",
+"174 253 CURVE SMOOTH",
+"201 253 OFFCURVE",
+"222 277 OFFCURVE",
+"222 302 CURVE SMOOTH"
+);
+},
+{
+closed = 1;
+nodes = (
+"980 642 OFFCURVE",
+"955 663 OFFCURVE",
+"931 663 CURVE SMOOTH",
+"904 663 OFFCURVE",
+"885 638 OFFCURVE",
+"885 614 CURVE SMOOTH",
+"885 588 OFFCURVE",
+"907 567 OFFCURVE",
+"931 567 CURVE SMOOTH",
+"959 567 OFFCURVE",
+"980 591 OFFCURVE",
+"980 615 CURVE SMOOTH"
+);
+},
+{
+closed = 1;
+nodes = (
+"310 195 OFFCURVE",
+"291 215 OFFCURVE",
+"263 215 CURVE SMOOTH",
+"238 215 OFFCURVE",
+"215 190 OFFCURVE",
+"215 168 CURVE SMOOTH",
+"215 143 OFFCURVE",
+"238 120 OFFCURVE",
+"263 120 CURVE SMOOTH",
+"289 120 OFFCURVE",
+"310 143 OFFCURVE",
+"310 168 CURVE SMOOTH"
+);
+},
+{
+closed = 1;
+nodes = (
+"890 774 OFFCURVE",
+"870 796 OFFCURVE",
+"843 796 CURVE SMOOTH",
+"815 796 OFFCURVE",
+"796 773 OFFCURVE",
+"796 748 CURVE SMOOTH",
+"796 724 OFFCURVE",
+"817 700 OFFCURVE",
+"843 700 CURVE SMOOTH",
+"869 700 OFFCURVE",
+"890 722 OFFCURVE",
+"890 748 CURVE SMOOTH"
+);
+},
+{
+closed = 1;
+nodes = (
+"444 102 OFFCURVE",
+"423 126 OFFCURVE",
+"396 126 CURVE SMOOTH",
+"370 126 OFFCURVE",
+"348 102 OFFCURVE",
+"348 78 CURVE SMOOTH",
+"348 55 OFFCURVE",
+"370 31 OFFCURVE",
+"396 31 CURVE SMOOTH",
+"420 31 OFFCURVE",
+"444 51 OFFCURVE",
+"444 78 CURVE SMOOTH"
+);
+},
+{
+closed = 1;
+nodes = (
+"758 861 OFFCURVE",
+"737 885 OFFCURVE",
+"710 885 CURVE SMOOTH",
+"684 885 OFFCURVE",
+"663 862 OFFCURVE",
+"663 838 CURVE SMOOTH",
+"663 814 OFFCURVE",
+"683 789 OFFCURVE",
+"710 789 CURVE SMOOTH",
+"734 789 OFFCURVE",
+"758 809 OFFCURVE",
+"758 836 CURVE SMOOTH"
+);
+},
+{
+closed = 1;
+nodes = (
+"601 73 OFFCURVE",
+"579 95 OFFCURVE",
+"553 95 CURVE SMOOTH",
+"527 95 OFFCURVE",
+"506 73 OFFCURVE",
+"506 47 CURVE SMOOTH",
+"506 21 OFFCURVE",
+"527 0 OFFCURVE",
+"553 0 CURVE SMOOTH",
+"579 0 OFFCURVE",
+"601 21 OFFCURVE",
+"601 47 CURVE SMOOTH"
+);
+},
+{
+closed = 1;
+nodes = (
+"601 894 OFFCURVE",
+"579 916 OFFCURVE",
+"553 916 CURVE SMOOTH",
+"527 916 OFFCURVE",
+"506 894 OFFCURVE",
+"506 868 CURVE SMOOTH",
+"506 842 OFFCURVE",
+"527 821 OFFCURVE",
+"553 821 CURVE SMOOTH",
+"579 821 OFFCURVE",
+"601 842 OFFCURVE",
+"601 868 CURVE SMOOTH"
+);
+}
+);
+width = 1106;
+}
+);
+unicode = 25CC;
+},
+{
+glyphname = Hyphen;
+layers = (
+{
+anchors = (
+{
+name = U;
+position = "{430, 1100}";
+}
+);
+layerId = master01;
+paths = (
+{
+closed = 1;
+nodes = (
+"780 555 LINE",
+"780 705 LINE",
+"80 705 LINE",
+"80 555 LINE"
+);
+}
+);
+width = 860;
+},
+{
+anchors = (
+{
+name = U;
+position = "{440, 1100}";
+}
+);
+layerId = master02;
+paths = (
+{
+closed = 1;
+nodes = (
+"810 525 LINE",
+"810 735 LINE",
+"70 735 LINE",
+"70 525 LINE"
+);
+}
+);
+width = 880;
+}
+);
+unicode = 2010;
+},
+{
+glyphname = NonBreakingHyphen;
+layers = (
+{
+anchors = (
+{
+name = U;
+position = "{430, 1100}";
+}
+);
+components = (
+{
+name = HyphenMinus;
+}
+);
+layerId = master01;
+width = 860;
+},
+{
+anchors = (
+{
+name = U;
+position = "{450, 1100}";
+}
+);
+components = (
+{
+name = HyphenMinus;
+}
+);
+layerId = master02;
+width = 895;
+}
+);
+unicode = 2011;
+},
+{
+glyphname = Hyphen_Soft;
+layers = (
+{
+anchors = (
+{
+name = U;
+position = "{430, 1100}";
+}
+);
+components = (
+{
+name = HyphenMinus;
+}
+);
+layerId = master01;
+width = 860;
+},
+{
+anchors = (
+{
+name = U;
+position = "{450, 1100}";
+}
+);
+components = (
+{
+name = HyphenMinus;
+}
+);
+layerId = master02;
+width = 895;
+}
+);
+unicode = 00AD;
+},
+{
+glyphname = CombAcute;
+layers = (
+{
+anchors = (
+{
+name = U;
+position = "{-570, 1635}";
+},
+{
+name = _U;
+position = "{-570, 1100}";
+}
+);
+layerId = master01;
+paths = (
+{
+closed = 1;
+nodes = (
+"-750 1170 LINE",
+"-590 1170 LINE",
+"-170 1600 LINE",
+"-400 1600 LINE"
+);
+}
+);
+width = 0;
+},
+{
+anchors = (
+{
+name = U;
+position = "{-600, 1635}";
+},
+{
+name = _U;
+position = "{-540, 1100}";
+}
+);
+layerId = master02;
+paths = (
+{
+closed = 1;
+nodes = (
+"-760 1200 LINE",
+"-520 1200 LINE",
+"-120 1600 LINE",
+"-470 1600 LINE"
+);
+}
+);
+width = 0;
+}
+);
+unicode = 0301;
+},
+{
+glyphname = CombGrave;
+layers = (
+{
+anchors = (
+{
+name = U;
+position = "{-550, 1635}";
+},
+{
+name = _U;
+position = "{-550, 1100}";
+}
+);
+layerId = master01;
+paths = (
+{
+closed = 1;
+nodes = (
+"-520 1170 LINE",
+"-360 1170 LINE",
+"-710 1600 LINE",
+"-940 1600 LINE"
+);
+}
+);
+width = 0;
+},
+{
+anchors = (
+{
+name = U;
+position = "{-590, 1635}";
+},
+{
+name = _U;
+position = "{-630, 1100}";
+}
+);
+layerId = master02;
+paths = (
+{
+closed = 1;
+nodes = (
+"-650 1200 LINE",
+"-410 1200 LINE",
+"-700 1600 LINE",
+"-1050 1600 LINE"
+);
+}
+);
+width = 0;
+}
+);
+unicode = 0300;
+},
+{
+glyphname = CombCircum;
+layers = (
+{
+anchors = (
+{
+name = U;
+position = "{-570, 1635}";
+},
+{
+name = _U;
+position = "{-570, 1100}";
+}
+);
+layerId = master01;
+paths = (
+{
+closed = 1;
+nodes = (
+"-570 1450 LINE",
+"-295 1170 LINE",
+"-145 1170 LINE",
+"-485 1600 LINE",
+"-655 1600 LINE",
+"-995 1170 LINE",
+"-845 1170 LINE"
+);
+}
+);
+width = 0;
+},
+{
+anchors = (
+{
+name = U;
+position = "{-588, 1635}";
+},
+{
+name = _U;
+position = "{-580, 1100}";
+}
+);
+layerId = master02;
+paths = (
+{
+closed = 1;
+nodes = (
+"-430 1600 LINE",
+"-730 1600 LINE",
+"-1020 1200 LINE",
+"-780 1200 LINE",
+"-580 1430 LINE",
+"-380 1200 LINE",
+"-140 1200 LINE"
+);
+}
+);
+width = 0;
+}
+);
+unicode = 0302;
+},
+{
+glyphname = CombTilde;
+layers = (
+{
+anchors = (
+{
+name = U;
+position = "{-575, 1475}";
+},
+{
+name = _U;
+position = "{-575, 1100}";
+}
+);
+layerId = master01;
+paths = (
+{
+closed = 1;
+nodes = (
+"-815 1254 OFFCURVE",
+"-784 1290 OFFCURVE",
+"-735 1290 CURVE SMOOTH",
+"-698 1290 OFFCURVE",
+"-657 1274 OFFCURVE",
+"-580 1238 CURVE SMOOTH",
+"-519 1210 OFFCURVE",
+"-466 1190 OFFCURVE",
+"-413 1190 CURVE SMOOTH",
+"-290 1190 OFFCURVE",
+"-215 1312 OFFCURVE",
+"-215 1440 CURVE",
+"-320 1440 LINE",
+"-327 1394 OFFCURVE",
+"-358 1355 OFFCURVE",
+"-405 1355 CURVE SMOOTH",
+"-447 1355 OFFCURVE",
+"-488 1374 OFFCURVE",
+"-560 1403 CURVE SMOOTH",
+"-630 1431 OFFCURVE",
+"-677 1455 OFFCURVE",
+"-733 1455 CURVE SMOOTH",
+"-852 1455 OFFCURVE",
+"-925 1327 OFFCURVE",
+"-925 1205 CURVE",
+"-820 1205 LINE"
+);
+}
+);
+width = 0;
+},
+{
+anchors = (
+{
+name = U;
+position = "{-580, 1490}";
+},
+{
+name = _U;
+position = "{-580, 1100}";
+}
+);
+layerId = master02;
+paths = (
+{
+closed = 1;
+nodes = (
+"-824 1232 OFFCURVE",
+"-803 1280 OFFCURVE",
+"-753 1280 CURVE SMOOTH",
+"-710 1280 OFFCURVE",
+"-653 1264 OFFCURVE",
+"-570 1229 CURVE SMOOTH",
+"-500 1199 OFFCURVE",
+"-448 1180 OFFCURVE",
+"-386 1180 CURVE SMOOTH",
+"-250 1180 OFFCURVE",
+"-155 1307 OFFCURVE",
+"-155 1480 CURVE",
+"-310 1480 LINE",
+"-318 1438 OFFCURVE",
+"-340 1390 OFFCURVE",
+"-387 1390 CURVE SMOOTH",
+"-435 1390 OFFCURVE",
+"-472 1408 OFFCURVE",
+"-550 1437 CURVE SMOOTH",
+"-629 1466 OFFCURVE",
+"-695 1490 OFFCURVE",
+"-760 1490 CURVE SMOOTH",
+"-892 1490 OFFCURVE",
+"-985 1349 OFFCURVE",
+"-985 1190 CURVE",
+"-830 1190 LINE"
+);
+}
+);
+width = 0;
+}
+);
+unicode = 0303;
+},
+{
+glyphname = CombDiaer;
+layers = (
+{
+anchors = (
+{
+name = U;
+position = "{-570, 1505}";
+},
+{
+name = _U;
+position = "{-570, 1100}";
+}
+);
+layerId = master01;
+paths = (
+{
+closed = 1;
+nodes = (
+"-490 1271 OFFCURVE",
+"-434 1210 OFFCURVE",
+"-360 1210 CURVE SMOOTH",
+"-285 1210 OFFCURVE",
+"-230 1271 OFFCURVE",
+"-230 1345 CURVE SMOOTH",
+"-230 1419 OFFCURVE",
+"-285 1480 OFFCURVE",
+"-360 1480 CURVE SMOOTH",
+"-434 1480 OFFCURVE",
+"-490 1419 OFFCURVE",
+"-490 1345 CURVE SMOOTH"
+);
+},
+{
+closed = 1;
+nodes = (
+"-910 1271 OFFCURVE",
+"-854 1210 OFFCURVE",
+"-780 1210 CURVE SMOOTH",
+"-705 1210 OFFCURVE",
+"-650 1271 OFFCURVE",
+"-650 1345 CURVE SMOOTH",
+"-650 1419 OFFCURVE",
+"-705 1480 OFFCURVE",
+"-780 1480 CURVE SMOOTH",
+"-854 1480 OFFCURVE",
+"-910 1419 OFFCURVE",
+"-910 1345 CURVE SMOOTH"
+);
+}
+);
+width = 0;
+},
+{
+anchors = (
+{
+name = U;
+position = "{-580, 1585}";
+},
+{
+name = _U;
+position = "{-580, 1100}";
+}
+);
+layerId = master02;
+paths = (
+{
+closed = 1;
+nodes = (
+"-510 1281 OFFCURVE",
+"-436 1210 OFFCURVE",
+"-335 1210 CURVE SMOOTH",
+"-233 1210 OFFCURVE",
+"-160 1281 OFFCURVE",
+"-160 1385 CURVE SMOOTH",
+"-160 1487 OFFCURVE",
+"-233 1560 OFFCURVE",
+"-335 1560 CURVE SMOOTH",
+"-436 1560 OFFCURVE",
+"-510 1487 OFFCURVE",
+"-510 1385 CURVE SMOOTH"
+);
+},
+{
+closed = 1;
+nodes = (
+"-1000 1281 OFFCURVE",
+"-926 1210 OFFCURVE",
+"-825 1210 CURVE SMOOTH",
+"-723 1210 OFFCURVE",
+"-650 1281 OFFCURVE",
+"-650 1385 CURVE SMOOTH",
+"-650 1487 OFFCURVE",
+"-723 1560 OFFCURVE",
+"-825 1560 CURVE SMOOTH",
+"-926 1560 OFFCURVE",
+"-1000 1487 OFFCURVE",
+"-1000 1385 CURVE SMOOTH"
+);
+}
+);
+width = 0;
+}
+);
+unicode = 0308;
+},
+{
+glyphname = CombRingAbv;
+layers = (
+{
+anchors = (
+{
+name = U;
+position = "{-570, 1635}";
+},
+{
+name = _U;
+position = "{-572, 1100}";
+}
+);
+layerId = master01;
+paths = (
+{
+closed = 1;
+nodes = (
+"-470 1325 OFFCURVE",
+"-510 1285 OFFCURVE",
+"-570 1285 CURVE SMOOTH",
+"-630 1285 OFFCURVE",
+"-670 1325 OFFCURVE",
+"-670 1385 CURVE SMOOTH",
+"-670 1445 OFFCURVE",
+"-630 1485 OFFCURVE",
+"-570 1485 CURVE SMOOTH",
+"-510 1485 OFFCURVE",
+"-470 1445 OFFCURVE",
+"-470 1385 CURVE SMOOTH"
+);
+},
+{
+closed = 1;
+nodes = (
+"-785 1265 OFFCURVE",
+"-690 1170 OFFCURVE",
+"-570 1170 CURVE SMOOTH",
+"-450 1170 OFFCURVE",
+"-355 1265 OFFCURVE",
+"-355 1385 CURVE SMOOTH",
+"-355 1505 OFFCURVE",
+"-450 1600 OFFCURVE",
+"-570 1600 CURVE SMOOTH",
+"-690 1600 OFFCURVE",
+"-785 1505 OFFCURVE",
+"-785 1385 CURVE SMOOTH"
+);
+}
+);
+width = 0;
+},
+{
+anchors = (
+{
+name = U;
+position = "{-570, 1635}";
+},
+{
+name = _U;
+position = "{-572, 1100}";
+}
+);
+layerId = master02;
+paths = (
+{
+closed = 1;
+nodes = (
+"-475 1345 OFFCURVE",
+"-515 1305 OFFCURVE",
+"-570 1305 CURVE SMOOTH",
+"-625 1305 OFFCURVE",
+"-665 1345 OFFCURVE",
+"-665 1400 CURVE SMOOTH",
+"-665 1455 OFFCURVE",
+"-625 1495 OFFCURVE",
+"-570 1495 CURVE SMOOTH",
+"-515 1495 OFFCURVE",
+"-475 1455 OFFCURVE",
+"-475 1400 CURVE SMOOTH"
+);
+},
+{
+closed = 1;
+nodes = (
+"-815 1260 OFFCURVE",
+"-710 1160 OFFCURVE",
+"-570 1160 CURVE SMOOTH",
+"-430 1160 OFFCURVE",
+"-325 1260 OFFCURVE",
+"-325 1400 CURVE SMOOTH",
+"-325 1540 OFFCURVE",
+"-430 1640 OFFCURVE",
+"-570 1640 CURVE SMOOTH",
+"-710 1640 OFFCURVE",
+"-815 1540 OFFCURVE",
+"-815 1400 CURVE SMOOTH"
+);
+}
+);
+width = 0;
+}
+);
+unicode = 030A;
+}
+);
+instances = (
+{
+interpolationWeight = 400;
+instanceInterpolations = {
+master01 = 1;
+};
+name = Regular;
+},
+{
+interpolationWeight = 700;
+instanceInterpolations = {
+master02 = 1;
+};
+name = Bold;
+}
+);
+manufacturer = "SIL International";
+manufacturerURL = "http://scripts.sil.org";
+unitsPerEm = 2048;
+versionMajor = 5;
+versionMinor = 550;
+}
diff --git a/tests/input/font-psf-test/source/glyph_data.csv b/tests/input/font-psf-test/source/glyph_data.csv
new file mode 100644
index 0000000..bf6d5e4
--- /dev/null
+++ b/tests/input/font-psf-test/source/glyph_data.csv
@@ -0,0 +1,115 @@
+glyph_name,ps_name,sort_final
+.notdef,.notdef,0
+.null,.null,1
+nonmarkingreturn,nonmarkingreturn,2
+Space,space,3
+ExclamationMrk,exclam,4
+QuotMrk,quotedbl,5
+NumSgn,numbersign,6
+DollarSgn,dollar,7
+PercentSgn,percent,8
+Ampersand,ampersand,9
+Apos,quotesingle,10
+LftParen,parenleft,11
+RtParen,parenright,12
+Asterisk,asterisk,13
+PlusSgn,plus,14
+Comma,comma,15
+HyphenMinus,hyphen,16
+FullStop,period,17
+Solidus,slash,18
+DigitZero,zero,19
+DigitOne,one,20
+DigitTwo,two,21
+DigitThree,three,22
+DigitFour,four,23
+DigitFive,five,24
+DigitSix,six,25
+DigitSeven,seven,26
+DigitEight,eight,27
+DigitNine,nine,28
+Colon,colon,29
+Semicolon,semicolon,30
+LTSgn,less,31
+EqSgn,equal,32
+GTSgn,greater,33
+QstnMrk,question,34
+AtSgn,at,35
+LtnCapA,A,36
+LtnCapA.alt,A,36
+LtnCapB,B,37
+LtnCapC,C,38
+LtnCapD,D,39
+LtnCapE,E,40
+LtnCapF,F,41
+LtnCapG,G,42
+LtnCapH,H,43
+LtnCapI,I,44
+LtnCapJ,J,45
+LtnCapK,K,46
+LtnCapL,L,47
+LtnCapM,M,48
+LtnCapN,N,49
+LtnCapO,O,50
+LtnCapP,P,51
+LtnCapQ,Q,52
+LtnCapR,R,53
+LtnCapS,S,54
+LtnCapT,T,55
+LtnCapU,U,56
+LtnCapV,V,57
+LtnCapW,W,58
+LtnCapX,X,59
+LtnCapY,Y,60
+LftSqrBrac,bracketleft,62
+ReverseSolidus,backslash,63
+RtSqrBrac,bracketright,64
+CircumAccent,asciicircum,65
+LowLine,underscore,66
+GraveAccent,grave,67
+LtnSmA,a,68
+LtnSmB,b,69
+LtnSmC,c,70
+LtnSmD,d,71
+LtnSmE,e,72
+LtnSmF,f,73
+LtnSmG,g,74
+LtnSmH,h,75
+LtnSmI,i,76
+LtnSmJ,j,77
+LtnSmK,k,78
+LtnSmL,l,79
+LtnSmM,m,80
+LtnSmN,n,81
+LtnSmO,o,82
+LtnSmP,p,83
+LtnSmQ,q,84
+LtnSmR,r,85
+LtnSmS,s,86
+LtnSmT,t,87
+LtnSmU,u,88
+LtnSmV,v,89
+LtnSmW,w,90
+LtnSmX,x,91
+LtnSmY,y,92
+LftCurlyBrac,braceleft,94
+VertLine,bar,95
+RtCurlyBrac,braceright,96
+Tilde,asciitilde,97
+LtnCapADiaer,Adieresis,98
+LtnSmAAcute,aacute,105
+LtnSmAGrave,agrave,106
+LtnSmACircum,acircumflex,107
+LtnSmADiaer,adieresis,108
+LtnSmATilde,atilde,109
+LtnSmARingAbv,aring,110
+DottedCirc,uni25CC,210
+Hyphen,uni2010,5670.1
+NonBreakingHyphen,uni2011,5670.2
+Hyphen_Soft,uni00AD,5680.6
+CombAcute,acutecomb,6000.5
+CombGrave,gravecomb,6050.5
+CombCircum,uni0302,6110.15
+CombTilde,tildecomb,6200.16
+CombDiaer,uni0308,6400.3
+CombRingAbv,uni030A,6450.4 \ No newline at end of file
diff --git a/tests/input/font-psf-test/source/logs/readme.txt b/tests/input/font-psf-test/source/logs/readme.txt
new file mode 100644
index 0000000..572dc6c
--- /dev/null
+++ b/tests/input/font-psf-test/source/logs/readme.txt
@@ -0,0 +1 @@
+This folder is for only temporary use for log files \ No newline at end of file
diff --git a/tests/input/font-psf-test/wscript b/tests/input/font-psf-test/wscript
new file mode 100644
index 0000000..3ad1580
--- /dev/null
+++ b/tests/input/font-psf-test/wscript
@@ -0,0 +1,27 @@
+#!/usr/bin/python
+# this is a smith configuration file
+
+# output folders use smith defaults and don't need to be set here
+
+# set the version control system for srcdist
+VCS = 'git'
+
+# set the font name, version, licensing and description
+APPNAME="PsfTest"
+
+DESC_SHORT = "Test font for UFO workflows"
+DESC_LONG = """
+Psf Test is a Latin script font family for testing UFO-based workflows.
+It is not intended to be generally useful as an installable font family, and
+may change significantly without notice. It will always be experimental and
+may not work as you expect!
+"""
+DESC_NAME = "PsfTest"
+
+getufoinfo('source/PsfTest-Regular.ufo')
+
+fontfamily=APPNAME
+for dspace in ('Roman', 'Italic'):
+ designspace('source/' + fontfamily + dspace + '.designspace',
+ target = "${DS:FILENAME_BASE}.ttf"
+ )
diff --git a/tests/input/glyph_data.csv b/tests/input/glyph_data.csv
new file mode 100644
index 0000000..33d1396
--- /dev/null
+++ b/tests/input/glyph_data.csv
@@ -0,0 +1,28 @@
+glyph_name,ps_name,sort_final
+AcuteAccent,acute,141
+Bullet,bullet,135
+BulletOperator,uni2219,5390.4
+CircumAccent,asciicircum,65
+CombAcute,acutecomb,6000.5
+DblAcuteAccent,hungarumlaut,223
+HyphenMinus,hyphen,16
+LtnCapAAcute,Aacute,201
+LtnCapEAcute,Eacute,144
+LtnCapIAcute,Iacute,204
+LtnCapOAcute,Oacute,208
+LtnCapUAcute,Uacute,212
+LtnCapYAcute,Yacute,3450.311
+LtnSmAAcute,aacute,105
+LtnSmEAcute,eacute,112
+LtnSmIAcute,iacute,116
+LtnSmOAcute,oacute,121
+LtnSmUAcute,uacute,126
+LtnSmYAcute,yacute,3400.311
+ModCircumAccent,circumflex,216
+nonmarkingreturn,nonmarkingreturn,2
+ReverseSolidus,backslash,63
+SupOne,onesuperior,4010.3
+SupThree,threesuperior,4030.3
+VulgFracOneHalf,onehalf,4120.1
+VulgFracOneQuarter,onequarter,4140.1
+VulgFracThreeQuarters,threequarters,4340.1
diff --git a/tests/input/issue65.feax b/tests/input/issue65.feax
new file mode 100644
index 0000000..25914c0
--- /dev/null
+++ b/tests/input/issue65.feax
@@ -0,0 +1,4 @@
+lookup ReorderInsert {
+ sub uni1C00' uni1C34 by uni1C34 uni1C00;
+} ReorderInsert;
+
diff --git a/tests/input/ligatures.feax b/tests/input/ligatures.feax
new file mode 100644
index 0000000..b4c8f43
--- /dev/null
+++ b/tests/input/ligatures.feax
@@ -0,0 +1,12 @@
+
+baseClass a <anchor 200 200> @TOP_1;
+baseClass fi <anchor 200 0> @BOTTOM_1;
+baseClass fi <anchor 400 0> @BOTTOM_2;
+markClass acute <anchor 0 200> @TOP;
+markClass circumflex <anchor 200 0> @BOTTOM;
+
+feature test {
+ pos ligature [a fi] @BOTTOM_1 mark @BOTTOM @TOP_1 mark @TOP
+ ligComponent @BOTTOM_2 mark @BOTTOM;
+} test;
+
diff --git a/tests/input/psfbuildcomp.txt b/tests/input/psfbuildcomp.txt
new file mode 100644
index 0000000..50a7f90
--- /dev/null
+++ b/tests/input/psfbuildcomp.txt
@@ -0,0 +1,30 @@
+# Copyright (c) 2008-2015, SIL International (http://www.sil.org) with Reserved Font Names 'Andika' and 'SIL'.
+# This Font Software is licensed under the SIL Open Font License, Version 1.1 (http://scripts.sil.org/OFL)
+# and is from the Andika Mtihani project (https://github.com/silnrsi/font-andika-mtihani)
+
+# Within each section, lines are in order of resulting Unicode value
+# Invented combinations are assigned Unicode values starting with E000
+# Version 2, DLR 2015-06-25 use & for joining two base glyphs
+#
+# Test & for joining two base glyphs
+LtnCapIJ = LtnCapI & LtnCapJ |0132
+LtnSmIJ = LtnSmI & LtnSmJ |0133
+#
+# Test base + diacritic@AP
+LtnCapCAcute = LtnSmC + CombAcute@U |0106
+LtnSmCAcute = LtnCapC + CombAcute@U |0107
+LtnCapCCircum = LtnCapC + CombCircum@U |0108
+LtnSmCCircum = LtnSmC + CombCircum@U |0109
+#
+# Test base + stacked diactrics (second diacritic attaching to first)
+LtnSmITildeGrave = LtnSmDotlessI + CombTilde@U + CombGrave@U | E000
+#
+#Test base + two diacritics attached to base (that is, second diacritic doesn't attach to first, but to base)
+LtnCapCAcuteCedilla = LtnCapC + CombCedilla@H + CombAcute@LtnCapC:U | 1E08
+LtnSmCAcuteCedilla = LtnSmC + CombCedilla@H + CombAcute@LtnSmC:U | 1E09
+#
+# Test ^200,200 (is this a realistic use of this function to add extra space on either side since the tilde is wider than the base character??)
+LtnSmITilde = LtnSmDotlessI + CombTilde@U ^200,200 | 0129
+#
+# Test three diacritics, ^200,200 and comment on end of line
+LtnSmITildeGraveCedilla = LtnSmDotlessI + CombCedilla@H + CombTilde@LtnSmDotlessI:U + CombGrave@U ^200,200 | E010 # i cedilla tilde grave
diff --git a/tests/input/psfcopyglyphs.csv b/tests/input/psfcopyglyphs.csv
new file mode 100644
index 0000000..eb456a6
--- /dev/null
+++ b/tests/input/psfcopyglyphs.csv
@@ -0,0 +1,7 @@
+glyph_name,newname,usv
+Ampersand,Ampergravel,3026
+Asterisk,Star,3027
+Colon,,3028
+LtnCapA.alt,,3029
+FullStop,Fullstart,
+
diff --git a/tests/input/psfdeleteglyphs.txt b/tests/input/psfdeleteglyphs.txt
new file mode 100644
index 0000000..0ab884c
--- /dev/null
+++ b/tests/input/psfdeleteglyphs.txt
@@ -0,0 +1,3 @@
+Apos
+Comma
+Missing
diff --git a/tests/input/psfgenftml.csv b/tests/input/psfgenftml.csv
new file mode 100644
index 0000000..9b48f28
--- /dev/null
+++ b/tests/input/psfgenftml.csv
@@ -0,0 +1,116 @@
+glyph_name,ps_name,sort_final,USV
+.notdef,.notdef,0,
+.null,.null,1,
+nonmarkingreturn,nonmarkingreturn,2,
+Space,space,3,0020
+ExclamationMrk,exclam,4,0021
+QuotMrk,quotedbl,5,0022
+NumSgn,numbersign,6,0023
+DollarSgn,dollar,7,0024
+PercentSgn,percent,8,0025
+Ampersand,ampersand,9,0026
+Apos,quotesingle,10,0027
+LftParen,parenleft,11,0028
+RtParen,parenright,12,0029
+Asterisk,asterisk,13,002A
+PlusSgn,plus,14,002B
+Comma,comma,15,002C
+HyphenMinus,hyphen,16,002D
+FullStop,period,17,002E
+Solidus,slash,18,002F
+DigitZero,zero,19,0030
+DigitOne,one,20,0031
+DigitTwo,two,21,0032
+DigitThree,three,22,0033
+DigitFour,four,23,0034
+DigitFive,five,24,0035
+DigitSix,six,25,0036
+DigitSeven,seven,26,0037
+DigitEight,eight,27,0038
+DigitNine,nine,28,0039
+Colon,colon,29,003A
+Semicolon,semicolon,30,003B
+LTSgn,less,31,003C
+EqSgn,equal,32,003D
+GTSgn,greater,33,003E
+QstnMrk,question,34,003F
+AtSgn,at,35,0040
+LtnCapA,A,36,0041
+LtnCapA.alt,A,36,
+LtnCapB,B,37,0042
+LtnCapC,C,38,0043
+LtnCapD,D,39,0044
+LtnCapE,E,40,0045
+LtnCapF,F,41,0046
+LtnCapG,G,42,0047
+LtnCapH,H,43,0048
+LtnCapI,I,44,0049
+LtnCapJ,J,45,004A
+LtnCapK,K,46,004B
+LtnCapL,L,47,004C
+LtnCapM,M,48,004D
+LtnCapN,N,49,004E
+LtnCapO,O,50,004F
+LtnCapP,P,51,0050
+LtnCapQ,Q,52,0051
+LtnCapR,R,53,0052
+LtnCapS,S,54,0053
+LtnCapT,T,55,0054
+LtnCapU,U,56,0055
+LtnCapV,V,57,0056
+LtnCapW,W,58,0057
+LtnCapX,X,59,0058
+LtnCapY,Y,60,0059
+LftSqrBrac,bracketleft,62,005B
+ReverseSolidus,backslash,63,005C
+RtSqrBrac,bracketright,64,005D
+CircumAccent,asciicircum,65,005E
+LowLine,underscore,66,005F
+GraveAccent,grave,67,0060
+LtnSmA,a,68,0061
+LtnSmB,b,69,0062
+LtnSmC,c,70,0063
+LtnSmD,d,71,0064
+LtnSmE,e,72,0065
+LtnSmF,f,73,0066
+LtnSmG,g,74,0067
+LtnSmH,h,75,0068
+LtnSmI,i,76,0069
+LtnSmJ,j,77,006A
+LtnSmK,k,78,006B
+LtnSmL,l,79,006C
+LtnSmM,m,80,006D
+LtnSmN,n,81,006E
+LtnSmO,o,82,006F
+LtnSmP,p,83,0070
+LtnSmQ,q,84,0071
+LtnSmR,r,85,0072
+LtnSmS,s,86,0073
+LtnSmT,t,87,0074
+LtnSmU,u,88,0075
+LtnSmV,v,89,0076
+LtnSmW,w,90,0077
+LtnSmX,x,91,0078
+LtnSmY,y,92,0079
+LftCurlyBrac,braceleft,94,007B
+VertLine,bar,95,007C
+RtCurlyBrac,braceright,96,007D
+Tilde,asciitilde,97,007E
+LtnCapADiaer,Adieresis,98,00C4
+LtnSmAAcute,aacute,105,00E1
+LtnSmAGrave,agrave,106,00E0
+LtnSmACircum,acircumflex,107,00E2
+LtnSmADiaer,adieresis,108,00E4
+LtnSmATilde,atilde,109,00E3
+LtnSmARingAbv,aring,110,00E5
+DottedCirc,uni25CC,210,25CC
+Hyphen,uni2010,5670.1,2010
+NonBreakingHyphen,uni2011,5670.2,2011
+Hyphen_Soft,uni00AD,5680.6,00AD
+CombAcute,acutecomb,6000.5,0301
+CombGrave,gravecomb,6050.5,0300
+CombCircum,uni0302,6110.15,0302
+CombTilde,tildecomb,6200.16,0303
+CombDiaer,uni0308,6400.3,0308
+CombRingAbv,uni030A,6450.4,030A
+,,,
diff --git a/tests/input/psfmakefea.feax b/tests/input/psfmakefea.feax
new file mode 100644
index 0000000..6de3523
--- /dev/null
+++ b/tests/input/psfmakefea.feax
@@ -0,0 +1,8 @@
+@base = [A a];
+@basex = [A.x a.x];
+@basey = [A.y a.y];
+
+feature alt {
+ sub @base from [@basex @basey];
+} alt;
+
diff --git a/tests/input/psfmakefea_2.feax b/tests/input/psfmakefea_2.feax
new file mode 100644
index 0000000..90fd24e
--- /dev/null
+++ b/tests/input/psfmakefea_2.feax
@@ -0,0 +1,11 @@
+def func(x, y) {
+ return x + y
+} func;
+
+feature test {
+do for a = [a1 a2 a3];
+ let b = "g"+str(func(int(a[1]), 4));
+ {
+ @c = [$b];
+ }
+} test;
diff --git a/tests/input/psfmakefea_3.feax b/tests/input/psfmakefea_3.feax
new file mode 100644
index 0000000..aef5249
--- /dev/null
+++ b/tests/input/psfmakefea_3.feax
@@ -0,0 +1,20 @@
+@Tooth2w3wBelowMedi = [toothedbelow2w3w.medi];
+@Tooth2w2wBelowMedi = [toothedbelow2w2w.medi];
+@Tooth3wBelowMedi = [toothedbelow3w.medi];
+@Tooth2wBelowMedi = [toothedbelow2w.medi];
+
+lookup _Insert2Kashidas {
+ sub @Tooth2w2wBelowMedi by kashida kashida @Tooth2w2wBelowMedi;
+} _Insert2Kashidas;
+
+lookup _InsertKashida {
+ sub @Tooth2w2wBelowMedi by kashida @Tooth2w2wBelowMedi;
+} _InsertKashida;
+
+lookup ToothKashidasMM {
+ lookupflag IgnoreMarks;
+ sub @Tooth2w3wBelowMedi' lookup _Insert2Kashidas @Tooth3wBelowMedi;
+ifinfo(styleName, "Bold") {
+ sub @Tooth2wBelowMedi' lookup _InsertKashida @Tooth2wBelowMedi; # BOLD
+}
+} ToothKashidasMM;
diff --git a/tests/input/psfmakewoffmetadata.txt b/tests/input/psfmakewoffmetadata.txt
new file mode 100644
index 0000000..18e41b2
--- /dev/null
+++ b/tests/input/psfmakewoffmetadata.txt
@@ -0,0 +1,40 @@
+FONTLOG
+Pysilfont Test font
+===================
+
+This file provides detailed information on the Pysilfont Test font
+
+It is meant purely for code testing purposes and is not intended to be usable.
+
+For copyright and licensing information - including any Reserved Font
+Names - see OFL.txt.
+
+For practical information about using, modifying and redistributing this
+font see OFL-FAQ.txt.
+
+
+Basic Font Information
+----------------------
+
+There are intentional problems with the UFO!
+
+Features
+--------
+
+What features?
+
+Acknowledgements
+-----------------
+(There needs to be something in here to test psfmakewoffmetadata!)
+
+N: Victor Gaultney
+E: victor_gaultney@sil.org
+W: http://www.sil.org/~gaultney/
+D: Original Designer
+
+N: SIL font engineers
+E: http://scripts.sil.org/support
+W: http://scripts.sil.org/
+D: Graphite, OpenType, and TypeTuner code, and build support
+
+The Pysilfont test font is maintained by SIL International.
diff --git a/tests/input/psfrenameglyphs.csv b/tests/input/psfrenameglyphs.csv
new file mode 100644
index 0000000..2e1334d
--- /dev/null
+++ b/tests/input/psfrenameglyphs.csv
@@ -0,0 +1,3 @@
+Apos,Bpos
+Asterisk,Star
+Commer,NotThere
diff --git a/tests/input/psfsetassocfeat.csv b/tests/input/psfsetassocfeat.csv
new file mode 100644
index 0000000..21660ee
--- /dev/null
+++ b/tests/input/psfsetassocfeat.csv
@@ -0,0 +1,2 @@
+LtnCapA,fea1
+LtnCapU,fea2
diff --git a/tests/input/psfsetassocuids.csv b/tests/input/psfsetassocuids.csv
new file mode 100644
index 0000000..1351af7
--- /dev/null
+++ b/tests/input/psfsetassocuids.csv
@@ -0,0 +1,3 @@
+SupThree,00B4
+LtnCapU,00fA
+CircumAccent,003E
diff --git a/tests/input/psfsetunicodes.csv b/tests/input/psfsetunicodes.csv
new file mode 100644
index 0000000..9b4612b
--- /dev/null
+++ b/tests/input/psfsetunicodes.csv
@@ -0,0 +1,4 @@
+Ampersand,002A
+Asterisk,0026
+Notthere,003A
+Hyphen,002C
diff --git a/tests/input/psfsubset.csv b/tests/input/psfsubset.csv
new file mode 100644
index 0000000..6ef4b90
--- /dev/null
+++ b/tests/input/psfsubset.csv
@@ -0,0 +1,73 @@
+.notdef
+.null
+Ampersand
+Apos
+Asterisk
+AtSgn
+CircumAccent
+Colon
+CombAcute
+CombCircum
+CombDiaer
+CombGrave
+CombRingAbv
+CombTilde
+Comma
+DollarSgn
+DottedCirc
+EqSgn
+ExclamationMrk
+FullStop
+GraveAccent
+GTSgn
+Hyphen_Soft
+Hyphen
+HyphenMinus
+LftCurlyBrac
+LftParen
+LftSqrBrac
+LowLine
+LtnCapA
+LtnCapADiaer
+LtnCapB
+LtnCapC
+LtnCapD
+LtnCapE
+LtnCapF
+LtnCapG
+LtnCapH
+LtnCapI
+LtnCapJ
+LtnCapK
+LtnCapL
+LtnCapM
+LtnCapN
+LtnCapO
+LtnCapP
+LtnCapQ
+LtnCapR
+LtnCapS
+LtnCapT
+LtnCapU
+LtnCapV
+LtnCapW
+LtnCapX
+LtnCapY
+LtnSmA
+LTSgn
+NonBreakingHyphen
+nonmarkingreturn
+NumSgn
+PercentSgn
+PlusSgn
+QstnMrk
+QuotMrk
+ReverseSolidus
+RtCurlyBrac
+RtParen
+RtSqrBrac
+Semicolon
+Solidus
+Space
+Tilde
+VertLine
diff --git a/tests/localufos.csv.sample b/tests/localufos.csv.sample
new file mode 100644
index 0000000..3f63b3f
--- /dev/null
+++ b/tests/localufos.csv.sample
@@ -0,0 +1,6 @@
+# Local fonts to be used with pysilfont tests
+# File format: font-path,type
+# where type is "copy" or "insitu". Use copy for fonts likely to be updated during development
+/home/david/src/font-andika-mtihani/source/AndikaMtihani-Regular.ufo,copy
+/home/david/src/font-andika/source/Andika-Regular.ufo,insitu
+
diff --git a/tests/reference/fontparts/psfbuildcompgc.lg b/tests/reference/fontparts/psfbuildcompgc.lg
new file mode 100644
index 0000000..601efdc
--- /dev/null
+++ b/tests/reference/fontparts/psfbuildcompgc.lg
@@ -0,0 +1,2 @@
+2020-07-28 14:48:16 Progress: Running: psfbuildcompgc tests/input/font-psf-test/source/PsfTest-Regular.ufo -i tests/input/psfbuildcomp.txt -l local/testresults/fontparts/psfbuildcompgc.log
+2020-07-28 14:48:16 Progress: Opening file for input: tests/input/psfbuildcomp.txt
diff --git a/tests/reference/fontparts/psfbuildcompgc.ufo/fontinfo.plist b/tests/reference/fontparts/psfbuildcompgc.ufo/fontinfo.plist
new file mode 100644
index 0000000..f68e491
--- /dev/null
+++ b/tests/reference/fontparts/psfbuildcompgc.ufo/fontinfo.plist
@@ -0,0 +1,266 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+ <dict>
+ <key>ascender</key>
+ <integer>2100</integer>
+ <key>capHeight</key>
+ <real>1485.0</real>
+ <key>copyright</key>
+ <string>Copyright (c) 2004-2021 SIL International</string>
+ <key>descender</key>
+ <integer>-550</integer>
+ <key>familyName</key>
+ <string>Psf Test</string>
+ <key>guidelines</key>
+ <array>
+ <dict>
+ <key>angle</key>
+ <integer>0</integer>
+ <key>x</key>
+ <integer>1084</integer>
+ <key>y</key>
+ <integer>1040</integer>
+ </dict>
+ <dict>
+ <key>y</key>
+ <integer>1250</integer>
+ </dict>
+ </array>
+ <key>note</key>
+ <string>Test note
+Second line
+
+Third line
+</string>
+ <key>openTypeHeadCreated</key>
+ <string>2021/01/01 11:00:00</string>
+ <key>openTypeHheaAscender</key>
+ <integer>2100</integer>
+ <key>openTypeHheaDescender</key>
+ <integer>-550</integer>
+ <key>openTypeHheaLineGap</key>
+ <integer>0</integer>
+ <key>openTypeNameDescription</key>
+ <string>Copyright (c) 2004-2021 SIL International</string>
+ <key>openTypeNameDesigner</key>
+ <string>Victor Gaultney, Annie Olsen, Julie Remington, Don Collingsworth, Eric Hays, Becca Hirsbrunner</string>
+ <key>openTypeNameDesignerURL</key>
+ <string>http://scripts.sil.org/</string>
+ <key>openTypeNameLicense</key>
+ <string>Copyright (c) 2004-2021 SIL International (http://www.sil.org/) with Reserved Font Names "Andika" and "SIL".
+
+This Font Software is licensed under the SIL Open Font License, Version 1.1. This license is copied below, and is also available with a FAQ at: http://scripts.sil.org/OFL
+
+
+-----------------------------------------------------------
+SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007
+-----------------------------------------------------------
+
+PREAMBLE
+The goals of the Open Font License (OFL) are to stimulate worldwide development of collaborative font projects, to support the font creation efforts of academic and linguistic communities, and to provide a free and open framework in which fonts may be shared and improved in partnership with others.
+
+The OFL allows the licensed fonts to be used, studied, modified and redistributed freely as long as they are not sold by themselves. The fonts, including any derivative works, can be bundled, embedded, redistributed and/or sold with any software provided that any reserved names are not used by derivative works. The fonts and derivatives, however, cannot be released under any other type of license. The requirement for fonts to remain under this license does not apply to any document created using the fonts or their derivatives.
+
+DEFINITIONS
+"Font Software" refers to the set of files released by the Copyright Holder(s) under this license and clearly marked as such. This may include source files, build scripts and documentation.
+
+"Reserved Font Name" refers to any names specified as such after the copyright statement(s).
+
+"Original Version" refers to the collection of Font Software components as distributed by the Copyright Holder(s).
+
+"Modified Version" refers to any derivative made by adding to, deleting, or substituting -- in part or in whole -- any of the components of the Original Version, by changing formats or by porting the Font Software to a new environment.
+
+"Author" refers to any designer, engineer, programmer, technical writer or other person who contributed to the Font Software.
+
+PERMISSION &amp; CONDITIONS
+Permission is hereby granted, free of charge, to any person obtaining a copy of the Font Software, to use, study, copy, merge, embed, modify, redistribute, and sell modified and unmodified copies of the Font Software, subject to the following conditions:
+
+1) Neither the Font Software nor any of its individual components, in Original or Modified Versions, may be sold by itself.
+
+2) Original or Modified Versions of the Font Software may be bundled, redistributed and/or sold with any software, provided that each copy contains the above copyright notice and this license. These can be included either as stand-alone text files, human-readable headers or in the appropriate machine-readable metadata fields within text or binary files as long as those fields can be easily viewed by the user.
+
+3) No Modified Version of the Font Software may use the Reserved Font Name(s) unless explicit written permission is granted by the corresponding Copyright Holder. This restriction only applies to the primary font name as presented to the users.
+
+4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font Software shall not be used to promote, endorse or advertise any Modified Version, except to acknowledge the contribution(s) of the Copyright Holder(s) and the Author(s) or with their explicit written permission.
+
+5) The Font Software, modified or unmodified, in part or in whole, must be distributed entirely under this license, and must not be distributed under any other license. The requirement for fonts to remain under this license does not apply to any document created using the Font Software.
+
+TERMINATION
+This license becomes null and void if any of the above conditions are not met.
+
+DISCLAIMER
+THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM OTHER DEALINGS IN THE FONT SOFTWARE.</string>
+ <key>openTypeNameLicenseURL</key>
+ <string>http://scripts.sil.org/OFL</string>
+ <key>openTypeNameManufacturer</key>
+ <string>SIL International</string>
+ <key>openTypeNameManufacturerURL</key>
+ <string>http://scripts.sil.org</string>
+ <key>openTypeNamePreferredFamilyName</key>
+ <string>Psf Test</string>
+ <key>openTypeNamePreferredSubfamilyName</key>
+ <string>Regular</string>
+ <key>openTypeNameUniqueID</key>
+ <string>SIL International: Psf Test Regular: 2022</string>
+ <key>openTypeNameVersion</key>
+ <string>Version 5.550</string>
+ <key>openTypeOS2CodePageRanges</key>
+ <array>
+ <integer>0</integer>
+ <integer>1</integer>
+ <integer>2</integer>
+ <integer>4</integer>
+ <integer>7</integer>
+ <integer>8</integer>
+ </array>
+ <key>openTypeOS2FamilyClass</key>
+ <array>
+ <integer>0</integer>
+ <integer>0</integer>
+ </array>
+ <key>openTypeOS2Panose</key>
+ <array>
+ <integer>2</integer>
+ <integer>0</integer>
+ <integer>0</integer>
+ <integer>0</integer>
+ <integer>0</integer>
+ <integer>0</integer>
+ <integer>0</integer>
+ <integer>0</integer>
+ <integer>0</integer>
+ <integer>0</integer>
+ </array>
+ <key>openTypeOS2StrikeoutPosition</key>
+ <integer>700</integer>
+ <key>openTypeOS2StrikeoutSize</key>
+ <integer>100</integer>
+ <key>openTypeOS2SubscriptXOffset</key>
+ <integer>0</integer>
+ <key>openTypeOS2SubscriptXSize</key>
+ <integer>1433</integer>
+ <key>openTypeOS2SubscriptYOffset</key>
+ <integer>286</integer>
+ <key>openTypeOS2SubscriptYSize</key>
+ <integer>1331</integer>
+ <key>openTypeOS2SuperscriptXOffset</key>
+ <integer>0</integer>
+ <key>openTypeOS2SuperscriptXSize</key>
+ <integer>1433</integer>
+ <key>openTypeOS2SuperscriptYOffset</key>
+ <integer>976</integer>
+ <key>openTypeOS2SuperscriptYSize</key>
+ <integer>1331</integer>
+ <key>openTypeOS2Type</key>
+ <array/>
+ <key>openTypeOS2TypoAscender</key>
+ <integer>2100</integer>
+ <key>openTypeOS2TypoDescender</key>
+ <integer>-550</integer>
+ <key>openTypeOS2TypoLineGap</key>
+ <integer>0</integer>
+ <key>openTypeOS2UnicodeRanges</key>
+ <array>
+ <integer>0</integer>
+ <integer>1</integer>
+ <integer>6</integer>
+ <integer>7</integer>
+ <integer>31</integer>
+ <integer>33</integer>
+ <integer>35</integer>
+ <integer>36</integer>
+ <integer>37</integer>
+ <integer>38</integer>
+ <integer>39</integer>
+ <integer>40</integer>
+ <integer>45</integer>
+ <integer>46</integer>
+ <integer>47</integer>
+ <integer>57</integer>
+ <integer>60</integer>
+ <integer>62</integer>
+ <integer>64</integer>
+ <integer>67</integer>
+ <integer>69</integer>
+ <integer>89</integer>
+ </array>
+ <key>openTypeOS2VendorID</key>
+ <string>SIL</string>
+ <key>openTypeOS2WeightClass</key>
+ <integer>400</integer>
+ <key>openTypeOS2WidthClass</key>
+ <integer>5</integer>
+ <key>openTypeOS2WinAscent</key>
+ <integer>2100</integer>
+ <key>openTypeOS2WinDescent</key>
+ <integer>550</integer>
+ <key>postscriptBlueValues</key>
+ <array>
+ <integer>-490</integer>
+ <integer>-490</integer>
+ <integer>-25</integer>
+ <integer>0</integer>
+ <integer>1020</integer>
+ <integer>1040</integer>
+ <integer>1455</integer>
+ <integer>1485</integer>
+ <integer>1600</integer>
+ <integer>1620</integer>
+ </array>
+ <key>postscriptFamilyBlues</key>
+ <array/>
+ <key>postscriptFamilyOtherBlues</key>
+ <array/>
+ <key>postscriptFontName</key>
+ <string>PsfTest-Regular</string>
+ <key>postscriptFullName</key>
+ <string>Psf Test Regular</string>
+ <key>postscriptOtherBlues</key>
+ <array/>
+ <key>postscriptStemSnapH</key>
+ <array>
+ <integer>140</integer>
+ <integer>145</integer>
+ <integer>150</integer>
+ <integer>155</integer>
+ <integer>160</integer>
+ <integer>165</integer>
+ <integer>170</integer>
+ <integer>175</integer>
+ <integer>185</integer>
+ <integer>270</integer>
+ </array>
+ <key>postscriptStemSnapV</key>
+ <array>
+ <integer>165</integer>
+ <integer>180</integer>
+ <integer>185</integer>
+ <integer>190</integer>
+ <integer>195</integer>
+ <integer>200</integer>
+ <integer>205</integer>
+ <integer>270</integer>
+ </array>
+ <key>postscriptUnderlinePosition</key>
+ <integer>-110</integer>
+ <key>postscriptUnderlineThickness</key>
+ <integer>80</integer>
+ <key>styleMapFamilyName</key>
+ <string>Psf Test</string>
+ <key>styleMapStyleName</key>
+ <string>regular</string>
+ <key>styleName</key>
+ <string>Regular</string>
+ <key>trademark</key>
+ <string>Andika is a trademark of SIL International.</string>
+ <key>unitsPerEm</key>
+ <integer>2048</integer>
+ <key>versionMajor</key>
+ <integer>5</integer>
+ <key>versionMinor</key>
+ <integer>550</integer>
+ <key>xHeight</key>
+ <integer>1040</integer>
+ </dict>
+</plist>
diff --git a/tests/reference/fontparts/psfbuildcompgc.ufo/glyphs/A_mpersand.glif b/tests/reference/fontparts/psfbuildcompgc.ufo/glyphs/A_mpersand.glif
new file mode 100644
index 0000000..921c81b
--- /dev/null
+++ b/tests/reference/fontparts/psfbuildcompgc.ufo/glyphs/A_mpersand.glif
@@ -0,0 +1,61 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<glyph name="Ampersand" format="2">
+ <advance width="1222"/>
+ <unicode hex="0026"/>
+ <outline>
+ <contour>
+ <point x="490" y="1485" type="curve" smooth="yes"/>
+ <point x="331" y="1485"/>
+ <point x="155" y="1412"/>
+ <point x="155" y="1190" type="curve" smooth="yes"/>
+ <point x="155" y="1010"/>
+ <point x="362" y="815"/>
+ <point x="535" y="570" type="curve" smooth="yes"/>
+ <point x="794" y="202"/>
+ <point x="973" y="-25"/>
+ <point x="1025" y="-25" type="curve" smooth="yes"/>
+ <point x="1060" y="-25"/>
+ <point x="1138" y="38"/>
+ <point x="1175" y="70" type="curve"/>
+ <point x="1080" y="110"/>
+ <point x="914" y="297"/>
+ <point x="650" y="680" type="curve" smooth="yes"/>
+ <point x="494" y="906"/>
+ <point x="315" y="1075"/>
+ <point x="315" y="1200" type="curve" smooth="yes"/>
+ <point x="315" y="1291"/>
+ <point x="398" y="1350"/>
+ <point x="475" y="1350" type="curve" smooth="yes"/>
+ <point x="555" y="1350"/>
+ <point x="630" y="1294"/>
+ <point x="630" y="1205" type="curve" smooth="yes"/>
+ <point x="630" y="1116"/>
+ <point x="523" y="1001"/>
+ <point x="350" y="840" type="curve" smooth="yes"/>
+ <point x="146" y="651"/>
+ <point x="55" y="527"/>
+ <point x="55" y="375" type="curve" smooth="yes"/>
+ <point x="55" y="151"/>
+ <point x="217" y="-25"/>
+ <point x="440" y="-25" type="curve" smooth="yes"/>
+ <point x="713" y="-25"/>
+ <point x="1002" y="274"/>
+ <point x="1080" y="435" type="curve"/>
+ <point x="975" y="570" type="line"/>
+ <point x="911" y="403"/>
+ <point x="630" y="150"/>
+ <point x="455" y="150" type="curve" smooth="yes"/>
+ <point x="310" y="150"/>
+ <point x="230" y="267"/>
+ <point x="230" y="380" type="curve" smooth="yes"/>
+ <point x="230" y="490"/>
+ <point x="296" y="587"/>
+ <point x="470" y="740" type="curve" smooth="yes"/>
+ <point x="651" y="899"/>
+ <point x="790" y="1068"/>
+ <point x="790" y="1200" type="curve" smooth="yes"/>
+ <point x="790" y="1382"/>
+ <point x="642" y="1485"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/fontparts/psfbuildcompgc.ufo/glyphs/A_pos.glif b/tests/reference/fontparts/psfbuildcompgc.ufo/glyphs/A_pos.glif
new file mode 100644
index 0000000..c50d8b5
--- /dev/null
+++ b/tests/reference/fontparts/psfbuildcompgc.ufo/glyphs/A_pos.glif
@@ -0,0 +1,17 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<glyph name="Apos" format="2">
+ <advance width="605"/>
+ <unicode hex="0027"/>
+ <outline>
+ <contour>
+ <point x="365" y="1045" type="line"/>
+ <point x="370" y="1186"/>
+ <point x="376" y="1339"/>
+ <point x="405" y="1585" type="curve"/>
+ <point x="200" y="1585" type="line"/>
+ <point x="231" y="1339"/>
+ <point x="236" y="1186"/>
+ <point x="240" y="1045" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/fontparts/psfbuildcompgc.ufo/glyphs/A_sterisk.glif b/tests/reference/fontparts/psfbuildcompgc.ufo/glyphs/A_sterisk.glif
new file mode 100644
index 0000000..b65fff8
--- /dev/null
+++ b/tests/reference/fontparts/psfbuildcompgc.ufo/glyphs/A_sterisk.glif
@@ -0,0 +1,51 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<glyph name="Asterisk" format="2">
+ <advance width="1028"/>
+ <unicode hex="002A"/>
+ <outline>
+ <contour>
+ <point x="560" y="1600" type="curve"/>
+ <point x="415" y="1600" type="line"/>
+ <point x="434" y="1467"/>
+ <point x="447" y="1387"/>
+ <point x="450" y="1300" type="curve"/>
+ <point x="376" y="1344"/>
+ <point x="309" y="1387"/>
+ <point x="200" y="1465" type="curve"/>
+ <point x="125" y="1340" type="line"/>
+ <point x="250" y="1290"/>
+ <point x="327" y="1261"/>
+ <point x="405" y="1220" type="curve"/>
+ <point x="329" y="1177"/>
+ <point x="256" y="1140"/>
+ <point x="135" y="1085" type="curve"/>
+ <point x="205" y="960" type="line"/>
+ <point x="310" y="1042"/>
+ <point x="377" y="1094"/>
+ <point x="450" y="1140" type="curve"/>
+ <point x="448" y="1055"/>
+ <point x="442" y="973"/>
+ <point x="430" y="840" type="curve"/>
+ <point x="570" y="840" type="line"/>
+ <point x="550" y="973"/>
+ <point x="544" y="1052"/>
+ <point x="540" y="1140" type="curve"/>
+ <point x="614" y="1095"/>
+ <point x="681" y="1053"/>
+ <point x="790" y="975" type="curve"/>
+ <point x="865" y="1100" type="line"/>
+ <point x="739" y="1149"/>
+ <point x="663" y="1179"/>
+ <point x="585" y="1220" type="curve"/>
+ <point x="661" y="1261"/>
+ <point x="733" y="1299"/>
+ <point x="855" y="1355" type="curve"/>
+ <point x="785" y="1480" type="line"/>
+ <point x="680" y="1396"/>
+ <point x="614" y="1348"/>
+ <point x="540" y="1300" type="curve"/>
+ <point x="541" y="1387"/>
+ <point x="547" y="1467"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/fontparts/psfbuildcompgc.ufo/glyphs/A_tS_gn.glif b/tests/reference/fontparts/psfbuildcompgc.ufo/glyphs/A_tS_gn.glif
new file mode 100644
index 0000000..aa6dc56
--- /dev/null
+++ b/tests/reference/fontparts/psfbuildcompgc.ufo/glyphs/A_tS_gn.glif
@@ -0,0 +1,80 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<glyph name="AtSgn" format="2">
+ <advance width="1702"/>
+ <unicode hex="0040"/>
+ <outline>
+ <contour>
+ <point x="1605" y="700" type="curve" smooth="yes"/>
+ <point x="1605" y="1127"/>
+ <point x="1307" y="1405"/>
+ <point x="880" y="1405" type="curve" smooth="yes"/>
+ <point x="465" y="1405"/>
+ <point x="95" y="1126"/>
+ <point x="95" y="575" type="curve" smooth="yes"/>
+ <point x="95" y="48"/>
+ <point x="464" y="-235"/>
+ <point x="855" y="-235" type="curve" smooth="yes"/>
+ <point x="990" y="-235"/>
+ <point x="1150" y="-188"/>
+ <point x="1250" y="-118" type="curve"/>
+ <point x="1145" y="-10" type="line"/>
+ <point x="1058" y="-70"/>
+ <point x="963" y="-95"/>
+ <point x="870" y="-95" type="curve" smooth="yes"/>
+ <point x="523" y="-95"/>
+ <point x="240" y="174"/>
+ <point x="240" y="605" type="curve" smooth="yes"/>
+ <point x="240" y="1003"/>
+ <point x="542" y="1270"/>
+ <point x="870" y="1270" type="curve" smooth="yes"/>
+ <point x="1263" y="1270"/>
+ <point x="1465" y="1002"/>
+ <point x="1465" y="670" type="curve" smooth="yes"/>
+ <point x="1465" y="432"/>
+ <point x="1348" y="315"/>
+ <point x="1280" y="315" type="curve" smooth="yes"/>
+ <point x="1221" y="315"/>
+ <point x="1175" y="410"/>
+ <point x="1175" y="630" type="curve" smooth="yes"/>
+ <point x="1175" y="980" type="line"/>
+ <point x="1088" y="1015"/>
+ <point x="961" y="1040"/>
+ <point x="880" y="1040" type="curve" smooth="yes"/>
+ <point x="716" y="1040"/>
+ <point x="613" y="971"/>
+ <point x="530" y="835" type="curve" smooth="yes"/>
+ <point x="483" y="756"/>
+ <point x="455" y="653"/>
+ <point x="455" y="530" type="curve" smooth="yes"/>
+ <point x="455" y="294"/>
+ <point x="601" y="183"/>
+ <point x="735" y="183" type="curve" smooth="yes"/>
+ <point x="852" y="183"/>
+ <point x="988" y="366"/>
+ <point x="1040" y="490" type="curve"/>
+ <point x="1050" y="322"/>
+ <point x="1128" y="180"/>
+ <point x="1250" y="180" type="curve" smooth="yes"/>
+ <point x="1425" y="180"/>
+ <point x="1605" y="368"/>
+ </contour>
+ <contour>
+ <point x="850" y="905" type="curve" smooth="yes"/>
+ <point x="924" y="905"/>
+ <point x="992" y="886"/>
+ <point x="1025" y="870" type="curve"/>
+ <point x="1025" y="720" type="line"/>
+ <point x="993" y="582"/>
+ <point x="838" y="320"/>
+ <point x="748" y="320" type="curve" smooth="yes"/>
+ <point x="676" y="320"/>
+ <point x="605" y="398"/>
+ <point x="605" y="575" type="curve" smooth="yes"/>
+ <point x="605" y="652"/>
+ <point x="621" y="731"/>
+ <point x="650" y="780" type="curve" smooth="yes"/>
+ <point x="706" y="876"/>
+ <point x="782" y="905"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/fontparts/psfbuildcompgc.ufo/glyphs/C_ircumA_ccent.glif b/tests/reference/fontparts/psfbuildcompgc.ufo/glyphs/C_ircumA_ccent.glif
new file mode 100644
index 0000000..3f77dc1
--- /dev/null
+++ b/tests/reference/fontparts/psfbuildcompgc.ufo/glyphs/C_ircumA_ccent.glif
@@ -0,0 +1,8 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<glyph name="CircumAccent" format="2">
+ <advance width="850"/>
+ <unicode hex="005E"/>
+ <outline>
+ <component base="CombCircum" xOffset="995"/>
+ </outline>
+</glyph>
diff --git a/tests/reference/fontparts/psfbuildcompgc.ufo/glyphs/C_olon.glif b/tests/reference/fontparts/psfbuildcompgc.ufo/glyphs/C_olon.glif
new file mode 100644
index 0000000..8e837f7
--- /dev/null
+++ b/tests/reference/fontparts/psfbuildcompgc.ufo/glyphs/C_olon.glif
@@ -0,0 +1,35 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<glyph name="Colon" format="2">
+ <advance width="640"/>
+ <unicode hex="003A"/>
+ <outline>
+ <contour>
+ <point x="185" y="790" type="curve" smooth="yes"/>
+ <point x="185" y="716"/>
+ <point x="246" y="655"/>
+ <point x="320" y="655" type="curve" smooth="yes"/>
+ <point x="394" y="655"/>
+ <point x="455" y="716"/>
+ <point x="455" y="790" type="curve" smooth="yes"/>
+ <point x="455" y="864"/>
+ <point x="394" y="925"/>
+ <point x="320" y="925" type="curve" smooth="yes"/>
+ <point x="246" y="925"/>
+ <point x="185" y="864"/>
+ </contour>
+ <contour>
+ <point x="185" y="110" type="curve" smooth="yes"/>
+ <point x="185" y="36"/>
+ <point x="246" y="-25"/>
+ <point x="320" y="-25" type="curve" smooth="yes"/>
+ <point x="394" y="-25"/>
+ <point x="455" y="36"/>
+ <point x="455" y="110" type="curve" smooth="yes"/>
+ <point x="455" y="184"/>
+ <point x="394" y="245"/>
+ <point x="320" y="245" type="curve" smooth="yes"/>
+ <point x="246" y="245"/>
+ <point x="185" y="184"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/fontparts/psfbuildcompgc.ufo/glyphs/C_ombA_cute.glif b/tests/reference/fontparts/psfbuildcompgc.ufo/glyphs/C_ombA_cute.glif
new file mode 100644
index 0000000..cc8b02d
--- /dev/null
+++ b/tests/reference/fontparts/psfbuildcompgc.ufo/glyphs/C_ombA_cute.glif
@@ -0,0 +1,14 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<glyph name="CombAcute" format="2">
+ <unicode hex="0301"/>
+ <anchor x="-570" y="1635" name="U"/>
+ <anchor x="-570" y="1100" name="_U"/>
+ <outline>
+ <contour>
+ <point x="-400" y="1600" type="line"/>
+ <point x="-750" y="1170" type="line"/>
+ <point x="-590" y="1170" type="line"/>
+ <point x="-170" y="1600" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/fontparts/psfbuildcompgc.ufo/glyphs/C_ombC_ircum.glif b/tests/reference/fontparts/psfbuildcompgc.ufo/glyphs/C_ombC_ircum.glif
new file mode 100644
index 0000000..4d372c6
--- /dev/null
+++ b/tests/reference/fontparts/psfbuildcompgc.ufo/glyphs/C_ombC_ircum.glif
@@ -0,0 +1,17 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<glyph name="CombCircum" format="2">
+ <unicode hex="0302"/>
+ <anchor x="-570" y="1635" name="U"/>
+ <anchor x="-570" y="1100" name="_U"/>
+ <outline>
+ <contour>
+ <point x="-845" y="1170" type="line"/>
+ <point x="-570" y="1450" type="line"/>
+ <point x="-295" y="1170" type="line"/>
+ <point x="-145" y="1170" type="line"/>
+ <point x="-485" y="1600" type="line"/>
+ <point x="-655" y="1600" type="line"/>
+ <point x="-995" y="1170" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/fontparts/psfbuildcompgc.ufo/glyphs/C_ombD_iaer.glif b/tests/reference/fontparts/psfbuildcompgc.ufo/glyphs/C_ombD_iaer.glif
new file mode 100644
index 0000000..10b0452
--- /dev/null
+++ b/tests/reference/fontparts/psfbuildcompgc.ufo/glyphs/C_ombD_iaer.glif
@@ -0,0 +1,36 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<glyph name="CombDiaer" format="2">
+ <unicode hex="0308"/>
+ <anchor x="-570" y="1505" name="U"/>
+ <anchor x="-570" y="1100" name="_U"/>
+ <outline>
+ <contour>
+ <point x="-490" y="1345" type="curve" smooth="yes"/>
+ <point x="-490" y="1271"/>
+ <point x="-434" y="1210"/>
+ <point x="-360" y="1210" type="curve" smooth="yes"/>
+ <point x="-285" y="1210"/>
+ <point x="-230" y="1271"/>
+ <point x="-230" y="1345" type="curve" smooth="yes"/>
+ <point x="-230" y="1419"/>
+ <point x="-285" y="1480"/>
+ <point x="-360" y="1480" type="curve" smooth="yes"/>
+ <point x="-434" y="1480"/>
+ <point x="-490" y="1419"/>
+ </contour>
+ <contour>
+ <point x="-910" y="1345" type="curve" smooth="yes"/>
+ <point x="-910" y="1271"/>
+ <point x="-854" y="1210"/>
+ <point x="-780" y="1210" type="curve" smooth="yes"/>
+ <point x="-705" y="1210"/>
+ <point x="-650" y="1271"/>
+ <point x="-650" y="1345" type="curve" smooth="yes"/>
+ <point x="-650" y="1419"/>
+ <point x="-705" y="1480"/>
+ <point x="-780" y="1480" type="curve" smooth="yes"/>
+ <point x="-854" y="1480"/>
+ <point x="-910" y="1419"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/fontparts/psfbuildcompgc.ufo/glyphs/C_ombG_rave.glif b/tests/reference/fontparts/psfbuildcompgc.ufo/glyphs/C_ombG_rave.glif
new file mode 100644
index 0000000..7a99e84
--- /dev/null
+++ b/tests/reference/fontparts/psfbuildcompgc.ufo/glyphs/C_ombG_rave.glif
@@ -0,0 +1,14 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<glyph name="CombGrave" format="2">
+ <unicode hex="0300"/>
+ <anchor x="-550" y="1635" name="U"/>
+ <anchor x="-550" y="1100" name="_U"/>
+ <outline>
+ <contour>
+ <point x="-940" y="1600" type="line"/>
+ <point x="-520" y="1170" type="line"/>
+ <point x="-360" y="1170" type="line"/>
+ <point x="-710" y="1600" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/fontparts/psfbuildcompgc.ufo/glyphs/C_ombR_ingA_bv.glif b/tests/reference/fontparts/psfbuildcompgc.ufo/glyphs/C_ombR_ingA_bv.glif
new file mode 100644
index 0000000..ba2c3d5
--- /dev/null
+++ b/tests/reference/fontparts/psfbuildcompgc.ufo/glyphs/C_ombR_ingA_bv.glif
@@ -0,0 +1,36 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<glyph name="CombRingAbv" format="2">
+ <unicode hex="030A"/>
+ <anchor x="-570" y="1635" name="U"/>
+ <anchor x="-572" y="1100" name="_U"/>
+ <outline>
+ <contour>
+ <point x="-470" y="1385" type="curve" smooth="yes"/>
+ <point x="-470" y="1325"/>
+ <point x="-510" y="1285"/>
+ <point x="-570" y="1285" type="curve" smooth="yes"/>
+ <point x="-630" y="1285"/>
+ <point x="-670" y="1325"/>
+ <point x="-670" y="1385" type="curve" smooth="yes"/>
+ <point x="-670" y="1445"/>
+ <point x="-630" y="1485"/>
+ <point x="-570" y="1485" type="curve" smooth="yes"/>
+ <point x="-510" y="1485"/>
+ <point x="-470" y="1445"/>
+ </contour>
+ <contour>
+ <point x="-785" y="1385" type="curve" smooth="yes"/>
+ <point x="-785" y="1265"/>
+ <point x="-690" y="1170"/>
+ <point x="-570" y="1170" type="curve" smooth="yes"/>
+ <point x="-450" y="1170"/>
+ <point x="-355" y="1265"/>
+ <point x="-355" y="1385" type="curve" smooth="yes"/>
+ <point x="-355" y="1505"/>
+ <point x="-450" y="1600"/>
+ <point x="-570" y="1600" type="curve" smooth="yes"/>
+ <point x="-690" y="1600"/>
+ <point x="-785" y="1505"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/fontparts/psfbuildcompgc.ufo/glyphs/C_ombT_ilde.glif b/tests/reference/fontparts/psfbuildcompgc.ufo/glyphs/C_ombT_ilde.glif
new file mode 100644
index 0000000..808ca70
--- /dev/null
+++ b/tests/reference/fontparts/psfbuildcompgc.ufo/glyphs/C_ombT_ilde.glif
@@ -0,0 +1,36 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<glyph name="CombTilde" format="2">
+ <unicode hex="0303"/>
+ <anchor x="-575" y="1475" name="U"/>
+ <anchor x="-575" y="1100" name="_U"/>
+ <outline>
+ <contour>
+ <point x="-820" y="1205" type="line"/>
+ <point x="-815" y="1254"/>
+ <point x="-784" y="1290"/>
+ <point x="-735" y="1290" type="curve" smooth="yes"/>
+ <point x="-698" y="1290"/>
+ <point x="-657" y="1274"/>
+ <point x="-580" y="1238" type="curve" smooth="yes"/>
+ <point x="-519" y="1210"/>
+ <point x="-466" y="1190"/>
+ <point x="-413" y="1190" type="curve" smooth="yes"/>
+ <point x="-290" y="1190"/>
+ <point x="-215" y="1312"/>
+ <point x="-215" y="1440" type="curve"/>
+ <point x="-320" y="1440" type="line"/>
+ <point x="-327" y="1394"/>
+ <point x="-358" y="1355"/>
+ <point x="-405" y="1355" type="curve" smooth="yes"/>
+ <point x="-447" y="1355"/>
+ <point x="-488" y="1374"/>
+ <point x="-560" y="1403" type="curve" smooth="yes"/>
+ <point x="-630" y="1431"/>
+ <point x="-677" y="1455"/>
+ <point x="-733" y="1455" type="curve" smooth="yes"/>
+ <point x="-852" y="1455"/>
+ <point x="-925" y="1327"/>
+ <point x="-925" y="1205" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/fontparts/psfbuildcompgc.ufo/glyphs/C_omma.glif b/tests/reference/fontparts/psfbuildcompgc.ufo/glyphs/C_omma.glif
new file mode 100644
index 0000000..65578e7
--- /dev/null
+++ b/tests/reference/fontparts/psfbuildcompgc.ufo/glyphs/C_omma.glif
@@ -0,0 +1,24 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<glyph name="Comma" format="2">
+ <advance width="650"/>
+ <unicode hex="002C"/>
+ <outline>
+ <contour>
+ <point x="185" y="50" type="line"/>
+ <point x="325" y="50" type="line"/>
+ <point x="325" y="-51"/>
+ <point x="248" y="-172"/>
+ <point x="190" y="-230" type="curve"/>
+ <point x="290" y="-270" type="line"/>
+ <point x="407" y="-160"/>
+ <point x="465" y="-37"/>
+ <point x="465" y="85" type="curve" smooth="yes"/>
+ <point x="465" y="186"/>
+ <point x="400" y="250"/>
+ <point x="320" y="250" type="curve" smooth="yes"/>
+ <point x="263" y="250"/>
+ <point x="198" y="213"/>
+ <point x="185" y="150" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/fontparts/psfbuildcompgc.ufo/glyphs/D_igitE_ight.glif b/tests/reference/fontparts/psfbuildcompgc.ufo/glyphs/D_igitE_ight.glif
new file mode 100644
index 0000000..14cdcef
--- /dev/null
+++ b/tests/reference/fontparts/psfbuildcompgc.ufo/glyphs/D_igitE_ight.glif
@@ -0,0 +1,63 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<glyph name="DigitEight" format="2">
+ <advance width="1200"/>
+ <unicode hex="0038"/>
+ <anchor x="600" y="-100" name="L"/>
+ <anchor x="600" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="600" y="-25" type="curve" smooth="yes"/>
+ <point x="857" y="-25"/>
+ <point x="1110" y="134"/>
+ <point x="1110" y="405" type="curve" smooth="yes"/>
+ <point x="1110" y="611"/>
+ <point x="965" y="739"/>
+ <point x="855" y="795" type="curve"/>
+ <point x="933" y="844"/>
+ <point x="1050" y="923"/>
+ <point x="1050" y="1105" type="curve" smooth="yes"/>
+ <point x="1050" y="1350"/>
+ <point x="840" y="1485"/>
+ <point x="610" y="1485" type="curve" smooth="yes"/>
+ <point x="381" y="1485"/>
+ <point x="150" y="1350"/>
+ <point x="150" y="1105" type="curve" smooth="yes"/>
+ <point x="150" y="923"/>
+ <point x="272" y="838"/>
+ <point x="350" y="795" type="curve"/>
+ <point x="221" y="725"/>
+ <point x="90" y="611"/>
+ <point x="90" y="405" type="curve" smooth="yes"/>
+ <point x="90" y="134"/>
+ <point x="344" y="-25"/>
+ </contour>
+ <contour>
+ <point x="860" y="1105" type="curve" smooth="yes"/>
+ <point x="860" y="949"/>
+ <point x="743" y="865"/>
+ <point x="600" y="865" type="curve" smooth="yes"/>
+ <point x="457" y="865"/>
+ <point x="340" y="949"/>
+ <point x="340" y="1105" type="curve" smooth="yes"/>
+ <point x="340" y="1252"/>
+ <point x="457" y="1325"/>
+ <point x="600" y="1325" type="curve" smooth="yes"/>
+ <point x="743" y="1325"/>
+ <point x="860" y="1252"/>
+ </contour>
+ <contour>
+ <point x="910" y="425" type="curve" smooth="yes"/>
+ <point x="910" y="250"/>
+ <point x="778" y="145"/>
+ <point x="600" y="145" type="curve" smooth="yes"/>
+ <point x="420" y="145"/>
+ <point x="290" y="250"/>
+ <point x="290" y="425" type="curve" smooth="yes"/>
+ <point x="290" y="592"/>
+ <point x="420" y="710"/>
+ <point x="600" y="710" type="curve" smooth="yes"/>
+ <point x="778" y="710"/>
+ <point x="910" y="592"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/fontparts/psfbuildcompgc.ufo/glyphs/D_igitF_ive.glif b/tests/reference/fontparts/psfbuildcompgc.ufo/glyphs/D_igitF_ive.glif
new file mode 100644
index 0000000..af294c1
--- /dev/null
+++ b/tests/reference/fontparts/psfbuildcompgc.ufo/glyphs/D_igitF_ive.glif
@@ -0,0 +1,44 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<glyph name="DigitFive" format="2">
+ <advance width="1200"/>
+ <unicode hex="0035"/>
+ <anchor x="600" y="-100" name="L"/>
+ <anchor x="600" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="195" y="685" type="line"/>
+ <point x="319" y="733"/>
+ <point x="404" y="750"/>
+ <point x="510" y="750" type="curve" smooth="yes"/>
+ <point x="670" y="750"/>
+ <point x="870" y="672"/>
+ <point x="870" y="470" type="curve" smooth="yes"/>
+ <point x="870" y="268"/>
+ <point x="730" y="155"/>
+ <point x="530" y="155" type="curve" smooth="yes"/>
+ <point x="390" y="155"/>
+ <point x="294" y="182"/>
+ <point x="160" y="290" type="curve"/>
+ <point x="130" y="80" type="line"/>
+ <point x="255" y="2"/>
+ <point x="363" y="-25"/>
+ <point x="518" y="-25" type="curve" smooth="yes"/>
+ <point x="831" y="-25"/>
+ <point x="1060" y="163"/>
+ <point x="1060" y="475" type="curve" smooth="yes"/>
+ <point x="1060" y="742"/>
+ <point x="832" y="930"/>
+ <point x="545" y="930" type="curve" smooth="yes"/>
+ <point x="472" y="930"/>
+ <point x="411" y="924"/>
+ <point x="380" y="920" type="curve"/>
+ <point x="380" y="1290" type="line"/>
+ <point x="765" y="1290" type="line"/>
+ <point x="849" y="1290"/>
+ <point x="925" y="1286"/>
+ <point x="1000" y="1270" type="curve"/>
+ <point x="1000" y="1460" type="line"/>
+ <point x="195" y="1460" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/fontparts/psfbuildcompgc.ufo/glyphs/D_igitF_our.glif b/tests/reference/fontparts/psfbuildcompgc.ufo/glyphs/D_igitF_our.glif
new file mode 100644
index 0000000..2571d95
--- /dev/null
+++ b/tests/reference/fontparts/psfbuildcompgc.ufo/glyphs/D_igitF_our.glif
@@ -0,0 +1,27 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<glyph name="DigitFour" format="2">
+ <advance width="1200"/>
+ <unicode hex="0034"/>
+ <anchor x="607" y="-100" name="L"/>
+ <anchor x="607" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="1125" y="395" type="line"/>
+ <point x="1125" y="550" type="line"/>
+ <point x="935" y="550" type="line"/>
+ <point x="935" y="1480" type="line"/>
+ <point x="745" y="1480" type="line"/>
+ <point x="90" y="550" type="line"/>
+ <point x="90" y="395" type="line"/>
+ <point x="745" y="395" type="line"/>
+ <point x="745" y="0" type="line"/>
+ <point x="935" y="0" type="line"/>
+ <point x="935" y="395" type="line"/>
+ </contour>
+ <contour>
+ <point x="745" y="1230" type="line"/>
+ <point x="745" y="550" type="line"/>
+ <point x="263" y="550" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/fontparts/psfbuildcompgc.ufo/glyphs/D_igitN_ine.glif b/tests/reference/fontparts/psfbuildcompgc.ufo/glyphs/D_igitN_ine.glif
new file mode 100644
index 0000000..68ddea0
--- /dev/null
+++ b/tests/reference/fontparts/psfbuildcompgc.ufo/glyphs/D_igitN_ine.glif
@@ -0,0 +1,49 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<glyph name="DigitNine" format="2">
+ <advance width="1200"/>
+ <unicode hex="0039"/>
+ <anchor x="600" y="-100" name="L"/>
+ <anchor x="600" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="193" y="65" type="line"/>
+ <point x="297" y="-5"/>
+ <point x="383" y="-25"/>
+ <point x="501" y="-25" type="curve" smooth="yes"/>
+ <point x="976" y="-25"/>
+ <point x="1114" y="411"/>
+ <point x="1114" y="780" type="curve" smooth="yes"/>
+ <point x="1114" y="1198"/>
+ <point x="926" y="1485"/>
+ <point x="616" y="1485" type="curve" smooth="yes"/>
+ <point x="349" y="1485"/>
+ <point x="112" y="1306"/>
+ <point x="112" y="1002" type="curve" smooth="yes"/>
+ <point x="112" y="773"/>
+ <point x="281" y="586"/>
+ <point x="559" y="586" type="curve" smooth="yes"/>
+ <point x="750" y="586"/>
+ <point x="922" y="717"/>
+ <point x="1019" y="878" type="curve"/>
+ <point x="948" y="961" type="line"/>
+ <point x="874" y="847"/>
+ <point x="738" y="760"/>
+ <point x="583" y="760" type="curve" smooth="yes"/>
+ <point x="424" y="760"/>
+ <point x="306" y="860"/>
+ <point x="306" y="1036" type="curve" smooth="yes"/>
+ <point x="306" y="1196"/>
+ <point x="420" y="1310"/>
+ <point x="596" y="1310" type="curve" smooth="yes"/>
+ <point x="837" y="1310"/>
+ <point x="919" y="1065"/>
+ <point x="919" y="813" type="curve" smooth="yes"/>
+ <point x="919" y="326"/>
+ <point x="748" y="150"/>
+ <point x="511" y="150" type="curve" smooth="yes"/>
+ <point x="415" y="150"/>
+ <point x="323" y="174"/>
+ <point x="237" y="260" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/fontparts/psfbuildcompgc.ufo/glyphs/D_igitO_ne.glif b/tests/reference/fontparts/psfbuildcompgc.ufo/glyphs/D_igitO_ne.glif
new file mode 100644
index 0000000..e024dc1
--- /dev/null
+++ b/tests/reference/fontparts/psfbuildcompgc.ufo/glyphs/D_igitO_ne.glif
@@ -0,0 +1,22 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<glyph name="DigitOne" format="2">
+ <advance width="1200"/>
+ <unicode hex="0031"/>
+ <anchor x="600" y="-100" name="L"/>
+ <anchor x="600" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="535" y="170" type="line"/>
+ <point x="220" y="170" type="line"/>
+ <point x="220" y="0" type="line"/>
+ <point x="1040" y="0" type="line"/>
+ <point x="1040" y="170" type="line"/>
+ <point x="725" y="170" type="line"/>
+ <point x="725" y="1480" type="line"/>
+ <point x="555" y="1480" type="line"/>
+ <point x="210" y="1268" type="line"/>
+ <point x="235" y="1088" type="line"/>
+ <point x="535" y="1260" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/fontparts/psfbuildcompgc.ufo/glyphs/D_igitS_even.glif b/tests/reference/fontparts/psfbuildcompgc.ufo/glyphs/D_igitS_even.glif
new file mode 100644
index 0000000..9a1b923
--- /dev/null
+++ b/tests/reference/fontparts/psfbuildcompgc.ufo/glyphs/D_igitS_even.glif
@@ -0,0 +1,25 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<glyph name="DigitSeven" format="2">
+ <advance width="1200"/>
+ <unicode hex="0037"/>
+ <anchor x="600" y="-100" name="L"/>
+ <anchor x="600" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="460" y="0" type="line"/>
+ <point x="589" y="459"/>
+ <point x="794" y="895"/>
+ <point x="1090" y="1300" type="curve"/>
+ <point x="1090" y="1460" type="line"/>
+ <point x="100" y="1460" type="line"/>
+ <point x="100" y="1275" type="line"/>
+ <point x="176" y="1291"/>
+ <point x="292" y="1295"/>
+ <point x="480" y="1295" type="curve" smooth="yes"/>
+ <point x="870" y="1295" type="line"/>
+ <point x="612" y="912"/>
+ <point x="439" y="566"/>
+ <point x="275" y="0" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/fontparts/psfbuildcompgc.ufo/glyphs/D_igitS_ix.glif b/tests/reference/fontparts/psfbuildcompgc.ufo/glyphs/D_igitS_ix.glif
new file mode 100644
index 0000000..204b6e6
--- /dev/null
+++ b/tests/reference/fontparts/psfbuildcompgc.ufo/glyphs/D_igitS_ix.glif
@@ -0,0 +1,49 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<glyph name="DigitSix" format="2">
+ <advance width="1200"/>
+ <unicode hex="0036"/>
+ <anchor x="600" y="-100" name="L"/>
+ <anchor x="600" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="1033" y="1395" type="line"/>
+ <point x="929" y="1465"/>
+ <point x="843" y="1485"/>
+ <point x="725" y="1485" type="curve" smooth="yes"/>
+ <point x="250" y="1485"/>
+ <point x="110" y="1049"/>
+ <point x="110" y="680" type="curve" smooth="yes"/>
+ <point x="110" y="242"/>
+ <point x="290" y="-25"/>
+ <point x="600" y="-25" type="curve" smooth="yes"/>
+ <point x="907" y="-25"/>
+ <point x="1115" y="166"/>
+ <point x="1115" y="470" type="curve" smooth="yes"/>
+ <point x="1115" y="719"/>
+ <point x="943" y="895"/>
+ <point x="665" y="895" type="curve" smooth="yes"/>
+ <point x="474" y="895"/>
+ <point x="328" y="780"/>
+ <point x="215" y="625" type="curve"/>
+ <point x="280" y="550" type="line"/>
+ <point x="362" y="653"/>
+ <point x="490" y="720"/>
+ <point x="645" y="720" type="curve" smooth="yes"/>
+ <point x="824" y="720"/>
+ <point x="920" y="611"/>
+ <point x="920" y="435" type="curve" smooth="yes"/>
+ <point x="920" y="275"/>
+ <point x="806" y="150"/>
+ <point x="630" y="150" type="curve" smooth="yes"/>
+ <point x="409" y="150"/>
+ <point x="305" y="393"/>
+ <point x="305" y="645" type="curve" smooth="yes"/>
+ <point x="305" y="1132"/>
+ <point x="478" y="1310"/>
+ <point x="715" y="1310" type="curve" smooth="yes"/>
+ <point x="811" y="1310"/>
+ <point x="903" y="1286"/>
+ <point x="989" y="1200" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/fontparts/psfbuildcompgc.ufo/glyphs/D_igitT_hree.glif b/tests/reference/fontparts/psfbuildcompgc.ufo/glyphs/D_igitT_hree.glif
new file mode 100644
index 0000000..876164d
--- /dev/null
+++ b/tests/reference/fontparts/psfbuildcompgc.ufo/glyphs/D_igitT_hree.glif
@@ -0,0 +1,52 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<glyph name="DigitThree" format="2">
+ <advance width="1200"/>
+ <unicode hex="0033"/>
+ <anchor x="600" y="-100" name="L"/>
+ <anchor x="600" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="410" y="870" type="line"/>
+ <point x="410" y="700" type="line"/>
+ <point x="480" y="700" type="line"/>
+ <point x="716" y="700"/>
+ <point x="895" y="588"/>
+ <point x="895" y="425" type="curve" smooth="yes"/>
+ <point x="895" y="241"/>
+ <point x="718" y="150"/>
+ <point x="565" y="150" type="curve" smooth="yes"/>
+ <point x="385" y="150"/>
+ <point x="244" y="232"/>
+ <point x="135" y="355" type="curve"/>
+ <point x="110" y="140" type="line"/>
+ <point x="215" y="42"/>
+ <point x="368" y="-25"/>
+ <point x="545" y="-25" type="curve" smooth="yes"/>
+ <point x="834" y="-25"/>
+ <point x="1090" y="170"/>
+ <point x="1090" y="405" type="curve" smooth="yes"/>
+ <point x="1090" y="672"/>
+ <point x="862" y="776"/>
+ <point x="720" y="800" type="curve"/>
+ <point x="862" y="829"/>
+ <point x="1040" y="957"/>
+ <point x="1040" y="1140" type="curve" smooth="yes"/>
+ <point x="1040" y="1354"/>
+ <point x="828" y="1485"/>
+ <point x="580" y="1485" type="curve"/>
+ <point x="413" y="1485"/>
+ <point x="260" y="1416"/>
+ <point x="180" y="1325" type="curve"/>
+ <point x="215" y="1155" type="line"/>
+ <point x="328" y="1271"/>
+ <point x="436" y="1310"/>
+ <point x="590" y="1310" type="curve" smooth="yes"/>
+ <point x="711" y="1310"/>
+ <point x="850" y="1250"/>
+ <point x="850" y="1115" type="curve" smooth="yes"/>
+ <point x="850" y="991"/>
+ <point x="679" y="870"/>
+ <point x="480" y="870" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/fontparts/psfbuildcompgc.ufo/glyphs/D_igitT_wo.glif b/tests/reference/fontparts/psfbuildcompgc.ufo/glyphs/D_igitT_wo.glif
new file mode 100644
index 0000000..9e58e78
--- /dev/null
+++ b/tests/reference/fontparts/psfbuildcompgc.ufo/glyphs/D_igitT_wo.glif
@@ -0,0 +1,37 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<glyph name="DigitTwo" format="2">
+ <advance width="1200"/>
+ <unicode hex="0032"/>
+ <anchor x="600" y="-100" name="L"/>
+ <anchor x="560" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="1080" y="180" type="line"/>
+ <point x="1000" y="166"/>
+ <point x="842" y="165"/>
+ <point x="645" y="165" type="curve" smooth="yes"/>
+ <point x="390" y="165" type="line"/>
+ <point x="609" y="352"/>
+ <point x="1010" y="729"/>
+ <point x="1010" y="1065" type="curve" smooth="yes"/>
+ <point x="1010" y="1323"/>
+ <point x="800" y="1485"/>
+ <point x="560" y="1485" type="curve" smooth="yes"/>
+ <point x="391" y="1485"/>
+ <point x="206" y="1402"/>
+ <point x="125" y="1290" type="curve"/>
+ <point x="170" y="1120" type="line"/>
+ <point x="259" y="1228"/>
+ <point x="402" y="1305"/>
+ <point x="525" y="1305" type="curve" smooth="yes"/>
+ <point x="668" y="1305"/>
+ <point x="810" y="1233"/>
+ <point x="810" y="1045" type="curve" smooth="yes"/>
+ <point x="810" y="768"/>
+ <point x="391" y="365"/>
+ <point x="120" y="170" type="curve"/>
+ <point x="120" y="0" type="line"/>
+ <point x="1080" y="0" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/fontparts/psfbuildcompgc.ufo/glyphs/D_igitZ_ero.glif b/tests/reference/fontparts/psfbuildcompgc.ufo/glyphs/D_igitZ_ero.glif
new file mode 100644
index 0000000..c146e7c
--- /dev/null
+++ b/tests/reference/fontparts/psfbuildcompgc.ufo/glyphs/D_igitZ_ero.glif
@@ -0,0 +1,37 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<glyph name="DigitZero" format="2">
+ <advance width="1200"/>
+ <unicode hex="0030"/>
+ <anchor x="605" y="-100" name="L"/>
+ <anchor x="605" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="910" y="715" type="curve" smooth="yes"/>
+ <point x="910" y="308"/>
+ <point x="792" y="145"/>
+ <point x="600" y="145" type="curve" smooth="yes"/>
+ <point x="402" y="145"/>
+ <point x="290" y="305"/>
+ <point x="290" y="745" type="curve" smooth="yes"/>
+ <point x="290" y="1153"/>
+ <point x="407" y="1315"/>
+ <point x="600" y="1315" type="curve" smooth="yes"/>
+ <point x="802" y="1315"/>
+ <point x="910" y="1156"/>
+ </contour>
+ <contour>
+ <point x="1110" y="740" type="curve" smooth="yes"/>
+ <point x="1110" y="1286"/>
+ <point x="900" y="1485"/>
+ <point x="610" y="1485" type="curve" smooth="yes"/>
+ <point x="321" y="1485"/>
+ <point x="90" y="1283"/>
+ <point x="90" y="720" type="curve" smooth="yes"/>
+ <point x="90" y="155"/>
+ <point x="301" y="-25"/>
+ <point x="590" y="-25" type="curve" smooth="yes"/>
+ <point x="881" y="-25"/>
+ <point x="1110" y="151"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/fontparts/psfbuildcompgc.ufo/glyphs/D_ollarS_gn.glif b/tests/reference/fontparts/psfbuildcompgc.ufo/glyphs/D_ollarS_gn.glif
new file mode 100644
index 0000000..ff237fa
--- /dev/null
+++ b/tests/reference/fontparts/psfbuildcompgc.ufo/glyphs/D_ollarS_gn.glif
@@ -0,0 +1,53 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<glyph name="DollarSgn" format="2">
+ <advance width="1200"/>
+ <unicode hex="0024"/>
+ <outline>
+ <contour>
+ <point x="553" y="1600" type="line"/>
+ <point x="553" y="-220" type="line"/>
+ <point x="683" y="-220" type="line"/>
+ <point x="683" y="1600" type="line"/>
+ </contour>
+ <contour>
+ <point x="986" y="1306" type="line"/>
+ <point x="866" y="1364"/>
+ <point x="764" y="1389"/>
+ <point x="623" y="1389" type="curve" smooth="yes"/>
+ <point x="317" y="1389"/>
+ <point x="190" y="1173"/>
+ <point x="190" y="1017" type="curve" smooth="yes"/>
+ <point x="190" y="860"/>
+ <point x="253" y="739"/>
+ <point x="540" y="653" type="curve" smooth="yes"/>
+ <point x="827" y="567"/>
+ <point x="871" y="492"/>
+ <point x="871" y="396" type="curve" smooth="yes"/>
+ <point x="871" y="247"/>
+ <point x="734" y="161"/>
+ <point x="586" y="161" type="curve" smooth="yes"/>
+ <point x="450" y="161"/>
+ <point x="316" y="207"/>
+ <point x="195" y="313" type="curve"/>
+ <point x="153" y="124" type="line"/>
+ <point x="247" y="52"/>
+ <point x="408" y="0"/>
+ <point x="586" y="0" type="curve" smooth="yes"/>
+ <point x="837" y="0"/>
+ <point x="1046" y="167"/>
+ <point x="1046" y="414" type="curve" smooth="yes"/>
+ <point x="1046" y="613"/>
+ <point x="912" y="725"/>
+ <point x="669" y="796" type="curve" smooth="yes"/>
+ <point x="406" y="873"/>
+ <point x="365" y="929"/>
+ <point x="365" y="1030" type="curve" smooth="yes"/>
+ <point x="365" y="1132"/>
+ <point x="466" y="1228"/>
+ <point x="613" y="1228" type="curve" smooth="yes"/>
+ <point x="731" y="1228"/>
+ <point x="818" y="1200"/>
+ <point x="949" y="1127" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/fontparts/psfbuildcompgc.ufo/glyphs/D_ottedC_irc.glif b/tests/reference/fontparts/psfbuildcompgc.ufo/glyphs/D_ottedC_irc.glif
new file mode 100644
index 0000000..b2c2552
--- /dev/null
+++ b/tests/reference/fontparts/psfbuildcompgc.ufo/glyphs/D_ottedC_irc.glif
@@ -0,0 +1,235 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<glyph name="DottedCirc" format="2">
+ <advance width="1106"/>
+ <unicode hex="25CC"/>
+ <anchor x="553" y="0" name="H"/>
+ <anchor x="553" y="-100" name="L"/>
+ <anchor x="810" y="0" name="O"/>
+ <anchor x="553" y="1000" name="U"/>
+ <outline>
+ <contour>
+ <point x="443" y="837" type="curve" smooth="yes"/>
+ <point x="443" y="864"/>
+ <point x="423" y="885"/>
+ <point x="398" y="885" type="curve" smooth="yes"/>
+ <point x="371" y="885"/>
+ <point x="348" y="861"/>
+ <point x="348" y="837" type="curve" smooth="yes"/>
+ <point x="348" y="809"/>
+ <point x="372" y="789"/>
+ <point x="398" y="789" type="curve" smooth="yes"/>
+ <point x="425" y="789"/>
+ <point x="443" y="812"/>
+ </contour>
+ <contour>
+ <point x="758" y="79" type="curve" smooth="yes"/>
+ <point x="758" y="106"/>
+ <point x="736" y="127"/>
+ <point x="710" y="127" type="curve" smooth="yes"/>
+ <point x="685" y="127"/>
+ <point x="662" y="103"/>
+ <point x="662" y="80" type="curve" smooth="yes"/>
+ <point x="662" y="52"/>
+ <point x="686" y="31"/>
+ <point x="710" y="31" type="curve" smooth="yes"/>
+ <point x="737" y="31"/>
+ <point x="758" y="55"/>
+ </contour>
+ <contour>
+ <point x="310" y="749" type="curve" smooth="yes"/>
+ <point x="310" y="775"/>
+ <point x="288" y="796"/>
+ <point x="263" y="796" type="curve" smooth="yes"/>
+ <point x="238" y="796"/>
+ <point x="215" y="774"/>
+ <point x="215" y="747" type="curve" smooth="yes"/>
+ <point x="215" y="722"/>
+ <point x="236" y="701"/>
+ <point x="263" y="701" type="curve" smooth="yes"/>
+ <point x="291" y="701"/>
+ <point x="310" y="720"/>
+ </contour>
+ <contour>
+ <point x="891" y="168" type="curve" smooth="yes"/>
+ <point x="891" y="197"/>
+ <point x="870" y="215"/>
+ <point x="843" y="215" type="curve" smooth="yes"/>
+ <point x="817" y="215"/>
+ <point x="795" y="194"/>
+ <point x="795" y="168" type="curve" smooth="yes"/>
+ <point x="795" y="143"/>
+ <point x="816" y="121"/>
+ <point x="843" y="121" type="curve" smooth="yes"/>
+ <point x="871" y="121"/>
+ <point x="891" y="143"/>
+ </contour>
+ <contour>
+ <point x="222" y="613" type="curve" smooth="yes"/>
+ <point x="222" y="640"/>
+ <point x="199" y="663"/>
+ <point x="173" y="663" type="curve" smooth="yes"/>
+ <point x="149" y="663"/>
+ <point x="126" y="642"/>
+ <point x="126" y="615" type="curve" smooth="yes"/>
+ <point x="126" y="591"/>
+ <point x="145" y="567"/>
+ <point x="173" y="567" type="curve" smooth="yes"/>
+ <point x="197" y="567"/>
+ <point x="222" y="587"/>
+ </contour>
+ <contour>
+ <point x="980" y="301" type="curve" smooth="yes"/>
+ <point x="980" y="327"/>
+ <point x="957" y="348"/>
+ <point x="932" y="348" type="curve" smooth="yes"/>
+ <point x="908" y="348"/>
+ <point x="884" y="332"/>
+ <point x="884" y="301" type="curve" smooth="yes"/>
+ <point x="884" y="277"/>
+ <point x="902" y="254"/>
+ <point x="932" y="254" type="curve" smooth="yes"/>
+ <point x="957" y="254"/>
+ <point x="980" y="274"/>
+ </contour>
+ <contour>
+ <point x="191" y="459" type="curve" smooth="yes"/>
+ <point x="191" y="484"/>
+ <point x="168" y="505"/>
+ <point x="143" y="505" type="curve" smooth="yes"/>
+ <point x="116" y="505"/>
+ <point x="95" y="484"/>
+ <point x="95" y="458" type="curve" smooth="yes"/>
+ <point x="95" y="433"/>
+ <point x="115" y="410"/>
+ <point x="143" y="410" type="curve" smooth="yes"/>
+ <point x="167" y="410"/>
+ <point x="191" y="432"/>
+ </contour>
+ <contour>
+ <point x="1011" y="458" type="curve" smooth="yes"/>
+ <point x="1011" y="484"/>
+ <point x="990" y="506"/>
+ <point x="964" y="506" type="curve" smooth="yes"/>
+ <point x="940" y="506"/>
+ <point x="915" y="484"/>
+ <point x="915" y="457" type="curve" smooth="yes"/>
+ <point x="915" y="433"/>
+ <point x="936" y="411"/>
+ <point x="964" y="411" type="curve" smooth="yes"/>
+ <point x="990" y="411"/>
+ <point x="1011" y="433"/>
+ </contour>
+ <contour>
+ <point x="222" y="302" type="curve" smooth="yes"/>
+ <point x="222" y="328"/>
+ <point x="200" y="348"/>
+ <point x="174" y="348" type="curve" smooth="yes"/>
+ <point x="147" y="348"/>
+ <point x="126" y="326"/>
+ <point x="126" y="302" type="curve" smooth="yes"/>
+ <point x="126" y="275"/>
+ <point x="149" y="253"/>
+ <point x="174" y="253" type="curve" smooth="yes"/>
+ <point x="201" y="253"/>
+ <point x="222" y="277"/>
+ </contour>
+ <contour>
+ <point x="980" y="615" type="curve" smooth="yes"/>
+ <point x="980" y="642"/>
+ <point x="955" y="663"/>
+ <point x="931" y="663" type="curve" smooth="yes"/>
+ <point x="904" y="663"/>
+ <point x="885" y="638"/>
+ <point x="885" y="614" type="curve" smooth="yes"/>
+ <point x="885" y="588"/>
+ <point x="907" y="567"/>
+ <point x="931" y="567" type="curve" smooth="yes"/>
+ <point x="959" y="567"/>
+ <point x="980" y="591"/>
+ </contour>
+ <contour>
+ <point x="310" y="168" type="curve" smooth="yes"/>
+ <point x="310" y="195"/>
+ <point x="291" y="215"/>
+ <point x="263" y="215" type="curve" smooth="yes"/>
+ <point x="238" y="215"/>
+ <point x="215" y="190"/>
+ <point x="215" y="168" type="curve" smooth="yes"/>
+ <point x="215" y="143"/>
+ <point x="238" y="120"/>
+ <point x="263" y="120" type="curve" smooth="yes"/>
+ <point x="289" y="120"/>
+ <point x="310" y="143"/>
+ </contour>
+ <contour>
+ <point x="890" y="748" type="curve" smooth="yes"/>
+ <point x="890" y="774"/>
+ <point x="870" y="796"/>
+ <point x="843" y="796" type="curve" smooth="yes"/>
+ <point x="815" y="796"/>
+ <point x="796" y="773"/>
+ <point x="796" y="748" type="curve" smooth="yes"/>
+ <point x="796" y="724"/>
+ <point x="817" y="700"/>
+ <point x="843" y="700" type="curve" smooth="yes"/>
+ <point x="869" y="700"/>
+ <point x="890" y="722"/>
+ </contour>
+ <contour>
+ <point x="444" y="78" type="curve" smooth="yes"/>
+ <point x="444" y="102"/>
+ <point x="423" y="126"/>
+ <point x="396" y="126" type="curve" smooth="yes"/>
+ <point x="370" y="126"/>
+ <point x="348" y="102"/>
+ <point x="348" y="78" type="curve" smooth="yes"/>
+ <point x="348" y="55"/>
+ <point x="370" y="31"/>
+ <point x="396" y="31" type="curve" smooth="yes"/>
+ <point x="420" y="31"/>
+ <point x="444" y="51"/>
+ </contour>
+ <contour>
+ <point x="758" y="836" type="curve" smooth="yes"/>
+ <point x="758" y="861"/>
+ <point x="737" y="885"/>
+ <point x="710" y="885" type="curve" smooth="yes"/>
+ <point x="684" y="885"/>
+ <point x="663" y="862"/>
+ <point x="663" y="838" type="curve" smooth="yes"/>
+ <point x="663" y="814"/>
+ <point x="683" y="789"/>
+ <point x="710" y="789" type="curve" smooth="yes"/>
+ <point x="734" y="789"/>
+ <point x="758" y="809"/>
+ </contour>
+ <contour>
+ <point x="601" y="47" type="curve" smooth="yes"/>
+ <point x="601" y="73"/>
+ <point x="579" y="95"/>
+ <point x="553" y="95" type="curve" smooth="yes"/>
+ <point x="527" y="95"/>
+ <point x="506" y="73"/>
+ <point x="506" y="47" type="curve" smooth="yes"/>
+ <point x="506" y="21"/>
+ <point x="527" y="0"/>
+ <point x="553" y="0" type="curve" smooth="yes"/>
+ <point x="579" y="0"/>
+ <point x="601" y="21"/>
+ </contour>
+ <contour>
+ <point x="601" y="868" type="curve" smooth="yes"/>
+ <point x="601" y="894"/>
+ <point x="579" y="916"/>
+ <point x="553" y="916" type="curve" smooth="yes"/>
+ <point x="527" y="916"/>
+ <point x="506" y="894"/>
+ <point x="506" y="868" type="curve" smooth="yes"/>
+ <point x="506" y="842"/>
+ <point x="527" y="821"/>
+ <point x="553" y="821" type="curve" smooth="yes"/>
+ <point x="579" y="821"/>
+ <point x="601" y="842"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/fontparts/psfbuildcompgc.ufo/glyphs/E_qS_gn.glif b/tests/reference/fontparts/psfbuildcompgc.ufo/glyphs/E_qS_gn.glif
new file mode 100644
index 0000000..fe4133b
--- /dev/null
+++ b/tests/reference/fontparts/psfbuildcompgc.ufo/glyphs/E_qS_gn.glif
@@ -0,0 +1,19 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<glyph name="EqSgn" format="2">
+ <advance width="1200"/>
+ <unicode hex="003D"/>
+ <outline>
+ <contour>
+ <point x="120" y="480" type="line"/>
+ <point x="1080" y="480" type="line"/>
+ <point x="1080" y="630" type="line"/>
+ <point x="120" y="630" type="line"/>
+ </contour>
+ <contour>
+ <point x="120" y="830" type="line"/>
+ <point x="1080" y="830" type="line"/>
+ <point x="1080" y="980" type="line"/>
+ <point x="120" y="980" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/fontparts/psfbuildcompgc.ufo/glyphs/E_xclamationM_rk.glif b/tests/reference/fontparts/psfbuildcompgc.ufo/glyphs/E_xclamationM_rk.glif
new file mode 100644
index 0000000..dc73854
--- /dev/null
+++ b/tests/reference/fontparts/psfbuildcompgc.ufo/glyphs/E_xclamationM_rk.glif
@@ -0,0 +1,31 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<glyph name="ExclamationMrk" format="2">
+ <advance width="764"/>
+ <unicode hex="0021"/>
+ <outline>
+ <contour>
+ <point x="450" y="440" type="line"/>
+ <point x="456" y="730"/>
+ <point x="451" y="1076"/>
+ <point x="490" y="1510" type="curve"/>
+ <point x="235" y="1510" type="line"/>
+ <point x="273" y="1076"/>
+ <point x="268" y="730"/>
+ <point x="275" y="440" type="curve"/>
+ </contour>
+ <contour>
+ <point x="225" y="110" type="curve" smooth="yes"/>
+ <point x="225" y="36"/>
+ <point x="286" y="-25"/>
+ <point x="360" y="-25" type="curve" smooth="yes"/>
+ <point x="434" y="-25"/>
+ <point x="495" y="36"/>
+ <point x="495" y="110" type="curve" smooth="yes"/>
+ <point x="495" y="184"/>
+ <point x="434" y="245"/>
+ <point x="360" y="245" type="curve" smooth="yes"/>
+ <point x="286" y="245"/>
+ <point x="225" y="184"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/fontparts/psfbuildcompgc.ufo/glyphs/F_ullS_top.glif b/tests/reference/fontparts/psfbuildcompgc.ufo/glyphs/F_ullS_top.glif
new file mode 100644
index 0000000..e727469
--- /dev/null
+++ b/tests/reference/fontparts/psfbuildcompgc.ufo/glyphs/F_ullS_top.glif
@@ -0,0 +1,21 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<glyph name="FullStop" format="2">
+ <advance width="640"/>
+ <unicode hex="002E"/>
+ <outline>
+ <contour>
+ <point x="185" y="110" type="curve" smooth="yes"/>
+ <point x="185" y="36"/>
+ <point x="246" y="-25"/>
+ <point x="320" y="-25" type="curve" smooth="yes"/>
+ <point x="394" y="-25"/>
+ <point x="455" y="36"/>
+ <point x="455" y="110" type="curve" smooth="yes"/>
+ <point x="455" y="184"/>
+ <point x="394" y="245"/>
+ <point x="320" y="245" type="curve" smooth="yes"/>
+ <point x="246" y="245"/>
+ <point x="185" y="184"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/fontparts/psfbuildcompgc.ufo/glyphs/G_T_S_gn.glif b/tests/reference/fontparts/psfbuildcompgc.ufo/glyphs/G_T_S_gn.glif
new file mode 100644
index 0000000..027bf85
--- /dev/null
+++ b/tests/reference/fontparts/psfbuildcompgc.ufo/glyphs/G_T_S_gn.glif
@@ -0,0 +1,16 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<glyph name="GTSgn" format="2">
+ <advance width="1200"/>
+ <unicode hex="003E"/>
+ <outline>
+ <contour>
+ <point x="120" y="1035" type="line"/>
+ <point x="910" y="730" type="line"/>
+ <point x="120" y="425" type="line"/>
+ <point x="120" y="245" type="line"/>
+ <point x="1100" y="645" type="line"/>
+ <point x="1100" y="815" type="line"/>
+ <point x="120" y="1215" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/fontparts/psfbuildcompgc.ufo/glyphs/G_raveA_ccent.glif b/tests/reference/fontparts/psfbuildcompgc.ufo/glyphs/G_raveA_ccent.glif
new file mode 100644
index 0000000..7353003
--- /dev/null
+++ b/tests/reference/fontparts/psfbuildcompgc.ufo/glyphs/G_raveA_ccent.glif
@@ -0,0 +1,8 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<glyph name="GraveAccent" format="2">
+ <advance width="580"/>
+ <unicode hex="0060"/>
+ <outline>
+ <component base="CombGrave" xOffset="940"/>
+ </outline>
+</glyph>
diff --git a/tests/reference/fontparts/psfbuildcompgc.ufo/glyphs/H_yphen.glif b/tests/reference/fontparts/psfbuildcompgc.ufo/glyphs/H_yphen.glif
new file mode 100644
index 0000000..406c624
--- /dev/null
+++ b/tests/reference/fontparts/psfbuildcompgc.ufo/glyphs/H_yphen.glif
@@ -0,0 +1,14 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<glyph name="Hyphen" format="2">
+ <advance width="860"/>
+ <unicode hex="2010"/>
+ <anchor x="430" y="1100" name="U"/>
+ <outline>
+ <contour>
+ <point x="80" y="555" type="line"/>
+ <point x="780" y="555" type="line"/>
+ <point x="780" y="705" type="line"/>
+ <point x="80" y="705" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/fontparts/psfbuildcompgc.ufo/glyphs/H_yphenM_inus.glif b/tests/reference/fontparts/psfbuildcompgc.ufo/glyphs/H_yphenM_inus.glif
new file mode 100644
index 0000000..257fbf0
--- /dev/null
+++ b/tests/reference/fontparts/psfbuildcompgc.ufo/glyphs/H_yphenM_inus.glif
@@ -0,0 +1,14 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<glyph name="HyphenMinus" format="2">
+ <advance width="860"/>
+ <unicode hex="002D"/>
+ <anchor x="430" y="1100" name="U"/>
+ <outline>
+ <contour>
+ <point x="80" y="555" type="line"/>
+ <point x="780" y="555" type="line"/>
+ <point x="780" y="705" type="line"/>
+ <point x="80" y="705" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/fontparts/psfbuildcompgc.ufo/glyphs/H_yphen_S_oft.glif b/tests/reference/fontparts/psfbuildcompgc.ufo/glyphs/H_yphen_S_oft.glif
new file mode 100644
index 0000000..97ffdb6
--- /dev/null
+++ b/tests/reference/fontparts/psfbuildcompgc.ufo/glyphs/H_yphen_S_oft.glif
@@ -0,0 +1,9 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<glyph name="Hyphen_Soft" format="2">
+ <advance width="860"/>
+ <unicode hex="00AD"/>
+ <anchor x="430" y="1100" name="U"/>
+ <outline>
+ <component base="HyphenMinus"/>
+ </outline>
+</glyph>
diff --git a/tests/reference/fontparts/psfbuildcompgc.ufo/glyphs/L_T_S_gn.glif b/tests/reference/fontparts/psfbuildcompgc.ufo/glyphs/L_T_S_gn.glif
new file mode 100644
index 0000000..ed3fa37
--- /dev/null
+++ b/tests/reference/fontparts/psfbuildcompgc.ufo/glyphs/L_T_S_gn.glif
@@ -0,0 +1,16 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<glyph name="LTSgn" format="2">
+ <advance width="1200"/>
+ <unicode hex="003C"/>
+ <outline>
+ <contour>
+ <point x="1080" y="425" type="line"/>
+ <point x="290" y="730" type="line"/>
+ <point x="1080" y="1035" type="line"/>
+ <point x="1080" y="1215" type="line"/>
+ <point x="100" y="815" type="line"/>
+ <point x="100" y="645" type="line"/>
+ <point x="1080" y="245" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/fontparts/psfbuildcompgc.ufo/glyphs/L_ftC_urlyB_rac.glif b/tests/reference/fontparts/psfbuildcompgc.ufo/glyphs/L_ftC_urlyB_rac.glif
new file mode 100644
index 0000000..b516844
--- /dev/null
+++ b/tests/reference/fontparts/psfbuildcompgc.ufo/glyphs/L_ftC_urlyB_rac.glif
@@ -0,0 +1,47 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<glyph name="LftCurlyBrac" format="2">
+ <advance width="1000"/>
+ <unicode hex="007B"/>
+ <outline>
+ <contour>
+ <point x="210" y="615" type="curve" smooth="yes"/>
+ <point x="210" y="583"/>
+ <point x="383" y="486"/>
+ <point x="410" y="450" type="curve" smooth="yes"/>
+ <point x="434" y="418"/>
+ <point x="424" y="-205"/>
+ <point x="495" y="-285" type="curve" smooth="yes"/>
+ <point x="535" y="-330"/>
+ <point x="696" y="-383"/>
+ <point x="800" y="-410" type="curve"/>
+ <point x="840" y="-270" type="line"/>
+ <point x="773" y="-247"/>
+ <point x="650" y="-198"/>
+ <point x="630" y="-170" type="curve" smooth="yes"/>
+ <point x="597" y="-123"/>
+ <point x="610" y="447"/>
+ <point x="590" y="485" type="curve" smooth="yes"/>
+ <point x="571" y="521"/>
+ <point x="434" y="593"/>
+ <point x="430" y="615" type="curve"/>
+ <point x="434" y="637"/>
+ <point x="571" y="709"/>
+ <point x="590" y="745" type="curve" smooth="yes"/>
+ <point x="610" y="783"/>
+ <point x="597" y="1353"/>
+ <point x="630" y="1400" type="curve" smooth="yes"/>
+ <point x="650" y="1428"/>
+ <point x="773" y="1477"/>
+ <point x="840" y="1500" type="curve"/>
+ <point x="800" y="1640" type="line"/>
+ <point x="696" y="1613"/>
+ <point x="535" y="1560"/>
+ <point x="495" y="1515" type="curve" smooth="yes"/>
+ <point x="424" y="1435"/>
+ <point x="434" y="812"/>
+ <point x="410" y="780" type="curve" smooth="yes"/>
+ <point x="383" y="744"/>
+ <point x="210" y="647"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/fontparts/psfbuildcompgc.ufo/glyphs/L_ftP_aren.glif b/tests/reference/fontparts/psfbuildcompgc.ufo/glyphs/L_ftP_aren.glif
new file mode 100644
index 0000000..1126b7f
--- /dev/null
+++ b/tests/reference/fontparts/psfbuildcompgc.ufo/glyphs/L_ftP_aren.glif
@@ -0,0 +1,23 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<glyph name="LftParen" format="2">
+ <advance width="795"/>
+ <unicode hex="0028"/>
+ <outline>
+ <contour>
+ <point x="115" y="625" type="curve" smooth="yes"/>
+ <point x="115" y="218"/>
+ <point x="260" y="-125"/>
+ <point x="535" y="-410" type="curve"/>
+ <point x="630" y="-265" type="line"/>
+ <point x="395" y="-8"/>
+ <point x="305" y="278"/>
+ <point x="305" y="625" type="curve" smooth="yes"/>
+ <point x="305" y="982"/>
+ <point x="395" y="1280"/>
+ <point x="630" y="1485" type="curve"/>
+ <point x="555" y="1640" type="line"/>
+ <point x="290" y="1444"/>
+ <point x="115" y="1062"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/fontparts/psfbuildcompgc.ufo/glyphs/L_ftS_qrB_rac.glif b/tests/reference/fontparts/psfbuildcompgc.ufo/glyphs/L_ftS_qrB_rac.glif
new file mode 100644
index 0000000..e5568d8
--- /dev/null
+++ b/tests/reference/fontparts/psfbuildcompgc.ufo/glyphs/L_ftS_qrB_rac.glif
@@ -0,0 +1,17 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<glyph name="LftSqrBrac" format="2">
+ <advance width="790"/>
+ <unicode hex="005B"/>
+ <outline>
+ <contour>
+ <point x="640" y="-410" type="line"/>
+ <point x="640" y="-260" type="line"/>
+ <point x="385" y="-260" type="line"/>
+ <point x="385" y="1450" type="line"/>
+ <point x="640" y="1450" type="line"/>
+ <point x="640" y="1600" type="line"/>
+ <point x="200" y="1600" type="line"/>
+ <point x="200" y="-410" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/fontparts/psfbuildcompgc.ufo/glyphs/L_owL_ine.glif b/tests/reference/fontparts/psfbuildcompgc.ufo/glyphs/L_owL_ine.glif
new file mode 100644
index 0000000..9c45eaa
--- /dev/null
+++ b/tests/reference/fontparts/psfbuildcompgc.ufo/glyphs/L_owL_ine.glif
@@ -0,0 +1,13 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<glyph name="LowLine" format="2">
+ <advance width="1274"/>
+ <unicode hex="005F"/>
+ <outline>
+ <contour>
+ <point x="0" y="-320" type="line"/>
+ <point x="1274" y="-320" type="line"/>
+ <point x="1274" y="-170" type="line"/>
+ <point x="0" y="-170" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/fontparts/psfbuildcompgc.ufo/glyphs/L_tnC_apA_.alt.glif b/tests/reference/fontparts/psfbuildcompgc.ufo/glyphs/L_tnC_apA_.alt.glif
new file mode 100644
index 0000000..02eccd6
--- /dev/null
+++ b/tests/reference/fontparts/psfbuildcompgc.ufo/glyphs/L_tnC_apA_.alt.glif
@@ -0,0 +1,31 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<glyph name="LtnCapA.alt" format="2">
+ <advance width="1395"/>
+ <anchor x="668" y="1460" name="H"/>
+ <anchor x="688" y="1560" name="L"/>
+ <anchor x="-75" y="1460" name="O"/>
+ <anchor x="688" y="-70" name="U"/>
+ <outline>
+ <contour>
+ <point x="1130" y="1460" type="line"/>
+ <point x="996" y="1075" type="line"/>
+ <point x="381" y="1075" type="line"/>
+ <point x="245" y="1460" type="line"/>
+ <point x="40" y="1460" type="line"/>
+ <point x="75" y="1380"/>
+ <point x="113" y="1291"/>
+ <point x="180" y="1105" type="curve" smooth="yes"/>
+ <point x="580" y="0" type="line"/>
+ <point x="795" y="0" type="line"/>
+ <point x="1195" y="1105" type="line" smooth="yes"/>
+ <point x="1263" y="1292"/>
+ <point x="1299" y="1379"/>
+ <point x="1335" y="1460" type="curve"/>
+ </contour>
+ <contour>
+ <point x="435" y="920" type="line"/>
+ <point x="942" y="920" type="line"/>
+ <point x="690" y="195" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/fontparts/psfbuildcompgc.ufo/glyphs/L_tnC_apA_.glif b/tests/reference/fontparts/psfbuildcompgc.ufo/glyphs/L_tnC_apA_.glif
new file mode 100644
index 0000000..791c68d
--- /dev/null
+++ b/tests/reference/fontparts/psfbuildcompgc.ufo/glyphs/L_tnC_apA_.glif
@@ -0,0 +1,32 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<glyph name="LtnCapA" format="2">
+ <advance width="1395"/>
+ <unicode hex="0041"/>
+ <anchor x="707" y="0" name="H"/>
+ <anchor x="687" y="-100" name="L"/>
+ <anchor x="1450" y="0" name="O"/>
+ <anchor x="687" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="245" y="0" type="line"/>
+ <point x="379" y="385" type="line"/>
+ <point x="994" y="385" type="line"/>
+ <point x="1130" y="0" type="line"/>
+ <point x="1335" y="0" type="line"/>
+ <point x="1300" y="80"/>
+ <point x="1262" y="169"/>
+ <point x="1195" y="355" type="curve" smooth="yes"/>
+ <point x="795" y="1460" type="line"/>
+ <point x="580" y="1460" type="line"/>
+ <point x="180" y="355" type="line" smooth="yes"/>
+ <point x="112" y="168"/>
+ <point x="76" y="81"/>
+ <point x="40" y="0" type="curve"/>
+ </contour>
+ <contour>
+ <point x="940" y="540" type="line"/>
+ <point x="433" y="540" type="line"/>
+ <point x="685" y="1265" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/fontparts/psfbuildcompgc.ufo/glyphs/L_tnC_apA_D_iaer.glif b/tests/reference/fontparts/psfbuildcompgc.ufo/glyphs/L_tnC_apA_D_iaer.glif
new file mode 100644
index 0000000..6458162
--- /dev/null
+++ b/tests/reference/fontparts/psfbuildcompgc.ufo/glyphs/L_tnC_apA_D_iaer.glif
@@ -0,0 +1,13 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<glyph name="LtnCapADiaer" format="2">
+ <advance width="1395"/>
+ <unicode hex="00C4"/>
+ <anchor x="707" y="0" name="H"/>
+ <anchor x="687" y="-100" name="L"/>
+ <anchor x="1450" y="0" name="O"/>
+ <anchor x="687" y="1935" name="U"/>
+ <outline>
+ <component base="LtnCapA"/>
+ <component base="CombDiaer" xOffset="1257" yOffset="430"/>
+ </outline>
+</glyph>
diff --git a/tests/reference/fontparts/psfbuildcompgc.ufo/glyphs/L_tnC_apB_.glif b/tests/reference/fontparts/psfbuildcompgc.ufo/glyphs/L_tnC_apB_.glif
new file mode 100644
index 0000000..bd2a70f
--- /dev/null
+++ b/tests/reference/fontparts/psfbuildcompgc.ufo/glyphs/L_tnC_apB_.glif
@@ -0,0 +1,62 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<glyph name="LtnCapB" format="2">
+ <advance width="1285"/>
+ <unicode hex="0042"/>
+ <anchor x="615" y="-100" name="L"/>
+ <anchor x="615" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="365" y="1310" type="line"/>
+ <point x="407" y="1312"/>
+ <point x="512" y="1315"/>
+ <point x="590" y="1315" type="curve" smooth="yes"/>
+ <point x="791" y="1315"/>
+ <point x="870" y="1239"/>
+ <point x="870" y="1090" type="curve" smooth="yes"/>
+ <point x="870" y="951"/>
+ <point x="774" y="855"/>
+ <point x="560" y="855" type="curve" smooth="yes"/>
+ <point x="365" y="855" type="line"/>
+ </contour>
+ <contour>
+ <point x="175" y="455" type="line"/>
+ <point x="175" y="257"/>
+ <point x="175" y="80"/>
+ <point x="160" y="0" type="curve"/>
+ <point x="213" y="-5"/>
+ <point x="402" y="-10"/>
+ <point x="605" y="-10" type="curve" smooth="yes"/>
+ <point x="988" y="-10"/>
+ <point x="1140" y="177"/>
+ <point x="1140" y="420" type="curve" smooth="yes"/>
+ <point x="1140" y="669"/>
+ <point x="974" y="759"/>
+ <point x="820" y="800" type="curve"/>
+ <point x="956" y="852"/>
+ <point x="1065" y="952"/>
+ <point x="1065" y="1120" type="curve" smooth="yes"/>
+ <point x="1065" y="1381"/>
+ <point x="897" y="1470"/>
+ <point x="600" y="1470" type="curve" smooth="yes"/>
+ <point x="431" y="1470"/>
+ <point x="248" y="1466"/>
+ <point x="160" y="1460" type="curve"/>
+ <point x="175" y="1380"/>
+ <point x="175" y="1196"/>
+ <point x="175" y="1000" type="curve" smooth="yes"/>
+ </contour>
+ <contour>
+ <point x="365" y="700" type="line"/>
+ <point x="600" y="700" type="line" smooth="yes"/>
+ <point x="833" y="700"/>
+ <point x="945" y="604"/>
+ <point x="945" y="420" type="curve" smooth="yes"/>
+ <point x="945" y="212"/>
+ <point x="781" y="150"/>
+ <point x="610" y="150" type="curve" smooth="yes"/>
+ <point x="498" y="150"/>
+ <point x="402" y="153"/>
+ <point x="365" y="155" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/fontparts/psfbuildcompgc.ufo/glyphs/L_tnC_apC_.glif b/tests/reference/fontparts/psfbuildcompgc.ufo/glyphs/L_tnC_apC_.glif
new file mode 100644
index 0000000..18d9cb1
--- /dev/null
+++ b/tests/reference/fontparts/psfbuildcompgc.ufo/glyphs/L_tnC_apC_.glif
@@ -0,0 +1,38 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<glyph name="LtnCapC" format="2">
+ <advance width="1355"/>
+ <unicode hex="0043"/>
+ <anchor x="750" y="0" name="H"/>
+ <anchor x="750" y="-100" name="L"/>
+ <anchor x="750" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="1190" y="335" type="line"/>
+ <point x="1078" y="223"/>
+ <point x="912" y="150"/>
+ <point x="760" y="150" type="curve" smooth="yes"/>
+ <point x="489" y="150"/>
+ <point x="290" y="376"/>
+ <point x="290" y="735" type="curve" smooth="yes"/>
+ <point x="290" y="1119"/>
+ <point x="491" y="1315"/>
+ <point x="770" y="1315" type="curve" smooth="yes"/>
+ <point x="891" y="1315"/>
+ <point x="1030" y="1278"/>
+ <point x="1155" y="1165" type="curve"/>
+ <point x="1215" y="1345" type="line"/>
+ <point x="1072" y="1452"/>
+ <point x="913" y="1485"/>
+ <point x="770" y="1485" type="curve" smooth="yes"/>
+ <point x="418" y="1485"/>
+ <point x="95" y="1225"/>
+ <point x="95" y="710" type="curve" smooth="yes"/>
+ <point x="95" y="260"/>
+ <point x="346" y="-25"/>
+ <point x="750" y="-25" type="curve" smooth="yes"/>
+ <point x="902" y="-25"/>
+ <point x="1114" y="32"/>
+ <point x="1230" y="140" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/fontparts/psfbuildcompgc.ufo/glyphs/L_tnC_apC_A_cute.glif b/tests/reference/fontparts/psfbuildcompgc.ufo/glyphs/L_tnC_apC_A_cute.glif
new file mode 100644
index 0000000..2fef8c0
--- /dev/null
+++ b/tests/reference/fontparts/psfbuildcompgc.ufo/glyphs/L_tnC_apC_A_cute.glif
@@ -0,0 +1,9 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<glyph name="LtnCapCAcute" format="2">
+ <advance width="1020"/>
+ <unicode hex="0106"/>
+ <outline>
+ <component base="LtnSmC"/>
+ <component base="CombAcute" xOffset="1140.0"/>
+ </outline>
+</glyph>
diff --git a/tests/reference/fontparts/psfbuildcompgc.ufo/glyphs/L_tnC_apC_A_cuteC_edilla.glif b/tests/reference/fontparts/psfbuildcompgc.ufo/glyphs/L_tnC_apC_A_cuteC_edilla.glif
new file mode 100644
index 0000000..eaf16f9
--- /dev/null
+++ b/tests/reference/fontparts/psfbuildcompgc.ufo/glyphs/L_tnC_apC_A_cuteC_edilla.glif
@@ -0,0 +1,10 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<glyph name="LtnCapCAcuteCedilla" format="2">
+ <advance width="1355"/>
+ <unicode hex="1E08"/>
+ <outline>
+ <component base="LtnCapC"/>
+ <component base="CombCedilla" xOffset="750.0"/>
+ <component base="CombAcute" xOffset="1320.0" yOffset="430.0"/>
+ </outline>
+</glyph>
diff --git a/tests/reference/fontparts/psfbuildcompgc.ufo/glyphs/L_tnC_apC_C_ircum.glif b/tests/reference/fontparts/psfbuildcompgc.ufo/glyphs/L_tnC_apC_C_ircum.glif
new file mode 100644
index 0000000..0f2f0f8
--- /dev/null
+++ b/tests/reference/fontparts/psfbuildcompgc.ufo/glyphs/L_tnC_apC_C_ircum.glif
@@ -0,0 +1,9 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<glyph name="LtnCapCCircum" format="2">
+ <advance width="1355"/>
+ <unicode hex="0108"/>
+ <outline>
+ <component base="LtnCapC"/>
+ <component base="CombCircum" xOffset="1320.0" yOffset="430.0"/>
+ </outline>
+</glyph>
diff --git a/tests/reference/fontparts/psfbuildcompgc.ufo/glyphs/L_tnC_apD_.glif b/tests/reference/fontparts/psfbuildcompgc.ufo/glyphs/L_tnC_apD_.glif
new file mode 100644
index 0000000..07be047
--- /dev/null
+++ b/tests/reference/fontparts/psfbuildcompgc.ufo/glyphs/L_tnC_apD_.glif
@@ -0,0 +1,45 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<glyph name="LtnCapD" format="2">
+ <advance width="1435"/>
+ <unicode hex="0044"/>
+ <anchor x="715" y="-100" name="L"/>
+ <anchor x="715" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="175" y="455" type="line"/>
+ <point x="174" y="257"/>
+ <point x="175" y="80"/>
+ <point x="160" y="0" type="curve"/>
+ <point x="160" y="0"/>
+ <point x="467" y="-10"/>
+ <point x="595" y="-10" type="curve" smooth="yes"/>
+ <point x="888" y="-10"/>
+ <point x="1315" y="145"/>
+ <point x="1315" y="740" type="curve" smooth="yes"/>
+ <point x="1315" y="1394"/>
+ <point x="829" y="1470"/>
+ <point x="615" y="1470" type="curve" smooth="yes"/>
+ <point x="480" y="1470"/>
+ <point x="245" y="1466"/>
+ <point x="160" y="1460" type="curve"/>
+ <point x="175" y="1380"/>
+ <point x="175" y="1196"/>
+ <point x="175" y="1000" type="curve" smooth="yes"/>
+ </contour>
+ <contour>
+ <point x="365" y="1305" type="line"/>
+ <point x="415" y="1307"/>
+ <point x="524" y="1310"/>
+ <point x="590" y="1310" type="curve" smooth="yes"/>
+ <point x="878" y="1310"/>
+ <point x="1120" y="1167"/>
+ <point x="1120" y="720" type="curve" smooth="yes"/>
+ <point x="1120" y="308"/>
+ <point x="853" y="155"/>
+ <point x="585" y="155" type="curve" smooth="yes"/>
+ <point x="490" y="155"/>
+ <point x="412" y="161"/>
+ <point x="365" y="165" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/fontparts/psfbuildcompgc.ufo/glyphs/L_tnC_apE_.glif b/tests/reference/fontparts/psfbuildcompgc.ufo/glyphs/L_tnC_apE_.glif
new file mode 100644
index 0000000..d37fb05
--- /dev/null
+++ b/tests/reference/fontparts/psfbuildcompgc.ufo/glyphs/L_tnC_apE_.glif
@@ -0,0 +1,35 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<glyph name="LtnCapE" format="2">
+ <advance width="1160"/>
+ <unicode hex="0045"/>
+ <anchor x="600" y="0" name="H"/>
+ <anchor x="600" y="-100" name="L"/>
+ <anchor x="917" y="0" name="O"/>
+ <anchor x="1160" y="1200" name="R"/>
+ <anchor x="600" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="365" y="845" type="line"/>
+ <point x="365" y="1295" type="line"/>
+ <point x="1010" y="1295" type="line"/>
+ <point x="1010" y="1460" type="line"/>
+ <point x="160" y="1460" type="line"/>
+ <point x="175" y="1380"/>
+ <point x="175" y="1222"/>
+ <point x="175" y="1025" type="curve" smooth="yes"/>
+ <point x="175" y="435" type="line" smooth="yes"/>
+ <point x="175" y="238"/>
+ <point x="175" y="80"/>
+ <point x="160" y="0" type="curve"/>
+ <point x="1040" y="0" type="line"/>
+ <point x="1040" y="180" type="line"/>
+ <point x="960" y="166"/>
+ <point x="826" y="165"/>
+ <point x="629" y="165" type="curve" smooth="yes"/>
+ <point x="365" y="165" type="line"/>
+ <point x="365" y="685" type="line"/>
+ <point x="935" y="685" type="line"/>
+ <point x="935" y="845" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/fontparts/psfbuildcompgc.ufo/glyphs/L_tnC_apF_.glif b/tests/reference/fontparts/psfbuildcompgc.ufo/glyphs/L_tnC_apF_.glif
new file mode 100644
index 0000000..9167dfd
--- /dev/null
+++ b/tests/reference/fontparts/psfbuildcompgc.ufo/glyphs/L_tnC_apF_.glif
@@ -0,0 +1,30 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<glyph name="LtnCapF" format="2">
+ <advance width="1150"/>
+ <unicode hex="0046"/>
+ <anchor x="595" y="-100" name="L"/>
+ <anchor x="595" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="365" y="835" type="line"/>
+ <point x="365" y="1295" type="line"/>
+ <point x="1030" y="1295" type="line"/>
+ <point x="1030" y="1460" type="line"/>
+ <point x="160" y="1460" type="line"/>
+ <point x="175" y="1380"/>
+ <point x="175" y="1217"/>
+ <point x="175" y="1020" type="curve" smooth="yes"/>
+ <point x="175" y="435" type="line" smooth="yes"/>
+ <point x="175" y="238"/>
+ <point x="175" y="80"/>
+ <point x="160" y="0" type="curve"/>
+ <point x="380" y="0" type="line"/>
+ <point x="365" y="78"/>
+ <point x="365" y="237"/>
+ <point x="365" y="435" type="curve" smooth="yes"/>
+ <point x="365" y="675" type="line"/>
+ <point x="945" y="675" type="line"/>
+ <point x="945" y="835" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/fontparts/psfbuildcompgc.ufo/glyphs/L_tnC_apG_.glif b/tests/reference/fontparts/psfbuildcompgc.ufo/glyphs/L_tnC_apG_.glif
new file mode 100644
index 0000000..e969082
--- /dev/null
+++ b/tests/reference/fontparts/psfbuildcompgc.ufo/glyphs/L_tnC_apG_.glif
@@ -0,0 +1,42 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<glyph name="LtnCapG" format="2">
+ <advance width="1420"/>
+ <unicode hex="0047"/>
+ <anchor x="745" y="0" name="H"/>
+ <anchor x="745" y="-100" name="L"/>
+ <anchor x="745" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="1275" y="745" type="line"/>
+ <point x="735" y="745" type="line"/>
+ <point x="735" y="580" type="line"/>
+ <point x="1085" y="580" type="line"/>
+ <point x="1085" y="245" type="line"/>
+ <point x="963" y="171"/>
+ <point x="876" y="150"/>
+ <point x="757" y="150" type="curve" smooth="yes"/>
+ <point x="471" y="150"/>
+ <point x="290" y="377"/>
+ <point x="290" y="745" type="curve" smooth="yes"/>
+ <point x="290" y="1094"/>
+ <point x="480" y="1315"/>
+ <point x="785" y="1315" type="curve" smooth="yes"/>
+ <point x="918" y="1315"/>
+ <point x="1046" y="1286"/>
+ <point x="1195" y="1165" type="curve"/>
+ <point x="1260" y="1345" type="line"/>
+ <point x="1085" y="1462"/>
+ <point x="947" y="1485"/>
+ <point x="785" y="1485" type="curve" smooth="yes"/>
+ <point x="402" y="1485"/>
+ <point x="95" y="1199"/>
+ <point x="95" y="720" type="curve" smooth="yes"/>
+ <point x="95" y="241"/>
+ <point x="367" y="-25"/>
+ <point x="745" y="-25" type="curve" smooth="yes"/>
+ <point x="918" y="-25"/>
+ <point x="1070" y="11"/>
+ <point x="1275" y="155" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/fontparts/psfbuildcompgc.ufo/glyphs/L_tnC_apH_.glif b/tests/reference/fontparts/psfbuildcompgc.ufo/glyphs/L_tnC_apH_.glif
new file mode 100644
index 0000000..9d529e4
--- /dev/null
+++ b/tests/reference/fontparts/psfbuildcompgc.ufo/glyphs/L_tnC_apH_.glif
@@ -0,0 +1,36 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<glyph name="LtnCapH" format="2">
+ <advance width="1475"/>
+ <unicode hex="0048"/>
+ <anchor x="285" y="0" name="H"/>
+ <anchor x="725" y="-100" name="L"/>
+ <anchor x="725" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="1290" y="0" type="line"/>
+ <point x="1275" y="80"/>
+ <point x="1275" y="238"/>
+ <point x="1275" y="435" type="curve" smooth="yes"/>
+ <point x="1275" y="1025" type="line" smooth="yes"/>
+ <point x="1275" y="1222"/>
+ <point x="1275" y="1380"/>
+ <point x="1290" y="1460" type="curve"/>
+ <point x="1085" y="1460" type="line"/>
+ <point x="1085" y="835" type="line"/>
+ <point x="365" y="835" type="line"/>
+ <point x="365" y="1460" type="line"/>
+ <point x="160" y="1460" type="line"/>
+ <point x="175" y="1380"/>
+ <point x="175" y="1222"/>
+ <point x="175" y="1025" type="curve" smooth="yes"/>
+ <point x="175" y="435" type="line" smooth="yes"/>
+ <point x="175" y="238"/>
+ <point x="175" y="80"/>
+ <point x="160" y="0" type="curve"/>
+ <point x="365" y="0" type="line"/>
+ <point x="365" y="675" type="line"/>
+ <point x="1085" y="675" type="line"/>
+ <point x="1085" y="0" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/fontparts/psfbuildcompgc.ufo/glyphs/L_tnC_apI_.glif b/tests/reference/fontparts/psfbuildcompgc.ufo/glyphs/L_tnC_apI_.glif
new file mode 100644
index 0000000..b7e0fb1
--- /dev/null
+++ b/tests/reference/fontparts/psfbuildcompgc.ufo/glyphs/L_tnC_apI_.glif
@@ -0,0 +1,26 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<glyph name="LtnCapI" format="2">
+ <advance width="975"/>
+ <unicode hex="0049"/>
+ <anchor x="477" y="0" name="H"/>
+ <anchor x="477" y="-100" name="L"/>
+ <anchor x="673" y="0" name="O"/>
+ <anchor x="975" y="1200" name="R"/>
+ <anchor x="477" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="140" y="1460" type="line"/>
+ <point x="140" y="1315" type="line"/>
+ <point x="380" y="1315" type="line"/>
+ <point x="380" y="145" type="line"/>
+ <point x="140" y="145" type="line"/>
+ <point x="140" y="0" type="line"/>
+ <point x="815" y="0" type="line"/>
+ <point x="815" y="145" type="line"/>
+ <point x="570" y="145" type="line"/>
+ <point x="570" y="1315" type="line"/>
+ <point x="815" y="1315" type="line"/>
+ <point x="815" y="1460" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/fontparts/psfbuildcompgc.ufo/glyphs/L_tnC_apI_J_.glif b/tests/reference/fontparts/psfbuildcompgc.ufo/glyphs/L_tnC_apI_J_.glif
new file mode 100644
index 0000000..56f2efb
--- /dev/null
+++ b/tests/reference/fontparts/psfbuildcompgc.ufo/glyphs/L_tnC_apI_J_.glif
@@ -0,0 +1,9 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<glyph name="LtnCapIJ" format="2">
+ <advance width="1940"/>
+ <unicode hex="0132"/>
+ <outline>
+ <component base="LtnCapI"/>
+ <component base="LtnCapJ" xOffset="975"/>
+ </outline>
+</glyph>
diff --git a/tests/reference/fontparts/psfbuildcompgc.ufo/glyphs/L_tnC_apJ_.glif b/tests/reference/fontparts/psfbuildcompgc.ufo/glyphs/L_tnC_apJ_.glif
new file mode 100644
index 0000000..46e2482
--- /dev/null
+++ b/tests/reference/fontparts/psfbuildcompgc.ufo/glyphs/L_tnC_apJ_.glif
@@ -0,0 +1,30 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<glyph name="LtnCapJ" format="2">
+ <advance width="965"/>
+ <unicode hex="004A"/>
+ <anchor x="410" y="-100" name="L"/>
+ <anchor x="675" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="575" y="1460" type="line"/>
+ <point x="588" y="1354"/>
+ <point x="590" y="1175"/>
+ <point x="590" y="980" type="curve"/>
+ <point x="590" y="485" type="line" smooth="yes"/>
+ <point x="590" y="256"/>
+ <point x="487" y="155"/>
+ <point x="340" y="155" type="curve" smooth="yes"/>
+ <point x="248" y="155"/>
+ <point x="147" y="198"/>
+ <point x="80" y="275" type="curve"/>
+ <point x="35" y="90" type="line"/>
+ <point x="106" y="9"/>
+ <point x="250" y="-25"/>
+ <point x="345" y="-25" type="curve" smooth="yes"/>
+ <point x="602" y="-25"/>
+ <point x="780" y="119"/>
+ <point x="780" y="535" type="curve" smooth="yes"/>
+ <point x="780" y="1460" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/fontparts/psfbuildcompgc.ufo/glyphs/L_tnC_apK_.glif b/tests/reference/fontparts/psfbuildcompgc.ufo/glyphs/L_tnC_apK_.glif
new file mode 100644
index 0000000..057c735
--- /dev/null
+++ b/tests/reference/fontparts/psfbuildcompgc.ufo/glyphs/L_tnC_apK_.glif
@@ -0,0 +1,35 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<glyph name="LtnCapK" format="2">
+ <advance width="1310"/>
+ <unicode hex="004B"/>
+ <anchor x="270" y="0" name="H"/>
+ <anchor x="695" y="-100" name="L"/>
+ <anchor x="650" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="925" y="1460" type="line"/>
+ <point x="295" y="703" type="line"/>
+ <point x="425" y="745" type="line"/>
+ <point x="530" y="740" type="line"/>
+ <point x="1165" y="1460" type="line"/>
+ </contour>
+ <contour>
+ <point x="350" y="735" type="line"/>
+ <point x="985" y="0" type="line"/>
+ <point x="1230" y="0" type="line"/>
+ <point x="485" y="860" type="line"/>
+ </contour>
+ <contour>
+ <point x="365" y="1460" type="line"/>
+ <point x="160" y="1460" type="line"/>
+ <point x="175" y="1380"/>
+ <point x="175" y="1222"/>
+ <point x="175" y="1025" type="curve" smooth="yes"/>
+ <point x="175" y="435" type="line" smooth="yes"/>
+ <point x="175" y="238"/>
+ <point x="175" y="80"/>
+ <point x="160" y="0" type="curve"/>
+ <point x="365" y="0" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/fontparts/psfbuildcompgc.ufo/glyphs/L_tnC_apL_.glif b/tests/reference/fontparts/psfbuildcompgc.ufo/glyphs/L_tnC_apL_.glif
new file mode 100644
index 0000000..52fdb6f
--- /dev/null
+++ b/tests/reference/fontparts/psfbuildcompgc.ufo/glyphs/L_tnC_apL_.glif
@@ -0,0 +1,28 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<glyph name="LtnCapL" format="2">
+ <advance width="1080"/>
+ <unicode hex="004C"/>
+ <anchor x="592" y="0" name="H"/>
+ <anchor x="592" y="-100" name="L"/>
+ <anchor x="540" y="1200" name="R"/>
+ <anchor x="592" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="365" y="165" type="line"/>
+ <point x="365" y="1460" type="line"/>
+ <point x="160" y="1460" type="line"/>
+ <point x="175" y="1380"/>
+ <point x="175" y="1222"/>
+ <point x="175" y="1025" type="curve" smooth="yes"/>
+ <point x="175" y="435" type="line" smooth="yes"/>
+ <point x="175" y="238"/>
+ <point x="175" y="80"/>
+ <point x="160" y="0" type="curve"/>
+ <point x="1025" y="0" type="line"/>
+ <point x="1025" y="180" type="line"/>
+ <point x="945" y="166"/>
+ <point x="786" y="165"/>
+ <point x="589" y="165" type="curve" smooth="yes"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/fontparts/psfbuildcompgc.ufo/glyphs/L_tnC_apM_.glif b/tests/reference/fontparts/psfbuildcompgc.ufo/glyphs/L_tnC_apM_.glif
new file mode 100644
index 0000000..f350197
--- /dev/null
+++ b/tests/reference/fontparts/psfbuildcompgc.ufo/glyphs/L_tnC_apM_.glif
@@ -0,0 +1,37 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<glyph name="LtnCapM" format="2">
+ <advance width="1795"/>
+ <unicode hex="004D"/>
+ <anchor x="1521" y="0" name="H"/>
+ <anchor x="885" y="-100" name="L"/>
+ <anchor x="885" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="885" y="205" type="line"/>
+ <point x="455" y="1460" type="line"/>
+ <point x="285" y="1460" type="line"/>
+ <point x="790" y="0" type="line"/>
+ <point x="985" y="0" type="line"/>
+ <point x="1487" y="1460" type="line"/>
+ <point x="1320" y="1460" type="line"/>
+ </contour>
+ <contour>
+ <point x="230" y="1460" type="line"/>
+ <point x="230" y="1460"/>
+ <point x="186" y="198"/>
+ <point x="160" y="0" type="curve"/>
+ <point x="345" y="0" type="line"/>
+ <point x="377" y="1205" type="line"/>
+ <point x="405" y="1460" type="line"/>
+ </contour>
+ <contour>
+ <point x="1610" y="0" type="line"/>
+ <point x="1581" y="198"/>
+ <point x="1540" y="1460"/>
+ <point x="1540" y="1460" type="curve"/>
+ <point x="1365" y="1460" type="line"/>
+ <point x="1397" y="1205" type="line"/>
+ <point x="1425" y="0" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/fontparts/psfbuildcompgc.ufo/glyphs/L_tnC_apN_.glif b/tests/reference/fontparts/psfbuildcompgc.ufo/glyphs/L_tnC_apN_.glif
new file mode 100644
index 0000000..2aaa015
--- /dev/null
+++ b/tests/reference/fontparts/psfbuildcompgc.ufo/glyphs/L_tnC_apN_.glif
@@ -0,0 +1,37 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<glyph name="LtnCapN" format="2">
+ <advance width="1500"/>
+ <unicode hex="004E"/>
+ <anchor x="1230" y="0" name="H"/>
+ <anchor x="737" y="-100" name="L"/>
+ <anchor x="737" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="200" y="1355" type="line"/>
+ <point x="1135" y="0" type="line"/>
+ <point x="1275" y="100" type="line"/>
+ <point x="340" y="1460" type="line"/>
+ </contour>
+ <contour>
+ <point x="1135" y="0" type="line"/>
+ <point x="1300" y="0" type="line"/>
+ <point x="1300" y="1025" type="line" smooth="yes"/>
+ <point x="1300" y="1222"/>
+ <point x="1301" y="1380"/>
+ <point x="1315" y="1460" type="curve"/>
+ <point x="1135" y="1460" type="line"/>
+ </contour>
+ <contour>
+ <point x="340" y="1460" type="line"/>
+ <point x="160" y="1460" type="line"/>
+ <point x="175" y="1380"/>
+ <point x="175" y="1222"/>
+ <point x="175" y="1025" type="curve" smooth="yes"/>
+ <point x="175" y="435" type="line" smooth="yes"/>
+ <point x="175" y="238"/>
+ <point x="175" y="80"/>
+ <point x="160" y="0" type="curve"/>
+ <point x="340" y="0" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/fontparts/psfbuildcompgc.ufo/glyphs/L_tnC_apO_.glif b/tests/reference/fontparts/psfbuildcompgc.ufo/glyphs/L_tnC_apO_.glif
new file mode 100644
index 0000000..a8d9d48
--- /dev/null
+++ b/tests/reference/fontparts/psfbuildcompgc.ufo/glyphs/L_tnC_apO_.glif
@@ -0,0 +1,40 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<glyph name="LtnCapO" format="2">
+ <advance width="1460"/>
+ <unicode hex="004F"/>
+ <anchor x="717" y="0" name="H"/>
+ <anchor x="717" y="-100" name="L"/>
+ <anchor x="994" y="0" name="O"/>
+ <anchor x="1460" y="1200" name="R"/>
+ <anchor x="717" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="1145" y="715" type="curve" smooth="yes"/>
+ <point x="1145" y="360"/>
+ <point x="965" y="150"/>
+ <point x="720" y="150" type="curve" smooth="yes"/>
+ <point x="460" y="150"/>
+ <point x="290" y="380"/>
+ <point x="290" y="745" type="curve" smooth="yes"/>
+ <point x="290" y="1091"/>
+ <point x="467" y="1310"/>
+ <point x="720" y="1310" type="curve" smooth="yes"/>
+ <point x="974" y="1310"/>
+ <point x="1145" y="1084"/>
+ </contour>
+ <contour>
+ <point x="1340" y="740" type="curve" smooth="yes"/>
+ <point x="1340" y="1219"/>
+ <point x="1048" y="1485"/>
+ <point x="730" y="1485" type="curve" smooth="yes"/>
+ <point x="407" y="1485"/>
+ <point x="95" y="1199"/>
+ <point x="95" y="720" type="curve" smooth="yes"/>
+ <point x="95" y="241"/>
+ <point x="388" y="-25"/>
+ <point x="710" y="-25" type="curve" smooth="yes"/>
+ <point x="1029" y="-25"/>
+ <point x="1340" y="260"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/fontparts/psfbuildcompgc.ufo/glyphs/L_tnC_apP_.glif b/tests/reference/fontparts/psfbuildcompgc.ufo/glyphs/L_tnC_apP_.glif
new file mode 100644
index 0000000..951363e
--- /dev/null
+++ b/tests/reference/fontparts/psfbuildcompgc.ufo/glyphs/L_tnC_apP_.glif
@@ -0,0 +1,50 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<glyph name="LtnCapP" format="2">
+ <advance width="1195"/>
+ <unicode hex="0050"/>
+ <anchor x="637" y="-100" name="L"/>
+ <anchor x="637" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="365" y="565" type="line"/>
+ <point x="430" y="558"/>
+ <point x="512" y="555"/>
+ <point x="585" y="555" type="curve" smooth="yes"/>
+ <point x="914" y="555"/>
+ <point x="1115" y="736"/>
+ <point x="1115" y="1030" type="curve" smooth="yes"/>
+ <point x="1115" y="1322"/>
+ <point x="908" y="1470"/>
+ <point x="585" y="1470" type="curve" smooth="yes"/>
+ <point x="372" y="1470"/>
+ <point x="160" y="1460"/>
+ <point x="160" y="1460" type="curve"/>
+ <point x="175" y="1380"/>
+ <point x="175" y="1196"/>
+ <point x="175" y="1000" type="curve"/>
+ <point x="175" y="435" type="line" smooth="yes"/>
+ <point x="175" y="238"/>
+ <point x="175" y="80"/>
+ <point x="160" y="0" type="curve"/>
+ <point x="380" y="0" type="line"/>
+ <point x="366" y="78"/>
+ <point x="365" y="237"/>
+ <point x="365" y="435" type="curve" smooth="yes"/>
+ </contour>
+ <contour>
+ <point x="365" y="1305" type="line"/>
+ <point x="433" y="1308"/>
+ <point x="481" y="1310"/>
+ <point x="575" y="1310" type="curve" smooth="yes"/>
+ <point x="841" y="1310"/>
+ <point x="925" y="1170"/>
+ <point x="925" y="1010" type="curve" smooth="yes"/>
+ <point x="925" y="849"/>
+ <point x="850" y="710"/>
+ <point x="570" y="710" type="curve" smooth="yes"/>
+ <point x="495" y="710"/>
+ <point x="428" y="712"/>
+ <point x="365" y="720" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/fontparts/psfbuildcompgc.ufo/glyphs/L_tnC_apQ_.glif b/tests/reference/fontparts/psfbuildcompgc.ufo/glyphs/L_tnC_apQ_.glif
new file mode 100644
index 0000000..f77cfcc
--- /dev/null
+++ b/tests/reference/fontparts/psfbuildcompgc.ufo/glyphs/L_tnC_apQ_.glif
@@ -0,0 +1,49 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<glyph name="LtnCapQ" format="2">
+ <advance width="1475"/>
+ <unicode hex="0051"/>
+ <anchor x="717" y="-270" name="L"/>
+ <anchor x="717" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="1340" y="740" type="curve" smooth="yes"/>
+ <point x="1340" y="1219"/>
+ <point x="1053" y="1485"/>
+ <point x="730" y="1485" type="curve" smooth="yes"/>
+ <point x="407" y="1485"/>
+ <point x="95" y="1199"/>
+ <point x="95" y="720" type="curve" smooth="yes"/>
+ <point x="95" y="241"/>
+ <point x="383" y="-25"/>
+ <point x="705" y="-25" type="curve" smooth="yes"/>
+ <point x="767" y="-25"/>
+ <point x="818" y="-18"/>
+ <point x="875" y="0" type="curve"/>
+ <point x="944" y="0"/>
+ <point x="1236" y="-190"/>
+ <point x="1320" y="-190" type="curve" smooth="yes"/>
+ <point x="1374" y="-190"/>
+ <point x="1431" y="-81"/>
+ <point x="1455" y="-45" type="curve"/>
+ <point x="1321" y="-28"/>
+ <point x="1205" y="28"/>
+ <point x="1080" y="105" type="curve"/>
+ <point x="1256" y="236"/>
+ <point x="1340" y="479"/>
+ </contour>
+ <contour>
+ <point x="1145" y="715" type="curve" smooth="yes"/>
+ <point x="1145" y="360"/>
+ <point x="965" y="150"/>
+ <point x="720" y="150" type="curve" smooth="yes"/>
+ <point x="460" y="150"/>
+ <point x="290" y="380"/>
+ <point x="290" y="745" type="curve" smooth="yes"/>
+ <point x="290" y="1091"/>
+ <point x="467" y="1310"/>
+ <point x="720" y="1310" type="curve" smooth="yes"/>
+ <point x="974" y="1310"/>
+ <point x="1145" y="1084"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/fontparts/psfbuildcompgc.ufo/glyphs/L_tnC_apR_.glif b/tests/reference/fontparts/psfbuildcompgc.ufo/glyphs/L_tnC_apR_.glif
new file mode 100644
index 0000000..5c26573
--- /dev/null
+++ b/tests/reference/fontparts/psfbuildcompgc.ufo/glyphs/L_tnC_apR_.glif
@@ -0,0 +1,55 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<glyph name="LtnCapR" format="2">
+ <advance width="1305"/>
+ <unicode hex="0052"/>
+ <anchor x="285" y="0" name="H"/>
+ <anchor x="610" y="-100" name="L"/>
+ <anchor x="610" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="365" y="625" type="line"/>
+ <point x="620" y="625" type="line"/>
+ <point x="805" y="625"/>
+ <point x="1090" y="743"/>
+ <point x="1090" y="1060" type="curve" smooth="yes"/>
+ <point x="1090" y="1349"/>
+ <point x="876" y="1470"/>
+ <point x="565" y="1470" type="curve" smooth="yes"/>
+ <point x="331" y="1470"/>
+ <point x="160" y="1460"/>
+ <point x="160" y="1460" type="curve"/>
+ <point x="175" y="1380"/>
+ <point x="175" y="1196"/>
+ <point x="175" y="1000" type="curve" smooth="yes"/>
+ <point x="175" y="435" type="line"/>
+ <point x="175" y="238"/>
+ <point x="175" y="80"/>
+ <point x="160" y="0" type="curve"/>
+ <point x="380" y="0" type="line"/>
+ <point x="366" y="78"/>
+ <point x="365" y="238"/>
+ <point x="365" y="435" type="curve"/>
+ </contour>
+ <contour>
+ <point x="365" y="1305" type="line"/>
+ <point x="418" y="1307"/>
+ <point x="485" y="1310"/>
+ <point x="555" y="1310" type="curve" smooth="yes"/>
+ <point x="800" y="1310"/>
+ <point x="900" y="1216"/>
+ <point x="900" y="1045" type="curve" smooth="yes"/>
+ <point x="900" y="879"/>
+ <point x="780" y="780"/>
+ <point x="555" y="780" type="curve"/>
+ <point x="365" y="780" type="line"/>
+ </contour>
+ <contour>
+ <point x="561" y="635" type="line"/>
+ <point x="990" y="0" type="line"/>
+ <point x="1245" y="0" type="line"/>
+ <point x="1178" y="73"/>
+ <point x="715" y="710"/>
+ <point x="715" y="710" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/fontparts/psfbuildcompgc.ufo/glyphs/L_tnC_apS_.glif b/tests/reference/fontparts/psfbuildcompgc.ufo/glyphs/L_tnC_apS_.glif
new file mode 100644
index 0000000..d366837
--- /dev/null
+++ b/tests/reference/fontparts/psfbuildcompgc.ufo/glyphs/L_tnC_apS_.glif
@@ -0,0 +1,50 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<glyph name="LtnCapS" format="2">
+ <advance width="1175"/>
+ <unicode hex="0053"/>
+ <anchor x="580" y="0" name="H"/>
+ <anchor x="580" y="-100" name="L"/>
+ <anchor x="580" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="1000" y="1395" type="line"/>
+ <point x="870" y="1458"/>
+ <point x="759" y="1485"/>
+ <point x="605" y="1485" type="curve" smooth="yes"/>
+ <point x="273" y="1485"/>
+ <point x="135" y="1250"/>
+ <point x="135" y="1080" type="curve" smooth="yes"/>
+ <point x="135" y="910"/>
+ <point x="203" y="778"/>
+ <point x="515" y="685" type="curve" smooth="yes"/>
+ <point x="827" y="591"/>
+ <point x="875" y="510"/>
+ <point x="875" y="405" type="curve" smooth="yes"/>
+ <point x="875" y="243"/>
+ <point x="726" y="150"/>
+ <point x="565" y="150" type="curve" smooth="yes"/>
+ <point x="417" y="150"/>
+ <point x="272" y="200"/>
+ <point x="140" y="315" type="curve"/>
+ <point x="95" y="110" type="line"/>
+ <point x="197" y="31"/>
+ <point x="372" y="-25"/>
+ <point x="565" y="-25" type="curve" smooth="yes"/>
+ <point x="838" y="-25"/>
+ <point x="1065" y="157"/>
+ <point x="1065" y="425" type="curve" smooth="yes"/>
+ <point x="1065" y="641"/>
+ <point x="920" y="762"/>
+ <point x="655" y="840" type="curve" smooth="yes"/>
+ <point x="370" y="923"/>
+ <point x="325" y="985"/>
+ <point x="325" y="1095" type="curve" smooth="yes"/>
+ <point x="325" y="1205"/>
+ <point x="435" y="1310"/>
+ <point x="595" y="1310" type="curve" smooth="yes"/>
+ <point x="723" y="1310"/>
+ <point x="817" y="1279"/>
+ <point x="960" y="1200" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/fontparts/psfbuildcompgc.ufo/glyphs/L_tnC_apT_.glif b/tests/reference/fontparts/psfbuildcompgc.ufo/glyphs/L_tnC_apT_.glif
new file mode 100644
index 0000000..04a79a2
--- /dev/null
+++ b/tests/reference/fontparts/psfbuildcompgc.ufo/glyphs/L_tnC_apT_.glif
@@ -0,0 +1,32 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<glyph name="LtnCapT" format="2">
+ <advance width="1265"/>
+ <unicode hex="0054"/>
+ <anchor x="622" y="0" name="H"/>
+ <anchor x="622" y="-100" name="L"/>
+ <anchor x="622" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="45" y="1460" type="line"/>
+ <point x="45" y="1275" type="line"/>
+ <point x="125" y="1292"/>
+ <point x="201" y="1295"/>
+ <point x="290" y="1295" type="curve" smooth="yes"/>
+ <point x="525" y="1295" type="line"/>
+ <point x="525" y="435" type="line" smooth="yes"/>
+ <point x="525" y="238"/>
+ <point x="522" y="80"/>
+ <point x="505" y="0" type="curve"/>
+ <point x="735" y="0" type="line"/>
+ <point x="718" y="80"/>
+ <point x="715" y="238"/>
+ <point x="715" y="435" type="curve" smooth="yes"/>
+ <point x="715" y="1295" type="line"/>
+ <point x="955" y="1295" type="line" smooth="yes"/>
+ <point x="1045" y="1295"/>
+ <point x="1120" y="1292"/>
+ <point x="1200" y="1275" type="curve"/>
+ <point x="1200" y="1460" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/fontparts/psfbuildcompgc.ufo/glyphs/L_tnC_apU_.glif b/tests/reference/fontparts/psfbuildcompgc.ufo/glyphs/L_tnC_apU_.glif
new file mode 100644
index 0000000..89a8ff7
--- /dev/null
+++ b/tests/reference/fontparts/psfbuildcompgc.ufo/glyphs/L_tnC_apU_.glif
@@ -0,0 +1,38 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<glyph name="LtnCapU" format="2">
+ <advance width="1440"/>
+ <unicode hex="0055"/>
+ <anchor x="707" y="0" name="H"/>
+ <anchor x="707" y="-100" name="L"/>
+ <anchor x="1026" y="0" name="O"/>
+ <anchor x="1400" y="1200" name="R"/>
+ <anchor x="707" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="1050" y="1460" type="line"/>
+ <point x="1050" y="560" type="line" smooth="yes"/>
+ <point x="1050" y="299"/>
+ <point x="968" y="135"/>
+ <point x="710" y="135" type="curve" smooth="yes"/>
+ <point x="447" y="135"/>
+ <point x="365" y="299"/>
+ <point x="365" y="560" type="curve" smooth="yes"/>
+ <point x="365" y="1460" type="line"/>
+ <point x="160" y="1460" type="line"/>
+ <point x="174" y="1380"/>
+ <point x="175" y="1222"/>
+ <point x="175" y="1025" type="curve" smooth="yes"/>
+ <point x="175" y="515" type="line"/>
+ <point x="175" y="190"/>
+ <point x="345" y="-25"/>
+ <point x="710" y="-25" type="curve" smooth="yes"/>
+ <point x="1071" y="-25"/>
+ <point x="1240" y="190"/>
+ <point x="1240" y="515" type="curve"/>
+ <point x="1240" y="1025" type="line" smooth="yes"/>
+ <point x="1240" y="1232"/>
+ <point x="1242" y="1380"/>
+ <point x="1255" y="1460" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/fontparts/psfbuildcompgc.ufo/glyphs/L_tnC_apV_.glif b/tests/reference/fontparts/psfbuildcompgc.ufo/glyphs/L_tnC_apV_.glif
new file mode 100644
index 0000000..997a8a7
--- /dev/null
+++ b/tests/reference/fontparts/psfbuildcompgc.ufo/glyphs/L_tnC_apV_.glif
@@ -0,0 +1,26 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<glyph name="LtnCapV" format="2">
+ <advance width="1365"/>
+ <unicode hex="0056"/>
+ <anchor x="680" y="0" name="H"/>
+ <anchor x="672" y="-100" name="L"/>
+ <anchor x="880" y="0" name="O"/>
+ <anchor x="672" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="1095" y="1460" type="line"/>
+ <point x="672" y="195" type="line"/>
+ <point x="250" y="1460" type="line"/>
+ <point x="35" y="1460" type="line"/>
+ <point x="68" y="1378"/>
+ <point x="101" y="1288"/>
+ <point x="170" y="1095" type="curve" smooth="yes"/>
+ <point x="560" y="0" type="line"/>
+ <point x="785" y="0" type="line"/>
+ <point x="1170" y="1095" type="line" smooth="yes"/>
+ <point x="1238" y="1289"/>
+ <point x="1274" y="1378"/>
+ <point x="1310" y="1460" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/fontparts/psfbuildcompgc.ufo/glyphs/L_tnC_apW_.glif b/tests/reference/fontparts/psfbuildcompgc.ufo/glyphs/L_tnC_apW_.glif
new file mode 100644
index 0000000..2c1334b
--- /dev/null
+++ b/tests/reference/fontparts/psfbuildcompgc.ufo/glyphs/L_tnC_apW_.glif
@@ -0,0 +1,45 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<glyph name="LtnCapW" format="2">
+ <advance width="2080"/>
+ <unicode hex="0057"/>
+ <anchor x="1027" y="-100" name="L"/>
+ <anchor x="1027" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="1480" y="0" type="line"/>
+ <point x="1595" y="0" type="line"/>
+ <point x="1900" y="1095" type="line" smooth="yes"/>
+ <point x="1954" y="1289"/>
+ <point x="1983" y="1378"/>
+ <point x="2015" y="1460" type="curve"/>
+ <point x="1795" y="1460" type="line"/>
+ <point x="1470" y="130" type="line"/>
+ </contour>
+ <contour>
+ <point x="1120" y="1460" type="line"/>
+ <point x="935" y="1460" type="line"/>
+ <point x="990" y="1305" type="line"/>
+ <point x="1370" y="0" type="line"/>
+ <point x="1480" y="0" type="line"/>
+ <point x="1500" y="130" type="line"/>
+ </contour>
+ <contour>
+ <point x="580" y="0" type="line"/>
+ <point x="685" y="0" type="line"/>
+ <point x="1065" y="1305" type="line"/>
+ <point x="1120" y="1460" type="line"/>
+ <point x="935" y="1460" type="line"/>
+ <point x="560" y="130" type="line"/>
+ </contour>
+ <contour>
+ <point x="260" y="1460" type="line"/>
+ <point x="40" y="1460" type="line"/>
+ <point x="71" y="1381"/>
+ <point x="102" y="1286"/>
+ <point x="155" y="1095" type="curve" smooth="yes"/>
+ <point x="460" y="0" type="line"/>
+ <point x="580" y="0" type="line"/>
+ <point x="590" y="130" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/fontparts/psfbuildcompgc.ufo/glyphs/L_tnC_apX_.glif b/tests/reference/fontparts/psfbuildcompgc.ufo/glyphs/L_tnC_apX_.glif
new file mode 100644
index 0000000..441f459
--- /dev/null
+++ b/tests/reference/fontparts/psfbuildcompgc.ufo/glyphs/L_tnC_apX_.glif
@@ -0,0 +1,35 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<glyph name="LtnCapX" format="2">
+ <advance width="1325"/>
+ <unicode hex="0058"/>
+ <anchor x="650" y="-100" name="L"/>
+ <anchor x="650" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="537" y="781" type="line"/>
+ <point x="265" y="340" type="line" smooth="yes"/>
+ <point x="136" y="132"/>
+ <point x="103" y="86"/>
+ <point x="40" y="0" type="curve"/>
+ <point x="270" y="0" type="line"/>
+ <point x="642" y="614" type="line"/>
+ <point x="1030" y="0" type="line"/>
+ <point x="1260" y="0" type="line"/>
+ <point x="1199" y="82"/>
+ <point x="1165" y="127"/>
+ <point x="1033" y="336" type="curve" smooth="yes"/>
+ <point x="761" y="767" type="line"/>
+ <point x="972" y="1110" type="line" smooth="yes"/>
+ <point x="1097" y="1313"/>
+ <point x="1148" y="1383"/>
+ <point x="1210" y="1460" type="curve"/>
+ <point x="975" y="1460" type="line"/>
+ <point x="656" y="934" type="line"/>
+ <point x="325" y="1460" type="line"/>
+ <point x="90" y="1460" type="line"/>
+ <point x="154" y="1376"/>
+ <point x="201" y="1315"/>
+ <point x="330" y="1110" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/fontparts/psfbuildcompgc.ufo/glyphs/L_tnC_apY_.glif b/tests/reference/fontparts/psfbuildcompgc.ufo/glyphs/L_tnC_apY_.glif
new file mode 100644
index 0000000..e21cdce
--- /dev/null
+++ b/tests/reference/fontparts/psfbuildcompgc.ufo/glyphs/L_tnC_apY_.glif
@@ -0,0 +1,32 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<glyph name="LtnCapY" format="2">
+ <advance width="1320"/>
+ <unicode hex="0059"/>
+ <anchor x="650" y="-100" name="L"/>
+ <anchor x="650" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="35" y="1460" type="line"/>
+ <point x="147" y="1311"/>
+ <point x="213" y="1197"/>
+ <point x="290" y="1065" type="curve" smooth="yes"/>
+ <point x="555" y="611" type="line"/>
+ <point x="555" y="435" type="line" smooth="yes"/>
+ <point x="555" y="238"/>
+ <point x="555" y="80"/>
+ <point x="540" y="0" type="curve"/>
+ <point x="760" y="0" type="line"/>
+ <point x="745" y="80"/>
+ <point x="745" y="238"/>
+ <point x="745" y="435" type="curve" smooth="yes"/>
+ <point x="745" y="603" type="line"/>
+ <point x="1015" y="1065" type="line" smooth="yes"/>
+ <point x="1091" y="1195"/>
+ <point x="1147" y="1291"/>
+ <point x="1265" y="1460" type="curve"/>
+ <point x="1035" y="1460" type="line"/>
+ <point x="660" y="799" type="line"/>
+ <point x="265" y="1460" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/fontparts/psfbuildcompgc.ufo/glyphs/L_tnS_mA_.glif b/tests/reference/fontparts/psfbuildcompgc.ufo/glyphs/L_tnS_mA_.glif
new file mode 100644
index 0000000..85a2cbd
--- /dev/null
+++ b/tests/reference/fontparts/psfbuildcompgc.ufo/glyphs/L_tnS_mA_.glif
@@ -0,0 +1,68 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<glyph name="LtnSmA" format="2">
+ <advance width="1120"/>
+ <unicode hex="0061"/>
+ <note>
+GlyphNote A
+</note>
+ <anchor x="540" y="0" name="H"/>
+ <anchor x="540" y="-100" name="L"/>
+ <anchor x="1125" y="0" name="O"/>
+ <anchor x="1120" y="1000" name="R"/>
+ <anchor x="540" y="1100" name="U"/>
+ <outline>
+ <contour>
+ <point x="950" y="760" type="line"/>
+ <point x="950" y="919"/>
+ <point x="800" y="1040"/>
+ <point x="570" y="1040" type="curve" smooth="yes"/>
+ <point x="418" y="1040"/>
+ <point x="312" y="994"/>
+ <point x="209" y="950" type="curve"/>
+ <point x="203" y="907"/>
+ <point x="200" y="799"/>
+ <point x="199" y="755" type="curve"/>
+ <point x="316" y="837"/>
+ <point x="419" y="880"/>
+ <point x="525" y="880" type="curve" smooth="yes"/>
+ <point x="675" y="880"/>
+ <point x="765" y="831"/>
+ <point x="765" y="710" type="curve" smooth="yes"/>
+ <point x="765" y="635" type="line"/>
+ <point x="724" y="632"/>
+ <point x="564" y="617"/>
+ <point x="495" y="610" type="curve" smooth="yes"/>
+ <point x="186" y="580"/>
+ <point x="95" y="407"/>
+ <point x="95" y="255" type="curve" smooth="yes"/>
+ <point x="95" y="107"/>
+ <point x="232" y="-25"/>
+ <point x="420" y="-25" type="curve" smooth="yes"/>
+ <point x="544" y="-25"/>
+ <point x="677" y="29"/>
+ <point x="795" y="155" type="curve"/>
+ <point x="809" y="91"/>
+ <point x="833" y="32"/>
+ <point x="845" y="0" type="curve"/>
+ <point x="1025" y="0" type="line"/>
+ <point x="981" y="112"/>
+ <point x="950" y="226"/>
+ <point x="950" y="370" type="curve"/>
+ </contour>
+ <contour>
+ <point x="765" y="325" type="line"/>
+ <point x="644" y="164"/>
+ <point x="552" y="140"/>
+ <point x="450" y="140" type="curve" smooth="yes"/>
+ <point x="340" y="140"/>
+ <point x="275" y="191"/>
+ <point x="275" y="280" type="curve" smooth="yes"/>
+ <point x="275" y="372"/>
+ <point x="335" y="450"/>
+ <point x="505" y="470" type="curve" smooth="yes"/>
+ <point x="568" y="478"/>
+ <point x="715" y="493"/>
+ <point x="765" y="495" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/fontparts/psfbuildcompgc.ufo/glyphs/L_tnS_mA_A_cute.glif b/tests/reference/fontparts/psfbuildcompgc.ufo/glyphs/L_tnS_mA_A_cute.glif
new file mode 100644
index 0000000..f65e4af
--- /dev/null
+++ b/tests/reference/fontparts/psfbuildcompgc.ufo/glyphs/L_tnS_mA_A_cute.glif
@@ -0,0 +1,14 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<glyph name="LtnSmAAcute" format="2">
+ <advance width="1120"/>
+ <unicode hex="00E1"/>
+ <anchor x="540" y="0" name="H"/>
+ <anchor x="540" y="-100" name="L"/>
+ <anchor x="1125" y="0" name="O"/>
+ <anchor x="1120" y="1000" name="R"/>
+ <anchor x="540" y="1635" name="U"/>
+ <outline>
+ <component base="LtnSmA"/>
+ <component base="CombAcute" xOffset="1110"/>
+ </outline>
+</glyph>
diff --git a/tests/reference/fontparts/psfbuildcompgc.ufo/glyphs/L_tnS_mA_C_ircum.glif b/tests/reference/fontparts/psfbuildcompgc.ufo/glyphs/L_tnS_mA_C_ircum.glif
new file mode 100644
index 0000000..3029ff4
--- /dev/null
+++ b/tests/reference/fontparts/psfbuildcompgc.ufo/glyphs/L_tnS_mA_C_ircum.glif
@@ -0,0 +1,14 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<glyph name="LtnSmACircum" format="2">
+ <advance width="1120"/>
+ <unicode hex="00E2"/>
+ <anchor x="540" y="0" name="H"/>
+ <anchor x="540" y="-100" name="L"/>
+ <anchor x="1125" y="0" name="O"/>
+ <anchor x="1120" y="1000" name="R"/>
+ <anchor x="540" y="1635" name="U"/>
+ <outline>
+ <component base="LtnSmA"/>
+ <component base="CombCircum" xOffset="1110"/>
+ </outline>
+</glyph>
diff --git a/tests/reference/fontparts/psfbuildcompgc.ufo/glyphs/L_tnS_mA_D_iaer.glif b/tests/reference/fontparts/psfbuildcompgc.ufo/glyphs/L_tnS_mA_D_iaer.glif
new file mode 100644
index 0000000..a276885
--- /dev/null
+++ b/tests/reference/fontparts/psfbuildcompgc.ufo/glyphs/L_tnS_mA_D_iaer.glif
@@ -0,0 +1,14 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<glyph name="LtnSmADiaer" format="2">
+ <advance width="1120"/>
+ <unicode hex="00E4"/>
+ <anchor x="540" y="0" name="H"/>
+ <anchor x="540" y="-100" name="L"/>
+ <anchor x="1125" y="0" name="O"/>
+ <anchor x="1120" y="1000" name="R"/>
+ <anchor x="540" y="1505" name="U"/>
+ <outline>
+ <component base="LtnSmA"/>
+ <component base="CombDiaer" xOffset="1110"/>
+ </outline>
+</glyph>
diff --git a/tests/reference/fontparts/psfbuildcompgc.ufo/glyphs/L_tnS_mA_G_rave.glif b/tests/reference/fontparts/psfbuildcompgc.ufo/glyphs/L_tnS_mA_G_rave.glif
new file mode 100644
index 0000000..d738e2a
--- /dev/null
+++ b/tests/reference/fontparts/psfbuildcompgc.ufo/glyphs/L_tnS_mA_G_rave.glif
@@ -0,0 +1,14 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<glyph name="LtnSmAGrave" format="2">
+ <advance width="1120"/>
+ <unicode hex="00E0"/>
+ <anchor x="540" y="0" name="H"/>
+ <anchor x="540" y="-100" name="L"/>
+ <anchor x="1125" y="0" name="O"/>
+ <anchor x="1120" y="1000" name="R"/>
+ <anchor x="540" y="1635" name="U"/>
+ <outline>
+ <component base="LtnSmA"/>
+ <component base="CombGrave" xOffset="1090"/>
+ </outline>
+</glyph>
diff --git a/tests/reference/fontparts/psfbuildcompgc.ufo/glyphs/L_tnS_mA_R_ingA_bv.glif b/tests/reference/fontparts/psfbuildcompgc.ufo/glyphs/L_tnS_mA_R_ingA_bv.glif
new file mode 100644
index 0000000..30de698
--- /dev/null
+++ b/tests/reference/fontparts/psfbuildcompgc.ufo/glyphs/L_tnS_mA_R_ingA_bv.glif
@@ -0,0 +1,41 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<glyph name="LtnSmARingAbv" format="2">
+ <advance width="1120"/>
+ <unicode hex="00E5"/>
+ <anchor x="540" y="0" name="H"/>
+ <anchor x="540" y="-100" name="L"/>
+ <anchor x="1125" y="0" name="O"/>
+ <anchor x="1120" y="1000" name="R"/>
+ <anchor x="542" y="1635" name="U"/>
+ <outline>
+ <contour>
+ <point x="642" y="1385" type="curve" smooth="yes"/>
+ <point x="642" y="1325"/>
+ <point x="602" y="1285"/>
+ <point x="542" y="1285" type="curve" smooth="yes"/>
+ <point x="482" y="1285"/>
+ <point x="442" y="1325"/>
+ <point x="442" y="1385" type="curve" smooth="yes"/>
+ <point x="442" y="1445"/>
+ <point x="482" y="1485"/>
+ <point x="542" y="1485" type="curve" smooth="yes"/>
+ <point x="602" y="1485"/>
+ <point x="642" y="1445"/>
+ </contour>
+ <contour>
+ <point x="327" y="1385" type="curve" smooth="yes"/>
+ <point x="327" y="1265"/>
+ <point x="422" y="1170"/>
+ <point x="542" y="1170" type="curve" smooth="yes"/>
+ <point x="662" y="1170"/>
+ <point x="757" y="1265"/>
+ <point x="757" y="1385" type="curve" smooth="yes"/>
+ <point x="757" y="1505"/>
+ <point x="662" y="1600"/>
+ <point x="542" y="1600" type="curve" smooth="yes"/>
+ <point x="422" y="1600"/>
+ <point x="327" y="1505"/>
+ </contour>
+ <component base="LtnSmA"/>
+ </outline>
+</glyph>
diff --git a/tests/reference/fontparts/psfbuildcompgc.ufo/glyphs/L_tnS_mA_T_ilde.glif b/tests/reference/fontparts/psfbuildcompgc.ufo/glyphs/L_tnS_mA_T_ilde.glif
new file mode 100644
index 0000000..83f6f41
--- /dev/null
+++ b/tests/reference/fontparts/psfbuildcompgc.ufo/glyphs/L_tnS_mA_T_ilde.glif
@@ -0,0 +1,41 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<glyph name="LtnSmATilde" format="2">
+ <advance width="1120"/>
+ <unicode hex="00E3"/>
+ <anchor x="540" y="0" name="H"/>
+ <anchor x="540" y="-100" name="L"/>
+ <anchor x="1125" y="0" name="O"/>
+ <anchor x="1120" y="1000" name="R"/>
+ <anchor x="540" y="1475" name="U"/>
+ <outline>
+ <contour>
+ <point x="295" y="1205" type="line"/>
+ <point x="300" y="1254"/>
+ <point x="331" y="1290"/>
+ <point x="380" y="1290" type="curve" smooth="yes"/>
+ <point x="417" y="1290"/>
+ <point x="458" y="1274"/>
+ <point x="535" y="1238" type="curve" smooth="yes"/>
+ <point x="596" y="1210"/>
+ <point x="649" y="1190"/>
+ <point x="702" y="1190" type="curve" smooth="yes"/>
+ <point x="825" y="1190"/>
+ <point x="900" y="1312"/>
+ <point x="900" y="1440" type="curve"/>
+ <point x="795" y="1440" type="line"/>
+ <point x="788" y="1394"/>
+ <point x="757" y="1355"/>
+ <point x="710" y="1355" type="curve" smooth="yes"/>
+ <point x="668" y="1355"/>
+ <point x="627" y="1374"/>
+ <point x="555" y="1403" type="curve" smooth="yes"/>
+ <point x="485" y="1431"/>
+ <point x="438" y="1455"/>
+ <point x="382" y="1455" type="curve" smooth="yes"/>
+ <point x="263" y="1455"/>
+ <point x="190" y="1327"/>
+ <point x="190" y="1205" type="curve"/>
+ </contour>
+ <component base="LtnSmA"/>
+ </outline>
+</glyph>
diff --git a/tests/reference/fontparts/psfbuildcompgc.ufo/glyphs/L_tnS_mB_.glif b/tests/reference/fontparts/psfbuildcompgc.ufo/glyphs/L_tnS_mB_.glif
new file mode 100644
index 0000000..ab7bcde
--- /dev/null
+++ b/tests/reference/fontparts/psfbuildcompgc.ufo/glyphs/L_tnS_mB_.glif
@@ -0,0 +1,50 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<glyph name="LtnSmB" format="2">
+ <advance width="1155"/>
+ <unicode hex="0062"/>
+ <anchor x="590" y="0" name="H"/>
+ <anchor x="590" y="-100" name="L"/>
+ <anchor x="1155" y="1000" name="R"/>
+ <anchor x="590" y="1635" name="U"/>
+ <outline>
+ <contour>
+ <point x="130" y="1600" type="line"/>
+ <point x="145" y="1488"/>
+ <point x="145" y="1273"/>
+ <point x="145" y="1130" type="curve" smooth="yes"/>
+ <point x="145" y="936"/>
+ <point x="145" y="228"/>
+ <point x="145" y="65" type="curve"/>
+ <point x="272" y="26"/>
+ <point x="413" y="-25"/>
+ <point x="575" y="-25" type="curve" smooth="yes"/>
+ <point x="870" y="-25"/>
+ <point x="1060" y="197"/>
+ <point x="1060" y="540" type="curve" smooth="yes"/>
+ <point x="1060" y="832"/>
+ <point x="917" y="1040"/>
+ <point x="715" y="1040" type="curve" smooth="yes"/>
+ <point x="547" y="1040"/>
+ <point x="423" y="947"/>
+ <point x="330" y="825" type="curve"/>
+ <point x="330" y="916"/>
+ <point x="330" y="1600"/>
+ <point x="330" y="1600" type="curve"/>
+ </contour>
+ <contour>
+ <point x="330" y="585" type="line"/>
+ <point x="398" y="751"/>
+ <point x="531" y="865"/>
+ <point x="655" y="865" type="curve" smooth="yes"/>
+ <point x="799" y="865"/>
+ <point x="880" y="727"/>
+ <point x="880" y="505" type="curve" smooth="yes"/>
+ <point x="880" y="280"/>
+ <point x="752" y="130"/>
+ <point x="575" y="130" type="curve" smooth="yes"/>
+ <point x="489" y="130"/>
+ <point x="428" y="144"/>
+ <point x="330" y="185" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/fontparts/psfbuildcompgc.ufo/glyphs/L_tnS_mC_.glif b/tests/reference/fontparts/psfbuildcompgc.ufo/glyphs/L_tnS_mC_.glif
new file mode 100644
index 0000000..39f16eb
--- /dev/null
+++ b/tests/reference/fontparts/psfbuildcompgc.ufo/glyphs/L_tnS_mC_.glif
@@ -0,0 +1,39 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<glyph name="LtnSmC" format="2">
+ <advance width="1020"/>
+ <unicode hex="0063"/>
+ <anchor x="580" y="0" name="H"/>
+ <anchor x="580" y="-100" name="L"/>
+ <anchor x="1020" y="1000" name="R"/>
+ <anchor x="570" y="1100" name="U"/>
+ <outline>
+ <contour>
+ <point x="905" y="260" type="line"/>
+ <point x="818" y="183"/>
+ <point x="720" y="140"/>
+ <point x="600" y="140" type="curve" smooth="yes"/>
+ <point x="406" y="140"/>
+ <point x="285" y="285"/>
+ <point x="285" y="500" type="curve" smooth="yes"/>
+ <point x="285" y="736"/>
+ <point x="422" y="875"/>
+ <point x="600" y="875" type="curve" smooth="yes"/>
+ <point x="703" y="875"/>
+ <point x="790" y="841"/>
+ <point x="880" y="775" type="curve"/>
+ <point x="915" y="955" type="line"/>
+ <point x="842" y="1005"/>
+ <point x="748" y="1040"/>
+ <point x="615" y="1040" type="curve" smooth="yes"/>
+ <point x="297" y="1040"/>
+ <point x="95" y="792"/>
+ <point x="95" y="490" type="curve" smooth="yes"/>
+ <point x="95" y="171"/>
+ <point x="312" y="-25"/>
+ <point x="580" y="-25" type="curve" smooth="yes"/>
+ <point x="730" y="-25"/>
+ <point x="824" y="9"/>
+ <point x="925" y="85" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/fontparts/psfbuildcompgc.ufo/glyphs/L_tnS_mC_A_cute.glif b/tests/reference/fontparts/psfbuildcompgc.ufo/glyphs/L_tnS_mC_A_cute.glif
new file mode 100644
index 0000000..de7824f
--- /dev/null
+++ b/tests/reference/fontparts/psfbuildcompgc.ufo/glyphs/L_tnS_mC_A_cute.glif
@@ -0,0 +1,9 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<glyph name="LtnSmCAcute" format="2">
+ <advance width="1355"/>
+ <unicode hex="0107"/>
+ <outline>
+ <component base="LtnCapC"/>
+ <component base="CombAcute" xOffset="1320.0" yOffset="430.0"/>
+ </outline>
+</glyph>
diff --git a/tests/reference/fontparts/psfbuildcompgc.ufo/glyphs/L_tnS_mC_A_cuteC_edilla.glif b/tests/reference/fontparts/psfbuildcompgc.ufo/glyphs/L_tnS_mC_A_cuteC_edilla.glif
new file mode 100644
index 0000000..0c65825
--- /dev/null
+++ b/tests/reference/fontparts/psfbuildcompgc.ufo/glyphs/L_tnS_mC_A_cuteC_edilla.glif
@@ -0,0 +1,10 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<glyph name="LtnSmCAcuteCedilla" format="2">
+ <advance width="1020"/>
+ <unicode hex="1E09"/>
+ <outline>
+ <component base="LtnSmC"/>
+ <component base="CombCedilla" xOffset="580.0"/>
+ <component base="CombAcute" xOffset="1140.0"/>
+ </outline>
+</glyph>
diff --git a/tests/reference/fontparts/psfbuildcompgc.ufo/glyphs/L_tnS_mC_C_ircum.glif b/tests/reference/fontparts/psfbuildcompgc.ufo/glyphs/L_tnS_mC_C_ircum.glif
new file mode 100644
index 0000000..5fc7213
--- /dev/null
+++ b/tests/reference/fontparts/psfbuildcompgc.ufo/glyphs/L_tnS_mC_C_ircum.glif
@@ -0,0 +1,9 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<glyph name="LtnSmCCircum" format="2">
+ <advance width="1020"/>
+ <unicode hex="0109"/>
+ <outline>
+ <component base="LtnSmC"/>
+ <component base="CombCircum" xOffset="1140.0"/>
+ </outline>
+</glyph>
diff --git a/tests/reference/fontparts/psfbuildcompgc.ufo/glyphs/L_tnS_mD_.glif b/tests/reference/fontparts/psfbuildcompgc.ufo/glyphs/L_tnS_mD_.glif
new file mode 100644
index 0000000..bbf7c3f
--- /dev/null
+++ b/tests/reference/fontparts/psfbuildcompgc.ufo/glyphs/L_tnS_mD_.glif
@@ -0,0 +1,53 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<glyph name="LtnSmD" format="2">
+ <advance width="1190"/>
+ <unicode hex="0064"/>
+ <anchor x="605" y="0" name="H"/>
+ <anchor x="605" y="-100" name="L"/>
+ <anchor x="1190" y="1000" name="R"/>
+ <anchor x="605" y="1635" name="U"/>
+ <outline>
+ <contour>
+ <point x="1030" y="1600" type="line"/>
+ <point x="820" y="1600" type="line"/>
+ <point x="839" y="1516"/>
+ <point x="845" y="1395"/>
+ <point x="845" y="1235" type="curve"/>
+ <point x="845" y="955" type="line"/>
+ <point x="767" y="999"/>
+ <point x="665" y="1040"/>
+ <point x="580" y="1040" type="curve" smooth="yes"/>
+ <point x="312" y="1040"/>
+ <point x="105" y="814"/>
+ <point x="105" y="460" type="curve" smooth="yes"/>
+ <point x="105" y="167"/>
+ <point x="261" y="-25"/>
+ <point x="505" y="-25" type="curve" smooth="yes"/>
+ <point x="652" y="-25"/>
+ <point x="775" y="50"/>
+ <point x="870" y="185" type="curve"/>
+ <point x="887" y="111"/>
+ <point x="910" y="34"/>
+ <point x="925" y="0" type="curve"/>
+ <point x="1105" y="0" type="line"/>
+ <point x="1062" y="112"/>
+ <point x="1030" y="278"/>
+ <point x="1030" y="530" type="curve"/>
+ </contour>
+ <contour>
+ <point x="845" y="400" type="line"/>
+ <point x="790" y="268"/>
+ <point x="662" y="135"/>
+ <point x="540" y="135" type="curve" smooth="yes"/>
+ <point x="366" y="135"/>
+ <point x="290" y="258"/>
+ <point x="290" y="490" type="curve" smooth="yes"/>
+ <point x="290" y="727"/>
+ <point x="429" y="870"/>
+ <point x="580" y="870" type="curve" smooth="yes"/>
+ <point x="681" y="870"/>
+ <point x="746" y="848"/>
+ <point x="845" y="795" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/fontparts/psfbuildcompgc.ufo/glyphs/L_tnS_mE_.glif b/tests/reference/fontparts/psfbuildcompgc.ufo/glyphs/L_tnS_mE_.glif
new file mode 100644
index 0000000..81c908d
--- /dev/null
+++ b/tests/reference/fontparts/psfbuildcompgc.ufo/glyphs/L_tnS_mE_.glif
@@ -0,0 +1,45 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<glyph name="LtnSmE" format="2">
+ <advance width="1095"/>
+ <unicode hex="0065"/>
+ <anchor x="545" y="0" name="H"/>
+ <anchor x="569" y="-100" name="L"/>
+ <anchor x="925" y="0" name="O"/>
+ <anchor x="1095" y="1000" name="R"/>
+ <anchor x="569" y="1100" name="U"/>
+ <outline>
+ <contour>
+ <point x="989" y="485" type="line"/>
+ <point x="990" y="503"/>
+ <point x="990" y="545"/>
+ <point x="990" y="563" type="curve" smooth="yes"/>
+ <point x="990" y="788"/>
+ <point x="905" y="1040"/>
+ <point x="575" y="1040" type="curve" smooth="yes"/>
+ <point x="279" y="1040"/>
+ <point x="95" y="826"/>
+ <point x="95" y="495" type="curve" smooth="yes"/>
+ <point x="95" y="155"/>
+ <point x="320" y="-25"/>
+ <point x="575" y="-25" type="curve" smooth="yes"/>
+ <point x="729" y="-25"/>
+ <point x="853" y="2"/>
+ <point x="995" y="75" type="curve"/>
+ <point x="975" y="240" type="line"/>
+ <point x="853" y="166"/>
+ <point x="729" y="140"/>
+ <point x="600" y="140" type="curve" smooth="yes"/>
+ <point x="414" y="140"/>
+ <point x="280" y="258"/>
+ <point x="280" y="505" type="curve" smooth="yes"/>
+ <point x="280" y="770"/>
+ <point x="385" y="890"/>
+ <point x="560" y="890" type="curve" smooth="yes"/>
+ <point x="705" y="890"/>
+ <point x="810" y="797"/>
+ <point x="810" y="625" type="curve"/>
+ <point x="245" y="625" type="line"/>
+ <point x="245" y="485" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/fontparts/psfbuildcompgc.ufo/glyphs/L_tnS_mF_.glif b/tests/reference/fontparts/psfbuildcompgc.ufo/glyphs/L_tnS_mF_.glif
new file mode 100644
index 0000000..3134ee2
--- /dev/null
+++ b/tests/reference/fontparts/psfbuildcompgc.ufo/glyphs/L_tnS_mF_.glif
@@ -0,0 +1,39 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<glyph name="LtnSmF" format="2">
+ <advance width="750"/>
+ <unicode hex="0066"/>
+ <anchor x="370" y="0" name="H"/>
+ <anchor x="335" y="-100" name="L"/>
+ <anchor x="560" y="1635" name="U"/>
+ <outline>
+ <contour>
+ <point x="40" y="850" type="line"/>
+ <point x="240" y="850" type="line"/>
+ <point x="240" y="0" type="line"/>
+ <point x="455" y="0" type="line"/>
+ <point x="433" y="105"/>
+ <point x="425" y="300"/>
+ <point x="425" y="494" type="curve" smooth="yes"/>
+ <point x="425" y="850" type="line"/>
+ <point x="695" y="850" type="line"/>
+ <point x="695" y="995" type="line"/>
+ <point x="425" y="995" type="line"/>
+ <point x="425" y="1210" type="line" smooth="yes"/>
+ <point x="425" y="1381"/>
+ <point x="481" y="1450"/>
+ <point x="585" y="1450" type="curve" smooth="yes"/>
+ <point x="643" y="1450"/>
+ <point x="710" y="1427"/>
+ <point x="760" y="1390" type="curve"/>
+ <point x="805" y="1550" type="line"/>
+ <point x="743" y="1594"/>
+ <point x="663" y="1620"/>
+ <point x="585" y="1620" type="curve" smooth="yes"/>
+ <point x="369" y="1620"/>
+ <point x="240" y="1470"/>
+ <point x="240" y="1170" type="curve" smooth="yes"/>
+ <point x="240" y="995" type="line"/>
+ <point x="40" y="995" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/fontparts/psfbuildcompgc.ufo/glyphs/L_tnS_mG_.glif b/tests/reference/fontparts/psfbuildcompgc.ufo/glyphs/L_tnS_mG_.glif
new file mode 100644
index 0000000..def42a0
--- /dev/null
+++ b/tests/reference/fontparts/psfbuildcompgc.ufo/glyphs/L_tnS_mG_.glif
@@ -0,0 +1,91 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<glyph name="LtnSmG" format="2">
+ <advance width="1095"/>
+ <unicode hex="0067"/>
+ <anchor x="545" y="-432" name="H"/>
+ <anchor x="545" y="-535" name="L"/>
+ <anchor x="1095" y="1000" name="R"/>
+ <anchor x="515" y="1100" name="U"/>
+ <outline>
+ <contour>
+ <point x="330" y="395" type="line"/>
+ <point x="234" y="357"/>
+ <point x="180" y="275"/>
+ <point x="180" y="215" type="curve" smooth="yes"/>
+ <point x="180" y="121"/>
+ <point x="263" y="27"/>
+ <point x="545" y="-5" type="curve" smooth="yes"/>
+ <point x="805" y="-35"/>
+ <point x="880" y="-90"/>
+ <point x="880" y="-170" type="curve" smooth="yes"/>
+ <point x="880" y="-255"/>
+ <point x="731" y="-360"/>
+ <point x="550" y="-360" type="curve" smooth="yes"/>
+ <point x="323" y="-360"/>
+ <point x="215" y="-261"/>
+ <point x="215" y="-180" type="curve" smooth="yes"/>
+ <point x="215" y="-121"/>
+ <point x="244" y="-56"/>
+ <point x="465" y="20" type="curve"/>
+ <point x="459" y="49"/>
+ <point x="290" y="75"/>
+ <point x="290" y="75" type="curve"/>
+ <point x="113" y="2"/>
+ <point x="30" y="-89"/>
+ <point x="30" y="-200" type="curve" smooth="yes"/>
+ <point x="30" y="-409"/>
+ <point x="303" y="-505"/>
+ <point x="535" y="-505" type="curve" smooth="yes"/>
+ <point x="777" y="-505"/>
+ <point x="1065" y="-375"/>
+ <point x="1065" y="-160" type="curve" smooth="yes"/>
+ <point x="1065" y="-8"/>
+ <point x="967" y="90"/>
+ <point x="670" y="125" type="curve" smooth="yes"/>
+ <point x="410" y="156"/>
+ <point x="345" y="198"/>
+ <point x="345" y="235" type="curve" smooth="yes"/>
+ <point x="345" y="271"/>
+ <point x="384" y="316"/>
+ <point x="500" y="350" type="curve"/>
+ </contour>
+ <contour>
+ <point x="1050" y="1040" type="line"/>
+ <point x="951" y="1033"/>
+ <point x="819" y="997"/>
+ <point x="730" y="940" type="curve"/>
+ <point x="795" y="825" type="line"/>
+ <point x="887" y="863"/>
+ <point x="967" y="878"/>
+ <point x="1040" y="880" type="curve"/>
+ </contour>
+ <contour>
+ <point x="115" y="680" type="curve" smooth="yes"/>
+ <point x="115" y="476"/>
+ <point x="289" y="325"/>
+ <point x="515" y="325" type="curve" smooth="yes"/>
+ <point x="742" y="325"/>
+ <point x="915" y="476"/>
+ <point x="915" y="680" type="curve" smooth="yes"/>
+ <point x="915" y="884"/>
+ <point x="742" y="1040"/>
+ <point x="515" y="1040" type="curve" smooth="yes"/>
+ <point x="289" y="1040"/>
+ <point x="115" y="884"/>
+ </contour>
+ <contour>
+ <point x="285" y="680" type="curve" smooth="yes"/>
+ <point x="285" y="803"/>
+ <point x="382" y="895"/>
+ <point x="515" y="895" type="curve" smooth="yes"/>
+ <point x="649" y="895"/>
+ <point x="745" y="803"/>
+ <point x="745" y="680" type="curve" smooth="yes"/>
+ <point x="745" y="557"/>
+ <point x="649" y="465"/>
+ <point x="515" y="465" type="curve" smooth="yes"/>
+ <point x="382" y="465"/>
+ <point x="285" y="557"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/fontparts/psfbuildcompgc.ufo/glyphs/L_tnS_mH_.glif b/tests/reference/fontparts/psfbuildcompgc.ufo/glyphs/L_tnS_mH_.glif
new file mode 100644
index 0000000..146c089
--- /dev/null
+++ b/tests/reference/fontparts/psfbuildcompgc.ufo/glyphs/L_tnS_mH_.glif
@@ -0,0 +1,43 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<glyph name="LtnSmH" format="2">
+ <advance width="1175"/>
+ <unicode hex="0068"/>
+ <anchor x="250" y="0" name="H"/>
+ <anchor x="585" y="-100" name="L"/>
+ <anchor x="585" y="1635" name="U"/>
+ <outline>
+ <contour>
+ <point x="1040" y="0" type="line"/>
+ <point x="1040" y="0"/>
+ <point x="1040" y="459"/>
+ <point x="1040" y="625" type="curve" smooth="yes"/>
+ <point x="1040" y="900"/>
+ <point x="923" y="1040"/>
+ <point x="710" y="1040" type="curve" smooth="yes"/>
+ <point x="570" y="1040"/>
+ <point x="428" y="969"/>
+ <point x="330" y="830" type="curve"/>
+ <point x="330" y="877"/>
+ <point x="330" y="1600"/>
+ <point x="330" y="1600" type="curve"/>
+ <point x="130" y="1600" type="line"/>
+ <point x="145" y="1514"/>
+ <point x="145" y="1345"/>
+ <point x="145" y="1130" type="curve" smooth="yes"/>
+ <point x="145" y="935"/>
+ <point x="145" y="0"/>
+ <point x="145" y="0" type="curve"/>
+ <point x="330" y="0" type="line"/>
+ <point x="330" y="580" type="line"/>
+ <point x="374" y="716"/>
+ <point x="511" y="865"/>
+ <point x="655" y="865" type="curve" smooth="yes"/>
+ <point x="789" y="865"/>
+ <point x="855" y="800"/>
+ <point x="855" y="550" type="curve" smooth="yes"/>
+ <point x="855" y="413"/>
+ <point x="855" y="0"/>
+ <point x="855" y="0" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/fontparts/psfbuildcompgc.ufo/glyphs/L_tnS_mI_.glif b/tests/reference/fontparts/psfbuildcompgc.ufo/glyphs/L_tnS_mI_.glif
new file mode 100644
index 0000000..08cb359
--- /dev/null
+++ b/tests/reference/fontparts/psfbuildcompgc.ufo/glyphs/L_tnS_mI_.glif
@@ -0,0 +1,40 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<glyph name="LtnSmI" format="2">
+ <advance width="565"/>
+ <unicode hex="0069"/>
+ <anchor x="282" y="0" name="H"/>
+ <anchor x="285" y="-100" name="L"/>
+ <anchor x="500" y="0" name="O"/>
+ <anchor x="555" y="1000" name="R"/>
+ <anchor x="282" y="1100" name="U"/>
+ <outline>
+ <contour>
+ <point x="375" y="1020" type="line"/>
+ <point x="175" y="1020" type="line"/>
+ <point x="188" y="915"/>
+ <point x="190" y="725"/>
+ <point x="190" y="530" type="curve" smooth="yes"/>
+ <point x="190" y="336"/>
+ <point x="190" y="0"/>
+ <point x="190" y="0" type="curve"/>
+ <point x="395" y="0" type="line"/>
+ <point x="382" y="107"/>
+ <point x="375" y="346"/>
+ <point x="375" y="475" type="curve" smooth="yes"/>
+ </contour>
+ <contour>
+ <point x="155" y="1345" type="curve" smooth="yes"/>
+ <point x="155" y="1271"/>
+ <point x="206" y="1210"/>
+ <point x="280" y="1210" type="curve" smooth="yes"/>
+ <point x="355" y="1210"/>
+ <point x="410" y="1271"/>
+ <point x="410" y="1345" type="curve" smooth="yes"/>
+ <point x="410" y="1419"/>
+ <point x="355" y="1480"/>
+ <point x="280" y="1480" type="curve" smooth="yes"/>
+ <point x="206" y="1480"/>
+ <point x="155" y="1419"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/fontparts/psfbuildcompgc.ufo/glyphs/L_tnS_mI_J_.glif b/tests/reference/fontparts/psfbuildcompgc.ufo/glyphs/L_tnS_mI_J_.glif
new file mode 100644
index 0000000..347d2ad
--- /dev/null
+++ b/tests/reference/fontparts/psfbuildcompgc.ufo/glyphs/L_tnS_mI_J_.glif
@@ -0,0 +1,9 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<glyph name="LtnSmIJ" format="2">
+ <advance width="1160"/>
+ <unicode hex="0133"/>
+ <outline>
+ <component base="LtnSmI"/>
+ <component base="LtnSmJ" xOffset="565"/>
+ </outline>
+</glyph>
diff --git a/tests/reference/fontparts/psfbuildcompgc.ufo/glyphs/L_tnS_mI_T_ilde.glif b/tests/reference/fontparts/psfbuildcompgc.ufo/glyphs/L_tnS_mI_T_ilde.glif
new file mode 100644
index 0000000..8316e85
--- /dev/null
+++ b/tests/reference/fontparts/psfbuildcompgc.ufo/glyphs/L_tnS_mI_T_ilde.glif
@@ -0,0 +1,9 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<glyph name="LtnSmITilde" format="2">
+ <advance width="1110.0"/>
+ <unicode hex="0129"/>
+ <outline>
+ <component base="LtnSmDotlessI" xOffset="550.0"/>
+ <component base="CombTilde" xOffset="1125.0" yOffset="-1100.0"/>
+ </outline>
+</glyph>
diff --git a/tests/reference/fontparts/psfbuildcompgc.ufo/glyphs/L_tnS_mI_T_ildeG_rave.glif b/tests/reference/fontparts/psfbuildcompgc.ufo/glyphs/L_tnS_mI_T_ildeG_rave.glif
new file mode 100644
index 0000000..65aebc1
--- /dev/null
+++ b/tests/reference/fontparts/psfbuildcompgc.ufo/glyphs/L_tnS_mI_T_ildeG_rave.glif
@@ -0,0 +1,9 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<glyph name="LtnSmITildeGrave" format="2">
+ <unicode hex="E000"/>
+ <outline>
+ <component base="LtnSmDotlessI"/>
+ <component base="CombTilde" xOffset="575.0" yOffset="-1100.0"/>
+ <component base="CombGrave" xOffset="550.0" yOffset="-725.0"/>
+ </outline>
+</glyph>
diff --git a/tests/reference/fontparts/psfbuildcompgc.ufo/glyphs/L_tnS_mI_T_ildeG_raveC_edilla.glif b/tests/reference/fontparts/psfbuildcompgc.ufo/glyphs/L_tnS_mI_T_ildeG_raveC_edilla.glif
new file mode 100644
index 0000000..62825a9
--- /dev/null
+++ b/tests/reference/fontparts/psfbuildcompgc.ufo/glyphs/L_tnS_mI_T_ildeG_raveC_edilla.glif
@@ -0,0 +1,14 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<glyph name="LtnSmITildeGraveCedilla" format="2">
+ <advance width="1150.0"/>
+ <unicode hex="E010"/>
+ <note>
+i cedilla tilde grave
+</note>
+ <outline>
+ <component base="LtnSmDotlessI" xOffset="590.0"/>
+ <component base="CombCedilla" xOffset="590.0"/>
+ <component base="CombTilde" xOffset="1165.0" yOffset="-1100.0"/>
+ <component base="CombGrave" xOffset="1140.0" yOffset="-725.0"/>
+ </outline>
+</glyph>
diff --git a/tests/reference/fontparts/psfbuildcompgc.ufo/glyphs/L_tnS_mJ_.glif b/tests/reference/fontparts/psfbuildcompgc.ufo/glyphs/L_tnS_mJ_.glif
new file mode 100644
index 0000000..f5d9485
--- /dev/null
+++ b/tests/reference/fontparts/psfbuildcompgc.ufo/glyphs/L_tnS_mJ_.glif
@@ -0,0 +1,44 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<glyph name="LtnSmJ" format="2">
+ <advance width="595"/>
+ <unicode hex="006A"/>
+ <anchor x="125" y="-500" name="L"/>
+ <anchor x="313" y="1100" name="U"/>
+ <outline>
+ <contour>
+ <point x="405" y="1020" type="line"/>
+ <point x="205" y="1020" type="line"/>
+ <point x="218" y="915"/>
+ <point x="220" y="725"/>
+ <point x="220" y="530" type="curve"/>
+ <point x="220" y="-25" type="line"/>
+ <point x="220" y="-222"/>
+ <point x="147" y="-300"/>
+ <point x="40" y="-300" type="curve" smooth="yes"/>
+ <point x="-16" y="-300"/>
+ <point x="-111" y="-273"/>
+ <point x="-155" y="-240" type="curve"/>
+ <point x="-190" y="-405" type="line"/>
+ <point x="-130" y="-446"/>
+ <point x="-26" y="-470"/>
+ <point x="30" y="-470" type="curve" smooth="yes"/>
+ <point x="258" y="-470"/>
+ <point x="405" y="-348"/>
+ <point x="405" y="25" type="curve" smooth="yes"/>
+ </contour>
+ <contour>
+ <point x="185" y="1345" type="curve" smooth="yes"/>
+ <point x="185" y="1271"/>
+ <point x="236" y="1210"/>
+ <point x="310" y="1210" type="curve" smooth="yes"/>
+ <point x="385" y="1210"/>
+ <point x="440" y="1271"/>
+ <point x="440" y="1345" type="curve" smooth="yes"/>
+ <point x="440" y="1419"/>
+ <point x="385" y="1480"/>
+ <point x="310" y="1480" type="curve" smooth="yes"/>
+ <point x="236" y="1480"/>
+ <point x="185" y="1419"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/fontparts/psfbuildcompgc.ufo/glyphs/L_tnS_mK_.glif b/tests/reference/fontparts/psfbuildcompgc.ufo/glyphs/L_tnS_mK_.glif
new file mode 100644
index 0000000..13033fa
--- /dev/null
+++ b/tests/reference/fontparts/psfbuildcompgc.ufo/glyphs/L_tnS_mK_.glif
@@ -0,0 +1,35 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<glyph name="LtnSmK" format="2">
+ <advance width="1035"/>
+ <unicode hex="006B"/>
+ <guideline x="500" y="774" angle="314"/>
+ <anchor x="243" y="0" name="H"/>
+ <anchor x="572" y="-100" name="L"/>
+ <anchor x="1035" y="1000" name="R"/>
+ <anchor x="572" y="1635" name="U"/>
+ <outline>
+ <contour>
+ <point x="330" y="0" type="line"/>
+ <point x="330" y="1600" type="line"/>
+ <point x="130" y="1600" type="line"/>
+ <point x="145" y="1514"/>
+ <point x="145" y="1345"/>
+ <point x="145" y="1130" type="curve" smooth="yes"/>
+ <point x="145" y="934"/>
+ <point x="145" y="0"/>
+ <point x="145" y="0" type="curve"/>
+ </contour>
+ <contour>
+ <point x="735" y="1020" type="line"/>
+ <point x="280" y="550" type="line"/>
+ <point x="436" y="524" type="line"/>
+ <point x="985" y="1020" type="line"/>
+ </contour>
+ <contour>
+ <point x="305" y="550" type="line"/>
+ <point x="770" y="0" type="line"/>
+ <point x="1015" y="0" type="line"/>
+ <point x="410" y="660" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/fontparts/psfbuildcompgc.ufo/glyphs/L_tnS_mL_.glif b/tests/reference/fontparts/psfbuildcompgc.ufo/glyphs/L_tnS_mL_.glif
new file mode 100644
index 0000000..11d4645
--- /dev/null
+++ b/tests/reference/fontparts/psfbuildcompgc.ufo/glyphs/L_tnS_mL_.glif
@@ -0,0 +1,24 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<glyph name="LtnSmL" format="2">
+ <advance width="565"/>
+ <unicode hex="006C"/>
+ <guideline x="500" y="874" angle="340"/>
+ <anchor x="290" y="0" name="H"/>
+ <anchor x="290" y="-100" name="L"/>
+ <anchor x="550" y="1000" name="R"/>
+ <anchor x="282" y="1635" name="U"/>
+ <outline>
+ <contour>
+ <point x="375" y="1600" type="line"/>
+ <point x="170" y="1600" type="line"/>
+ <point x="183" y="1485"/>
+ <point x="190" y="1324"/>
+ <point x="190" y="1130" type="curve"/>
+ <point x="190" y="0" type="line"/>
+ <point x="395" y="0" type="line"/>
+ <point x="382" y="109"/>
+ <point x="375" y="346"/>
+ <point x="375" y="475" type="curve" smooth="yes"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/fontparts/psfbuildcompgc.ufo/glyphs/L_tnS_mM_.glif b/tests/reference/fontparts/psfbuildcompgc.ufo/glyphs/L_tnS_mM_.glif
new file mode 100644
index 0000000..921bd1f
--- /dev/null
+++ b/tests/reference/fontparts/psfbuildcompgc.ufo/glyphs/L_tnS_mM_.glif
@@ -0,0 +1,52 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<glyph name="LtnSmM" format="2">
+ <advance width="1685"/>
+ <unicode hex="006D"/>
+ <anchor x="1450" y="0" name="H"/>
+ <anchor x="865" y="-100" name="L"/>
+ <anchor x="865" y="1100" name="U"/>
+ <outline>
+ <contour>
+ <point x="945" y="660" type="line"/>
+ <point x="1003" y="785"/>
+ <point x="1102" y="865"/>
+ <point x="1200" y="865" type="curve" smooth="yes"/>
+ <point x="1312" y="865"/>
+ <point x="1345" y="808"/>
+ <point x="1345" y="550" type="curve" smooth="yes"/>
+ <point x="1345" y="0" type="line"/>
+ <point x="1530" y="0" type="line"/>
+ <point x="1530" y="660" type="line" smooth="yes"/>
+ <point x="1530" y="907"/>
+ <point x="1463" y="1040"/>
+ <point x="1260" y="1040" type="curve" smooth="yes"/>
+ <point x="1155" y="1040"/>
+ <point x="1046" y="1007"/>
+ <point x="921" y="872" type="curve"/>
+ <point x="888" y="960"/>
+ <point x="806" y="1040"/>
+ <point x="675" y="1040" type="curve" smooth="yes"/>
+ <point x="560" y="1040"/>
+ <point x="459" y="1006"/>
+ <point x="337" y="865" type="curve"/>
+ <point x="330" y="913"/>
+ <point x="320" y="978"/>
+ <point x="305" y="1020" type="curve"/>
+ <point x="125" y="1020" type="line"/>
+ <point x="146" y="951"/>
+ <point x="175" y="811"/>
+ <point x="175" y="615" type="curve" smooth="yes"/>
+ <point x="175" y="0" type="line"/>
+ <point x="360" y="0" type="line"/>
+ <point x="360" y="660" type="line"/>
+ <point x="413" y="780"/>
+ <point x="517" y="865"/>
+ <point x="615" y="865" type="curve" smooth="yes"/>
+ <point x="727" y="865"/>
+ <point x="760" y="818"/>
+ <point x="760" y="570" type="curve" smooth="yes"/>
+ <point x="760" y="0" type="line"/>
+ <point x="945" y="0" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/fontparts/psfbuildcompgc.ufo/glyphs/L_tnS_mN_.glif b/tests/reference/fontparts/psfbuildcompgc.ufo/glyphs/L_tnS_mN_.glif
new file mode 100644
index 0000000..bb83ce9
--- /dev/null
+++ b/tests/reference/fontparts/psfbuildcompgc.ufo/glyphs/L_tnS_mN_.glif
@@ -0,0 +1,43 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<glyph name="LtnSmN" format="2">
+ <advance width="1185"/>
+ <unicode hex="006E"/>
+ <anchor x="970" y="0" name="H"/>
+ <anchor x="600" y="-100" name="L"/>
+ <anchor x="600" y="1100" name="U"/>
+ <outline>
+ <contour>
+ <point x="1050" y="0" type="line"/>
+ <point x="1050" y="0"/>
+ <point x="1050" y="459"/>
+ <point x="1050" y="625" type="curve" smooth="yes"/>
+ <point x="1050" y="900"/>
+ <point x="933" y="1040"/>
+ <point x="720" y="1040" type="curve" smooth="yes"/>
+ <point x="579" y="1040"/>
+ <point x="452" y="977"/>
+ <point x="325" y="825" type="curve"/>
+ <point x="318" y="873"/>
+ <point x="300" y="978"/>
+ <point x="285" y="1020" type="curve"/>
+ <point x="105" y="1020" type="line"/>
+ <point x="127" y="951"/>
+ <point x="155" y="811"/>
+ <point x="155" y="615" type="curve" smooth="yes"/>
+ <point x="155" y="420"/>
+ <point x="155" y="0"/>
+ <point x="155" y="0" type="curve"/>
+ <point x="340" y="0" type="line"/>
+ <point x="340" y="580" type="line"/>
+ <point x="384" y="716"/>
+ <point x="521" y="865"/>
+ <point x="665" y="865" type="curve" smooth="yes"/>
+ <point x="800" y="865"/>
+ <point x="865" y="800"/>
+ <point x="865" y="550" type="curve" smooth="yes"/>
+ <point x="865" y="413"/>
+ <point x="865" y="0"/>
+ <point x="865" y="0" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/fontparts/psfbuildcompgc.ufo/glyphs/L_tnS_mO_.glif b/tests/reference/fontparts/psfbuildcompgc.ufo/glyphs/L_tnS_mO_.glif
new file mode 100644
index 0000000..307e0a8
--- /dev/null
+++ b/tests/reference/fontparts/psfbuildcompgc.ufo/glyphs/L_tnS_mO_.glif
@@ -0,0 +1,40 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<glyph name="LtnSmO" format="2">
+ <advance width="1140"/>
+ <unicode hex="006F"/>
+ <anchor x="570" y="0" name="H"/>
+ <anchor x="570" y="-100" name="L"/>
+ <anchor x="835" y="0" name="O"/>
+ <anchor x="1140" y="1000" name="R"/>
+ <anchor x="570" y="1100" name="U"/>
+ <outline>
+ <contour>
+ <point x="95" y="505" type="curve" smooth="yes"/>
+ <point x="95" y="161"/>
+ <point x="286" y="-25"/>
+ <point x="560" y="-25" type="curve" smooth="yes"/>
+ <point x="823" y="-25"/>
+ <point x="1045" y="161"/>
+ <point x="1045" y="505" type="curve" smooth="yes"/>
+ <point x="1045" y="849"/>
+ <point x="855" y="1040"/>
+ <point x="580" y="1040" type="curve" smooth="yes"/>
+ <point x="317" y="1040"/>
+ <point x="95" y="849"/>
+ </contour>
+ <contour>
+ <point x="280" y="505" type="curve" smooth="yes"/>
+ <point x="280" y="739"/>
+ <point x="408" y="880"/>
+ <point x="570" y="880" type="curve" smooth="yes"/>
+ <point x="742" y="880"/>
+ <point x="860" y="739"/>
+ <point x="860" y="505" type="curve" smooth="yes"/>
+ <point x="860" y="272"/>
+ <point x="731" y="135"/>
+ <point x="570" y="135" type="curve" smooth="yes"/>
+ <point x="398" y="135"/>
+ <point x="280" y="272"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/fontparts/psfbuildcompgc.ufo/glyphs/L_tnS_mP_.glif b/tests/reference/fontparts/psfbuildcompgc.ufo/glyphs/L_tnS_mP_.glif
new file mode 100644
index 0000000..ec43067
--- /dev/null
+++ b/tests/reference/fontparts/psfbuildcompgc.ufo/glyphs/L_tnS_mP_.glif
@@ -0,0 +1,56 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<glyph name="LtnSmP" format="2">
+ <advance width="1170"/>
+ <unicode hex="0070"/>
+ <guideline x="214" y="-490" angle="0"/>
+ <anchor x="265" y="-435" name="H"/>
+ <anchor x="590" y="-500" name="L"/>
+ <anchor x="1170" y="1000" name="R"/>
+ <anchor x="590" y="1100" name="U"/>
+ <outline>
+ <contour>
+ <point x="105" y="1020" type="line"/>
+ <point x="150" y="907"/>
+ <point x="155" y="734"/>
+ <point x="155" y="485" type="curve" smooth="yes"/>
+ <point x="155" y="291"/>
+ <point x="155" y="-490"/>
+ <point x="155" y="-490" type="curve"/>
+ <point x="365" y="-490" type="line"/>
+ <point x="348" y="-405"/>
+ <point x="340" y="-310"/>
+ <point x="340" y="-150" type="curve"/>
+ <point x="340" y="85" type="line"/>
+ <point x="435" y="18"/>
+ <point x="513" y="-25"/>
+ <point x="620" y="-25" type="curve" smooth="yes"/>
+ <point x="871" y="-25"/>
+ <point x="1075" y="193"/>
+ <point x="1075" y="535" type="curve" smooth="yes"/>
+ <point x="1075" y="828"/>
+ <point x="923" y="1040"/>
+ <point x="695" y="1040" type="curve" smooth="yes"/>
+ <point x="547" y="1040"/>
+ <point x="419" y="954"/>
+ <point x="325" y="830" type="curve"/>
+ <point x="316" y="922"/>
+ <point x="300" y="986"/>
+ <point x="285" y="1020" type="curve"/>
+ </contour>
+ <contour>
+ <point x="340" y="575" type="line"/>
+ <point x="414" y="768"/>
+ <point x="545" y="870"/>
+ <point x="660" y="870" type="curve" smooth="yes"/>
+ <point x="804" y="870"/>
+ <point x="890" y="727"/>
+ <point x="890" y="505" type="curve" smooth="yes"/>
+ <point x="890" y="279"/>
+ <point x="761" y="140"/>
+ <point x="620" y="140" type="curve" smooth="yes"/>
+ <point x="528" y="140"/>
+ <point x="477" y="164"/>
+ <point x="340" y="260" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/fontparts/psfbuildcompgc.ufo/glyphs/L_tnS_mQ_.glif b/tests/reference/fontparts/psfbuildcompgc.ufo/glyphs/L_tnS_mQ_.glif
new file mode 100644
index 0000000..9a891c1
--- /dev/null
+++ b/tests/reference/fontparts/psfbuildcompgc.ufo/glyphs/L_tnS_mQ_.glif
@@ -0,0 +1,47 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<glyph name="LtnSmQ" format="2">
+ <advance width="1130"/>
+ <unicode hex="0071"/>
+ <anchor x="555" y="-500" name="L"/>
+ <anchor x="1130" y="1000" name="R"/>
+ <anchor x="555" y="1100" name="U"/>
+ <outline>
+ <contour>
+ <point x="795" y="-490" type="line"/>
+ <point x="1005" y="-490" type="line"/>
+ <point x="988" y="-405"/>
+ <point x="980" y="-310"/>
+ <point x="980" y="-150" type="curve" smooth="yes"/>
+ <point x="980" y="-26"/>
+ <point x="980" y="965"/>
+ <point x="980" y="965" type="curve"/>
+ <point x="872" y="1001"/>
+ <point x="746" y="1040"/>
+ <point x="625" y="1040" type="curve" smooth="yes"/>
+ <point x="260" y="1040"/>
+ <point x="105" y="742"/>
+ <point x="105" y="435" type="curve" smooth="yes"/>
+ <point x="105" y="117"/>
+ <point x="321" y="-25"/>
+ <point x="505" y="-25" type="curve" smooth="yes"/>
+ <point x="598" y="-25"/>
+ <point x="691" y="19"/>
+ <point x="795" y="140" type="curve"/>
+ </contour>
+ <contour>
+ <point x="795" y="365" type="line"/>
+ <point x="713" y="219"/>
+ <point x="612" y="145"/>
+ <point x="520" y="145" type="curve" smooth="yes"/>
+ <point x="412" y="145"/>
+ <point x="290" y="237"/>
+ <point x="290" y="485" type="curve" smooth="yes"/>
+ <point x="290" y="674"/>
+ <point x="376" y="870"/>
+ <point x="595" y="870" type="curve" smooth="yes"/>
+ <point x="656" y="870"/>
+ <point x="735" y="853"/>
+ <point x="795" y="830" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/fontparts/psfbuildcompgc.ufo/glyphs/L_tnS_mR_.glif b/tests/reference/fontparts/psfbuildcompgc.ufo/glyphs/L_tnS_mR_.glif
new file mode 100644
index 0000000..a49e22e
--- /dev/null
+++ b/tests/reference/fontparts/psfbuildcompgc.ufo/glyphs/L_tnS_mR_.glif
@@ -0,0 +1,36 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<glyph name="LtnSmR" format="2">
+ <advance width="890"/>
+ <unicode hex="0072"/>
+ <guideline x="214" y="500" angle="0"/>
+ <anchor x="270" y="0" name="H"/>
+ <anchor x="255" y="-100" name="L"/>
+ <anchor x="455" y="1100" name="U"/>
+ <outline>
+ <contour>
+ <point x="340" y="0" type="line"/>
+ <point x="340" y="580" type="line"/>
+ <point x="384" y="716"/>
+ <point x="521" y="860"/>
+ <point x="605" y="860" type="curve" smooth="yes"/>
+ <point x="684" y="860"/>
+ <point x="720" y="770"/>
+ <point x="720" y="670" type="curve"/>
+ <point x="880" y="705" type="line"/>
+ <point x="880" y="880"/>
+ <point x="817" y="1040"/>
+ <point x="650" y="1040" type="curve" smooth="yes"/>
+ <point x="559" y="1040"/>
+ <point x="422" y="964"/>
+ <point x="325" y="825" type="curve"/>
+ <point x="318" y="873"/>
+ <point x="300" y="978"/>
+ <point x="285" y="1020" type="curve"/>
+ <point x="105" y="1020" type="line"/>
+ <point x="127" y="951"/>
+ <point x="155" y="811"/>
+ <point x="155" y="615" type="curve" smooth="yes"/>
+ <point x="155" y="0" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/fontparts/psfbuildcompgc.ufo/glyphs/L_tnS_mS_.glif b/tests/reference/fontparts/psfbuildcompgc.ufo/glyphs/L_tnS_mS_.glif
new file mode 100644
index 0000000..e823587
--- /dev/null
+++ b/tests/reference/fontparts/psfbuildcompgc.ufo/glyphs/L_tnS_mS_.glif
@@ -0,0 +1,50 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<glyph name="LtnSmS" format="2">
+ <advance width="965"/>
+ <unicode hex="0073"/>
+ <anchor x="495" y="0" name="H"/>
+ <anchor x="495" y="-100" name="L"/>
+ <anchor x="495" y="1100" name="U"/>
+ <outline>
+ <contour>
+ <point x="835" y="960" type="line"/>
+ <point x="766" y="998"/>
+ <point x="660" y="1040"/>
+ <point x="515" y="1040" type="curve" smooth="yes"/>
+ <point x="211" y="1040"/>
+ <point x="130" y="832"/>
+ <point x="130" y="740" type="curve" smooth="yes"/>
+ <point x="130" y="616"/>
+ <point x="182" y="514"/>
+ <point x="425" y="455" type="curve" smooth="yes"/>
+ <point x="649" y="400"/>
+ <point x="700" y="345"/>
+ <point x="700" y="270" type="curve" smooth="yes"/>
+ <point x="700" y="201"/>
+ <point x="617" y="135"/>
+ <point x="500" y="135" type="curve" smooth="yes"/>
+ <point x="394" y="135"/>
+ <point x="250" y="189"/>
+ <point x="160" y="270" type="curve"/>
+ <point x="110" y="90" type="line"/>
+ <point x="189" y="28"/>
+ <point x="333" y="-25"/>
+ <point x="495" y="-25" type="curve" smooth="yes"/>
+ <point x="710" y="-25"/>
+ <point x="880" y="115"/>
+ <point x="880" y="295" type="curve" smooth="yes"/>
+ <point x="880" y="481"/>
+ <point x="731" y="559"/>
+ <point x="550" y="600" type="curve" smooth="yes"/>
+ <point x="340" y="648"/>
+ <point x="310" y="680"/>
+ <point x="310" y="750" type="curve" smooth="yes"/>
+ <point x="310" y="810"/>
+ <point x="358" y="880"/>
+ <point x="505" y="880" type="curve" smooth="yes"/>
+ <point x="629" y="880"/>
+ <point x="733" y="824"/>
+ <point x="800" y="785" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/fontparts/psfbuildcompgc.ufo/glyphs/L_tnS_mT_.glif b/tests/reference/fontparts/psfbuildcompgc.ufo/glyphs/L_tnS_mT_.glif
new file mode 100644
index 0000000..841b84d
--- /dev/null
+++ b/tests/reference/fontparts/psfbuildcompgc.ufo/glyphs/L_tnS_mT_.glif
@@ -0,0 +1,39 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<glyph name="LtnSmT" format="2">
+ <advance width="835"/>
+ <unicode hex="0074"/>
+ <anchor x="475" y="0" name="H"/>
+ <anchor x="475" y="-100" name="L"/>
+ <anchor x="835" y="1000" name="R"/>
+ <anchor x="325" y="1360" name="U"/>
+ <outline>
+ <contour>
+ <point x="760" y="215" type="line"/>
+ <point x="672" y="166"/>
+ <point x="600" y="140"/>
+ <point x="543" y="140" type="curve" smooth="yes"/>
+ <point x="453" y="140"/>
+ <point x="415" y="184"/>
+ <point x="415" y="390" type="curve" smooth="yes"/>
+ <point x="415" y="528"/>
+ <point x="415" y="1320"/>
+ <point x="415" y="1320" type="curve"/>
+ <point x="230" y="1320" type="line"/>
+ <point x="230" y="1320"/>
+ <point x="230" y="435"/>
+ <point x="230" y="270" type="curve" smooth="yes"/>
+ <point x="230" y="39"/>
+ <point x="356" y="-25"/>
+ <point x="512" y="-25" type="curve" smooth="yes"/>
+ <point x="582" y="-25"/>
+ <point x="668" y="-4"/>
+ <point x="760" y="55" type="curve"/>
+ </contour>
+ <contour>
+ <point x="30" y="850" type="line"/>
+ <point x="740" y="850" type="line"/>
+ <point x="740" y="995" type="line"/>
+ <point x="30" y="995" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/fontparts/psfbuildcompgc.ufo/glyphs/L_tnS_mU_.glif b/tests/reference/fontparts/psfbuildcompgc.ufo/glyphs/L_tnS_mU_.glif
new file mode 100644
index 0000000..58e1d92
--- /dev/null
+++ b/tests/reference/fontparts/psfbuildcompgc.ufo/glyphs/L_tnS_mU_.glif
@@ -0,0 +1,51 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<glyph name="LtnSmU" format="2">
+ <advance width="1185"/>
+ <unicode hex="0075"/>
+ <anchor x="589" y="0" name="H"/>
+ <anchor x="589" y="-100" name="L"/>
+ <anchor x="1192" y="0" name="O"/>
+ <anchor x="1185" y="1000" name="R"/>
+ <anchor x="589" y="1100" name="U"/>
+ <outline>
+ <contour>
+ <point x="1090" y="0" type="line"/>
+ <point x="1048" y="112"/>
+ <point x="1025" y="256"/>
+ <point x="1025" y="450" type="curve" smooth="yes"/>
+ <point x="1025" y="646"/>
+ <point x="1025" y="1020"/>
+ <point x="1025" y="1020" type="curve"/>
+ <point x="820" y="1020" type="line"/>
+ <point x="838" y="898"/>
+ <point x="840" y="832"/>
+ <point x="840" y="700" type="curve" smooth="yes"/>
+ <point x="840" y="420" type="line"/>
+ <point x="787" y="298"/>
+ <point x="628" y="140"/>
+ <point x="510" y="140" type="curve" smooth="yes"/>
+ <point x="383" y="140"/>
+ <point x="340" y="238"/>
+ <point x="340" y="465" type="curve" smooth="yes"/>
+ <point x="340" y="603"/>
+ <point x="340" y="1020"/>
+ <point x="340" y="1020" type="curve"/>
+ <point x="135" y="1020" type="line"/>
+ <point x="153" y="900"/>
+ <point x="155" y="827"/>
+ <point x="155" y="700" type="curve" smooth="yes"/>
+ <point x="155" y="681"/>
+ <point x="155" y="424"/>
+ <point x="155" y="405" type="curve" smooth="yes"/>
+ <point x="155" y="120"/>
+ <point x="262" y="-25"/>
+ <point x="475" y="-25" type="curve" smooth="yes"/>
+ <point x="615" y="-25"/>
+ <point x="744" y="53"/>
+ <point x="865" y="200" type="curve"/>
+ <point x="875" y="125"/>
+ <point x="901" y="46"/>
+ <point x="920" y="0" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/fontparts/psfbuildcompgc.ufo/glyphs/L_tnS_mV_.glif b/tests/reference/fontparts/psfbuildcompgc.ufo/glyphs/L_tnS_mV_.glif
new file mode 100644
index 0000000..803148c
--- /dev/null
+++ b/tests/reference/fontparts/psfbuildcompgc.ufo/glyphs/L_tnS_mV_.glif
@@ -0,0 +1,30 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<glyph name="LtnSmV" format="2">
+ <advance width="1070"/>
+ <unicode hex="0076"/>
+ <anchor x="549" y="0" name="H"/>
+ <anchor x="535" y="-100" name="L"/>
+ <anchor x="725" y="0" name="O"/>
+ <anchor x="535" y="1100" name="U"/>
+ <outline>
+ <contour>
+ <point x="840" y="1020" type="line"/>
+ <point x="535" y="200" type="line"/>
+ <point x="230" y="1020" type="line"/>
+ <point x="20" y="1020" type="line"/>
+ <point x="75" y="905"/>
+ <point x="143" y="746"/>
+ <point x="175" y="665" type="curve" smooth="yes"/>
+ <point x="237" y="510"/>
+ <point x="440" y="0"/>
+ <point x="440" y="0" type="curve"/>
+ <point x="630" y="0" type="line"/>
+ <point x="630" y="0"/>
+ <point x="842" y="536"/>
+ <point x="895" y="665" type="curve" smooth="yes"/>
+ <point x="928" y="744"/>
+ <point x="993" y="905"/>
+ <point x="1050" y="1020" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/fontparts/psfbuildcompgc.ufo/glyphs/L_tnS_mW_.glif b/tests/reference/fontparts/psfbuildcompgc.ufo/glyphs/L_tnS_mW_.glif
new file mode 100644
index 0000000..947f002
--- /dev/null
+++ b/tests/reference/fontparts/psfbuildcompgc.ufo/glyphs/L_tnS_mW_.glif
@@ -0,0 +1,30 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<glyph name="LtnSmW" format="2">
+ <advance width="1550"/>
+ <unicode hex="0077"/>
+ <anchor x="775" y="-100" name="L"/>
+ <anchor x="775" y="1100" name="U"/>
+ <outline>
+ <contour>
+ <point x="700" y="1020" type="line"/>
+ <point x="440" y="215" type="line"/>
+ <point x="230" y="1020" type="line"/>
+ <point x="45" y="1020" type="line"/>
+ <point x="92" y="867"/>
+ <point x="120" y="771"/>
+ <point x="150" y="665" type="curve" smooth="yes"/>
+ <point x="335" y="0" type="line"/>
+ <point x="525" y="0" type="line"/>
+ <point x="775" y="785" type="line"/>
+ <point x="1025" y="0" type="line"/>
+ <point x="1215" y="0" type="line"/>
+ <point x="1400" y="665" type="line" smooth="yes"/>
+ <point x="1434" y="785"/>
+ <point x="1458" y="868"/>
+ <point x="1505" y="1020" type="curve"/>
+ <point x="1320" y="1020" type="line"/>
+ <point x="1110" y="215" type="line"/>
+ <point x="850" y="1020" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/fontparts/psfbuildcompgc.ufo/glyphs/L_tnS_mX_.glif b/tests/reference/fontparts/psfbuildcompgc.ufo/glyphs/L_tnS_mX_.glif
new file mode 100644
index 0000000..a194d45
--- /dev/null
+++ b/tests/reference/fontparts/psfbuildcompgc.ufo/glyphs/L_tnS_mX_.glif
@@ -0,0 +1,40 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<glyph name="LtnSmX" format="2">
+ <advance width="1085"/>
+ <unicode hex="0078"/>
+ <anchor x="900" y="0" name="H"/>
+ <anchor x="542" y="-100" name="L"/>
+ <anchor x="542" y="1100" name="U"/>
+ <outline>
+ <contour>
+ <point x="805" y="0" type="line"/>
+ <point x="1035" y="0" type="line"/>
+ <point x="927" y="142"/>
+ <point x="902" y="170"/>
+ <point x="830" y="270" type="curve" smooth="yes"/>
+ <point x="290" y="1020" type="line"/>
+ <point x="60" y="1020" type="line"/>
+ <point x="168" y="887"/>
+ <point x="203" y="843"/>
+ <point x="270" y="750" type="curve"/>
+ </contour>
+ <contour>
+ <point x="489" y="616" type="line"/>
+ <point x="250" y="270" type="line" smooth="yes"/>
+ <point x="189" y="182"/>
+ <point x="160" y="143"/>
+ <point x="50" y="0" type="curve"/>
+ <point x="275" y="0" type="line"/>
+ <point x="556" y="404" type="line"/>
+ </contour>
+ <contour>
+ <point x="585" y="405" type="line"/>
+ <point x="820" y="750" type="line" smooth="yes"/>
+ <point x="883" y="842"/>
+ <point x="917" y="886"/>
+ <point x="1020" y="1020" type="curve"/>
+ <point x="795" y="1020" type="line"/>
+ <point x="520" y="615" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/fontparts/psfbuildcompgc.ufo/glyphs/L_tnS_mY_.glif b/tests/reference/fontparts/psfbuildcompgc.ufo/glyphs/L_tnS_mY_.glif
new file mode 100644
index 0000000..804529e
--- /dev/null
+++ b/tests/reference/fontparts/psfbuildcompgc.ufo/glyphs/L_tnS_mY_.glif
@@ -0,0 +1,42 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<glyph name="LtnSmY" format="2">
+ <advance width="1060"/>
+ <unicode hex="0079"/>
+ <anchor x="795" y="-100" name="L"/>
+ <anchor x="1120" y="1000" name="R"/>
+ <anchor x="535" y="1100" name="U"/>
+ <outline>
+ <contour>
+ <point x="610" y="60" type="line"/>
+ <point x="230" y="1020" type="line"/>
+ <point x="30" y="1020" type="line"/>
+ <point x="107" y="864"/>
+ <point x="153" y="756"/>
+ <point x="190" y="665" type="curve" smooth="yes"/>
+ <point x="525" y="-165" type="line"/>
+ </contour>
+ <contour>
+ <point x="895" y="665" type="line"/>
+ <point x="928" y="758"/>
+ <point x="971" y="865"/>
+ <point x="1040" y="1020" type="curve"/>
+ <point x="840" y="1020" type="line"/>
+ <point x="840" y="1020"/>
+ <point x="564" y="230"/>
+ <point x="500" y="55" type="curve" smooth="yes"/>
+ <point x="391" y="-248"/>
+ <point x="315" y="-300"/>
+ <point x="225" y="-300" type="curve" smooth="yes"/>
+ <point x="159" y="-300"/>
+ <point x="82" y="-260"/>
+ <point x="40" y="-225" type="curve"/>
+ <point x="-20" y="-385" type="line"/>
+ <point x="53" y="-439"/>
+ <point x="134" y="-470"/>
+ <point x="225" y="-470" type="curve" smooth="yes"/>
+ <point x="395" y="-470"/>
+ <point x="516" y="-383"/>
+ <point x="655" y="0" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/fontparts/psfbuildcompgc.ufo/glyphs/N_onB_reakingH_yphen.glif b/tests/reference/fontparts/psfbuildcompgc.ufo/glyphs/N_onB_reakingH_yphen.glif
new file mode 100644
index 0000000..69d61c1
--- /dev/null
+++ b/tests/reference/fontparts/psfbuildcompgc.ufo/glyphs/N_onB_reakingH_yphen.glif
@@ -0,0 +1,9 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<glyph name="NonBreakingHyphen" format="2">
+ <advance width="860"/>
+ <unicode hex="2011"/>
+ <anchor x="430" y="1100" name="U"/>
+ <outline>
+ <component base="HyphenMinus"/>
+ </outline>
+</glyph>
diff --git a/tests/reference/fontparts/psfbuildcompgc.ufo/glyphs/N_umS_gn.glif b/tests/reference/fontparts/psfbuildcompgc.ufo/glyphs/N_umS_gn.glif
new file mode 100644
index 0000000..4128da8
--- /dev/null
+++ b/tests/reference/fontparts/psfbuildcompgc.ufo/glyphs/N_umS_gn.glif
@@ -0,0 +1,31 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<glyph name="NumSgn" format="2">
+ <advance width="1200"/>
+ <unicode hex="0023"/>
+ <outline>
+ <contour>
+ <point x="487" y="1460" type="line"/>
+ <point x="127" y="200" type="line"/>
+ <point x="277" y="200" type="line"/>
+ <point x="637" y="1460" type="line"/>
+ </contour>
+ <contour>
+ <point x="25" y="575" type="line"/>
+ <point x="1116" y="575" type="line"/>
+ <point x="1116" y="725" type="line"/>
+ <point x="25" y="725" type="line"/>
+ </contour>
+ <contour>
+ <point x="84" y="960" type="line"/>
+ <point x="1175" y="960" type="line"/>
+ <point x="1175" y="1110" type="line"/>
+ <point x="84" y="1110" type="line"/>
+ </contour>
+ <contour>
+ <point x="912" y="1460" type="line"/>
+ <point x="552" y="200" type="line"/>
+ <point x="702" y="200" type="line"/>
+ <point x="1062" y="1460" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/fontparts/psfbuildcompgc.ufo/glyphs/P_ercentS_gn.glif b/tests/reference/fontparts/psfbuildcompgc.ufo/glyphs/P_ercentS_gn.glif
new file mode 100644
index 0000000..ed94862
--- /dev/null
+++ b/tests/reference/fontparts/psfbuildcompgc.ufo/glyphs/P_ercentS_gn.glif
@@ -0,0 +1,69 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<glyph name="PercentSgn" format="2">
+ <advance width="1526"/>
+ <unicode hex="0025"/>
+ <outline>
+ <contour>
+ <point x="1261" y="366" type="curve" smooth="yes"/>
+ <point x="1261" y="182"/>
+ <point x="1216" y="115"/>
+ <point x="1130" y="115" type="curve" smooth="yes"/>
+ <point x="1041" y="115"/>
+ <point x="1001" y="181"/>
+ <point x="1001" y="381" type="curve" smooth="yes"/>
+ <point x="1001" y="565"/>
+ <point x="1043" y="630"/>
+ <point x="1130" y="630" type="curve" smooth="yes"/>
+ <point x="1221" y="630"/>
+ <point x="1261" y="566"/>
+ </contour>
+ <contour>
+ <point x="1426" y="379" type="curve" smooth="yes"/>
+ <point x="1426" y="652"/>
+ <point x="1310" y="770"/>
+ <point x="1135" y="770" type="curve" smooth="yes"/>
+ <point x="961" y="770"/>
+ <point x="836" y="650"/>
+ <point x="836" y="368" type="curve" smooth="yes"/>
+ <point x="836" y="86"/>
+ <point x="951" y="-25"/>
+ <point x="1126" y="-25" type="curve" smooth="yes"/>
+ <point x="1301" y="-25"/>
+ <point x="1426" y="84"/>
+ </contour>
+ <contour>
+ <point x="1073" y="1480" type="line"/>
+ <point x="291" y="-25" type="line"/>
+ <point x="459" y="-25" type="line"/>
+ <point x="1239" y="1480" type="line"/>
+ </contour>
+ <contour>
+ <point x="525" y="1076" type="curve" smooth="yes"/>
+ <point x="525" y="892"/>
+ <point x="480" y="825"/>
+ <point x="394" y="825" type="curve" smooth="yes"/>
+ <point x="305" y="825"/>
+ <point x="265" y="891"/>
+ <point x="265" y="1091" type="curve" smooth="yes"/>
+ <point x="265" y="1275"/>
+ <point x="307" y="1340"/>
+ <point x="394" y="1340" type="curve" smooth="yes"/>
+ <point x="485" y="1340"/>
+ <point x="525" y="1276"/>
+ </contour>
+ <contour>
+ <point x="690" y="1089" type="curve" smooth="yes"/>
+ <point x="690" y="1362"/>
+ <point x="574" y="1480"/>
+ <point x="399" y="1480" type="curve" smooth="yes"/>
+ <point x="225" y="1480"/>
+ <point x="100" y="1360"/>
+ <point x="100" y="1078" type="curve" smooth="yes"/>
+ <point x="100" y="796"/>
+ <point x="215" y="685"/>
+ <point x="390" y="685" type="curve" smooth="yes"/>
+ <point x="565" y="685"/>
+ <point x="690" y="794"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/fontparts/psfbuildcompgc.ufo/glyphs/P_lusS_gn.glif b/tests/reference/fontparts/psfbuildcompgc.ufo/glyphs/P_lusS_gn.glif
new file mode 100644
index 0000000..13fc2a0
--- /dev/null
+++ b/tests/reference/fontparts/psfbuildcompgc.ufo/glyphs/P_lusS_gn.glif
@@ -0,0 +1,19 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<glyph name="PlusSgn" format="2">
+ <advance width="1200"/>
+ <unicode hex="002B"/>
+ <outline>
+ <contour>
+ <point x="525" y="1180" type="line"/>
+ <point x="525" y="285" type="line"/>
+ <point x="675" y="285" type="line"/>
+ <point x="675" y="1180" type="line"/>
+ </contour>
+ <contour>
+ <point x="155" y="660" type="line"/>
+ <point x="1045" y="660" type="line"/>
+ <point x="1045" y="810" type="line"/>
+ <point x="155" y="810" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/fontparts/psfbuildcompgc.ufo/glyphs/Q_stnM_rk.glif b/tests/reference/fontparts/psfbuildcompgc.ufo/glyphs/Q_stnM_rk.glif
new file mode 100644
index 0000000..ab5a7d9
--- /dev/null
+++ b/tests/reference/fontparts/psfbuildcompgc.ufo/glyphs/Q_stnM_rk.glif
@@ -0,0 +1,49 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<glyph name="QstnMrk" format="2">
+ <advance width="1050"/>
+ <unicode hex="003F"/>
+ <outline>
+ <contour>
+ <point x="460" y="1540" type="curve" smooth="yes"/>
+ <point x="335" y="1540"/>
+ <point x="206" y="1493"/>
+ <point x="140" y="1430" type="curve"/>
+ <point x="185" y="1251" type="line"/>
+ <point x="261" y="1330"/>
+ <point x="352" y="1365"/>
+ <point x="432" y="1365" type="curve" smooth="yes"/>
+ <point x="579" y="1365"/>
+ <point x="625" y="1289"/>
+ <point x="625" y="1230" type="curve" smooth="yes"/>
+ <point x="625" y="1159"/>
+ <point x="572" y="1092"/>
+ <point x="485" y="980" type="curve" smooth="yes"/>
+ <point x="397" y="867"/>
+ <point x="355" y="730"/>
+ <point x="355" y="440" type="curve"/>
+ <point x="540" y="440" type="line"/>
+ <point x="540" y="721"/>
+ <point x="561" y="806"/>
+ <point x="665" y="927" type="curve" smooth="yes"/>
+ <point x="753" y="1028"/>
+ <point x="830" y="1117"/>
+ <point x="830" y="1240" type="curve" smooth="yes"/>
+ <point x="830" y="1422"/>
+ <point x="697" y="1540"/>
+ </contour>
+ <contour>
+ <point x="315" y="110" type="curve" smooth="yes"/>
+ <point x="315" y="36"/>
+ <point x="376" y="-25"/>
+ <point x="450" y="-25" type="curve" smooth="yes"/>
+ <point x="524" y="-25"/>
+ <point x="585" y="36"/>
+ <point x="585" y="110" type="curve" smooth="yes"/>
+ <point x="585" y="184"/>
+ <point x="524" y="245"/>
+ <point x="450" y="245" type="curve" smooth="yes"/>
+ <point x="376" y="245"/>
+ <point x="315" y="184"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/fontparts/psfbuildcompgc.ufo/glyphs/Q_uotM_rk.glif b/tests/reference/fontparts/psfbuildcompgc.ufo/glyphs/Q_uotM_rk.glif
new file mode 100644
index 0000000..cbffc49
--- /dev/null
+++ b/tests/reference/fontparts/psfbuildcompgc.ufo/glyphs/Q_uotM_rk.glif
@@ -0,0 +1,27 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<glyph name="QuotMrk" format="2">
+ <advance width="1025"/>
+ <unicode hex="0022"/>
+ <outline>
+ <contour>
+ <point x="405" y="1045" type="line"/>
+ <point x="410" y="1186"/>
+ <point x="416" y="1339"/>
+ <point x="445" y="1585" type="curve"/>
+ <point x="240" y="1585" type="line"/>
+ <point x="271" y="1339"/>
+ <point x="276" y="1186"/>
+ <point x="280" y="1045" type="curve"/>
+ </contour>
+ <contour>
+ <point x="745" y="1045" type="line"/>
+ <point x="750" y="1186"/>
+ <point x="756" y="1339"/>
+ <point x="785" y="1585" type="curve"/>
+ <point x="580" y="1585" type="line"/>
+ <point x="611" y="1339"/>
+ <point x="616" y="1186"/>
+ <point x="620" y="1045" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/fontparts/psfbuildcompgc.ufo/glyphs/R_everseS_olidus.glif b/tests/reference/fontparts/psfbuildcompgc.ufo/glyphs/R_everseS_olidus.glif
new file mode 100644
index 0000000..1860a5c
--- /dev/null
+++ b/tests/reference/fontparts/psfbuildcompgc.ufo/glyphs/R_everseS_olidus.glif
@@ -0,0 +1,13 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<glyph name="ReverseSolidus" format="2">
+ <advance width="1000"/>
+ <unicode hex="005C"/>
+ <outline>
+ <contour>
+ <point x="990" y="-245" type="line"/>
+ <point x="160" y="1600" type="line"/>
+ <point x="10" y="1600" type="line"/>
+ <point x="840" y="-245" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/fontparts/psfbuildcompgc.ufo/glyphs/R_tC_urlyB_rac.glif b/tests/reference/fontparts/psfbuildcompgc.ufo/glyphs/R_tC_urlyB_rac.glif
new file mode 100644
index 0000000..28db4ac
--- /dev/null
+++ b/tests/reference/fontparts/psfbuildcompgc.ufo/glyphs/R_tC_urlyB_rac.glif
@@ -0,0 +1,47 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<glyph name="RtCurlyBrac" format="2">
+ <advance width="1000"/>
+ <unicode hex="007D"/>
+ <outline>
+ <contour>
+ <point x="790" y="615" type="curve" smooth="yes"/>
+ <point x="790" y="647"/>
+ <point x="617" y="744"/>
+ <point x="590" y="780" type="curve" smooth="yes"/>
+ <point x="566" y="812"/>
+ <point x="576" y="1435"/>
+ <point x="505" y="1515" type="curve" smooth="yes"/>
+ <point x="465" y="1560"/>
+ <point x="304" y="1613"/>
+ <point x="200" y="1640" type="curve"/>
+ <point x="160" y="1500" type="line"/>
+ <point x="227" y="1477"/>
+ <point x="350" y="1428"/>
+ <point x="370" y="1400" type="curve" smooth="yes"/>
+ <point x="403" y="1353"/>
+ <point x="390" y="783"/>
+ <point x="410" y="745" type="curve" smooth="yes"/>
+ <point x="429" y="709"/>
+ <point x="566" y="637"/>
+ <point x="570" y="615" type="curve"/>
+ <point x="566" y="593"/>
+ <point x="429" y="521"/>
+ <point x="410" y="485" type="curve" smooth="yes"/>
+ <point x="390" y="447"/>
+ <point x="403" y="-123"/>
+ <point x="370" y="-170" type="curve" smooth="yes"/>
+ <point x="350" y="-198"/>
+ <point x="227" y="-247"/>
+ <point x="160" y="-270" type="curve"/>
+ <point x="200" y="-410" type="line"/>
+ <point x="304" y="-383"/>
+ <point x="465" y="-330"/>
+ <point x="505" y="-285" type="curve" smooth="yes"/>
+ <point x="576" y="-205"/>
+ <point x="566" y="418"/>
+ <point x="590" y="450" type="curve" smooth="yes"/>
+ <point x="617" y="486"/>
+ <point x="790" y="583"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/fontparts/psfbuildcompgc.ufo/glyphs/R_tP_aren.glif b/tests/reference/fontparts/psfbuildcompgc.ufo/glyphs/R_tP_aren.glif
new file mode 100644
index 0000000..4275b62
--- /dev/null
+++ b/tests/reference/fontparts/psfbuildcompgc.ufo/glyphs/R_tP_aren.glif
@@ -0,0 +1,23 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<glyph name="RtParen" format="2">
+ <advance width="795"/>
+ <unicode hex="0029"/>
+ <outline>
+ <contour>
+ <point x="680" y="625" type="curve" smooth="yes"/>
+ <point x="680" y="1062"/>
+ <point x="505" y="1444"/>
+ <point x="240" y="1640" type="curve"/>
+ <point x="165" y="1485" type="line"/>
+ <point x="390" y="1280"/>
+ <point x="490" y="962"/>
+ <point x="490" y="625" type="curve" smooth="yes"/>
+ <point x="490" y="278"/>
+ <point x="390" y="-8"/>
+ <point x="165" y="-265" type="curve"/>
+ <point x="260" y="-410" type="line"/>
+ <point x="535" y="-125"/>
+ <point x="680" y="218"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/fontparts/psfbuildcompgc.ufo/glyphs/R_tS_qrB_rac.glif b/tests/reference/fontparts/psfbuildcompgc.ufo/glyphs/R_tS_qrB_rac.glif
new file mode 100644
index 0000000..e7c3618
--- /dev/null
+++ b/tests/reference/fontparts/psfbuildcompgc.ufo/glyphs/R_tS_qrB_rac.glif
@@ -0,0 +1,17 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<glyph name="RtSqrBrac" format="2">
+ <advance width="790"/>
+ <unicode hex="005D"/>
+ <outline>
+ <contour>
+ <point x="590" y="-410" type="line"/>
+ <point x="590" y="1600" type="line"/>
+ <point x="150" y="1600" type="line"/>
+ <point x="150" y="1450" type="line"/>
+ <point x="405" y="1450" type="line"/>
+ <point x="405" y="-260" type="line"/>
+ <point x="150" y="-260" type="line"/>
+ <point x="150" y="-410" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/fontparts/psfbuildcompgc.ufo/glyphs/S_emicolon.glif b/tests/reference/fontparts/psfbuildcompgc.ufo/glyphs/S_emicolon.glif
new file mode 100644
index 0000000..53d0447
--- /dev/null
+++ b/tests/reference/fontparts/psfbuildcompgc.ufo/glyphs/S_emicolon.glif
@@ -0,0 +1,38 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<glyph name="Semicolon" format="2">
+ <advance width="650"/>
+ <unicode hex="003B"/>
+ <outline>
+ <contour>
+ <point x="185" y="790" type="curve" smooth="yes"/>
+ <point x="185" y="716"/>
+ <point x="246" y="655"/>
+ <point x="320" y="655" type="curve" smooth="yes"/>
+ <point x="394" y="655"/>
+ <point x="455" y="716"/>
+ <point x="455" y="790" type="curve" smooth="yes"/>
+ <point x="455" y="864"/>
+ <point x="394" y="925"/>
+ <point x="320" y="925" type="curve" smooth="yes"/>
+ <point x="246" y="925"/>
+ <point x="185" y="864"/>
+ </contour>
+ <contour>
+ <point x="185" y="50" type="line"/>
+ <point x="325" y="50" type="line"/>
+ <point x="325" y="-51"/>
+ <point x="248" y="-172"/>
+ <point x="190" y="-230" type="curve"/>
+ <point x="290" y="-270" type="line"/>
+ <point x="407" y="-160"/>
+ <point x="465" y="-37"/>
+ <point x="465" y="85" type="curve" smooth="yes"/>
+ <point x="465" y="186"/>
+ <point x="400" y="250"/>
+ <point x="320" y="250" type="curve" smooth="yes"/>
+ <point x="263" y="250"/>
+ <point x="198" y="213"/>
+ <point x="185" y="150" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/fontparts/psfbuildcompgc.ufo/glyphs/S_olidus.glif b/tests/reference/fontparts/psfbuildcompgc.ufo/glyphs/S_olidus.glif
new file mode 100644
index 0000000..84af648
--- /dev/null
+++ b/tests/reference/fontparts/psfbuildcompgc.ufo/glyphs/S_olidus.glif
@@ -0,0 +1,13 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<glyph name="Solidus" format="2">
+ <advance width="1000"/>
+ <unicode hex="002F"/>
+ <outline>
+ <contour>
+ <point x="840" y="1600" type="line"/>
+ <point x="10" y="-245" type="line"/>
+ <point x="160" y="-245" type="line"/>
+ <point x="990" y="1600" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/fontparts/psfbuildcompgc.ufo/glyphs/S_pace.glif b/tests/reference/fontparts/psfbuildcompgc.ufo/glyphs/S_pace.glif
new file mode 100644
index 0000000..f9f2cd9
--- /dev/null
+++ b/tests/reference/fontparts/psfbuildcompgc.ufo/glyphs/S_pace.glif
@@ -0,0 +1,7 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<glyph name="Space" format="2">
+ <advance width="550"/>
+ <unicode hex="0020"/>
+ <outline>
+ </outline>
+</glyph>
diff --git a/tests/reference/fontparts/psfbuildcompgc.ufo/glyphs/T_ilde.glif b/tests/reference/fontparts/psfbuildcompgc.ufo/glyphs/T_ilde.glif
new file mode 100644
index 0000000..afad348
--- /dev/null
+++ b/tests/reference/fontparts/psfbuildcompgc.ufo/glyphs/T_ilde.glif
@@ -0,0 +1,29 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<glyph name="Tilde" format="2">
+ <advance width="1115"/>
+ <unicode hex="007E"/>
+ <outline>
+ <contour>
+ <point x="125" y="375" type="line"/>
+ <point x="130" y="424"/>
+ <point x="162" y="465"/>
+ <point x="240" y="465" type="curve" smooth="yes"/>
+ <point x="415" y="465"/>
+ <point x="615" y="360"/>
+ <point x="845" y="360" type="curve" smooth="yes"/>
+ <point x="1004" y="360"/>
+ <point x="1080" y="482"/>
+ <point x="1080" y="610" type="curve"/>
+ <point x="975" y="610" type="line"/>
+ <point x="968" y="564"/>
+ <point x="938" y="510"/>
+ <point x="855" y="510" type="curve" smooth="yes"/>
+ <point x="619" y="510"/>
+ <point x="461" y="615"/>
+ <point x="240" y="615" type="curve" smooth="yes"/>
+ <point x="94" y="615"/>
+ <point x="20" y="497"/>
+ <point x="20" y="375" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/fontparts/psfbuildcompgc.ufo/glyphs/V_ertL_ine.glif b/tests/reference/fontparts/psfbuildcompgc.ufo/glyphs/V_ertL_ine.glif
new file mode 100644
index 0000000..3e1a16f
--- /dev/null
+++ b/tests/reference/fontparts/psfbuildcompgc.ufo/glyphs/V_ertL_ine.glif
@@ -0,0 +1,13 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<glyph name="VertLine" format="2">
+ <advance width="690"/>
+ <unicode hex="007C"/>
+ <outline>
+ <contour>
+ <point x="270" y="1600" type="line"/>
+ <point x="270" y="-390" type="line"/>
+ <point x="420" y="-390" type="line"/>
+ <point x="420" y="1600" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/fontparts/psfbuildcompgc.ufo/glyphs/_notdef.glif b/tests/reference/fontparts/psfbuildcompgc.ufo/glyphs/_notdef.glif
new file mode 100644
index 0000000..f4d5348
--- /dev/null
+++ b/tests/reference/fontparts/psfbuildcompgc.ufo/glyphs/_notdef.glif
@@ -0,0 +1,18 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<glyph name=".notdef" format="2">
+ <advance width="1400"/>
+ <outline>
+ <contour>
+ <point x="100" y="0" type="line"/>
+ <point x="1300" y="0" type="line"/>
+ <point x="1300" y="1800" type="line"/>
+ <point x="100" y="1800" type="line"/>
+ </contour>
+ <contour>
+ <point x="150" y="1750" type="line"/>
+ <point x="1250" y="1750" type="line"/>
+ <point x="1250" y="50" type="line"/>
+ <point x="150" y="50" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/fontparts/psfbuildcompgc.ufo/glyphs/_null.glif b/tests/reference/fontparts/psfbuildcompgc.ufo/glyphs/_null.glif
new file mode 100644
index 0000000..f6c8b49
--- /dev/null
+++ b/tests/reference/fontparts/psfbuildcompgc.ufo/glyphs/_null.glif
@@ -0,0 +1,5 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<glyph name=".null" format="2">
+ <outline>
+ </outline>
+</glyph>
diff --git a/tests/reference/fontparts/psfbuildcompgc.ufo/glyphs/contents.plist b/tests/reference/fontparts/psfbuildcompgc.ufo/glyphs/contents.plist
new file mode 100644
index 0000000..30ac1df
--- /dev/null
+++ b/tests/reference/fontparts/psfbuildcompgc.ufo/glyphs/contents.plist
@@ -0,0 +1,256 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+ <dict>
+ <key>.notdef</key>
+ <string>_notdef.glif</string>
+ <key>.null</key>
+ <string>_null.glif</string>
+ <key>Ampersand</key>
+ <string>A_mpersand.glif</string>
+ <key>Apos</key>
+ <string>A_pos.glif</string>
+ <key>Asterisk</key>
+ <string>A_sterisk.glif</string>
+ <key>AtSgn</key>
+ <string>A_tS_gn.glif</string>
+ <key>CircumAccent</key>
+ <string>C_ircumA_ccent.glif</string>
+ <key>Colon</key>
+ <string>C_olon.glif</string>
+ <key>CombAcute</key>
+ <string>C_ombA_cute.glif</string>
+ <key>CombCircum</key>
+ <string>C_ombC_ircum.glif</string>
+ <key>CombDiaer</key>
+ <string>C_ombD_iaer.glif</string>
+ <key>CombGrave</key>
+ <string>C_ombG_rave.glif</string>
+ <key>CombRingAbv</key>
+ <string>C_ombR_ingA_bv.glif</string>
+ <key>CombTilde</key>
+ <string>C_ombT_ilde.glif</string>
+ <key>Comma</key>
+ <string>C_omma.glif</string>
+ <key>DigitEight</key>
+ <string>D_igitE_ight.glif</string>
+ <key>DigitFive</key>
+ <string>D_igitF_ive.glif</string>
+ <key>DigitFour</key>
+ <string>D_igitF_our.glif</string>
+ <key>DigitNine</key>
+ <string>D_igitN_ine.glif</string>
+ <key>DigitOne</key>
+ <string>D_igitO_ne.glif</string>
+ <key>DigitSeven</key>
+ <string>D_igitS_even.glif</string>
+ <key>DigitSix</key>
+ <string>D_igitS_ix.glif</string>
+ <key>DigitThree</key>
+ <string>D_igitT_hree.glif</string>
+ <key>DigitTwo</key>
+ <string>D_igitT_wo.glif</string>
+ <key>DigitZero</key>
+ <string>D_igitZ_ero.glif</string>
+ <key>DollarSgn</key>
+ <string>D_ollarS_gn.glif</string>
+ <key>DottedCirc</key>
+ <string>D_ottedC_irc.glif</string>
+ <key>EqSgn</key>
+ <string>E_qS_gn.glif</string>
+ <key>ExclamationMrk</key>
+ <string>E_xclamationM_rk.glif</string>
+ <key>FullStop</key>
+ <string>F_ullS_top.glif</string>
+ <key>GTSgn</key>
+ <string>G_T_S_gn.glif</string>
+ <key>GraveAccent</key>
+ <string>G_raveA_ccent.glif</string>
+ <key>Hyphen</key>
+ <string>H_yphen.glif</string>
+ <key>HyphenMinus</key>
+ <string>H_yphenM_inus.glif</string>
+ <key>Hyphen_Soft</key>
+ <string>H_yphen_S_oft.glif</string>
+ <key>LTSgn</key>
+ <string>L_T_S_gn.glif</string>
+ <key>LftCurlyBrac</key>
+ <string>L_ftC_urlyB_rac.glif</string>
+ <key>LftParen</key>
+ <string>L_ftP_aren.glif</string>
+ <key>LftSqrBrac</key>
+ <string>L_ftS_qrB_rac.glif</string>
+ <key>LowLine</key>
+ <string>L_owL_ine.glif</string>
+ <key>LtnCapA</key>
+ <string>L_tnC_apA_.glif</string>
+ <key>LtnCapA.alt</key>
+ <string>L_tnC_apA_.alt.glif</string>
+ <key>LtnCapADiaer</key>
+ <string>L_tnC_apA_D_iaer.glif</string>
+ <key>LtnCapB</key>
+ <string>L_tnC_apB_.glif</string>
+ <key>LtnCapC</key>
+ <string>L_tnC_apC_.glif</string>
+ <key>LtnCapCAcute</key>
+ <string>L_tnC_apC_A_cute.glif</string>
+ <key>LtnCapCAcuteCedilla</key>
+ <string>L_tnC_apC_A_cuteC_edilla.glif</string>
+ <key>LtnCapCCircum</key>
+ <string>L_tnC_apC_C_ircum.glif</string>
+ <key>LtnCapD</key>
+ <string>L_tnC_apD_.glif</string>
+ <key>LtnCapE</key>
+ <string>L_tnC_apE_.glif</string>
+ <key>LtnCapF</key>
+ <string>L_tnC_apF_.glif</string>
+ <key>LtnCapG</key>
+ <string>L_tnC_apG_.glif</string>
+ <key>LtnCapH</key>
+ <string>L_tnC_apH_.glif</string>
+ <key>LtnCapI</key>
+ <string>L_tnC_apI_.glif</string>
+ <key>LtnCapIJ</key>
+ <string>L_tnC_apI_J_.glif</string>
+ <key>LtnCapJ</key>
+ <string>L_tnC_apJ_.glif</string>
+ <key>LtnCapK</key>
+ <string>L_tnC_apK_.glif</string>
+ <key>LtnCapL</key>
+ <string>L_tnC_apL_.glif</string>
+ <key>LtnCapM</key>
+ <string>L_tnC_apM_.glif</string>
+ <key>LtnCapN</key>
+ <string>L_tnC_apN_.glif</string>
+ <key>LtnCapO</key>
+ <string>L_tnC_apO_.glif</string>
+ <key>LtnCapP</key>
+ <string>L_tnC_apP_.glif</string>
+ <key>LtnCapQ</key>
+ <string>L_tnC_apQ_.glif</string>
+ <key>LtnCapR</key>
+ <string>L_tnC_apR_.glif</string>
+ <key>LtnCapS</key>
+ <string>L_tnC_apS_.glif</string>
+ <key>LtnCapT</key>
+ <string>L_tnC_apT_.glif</string>
+ <key>LtnCapU</key>
+ <string>L_tnC_apU_.glif</string>
+ <key>LtnCapV</key>
+ <string>L_tnC_apV_.glif</string>
+ <key>LtnCapW</key>
+ <string>L_tnC_apW_.glif</string>
+ <key>LtnCapX</key>
+ <string>L_tnC_apX_.glif</string>
+ <key>LtnCapY</key>
+ <string>L_tnC_apY_.glif</string>
+ <key>LtnSmA</key>
+ <string>L_tnS_mA_.glif</string>
+ <key>LtnSmAAcute</key>
+ <string>L_tnS_mA_A_cute.glif</string>
+ <key>LtnSmACircum</key>
+ <string>L_tnS_mA_C_ircum.glif</string>
+ <key>LtnSmADiaer</key>
+ <string>L_tnS_mA_D_iaer.glif</string>
+ <key>LtnSmAGrave</key>
+ <string>L_tnS_mA_G_rave.glif</string>
+ <key>LtnSmARingAbv</key>
+ <string>L_tnS_mA_R_ingA_bv.glif</string>
+ <key>LtnSmATilde</key>
+ <string>L_tnS_mA_T_ilde.glif</string>
+ <key>LtnSmB</key>
+ <string>L_tnS_mB_.glif</string>
+ <key>LtnSmC</key>
+ <string>L_tnS_mC_.glif</string>
+ <key>LtnSmCAcute</key>
+ <string>L_tnS_mC_A_cute.glif</string>
+ <key>LtnSmCAcuteCedilla</key>
+ <string>L_tnS_mC_A_cuteC_edilla.glif</string>
+ <key>LtnSmCCircum</key>
+ <string>L_tnS_mC_C_ircum.glif</string>
+ <key>LtnSmD</key>
+ <string>L_tnS_mD_.glif</string>
+ <key>LtnSmE</key>
+ <string>L_tnS_mE_.glif</string>
+ <key>LtnSmF</key>
+ <string>L_tnS_mF_.glif</string>
+ <key>LtnSmG</key>
+ <string>L_tnS_mG_.glif</string>
+ <key>LtnSmH</key>
+ <string>L_tnS_mH_.glif</string>
+ <key>LtnSmI</key>
+ <string>L_tnS_mI_.glif</string>
+ <key>LtnSmIJ</key>
+ <string>L_tnS_mI_J_.glif</string>
+ <key>LtnSmITilde</key>
+ <string>L_tnS_mI_T_ilde.glif</string>
+ <key>LtnSmITildeGrave</key>
+ <string>L_tnS_mI_T_ildeG_rave.glif</string>
+ <key>LtnSmITildeGraveCedilla</key>
+ <string>L_tnS_mI_T_ildeG_raveC_edilla.glif</string>
+ <key>LtnSmJ</key>
+ <string>L_tnS_mJ_.glif</string>
+ <key>LtnSmK</key>
+ <string>L_tnS_mK_.glif</string>
+ <key>LtnSmL</key>
+ <string>L_tnS_mL_.glif</string>
+ <key>LtnSmM</key>
+ <string>L_tnS_mM_.glif</string>
+ <key>LtnSmN</key>
+ <string>L_tnS_mN_.glif</string>
+ <key>LtnSmO</key>
+ <string>L_tnS_mO_.glif</string>
+ <key>LtnSmP</key>
+ <string>L_tnS_mP_.glif</string>
+ <key>LtnSmQ</key>
+ <string>L_tnS_mQ_.glif</string>
+ <key>LtnSmR</key>
+ <string>L_tnS_mR_.glif</string>
+ <key>LtnSmS</key>
+ <string>L_tnS_mS_.glif</string>
+ <key>LtnSmT</key>
+ <string>L_tnS_mT_.glif</string>
+ <key>LtnSmU</key>
+ <string>L_tnS_mU_.glif</string>
+ <key>LtnSmV</key>
+ <string>L_tnS_mV_.glif</string>
+ <key>LtnSmW</key>
+ <string>L_tnS_mW_.glif</string>
+ <key>LtnSmX</key>
+ <string>L_tnS_mX_.glif</string>
+ <key>LtnSmY</key>
+ <string>L_tnS_mY_.glif</string>
+ <key>NonBreakingHyphen</key>
+ <string>N_onB_reakingH_yphen.glif</string>
+ <key>NumSgn</key>
+ <string>N_umS_gn.glif</string>
+ <key>PercentSgn</key>
+ <string>P_ercentS_gn.glif</string>
+ <key>PlusSgn</key>
+ <string>P_lusS_gn.glif</string>
+ <key>QstnMrk</key>
+ <string>Q_stnM_rk.glif</string>
+ <key>QuotMrk</key>
+ <string>Q_uotM_rk.glif</string>
+ <key>ReverseSolidus</key>
+ <string>R_everseS_olidus.glif</string>
+ <key>RtCurlyBrac</key>
+ <string>R_tC_urlyB_rac.glif</string>
+ <key>RtParen</key>
+ <string>R_tP_aren.glif</string>
+ <key>RtSqrBrac</key>
+ <string>R_tS_qrB_rac.glif</string>
+ <key>Semicolon</key>
+ <string>S_emicolon.glif</string>
+ <key>Solidus</key>
+ <string>S_olidus.glif</string>
+ <key>Space</key>
+ <string>S_pace.glif</string>
+ <key>Tilde</key>
+ <string>T_ilde.glif</string>
+ <key>VertLine</key>
+ <string>V_ertL_ine.glif</string>
+ <key>nonmarkingreturn</key>
+ <string>nonmarkingreturn.glif</string>
+ </dict>
+</plist>
diff --git a/tests/reference/fontparts/psfbuildcompgc.ufo/glyphs/nonmarkingreturn.glif b/tests/reference/fontparts/psfbuildcompgc.ufo/glyphs/nonmarkingreturn.glif
new file mode 100644
index 0000000..4dbf648
--- /dev/null
+++ b/tests/reference/fontparts/psfbuildcompgc.ufo/glyphs/nonmarkingreturn.glif
@@ -0,0 +1,6 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<glyph name="nonmarkingreturn" format="2">
+ <advance width="1024"/>
+ <outline>
+ </outline>
+</glyph>
diff --git a/tests/reference/fontparts/psfbuildcompgc.ufo/layercontents.plist b/tests/reference/fontparts/psfbuildcompgc.ufo/layercontents.plist
new file mode 100644
index 0000000..b9c1a4f
--- /dev/null
+++ b/tests/reference/fontparts/psfbuildcompgc.ufo/layercontents.plist
@@ -0,0 +1,10 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+ <array>
+ <array>
+ <string>public.default</string>
+ <string>glyphs</string>
+ </array>
+ </array>
+</plist>
diff --git a/tests/reference/fontparts/psfbuildcompgc.ufo/lib.plist b/tests/reference/fontparts/psfbuildcompgc.ufo/lib.plist
new file mode 100644
index 0000000..b3dadfa
--- /dev/null
+++ b/tests/reference/fontparts/psfbuildcompgc.ufo/lib.plist
@@ -0,0 +1,547 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+ <dict>
+ <key>com.schriftgestaltung.Glyphs.fontUserData</key>
+ <dict/>
+ <key>com.schriftgestaltung.appVersion</key>
+ <string>1161</string>
+ <key>com.schriftgestaltung.customParameter.GSFont.DisplayStrings</key>
+ <string></string>
+ <key>com.schriftgestaltung.customParameter.GSFont.disablesAutomaticAlignment</key>
+ <true/>
+ <key>com.schriftgestaltung.customParameter.GSFont.disablesLastChange</key>
+ <true/>
+ <key>com.schriftgestaltung.customParameter.GSFont.useNiceNames</key>
+ <integer>0</integer>
+ <key>com.schriftgestaltung.customParameter.GSFontMaster.customValue</key>
+ <integer>0</integer>
+ <key>com.schriftgestaltung.customParameter.GSFontMaster.customValue1</key>
+ <integer>0</integer>
+ <key>com.schriftgestaltung.customParameter.GSFontMaster.customValue2</key>
+ <integer>0</integer>
+ <key>com.schriftgestaltung.customParameter.GSFontMaster.customValue3</key>
+ <integer>0</integer>
+ <key>com.schriftgestaltung.customParameter.GSFontMaster.iconName</key>
+ <string></string>
+ <key>com.schriftgestaltung.customParameter.GSFontMaster.weightValue</key>
+ <integer>400</integer>
+ <key>com.schriftgestaltung.customParameter.GSFontMaster.widthValue</key>
+ <integer>100</integer>
+ <key>com.schriftgestaltung.disablesAutomaticAlignment</key>
+ <true/>
+ <key>com.schriftgestaltung.disablesLastChange</key>
+ <true/>
+ <key>com.schriftgestaltung.fontMasterOrder</key>
+ <integer>0</integer>
+ <key>com.schriftgestaltung.glyphOrder</key>
+ <array>
+ <string>.notdef</string>
+ <string>.null</string>
+ <string>nonmarkingreturn</string>
+ <string>Space</string>
+ <string>ExclamationMrk</string>
+ <string>QuotMrk</string>
+ <string>NumSgn</string>
+ <string>DollarSgn</string>
+ <string>PercentSgn</string>
+ <string>Ampersand</string>
+ <string>Apos</string>
+ <string>LftParen</string>
+ <string>RtParen</string>
+ <string>Asterisk</string>
+ <string>PlusSgn</string>
+ <string>Comma</string>
+ <string>HyphenMinus</string>
+ <string>FullStop</string>
+ <string>Solidus</string>
+ <string>DigitZero</string>
+ <string>DigitOne</string>
+ <string>DigitTwo</string>
+ <string>DigitThree</string>
+ <string>DigitFour</string>
+ <string>DigitFive</string>
+ <string>DigitSix</string>
+ <string>DigitSeven</string>
+ <string>DigitEight</string>
+ <string>DigitNine</string>
+ <string>Colon</string>
+ <string>Semicolon</string>
+ <string>LTSgn</string>
+ <string>EqSgn</string>
+ <string>GTSgn</string>
+ <string>QstnMrk</string>
+ <string>AtSgn</string>
+ <string>LtnCapA</string>
+ <string>LtnCapA.alt</string>
+ <string>LtnCapB</string>
+ <string>LtnCapC</string>
+ <string>LtnCapD</string>
+ <string>LtnCapE</string>
+ <string>LtnCapF</string>
+ <string>LtnCapG</string>
+ <string>LtnCapH</string>
+ <string>LtnCapI</string>
+ <string>LtnCapJ</string>
+ <string>LtnCapK</string>
+ <string>LtnCapL</string>
+ <string>LtnCapM</string>
+ <string>LtnCapN</string>
+ <string>LtnCapO</string>
+ <string>LtnCapP</string>
+ <string>LtnCapQ</string>
+ <string>LtnCapR</string>
+ <string>LtnCapS</string>
+ <string>LtnCapT</string>
+ <string>LtnCapU</string>
+ <string>LtnCapV</string>
+ <string>LtnCapW</string>
+ <string>LtnCapX</string>
+ <string>LtnCapY</string>
+ <string>LftSqrBrac</string>
+ <string>ReverseSolidus</string>
+ <string>RtSqrBrac</string>
+ <string>CircumAccent</string>
+ <string>LowLine</string>
+ <string>GraveAccent</string>
+ <string>LtnSmA</string>
+ <string>LtnSmB</string>
+ <string>LtnSmC</string>
+ <string>LtnSmD</string>
+ <string>LtnSmE</string>
+ <string>LtnSmF</string>
+ <string>LtnSmG</string>
+ <string>LtnSmH</string>
+ <string>LtnSmI</string>
+ <string>LtnSmJ</string>
+ <string>LtnSmK</string>
+ <string>LtnSmL</string>
+ <string>LtnSmM</string>
+ <string>LtnSmN</string>
+ <string>LtnSmO</string>
+ <string>LtnSmP</string>
+ <string>LtnSmQ</string>
+ <string>LtnSmR</string>
+ <string>LtnSmS</string>
+ <string>LtnSmT</string>
+ <string>LtnSmU</string>
+ <string>LtnSmV</string>
+ <string>LtnSmW</string>
+ <string>LtnSmX</string>
+ <string>LtnSmY</string>
+ <string>LftCurlyBrac</string>
+ <string>VertLine</string>
+ <string>RtCurlyBrac</string>
+ <string>Tilde</string>
+ <string>LtnCapADiaer</string>
+ <string>LtnSmAAcute</string>
+ <string>LtnSmAGrave</string>
+ <string>LtnSmACircum</string>
+ <string>LtnSmADiaer</string>
+ <string>LtnSmATilde</string>
+ <string>LtnSmARingAbv</string>
+ <string>DottedCirc</string>
+ <string>Hyphen</string>
+ <string>NonBreakingHyphen</string>
+ <string>Hyphen_Soft</string>
+ <string>CombAcute</string>
+ <string>CombGrave</string>
+ <string>CombCircum</string>
+ <string>CombTilde</string>
+ <string>CombDiaer</string>
+ <string>CombRingAbv</string>
+ </array>
+ <key>com.schriftgestaltung.keyboardIncrement</key>
+ <integer>1</integer>
+ <key>com.schriftgestaltung.weight</key>
+ <string>Regular</string>
+ <key>com.schriftgestaltung.weightValue</key>
+ <integer>400</integer>
+ <key>com.schriftgestaltung.width</key>
+ <string>Regular</string>
+ <key>com.schriftgestaltung.widthValue</key>
+ <integer>100</integer>
+ <key>org.sil.lcg.toneLetters</key>
+ <dict>
+ <key>contourWidth</key>
+ <integer>480</integer>
+ <key>dotSize</key>
+ <integer>180</integer>
+ <key>dotSpacing</key>
+ <integer>200</integer>
+ <key>glyphDepth</key>
+ <integer>-25</integer>
+ <key>glyphHeight</key>
+ <integer>1600</integer>
+ <key>italicAngle</key>
+ <integer>0</integer>
+ <key>marginDotLeft</key>
+ <integer>120</integer>
+ <key>marginDotRight</key>
+ <integer>160</integer>
+ <key>marginFlatLeft</key>
+ <integer>120</integer>
+ <key>marginFlatRight</key>
+ <integer>160</integer>
+ <key>marginPointLeft</key>
+ <integer>100</integer>
+ <key>marginPointRight</key>
+ <integer>140</integer>
+ <key>strokeThickness</key>
+ <integer>120</integer>
+ </dict>
+ <key>public.glyphOrder</key>
+ <array>
+ <string>.notdef</string>
+ <string>.null</string>
+ <string>nonmarkingreturn</string>
+ <string>Space</string>
+ <string>ExclamationMrk</string>
+ <string>QuotMrk</string>
+ <string>NumSgn</string>
+ <string>DollarSgn</string>
+ <string>PercentSgn</string>
+ <string>Ampersand</string>
+ <string>Apos</string>
+ <string>LftParen</string>
+ <string>RtParen</string>
+ <string>Asterisk</string>
+ <string>PlusSgn</string>
+ <string>Comma</string>
+ <string>HyphenMinus</string>
+ <string>FullStop</string>
+ <string>Solidus</string>
+ <string>DigitZero</string>
+ <string>DigitOne</string>
+ <string>DigitTwo</string>
+ <string>DigitThree</string>
+ <string>DigitFour</string>
+ <string>DigitFive</string>
+ <string>DigitSix</string>
+ <string>DigitSeven</string>
+ <string>DigitEight</string>
+ <string>DigitNine</string>
+ <string>Colon</string>
+ <string>Semicolon</string>
+ <string>LTSgn</string>
+ <string>EqSgn</string>
+ <string>GTSgn</string>
+ <string>QstnMrk</string>
+ <string>AtSgn</string>
+ <string>LtnCapA</string>
+ <string>LtnCapA.alt</string>
+ <string>LtnCapB</string>
+ <string>LtnCapC</string>
+ <string>LtnCapD</string>
+ <string>LtnCapE</string>
+ <string>LtnCapF</string>
+ <string>LtnCapG</string>
+ <string>LtnCapH</string>
+ <string>LtnCapI</string>
+ <string>LtnCapJ</string>
+ <string>LtnCapK</string>
+ <string>LtnCapL</string>
+ <string>LtnCapM</string>
+ <string>LtnCapN</string>
+ <string>LtnCapO</string>
+ <string>LtnCapP</string>
+ <string>LtnCapQ</string>
+ <string>LtnCapR</string>
+ <string>LtnCapS</string>
+ <string>LtnCapT</string>
+ <string>LtnCapU</string>
+ <string>LtnCapV</string>
+ <string>LtnCapW</string>
+ <string>LtnCapX</string>
+ <string>LtnCapY</string>
+ <string>LftSqrBrac</string>
+ <string>ReverseSolidus</string>
+ <string>RtSqrBrac</string>
+ <string>CircumAccent</string>
+ <string>LowLine</string>
+ <string>GraveAccent</string>
+ <string>LtnSmA</string>
+ <string>LtnSmB</string>
+ <string>LtnSmC</string>
+ <string>LtnSmD</string>
+ <string>LtnSmE</string>
+ <string>LtnSmF</string>
+ <string>LtnSmG</string>
+ <string>LtnSmH</string>
+ <string>LtnSmI</string>
+ <string>LtnSmJ</string>
+ <string>LtnSmK</string>
+ <string>LtnSmL</string>
+ <string>LtnSmM</string>
+ <string>LtnSmN</string>
+ <string>LtnSmO</string>
+ <string>LtnSmP</string>
+ <string>LtnSmQ</string>
+ <string>LtnSmR</string>
+ <string>LtnSmS</string>
+ <string>LtnSmT</string>
+ <string>LtnSmU</string>
+ <string>LtnSmV</string>
+ <string>LtnSmW</string>
+ <string>LtnSmX</string>
+ <string>LtnSmY</string>
+ <string>LftCurlyBrac</string>
+ <string>VertLine</string>
+ <string>RtCurlyBrac</string>
+ <string>Tilde</string>
+ <string>LtnCapADiaer</string>
+ <string>LtnSmAAcute</string>
+ <string>LtnSmAGrave</string>
+ <string>LtnSmACircum</string>
+ <string>LtnSmADiaer</string>
+ <string>LtnSmATilde</string>
+ <string>LtnSmARingAbv</string>
+ <string>DottedCirc</string>
+ <string>Hyphen</string>
+ <string>NonBreakingHyphen</string>
+ <string>Hyphen_Soft</string>
+ <string>CombAcute</string>
+ <string>CombGrave</string>
+ <string>CombCircum</string>
+ <string>CombTilde</string>
+ <string>CombDiaer</string>
+ <string>CombRingAbv</string>
+ <string>LtnCapIJ</string>
+ <string>LtnSmIJ</string>
+ <string>LtnCapCAcute</string>
+ <string>LtnSmCAcute</string>
+ <string>LtnCapCCircum</string>
+ <string>LtnSmCCircum</string>
+ <string>LtnSmITildeGrave</string>
+ <string>LtnCapCAcuteCedilla</string>
+ <string>LtnSmCAcuteCedilla</string>
+ <string>LtnSmITilde</string>
+ <string>LtnSmITildeGraveCedilla</string>
+ </array>
+ <key>public.postscriptNames</key>
+ <dict>
+ <key>Ampersand</key>
+ <string>ampersand</string>
+ <key>Apos</key>
+ <string>quotesingle</string>
+ <key>Asterisk</key>
+ <string>asterisk</string>
+ <key>AtSgn</key>
+ <string>at</string>
+ <key>CircumAccent</key>
+ <string>asciicircum</string>
+ <key>Colon</key>
+ <string>colon</string>
+ <key>CombAcute</key>
+ <string>acutecomb</string>
+ <key>CombCircum</key>
+ <string>uni0302</string>
+ <key>CombDiaer</key>
+ <string>uni0308</string>
+ <key>CombGrave</key>
+ <string>gravecomb</string>
+ <key>CombRingAbv</key>
+ <string>uni030A</string>
+ <key>CombTilde</key>
+ <string>tildecomb</string>
+ <key>Comma</key>
+ <string>comma</string>
+ <key>DigitEight</key>
+ <string>eight</string>
+ <key>DigitFive</key>
+ <string>five</string>
+ <key>DigitFour</key>
+ <string>four</string>
+ <key>DigitNine</key>
+ <string>nine</string>
+ <key>DigitOne</key>
+ <string>one</string>
+ <key>DigitSeven</key>
+ <string>seven</string>
+ <key>DigitSix</key>
+ <string>six</string>
+ <key>DigitThree</key>
+ <string>three</string>
+ <key>DigitTwo</key>
+ <string>two</string>
+ <key>DigitZero</key>
+ <string>zero</string>
+ <key>DollarSgn</key>
+ <string>dollar</string>
+ <key>DottedCirc</key>
+ <string>uni25CC</string>
+ <key>EqSgn</key>
+ <string>equal</string>
+ <key>ExclamationMrk</key>
+ <string>exclam</string>
+ <key>FullStop</key>
+ <string>period</string>
+ <key>GTSgn</key>
+ <string>greater</string>
+ <key>GraveAccent</key>
+ <string>grave</string>
+ <key>Hyphen</key>
+ <string>uni2010</string>
+ <key>HyphenMinus</key>
+ <string>hyphen</string>
+ <key>Hyphen_Soft</key>
+ <string>uni00AD</string>
+ <key>LTSgn</key>
+ <string>less</string>
+ <key>LftCurlyBrac</key>
+ <string>braceleft</string>
+ <key>LftParen</key>
+ <string>parenleft</string>
+ <key>LftSqrBrac</key>
+ <string>bracketleft</string>
+ <key>LowLine</key>
+ <string>underscore</string>
+ <key>LtnCapA</key>
+ <string>A</string>
+ <key>LtnCapA.alt</key>
+ <string>A</string>
+ <key>LtnCapADiaer</key>
+ <string>Adieresis</string>
+ <key>LtnCapB</key>
+ <string>B</string>
+ <key>LtnCapC</key>
+ <string>C</string>
+ <key>LtnCapD</key>
+ <string>D</string>
+ <key>LtnCapE</key>
+ <string>E</string>
+ <key>LtnCapF</key>
+ <string>F</string>
+ <key>LtnCapG</key>
+ <string>G</string>
+ <key>LtnCapH</key>
+ <string>H</string>
+ <key>LtnCapI</key>
+ <string>I</string>
+ <key>LtnCapJ</key>
+ <string>J</string>
+ <key>LtnCapK</key>
+ <string>K</string>
+ <key>LtnCapL</key>
+ <string>L</string>
+ <key>LtnCapM</key>
+ <string>M</string>
+ <key>LtnCapN</key>
+ <string>N</string>
+ <key>LtnCapO</key>
+ <string>O</string>
+ <key>LtnCapP</key>
+ <string>P</string>
+ <key>LtnCapQ</key>
+ <string>Q</string>
+ <key>LtnCapR</key>
+ <string>R</string>
+ <key>LtnCapS</key>
+ <string>S</string>
+ <key>LtnCapT</key>
+ <string>T</string>
+ <key>LtnCapU</key>
+ <string>U</string>
+ <key>LtnCapV</key>
+ <string>V</string>
+ <key>LtnCapW</key>
+ <string>W</string>
+ <key>LtnCapX</key>
+ <string>X</string>
+ <key>LtnCapY</key>
+ <string>Y</string>
+ <key>LtnSmA</key>
+ <string>a</string>
+ <key>LtnSmAAcute</key>
+ <string>aacute</string>
+ <key>LtnSmACircum</key>
+ <string>acircumflex</string>
+ <key>LtnSmADiaer</key>
+ <string>adieresis</string>
+ <key>LtnSmAGrave</key>
+ <string>agrave</string>
+ <key>LtnSmARingAbv</key>
+ <string>aring</string>
+ <key>LtnSmATilde</key>
+ <string>atilde</string>
+ <key>LtnSmB</key>
+ <string>b</string>
+ <key>LtnSmC</key>
+ <string>c</string>
+ <key>LtnSmD</key>
+ <string>d</string>
+ <key>LtnSmE</key>
+ <string>e</string>
+ <key>LtnSmF</key>
+ <string>f</string>
+ <key>LtnSmG</key>
+ <string>g</string>
+ <key>LtnSmH</key>
+ <string>h</string>
+ <key>LtnSmI</key>
+ <string>i</string>
+ <key>LtnSmJ</key>
+ <string>j</string>
+ <key>LtnSmK</key>
+ <string>k</string>
+ <key>LtnSmL</key>
+ <string>l</string>
+ <key>LtnSmM</key>
+ <string>m</string>
+ <key>LtnSmN</key>
+ <string>n</string>
+ <key>LtnSmO</key>
+ <string>o</string>
+ <key>LtnSmP</key>
+ <string>p</string>
+ <key>LtnSmQ</key>
+ <string>q</string>
+ <key>LtnSmR</key>
+ <string>r</string>
+ <key>LtnSmS</key>
+ <string>s</string>
+ <key>LtnSmT</key>
+ <string>t</string>
+ <key>LtnSmU</key>
+ <string>u</string>
+ <key>LtnSmV</key>
+ <string>v</string>
+ <key>LtnSmW</key>
+ <string>w</string>
+ <key>LtnSmX</key>
+ <string>x</string>
+ <key>LtnSmY</key>
+ <string>y</string>
+ <key>NonBreakingHyphen</key>
+ <string>uni2011</string>
+ <key>NumSgn</key>
+ <string>numbersign</string>
+ <key>PercentSgn</key>
+ <string>percent</string>
+ <key>PlusSgn</key>
+ <string>plus</string>
+ <key>QstnMrk</key>
+ <string>question</string>
+ <key>QuotMrk</key>
+ <string>quotedbl</string>
+ <key>ReverseSolidus</key>
+ <string>backslash</string>
+ <key>RtCurlyBrac</key>
+ <string>braceright</string>
+ <key>RtParen</key>
+ <string>parenright</string>
+ <key>RtSqrBrac</key>
+ <string>bracketright</string>
+ <key>Semicolon</key>
+ <string>semicolon</string>
+ <key>Solidus</key>
+ <string>slash</string>
+ <key>Space</key>
+ <string>space</string>
+ <key>Tilde</key>
+ <string>asciitilde</string>
+ <key>VertLine</key>
+ <string>bar</string>
+ </dict>
+ </dict>
+</plist>
diff --git a/tests/reference/fontparts/psfbuildcompgc.ufo/metainfo.plist b/tests/reference/fontparts/psfbuildcompgc.ufo/metainfo.plist
new file mode 100644
index 0000000..7b8b34a
--- /dev/null
+++ b/tests/reference/fontparts/psfbuildcompgc.ufo/metainfo.plist
@@ -0,0 +1,10 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+ <dict>
+ <key>creator</key>
+ <string>com.github.fonttools.ufoLib</string>
+ <key>formatVersion</key>
+ <integer>3</integer>
+ </dict>
+</plist>
diff --git a/tests/reference/psfmakefea/issue65.fea b/tests/reference/psfmakefea/issue65.fea
new file mode 100644
index 0000000..0d8dd9a
--- /dev/null
+++ b/tests/reference/psfmakefea/issue65.fea
@@ -0,0 +1,7 @@
+
+# Main Classes
+
+# Positioning classes and statements
+lookup ReorderInsert {
+ sub uni1C00' uni1C34 by uni1C34 uni1C00;
+} ReorderInsert;
diff --git a/tests/reference/psfmakefea/issue65.log b/tests/reference/psfmakefea/issue65.log
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/tests/reference/psfmakefea/issue65.log
diff --git a/tests/reference/psfmakefea/ligatures.fea b/tests/reference/psfmakefea/ligatures.fea
new file mode 100644
index 0000000..2157709
--- /dev/null
+++ b/tests/reference/psfmakefea/ligatures.fea
@@ -0,0 +1,15 @@
+
+# Main Classes
+
+# Positioning classes and statements
+# baseClass a <anchor 200 200> @TOP_1;
+# baseClass fi <anchor 200 0> @BOTTOM_1;
+# baseClass fi <anchor 400 0> @BOTTOM_2;
+markClass acute <anchor 0 200> @TOP;
+markClass circumflex <anchor 200 0> @BOTTOM;
+feature test {
+ pos ligature a <anchor 200 200> mark @TOP
+ ligComponent <anchor NULL>;
+ pos ligature fi <anchor 200 0> mark @BOTTOM
+ ligComponent <anchor 400 0> mark @BOTTOM;
+} test;
diff --git a/tests/reference/psfmakefea/ligatures.log b/tests/reference/psfmakefea/ligatures.log
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/tests/reference/psfmakefea/ligatures.log
diff --git a/tests/reference/psfmakefea/psfmakefea.fea b/tests/reference/psfmakefea/psfmakefea.fea
new file mode 100644
index 0000000..90fb7ff
--- /dev/null
+++ b/tests/reference/psfmakefea/psfmakefea.fea
@@ -0,0 +1,11 @@
+
+# Main Classes
+
+# Positioning classes and statements
+@base = [A a];
+@basex = [A.x a.x];
+@basey = [A.y a.y];
+feature alt {
+ sub A from [A.x A.y];
+ sub a from [a.x a.y];
+} alt;
diff --git a/tests/reference/psfmakefea/psfmakefea.log b/tests/reference/psfmakefea/psfmakefea.log
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/tests/reference/psfmakefea/psfmakefea.log
diff --git a/tests/reference/psfmakefea/psfmakefea_2.fea b/tests/reference/psfmakefea/psfmakefea_2.fea
new file mode 100644
index 0000000..a6b49b1
--- /dev/null
+++ b/tests/reference/psfmakefea/psfmakefea_2.fea
@@ -0,0 +1,11 @@
+
+# Main Classes
+
+# Positioning classes and statements
+# def func
+feature test {
+ @c = [g5];
+ @c = [g6];
+ @c = [g7];
+
+} test;
diff --git a/tests/reference/psfmakefea/psfmakefea_2.log b/tests/reference/psfmakefea/psfmakefea_2.log
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/tests/reference/psfmakefea/psfmakefea_2.log
diff --git a/tests/reference/ufo/psfbuildcomp.lg b/tests/reference/ufo/psfbuildcomp.lg
new file mode 100644
index 0000000..ab203a3
--- /dev/null
+++ b/tests/reference/ufo/psfbuildcomp.lg
@@ -0,0 +1,52 @@
+2021-06-29 14:42:19 Progress: Running: psfbuildcomp tests/input/font-psf-test/source/PsfTest-Regular.ufo -i tests/input/psfbuildcomp.txt -l local/testresults/ufo/psfbuildcomp.log -p loglevel=i
+2021-06-29 14:42:19 Progress: Opening file for input: tests/input/psfbuildcomp.txt
+2021-06-29 14:42:19 Progress: Reading UFO: tests/input/font-psf-test/source/PsfTest-Regular.ufo
+2021-06-29 14:42:19 Info: Processing Glyph Layer 0: public.defaultglyphs
+2021-06-29 14:42:19 Progress: Checking fontinfo.plist metadata
+2021-06-29 14:42:19 Warning: note is present - it's use is discouraged
+2021-06-29 14:42:19 Warning: openTypeOS2FamilyClass would be removed from fontinfo Old value: [0, 0]
+2021-06-29 14:42:19 Info: Types: Old - list, New - NoneType
+2021-06-29 14:42:19 Warning: openTypeOS2Selection would be added New value: [7]
+2021-06-29 14:42:19 Info: Types: Old - NoneType, New - list
+2021-06-29 14:42:19 Progress: Checking lib.plist metadata
+2021-06-29 14:42:19 Warning: com.schriftgestaltung.disablesAutomaticAlignment would be deleted - obsolete key Old value: True
+2021-06-29 14:42:19 Info: Types: Old - bool, New - NoneType
+2021-06-29 14:42:19 Warning: com.schriftgestaltung.disablesLastChange would be deleted - obsolete key Old value: True
+2021-06-29 14:42:19 Info: Types: Old - bool, New - NoneType
+2021-06-29 14:42:19 Progress: Check & fix results:- Errors: 0, Changes to make: 4, Other warnings: 1
+2021-06-29 14:42:19 Progress: See log file for details
+2021-06-29 14:42:19 Info: Processing line 10: LtnCapIJ = LtnCapI & LtnCapJ |0132
+2021-06-29 14:42:19 Info: Adding new glyph, LtnCapIJ
+2021-06-29 14:42:19 Info: Processing line 11: LtnSmIJ = LtnSmI & LtnSmJ |0133
+2021-06-29 14:42:19 Info: Adding new glyph, LtnSmIJ
+2021-06-29 14:42:19 Info: Processing line 14: LtnCapCAcute = LtnSmC + CombAcute@U |0106
+2021-06-29 14:42:19 Info: Adding new glyph, LtnCapCAcute
+2021-06-29 14:42:19 Info: Processing line 15: LtnSmCAcute = LtnCapC + CombAcute@U |0107
+2021-06-29 14:42:19 Info: Adding new glyph, LtnSmCAcute
+2021-06-29 14:42:19 Info: Processing line 16: LtnCapCCircum = LtnCapC + CombCircum@U |0108
+2021-06-29 14:42:19 Info: Adding new glyph, LtnCapCCircum
+2021-06-29 14:42:19 Info: Processing line 17: LtnSmCCircum = LtnSmC + CombCircum@U |0109
+2021-06-29 14:42:19 Info: Adding new glyph, LtnSmCCircum
+2021-06-29 14:42:19 Info: Processing line 20: LtnSmITildeGrave = LtnSmDotlessI + CombTilde@U + CombGrave@U | E000
+2021-06-29 14:42:19 Error: LtnSmDotlessI not found in font
+2021-06-29 14:42:19 Error: The AP 'U' does not exist on base glyph when building LtnSmITildeGrave
+2021-06-29 14:42:19 Info: Adding new glyph, LtnSmITildeGrave
+2021-06-29 14:42:19 Info: Processing line 23: LtnCapCAcuteCedilla = LtnCapC + CombCedilla@H + CombAcute@LtnCapC:U | 1E08
+2021-06-29 14:42:19 Error: CombCedilla not found in font
+2021-06-29 14:42:19 Info: Adding new glyph, LtnCapCAcuteCedilla
+2021-06-29 14:42:19 Info: Processing line 24: LtnSmCAcuteCedilla = LtnSmC + CombCedilla@H + CombAcute@LtnSmC:U | 1E09
+2021-06-29 14:42:19 Error: CombCedilla not found in font
+2021-06-29 14:42:19 Info: Adding new glyph, LtnSmCAcuteCedilla
+2021-06-29 14:42:19 Info: Processing line 27: LtnSmITilde = LtnSmDotlessI + CombTilde@U ^200,200 | 0129
+2021-06-29 14:42:19 Error: LtnSmDotlessI not found in font
+2021-06-29 14:42:19 Error: The AP 'U' does not exist on base glyph when building LtnSmITilde
+2021-06-29 14:42:19 Info: Adding new glyph, LtnSmITilde
+2021-06-29 14:42:19 Info: Processing line 30: LtnSmITildeGraveCedilla = LtnSmDotlessI + CombCedilla@H + CombTilde@LtnSmDotlessI:U + CombGrave@U ^200,200 | E010 # i cedilla tilde grave
+2021-06-29 14:42:19 Error: LtnSmDotlessI not found in font
+2021-06-29 14:42:19 Error: CombCedilla not found in font
+2021-06-29 14:42:19 Error: The AP 'U' does not exist on base glyph when building LtnSmITildeGraveCedilla
+2021-06-29 14:42:19 Info: Adding new glyph, LtnSmITildeGraveCedilla
+2021-06-29 14:42:19 Progress: Processing font for output
+2021-06-29 14:42:19 Progress: Output UFO already exists - reading for comparison
+2021-06-29 14:42:19 Progress: Writing font to local/testresults/ufo/psfbuildcomp.ufo
+2021-06-29 14:42:19 Info: Processing glyphs directory
diff --git a/tests/reference/ufo/psfbuildcomp.ufo/fontinfo.plist b/tests/reference/ufo/psfbuildcomp.ufo/fontinfo.plist
new file mode 100644
index 0000000..c151323
--- /dev/null
+++ b/tests/reference/ufo/psfbuildcomp.ufo/fontinfo.plist
@@ -0,0 +1,260 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+ <key>ascender</key>
+ <integer>2100</integer>
+ <key>capHeight</key>
+ <integer>1485</integer>
+ <key>copyright</key>
+ <string>Copyright (c) 2004-2021 SIL International</string>
+ <key>descender</key>
+ <integer>-550</integer>
+ <key>familyName</key>
+ <string>Psf Test</string>
+ <key>guidelines</key>
+ <array>
+ <dict>
+ <key>angle</key>
+ <integer>0</integer>
+ <key>x</key>
+ <integer>1084</integer>
+ <key>y</key>
+ <integer>1040</integer>
+ </dict>
+ <dict>
+ <key>y</key>
+ <integer>1250</integer>
+ </dict>
+ </array>
+ <key>note</key>
+ <string>Test note
+Second line
+
+Third line
+</string>
+ <key>openTypeHeadCreated</key>
+ <string>2021/01/29 10:05:04</string>
+ <key>openTypeHheaAscender</key>
+ <integer>2100</integer>
+ <key>openTypeHheaDescender</key>
+ <integer>-550</integer>
+ <key>openTypeHheaLineGap</key>
+ <integer>0</integer>
+ <key>openTypeNameDescription</key>
+ <string>Copyright (c) 2004-2021 SIL International</string>
+ <key>openTypeNameDesigner</key>
+ <string>Victor Gaultney, Annie Olsen, Julie Remington, Don Collingsworth, Eric Hays, Becca Hirsbrunner</string>
+ <key>openTypeNameDesignerURL</key>
+ <string>http://scripts.sil.org/</string>
+ <key>openTypeNameLicense</key>
+ <string>Copyright (c) 2004-2021 SIL International (http://www.sil.org/) with Reserved Font Names "Andika" and "SIL".
+
+This Font Software is licensed under the SIL Open Font License, Version 1.1. This license is copied below, and is also available with a FAQ at: http://scripts.sil.org/OFL
+
+
+-----------------------------------------------------------
+SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007
+-----------------------------------------------------------
+
+PREAMBLE
+The goals of the Open Font License (OFL) are to stimulate worldwide development of collaborative font projects, to support the font creation efforts of academic and linguistic communities, and to provide a free and open framework in which fonts may be shared and improved in partnership with others.
+
+The OFL allows the licensed fonts to be used, studied, modified and redistributed freely as long as they are not sold by themselves. The fonts, including any derivative works, can be bundled, embedded, redistributed and/or sold with any software provided that any reserved names are not used by derivative works. The fonts and derivatives, however, cannot be released under any other type of license. The requirement for fonts to remain under this license does not apply to any document created using the fonts or their derivatives.
+
+DEFINITIONS
+"Font Software" refers to the set of files released by the Copyright Holder(s) under this license and clearly marked as such. This may include source files, build scripts and documentation.
+
+"Reserved Font Name" refers to any names specified as such after the copyright statement(s).
+
+"Original Version" refers to the collection of Font Software components as distributed by the Copyright Holder(s).
+
+"Modified Version" refers to any derivative made by adding to, deleting, or substituting -- in part or in whole -- any of the components of the Original Version, by changing formats or by porting the Font Software to a new environment.
+
+"Author" refers to any designer, engineer, programmer, technical writer or other person who contributed to the Font Software.
+
+PERMISSION &amp; CONDITIONS
+Permission is hereby granted, free of charge, to any person obtaining a copy of the Font Software, to use, study, copy, merge, embed, modify, redistribute, and sell modified and unmodified copies of the Font Software, subject to the following conditions:
+
+1) Neither the Font Software nor any of its individual components, in Original or Modified Versions, may be sold by itself.
+
+2) Original or Modified Versions of the Font Software may be bundled, redistributed and/or sold with any software, provided that each copy contains the above copyright notice and this license. These can be included either as stand-alone text files, human-readable headers or in the appropriate machine-readable metadata fields within text or binary files as long as those fields can be easily viewed by the user.
+
+3) No Modified Version of the Font Software may use the Reserved Font Name(s) unless explicit written permission is granted by the corresponding Copyright Holder. This restriction only applies to the primary font name as presented to the users.
+
+4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font Software shall not be used to promote, endorse or advertise any Modified Version, except to acknowledge the contribution(s) of the Copyright Holder(s) and the Author(s) or with their explicit written permission.
+
+5) The Font Software, modified or unmodified, in part or in whole, must be distributed entirely under this license, and must not be distributed under any other license. The requirement for fonts to remain under this license does not apply to any document created using the Font Software.
+
+TERMINATION
+This license becomes null and void if any of the above conditions are not met.
+
+DISCLAIMER
+THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM OTHER DEALINGS IN THE FONT SOFTWARE.</string>
+ <key>openTypeNameLicenseURL</key>
+ <string>http://scripts.sil.org/OFL</string>
+ <key>openTypeNameManufacturer</key>
+ <string>SIL International</string>
+ <key>openTypeNameManufacturerURL</key>
+ <string>http://scripts.sil.org</string>
+ <key>openTypeNamePreferredFamilyName</key>
+ <string>Psf Test</string>
+ <key>openTypeNamePreferredSubfamilyName</key>
+ <string>Regular</string>
+ <key>openTypeNameUniqueID</key>
+ <string>SIL International: Psf Test Regular: 2022</string>
+ <key>openTypeNameVersion</key>
+ <string>Version 5.550</string>
+ <key>openTypeOS2CodePageRanges</key>
+ <array>
+ <integer>0</integer>
+ <integer>1</integer>
+ <integer>2</integer>
+ <integer>4</integer>
+ <integer>7</integer>
+ <integer>8</integer>
+ </array>
+ <key>openTypeOS2FamilyClass</key>
+ <array>
+ <integer>0</integer>
+ <integer>0</integer>
+ </array>
+ <key>openTypeOS2Panose</key>
+ <array>
+ <integer>2</integer>
+ <integer>0</integer>
+ <integer>0</integer>
+ <integer>0</integer>
+ <integer>0</integer>
+ <integer>0</integer>
+ <integer>0</integer>
+ <integer>0</integer>
+ <integer>0</integer>
+ <integer>0</integer>
+ </array>
+ <key>openTypeOS2StrikeoutPosition</key>
+ <integer>700</integer>
+ <key>openTypeOS2StrikeoutSize</key>
+ <integer>100</integer>
+ <key>openTypeOS2SubscriptXOffset</key>
+ <integer>0</integer>
+ <key>openTypeOS2SubscriptXSize</key>
+ <integer>1433</integer>
+ <key>openTypeOS2SubscriptYOffset</key>
+ <integer>286</integer>
+ <key>openTypeOS2SubscriptYSize</key>
+ <integer>1331</integer>
+ <key>openTypeOS2SuperscriptXOffset</key>
+ <integer>0</integer>
+ <key>openTypeOS2SuperscriptXSize</key>
+ <integer>1433</integer>
+ <key>openTypeOS2SuperscriptYOffset</key>
+ <integer>976</integer>
+ <key>openTypeOS2SuperscriptYSize</key>
+ <integer>1331</integer>
+ <key>openTypeOS2Type</key>
+ <array/>
+ <key>openTypeOS2TypoAscender</key>
+ <integer>2100</integer>
+ <key>openTypeOS2TypoDescender</key>
+ <integer>-550</integer>
+ <key>openTypeOS2TypoLineGap</key>
+ <integer>0</integer>
+ <key>openTypeOS2UnicodeRanges</key>
+ <array>
+ <integer>0</integer>
+ <integer>1</integer>
+ <integer>6</integer>
+ <integer>7</integer>
+ <integer>31</integer>
+ <integer>33</integer>
+ <integer>35</integer>
+ <integer>36</integer>
+ <integer>37</integer>
+ <integer>38</integer>
+ <integer>39</integer>
+ <integer>40</integer>
+ <integer>45</integer>
+ <integer>46</integer>
+ <integer>47</integer>
+ <integer>57</integer>
+ <integer>60</integer>
+ <integer>62</integer>
+ <integer>64</integer>
+ <integer>67</integer>
+ <integer>69</integer>
+ <integer>89</integer>
+ </array>
+ <key>openTypeOS2VendorID</key>
+ <string>SIL</string>
+ <key>openTypeOS2WeightClass</key>
+ <integer>400</integer>
+ <key>openTypeOS2WidthClass</key>
+ <integer>5</integer>
+ <key>openTypeOS2WinAscent</key>
+ <integer>2100</integer>
+ <key>openTypeOS2WinDescent</key>
+ <integer>550</integer>
+ <key>postscriptBlueValues</key>
+ <array>
+ <integer>-490</integer>
+ <integer>-490</integer>
+ <integer>-25</integer>
+ <integer>0</integer>
+ <integer>1020</integer>
+ <integer>1040</integer>
+ <integer>1455</integer>
+ <integer>1485</integer>
+ <integer>1600</integer>
+ <integer>1620</integer>
+ </array>
+ <key>postscriptFontName</key>
+ <string>PsfTest-Regular</string>
+ <key>postscriptFullName</key>
+ <string>Psf Test Regular</string>
+ <key>postscriptStemSnapH</key>
+ <array>
+ <integer>140</integer>
+ <integer>145</integer>
+ <integer>150</integer>
+ <integer>155</integer>
+ <integer>160</integer>
+ <integer>165</integer>
+ <integer>170</integer>
+ <integer>175</integer>
+ <integer>185</integer>
+ <integer>270</integer>
+ </array>
+ <key>postscriptStemSnapV</key>
+ <array>
+ <integer>165</integer>
+ <integer>180</integer>
+ <integer>185</integer>
+ <integer>190</integer>
+ <integer>195</integer>
+ <integer>200</integer>
+ <integer>205</integer>
+ <integer>270</integer>
+ </array>
+ <key>postscriptUnderlinePosition</key>
+ <integer>-110</integer>
+ <key>postscriptUnderlineThickness</key>
+ <integer>80</integer>
+ <key>styleMapFamilyName</key>
+ <string>Psf Test</string>
+ <key>styleMapStyleName</key>
+ <string>regular</string>
+ <key>styleName</key>
+ <string>Regular</string>
+ <key>trademark</key>
+ <string>Andika is a trademark of SIL International.</string>
+ <key>unitsPerEm</key>
+ <integer>2048</integer>
+ <key>versionMajor</key>
+ <integer>5</integer>
+ <key>versionMinor</key>
+ <integer>550</integer>
+ <key>xHeight</key>
+ <integer>1040</integer>
+</dict>
+</plist>
diff --git a/tests/reference/ufo/psfbuildcomp.ufo/glyphs/A_mpersand.glif b/tests/reference/ufo/psfbuildcomp.ufo/glyphs/A_mpersand.glif
new file mode 100644
index 0000000..c2cef04
--- /dev/null
+++ b/tests/reference/ufo/psfbuildcomp.ufo/glyphs/A_mpersand.glif
@@ -0,0 +1,61 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="Ampersand" format="2">
+ <advance width="1222"/>
+ <unicode hex="0026"/>
+ <outline>
+ <contour>
+ <point x="490" y="1485" type="curve" smooth="yes"/>
+ <point x="331" y="1485"/>
+ <point x="155" y="1412"/>
+ <point x="155" y="1190" type="curve" smooth="yes"/>
+ <point x="155" y="1010"/>
+ <point x="362" y="815"/>
+ <point x="535" y="570" type="curve" smooth="yes"/>
+ <point x="794" y="202"/>
+ <point x="973" y="-25"/>
+ <point x="1025" y="-25" type="curve" smooth="yes"/>
+ <point x="1060" y="-25"/>
+ <point x="1138" y="38"/>
+ <point x="1175" y="70" type="curve"/>
+ <point x="1080" y="110"/>
+ <point x="914" y="297"/>
+ <point x="650" y="680" type="curve" smooth="yes"/>
+ <point x="494" y="906"/>
+ <point x="315" y="1075"/>
+ <point x="315" y="1200" type="curve" smooth="yes"/>
+ <point x="315" y="1291"/>
+ <point x="398" y="1350"/>
+ <point x="475" y="1350" type="curve" smooth="yes"/>
+ <point x="555" y="1350"/>
+ <point x="630" y="1294"/>
+ <point x="630" y="1205" type="curve" smooth="yes"/>
+ <point x="630" y="1116"/>
+ <point x="523" y="1001"/>
+ <point x="350" y="840" type="curve" smooth="yes"/>
+ <point x="146" y="651"/>
+ <point x="55" y="527"/>
+ <point x="55" y="375" type="curve" smooth="yes"/>
+ <point x="55" y="151"/>
+ <point x="217" y="-25"/>
+ <point x="440" y="-25" type="curve" smooth="yes"/>
+ <point x="713" y="-25"/>
+ <point x="1002" y="274"/>
+ <point x="1080" y="435" type="curve"/>
+ <point x="975" y="570" type="line"/>
+ <point x="911" y="403"/>
+ <point x="630" y="150"/>
+ <point x="455" y="150" type="curve" smooth="yes"/>
+ <point x="310" y="150"/>
+ <point x="230" y="267"/>
+ <point x="230" y="380" type="curve" smooth="yes"/>
+ <point x="230" y="490"/>
+ <point x="296" y="587"/>
+ <point x="470" y="740" type="curve" smooth="yes"/>
+ <point x="651" y="899"/>
+ <point x="790" y="1068"/>
+ <point x="790" y="1200" type="curve" smooth="yes"/>
+ <point x="790" y="1382"/>
+ <point x="642" y="1485"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfbuildcomp.ufo/glyphs/A_pos.glif b/tests/reference/ufo/psfbuildcomp.ufo/glyphs/A_pos.glif
new file mode 100644
index 0000000..5042901
--- /dev/null
+++ b/tests/reference/ufo/psfbuildcomp.ufo/glyphs/A_pos.glif
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="Apos" format="2">
+ <advance width="605"/>
+ <unicode hex="0027"/>
+ <outline>
+ <contour>
+ <point x="365" y="1045" type="line"/>
+ <point x="370" y="1186"/>
+ <point x="376" y="1339"/>
+ <point x="405" y="1585" type="curve"/>
+ <point x="200" y="1585" type="line"/>
+ <point x="231" y="1339"/>
+ <point x="236" y="1186"/>
+ <point x="240" y="1045" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfbuildcomp.ufo/glyphs/A_sterisk.glif b/tests/reference/ufo/psfbuildcomp.ufo/glyphs/A_sterisk.glif
new file mode 100644
index 0000000..850d344
--- /dev/null
+++ b/tests/reference/ufo/psfbuildcomp.ufo/glyphs/A_sterisk.glif
@@ -0,0 +1,51 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="Asterisk" format="2">
+ <advance width="1028"/>
+ <unicode hex="002A"/>
+ <outline>
+ <contour>
+ <point x="560" y="1600" type="curve"/>
+ <point x="415" y="1600" type="line"/>
+ <point x="434" y="1467"/>
+ <point x="447" y="1387"/>
+ <point x="450" y="1300" type="curve"/>
+ <point x="376" y="1344"/>
+ <point x="309" y="1387"/>
+ <point x="200" y="1465" type="curve"/>
+ <point x="125" y="1340" type="line"/>
+ <point x="250" y="1290"/>
+ <point x="327" y="1261"/>
+ <point x="405" y="1220" type="curve"/>
+ <point x="329" y="1177"/>
+ <point x="256" y="1140"/>
+ <point x="135" y="1085" type="curve"/>
+ <point x="205" y="960" type="line"/>
+ <point x="310" y="1042"/>
+ <point x="377" y="1094"/>
+ <point x="450" y="1140" type="curve"/>
+ <point x="448" y="1055"/>
+ <point x="442" y="973"/>
+ <point x="430" y="840" type="curve"/>
+ <point x="570" y="840" type="line"/>
+ <point x="550" y="973"/>
+ <point x="544" y="1052"/>
+ <point x="540" y="1140" type="curve"/>
+ <point x="614" y="1095"/>
+ <point x="681" y="1053"/>
+ <point x="790" y="975" type="curve"/>
+ <point x="865" y="1100" type="line"/>
+ <point x="739" y="1149"/>
+ <point x="663" y="1179"/>
+ <point x="585" y="1220" type="curve"/>
+ <point x="661" y="1261"/>
+ <point x="733" y="1299"/>
+ <point x="855" y="1355" type="curve"/>
+ <point x="785" y="1480" type="line"/>
+ <point x="680" y="1396"/>
+ <point x="614" y="1348"/>
+ <point x="540" y="1300" type="curve"/>
+ <point x="541" y="1387"/>
+ <point x="547" y="1467"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfbuildcomp.ufo/glyphs/A_tS_gn.glif b/tests/reference/ufo/psfbuildcomp.ufo/glyphs/A_tS_gn.glif
new file mode 100644
index 0000000..681014d
--- /dev/null
+++ b/tests/reference/ufo/psfbuildcomp.ufo/glyphs/A_tS_gn.glif
@@ -0,0 +1,80 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="AtSgn" format="2">
+ <advance width="1702"/>
+ <unicode hex="0040"/>
+ <outline>
+ <contour>
+ <point x="1605" y="700" type="curve" smooth="yes"/>
+ <point x="1605" y="1127"/>
+ <point x="1307" y="1405"/>
+ <point x="880" y="1405" type="curve" smooth="yes"/>
+ <point x="465" y="1405"/>
+ <point x="95" y="1126"/>
+ <point x="95" y="575" type="curve" smooth="yes"/>
+ <point x="95" y="48"/>
+ <point x="464" y="-235"/>
+ <point x="855" y="-235" type="curve" smooth="yes"/>
+ <point x="990" y="-235"/>
+ <point x="1150" y="-188"/>
+ <point x="1250" y="-118" type="curve"/>
+ <point x="1145" y="-10" type="line"/>
+ <point x="1058" y="-70"/>
+ <point x="963" y="-95"/>
+ <point x="870" y="-95" type="curve" smooth="yes"/>
+ <point x="523" y="-95"/>
+ <point x="240" y="174"/>
+ <point x="240" y="605" type="curve" smooth="yes"/>
+ <point x="240" y="1003"/>
+ <point x="542" y="1270"/>
+ <point x="870" y="1270" type="curve" smooth="yes"/>
+ <point x="1263" y="1270"/>
+ <point x="1465" y="1002"/>
+ <point x="1465" y="670" type="curve" smooth="yes"/>
+ <point x="1465" y="432"/>
+ <point x="1348" y="315"/>
+ <point x="1280" y="315" type="curve" smooth="yes"/>
+ <point x="1221" y="315"/>
+ <point x="1175" y="410"/>
+ <point x="1175" y="630" type="curve" smooth="yes"/>
+ <point x="1175" y="980" type="line"/>
+ <point x="1088" y="1015"/>
+ <point x="961" y="1040"/>
+ <point x="880" y="1040" type="curve" smooth="yes"/>
+ <point x="716" y="1040"/>
+ <point x="613" y="971"/>
+ <point x="530" y="835" type="curve" smooth="yes"/>
+ <point x="483" y="756"/>
+ <point x="455" y="653"/>
+ <point x="455" y="530" type="curve" smooth="yes"/>
+ <point x="455" y="294"/>
+ <point x="601" y="183"/>
+ <point x="735" y="183" type="curve" smooth="yes"/>
+ <point x="852" y="183"/>
+ <point x="988" y="366"/>
+ <point x="1040" y="490" type="curve"/>
+ <point x="1050" y="322"/>
+ <point x="1128" y="180"/>
+ <point x="1250" y="180" type="curve" smooth="yes"/>
+ <point x="1425" y="180"/>
+ <point x="1605" y="368"/>
+ </contour>
+ <contour>
+ <point x="850" y="905" type="curve" smooth="yes"/>
+ <point x="924" y="905"/>
+ <point x="992" y="886"/>
+ <point x="1025" y="870" type="curve"/>
+ <point x="1025" y="720" type="line"/>
+ <point x="993" y="582"/>
+ <point x="838" y="320"/>
+ <point x="748" y="320" type="curve" smooth="yes"/>
+ <point x="676" y="320"/>
+ <point x="605" y="398"/>
+ <point x="605" y="575" type="curve" smooth="yes"/>
+ <point x="605" y="652"/>
+ <point x="621" y="731"/>
+ <point x="650" y="780" type="curve" smooth="yes"/>
+ <point x="706" y="876"/>
+ <point x="782" y="905"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfbuildcomp.ufo/glyphs/C_ircumA_ccent.glif b/tests/reference/ufo/psfbuildcomp.ufo/glyphs/C_ircumA_ccent.glif
new file mode 100644
index 0000000..60bd1cf
--- /dev/null
+++ b/tests/reference/ufo/psfbuildcomp.ufo/glyphs/C_ircumA_ccent.glif
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="CircumAccent" format="2">
+ <advance width="850"/>
+ <unicode hex="005E"/>
+ <outline>
+ <component base="CombCircum" xOffset="995"/>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfbuildcomp.ufo/glyphs/C_olon.glif b/tests/reference/ufo/psfbuildcomp.ufo/glyphs/C_olon.glif
new file mode 100644
index 0000000..3cfbbc1
--- /dev/null
+++ b/tests/reference/ufo/psfbuildcomp.ufo/glyphs/C_olon.glif
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="Colon" format="2">
+ <advance width="640"/>
+ <unicode hex="003A"/>
+ <outline>
+ <contour>
+ <point x="185" y="790" type="curve" smooth="yes"/>
+ <point x="185" y="716"/>
+ <point x="246" y="655"/>
+ <point x="320" y="655" type="curve" smooth="yes"/>
+ <point x="394" y="655"/>
+ <point x="455" y="716"/>
+ <point x="455" y="790" type="curve" smooth="yes"/>
+ <point x="455" y="864"/>
+ <point x="394" y="925"/>
+ <point x="320" y="925" type="curve" smooth="yes"/>
+ <point x="246" y="925"/>
+ <point x="185" y="864"/>
+ </contour>
+ <contour>
+ <point x="185" y="110" type="curve" smooth="yes"/>
+ <point x="185" y="36"/>
+ <point x="246" y="-25"/>
+ <point x="320" y="-25" type="curve" smooth="yes"/>
+ <point x="394" y="-25"/>
+ <point x="455" y="36"/>
+ <point x="455" y="110" type="curve" smooth="yes"/>
+ <point x="455" y="184"/>
+ <point x="394" y="245"/>
+ <point x="320" y="245" type="curve" smooth="yes"/>
+ <point x="246" y="245"/>
+ <point x="185" y="184"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfbuildcomp.ufo/glyphs/C_ombA_cute.glif b/tests/reference/ufo/psfbuildcomp.ufo/glyphs/C_ombA_cute.glif
new file mode 100644
index 0000000..bb13221
--- /dev/null
+++ b/tests/reference/ufo/psfbuildcomp.ufo/glyphs/C_ombA_cute.glif
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="CombAcute" format="2">
+ <unicode hex="0301"/>
+ <anchor x="-570" y="1635" name="U"/>
+ <anchor x="-570" y="1100" name="_U"/>
+ <outline>
+ <contour>
+ <point x="-400" y="1600" type="line"/>
+ <point x="-750" y="1170" type="line"/>
+ <point x="-590" y="1170" type="line"/>
+ <point x="-170" y="1600" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfbuildcomp.ufo/glyphs/C_ombC_ircum.glif b/tests/reference/ufo/psfbuildcomp.ufo/glyphs/C_ombC_ircum.glif
new file mode 100644
index 0000000..fa444ec
--- /dev/null
+++ b/tests/reference/ufo/psfbuildcomp.ufo/glyphs/C_ombC_ircum.glif
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="CombCircum" format="2">
+ <unicode hex="0302"/>
+ <anchor x="-570" y="1635" name="U"/>
+ <anchor x="-570" y="1100" name="_U"/>
+ <outline>
+ <contour>
+ <point x="-845" y="1170" type="line"/>
+ <point x="-570" y="1450" type="line"/>
+ <point x="-295" y="1170" type="line"/>
+ <point x="-145" y="1170" type="line"/>
+ <point x="-485" y="1600" type="line"/>
+ <point x="-655" y="1600" type="line"/>
+ <point x="-995" y="1170" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfbuildcomp.ufo/glyphs/C_ombD_iaer.glif b/tests/reference/ufo/psfbuildcomp.ufo/glyphs/C_ombD_iaer.glif
new file mode 100644
index 0000000..f7540ef
--- /dev/null
+++ b/tests/reference/ufo/psfbuildcomp.ufo/glyphs/C_ombD_iaer.glif
@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="CombDiaer" format="2">
+ <unicode hex="0308"/>
+ <anchor x="-570" y="1505" name="U"/>
+ <anchor x="-570" y="1100" name="_U"/>
+ <outline>
+ <contour>
+ <point x="-490" y="1345" type="curve" smooth="yes"/>
+ <point x="-490" y="1271"/>
+ <point x="-434" y="1210"/>
+ <point x="-360" y="1210" type="curve" smooth="yes"/>
+ <point x="-285" y="1210"/>
+ <point x="-230" y="1271"/>
+ <point x="-230" y="1345" type="curve" smooth="yes"/>
+ <point x="-230" y="1419"/>
+ <point x="-285" y="1480"/>
+ <point x="-360" y="1480" type="curve" smooth="yes"/>
+ <point x="-434" y="1480"/>
+ <point x="-490" y="1419"/>
+ </contour>
+ <contour>
+ <point x="-910" y="1345" type="curve" smooth="yes"/>
+ <point x="-910" y="1271"/>
+ <point x="-854" y="1210"/>
+ <point x="-780" y="1210" type="curve" smooth="yes"/>
+ <point x="-705" y="1210"/>
+ <point x="-650" y="1271"/>
+ <point x="-650" y="1345" type="curve" smooth="yes"/>
+ <point x="-650" y="1419"/>
+ <point x="-705" y="1480"/>
+ <point x="-780" y="1480" type="curve" smooth="yes"/>
+ <point x="-854" y="1480"/>
+ <point x="-910" y="1419"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfbuildcomp.ufo/glyphs/C_ombG_rave.glif b/tests/reference/ufo/psfbuildcomp.ufo/glyphs/C_ombG_rave.glif
new file mode 100644
index 0000000..c33b56a
--- /dev/null
+++ b/tests/reference/ufo/psfbuildcomp.ufo/glyphs/C_ombG_rave.glif
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="CombGrave" format="2">
+ <unicode hex="0300"/>
+ <anchor x="-550" y="1635" name="U"/>
+ <anchor x="-550" y="1100" name="_U"/>
+ <outline>
+ <contour>
+ <point x="-940" y="1600" type="line"/>
+ <point x="-520" y="1170" type="line"/>
+ <point x="-360" y="1170" type="line"/>
+ <point x="-710" y="1600" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfbuildcomp.ufo/glyphs/C_ombR_ingA_bv.glif b/tests/reference/ufo/psfbuildcomp.ufo/glyphs/C_ombR_ingA_bv.glif
new file mode 100644
index 0000000..b019e05
--- /dev/null
+++ b/tests/reference/ufo/psfbuildcomp.ufo/glyphs/C_ombR_ingA_bv.glif
@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="CombRingAbv" format="2">
+ <unicode hex="030A"/>
+ <anchor x="-570" y="1635" name="U"/>
+ <anchor x="-572" y="1100" name="_U"/>
+ <outline>
+ <contour>
+ <point x="-470" y="1385" type="curve" smooth="yes"/>
+ <point x="-470" y="1325"/>
+ <point x="-510" y="1285"/>
+ <point x="-570" y="1285" type="curve" smooth="yes"/>
+ <point x="-630" y="1285"/>
+ <point x="-670" y="1325"/>
+ <point x="-670" y="1385" type="curve" smooth="yes"/>
+ <point x="-670" y="1445"/>
+ <point x="-630" y="1485"/>
+ <point x="-570" y="1485" type="curve" smooth="yes"/>
+ <point x="-510" y="1485"/>
+ <point x="-470" y="1445"/>
+ </contour>
+ <contour>
+ <point x="-785" y="1385" type="curve" smooth="yes"/>
+ <point x="-785" y="1265"/>
+ <point x="-690" y="1170"/>
+ <point x="-570" y="1170" type="curve" smooth="yes"/>
+ <point x="-450" y="1170"/>
+ <point x="-355" y="1265"/>
+ <point x="-355" y="1385" type="curve" smooth="yes"/>
+ <point x="-355" y="1505"/>
+ <point x="-450" y="1600"/>
+ <point x="-570" y="1600" type="curve" smooth="yes"/>
+ <point x="-690" y="1600"/>
+ <point x="-785" y="1505"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfbuildcomp.ufo/glyphs/C_ombT_ilde.glif b/tests/reference/ufo/psfbuildcomp.ufo/glyphs/C_ombT_ilde.glif
new file mode 100644
index 0000000..88d5ca7
--- /dev/null
+++ b/tests/reference/ufo/psfbuildcomp.ufo/glyphs/C_ombT_ilde.glif
@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="CombTilde" format="2">
+ <unicode hex="0303"/>
+ <anchor x="-575" y="1475" name="U"/>
+ <anchor x="-575" y="1100" name="_U"/>
+ <outline>
+ <contour>
+ <point x="-820" y="1205" type="line"/>
+ <point x="-815" y="1254"/>
+ <point x="-784" y="1290"/>
+ <point x="-735" y="1290" type="curve" smooth="yes"/>
+ <point x="-698" y="1290"/>
+ <point x="-657" y="1274"/>
+ <point x="-580" y="1238" type="curve" smooth="yes"/>
+ <point x="-519" y="1210"/>
+ <point x="-466" y="1190"/>
+ <point x="-413" y="1190" type="curve" smooth="yes"/>
+ <point x="-290" y="1190"/>
+ <point x="-215" y="1312"/>
+ <point x="-215" y="1440" type="curve"/>
+ <point x="-320" y="1440" type="line"/>
+ <point x="-327" y="1394"/>
+ <point x="-358" y="1355"/>
+ <point x="-405" y="1355" type="curve" smooth="yes"/>
+ <point x="-447" y="1355"/>
+ <point x="-488" y="1374"/>
+ <point x="-560" y="1403" type="curve" smooth="yes"/>
+ <point x="-630" y="1431"/>
+ <point x="-677" y="1455"/>
+ <point x="-733" y="1455" type="curve" smooth="yes"/>
+ <point x="-852" y="1455"/>
+ <point x="-925" y="1327"/>
+ <point x="-925" y="1205" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfbuildcomp.ufo/glyphs/C_omma.glif b/tests/reference/ufo/psfbuildcomp.ufo/glyphs/C_omma.glif
new file mode 100644
index 0000000..6e8f5a3
--- /dev/null
+++ b/tests/reference/ufo/psfbuildcomp.ufo/glyphs/C_omma.glif
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="Comma" format="2">
+ <advance width="650"/>
+ <unicode hex="002C"/>
+ <outline>
+ <contour>
+ <point x="185" y="50" type="line"/>
+ <point x="325" y="50" type="line"/>
+ <point x="325" y="-51"/>
+ <point x="248" y="-172"/>
+ <point x="190" y="-230" type="curve"/>
+ <point x="290" y="-270" type="line"/>
+ <point x="407" y="-160"/>
+ <point x="465" y="-37"/>
+ <point x="465" y="85" type="curve" smooth="yes"/>
+ <point x="465" y="186"/>
+ <point x="400" y="250"/>
+ <point x="320" y="250" type="curve" smooth="yes"/>
+ <point x="263" y="250"/>
+ <point x="198" y="213"/>
+ <point x="185" y="150" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfbuildcomp.ufo/glyphs/D_igitE_ight.glif b/tests/reference/ufo/psfbuildcomp.ufo/glyphs/D_igitE_ight.glif
new file mode 100644
index 0000000..b7e540a
--- /dev/null
+++ b/tests/reference/ufo/psfbuildcomp.ufo/glyphs/D_igitE_ight.glif
@@ -0,0 +1,63 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="DigitEight" format="2">
+ <advance width="1200"/>
+ <unicode hex="0038"/>
+ <anchor x="600" y="-100" name="L"/>
+ <anchor x="600" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="600" y="-25" type="curve" smooth="yes"/>
+ <point x="857" y="-25"/>
+ <point x="1110" y="134"/>
+ <point x="1110" y="405" type="curve" smooth="yes"/>
+ <point x="1110" y="611"/>
+ <point x="965" y="739"/>
+ <point x="855" y="795" type="curve"/>
+ <point x="933" y="844"/>
+ <point x="1050" y="923"/>
+ <point x="1050" y="1105" type="curve" smooth="yes"/>
+ <point x="1050" y="1350"/>
+ <point x="840" y="1485"/>
+ <point x="610" y="1485" type="curve" smooth="yes"/>
+ <point x="381" y="1485"/>
+ <point x="150" y="1350"/>
+ <point x="150" y="1105" type="curve" smooth="yes"/>
+ <point x="150" y="923"/>
+ <point x="272" y="838"/>
+ <point x="350" y="795" type="curve"/>
+ <point x="221" y="725"/>
+ <point x="90" y="611"/>
+ <point x="90" y="405" type="curve" smooth="yes"/>
+ <point x="90" y="134"/>
+ <point x="344" y="-25"/>
+ </contour>
+ <contour>
+ <point x="860" y="1105" type="curve" smooth="yes"/>
+ <point x="860" y="949"/>
+ <point x="743" y="865"/>
+ <point x="600" y="865" type="curve" smooth="yes"/>
+ <point x="457" y="865"/>
+ <point x="340" y="949"/>
+ <point x="340" y="1105" type="curve" smooth="yes"/>
+ <point x="340" y="1252"/>
+ <point x="457" y="1325"/>
+ <point x="600" y="1325" type="curve" smooth="yes"/>
+ <point x="743" y="1325"/>
+ <point x="860" y="1252"/>
+ </contour>
+ <contour>
+ <point x="910" y="425" type="curve" smooth="yes"/>
+ <point x="910" y="250"/>
+ <point x="778" y="145"/>
+ <point x="600" y="145" type="curve" smooth="yes"/>
+ <point x="420" y="145"/>
+ <point x="290" y="250"/>
+ <point x="290" y="425" type="curve" smooth="yes"/>
+ <point x="290" y="592"/>
+ <point x="420" y="710"/>
+ <point x="600" y="710" type="curve" smooth="yes"/>
+ <point x="778" y="710"/>
+ <point x="910" y="592"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfbuildcomp.ufo/glyphs/D_igitF_ive.glif b/tests/reference/ufo/psfbuildcomp.ufo/glyphs/D_igitF_ive.glif
new file mode 100644
index 0000000..cb2dd85
--- /dev/null
+++ b/tests/reference/ufo/psfbuildcomp.ufo/glyphs/D_igitF_ive.glif
@@ -0,0 +1,44 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="DigitFive" format="2">
+ <advance width="1200"/>
+ <unicode hex="0035"/>
+ <anchor x="600" y="-100" name="L"/>
+ <anchor x="600" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="195" y="685" type="line"/>
+ <point x="319" y="733"/>
+ <point x="404" y="750"/>
+ <point x="510" y="750" type="curve" smooth="yes"/>
+ <point x="670" y="750"/>
+ <point x="870" y="672"/>
+ <point x="870" y="470" type="curve" smooth="yes"/>
+ <point x="870" y="268"/>
+ <point x="730" y="155"/>
+ <point x="530" y="155" type="curve" smooth="yes"/>
+ <point x="390" y="155"/>
+ <point x="294" y="182"/>
+ <point x="160" y="290" type="curve"/>
+ <point x="130" y="80" type="line"/>
+ <point x="255" y="2"/>
+ <point x="363" y="-25"/>
+ <point x="518" y="-25" type="curve" smooth="yes"/>
+ <point x="831" y="-25"/>
+ <point x="1060" y="163"/>
+ <point x="1060" y="475" type="curve" smooth="yes"/>
+ <point x="1060" y="742"/>
+ <point x="832" y="930"/>
+ <point x="545" y="930" type="curve" smooth="yes"/>
+ <point x="472" y="930"/>
+ <point x="411" y="924"/>
+ <point x="380" y="920" type="curve"/>
+ <point x="380" y="1290" type="line"/>
+ <point x="765" y="1290" type="line"/>
+ <point x="849" y="1290"/>
+ <point x="925" y="1286"/>
+ <point x="1000" y="1270" type="curve"/>
+ <point x="1000" y="1460" type="line"/>
+ <point x="195" y="1460" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfbuildcomp.ufo/glyphs/D_igitF_our.glif b/tests/reference/ufo/psfbuildcomp.ufo/glyphs/D_igitF_our.glif
new file mode 100644
index 0000000..d9a5610
--- /dev/null
+++ b/tests/reference/ufo/psfbuildcomp.ufo/glyphs/D_igitF_our.glif
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="DigitFour" format="2">
+ <advance width="1200"/>
+ <unicode hex="0034"/>
+ <anchor x="607" y="-100" name="L"/>
+ <anchor x="607" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="1125" y="395" type="line"/>
+ <point x="1125" y="550" type="line"/>
+ <point x="935" y="550" type="line"/>
+ <point x="935" y="1480" type="line"/>
+ <point x="745" y="1480" type="line"/>
+ <point x="90" y="550" type="line"/>
+ <point x="90" y="395" type="line"/>
+ <point x="745" y="395" type="line"/>
+ <point x="745" y="0" type="line"/>
+ <point x="935" y="0" type="line"/>
+ <point x="935" y="395" type="line"/>
+ </contour>
+ <contour>
+ <point x="745" y="1230" type="line"/>
+ <point x="745" y="550" type="line"/>
+ <point x="263" y="550" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfbuildcomp.ufo/glyphs/D_igitN_ine.glif b/tests/reference/ufo/psfbuildcomp.ufo/glyphs/D_igitN_ine.glif
new file mode 100644
index 0000000..0ce656a
--- /dev/null
+++ b/tests/reference/ufo/psfbuildcomp.ufo/glyphs/D_igitN_ine.glif
@@ -0,0 +1,49 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="DigitNine" format="2">
+ <advance width="1200"/>
+ <unicode hex="0039"/>
+ <anchor x="600" y="-100" name="L"/>
+ <anchor x="600" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="193" y="65" type="line"/>
+ <point x="297" y="-5"/>
+ <point x="383" y="-25"/>
+ <point x="501" y="-25" type="curve" smooth="yes"/>
+ <point x="976" y="-25"/>
+ <point x="1114" y="411"/>
+ <point x="1114" y="780" type="curve" smooth="yes"/>
+ <point x="1114" y="1198"/>
+ <point x="926" y="1485"/>
+ <point x="616" y="1485" type="curve" smooth="yes"/>
+ <point x="349" y="1485"/>
+ <point x="112" y="1306"/>
+ <point x="112" y="1002" type="curve" smooth="yes"/>
+ <point x="112" y="773"/>
+ <point x="281" y="586"/>
+ <point x="559" y="586" type="curve" smooth="yes"/>
+ <point x="750" y="586"/>
+ <point x="922" y="717"/>
+ <point x="1019" y="878" type="curve"/>
+ <point x="948" y="961" type="line"/>
+ <point x="874" y="847"/>
+ <point x="738" y="760"/>
+ <point x="583" y="760" type="curve" smooth="yes"/>
+ <point x="424" y="760"/>
+ <point x="306" y="860"/>
+ <point x="306" y="1036" type="curve" smooth="yes"/>
+ <point x="306" y="1196"/>
+ <point x="420" y="1310"/>
+ <point x="596" y="1310" type="curve" smooth="yes"/>
+ <point x="837" y="1310"/>
+ <point x="919" y="1065"/>
+ <point x="919" y="813" type="curve" smooth="yes"/>
+ <point x="919" y="326"/>
+ <point x="748" y="150"/>
+ <point x="511" y="150" type="curve" smooth="yes"/>
+ <point x="415" y="150"/>
+ <point x="323" y="174"/>
+ <point x="237" y="260" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfbuildcomp.ufo/glyphs/D_igitO_ne.glif b/tests/reference/ufo/psfbuildcomp.ufo/glyphs/D_igitO_ne.glif
new file mode 100644
index 0000000..42c7708
--- /dev/null
+++ b/tests/reference/ufo/psfbuildcomp.ufo/glyphs/D_igitO_ne.glif
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="DigitOne" format="2">
+ <advance width="1200"/>
+ <unicode hex="0031"/>
+ <anchor x="600" y="-100" name="L"/>
+ <anchor x="600" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="535" y="170" type="line"/>
+ <point x="220" y="170" type="line"/>
+ <point x="220" y="0" type="line"/>
+ <point x="1040" y="0" type="line"/>
+ <point x="1040" y="170" type="line"/>
+ <point x="725" y="170" type="line"/>
+ <point x="725" y="1480" type="line"/>
+ <point x="555" y="1480" type="line"/>
+ <point x="210" y="1268" type="line"/>
+ <point x="235" y="1088" type="line"/>
+ <point x="535" y="1260" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfbuildcomp.ufo/glyphs/D_igitS_even.glif b/tests/reference/ufo/psfbuildcomp.ufo/glyphs/D_igitS_even.glif
new file mode 100644
index 0000000..c9ca97e
--- /dev/null
+++ b/tests/reference/ufo/psfbuildcomp.ufo/glyphs/D_igitS_even.glif
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="DigitSeven" format="2">
+ <advance width="1200"/>
+ <unicode hex="0037"/>
+ <anchor x="600" y="-100" name="L"/>
+ <anchor x="600" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="460" y="0" type="line"/>
+ <point x="589" y="459"/>
+ <point x="794" y="895"/>
+ <point x="1090" y="1300" type="curve"/>
+ <point x="1090" y="1460" type="line"/>
+ <point x="100" y="1460" type="line"/>
+ <point x="100" y="1275" type="line"/>
+ <point x="176" y="1291"/>
+ <point x="292" y="1295"/>
+ <point x="480" y="1295" type="curve" smooth="yes"/>
+ <point x="870" y="1295" type="line"/>
+ <point x="612" y="912"/>
+ <point x="439" y="566"/>
+ <point x="275" y="0" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfbuildcomp.ufo/glyphs/D_igitS_ix.glif b/tests/reference/ufo/psfbuildcomp.ufo/glyphs/D_igitS_ix.glif
new file mode 100644
index 0000000..ec0acdb
--- /dev/null
+++ b/tests/reference/ufo/psfbuildcomp.ufo/glyphs/D_igitS_ix.glif
@@ -0,0 +1,49 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="DigitSix" format="2">
+ <advance width="1200"/>
+ <unicode hex="0036"/>
+ <anchor x="600" y="-100" name="L"/>
+ <anchor x="600" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="1033" y="1395" type="line"/>
+ <point x="929" y="1465"/>
+ <point x="843" y="1485"/>
+ <point x="725" y="1485" type="curve" smooth="yes"/>
+ <point x="250" y="1485"/>
+ <point x="110" y="1049"/>
+ <point x="110" y="680" type="curve" smooth="yes"/>
+ <point x="110" y="242"/>
+ <point x="290" y="-25"/>
+ <point x="600" y="-25" type="curve" smooth="yes"/>
+ <point x="907" y="-25"/>
+ <point x="1115" y="166"/>
+ <point x="1115" y="470" type="curve" smooth="yes"/>
+ <point x="1115" y="719"/>
+ <point x="943" y="895"/>
+ <point x="665" y="895" type="curve" smooth="yes"/>
+ <point x="474" y="895"/>
+ <point x="328" y="780"/>
+ <point x="215" y="625" type="curve"/>
+ <point x="280" y="550" type="line"/>
+ <point x="362" y="653"/>
+ <point x="490" y="720"/>
+ <point x="645" y="720" type="curve" smooth="yes"/>
+ <point x="824" y="720"/>
+ <point x="920" y="611"/>
+ <point x="920" y="435" type="curve" smooth="yes"/>
+ <point x="920" y="275"/>
+ <point x="806" y="150"/>
+ <point x="630" y="150" type="curve" smooth="yes"/>
+ <point x="409" y="150"/>
+ <point x="305" y="393"/>
+ <point x="305" y="645" type="curve" smooth="yes"/>
+ <point x="305" y="1132"/>
+ <point x="478" y="1310"/>
+ <point x="715" y="1310" type="curve" smooth="yes"/>
+ <point x="811" y="1310"/>
+ <point x="903" y="1286"/>
+ <point x="989" y="1200" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfbuildcomp.ufo/glyphs/D_igitT_hree.glif b/tests/reference/ufo/psfbuildcomp.ufo/glyphs/D_igitT_hree.glif
new file mode 100644
index 0000000..3242c12
--- /dev/null
+++ b/tests/reference/ufo/psfbuildcomp.ufo/glyphs/D_igitT_hree.glif
@@ -0,0 +1,52 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="DigitThree" format="2">
+ <advance width="1200"/>
+ <unicode hex="0033"/>
+ <anchor x="600" y="-100" name="L"/>
+ <anchor x="600" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="410" y="870" type="line"/>
+ <point x="410" y="700" type="line"/>
+ <point x="480" y="700" type="line"/>
+ <point x="716" y="700"/>
+ <point x="895" y="588"/>
+ <point x="895" y="425" type="curve" smooth="yes"/>
+ <point x="895" y="241"/>
+ <point x="718" y="150"/>
+ <point x="565" y="150" type="curve" smooth="yes"/>
+ <point x="385" y="150"/>
+ <point x="244" y="232"/>
+ <point x="135" y="355" type="curve"/>
+ <point x="110" y="140" type="line"/>
+ <point x="215" y="42"/>
+ <point x="368" y="-25"/>
+ <point x="545" y="-25" type="curve" smooth="yes"/>
+ <point x="834" y="-25"/>
+ <point x="1090" y="170"/>
+ <point x="1090" y="405" type="curve" smooth="yes"/>
+ <point x="1090" y="672"/>
+ <point x="862" y="776"/>
+ <point x="720" y="800" type="curve"/>
+ <point x="862" y="829"/>
+ <point x="1040" y="957"/>
+ <point x="1040" y="1140" type="curve" smooth="yes"/>
+ <point x="1040" y="1354"/>
+ <point x="828" y="1485"/>
+ <point x="580" y="1485" type="curve"/>
+ <point x="413" y="1485"/>
+ <point x="260" y="1416"/>
+ <point x="180" y="1325" type="curve"/>
+ <point x="215" y="1155" type="line"/>
+ <point x="328" y="1271"/>
+ <point x="436" y="1310"/>
+ <point x="590" y="1310" type="curve" smooth="yes"/>
+ <point x="711" y="1310"/>
+ <point x="850" y="1250"/>
+ <point x="850" y="1115" type="curve" smooth="yes"/>
+ <point x="850" y="991"/>
+ <point x="679" y="870"/>
+ <point x="480" y="870" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfbuildcomp.ufo/glyphs/D_igitT_wo.glif b/tests/reference/ufo/psfbuildcomp.ufo/glyphs/D_igitT_wo.glif
new file mode 100644
index 0000000..c179477
--- /dev/null
+++ b/tests/reference/ufo/psfbuildcomp.ufo/glyphs/D_igitT_wo.glif
@@ -0,0 +1,37 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="DigitTwo" format="2">
+ <advance width="1200"/>
+ <unicode hex="0032"/>
+ <anchor x="600" y="-100" name="L"/>
+ <anchor x="560" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="1080" y="180" type="line"/>
+ <point x="1000" y="166"/>
+ <point x="842" y="165"/>
+ <point x="645" y="165" type="curve" smooth="yes"/>
+ <point x="390" y="165" type="line"/>
+ <point x="609" y="352"/>
+ <point x="1010" y="729"/>
+ <point x="1010" y="1065" type="curve" smooth="yes"/>
+ <point x="1010" y="1323"/>
+ <point x="800" y="1485"/>
+ <point x="560" y="1485" type="curve" smooth="yes"/>
+ <point x="391" y="1485"/>
+ <point x="206" y="1402"/>
+ <point x="125" y="1290" type="curve"/>
+ <point x="170" y="1120" type="line"/>
+ <point x="259" y="1228"/>
+ <point x="402" y="1305"/>
+ <point x="525" y="1305" type="curve" smooth="yes"/>
+ <point x="668" y="1305"/>
+ <point x="810" y="1233"/>
+ <point x="810" y="1045" type="curve" smooth="yes"/>
+ <point x="810" y="768"/>
+ <point x="391" y="365"/>
+ <point x="120" y="170" type="curve"/>
+ <point x="120" y="0" type="line"/>
+ <point x="1080" y="0" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfbuildcomp.ufo/glyphs/D_igitZ_ero.glif b/tests/reference/ufo/psfbuildcomp.ufo/glyphs/D_igitZ_ero.glif
new file mode 100644
index 0000000..d976d0f
--- /dev/null
+++ b/tests/reference/ufo/psfbuildcomp.ufo/glyphs/D_igitZ_ero.glif
@@ -0,0 +1,37 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="DigitZero" format="2">
+ <advance width="1200"/>
+ <unicode hex="0030"/>
+ <anchor x="605" y="-100" name="L"/>
+ <anchor x="605" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="910" y="715" type="curve" smooth="yes"/>
+ <point x="910" y="308"/>
+ <point x="792" y="145"/>
+ <point x="600" y="145" type="curve" smooth="yes"/>
+ <point x="402" y="145"/>
+ <point x="290" y="305"/>
+ <point x="290" y="745" type="curve" smooth="yes"/>
+ <point x="290" y="1153"/>
+ <point x="407" y="1315"/>
+ <point x="600" y="1315" type="curve" smooth="yes"/>
+ <point x="802" y="1315"/>
+ <point x="910" y="1156"/>
+ </contour>
+ <contour>
+ <point x="1110" y="740" type="curve" smooth="yes"/>
+ <point x="1110" y="1286"/>
+ <point x="900" y="1485"/>
+ <point x="610" y="1485" type="curve" smooth="yes"/>
+ <point x="321" y="1485"/>
+ <point x="90" y="1283"/>
+ <point x="90" y="720" type="curve" smooth="yes"/>
+ <point x="90" y="155"/>
+ <point x="301" y="-25"/>
+ <point x="590" y="-25" type="curve" smooth="yes"/>
+ <point x="881" y="-25"/>
+ <point x="1110" y="151"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfbuildcomp.ufo/glyphs/D_ollarS_gn.glif b/tests/reference/ufo/psfbuildcomp.ufo/glyphs/D_ollarS_gn.glif
new file mode 100644
index 0000000..52136d8
--- /dev/null
+++ b/tests/reference/ufo/psfbuildcomp.ufo/glyphs/D_ollarS_gn.glif
@@ -0,0 +1,53 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="DollarSgn" format="2">
+ <advance width="1200"/>
+ <unicode hex="0024"/>
+ <outline>
+ <contour>
+ <point x="553" y="1600" type="line"/>
+ <point x="553" y="-220" type="line"/>
+ <point x="683" y="-220" type="line"/>
+ <point x="683" y="1600" type="line"/>
+ </contour>
+ <contour>
+ <point x="986" y="1306" type="line"/>
+ <point x="866" y="1364"/>
+ <point x="764" y="1389"/>
+ <point x="623" y="1389" type="curve" smooth="yes"/>
+ <point x="317" y="1389"/>
+ <point x="190" y="1173"/>
+ <point x="190" y="1017" type="curve" smooth="yes"/>
+ <point x="190" y="860"/>
+ <point x="253" y="739"/>
+ <point x="540" y="653" type="curve" smooth="yes"/>
+ <point x="827" y="567"/>
+ <point x="871" y="492"/>
+ <point x="871" y="396" type="curve" smooth="yes"/>
+ <point x="871" y="247"/>
+ <point x="734" y="161"/>
+ <point x="586" y="161" type="curve" smooth="yes"/>
+ <point x="450" y="161"/>
+ <point x="316" y="207"/>
+ <point x="195" y="313" type="curve"/>
+ <point x="153" y="124" type="line"/>
+ <point x="247" y="52"/>
+ <point x="408" y="0"/>
+ <point x="586" y="0" type="curve" smooth="yes"/>
+ <point x="837" y="0"/>
+ <point x="1046" y="167"/>
+ <point x="1046" y="414" type="curve" smooth="yes"/>
+ <point x="1046" y="613"/>
+ <point x="912" y="725"/>
+ <point x="669" y="796" type="curve" smooth="yes"/>
+ <point x="406" y="873"/>
+ <point x="365" y="929"/>
+ <point x="365" y="1030" type="curve" smooth="yes"/>
+ <point x="365" y="1132"/>
+ <point x="466" y="1228"/>
+ <point x="613" y="1228" type="curve" smooth="yes"/>
+ <point x="731" y="1228"/>
+ <point x="818" y="1200"/>
+ <point x="949" y="1127" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfbuildcomp.ufo/glyphs/D_ottedC_irc.glif b/tests/reference/ufo/psfbuildcomp.ufo/glyphs/D_ottedC_irc.glif
new file mode 100644
index 0000000..4cf5cb4
--- /dev/null
+++ b/tests/reference/ufo/psfbuildcomp.ufo/glyphs/D_ottedC_irc.glif
@@ -0,0 +1,235 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="DottedCirc" format="2">
+ <advance width="1106"/>
+ <unicode hex="25CC"/>
+ <anchor x="553" y="0" name="H"/>
+ <anchor x="553" y="-100" name="L"/>
+ <anchor x="810" y="0" name="O"/>
+ <anchor x="553" y="1000" name="U"/>
+ <outline>
+ <contour>
+ <point x="443" y="837" type="curve" smooth="yes"/>
+ <point x="443" y="864"/>
+ <point x="423" y="885"/>
+ <point x="398" y="885" type="curve" smooth="yes"/>
+ <point x="371" y="885"/>
+ <point x="348" y="861"/>
+ <point x="348" y="837" type="curve" smooth="yes"/>
+ <point x="348" y="809"/>
+ <point x="372" y="789"/>
+ <point x="398" y="789" type="curve" smooth="yes"/>
+ <point x="425" y="789"/>
+ <point x="443" y="812"/>
+ </contour>
+ <contour>
+ <point x="758" y="79" type="curve" smooth="yes"/>
+ <point x="758" y="106"/>
+ <point x="736" y="127"/>
+ <point x="710" y="127" type="curve" smooth="yes"/>
+ <point x="685" y="127"/>
+ <point x="662" y="103"/>
+ <point x="662" y="80" type="curve" smooth="yes"/>
+ <point x="662" y="52"/>
+ <point x="686" y="31"/>
+ <point x="710" y="31" type="curve" smooth="yes"/>
+ <point x="737" y="31"/>
+ <point x="758" y="55"/>
+ </contour>
+ <contour>
+ <point x="310" y="749" type="curve" smooth="yes"/>
+ <point x="310" y="775"/>
+ <point x="288" y="796"/>
+ <point x="263" y="796" type="curve" smooth="yes"/>
+ <point x="238" y="796"/>
+ <point x="215" y="774"/>
+ <point x="215" y="747" type="curve" smooth="yes"/>
+ <point x="215" y="722"/>
+ <point x="236" y="701"/>
+ <point x="263" y="701" type="curve" smooth="yes"/>
+ <point x="291" y="701"/>
+ <point x="310" y="720"/>
+ </contour>
+ <contour>
+ <point x="891" y="168" type="curve" smooth="yes"/>
+ <point x="891" y="197"/>
+ <point x="870" y="215"/>
+ <point x="843" y="215" type="curve" smooth="yes"/>
+ <point x="817" y="215"/>
+ <point x="795" y="194"/>
+ <point x="795" y="168" type="curve" smooth="yes"/>
+ <point x="795" y="143"/>
+ <point x="816" y="121"/>
+ <point x="843" y="121" type="curve" smooth="yes"/>
+ <point x="871" y="121"/>
+ <point x="891" y="143"/>
+ </contour>
+ <contour>
+ <point x="222" y="613" type="curve" smooth="yes"/>
+ <point x="222" y="640"/>
+ <point x="199" y="663"/>
+ <point x="173" y="663" type="curve" smooth="yes"/>
+ <point x="149" y="663"/>
+ <point x="126" y="642"/>
+ <point x="126" y="615" type="curve" smooth="yes"/>
+ <point x="126" y="591"/>
+ <point x="145" y="567"/>
+ <point x="173" y="567" type="curve" smooth="yes"/>
+ <point x="197" y="567"/>
+ <point x="222" y="587"/>
+ </contour>
+ <contour>
+ <point x="980" y="301" type="curve" smooth="yes"/>
+ <point x="980" y="327"/>
+ <point x="957" y="348"/>
+ <point x="932" y="348" type="curve" smooth="yes"/>
+ <point x="908" y="348"/>
+ <point x="884" y="332"/>
+ <point x="884" y="301" type="curve" smooth="yes"/>
+ <point x="884" y="277"/>
+ <point x="902" y="254"/>
+ <point x="932" y="254" type="curve" smooth="yes"/>
+ <point x="957" y="254"/>
+ <point x="980" y="274"/>
+ </contour>
+ <contour>
+ <point x="191" y="459" type="curve" smooth="yes"/>
+ <point x="191" y="484"/>
+ <point x="168" y="505"/>
+ <point x="143" y="505" type="curve" smooth="yes"/>
+ <point x="116" y="505"/>
+ <point x="95" y="484"/>
+ <point x="95" y="458" type="curve" smooth="yes"/>
+ <point x="95" y="433"/>
+ <point x="115" y="410"/>
+ <point x="143" y="410" type="curve" smooth="yes"/>
+ <point x="167" y="410"/>
+ <point x="191" y="432"/>
+ </contour>
+ <contour>
+ <point x="1011" y="458" type="curve" smooth="yes"/>
+ <point x="1011" y="484"/>
+ <point x="990" y="506"/>
+ <point x="964" y="506" type="curve" smooth="yes"/>
+ <point x="940" y="506"/>
+ <point x="915" y="484"/>
+ <point x="915" y="457" type="curve" smooth="yes"/>
+ <point x="915" y="433"/>
+ <point x="936" y="411"/>
+ <point x="964" y="411" type="curve" smooth="yes"/>
+ <point x="990" y="411"/>
+ <point x="1011" y="433"/>
+ </contour>
+ <contour>
+ <point x="222" y="302" type="curve" smooth="yes"/>
+ <point x="222" y="328"/>
+ <point x="200" y="348"/>
+ <point x="174" y="348" type="curve" smooth="yes"/>
+ <point x="147" y="348"/>
+ <point x="126" y="326"/>
+ <point x="126" y="302" type="curve" smooth="yes"/>
+ <point x="126" y="275"/>
+ <point x="149" y="253"/>
+ <point x="174" y="253" type="curve" smooth="yes"/>
+ <point x="201" y="253"/>
+ <point x="222" y="277"/>
+ </contour>
+ <contour>
+ <point x="980" y="615" type="curve" smooth="yes"/>
+ <point x="980" y="642"/>
+ <point x="955" y="663"/>
+ <point x="931" y="663" type="curve" smooth="yes"/>
+ <point x="904" y="663"/>
+ <point x="885" y="638"/>
+ <point x="885" y="614" type="curve" smooth="yes"/>
+ <point x="885" y="588"/>
+ <point x="907" y="567"/>
+ <point x="931" y="567" type="curve" smooth="yes"/>
+ <point x="959" y="567"/>
+ <point x="980" y="591"/>
+ </contour>
+ <contour>
+ <point x="310" y="168" type="curve" smooth="yes"/>
+ <point x="310" y="195"/>
+ <point x="291" y="215"/>
+ <point x="263" y="215" type="curve" smooth="yes"/>
+ <point x="238" y="215"/>
+ <point x="215" y="190"/>
+ <point x="215" y="168" type="curve" smooth="yes"/>
+ <point x="215" y="143"/>
+ <point x="238" y="120"/>
+ <point x="263" y="120" type="curve" smooth="yes"/>
+ <point x="289" y="120"/>
+ <point x="310" y="143"/>
+ </contour>
+ <contour>
+ <point x="890" y="748" type="curve" smooth="yes"/>
+ <point x="890" y="774"/>
+ <point x="870" y="796"/>
+ <point x="843" y="796" type="curve" smooth="yes"/>
+ <point x="815" y="796"/>
+ <point x="796" y="773"/>
+ <point x="796" y="748" type="curve" smooth="yes"/>
+ <point x="796" y="724"/>
+ <point x="817" y="700"/>
+ <point x="843" y="700" type="curve" smooth="yes"/>
+ <point x="869" y="700"/>
+ <point x="890" y="722"/>
+ </contour>
+ <contour>
+ <point x="444" y="78" type="curve" smooth="yes"/>
+ <point x="444" y="102"/>
+ <point x="423" y="126"/>
+ <point x="396" y="126" type="curve" smooth="yes"/>
+ <point x="370" y="126"/>
+ <point x="348" y="102"/>
+ <point x="348" y="78" type="curve" smooth="yes"/>
+ <point x="348" y="55"/>
+ <point x="370" y="31"/>
+ <point x="396" y="31" type="curve" smooth="yes"/>
+ <point x="420" y="31"/>
+ <point x="444" y="51"/>
+ </contour>
+ <contour>
+ <point x="758" y="836" type="curve" smooth="yes"/>
+ <point x="758" y="861"/>
+ <point x="737" y="885"/>
+ <point x="710" y="885" type="curve" smooth="yes"/>
+ <point x="684" y="885"/>
+ <point x="663" y="862"/>
+ <point x="663" y="838" type="curve" smooth="yes"/>
+ <point x="663" y="814"/>
+ <point x="683" y="789"/>
+ <point x="710" y="789" type="curve" smooth="yes"/>
+ <point x="734" y="789"/>
+ <point x="758" y="809"/>
+ </contour>
+ <contour>
+ <point x="601" y="47" type="curve" smooth="yes"/>
+ <point x="601" y="73"/>
+ <point x="579" y="95"/>
+ <point x="553" y="95" type="curve" smooth="yes"/>
+ <point x="527" y="95"/>
+ <point x="506" y="73"/>
+ <point x="506" y="47" type="curve" smooth="yes"/>
+ <point x="506" y="21"/>
+ <point x="527" y="0"/>
+ <point x="553" y="0" type="curve" smooth="yes"/>
+ <point x="579" y="0"/>
+ <point x="601" y="21"/>
+ </contour>
+ <contour>
+ <point x="601" y="868" type="curve" smooth="yes"/>
+ <point x="601" y="894"/>
+ <point x="579" y="916"/>
+ <point x="553" y="916" type="curve" smooth="yes"/>
+ <point x="527" y="916"/>
+ <point x="506" y="894"/>
+ <point x="506" y="868" type="curve" smooth="yes"/>
+ <point x="506" y="842"/>
+ <point x="527" y="821"/>
+ <point x="553" y="821" type="curve" smooth="yes"/>
+ <point x="579" y="821"/>
+ <point x="601" y="842"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfbuildcomp.ufo/glyphs/E_qS_gn.glif b/tests/reference/ufo/psfbuildcomp.ufo/glyphs/E_qS_gn.glif
new file mode 100644
index 0000000..1315ffa
--- /dev/null
+++ b/tests/reference/ufo/psfbuildcomp.ufo/glyphs/E_qS_gn.glif
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="EqSgn" format="2">
+ <advance width="1200"/>
+ <unicode hex="003D"/>
+ <outline>
+ <contour>
+ <point x="120" y="480" type="line"/>
+ <point x="1080" y="480" type="line"/>
+ <point x="1080" y="630" type="line"/>
+ <point x="120" y="630" type="line"/>
+ </contour>
+ <contour>
+ <point x="120" y="830" type="line"/>
+ <point x="1080" y="830" type="line"/>
+ <point x="1080" y="980" type="line"/>
+ <point x="120" y="980" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfbuildcomp.ufo/glyphs/E_xclamationM_rk.glif b/tests/reference/ufo/psfbuildcomp.ufo/glyphs/E_xclamationM_rk.glif
new file mode 100644
index 0000000..e683644
--- /dev/null
+++ b/tests/reference/ufo/psfbuildcomp.ufo/glyphs/E_xclamationM_rk.glif
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="ExclamationMrk" format="2">
+ <advance width="764"/>
+ <unicode hex="0021"/>
+ <outline>
+ <contour>
+ <point x="450" y="440" type="line"/>
+ <point x="456" y="730"/>
+ <point x="451" y="1076"/>
+ <point x="490" y="1510" type="curve"/>
+ <point x="235" y="1510" type="line"/>
+ <point x="273" y="1076"/>
+ <point x="268" y="730"/>
+ <point x="275" y="440" type="curve"/>
+ </contour>
+ <contour>
+ <point x="225" y="110" type="curve" smooth="yes"/>
+ <point x="225" y="36"/>
+ <point x="286" y="-25"/>
+ <point x="360" y="-25" type="curve" smooth="yes"/>
+ <point x="434" y="-25"/>
+ <point x="495" y="36"/>
+ <point x="495" y="110" type="curve" smooth="yes"/>
+ <point x="495" y="184"/>
+ <point x="434" y="245"/>
+ <point x="360" y="245" type="curve" smooth="yes"/>
+ <point x="286" y="245"/>
+ <point x="225" y="184"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfbuildcomp.ufo/glyphs/F_ullS_top.glif b/tests/reference/ufo/psfbuildcomp.ufo/glyphs/F_ullS_top.glif
new file mode 100644
index 0000000..9f3a3f0
--- /dev/null
+++ b/tests/reference/ufo/psfbuildcomp.ufo/glyphs/F_ullS_top.glif
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="FullStop" format="2">
+ <advance width="640"/>
+ <unicode hex="002E"/>
+ <outline>
+ <contour>
+ <point x="185" y="110" type="curve" smooth="yes"/>
+ <point x="185" y="36"/>
+ <point x="246" y="-25"/>
+ <point x="320" y="-25" type="curve" smooth="yes"/>
+ <point x="394" y="-25"/>
+ <point x="455" y="36"/>
+ <point x="455" y="110" type="curve" smooth="yes"/>
+ <point x="455" y="184"/>
+ <point x="394" y="245"/>
+ <point x="320" y="245" type="curve" smooth="yes"/>
+ <point x="246" y="245"/>
+ <point x="185" y="184"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfbuildcomp.ufo/glyphs/G_T_S_gn.glif b/tests/reference/ufo/psfbuildcomp.ufo/glyphs/G_T_S_gn.glif
new file mode 100644
index 0000000..c591997
--- /dev/null
+++ b/tests/reference/ufo/psfbuildcomp.ufo/glyphs/G_T_S_gn.glif
@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="GTSgn" format="2">
+ <advance width="1200"/>
+ <unicode hex="003E"/>
+ <outline>
+ <contour>
+ <point x="120" y="1035" type="line"/>
+ <point x="910" y="730" type="line"/>
+ <point x="120" y="425" type="line"/>
+ <point x="120" y="245" type="line"/>
+ <point x="1100" y="645" type="line"/>
+ <point x="1100" y="815" type="line"/>
+ <point x="120" y="1215" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfbuildcomp.ufo/glyphs/G_raveA_ccent.glif b/tests/reference/ufo/psfbuildcomp.ufo/glyphs/G_raveA_ccent.glif
new file mode 100644
index 0000000..a0a0004
--- /dev/null
+++ b/tests/reference/ufo/psfbuildcomp.ufo/glyphs/G_raveA_ccent.glif
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="GraveAccent" format="2">
+ <advance width="580"/>
+ <unicode hex="0060"/>
+ <outline>
+ <component base="CombGrave" xOffset="940"/>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfbuildcomp.ufo/glyphs/H_yphen.glif b/tests/reference/ufo/psfbuildcomp.ufo/glyphs/H_yphen.glif
new file mode 100644
index 0000000..fabf6ce
--- /dev/null
+++ b/tests/reference/ufo/psfbuildcomp.ufo/glyphs/H_yphen.glif
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="Hyphen" format="2">
+ <advance width="860"/>
+ <unicode hex="2010"/>
+ <anchor x="430" y="1100" name="U"/>
+ <outline>
+ <contour>
+ <point x="80" y="555" type="line"/>
+ <point x="780" y="555" type="line"/>
+ <point x="780" y="705" type="line"/>
+ <point x="80" y="705" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfbuildcomp.ufo/glyphs/H_yphenM_inus.glif b/tests/reference/ufo/psfbuildcomp.ufo/glyphs/H_yphenM_inus.glif
new file mode 100644
index 0000000..bc3f4eb
--- /dev/null
+++ b/tests/reference/ufo/psfbuildcomp.ufo/glyphs/H_yphenM_inus.glif
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="HyphenMinus" format="2">
+ <advance width="860"/>
+ <unicode hex="002D"/>
+ <anchor x="430" y="1100" name="U"/>
+ <outline>
+ <contour>
+ <point x="80" y="555" type="line"/>
+ <point x="780" y="555" type="line"/>
+ <point x="780" y="705" type="line"/>
+ <point x="80" y="705" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfbuildcomp.ufo/glyphs/H_yphen_S_oft.glif b/tests/reference/ufo/psfbuildcomp.ufo/glyphs/H_yphen_S_oft.glif
new file mode 100644
index 0000000..293b653
--- /dev/null
+++ b/tests/reference/ufo/psfbuildcomp.ufo/glyphs/H_yphen_S_oft.glif
@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="Hyphen_Soft" format="2">
+ <advance width="860"/>
+ <unicode hex="00AD"/>
+ <anchor x="430" y="1100" name="U"/>
+ <outline>
+ <component base="HyphenMinus"/>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfbuildcomp.ufo/glyphs/L_T_S_gn.glif b/tests/reference/ufo/psfbuildcomp.ufo/glyphs/L_T_S_gn.glif
new file mode 100644
index 0000000..db9ae78
--- /dev/null
+++ b/tests/reference/ufo/psfbuildcomp.ufo/glyphs/L_T_S_gn.glif
@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LTSgn" format="2">
+ <advance width="1200"/>
+ <unicode hex="003C"/>
+ <outline>
+ <contour>
+ <point x="1080" y="425" type="line"/>
+ <point x="290" y="730" type="line"/>
+ <point x="1080" y="1035" type="line"/>
+ <point x="1080" y="1215" type="line"/>
+ <point x="100" y="815" type="line"/>
+ <point x="100" y="645" type="line"/>
+ <point x="1080" y="245" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfbuildcomp.ufo/glyphs/L_ftC_urlyB_rac.glif b/tests/reference/ufo/psfbuildcomp.ufo/glyphs/L_ftC_urlyB_rac.glif
new file mode 100644
index 0000000..bc7ef03
--- /dev/null
+++ b/tests/reference/ufo/psfbuildcomp.ufo/glyphs/L_ftC_urlyB_rac.glif
@@ -0,0 +1,47 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LftCurlyBrac" format="2">
+ <advance width="1000"/>
+ <unicode hex="007B"/>
+ <outline>
+ <contour>
+ <point x="210" y="615" type="curve" smooth="yes"/>
+ <point x="210" y="583"/>
+ <point x="383" y="486"/>
+ <point x="410" y="450" type="curve" smooth="yes"/>
+ <point x="434" y="418"/>
+ <point x="424" y="-205"/>
+ <point x="495" y="-285" type="curve" smooth="yes"/>
+ <point x="535" y="-330"/>
+ <point x="696" y="-383"/>
+ <point x="800" y="-410" type="curve"/>
+ <point x="840" y="-270" type="line"/>
+ <point x="773" y="-247"/>
+ <point x="650" y="-198"/>
+ <point x="630" y="-170" type="curve" smooth="yes"/>
+ <point x="597" y="-123"/>
+ <point x="610" y="447"/>
+ <point x="590" y="485" type="curve" smooth="yes"/>
+ <point x="571" y="521"/>
+ <point x="434" y="593"/>
+ <point x="430" y="615" type="curve"/>
+ <point x="434" y="637"/>
+ <point x="571" y="709"/>
+ <point x="590" y="745" type="curve" smooth="yes"/>
+ <point x="610" y="783"/>
+ <point x="597" y="1353"/>
+ <point x="630" y="1400" type="curve" smooth="yes"/>
+ <point x="650" y="1428"/>
+ <point x="773" y="1477"/>
+ <point x="840" y="1500" type="curve"/>
+ <point x="800" y="1640" type="line"/>
+ <point x="696" y="1613"/>
+ <point x="535" y="1560"/>
+ <point x="495" y="1515" type="curve" smooth="yes"/>
+ <point x="424" y="1435"/>
+ <point x="434" y="812"/>
+ <point x="410" y="780" type="curve" smooth="yes"/>
+ <point x="383" y="744"/>
+ <point x="210" y="647"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfbuildcomp.ufo/glyphs/L_ftP_aren.glif b/tests/reference/ufo/psfbuildcomp.ufo/glyphs/L_ftP_aren.glif
new file mode 100644
index 0000000..a4b9814
--- /dev/null
+++ b/tests/reference/ufo/psfbuildcomp.ufo/glyphs/L_ftP_aren.glif
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LftParen" format="2">
+ <advance width="795"/>
+ <unicode hex="0028"/>
+ <outline>
+ <contour>
+ <point x="115" y="625" type="curve" smooth="yes"/>
+ <point x="115" y="218"/>
+ <point x="260" y="-125"/>
+ <point x="535" y="-410" type="curve"/>
+ <point x="630" y="-265" type="line"/>
+ <point x="395" y="-8"/>
+ <point x="305" y="278"/>
+ <point x="305" y="625" type="curve" smooth="yes"/>
+ <point x="305" y="982"/>
+ <point x="395" y="1280"/>
+ <point x="630" y="1485" type="curve"/>
+ <point x="555" y="1640" type="line"/>
+ <point x="290" y="1444"/>
+ <point x="115" y="1062"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfbuildcomp.ufo/glyphs/L_ftS_qrB_rac.glif b/tests/reference/ufo/psfbuildcomp.ufo/glyphs/L_ftS_qrB_rac.glif
new file mode 100644
index 0000000..e97ed98
--- /dev/null
+++ b/tests/reference/ufo/psfbuildcomp.ufo/glyphs/L_ftS_qrB_rac.glif
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LftSqrBrac" format="2">
+ <advance width="790"/>
+ <unicode hex="005B"/>
+ <outline>
+ <contour>
+ <point x="640" y="-410" type="line"/>
+ <point x="640" y="-260" type="line"/>
+ <point x="385" y="-260" type="line"/>
+ <point x="385" y="1450" type="line"/>
+ <point x="640" y="1450" type="line"/>
+ <point x="640" y="1600" type="line"/>
+ <point x="200" y="1600" type="line"/>
+ <point x="200" y="-410" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfbuildcomp.ufo/glyphs/L_owL_ine.glif b/tests/reference/ufo/psfbuildcomp.ufo/glyphs/L_owL_ine.glif
new file mode 100644
index 0000000..2fc71eb
--- /dev/null
+++ b/tests/reference/ufo/psfbuildcomp.ufo/glyphs/L_owL_ine.glif
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LowLine" format="2">
+ <advance width="1274"/>
+ <unicode hex="005F"/>
+ <outline>
+ <contour>
+ <point x="0" y="-320" type="line"/>
+ <point x="1274" y="-320" type="line"/>
+ <point x="1274" y="-170" type="line"/>
+ <point x="0" y="-170" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfbuildcomp.ufo/glyphs/L_tnC_apA_.alt.glif b/tests/reference/ufo/psfbuildcomp.ufo/glyphs/L_tnC_apA_.alt.glif
new file mode 100644
index 0000000..fbdfff2
--- /dev/null
+++ b/tests/reference/ufo/psfbuildcomp.ufo/glyphs/L_tnC_apA_.alt.glif
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnCapA.alt" format="2">
+ <advance width="1395"/>
+ <anchor x="668" y="1460" name="H"/>
+ <anchor x="688" y="1560" name="L"/>
+ <anchor x="-75" y="1460" name="O"/>
+ <anchor x="688" y="-70" name="U"/>
+ <outline>
+ <contour>
+ <point x="1130" y="1460" type="line"/>
+ <point x="996" y="1075" type="line"/>
+ <point x="381" y="1075" type="line"/>
+ <point x="245" y="1460" type="line"/>
+ <point x="40" y="1460" type="line"/>
+ <point x="75" y="1380"/>
+ <point x="113" y="1291"/>
+ <point x="180" y="1105" type="curve" smooth="yes"/>
+ <point x="580" y="0" type="line"/>
+ <point x="795" y="0" type="line"/>
+ <point x="1195" y="1105" type="line" smooth="yes"/>
+ <point x="1263" y="1292"/>
+ <point x="1299" y="1379"/>
+ <point x="1335" y="1460" type="curve"/>
+ </contour>
+ <contour>
+ <point x="435" y="920" type="line"/>
+ <point x="942" y="920" type="line"/>
+ <point x="690" y="195" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfbuildcomp.ufo/glyphs/L_tnC_apA_.glif b/tests/reference/ufo/psfbuildcomp.ufo/glyphs/L_tnC_apA_.glif
new file mode 100644
index 0000000..3c64e18
--- /dev/null
+++ b/tests/reference/ufo/psfbuildcomp.ufo/glyphs/L_tnC_apA_.glif
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnCapA" format="2">
+ <advance width="1395"/>
+ <unicode hex="0041"/>
+ <anchor x="707" y="0" name="H"/>
+ <anchor x="687" y="-100" name="L"/>
+ <anchor x="1450" y="0" name="O"/>
+ <anchor x="687" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="245" y="0" type="line"/>
+ <point x="379" y="385" type="line"/>
+ <point x="994" y="385" type="line"/>
+ <point x="1130" y="0" type="line"/>
+ <point x="1335" y="0" type="line"/>
+ <point x="1300" y="80"/>
+ <point x="1262" y="169"/>
+ <point x="1195" y="355" type="curve" smooth="yes"/>
+ <point x="795" y="1460" type="line"/>
+ <point x="580" y="1460" type="line"/>
+ <point x="180" y="355" type="line" smooth="yes"/>
+ <point x="112" y="168"/>
+ <point x="76" y="81"/>
+ <point x="40" y="0" type="curve"/>
+ </contour>
+ <contour>
+ <point x="940" y="540" type="line"/>
+ <point x="433" y="540" type="line"/>
+ <point x="685" y="1265" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfbuildcomp.ufo/glyphs/L_tnC_apA_D_iaer.glif b/tests/reference/ufo/psfbuildcomp.ufo/glyphs/L_tnC_apA_D_iaer.glif
new file mode 100644
index 0000000..b74cc60
--- /dev/null
+++ b/tests/reference/ufo/psfbuildcomp.ufo/glyphs/L_tnC_apA_D_iaer.glif
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnCapADiaer" format="2">
+ <advance width="1395"/>
+ <unicode hex="00C4"/>
+ <anchor x="707" y="0" name="H"/>
+ <anchor x="687" y="-100" name="L"/>
+ <anchor x="1450" y="0" name="O"/>
+ <anchor x="687" y="1935" name="U"/>
+ <outline>
+ <component base="LtnCapA"/>
+ <component base="CombDiaer" xOffset="1257" yOffset="430"/>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfbuildcomp.ufo/glyphs/L_tnC_apB_.glif b/tests/reference/ufo/psfbuildcomp.ufo/glyphs/L_tnC_apB_.glif
new file mode 100644
index 0000000..415122e
--- /dev/null
+++ b/tests/reference/ufo/psfbuildcomp.ufo/glyphs/L_tnC_apB_.glif
@@ -0,0 +1,62 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnCapB" format="2">
+ <advance width="1285"/>
+ <unicode hex="0042"/>
+ <anchor x="615" y="-100" name="L"/>
+ <anchor x="615" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="365" y="1310" type="line"/>
+ <point x="407" y="1312"/>
+ <point x="512" y="1315"/>
+ <point x="590" y="1315" type="curve" smooth="yes"/>
+ <point x="791" y="1315"/>
+ <point x="870" y="1239"/>
+ <point x="870" y="1090" type="curve" smooth="yes"/>
+ <point x="870" y="951"/>
+ <point x="774" y="855"/>
+ <point x="560" y="855" type="curve" smooth="yes"/>
+ <point x="365" y="855" type="line"/>
+ </contour>
+ <contour>
+ <point x="175" y="455" type="line"/>
+ <point x="175" y="257"/>
+ <point x="175" y="80"/>
+ <point x="160" y="0" type="curve"/>
+ <point x="213" y="-5"/>
+ <point x="402" y="-10"/>
+ <point x="605" y="-10" type="curve" smooth="yes"/>
+ <point x="988" y="-10"/>
+ <point x="1140" y="177"/>
+ <point x="1140" y="420" type="curve" smooth="yes"/>
+ <point x="1140" y="669"/>
+ <point x="974" y="759"/>
+ <point x="820" y="800" type="curve"/>
+ <point x="956" y="852"/>
+ <point x="1065" y="952"/>
+ <point x="1065" y="1120" type="curve" smooth="yes"/>
+ <point x="1065" y="1381"/>
+ <point x="897" y="1470"/>
+ <point x="600" y="1470" type="curve" smooth="yes"/>
+ <point x="431" y="1470"/>
+ <point x="248" y="1466"/>
+ <point x="160" y="1460" type="curve"/>
+ <point x="175" y="1380"/>
+ <point x="175" y="1196"/>
+ <point x="175" y="1000" type="curve" smooth="yes"/>
+ </contour>
+ <contour>
+ <point x="365" y="700" type="line"/>
+ <point x="600" y="700" type="line" smooth="yes"/>
+ <point x="833" y="700"/>
+ <point x="945" y="604"/>
+ <point x="945" y="420" type="curve" smooth="yes"/>
+ <point x="945" y="212"/>
+ <point x="781" y="150"/>
+ <point x="610" y="150" type="curve" smooth="yes"/>
+ <point x="498" y="150"/>
+ <point x="402" y="153"/>
+ <point x="365" y="155" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfbuildcomp.ufo/glyphs/L_tnC_apC_.glif b/tests/reference/ufo/psfbuildcomp.ufo/glyphs/L_tnC_apC_.glif
new file mode 100644
index 0000000..daf4f2d
--- /dev/null
+++ b/tests/reference/ufo/psfbuildcomp.ufo/glyphs/L_tnC_apC_.glif
@@ -0,0 +1,38 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnCapC" format="2">
+ <advance width="1355"/>
+ <unicode hex="0043"/>
+ <anchor x="750" y="0" name="H"/>
+ <anchor x="750" y="-100" name="L"/>
+ <anchor x="750" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="1190" y="335" type="line"/>
+ <point x="1078" y="223"/>
+ <point x="912" y="150"/>
+ <point x="760" y="150" type="curve" smooth="yes"/>
+ <point x="489" y="150"/>
+ <point x="290" y="376"/>
+ <point x="290" y="735" type="curve" smooth="yes"/>
+ <point x="290" y="1119"/>
+ <point x="491" y="1315"/>
+ <point x="770" y="1315" type="curve" smooth="yes"/>
+ <point x="891" y="1315"/>
+ <point x="1030" y="1278"/>
+ <point x="1155" y="1165" type="curve"/>
+ <point x="1215" y="1345" type="line"/>
+ <point x="1072" y="1452"/>
+ <point x="913" y="1485"/>
+ <point x="770" y="1485" type="curve" smooth="yes"/>
+ <point x="418" y="1485"/>
+ <point x="95" y="1225"/>
+ <point x="95" y="710" type="curve" smooth="yes"/>
+ <point x="95" y="260"/>
+ <point x="346" y="-25"/>
+ <point x="750" y="-25" type="curve" smooth="yes"/>
+ <point x="902" y="-25"/>
+ <point x="1114" y="32"/>
+ <point x="1230" y="140" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfbuildcomp.ufo/glyphs/L_tnC_apC_A_cute.glif b/tests/reference/ufo/psfbuildcomp.ufo/glyphs/L_tnC_apC_A_cute.glif
new file mode 100644
index 0000000..c997cca
--- /dev/null
+++ b/tests/reference/ufo/psfbuildcomp.ufo/glyphs/L_tnC_apC_A_cute.glif
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnCapCAcute" format="2">
+ <advance width="1020"/>
+ <unicode hex="0106"/>
+ <anchor x="580" y="0" name="H"/>
+ <anchor x="580" y="-100" name="L"/>
+ <anchor x="1020" y="1000" name="R"/>
+ <anchor x="570" y="1635" name="U"/>
+ <outline>
+ <component base="LtnSmC"/>
+ <component base="CombAcute" xOffset="1140"/>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfbuildcomp.ufo/glyphs/L_tnC_apC_A_cuteC_edilla.glif b/tests/reference/ufo/psfbuildcomp.ufo/glyphs/L_tnC_apC_A_cuteC_edilla.glif
new file mode 100644
index 0000000..9c993a9
--- /dev/null
+++ b/tests/reference/ufo/psfbuildcomp.ufo/glyphs/L_tnC_apC_A_cuteC_edilla.glif
@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnCapCAcuteCedilla" format="2">
+ <advance width="1355"/>
+ <unicode hex="1E08"/>
+ <anchor x="750" y="0" name="H"/>
+ <anchor x="750" y="-100" name="L"/>
+ <anchor x="750" y="2065" name="U"/>
+ <outline>
+ <component base="LtnCapC"/>
+ <component base="CombAcute" xOffset="1320" yOffset="430"/>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfbuildcomp.ufo/glyphs/L_tnC_apC_C_ircum.glif b/tests/reference/ufo/psfbuildcomp.ufo/glyphs/L_tnC_apC_C_ircum.glif
new file mode 100644
index 0000000..0291e5d
--- /dev/null
+++ b/tests/reference/ufo/psfbuildcomp.ufo/glyphs/L_tnC_apC_C_ircum.glif
@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnCapCCircum" format="2">
+ <advance width="1355"/>
+ <unicode hex="0108"/>
+ <anchor x="750" y="0" name="H"/>
+ <anchor x="750" y="-100" name="L"/>
+ <anchor x="750" y="2065" name="U"/>
+ <outline>
+ <component base="LtnCapC"/>
+ <component base="CombCircum" xOffset="1320" yOffset="430"/>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfbuildcomp.ufo/glyphs/L_tnC_apD_.glif b/tests/reference/ufo/psfbuildcomp.ufo/glyphs/L_tnC_apD_.glif
new file mode 100644
index 0000000..9154a06
--- /dev/null
+++ b/tests/reference/ufo/psfbuildcomp.ufo/glyphs/L_tnC_apD_.glif
@@ -0,0 +1,45 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnCapD" format="2">
+ <advance width="1435"/>
+ <unicode hex="0044"/>
+ <anchor x="715" y="-100" name="L"/>
+ <anchor x="715" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="175" y="455" type="line"/>
+ <point x="174" y="257"/>
+ <point x="175" y="80"/>
+ <point x="160" y="0" type="curve"/>
+ <point x="160" y="0"/>
+ <point x="467" y="-10"/>
+ <point x="595" y="-10" type="curve" smooth="yes"/>
+ <point x="888" y="-10"/>
+ <point x="1315" y="145"/>
+ <point x="1315" y="740" type="curve" smooth="yes"/>
+ <point x="1315" y="1394"/>
+ <point x="829" y="1470"/>
+ <point x="615" y="1470" type="curve" smooth="yes"/>
+ <point x="480" y="1470"/>
+ <point x="245" y="1466"/>
+ <point x="160" y="1460" type="curve"/>
+ <point x="175" y="1380"/>
+ <point x="175" y="1196"/>
+ <point x="175" y="1000" type="curve" smooth="yes"/>
+ </contour>
+ <contour>
+ <point x="365" y="1305" type="line"/>
+ <point x="415" y="1307"/>
+ <point x="524" y="1310"/>
+ <point x="590" y="1310" type="curve" smooth="yes"/>
+ <point x="878" y="1310"/>
+ <point x="1120" y="1167"/>
+ <point x="1120" y="720" type="curve" smooth="yes"/>
+ <point x="1120" y="308"/>
+ <point x="853" y="155"/>
+ <point x="585" y="155" type="curve" smooth="yes"/>
+ <point x="490" y="155"/>
+ <point x="412" y="161"/>
+ <point x="365" y="165" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfbuildcomp.ufo/glyphs/L_tnC_apE_.glif b/tests/reference/ufo/psfbuildcomp.ufo/glyphs/L_tnC_apE_.glif
new file mode 100644
index 0000000..e5d0043
--- /dev/null
+++ b/tests/reference/ufo/psfbuildcomp.ufo/glyphs/L_tnC_apE_.glif
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnCapE" format="2">
+ <advance width="1160"/>
+ <unicode hex="0045"/>
+ <anchor x="600" y="0" name="H"/>
+ <anchor x="600" y="-100" name="L"/>
+ <anchor x="917" y="0" name="O"/>
+ <anchor x="1160" y="1200" name="R"/>
+ <anchor x="600" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="365" y="845" type="line"/>
+ <point x="365" y="1295" type="line"/>
+ <point x="1010" y="1295" type="line"/>
+ <point x="1010" y="1460" type="line"/>
+ <point x="160" y="1460" type="line"/>
+ <point x="175" y="1380"/>
+ <point x="175" y="1222"/>
+ <point x="175" y="1025" type="curve" smooth="yes"/>
+ <point x="175" y="435" type="line" smooth="yes"/>
+ <point x="175" y="238"/>
+ <point x="175" y="80"/>
+ <point x="160" y="0" type="curve"/>
+ <point x="1040" y="0" type="line"/>
+ <point x="1040" y="180" type="line"/>
+ <point x="960" y="166"/>
+ <point x="826" y="165"/>
+ <point x="629" y="165" type="curve" smooth="yes"/>
+ <point x="365" y="165" type="line"/>
+ <point x="365" y="685" type="line"/>
+ <point x="935" y="685" type="line"/>
+ <point x="935" y="845" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfbuildcomp.ufo/glyphs/L_tnC_apF_.glif b/tests/reference/ufo/psfbuildcomp.ufo/glyphs/L_tnC_apF_.glif
new file mode 100644
index 0000000..deb38fb
--- /dev/null
+++ b/tests/reference/ufo/psfbuildcomp.ufo/glyphs/L_tnC_apF_.glif
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnCapF" format="2">
+ <advance width="1150"/>
+ <unicode hex="0046"/>
+ <anchor x="595" y="-100" name="L"/>
+ <anchor x="595" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="365" y="835" type="line"/>
+ <point x="365" y="1295" type="line"/>
+ <point x="1030" y="1295" type="line"/>
+ <point x="1030" y="1460" type="line"/>
+ <point x="160" y="1460" type="line"/>
+ <point x="175" y="1380"/>
+ <point x="175" y="1217"/>
+ <point x="175" y="1020" type="curve" smooth="yes"/>
+ <point x="175" y="435" type="line" smooth="yes"/>
+ <point x="175" y="238"/>
+ <point x="175" y="80"/>
+ <point x="160" y="0" type="curve"/>
+ <point x="380" y="0" type="line"/>
+ <point x="365" y="78"/>
+ <point x="365" y="237"/>
+ <point x="365" y="435" type="curve" smooth="yes"/>
+ <point x="365" y="675" type="line"/>
+ <point x="945" y="675" type="line"/>
+ <point x="945" y="835" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfbuildcomp.ufo/glyphs/L_tnC_apG_.glif b/tests/reference/ufo/psfbuildcomp.ufo/glyphs/L_tnC_apG_.glif
new file mode 100644
index 0000000..477d223
--- /dev/null
+++ b/tests/reference/ufo/psfbuildcomp.ufo/glyphs/L_tnC_apG_.glif
@@ -0,0 +1,42 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnCapG" format="2">
+ <advance width="1420"/>
+ <unicode hex="0047"/>
+ <anchor x="745" y="0" name="H"/>
+ <anchor x="745" y="-100" name="L"/>
+ <anchor x="745" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="1275" y="745" type="line"/>
+ <point x="735" y="745" type="line"/>
+ <point x="735" y="580" type="line"/>
+ <point x="1085" y="580" type="line"/>
+ <point x="1085" y="245" type="line"/>
+ <point x="963" y="171"/>
+ <point x="876" y="150"/>
+ <point x="757" y="150" type="curve" smooth="yes"/>
+ <point x="471" y="150"/>
+ <point x="290" y="377"/>
+ <point x="290" y="745" type="curve" smooth="yes"/>
+ <point x="290" y="1094"/>
+ <point x="480" y="1315"/>
+ <point x="785" y="1315" type="curve" smooth="yes"/>
+ <point x="918" y="1315"/>
+ <point x="1046" y="1286"/>
+ <point x="1195" y="1165" type="curve"/>
+ <point x="1260" y="1345" type="line"/>
+ <point x="1085" y="1462"/>
+ <point x="947" y="1485"/>
+ <point x="785" y="1485" type="curve" smooth="yes"/>
+ <point x="402" y="1485"/>
+ <point x="95" y="1199"/>
+ <point x="95" y="720" type="curve" smooth="yes"/>
+ <point x="95" y="241"/>
+ <point x="367" y="-25"/>
+ <point x="745" y="-25" type="curve" smooth="yes"/>
+ <point x="918" y="-25"/>
+ <point x="1070" y="11"/>
+ <point x="1275" y="155" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfbuildcomp.ufo/glyphs/L_tnC_apH_.glif b/tests/reference/ufo/psfbuildcomp.ufo/glyphs/L_tnC_apH_.glif
new file mode 100644
index 0000000..5924270
--- /dev/null
+++ b/tests/reference/ufo/psfbuildcomp.ufo/glyphs/L_tnC_apH_.glif
@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnCapH" format="2">
+ <advance width="1475"/>
+ <unicode hex="0048"/>
+ <anchor x="285" y="0" name="H"/>
+ <anchor x="725" y="-100" name="L"/>
+ <anchor x="725" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="1290" y="0" type="line"/>
+ <point x="1275" y="80"/>
+ <point x="1275" y="238"/>
+ <point x="1275" y="435" type="curve" smooth="yes"/>
+ <point x="1275" y="1025" type="line" smooth="yes"/>
+ <point x="1275" y="1222"/>
+ <point x="1275" y="1380"/>
+ <point x="1290" y="1460" type="curve"/>
+ <point x="1085" y="1460" type="line"/>
+ <point x="1085" y="835" type="line"/>
+ <point x="365" y="835" type="line"/>
+ <point x="365" y="1460" type="line"/>
+ <point x="160" y="1460" type="line"/>
+ <point x="175" y="1380"/>
+ <point x="175" y="1222"/>
+ <point x="175" y="1025" type="curve" smooth="yes"/>
+ <point x="175" y="435" type="line" smooth="yes"/>
+ <point x="175" y="238"/>
+ <point x="175" y="80"/>
+ <point x="160" y="0" type="curve"/>
+ <point x="365" y="0" type="line"/>
+ <point x="365" y="675" type="line"/>
+ <point x="1085" y="675" type="line"/>
+ <point x="1085" y="0" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfbuildcomp.ufo/glyphs/L_tnC_apI_.glif b/tests/reference/ufo/psfbuildcomp.ufo/glyphs/L_tnC_apI_.glif
new file mode 100644
index 0000000..c6001c3
--- /dev/null
+++ b/tests/reference/ufo/psfbuildcomp.ufo/glyphs/L_tnC_apI_.glif
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnCapI" format="2">
+ <advance width="975"/>
+ <unicode hex="0049"/>
+ <anchor x="477" y="0" name="H"/>
+ <anchor x="477" y="-100" name="L"/>
+ <anchor x="673" y="0" name="O"/>
+ <anchor x="975" y="1200" name="R"/>
+ <anchor x="477" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="140" y="1460" type="line"/>
+ <point x="140" y="1315" type="line"/>
+ <point x="380" y="1315" type="line"/>
+ <point x="380" y="145" type="line"/>
+ <point x="140" y="145" type="line"/>
+ <point x="140" y="0" type="line"/>
+ <point x="815" y="0" type="line"/>
+ <point x="815" y="145" type="line"/>
+ <point x="570" y="145" type="line"/>
+ <point x="570" y="1315" type="line"/>
+ <point x="815" y="1315" type="line"/>
+ <point x="815" y="1460" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfbuildcomp.ufo/glyphs/L_tnC_apI_J_.glif b/tests/reference/ufo/psfbuildcomp.ufo/glyphs/L_tnC_apI_J_.glif
new file mode 100644
index 0000000..35cb406
--- /dev/null
+++ b/tests/reference/ufo/psfbuildcomp.ufo/glyphs/L_tnC_apI_J_.glif
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnCapIJ" format="2">
+ <advance width="1940"/>
+ <unicode hex="0132"/>
+ <anchor x="477" y="0" name="H"/>
+ <anchor x="1385" y="-100" name="L"/>
+ <anchor x="673" y="0" name="O"/>
+ <anchor x="975" y="1200" name="R"/>
+ <anchor x="1650" y="1530" name="U"/>
+ <outline>
+ <component base="LtnCapI"/>
+ <component base="LtnCapJ" xOffset="975"/>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfbuildcomp.ufo/glyphs/L_tnC_apJ_.glif b/tests/reference/ufo/psfbuildcomp.ufo/glyphs/L_tnC_apJ_.glif
new file mode 100644
index 0000000..457e39d
--- /dev/null
+++ b/tests/reference/ufo/psfbuildcomp.ufo/glyphs/L_tnC_apJ_.glif
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnCapJ" format="2">
+ <advance width="965"/>
+ <unicode hex="004A"/>
+ <anchor x="410" y="-100" name="L"/>
+ <anchor x="675" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="575" y="1460" type="line"/>
+ <point x="588" y="1354"/>
+ <point x="590" y="1175"/>
+ <point x="590" y="980" type="curve"/>
+ <point x="590" y="485" type="line" smooth="yes"/>
+ <point x="590" y="256"/>
+ <point x="487" y="155"/>
+ <point x="340" y="155" type="curve" smooth="yes"/>
+ <point x="248" y="155"/>
+ <point x="147" y="198"/>
+ <point x="80" y="275" type="curve"/>
+ <point x="35" y="90" type="line"/>
+ <point x="106" y="9"/>
+ <point x="250" y="-25"/>
+ <point x="345" y="-25" type="curve" smooth="yes"/>
+ <point x="602" y="-25"/>
+ <point x="780" y="119"/>
+ <point x="780" y="535" type="curve" smooth="yes"/>
+ <point x="780" y="1460" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfbuildcomp.ufo/glyphs/L_tnC_apK_.glif b/tests/reference/ufo/psfbuildcomp.ufo/glyphs/L_tnC_apK_.glif
new file mode 100644
index 0000000..b3f4cdd
--- /dev/null
+++ b/tests/reference/ufo/psfbuildcomp.ufo/glyphs/L_tnC_apK_.glif
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnCapK" format="2">
+ <advance width="1310"/>
+ <unicode hex="004B"/>
+ <anchor x="270" y="0" name="H"/>
+ <anchor x="695" y="-100" name="L"/>
+ <anchor x="650" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="925" y="1460" type="line"/>
+ <point x="295" y="703" type="line"/>
+ <point x="425" y="745" type="line"/>
+ <point x="530" y="740" type="line"/>
+ <point x="1165" y="1460" type="line"/>
+ </contour>
+ <contour>
+ <point x="350" y="735" type="line"/>
+ <point x="985" y="0" type="line"/>
+ <point x="1230" y="0" type="line"/>
+ <point x="485" y="860" type="line"/>
+ </contour>
+ <contour>
+ <point x="365" y="1460" type="line"/>
+ <point x="160" y="1460" type="line"/>
+ <point x="175" y="1380"/>
+ <point x="175" y="1222"/>
+ <point x="175" y="1025" type="curve" smooth="yes"/>
+ <point x="175" y="435" type="line" smooth="yes"/>
+ <point x="175" y="238"/>
+ <point x="175" y="80"/>
+ <point x="160" y="0" type="curve"/>
+ <point x="365" y="0" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfbuildcomp.ufo/glyphs/L_tnC_apL_.glif b/tests/reference/ufo/psfbuildcomp.ufo/glyphs/L_tnC_apL_.glif
new file mode 100644
index 0000000..3d5883a
--- /dev/null
+++ b/tests/reference/ufo/psfbuildcomp.ufo/glyphs/L_tnC_apL_.glif
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnCapL" format="2">
+ <advance width="1080"/>
+ <unicode hex="004C"/>
+ <anchor x="592" y="0" name="H"/>
+ <anchor x="592" y="-100" name="L"/>
+ <anchor x="540" y="1200" name="R"/>
+ <anchor x="592" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="365" y="165" type="line"/>
+ <point x="365" y="1460" type="line"/>
+ <point x="160" y="1460" type="line"/>
+ <point x="175" y="1380"/>
+ <point x="175" y="1222"/>
+ <point x="175" y="1025" type="curve" smooth="yes"/>
+ <point x="175" y="435" type="line" smooth="yes"/>
+ <point x="175" y="238"/>
+ <point x="175" y="80"/>
+ <point x="160" y="0" type="curve"/>
+ <point x="1025" y="0" type="line"/>
+ <point x="1025" y="180" type="line"/>
+ <point x="945" y="166"/>
+ <point x="786" y="165"/>
+ <point x="589" y="165" type="curve" smooth="yes"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfbuildcomp.ufo/glyphs/L_tnC_apM_.glif b/tests/reference/ufo/psfbuildcomp.ufo/glyphs/L_tnC_apM_.glif
new file mode 100644
index 0000000..fbdf3b1
--- /dev/null
+++ b/tests/reference/ufo/psfbuildcomp.ufo/glyphs/L_tnC_apM_.glif
@@ -0,0 +1,37 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnCapM" format="2">
+ <advance width="1795"/>
+ <unicode hex="004D"/>
+ <anchor x="1521" y="0" name="H"/>
+ <anchor x="885" y="-100" name="L"/>
+ <anchor x="885" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="885" y="205" type="line"/>
+ <point x="455" y="1460" type="line"/>
+ <point x="285" y="1460" type="line"/>
+ <point x="790" y="0" type="line"/>
+ <point x="985" y="0" type="line"/>
+ <point x="1487" y="1460" type="line"/>
+ <point x="1320" y="1460" type="line"/>
+ </contour>
+ <contour>
+ <point x="230" y="1460" type="line"/>
+ <point x="230" y="1460"/>
+ <point x="186" y="198"/>
+ <point x="160" y="0" type="curve"/>
+ <point x="345" y="0" type="line"/>
+ <point x="377" y="1205" type="line"/>
+ <point x="405" y="1460" type="line"/>
+ </contour>
+ <contour>
+ <point x="1610" y="0" type="line"/>
+ <point x="1581" y="198"/>
+ <point x="1540" y="1460"/>
+ <point x="1540" y="1460" type="curve"/>
+ <point x="1365" y="1460" type="line"/>
+ <point x="1397" y="1205" type="line"/>
+ <point x="1425" y="0" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfbuildcomp.ufo/glyphs/L_tnC_apN_.glif b/tests/reference/ufo/psfbuildcomp.ufo/glyphs/L_tnC_apN_.glif
new file mode 100644
index 0000000..360e6e6
--- /dev/null
+++ b/tests/reference/ufo/psfbuildcomp.ufo/glyphs/L_tnC_apN_.glif
@@ -0,0 +1,37 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnCapN" format="2">
+ <advance width="1500"/>
+ <unicode hex="004E"/>
+ <anchor x="1230" y="0" name="H"/>
+ <anchor x="737" y="-100" name="L"/>
+ <anchor x="737" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="200" y="1355" type="line"/>
+ <point x="1135" y="0" type="line"/>
+ <point x="1275" y="100" type="line"/>
+ <point x="340" y="1460" type="line"/>
+ </contour>
+ <contour>
+ <point x="1135" y="0" type="line"/>
+ <point x="1300" y="0" type="line"/>
+ <point x="1300" y="1025" type="line" smooth="yes"/>
+ <point x="1300" y="1222"/>
+ <point x="1301" y="1380"/>
+ <point x="1315" y="1460" type="curve"/>
+ <point x="1135" y="1460" type="line"/>
+ </contour>
+ <contour>
+ <point x="340" y="1460" type="line"/>
+ <point x="160" y="1460" type="line"/>
+ <point x="175" y="1380"/>
+ <point x="175" y="1222"/>
+ <point x="175" y="1025" type="curve" smooth="yes"/>
+ <point x="175" y="435" type="line" smooth="yes"/>
+ <point x="175" y="238"/>
+ <point x="175" y="80"/>
+ <point x="160" y="0" type="curve"/>
+ <point x="340" y="0" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfbuildcomp.ufo/glyphs/L_tnC_apO_.glif b/tests/reference/ufo/psfbuildcomp.ufo/glyphs/L_tnC_apO_.glif
new file mode 100644
index 0000000..e351c3d
--- /dev/null
+++ b/tests/reference/ufo/psfbuildcomp.ufo/glyphs/L_tnC_apO_.glif
@@ -0,0 +1,40 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnCapO" format="2">
+ <advance width="1460"/>
+ <unicode hex="004F"/>
+ <anchor x="717" y="0" name="H"/>
+ <anchor x="717" y="-100" name="L"/>
+ <anchor x="994" y="0" name="O"/>
+ <anchor x="1460" y="1200" name="R"/>
+ <anchor x="717" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="1145" y="715" type="curve" smooth="yes"/>
+ <point x="1145" y="360"/>
+ <point x="965" y="150"/>
+ <point x="720" y="150" type="curve" smooth="yes"/>
+ <point x="460" y="150"/>
+ <point x="290" y="380"/>
+ <point x="290" y="745" type="curve" smooth="yes"/>
+ <point x="290" y="1091"/>
+ <point x="467" y="1310"/>
+ <point x="720" y="1310" type="curve" smooth="yes"/>
+ <point x="974" y="1310"/>
+ <point x="1145" y="1084"/>
+ </contour>
+ <contour>
+ <point x="1340" y="740" type="curve" smooth="yes"/>
+ <point x="1340" y="1219"/>
+ <point x="1048" y="1485"/>
+ <point x="730" y="1485" type="curve" smooth="yes"/>
+ <point x="407" y="1485"/>
+ <point x="95" y="1199"/>
+ <point x="95" y="720" type="curve" smooth="yes"/>
+ <point x="95" y="241"/>
+ <point x="388" y="-25"/>
+ <point x="710" y="-25" type="curve" smooth="yes"/>
+ <point x="1029" y="-25"/>
+ <point x="1340" y="260"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfbuildcomp.ufo/glyphs/L_tnC_apP_.glif b/tests/reference/ufo/psfbuildcomp.ufo/glyphs/L_tnC_apP_.glif
new file mode 100644
index 0000000..9f29954
--- /dev/null
+++ b/tests/reference/ufo/psfbuildcomp.ufo/glyphs/L_tnC_apP_.glif
@@ -0,0 +1,50 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnCapP" format="2">
+ <advance width="1195"/>
+ <unicode hex="0050"/>
+ <anchor x="637" y="-100" name="L"/>
+ <anchor x="637" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="365" y="565" type="line"/>
+ <point x="430" y="558"/>
+ <point x="512" y="555"/>
+ <point x="585" y="555" type="curve" smooth="yes"/>
+ <point x="914" y="555"/>
+ <point x="1115" y="736"/>
+ <point x="1115" y="1030" type="curve" smooth="yes"/>
+ <point x="1115" y="1322"/>
+ <point x="908" y="1470"/>
+ <point x="585" y="1470" type="curve" smooth="yes"/>
+ <point x="372" y="1470"/>
+ <point x="160" y="1460"/>
+ <point x="160" y="1460" type="curve"/>
+ <point x="175" y="1380"/>
+ <point x="175" y="1196"/>
+ <point x="175" y="1000" type="curve"/>
+ <point x="175" y="435" type="line" smooth="yes"/>
+ <point x="175" y="238"/>
+ <point x="175" y="80"/>
+ <point x="160" y="0" type="curve"/>
+ <point x="380" y="0" type="line"/>
+ <point x="366" y="78"/>
+ <point x="365" y="237"/>
+ <point x="365" y="435" type="curve" smooth="yes"/>
+ </contour>
+ <contour>
+ <point x="365" y="1305" type="line"/>
+ <point x="433" y="1308"/>
+ <point x="481" y="1310"/>
+ <point x="575" y="1310" type="curve" smooth="yes"/>
+ <point x="841" y="1310"/>
+ <point x="925" y="1170"/>
+ <point x="925" y="1010" type="curve" smooth="yes"/>
+ <point x="925" y="849"/>
+ <point x="850" y="710"/>
+ <point x="570" y="710" type="curve" smooth="yes"/>
+ <point x="495" y="710"/>
+ <point x="428" y="712"/>
+ <point x="365" y="720" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfbuildcomp.ufo/glyphs/L_tnC_apQ_.glif b/tests/reference/ufo/psfbuildcomp.ufo/glyphs/L_tnC_apQ_.glif
new file mode 100644
index 0000000..ddd0351
--- /dev/null
+++ b/tests/reference/ufo/psfbuildcomp.ufo/glyphs/L_tnC_apQ_.glif
@@ -0,0 +1,49 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnCapQ" format="2">
+ <advance width="1475"/>
+ <unicode hex="0051"/>
+ <anchor x="717" y="-270" name="L"/>
+ <anchor x="717" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="1340" y="740" type="curve" smooth="yes"/>
+ <point x="1340" y="1219"/>
+ <point x="1053" y="1485"/>
+ <point x="730" y="1485" type="curve" smooth="yes"/>
+ <point x="407" y="1485"/>
+ <point x="95" y="1199"/>
+ <point x="95" y="720" type="curve" smooth="yes"/>
+ <point x="95" y="241"/>
+ <point x="383" y="-25"/>
+ <point x="705" y="-25" type="curve" smooth="yes"/>
+ <point x="767" y="-25"/>
+ <point x="818" y="-18"/>
+ <point x="875" y="0" type="curve"/>
+ <point x="944" y="0"/>
+ <point x="1236" y="-190"/>
+ <point x="1320" y="-190" type="curve" smooth="yes"/>
+ <point x="1374" y="-190"/>
+ <point x="1431" y="-81"/>
+ <point x="1455" y="-45" type="curve"/>
+ <point x="1321" y="-28"/>
+ <point x="1205" y="28"/>
+ <point x="1080" y="105" type="curve"/>
+ <point x="1256" y="236"/>
+ <point x="1340" y="479"/>
+ </contour>
+ <contour>
+ <point x="1145" y="715" type="curve" smooth="yes"/>
+ <point x="1145" y="360"/>
+ <point x="965" y="150"/>
+ <point x="720" y="150" type="curve" smooth="yes"/>
+ <point x="460" y="150"/>
+ <point x="290" y="380"/>
+ <point x="290" y="745" type="curve" smooth="yes"/>
+ <point x="290" y="1091"/>
+ <point x="467" y="1310"/>
+ <point x="720" y="1310" type="curve" smooth="yes"/>
+ <point x="974" y="1310"/>
+ <point x="1145" y="1084"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfbuildcomp.ufo/glyphs/L_tnC_apR_.glif b/tests/reference/ufo/psfbuildcomp.ufo/glyphs/L_tnC_apR_.glif
new file mode 100644
index 0000000..cd9e037
--- /dev/null
+++ b/tests/reference/ufo/psfbuildcomp.ufo/glyphs/L_tnC_apR_.glif
@@ -0,0 +1,55 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnCapR" format="2">
+ <advance width="1305"/>
+ <unicode hex="0052"/>
+ <anchor x="285" y="0" name="H"/>
+ <anchor x="610" y="-100" name="L"/>
+ <anchor x="610" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="365" y="625" type="line"/>
+ <point x="620" y="625" type="line"/>
+ <point x="805" y="625"/>
+ <point x="1090" y="743"/>
+ <point x="1090" y="1060" type="curve" smooth="yes"/>
+ <point x="1090" y="1349"/>
+ <point x="876" y="1470"/>
+ <point x="565" y="1470" type="curve" smooth="yes"/>
+ <point x="331" y="1470"/>
+ <point x="160" y="1460"/>
+ <point x="160" y="1460" type="curve"/>
+ <point x="175" y="1380"/>
+ <point x="175" y="1196"/>
+ <point x="175" y="1000" type="curve" smooth="yes"/>
+ <point x="175" y="435" type="line"/>
+ <point x="175" y="238"/>
+ <point x="175" y="80"/>
+ <point x="160" y="0" type="curve"/>
+ <point x="380" y="0" type="line"/>
+ <point x="366" y="78"/>
+ <point x="365" y="238"/>
+ <point x="365" y="435" type="curve"/>
+ </contour>
+ <contour>
+ <point x="365" y="1305" type="line"/>
+ <point x="418" y="1307"/>
+ <point x="485" y="1310"/>
+ <point x="555" y="1310" type="curve" smooth="yes"/>
+ <point x="800" y="1310"/>
+ <point x="900" y="1216"/>
+ <point x="900" y="1045" type="curve" smooth="yes"/>
+ <point x="900" y="879"/>
+ <point x="780" y="780"/>
+ <point x="555" y="780" type="curve"/>
+ <point x="365" y="780" type="line"/>
+ </contour>
+ <contour>
+ <point x="561" y="635" type="line"/>
+ <point x="990" y="0" type="line"/>
+ <point x="1245" y="0" type="line"/>
+ <point x="1178" y="73"/>
+ <point x="715" y="710"/>
+ <point x="715" y="710" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfbuildcomp.ufo/glyphs/L_tnC_apS_.glif b/tests/reference/ufo/psfbuildcomp.ufo/glyphs/L_tnC_apS_.glif
new file mode 100644
index 0000000..92da6b0
--- /dev/null
+++ b/tests/reference/ufo/psfbuildcomp.ufo/glyphs/L_tnC_apS_.glif
@@ -0,0 +1,50 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnCapS" format="2">
+ <advance width="1175"/>
+ <unicode hex="0053"/>
+ <anchor x="580" y="0" name="H"/>
+ <anchor x="580" y="-100" name="L"/>
+ <anchor x="580" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="1000" y="1395" type="line"/>
+ <point x="870" y="1458"/>
+ <point x="759" y="1485"/>
+ <point x="605" y="1485" type="curve" smooth="yes"/>
+ <point x="273" y="1485"/>
+ <point x="135" y="1250"/>
+ <point x="135" y="1080" type="curve" smooth="yes"/>
+ <point x="135" y="910"/>
+ <point x="203" y="778"/>
+ <point x="515" y="685" type="curve" smooth="yes"/>
+ <point x="827" y="591"/>
+ <point x="875" y="510"/>
+ <point x="875" y="405" type="curve" smooth="yes"/>
+ <point x="875" y="243"/>
+ <point x="726" y="150"/>
+ <point x="565" y="150" type="curve" smooth="yes"/>
+ <point x="417" y="150"/>
+ <point x="272" y="200"/>
+ <point x="140" y="315" type="curve"/>
+ <point x="95" y="110" type="line"/>
+ <point x="197" y="31"/>
+ <point x="372" y="-25"/>
+ <point x="565" y="-25" type="curve" smooth="yes"/>
+ <point x="838" y="-25"/>
+ <point x="1065" y="157"/>
+ <point x="1065" y="425" type="curve" smooth="yes"/>
+ <point x="1065" y="641"/>
+ <point x="920" y="762"/>
+ <point x="655" y="840" type="curve" smooth="yes"/>
+ <point x="370" y="923"/>
+ <point x="325" y="985"/>
+ <point x="325" y="1095" type="curve" smooth="yes"/>
+ <point x="325" y="1205"/>
+ <point x="435" y="1310"/>
+ <point x="595" y="1310" type="curve" smooth="yes"/>
+ <point x="723" y="1310"/>
+ <point x="817" y="1279"/>
+ <point x="960" y="1200" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfbuildcomp.ufo/glyphs/L_tnC_apT_.glif b/tests/reference/ufo/psfbuildcomp.ufo/glyphs/L_tnC_apT_.glif
new file mode 100644
index 0000000..124138f
--- /dev/null
+++ b/tests/reference/ufo/psfbuildcomp.ufo/glyphs/L_tnC_apT_.glif
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnCapT" format="2">
+ <advance width="1265"/>
+ <unicode hex="0054"/>
+ <anchor x="622" y="0" name="H"/>
+ <anchor x="622" y="-100" name="L"/>
+ <anchor x="622" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="45" y="1460" type="line"/>
+ <point x="45" y="1275" type="line"/>
+ <point x="125" y="1292"/>
+ <point x="201" y="1295"/>
+ <point x="290" y="1295" type="curve" smooth="yes"/>
+ <point x="525" y="1295" type="line"/>
+ <point x="525" y="435" type="line" smooth="yes"/>
+ <point x="525" y="238"/>
+ <point x="522" y="80"/>
+ <point x="505" y="0" type="curve"/>
+ <point x="735" y="0" type="line"/>
+ <point x="718" y="80"/>
+ <point x="715" y="238"/>
+ <point x="715" y="435" type="curve" smooth="yes"/>
+ <point x="715" y="1295" type="line"/>
+ <point x="955" y="1295" type="line" smooth="yes"/>
+ <point x="1045" y="1295"/>
+ <point x="1120" y="1292"/>
+ <point x="1200" y="1275" type="curve"/>
+ <point x="1200" y="1460" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfbuildcomp.ufo/glyphs/L_tnC_apU_.glif b/tests/reference/ufo/psfbuildcomp.ufo/glyphs/L_tnC_apU_.glif
new file mode 100644
index 0000000..7afa08d
--- /dev/null
+++ b/tests/reference/ufo/psfbuildcomp.ufo/glyphs/L_tnC_apU_.glif
@@ -0,0 +1,38 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnCapU" format="2">
+ <advance width="1440"/>
+ <unicode hex="0055"/>
+ <anchor x="707" y="0" name="H"/>
+ <anchor x="707" y="-100" name="L"/>
+ <anchor x="1026" y="0" name="O"/>
+ <anchor x="1400" y="1200" name="R"/>
+ <anchor x="707" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="1050" y="1460" type="line"/>
+ <point x="1050" y="560" type="line" smooth="yes"/>
+ <point x="1050" y="299"/>
+ <point x="968" y="135"/>
+ <point x="710" y="135" type="curve" smooth="yes"/>
+ <point x="447" y="135"/>
+ <point x="365" y="299"/>
+ <point x="365" y="560" type="curve" smooth="yes"/>
+ <point x="365" y="1460" type="line"/>
+ <point x="160" y="1460" type="line"/>
+ <point x="174" y="1380"/>
+ <point x="175" y="1222"/>
+ <point x="175" y="1025" type="curve" smooth="yes"/>
+ <point x="175" y="515" type="line"/>
+ <point x="175" y="190"/>
+ <point x="345" y="-25"/>
+ <point x="710" y="-25" type="curve" smooth="yes"/>
+ <point x="1071" y="-25"/>
+ <point x="1240" y="190"/>
+ <point x="1240" y="515" type="curve"/>
+ <point x="1240" y="1025" type="line" smooth="yes"/>
+ <point x="1240" y="1232"/>
+ <point x="1242" y="1380"/>
+ <point x="1255" y="1460" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfbuildcomp.ufo/glyphs/L_tnC_apV_.glif b/tests/reference/ufo/psfbuildcomp.ufo/glyphs/L_tnC_apV_.glif
new file mode 100644
index 0000000..86c76b5
--- /dev/null
+++ b/tests/reference/ufo/psfbuildcomp.ufo/glyphs/L_tnC_apV_.glif
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnCapV" format="2">
+ <advance width="1365"/>
+ <unicode hex="0056"/>
+ <anchor x="680" y="0" name="H"/>
+ <anchor x="672" y="-100" name="L"/>
+ <anchor x="880" y="0" name="O"/>
+ <anchor x="672" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="1095" y="1460" type="line"/>
+ <point x="672" y="195" type="line"/>
+ <point x="250" y="1460" type="line"/>
+ <point x="35" y="1460" type="line"/>
+ <point x="68" y="1378"/>
+ <point x="101" y="1288"/>
+ <point x="170" y="1095" type="curve" smooth="yes"/>
+ <point x="560" y="0" type="line"/>
+ <point x="785" y="0" type="line"/>
+ <point x="1170" y="1095" type="line" smooth="yes"/>
+ <point x="1238" y="1289"/>
+ <point x="1274" y="1378"/>
+ <point x="1310" y="1460" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfbuildcomp.ufo/glyphs/L_tnC_apW_.glif b/tests/reference/ufo/psfbuildcomp.ufo/glyphs/L_tnC_apW_.glif
new file mode 100644
index 0000000..b1f4961
--- /dev/null
+++ b/tests/reference/ufo/psfbuildcomp.ufo/glyphs/L_tnC_apW_.glif
@@ -0,0 +1,45 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnCapW" format="2">
+ <advance width="2080"/>
+ <unicode hex="0057"/>
+ <anchor x="1027" y="-100" name="L"/>
+ <anchor x="1027" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="1480" y="0" type="line"/>
+ <point x="1595" y="0" type="line"/>
+ <point x="1900" y="1095" type="line" smooth="yes"/>
+ <point x="1954" y="1289"/>
+ <point x="1983" y="1378"/>
+ <point x="2015" y="1460" type="curve"/>
+ <point x="1795" y="1460" type="line"/>
+ <point x="1470" y="130" type="line"/>
+ </contour>
+ <contour>
+ <point x="1120" y="1460" type="line"/>
+ <point x="935" y="1460" type="line"/>
+ <point x="990" y="1305" type="line"/>
+ <point x="1370" y="0" type="line"/>
+ <point x="1480" y="0" type="line"/>
+ <point x="1500" y="130" type="line"/>
+ </contour>
+ <contour>
+ <point x="580" y="0" type="line"/>
+ <point x="685" y="0" type="line"/>
+ <point x="1065" y="1305" type="line"/>
+ <point x="1120" y="1460" type="line"/>
+ <point x="935" y="1460" type="line"/>
+ <point x="560" y="130" type="line"/>
+ </contour>
+ <contour>
+ <point x="260" y="1460" type="line"/>
+ <point x="40" y="1460" type="line"/>
+ <point x="71" y="1381"/>
+ <point x="102" y="1286"/>
+ <point x="155" y="1095" type="curve" smooth="yes"/>
+ <point x="460" y="0" type="line"/>
+ <point x="580" y="0" type="line"/>
+ <point x="590" y="130" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfbuildcomp.ufo/glyphs/L_tnC_apX_.glif b/tests/reference/ufo/psfbuildcomp.ufo/glyphs/L_tnC_apX_.glif
new file mode 100644
index 0000000..7472407
--- /dev/null
+++ b/tests/reference/ufo/psfbuildcomp.ufo/glyphs/L_tnC_apX_.glif
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnCapX" format="2">
+ <advance width="1325"/>
+ <unicode hex="0058"/>
+ <anchor x="650" y="-100" name="L"/>
+ <anchor x="650" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="537" y="781" type="line"/>
+ <point x="265" y="340" type="line" smooth="yes"/>
+ <point x="136" y="132"/>
+ <point x="103" y="86"/>
+ <point x="40" y="0" type="curve"/>
+ <point x="270" y="0" type="line"/>
+ <point x="642" y="614" type="line"/>
+ <point x="1030" y="0" type="line"/>
+ <point x="1260" y="0" type="line"/>
+ <point x="1199" y="82"/>
+ <point x="1165" y="127"/>
+ <point x="1033" y="336" type="curve" smooth="yes"/>
+ <point x="761" y="767" type="line"/>
+ <point x="972" y="1110" type="line" smooth="yes"/>
+ <point x="1097" y="1313"/>
+ <point x="1148" y="1383"/>
+ <point x="1210" y="1460" type="curve"/>
+ <point x="975" y="1460" type="line"/>
+ <point x="656" y="934" type="line"/>
+ <point x="325" y="1460" type="line"/>
+ <point x="90" y="1460" type="line"/>
+ <point x="154" y="1376"/>
+ <point x="201" y="1315"/>
+ <point x="330" y="1110" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfbuildcomp.ufo/glyphs/L_tnC_apY_.glif b/tests/reference/ufo/psfbuildcomp.ufo/glyphs/L_tnC_apY_.glif
new file mode 100644
index 0000000..c2c5f54
--- /dev/null
+++ b/tests/reference/ufo/psfbuildcomp.ufo/glyphs/L_tnC_apY_.glif
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnCapY" format="2">
+ <advance width="1320"/>
+ <unicode hex="0059"/>
+ <anchor x="650" y="-100" name="L"/>
+ <anchor x="650" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="35" y="1460" type="line"/>
+ <point x="147" y="1311"/>
+ <point x="213" y="1197"/>
+ <point x="290" y="1065" type="curve" smooth="yes"/>
+ <point x="555" y="611" type="line"/>
+ <point x="555" y="435" type="line" smooth="yes"/>
+ <point x="555" y="238"/>
+ <point x="555" y="80"/>
+ <point x="540" y="0" type="curve"/>
+ <point x="760" y="0" type="line"/>
+ <point x="745" y="80"/>
+ <point x="745" y="238"/>
+ <point x="745" y="435" type="curve" smooth="yes"/>
+ <point x="745" y="603" type="line"/>
+ <point x="1015" y="1065" type="line" smooth="yes"/>
+ <point x="1091" y="1195"/>
+ <point x="1147" y="1291"/>
+ <point x="1265" y="1460" type="curve"/>
+ <point x="1035" y="1460" type="line"/>
+ <point x="660" y="799" type="line"/>
+ <point x="265" y="1460" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfbuildcomp.ufo/glyphs/L_tnS_mA_.glif b/tests/reference/ufo/psfbuildcomp.ufo/glyphs/L_tnS_mA_.glif
new file mode 100644
index 0000000..20f7261
--- /dev/null
+++ b/tests/reference/ufo/psfbuildcomp.ufo/glyphs/L_tnS_mA_.glif
@@ -0,0 +1,76 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmA" format="2">
+ <advance width="1120"/>
+ <unicode hex="0061"/>
+ <note>
+
+
+
+
+ GlyphNote A
+
+
+
+
+ </note>
+ <anchor x="540" y="0" name="H"/>
+ <anchor x="540" y="-100" name="L"/>
+ <anchor x="1125" y="0" name="O"/>
+ <anchor x="1120" y="1000" name="R"/>
+ <anchor x="540" y="1100" name="U"/>
+ <outline>
+ <contour>
+ <point x="950" y="760" type="line"/>
+ <point x="950" y="919"/>
+ <point x="800" y="1040"/>
+ <point x="570" y="1040" type="curve" smooth="yes"/>
+ <point x="418" y="1040"/>
+ <point x="312" y="994"/>
+ <point x="209" y="950" type="curve"/>
+ <point x="203" y="907"/>
+ <point x="200" y="799"/>
+ <point x="199" y="755" type="curve"/>
+ <point x="316" y="837"/>
+ <point x="419" y="880"/>
+ <point x="525" y="880" type="curve" smooth="yes"/>
+ <point x="675" y="880"/>
+ <point x="765" y="831"/>
+ <point x="765" y="710" type="curve" smooth="yes"/>
+ <point x="765" y="635" type="line"/>
+ <point x="724" y="632"/>
+ <point x="564" y="617"/>
+ <point x="495" y="610" type="curve" smooth="yes"/>
+ <point x="186" y="580"/>
+ <point x="95" y="407"/>
+ <point x="95" y="255" type="curve" smooth="yes"/>
+ <point x="95" y="107"/>
+ <point x="232" y="-25"/>
+ <point x="420" y="-25" type="curve" smooth="yes"/>
+ <point x="544" y="-25"/>
+ <point x="677" y="29"/>
+ <point x="795" y="155" type="curve"/>
+ <point x="809" y="91"/>
+ <point x="833" y="32"/>
+ <point x="845" y="0" type="curve"/>
+ <point x="1025" y="0" type="line"/>
+ <point x="981" y="112"/>
+ <point x="950" y="226"/>
+ <point x="950" y="370" type="curve"/>
+ </contour>
+ <contour>
+ <point x="765" y="325" type="line"/>
+ <point x="644" y="164"/>
+ <point x="552" y="140"/>
+ <point x="450" y="140" type="curve" smooth="yes"/>
+ <point x="340" y="140"/>
+ <point x="275" y="191"/>
+ <point x="275" y="280" type="curve" smooth="yes"/>
+ <point x="275" y="372"/>
+ <point x="335" y="450"/>
+ <point x="505" y="470" type="curve" smooth="yes"/>
+ <point x="568" y="478"/>
+ <point x="715" y="493"/>
+ <point x="765" y="495" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfbuildcomp.ufo/glyphs/L_tnS_mA_A_cute.glif b/tests/reference/ufo/psfbuildcomp.ufo/glyphs/L_tnS_mA_A_cute.glif
new file mode 100644
index 0000000..2ab1b23
--- /dev/null
+++ b/tests/reference/ufo/psfbuildcomp.ufo/glyphs/L_tnS_mA_A_cute.glif
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmAAcute" format="2">
+ <advance width="1120"/>
+ <unicode hex="00E1"/>
+ <anchor x="540" y="0" name="H"/>
+ <anchor x="540" y="-100" name="L"/>
+ <anchor x="1125" y="0" name="O"/>
+ <anchor x="1120" y="1000" name="R"/>
+ <anchor x="540" y="1635" name="U"/>
+ <outline>
+ <component base="LtnSmA"/>
+ <component base="CombAcute" xOffset="1110"/>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfbuildcomp.ufo/glyphs/L_tnS_mA_C_ircum.glif b/tests/reference/ufo/psfbuildcomp.ufo/glyphs/L_tnS_mA_C_ircum.glif
new file mode 100644
index 0000000..6551c45
--- /dev/null
+++ b/tests/reference/ufo/psfbuildcomp.ufo/glyphs/L_tnS_mA_C_ircum.glif
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmACircum" format="2">
+ <advance width="1120"/>
+ <unicode hex="00E2"/>
+ <anchor x="540" y="0" name="H"/>
+ <anchor x="540" y="-100" name="L"/>
+ <anchor x="1125" y="0" name="O"/>
+ <anchor x="1120" y="1000" name="R"/>
+ <anchor x="540" y="1635" name="U"/>
+ <outline>
+ <component base="LtnSmA"/>
+ <component base="CombCircum" xOffset="1110"/>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfbuildcomp.ufo/glyphs/L_tnS_mA_D_iaer.glif b/tests/reference/ufo/psfbuildcomp.ufo/glyphs/L_tnS_mA_D_iaer.glif
new file mode 100644
index 0000000..61c5d3f
--- /dev/null
+++ b/tests/reference/ufo/psfbuildcomp.ufo/glyphs/L_tnS_mA_D_iaer.glif
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmADiaer" format="2">
+ <advance width="1120"/>
+ <unicode hex="00E4"/>
+ <anchor x="540" y="0" name="H"/>
+ <anchor x="540" y="-100" name="L"/>
+ <anchor x="1125" y="0" name="O"/>
+ <anchor x="1120" y="1000" name="R"/>
+ <anchor x="540" y="1505" name="U"/>
+ <outline>
+ <component base="LtnSmA"/>
+ <component base="CombDiaer" xOffset="1110"/>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfbuildcomp.ufo/glyphs/L_tnS_mA_G_rave.glif b/tests/reference/ufo/psfbuildcomp.ufo/glyphs/L_tnS_mA_G_rave.glif
new file mode 100644
index 0000000..9879252
--- /dev/null
+++ b/tests/reference/ufo/psfbuildcomp.ufo/glyphs/L_tnS_mA_G_rave.glif
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmAGrave" format="2">
+ <advance width="1120"/>
+ <unicode hex="00E0"/>
+ <anchor x="540" y="0" name="H"/>
+ <anchor x="540" y="-100" name="L"/>
+ <anchor x="1125" y="0" name="O"/>
+ <anchor x="1120" y="1000" name="R"/>
+ <anchor x="540" y="1635" name="U"/>
+ <outline>
+ <component base="LtnSmA"/>
+ <component base="CombGrave" xOffset="1090"/>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfbuildcomp.ufo/glyphs/L_tnS_mA_R_ingA_bv.glif b/tests/reference/ufo/psfbuildcomp.ufo/glyphs/L_tnS_mA_R_ingA_bv.glif
new file mode 100644
index 0000000..ae3b838
--- /dev/null
+++ b/tests/reference/ufo/psfbuildcomp.ufo/glyphs/L_tnS_mA_R_ingA_bv.glif
@@ -0,0 +1,41 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmARingAbv" format="2">
+ <advance width="1120"/>
+ <unicode hex="00E5"/>
+ <anchor x="540" y="0" name="H"/>
+ <anchor x="540" y="-100" name="L"/>
+ <anchor x="1125" y="0" name="O"/>
+ <anchor x="1120" y="1000" name="R"/>
+ <anchor x="542" y="1635" name="U"/>
+ <outline>
+ <component base="LtnSmA"/>
+ <contour>
+ <point x="642" y="1385" type="curve" smooth="yes"/>
+ <point x="642" y="1325"/>
+ <point x="602" y="1285"/>
+ <point x="542" y="1285" type="curve" smooth="yes"/>
+ <point x="482" y="1285"/>
+ <point x="442" y="1325"/>
+ <point x="442" y="1385" type="curve" smooth="yes"/>
+ <point x="442" y="1445"/>
+ <point x="482" y="1485"/>
+ <point x="542" y="1485" type="curve" smooth="yes"/>
+ <point x="602" y="1485"/>
+ <point x="642" y="1445"/>
+ </contour>
+ <contour>
+ <point x="327" y="1385" type="curve" smooth="yes"/>
+ <point x="327" y="1265"/>
+ <point x="422" y="1170"/>
+ <point x="542" y="1170" type="curve" smooth="yes"/>
+ <point x="662" y="1170"/>
+ <point x="757" y="1265"/>
+ <point x="757" y="1385" type="curve" smooth="yes"/>
+ <point x="757" y="1505"/>
+ <point x="662" y="1600"/>
+ <point x="542" y="1600" type="curve" smooth="yes"/>
+ <point x="422" y="1600"/>
+ <point x="327" y="1505"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfbuildcomp.ufo/glyphs/L_tnS_mA_T_ilde.glif b/tests/reference/ufo/psfbuildcomp.ufo/glyphs/L_tnS_mA_T_ilde.glif
new file mode 100644
index 0000000..cf21919
--- /dev/null
+++ b/tests/reference/ufo/psfbuildcomp.ufo/glyphs/L_tnS_mA_T_ilde.glif
@@ -0,0 +1,41 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmATilde" format="2">
+ <advance width="1120"/>
+ <unicode hex="00E3"/>
+ <anchor x="540" y="0" name="H"/>
+ <anchor x="540" y="-100" name="L"/>
+ <anchor x="1125" y="0" name="O"/>
+ <anchor x="1120" y="1000" name="R"/>
+ <anchor x="540" y="1475" name="U"/>
+ <outline>
+ <component base="LtnSmA"/>
+ <contour>
+ <point x="295" y="1205" type="line"/>
+ <point x="300" y="1254"/>
+ <point x="331" y="1290"/>
+ <point x="380" y="1290" type="curve" smooth="yes"/>
+ <point x="417" y="1290"/>
+ <point x="458" y="1274"/>
+ <point x="535" y="1238" type="curve" smooth="yes"/>
+ <point x="596" y="1210"/>
+ <point x="649" y="1190"/>
+ <point x="702" y="1190" type="curve" smooth="yes"/>
+ <point x="825" y="1190"/>
+ <point x="900" y="1312"/>
+ <point x="900" y="1440" type="curve"/>
+ <point x="795" y="1440" type="line"/>
+ <point x="788" y="1394"/>
+ <point x="757" y="1355"/>
+ <point x="710" y="1355" type="curve" smooth="yes"/>
+ <point x="668" y="1355"/>
+ <point x="627" y="1374"/>
+ <point x="555" y="1403" type="curve" smooth="yes"/>
+ <point x="485" y="1431"/>
+ <point x="438" y="1455"/>
+ <point x="382" y="1455" type="curve" smooth="yes"/>
+ <point x="263" y="1455"/>
+ <point x="190" y="1327"/>
+ <point x="190" y="1205" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfbuildcomp.ufo/glyphs/L_tnS_mB_.glif b/tests/reference/ufo/psfbuildcomp.ufo/glyphs/L_tnS_mB_.glif
new file mode 100644
index 0000000..67ff8ac
--- /dev/null
+++ b/tests/reference/ufo/psfbuildcomp.ufo/glyphs/L_tnS_mB_.glif
@@ -0,0 +1,50 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmB" format="2">
+ <advance width="1155"/>
+ <unicode hex="0062"/>
+ <anchor x="590" y="0" name="H"/>
+ <anchor x="590" y="-100" name="L"/>
+ <anchor x="1155" y="1000" name="R"/>
+ <anchor x="590" y="1635" name="U"/>
+ <outline>
+ <contour>
+ <point x="130" y="1600" type="line"/>
+ <point x="145" y="1488"/>
+ <point x="145" y="1273"/>
+ <point x="145" y="1130" type="curve" smooth="yes"/>
+ <point x="145" y="936"/>
+ <point x="145" y="228"/>
+ <point x="145" y="65" type="curve"/>
+ <point x="272" y="26"/>
+ <point x="413" y="-25"/>
+ <point x="575" y="-25" type="curve" smooth="yes"/>
+ <point x="870" y="-25"/>
+ <point x="1060" y="197"/>
+ <point x="1060" y="540" type="curve" smooth="yes"/>
+ <point x="1060" y="832"/>
+ <point x="917" y="1040"/>
+ <point x="715" y="1040" type="curve" smooth="yes"/>
+ <point x="547" y="1040"/>
+ <point x="423" y="947"/>
+ <point x="330" y="825" type="curve"/>
+ <point x="330" y="916"/>
+ <point x="330" y="1600"/>
+ <point x="330" y="1600" type="curve"/>
+ </contour>
+ <contour>
+ <point x="330" y="585" type="line"/>
+ <point x="398" y="751"/>
+ <point x="531" y="865"/>
+ <point x="655" y="865" type="curve" smooth="yes"/>
+ <point x="799" y="865"/>
+ <point x="880" y="727"/>
+ <point x="880" y="505" type="curve" smooth="yes"/>
+ <point x="880" y="280"/>
+ <point x="752" y="130"/>
+ <point x="575" y="130" type="curve" smooth="yes"/>
+ <point x="489" y="130"/>
+ <point x="428" y="144"/>
+ <point x="330" y="185" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfbuildcomp.ufo/glyphs/L_tnS_mC_.glif b/tests/reference/ufo/psfbuildcomp.ufo/glyphs/L_tnS_mC_.glif
new file mode 100644
index 0000000..7c403fb
--- /dev/null
+++ b/tests/reference/ufo/psfbuildcomp.ufo/glyphs/L_tnS_mC_.glif
@@ -0,0 +1,39 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmC" format="2">
+ <advance width="1020"/>
+ <unicode hex="0063"/>
+ <anchor x="580" y="0" name="H"/>
+ <anchor x="580" y="-100" name="L"/>
+ <anchor x="1020" y="1000" name="R"/>
+ <anchor x="570" y="1100" name="U"/>
+ <outline>
+ <contour>
+ <point x="905" y="260" type="line"/>
+ <point x="818" y="183"/>
+ <point x="720" y="140"/>
+ <point x="600" y="140" type="curve" smooth="yes"/>
+ <point x="406" y="140"/>
+ <point x="285" y="285"/>
+ <point x="285" y="500" type="curve" smooth="yes"/>
+ <point x="285" y="736"/>
+ <point x="422" y="875"/>
+ <point x="600" y="875" type="curve" smooth="yes"/>
+ <point x="703" y="875"/>
+ <point x="790" y="841"/>
+ <point x="880" y="775" type="curve"/>
+ <point x="915" y="955" type="line"/>
+ <point x="842" y="1005"/>
+ <point x="748" y="1040"/>
+ <point x="615" y="1040" type="curve" smooth="yes"/>
+ <point x="297" y="1040"/>
+ <point x="95" y="792"/>
+ <point x="95" y="490" type="curve" smooth="yes"/>
+ <point x="95" y="171"/>
+ <point x="312" y="-25"/>
+ <point x="580" y="-25" type="curve" smooth="yes"/>
+ <point x="730" y="-25"/>
+ <point x="824" y="9"/>
+ <point x="925" y="85" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfbuildcomp.ufo/glyphs/L_tnS_mC_A_cute.glif b/tests/reference/ufo/psfbuildcomp.ufo/glyphs/L_tnS_mC_A_cute.glif
new file mode 100644
index 0000000..7a0f29b
--- /dev/null
+++ b/tests/reference/ufo/psfbuildcomp.ufo/glyphs/L_tnS_mC_A_cute.glif
@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmCAcute" format="2">
+ <advance width="1355"/>
+ <unicode hex="0107"/>
+ <anchor x="750" y="0" name="H"/>
+ <anchor x="750" y="-100" name="L"/>
+ <anchor x="750" y="2065" name="U"/>
+ <outline>
+ <component base="LtnCapC"/>
+ <component base="CombAcute" xOffset="1320" yOffset="430"/>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfbuildcomp.ufo/glyphs/L_tnS_mC_A_cuteC_edilla.glif b/tests/reference/ufo/psfbuildcomp.ufo/glyphs/L_tnS_mC_A_cuteC_edilla.glif
new file mode 100644
index 0000000..0791a42
--- /dev/null
+++ b/tests/reference/ufo/psfbuildcomp.ufo/glyphs/L_tnS_mC_A_cuteC_edilla.glif
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmCAcuteCedilla" format="2">
+ <advance width="1020"/>
+ <unicode hex="1E09"/>
+ <anchor x="580" y="0" name="H"/>
+ <anchor x="580" y="-100" name="L"/>
+ <anchor x="1020" y="1000" name="R"/>
+ <anchor x="570" y="1635" name="U"/>
+ <outline>
+ <component base="LtnSmC"/>
+ <component base="CombAcute" xOffset="1140"/>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfbuildcomp.ufo/glyphs/L_tnS_mC_C_ircum.glif b/tests/reference/ufo/psfbuildcomp.ufo/glyphs/L_tnS_mC_C_ircum.glif
new file mode 100644
index 0000000..7b37429
--- /dev/null
+++ b/tests/reference/ufo/psfbuildcomp.ufo/glyphs/L_tnS_mC_C_ircum.glif
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmCCircum" format="2">
+ <advance width="1020"/>
+ <unicode hex="0109"/>
+ <anchor x="580" y="0" name="H"/>
+ <anchor x="580" y="-100" name="L"/>
+ <anchor x="1020" y="1000" name="R"/>
+ <anchor x="570" y="1635" name="U"/>
+ <outline>
+ <component base="LtnSmC"/>
+ <component base="CombCircum" xOffset="1140"/>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfbuildcomp.ufo/glyphs/L_tnS_mD_.glif b/tests/reference/ufo/psfbuildcomp.ufo/glyphs/L_tnS_mD_.glif
new file mode 100644
index 0000000..13547d4
--- /dev/null
+++ b/tests/reference/ufo/psfbuildcomp.ufo/glyphs/L_tnS_mD_.glif
@@ -0,0 +1,53 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmD" format="2">
+ <advance width="1190"/>
+ <unicode hex="0064"/>
+ <anchor x="605" y="0" name="H"/>
+ <anchor x="605" y="-100" name="L"/>
+ <anchor x="1190" y="1000" name="R"/>
+ <anchor x="605" y="1635" name="U"/>
+ <outline>
+ <contour>
+ <point x="1030" y="1600" type="line"/>
+ <point x="820" y="1600" type="line"/>
+ <point x="839" y="1516"/>
+ <point x="845" y="1395"/>
+ <point x="845" y="1235" type="curve"/>
+ <point x="845" y="955" type="line"/>
+ <point x="767" y="999"/>
+ <point x="665" y="1040"/>
+ <point x="580" y="1040" type="curve" smooth="yes"/>
+ <point x="312" y="1040"/>
+ <point x="105" y="814"/>
+ <point x="105" y="460" type="curve" smooth="yes"/>
+ <point x="105" y="167"/>
+ <point x="261" y="-25"/>
+ <point x="505" y="-25" type="curve" smooth="yes"/>
+ <point x="652" y="-25"/>
+ <point x="775" y="50"/>
+ <point x="870" y="185" type="curve"/>
+ <point x="887" y="111"/>
+ <point x="910" y="34"/>
+ <point x="925" y="0" type="curve"/>
+ <point x="1105" y="0" type="line"/>
+ <point x="1062" y="112"/>
+ <point x="1030" y="278"/>
+ <point x="1030" y="530" type="curve"/>
+ </contour>
+ <contour>
+ <point x="845" y="400" type="line"/>
+ <point x="790" y="268"/>
+ <point x="662" y="135"/>
+ <point x="540" y="135" type="curve" smooth="yes"/>
+ <point x="366" y="135"/>
+ <point x="290" y="258"/>
+ <point x="290" y="490" type="curve" smooth="yes"/>
+ <point x="290" y="727"/>
+ <point x="429" y="870"/>
+ <point x="580" y="870" type="curve" smooth="yes"/>
+ <point x="681" y="870"/>
+ <point x="746" y="848"/>
+ <point x="845" y="795" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfbuildcomp.ufo/glyphs/L_tnS_mE_.glif b/tests/reference/ufo/psfbuildcomp.ufo/glyphs/L_tnS_mE_.glif
new file mode 100644
index 0000000..f231440
--- /dev/null
+++ b/tests/reference/ufo/psfbuildcomp.ufo/glyphs/L_tnS_mE_.glif
@@ -0,0 +1,45 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmE" format="2">
+ <advance width="1095"/>
+ <unicode hex="0065"/>
+ <anchor x="545" y="0" name="H"/>
+ <anchor x="569" y="-100" name="L"/>
+ <anchor x="925" y="0" name="O"/>
+ <anchor x="1095" y="1000" name="R"/>
+ <anchor x="569" y="1100" name="U"/>
+ <outline>
+ <contour>
+ <point x="989" y="485" type="line"/>
+ <point x="990" y="503"/>
+ <point x="990" y="545"/>
+ <point x="990" y="563" type="curve" smooth="yes"/>
+ <point x="990" y="788"/>
+ <point x="905" y="1040"/>
+ <point x="575" y="1040" type="curve" smooth="yes"/>
+ <point x="279" y="1040"/>
+ <point x="95" y="826"/>
+ <point x="95" y="495" type="curve" smooth="yes"/>
+ <point x="95" y="155"/>
+ <point x="320" y="-25"/>
+ <point x="575" y="-25" type="curve" smooth="yes"/>
+ <point x="729" y="-25"/>
+ <point x="853" y="2"/>
+ <point x="995" y="75" type="curve"/>
+ <point x="975" y="240" type="line"/>
+ <point x="853" y="166"/>
+ <point x="729" y="140"/>
+ <point x="600" y="140" type="curve" smooth="yes"/>
+ <point x="414" y="140"/>
+ <point x="280" y="258"/>
+ <point x="280" y="505" type="curve" smooth="yes"/>
+ <point x="280" y="770"/>
+ <point x="385" y="890"/>
+ <point x="560" y="890" type="curve" smooth="yes"/>
+ <point x="705" y="890"/>
+ <point x="810" y="797"/>
+ <point x="810" y="625" type="curve"/>
+ <point x="245" y="625" type="line"/>
+ <point x="245" y="485" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfbuildcomp.ufo/glyphs/L_tnS_mF_.glif b/tests/reference/ufo/psfbuildcomp.ufo/glyphs/L_tnS_mF_.glif
new file mode 100644
index 0000000..56c0b15
--- /dev/null
+++ b/tests/reference/ufo/psfbuildcomp.ufo/glyphs/L_tnS_mF_.glif
@@ -0,0 +1,39 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmF" format="2">
+ <advance width="750"/>
+ <unicode hex="0066"/>
+ <anchor x="370" y="0" name="H"/>
+ <anchor x="335" y="-100" name="L"/>
+ <anchor x="560" y="1635" name="U"/>
+ <outline>
+ <contour>
+ <point x="40" y="850" type="line"/>
+ <point x="240" y="850" type="line"/>
+ <point x="240" y="0" type="line"/>
+ <point x="455" y="0" type="line"/>
+ <point x="433" y="105"/>
+ <point x="425" y="300"/>
+ <point x="425" y="494" type="curve" smooth="yes"/>
+ <point x="425" y="850" type="line"/>
+ <point x="695" y="850" type="line"/>
+ <point x="695" y="995" type="line"/>
+ <point x="425" y="995" type="line"/>
+ <point x="425" y="1210" type="line" smooth="yes"/>
+ <point x="425" y="1381"/>
+ <point x="481" y="1450"/>
+ <point x="585" y="1450" type="curve" smooth="yes"/>
+ <point x="643" y="1450"/>
+ <point x="710" y="1427"/>
+ <point x="760" y="1390" type="curve"/>
+ <point x="805" y="1550" type="line"/>
+ <point x="743" y="1594"/>
+ <point x="663" y="1620"/>
+ <point x="585" y="1620" type="curve" smooth="yes"/>
+ <point x="369" y="1620"/>
+ <point x="240" y="1470"/>
+ <point x="240" y="1170" type="curve" smooth="yes"/>
+ <point x="240" y="995" type="line"/>
+ <point x="40" y="995" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfbuildcomp.ufo/glyphs/L_tnS_mG_.glif b/tests/reference/ufo/psfbuildcomp.ufo/glyphs/L_tnS_mG_.glif
new file mode 100644
index 0000000..236da64
--- /dev/null
+++ b/tests/reference/ufo/psfbuildcomp.ufo/glyphs/L_tnS_mG_.glif
@@ -0,0 +1,91 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmG" format="2">
+ <advance width="1095"/>
+ <unicode hex="0067"/>
+ <anchor x="545" y="-432" name="H"/>
+ <anchor x="545" y="-535" name="L"/>
+ <anchor x="1095" y="1000" name="R"/>
+ <anchor x="515" y="1100" name="U"/>
+ <outline>
+ <contour>
+ <point x="330" y="395" type="line"/>
+ <point x="234" y="357"/>
+ <point x="180" y="275"/>
+ <point x="180" y="215" type="curve" smooth="yes"/>
+ <point x="180" y="121"/>
+ <point x="263" y="27"/>
+ <point x="545" y="-5" type="curve" smooth="yes"/>
+ <point x="805" y="-35"/>
+ <point x="880" y="-90"/>
+ <point x="880" y="-170" type="curve" smooth="yes"/>
+ <point x="880" y="-255"/>
+ <point x="731" y="-360"/>
+ <point x="550" y="-360" type="curve" smooth="yes"/>
+ <point x="323" y="-360"/>
+ <point x="215" y="-261"/>
+ <point x="215" y="-180" type="curve" smooth="yes"/>
+ <point x="215" y="-121"/>
+ <point x="244" y="-56"/>
+ <point x="465" y="20" type="curve"/>
+ <point x="459" y="49"/>
+ <point x="290" y="75"/>
+ <point x="290" y="75" type="curve"/>
+ <point x="113" y="2"/>
+ <point x="30" y="-89"/>
+ <point x="30" y="-200" type="curve" smooth="yes"/>
+ <point x="30" y="-409"/>
+ <point x="303" y="-505"/>
+ <point x="535" y="-505" type="curve" smooth="yes"/>
+ <point x="777" y="-505"/>
+ <point x="1065" y="-375"/>
+ <point x="1065" y="-160" type="curve" smooth="yes"/>
+ <point x="1065" y="-8"/>
+ <point x="967" y="90"/>
+ <point x="670" y="125" type="curve" smooth="yes"/>
+ <point x="410" y="156"/>
+ <point x="345" y="198"/>
+ <point x="345" y="235" type="curve" smooth="yes"/>
+ <point x="345" y="271"/>
+ <point x="384" y="316"/>
+ <point x="500" y="350" type="curve"/>
+ </contour>
+ <contour>
+ <point x="1050" y="1040" type="line"/>
+ <point x="951" y="1033"/>
+ <point x="819" y="997"/>
+ <point x="730" y="940" type="curve"/>
+ <point x="795" y="825" type="line"/>
+ <point x="887" y="863"/>
+ <point x="967" y="878"/>
+ <point x="1040" y="880" type="curve"/>
+ </contour>
+ <contour>
+ <point x="115" y="680" type="curve" smooth="yes"/>
+ <point x="115" y="476"/>
+ <point x="289" y="325"/>
+ <point x="515" y="325" type="curve" smooth="yes"/>
+ <point x="742" y="325"/>
+ <point x="915" y="476"/>
+ <point x="915" y="680" type="curve" smooth="yes"/>
+ <point x="915" y="884"/>
+ <point x="742" y="1040"/>
+ <point x="515" y="1040" type="curve" smooth="yes"/>
+ <point x="289" y="1040"/>
+ <point x="115" y="884"/>
+ </contour>
+ <contour>
+ <point x="285" y="680" type="curve" smooth="yes"/>
+ <point x="285" y="803"/>
+ <point x="382" y="895"/>
+ <point x="515" y="895" type="curve" smooth="yes"/>
+ <point x="649" y="895"/>
+ <point x="745" y="803"/>
+ <point x="745" y="680" type="curve" smooth="yes"/>
+ <point x="745" y="557"/>
+ <point x="649" y="465"/>
+ <point x="515" y="465" type="curve" smooth="yes"/>
+ <point x="382" y="465"/>
+ <point x="285" y="557"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfbuildcomp.ufo/glyphs/L_tnS_mH_.glif b/tests/reference/ufo/psfbuildcomp.ufo/glyphs/L_tnS_mH_.glif
new file mode 100644
index 0000000..bad060c
--- /dev/null
+++ b/tests/reference/ufo/psfbuildcomp.ufo/glyphs/L_tnS_mH_.glif
@@ -0,0 +1,43 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmH" format="2">
+ <advance width="1175"/>
+ <unicode hex="0068"/>
+ <anchor x="250" y="0" name="H"/>
+ <anchor x="585" y="-100" name="L"/>
+ <anchor x="585" y="1635" name="U"/>
+ <outline>
+ <contour>
+ <point x="1040" y="0" type="line"/>
+ <point x="1040" y="0"/>
+ <point x="1040" y="459"/>
+ <point x="1040" y="625" type="curve" smooth="yes"/>
+ <point x="1040" y="900"/>
+ <point x="923" y="1040"/>
+ <point x="710" y="1040" type="curve" smooth="yes"/>
+ <point x="570" y="1040"/>
+ <point x="428" y="969"/>
+ <point x="330" y="830" type="curve"/>
+ <point x="330" y="877"/>
+ <point x="330" y="1600"/>
+ <point x="330" y="1600" type="curve"/>
+ <point x="130" y="1600" type="line"/>
+ <point x="145" y="1514"/>
+ <point x="145" y="1345"/>
+ <point x="145" y="1130" type="curve" smooth="yes"/>
+ <point x="145" y="935"/>
+ <point x="145" y="0"/>
+ <point x="145" y="0" type="curve"/>
+ <point x="330" y="0" type="line"/>
+ <point x="330" y="580" type="line"/>
+ <point x="374" y="716"/>
+ <point x="511" y="865"/>
+ <point x="655" y="865" type="curve" smooth="yes"/>
+ <point x="789" y="865"/>
+ <point x="855" y="800"/>
+ <point x="855" y="550" type="curve" smooth="yes"/>
+ <point x="855" y="413"/>
+ <point x="855" y="0"/>
+ <point x="855" y="0" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfbuildcomp.ufo/glyphs/L_tnS_mI_.glif b/tests/reference/ufo/psfbuildcomp.ufo/glyphs/L_tnS_mI_.glif
new file mode 100644
index 0000000..369347b
--- /dev/null
+++ b/tests/reference/ufo/psfbuildcomp.ufo/glyphs/L_tnS_mI_.glif
@@ -0,0 +1,40 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmI" format="2">
+ <advance width="565"/>
+ <unicode hex="0069"/>
+ <anchor x="282" y="0" name="H"/>
+ <anchor x="285" y="-100" name="L"/>
+ <anchor x="500" y="0" name="O"/>
+ <anchor x="555" y="1000" name="R"/>
+ <anchor x="282" y="1100" name="U"/>
+ <outline>
+ <contour>
+ <point x="375" y="1020" type="line"/>
+ <point x="175" y="1020" type="line"/>
+ <point x="188" y="915"/>
+ <point x="190" y="725"/>
+ <point x="190" y="530" type="curve" smooth="yes"/>
+ <point x="190" y="336"/>
+ <point x="190" y="0"/>
+ <point x="190" y="0" type="curve"/>
+ <point x="395" y="0" type="line"/>
+ <point x="382" y="107"/>
+ <point x="375" y="346"/>
+ <point x="375" y="475" type="curve" smooth="yes"/>
+ </contour>
+ <contour>
+ <point x="155" y="1345" type="curve" smooth="yes"/>
+ <point x="155" y="1271"/>
+ <point x="206" y="1210"/>
+ <point x="280" y="1210" type="curve" smooth="yes"/>
+ <point x="355" y="1210"/>
+ <point x="410" y="1271"/>
+ <point x="410" y="1345" type="curve" smooth="yes"/>
+ <point x="410" y="1419"/>
+ <point x="355" y="1480"/>
+ <point x="280" y="1480" type="curve" smooth="yes"/>
+ <point x="206" y="1480"/>
+ <point x="155" y="1419"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfbuildcomp.ufo/glyphs/L_tnS_mI_J_.glif b/tests/reference/ufo/psfbuildcomp.ufo/glyphs/L_tnS_mI_J_.glif
new file mode 100644
index 0000000..f6ad58c
--- /dev/null
+++ b/tests/reference/ufo/psfbuildcomp.ufo/glyphs/L_tnS_mI_J_.glif
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmIJ" format="2">
+ <advance width="1160"/>
+ <unicode hex="0133"/>
+ <anchor x="282" y="0" name="H"/>
+ <anchor x="690" y="-500" name="L"/>
+ <anchor x="500" y="0" name="O"/>
+ <anchor x="555" y="1000" name="R"/>
+ <anchor x="878" y="1100" name="U"/>
+ <outline>
+ <component base="LtnSmI"/>
+ <component base="LtnSmJ" xOffset="565"/>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfbuildcomp.ufo/glyphs/L_tnS_mI_T_ilde.glif b/tests/reference/ufo/psfbuildcomp.ufo/glyphs/L_tnS_mI_T_ilde.glif
new file mode 100644
index 0000000..8da3a8d
--- /dev/null
+++ b/tests/reference/ufo/psfbuildcomp.ufo/glyphs/L_tnS_mI_T_ilde.glif
@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmITilde" format="2">
+ <advance width="400"/>
+ <unicode hex="0129"/>
+ <anchor x="0" y="375" name="U"/>
+ <outline>
+ <component base="CombTilde" xOffset="575" yOffset="-1100"/>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfbuildcomp.ufo/glyphs/L_tnS_mI_T_ildeG_rave.glif b/tests/reference/ufo/psfbuildcomp.ufo/glyphs/L_tnS_mI_T_ildeG_rave.glif
new file mode 100644
index 0000000..37bd42e
--- /dev/null
+++ b/tests/reference/ufo/psfbuildcomp.ufo/glyphs/L_tnS_mI_T_ildeG_rave.glif
@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmITildeGrave" format="2">
+ <unicode hex="E000"/>
+ <anchor x="0" y="910" name="U"/>
+ <outline>
+ <component base="CombTilde" xOffset="575" yOffset="-1100"/>
+ <component base="CombGrave" xOffset="550" yOffset="-725"/>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfbuildcomp.ufo/glyphs/L_tnS_mI_T_ildeG_raveC_edilla.glif b/tests/reference/ufo/psfbuildcomp.ufo/glyphs/L_tnS_mI_T_ildeG_raveC_edilla.glif
new file mode 100644
index 0000000..6d460d8
--- /dev/null
+++ b/tests/reference/ufo/psfbuildcomp.ufo/glyphs/L_tnS_mI_T_ildeG_raveC_edilla.glif
@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmITildeGraveCedilla" format="2">
+ <advance width="400"/>
+ <unicode hex="E010"/>
+ <anchor x="0" y="910" name="U"/>
+ <outline>
+ <component base="CombTilde" xOffset="575" yOffset="-1100"/>
+ <component base="CombGrave" xOffset="550" yOffset="-725"/>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfbuildcomp.ufo/glyphs/L_tnS_mJ_.glif b/tests/reference/ufo/psfbuildcomp.ufo/glyphs/L_tnS_mJ_.glif
new file mode 100644
index 0000000..87f74c6
--- /dev/null
+++ b/tests/reference/ufo/psfbuildcomp.ufo/glyphs/L_tnS_mJ_.glif
@@ -0,0 +1,44 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmJ" format="2">
+ <advance width="595"/>
+ <unicode hex="006A"/>
+ <anchor x="125" y="-500" name="L"/>
+ <anchor x="313" y="1100" name="U"/>
+ <outline>
+ <contour>
+ <point x="405" y="1020" type="line"/>
+ <point x="205" y="1020" type="line"/>
+ <point x="218" y="915"/>
+ <point x="220" y="725"/>
+ <point x="220" y="530" type="curve"/>
+ <point x="220" y="-25" type="line"/>
+ <point x="220" y="-222"/>
+ <point x="147" y="-300"/>
+ <point x="40" y="-300" type="curve" smooth="yes"/>
+ <point x="-16" y="-300"/>
+ <point x="-111" y="-273"/>
+ <point x="-155" y="-240" type="curve"/>
+ <point x="-190" y="-405" type="line"/>
+ <point x="-130" y="-446"/>
+ <point x="-26" y="-470"/>
+ <point x="30" y="-470" type="curve" smooth="yes"/>
+ <point x="258" y="-470"/>
+ <point x="405" y="-348"/>
+ <point x="405" y="25" type="curve" smooth="yes"/>
+ </contour>
+ <contour>
+ <point x="185" y="1345" type="curve" smooth="yes"/>
+ <point x="185" y="1271"/>
+ <point x="236" y="1210"/>
+ <point x="310" y="1210" type="curve" smooth="yes"/>
+ <point x="385" y="1210"/>
+ <point x="440" y="1271"/>
+ <point x="440" y="1345" type="curve" smooth="yes"/>
+ <point x="440" y="1419"/>
+ <point x="385" y="1480"/>
+ <point x="310" y="1480" type="curve" smooth="yes"/>
+ <point x="236" y="1480"/>
+ <point x="185" y="1419"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfbuildcomp.ufo/glyphs/L_tnS_mK_.glif b/tests/reference/ufo/psfbuildcomp.ufo/glyphs/L_tnS_mK_.glif
new file mode 100644
index 0000000..d1b00cb
--- /dev/null
+++ b/tests/reference/ufo/psfbuildcomp.ufo/glyphs/L_tnS_mK_.glif
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmK" format="2">
+ <advance width="1035"/>
+ <unicode hex="006B"/>
+ <guideline x="500" y="774" angle="314"/>
+ <anchor x="243" y="0" name="H"/>
+ <anchor x="572" y="-100" name="L"/>
+ <anchor x="1035" y="1000" name="R"/>
+ <anchor x="572" y="1635" name="U"/>
+ <outline>
+ <contour>
+ <point x="330" y="0" type="line"/>
+ <point x="330" y="1600" type="line"/>
+ <point x="130" y="1600" type="line"/>
+ <point x="145" y="1514"/>
+ <point x="145" y="1345"/>
+ <point x="145" y="1130" type="curve" smooth="yes"/>
+ <point x="145" y="934"/>
+ <point x="145" y="0"/>
+ <point x="145" y="0" type="curve"/>
+ </contour>
+ <contour>
+ <point x="735" y="1020" type="line"/>
+ <point x="280" y="550" type="line"/>
+ <point x="436" y="524" type="line"/>
+ <point x="985" y="1020" type="line"/>
+ </contour>
+ <contour>
+ <point x="305" y="550" type="line"/>
+ <point x="770" y="0" type="line"/>
+ <point x="1015" y="0" type="line"/>
+ <point x="410" y="660" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfbuildcomp.ufo/glyphs/L_tnS_mL_.glif b/tests/reference/ufo/psfbuildcomp.ufo/glyphs/L_tnS_mL_.glif
new file mode 100644
index 0000000..4378793
--- /dev/null
+++ b/tests/reference/ufo/psfbuildcomp.ufo/glyphs/L_tnS_mL_.glif
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmL" format="2">
+ <advance width="565"/>
+ <unicode hex="006C"/>
+ <guideline x="500" y="874" angle="340"/>
+ <anchor x="290" y="0" name="H"/>
+ <anchor x="290" y="-100" name="L"/>
+ <anchor x="550" y="1000" name="R"/>
+ <anchor x="282" y="1635" name="U"/>
+ <outline>
+ <contour>
+ <point x="375" y="1600" type="line"/>
+ <point x="170" y="1600" type="line"/>
+ <point x="183" y="1485"/>
+ <point x="190" y="1324"/>
+ <point x="190" y="1130" type="curve"/>
+ <point x="190" y="0" type="line"/>
+ <point x="395" y="0" type="line"/>
+ <point x="382" y="109"/>
+ <point x="375" y="346"/>
+ <point x="375" y="475" type="curve" smooth="yes"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfbuildcomp.ufo/glyphs/L_tnS_mM_.glif b/tests/reference/ufo/psfbuildcomp.ufo/glyphs/L_tnS_mM_.glif
new file mode 100644
index 0000000..4498bb1
--- /dev/null
+++ b/tests/reference/ufo/psfbuildcomp.ufo/glyphs/L_tnS_mM_.glif
@@ -0,0 +1,52 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmM" format="2">
+ <advance width="1685"/>
+ <unicode hex="006D"/>
+ <anchor x="1450" y="0" name="H"/>
+ <anchor x="865" y="-100" name="L"/>
+ <anchor x="865" y="1100" name="U"/>
+ <outline>
+ <contour>
+ <point x="945" y="660" type="line"/>
+ <point x="1003" y="785"/>
+ <point x="1102" y="865"/>
+ <point x="1200" y="865" type="curve" smooth="yes"/>
+ <point x="1312" y="865"/>
+ <point x="1345" y="808"/>
+ <point x="1345" y="550" type="curve" smooth="yes"/>
+ <point x="1345" y="0" type="line"/>
+ <point x="1530" y="0" type="line"/>
+ <point x="1530" y="660" type="line" smooth="yes"/>
+ <point x="1530" y="907"/>
+ <point x="1463" y="1040"/>
+ <point x="1260" y="1040" type="curve" smooth="yes"/>
+ <point x="1155" y="1040"/>
+ <point x="1046" y="1007"/>
+ <point x="921" y="872" type="curve"/>
+ <point x="888" y="960"/>
+ <point x="806" y="1040"/>
+ <point x="675" y="1040" type="curve" smooth="yes"/>
+ <point x="560" y="1040"/>
+ <point x="459" y="1006"/>
+ <point x="337" y="865" type="curve"/>
+ <point x="330" y="913"/>
+ <point x="320" y="978"/>
+ <point x="305" y="1020" type="curve"/>
+ <point x="125" y="1020" type="line"/>
+ <point x="146" y="951"/>
+ <point x="175" y="811"/>
+ <point x="175" y="615" type="curve" smooth="yes"/>
+ <point x="175" y="0" type="line"/>
+ <point x="360" y="0" type="line"/>
+ <point x="360" y="660" type="line"/>
+ <point x="413" y="780"/>
+ <point x="517" y="865"/>
+ <point x="615" y="865" type="curve" smooth="yes"/>
+ <point x="727" y="865"/>
+ <point x="760" y="818"/>
+ <point x="760" y="570" type="curve" smooth="yes"/>
+ <point x="760" y="0" type="line"/>
+ <point x="945" y="0" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfbuildcomp.ufo/glyphs/L_tnS_mN_.glif b/tests/reference/ufo/psfbuildcomp.ufo/glyphs/L_tnS_mN_.glif
new file mode 100644
index 0000000..5534dd8
--- /dev/null
+++ b/tests/reference/ufo/psfbuildcomp.ufo/glyphs/L_tnS_mN_.glif
@@ -0,0 +1,43 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmN" format="2">
+ <advance width="1185"/>
+ <unicode hex="006E"/>
+ <anchor x="970" y="0" name="H"/>
+ <anchor x="600" y="-100" name="L"/>
+ <anchor x="600" y="1100" name="U"/>
+ <outline>
+ <contour>
+ <point x="1050" y="0" type="line"/>
+ <point x="1050" y="0"/>
+ <point x="1050" y="459"/>
+ <point x="1050" y="625" type="curve" smooth="yes"/>
+ <point x="1050" y="900"/>
+ <point x="933" y="1040"/>
+ <point x="720" y="1040" type="curve" smooth="yes"/>
+ <point x="579" y="1040"/>
+ <point x="452" y="977"/>
+ <point x="325" y="825" type="curve"/>
+ <point x="318" y="873"/>
+ <point x="300" y="978"/>
+ <point x="285" y="1020" type="curve"/>
+ <point x="105" y="1020" type="line"/>
+ <point x="127" y="951"/>
+ <point x="155" y="811"/>
+ <point x="155" y="615" type="curve" smooth="yes"/>
+ <point x="155" y="420"/>
+ <point x="155" y="0"/>
+ <point x="155" y="0" type="curve"/>
+ <point x="340" y="0" type="line"/>
+ <point x="340" y="580" type="line"/>
+ <point x="384" y="716"/>
+ <point x="521" y="865"/>
+ <point x="665" y="865" type="curve" smooth="yes"/>
+ <point x="800" y="865"/>
+ <point x="865" y="800"/>
+ <point x="865" y="550" type="curve" smooth="yes"/>
+ <point x="865" y="413"/>
+ <point x="865" y="0"/>
+ <point x="865" y="0" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfbuildcomp.ufo/glyphs/L_tnS_mO_.glif b/tests/reference/ufo/psfbuildcomp.ufo/glyphs/L_tnS_mO_.glif
new file mode 100644
index 0000000..ee9b6c6
--- /dev/null
+++ b/tests/reference/ufo/psfbuildcomp.ufo/glyphs/L_tnS_mO_.glif
@@ -0,0 +1,40 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmO" format="2">
+ <advance width="1140"/>
+ <unicode hex="006F"/>
+ <anchor x="570" y="0" name="H"/>
+ <anchor x="570" y="-100" name="L"/>
+ <anchor x="835" y="0" name="O"/>
+ <anchor x="1140" y="1000" name="R"/>
+ <anchor x="570" y="1100" name="U"/>
+ <outline>
+ <contour>
+ <point x="95" y="505" type="curve" smooth="yes"/>
+ <point x="95" y="161"/>
+ <point x="286" y="-25"/>
+ <point x="560" y="-25" type="curve" smooth="yes"/>
+ <point x="823" y="-25"/>
+ <point x="1045" y="161"/>
+ <point x="1045" y="505" type="curve" smooth="yes"/>
+ <point x="1045" y="849"/>
+ <point x="855" y="1040"/>
+ <point x="580" y="1040" type="curve" smooth="yes"/>
+ <point x="317" y="1040"/>
+ <point x="95" y="849"/>
+ </contour>
+ <contour>
+ <point x="280" y="505" type="curve" smooth="yes"/>
+ <point x="280" y="739"/>
+ <point x="408" y="880"/>
+ <point x="570" y="880" type="curve" smooth="yes"/>
+ <point x="742" y="880"/>
+ <point x="860" y="739"/>
+ <point x="860" y="505" type="curve" smooth="yes"/>
+ <point x="860" y="272"/>
+ <point x="731" y="135"/>
+ <point x="570" y="135" type="curve" smooth="yes"/>
+ <point x="398" y="135"/>
+ <point x="280" y="272"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfbuildcomp.ufo/glyphs/L_tnS_mP_.glif b/tests/reference/ufo/psfbuildcomp.ufo/glyphs/L_tnS_mP_.glif
new file mode 100644
index 0000000..e960bc9
--- /dev/null
+++ b/tests/reference/ufo/psfbuildcomp.ufo/glyphs/L_tnS_mP_.glif
@@ -0,0 +1,56 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmP" format="2">
+ <advance width="1170"/>
+ <unicode hex="0070"/>
+ <guideline x="214" y="-490" angle="0"/>
+ <anchor x="265" y="-435" name="H"/>
+ <anchor x="590" y="-500" name="L"/>
+ <anchor x="1170" y="1000" name="R"/>
+ <anchor x="590" y="1100" name="U"/>
+ <outline>
+ <contour>
+ <point x="105" y="1020" type="line"/>
+ <point x="150" y="907"/>
+ <point x="155" y="734"/>
+ <point x="155" y="485" type="curve" smooth="yes"/>
+ <point x="155" y="291"/>
+ <point x="155" y="-490"/>
+ <point x="155" y="-490" type="curve"/>
+ <point x="365" y="-490" type="line"/>
+ <point x="348" y="-405"/>
+ <point x="340" y="-310"/>
+ <point x="340" y="-150" type="curve"/>
+ <point x="340" y="85" type="line"/>
+ <point x="435" y="18"/>
+ <point x="513" y="-25"/>
+ <point x="620" y="-25" type="curve" smooth="yes"/>
+ <point x="871" y="-25"/>
+ <point x="1075" y="193"/>
+ <point x="1075" y="535" type="curve" smooth="yes"/>
+ <point x="1075" y="828"/>
+ <point x="923" y="1040"/>
+ <point x="695" y="1040" type="curve" smooth="yes"/>
+ <point x="547" y="1040"/>
+ <point x="419" y="954"/>
+ <point x="325" y="830" type="curve"/>
+ <point x="316" y="922"/>
+ <point x="300" y="986"/>
+ <point x="285" y="1020" type="curve"/>
+ </contour>
+ <contour>
+ <point x="340" y="575" type="line"/>
+ <point x="414" y="768"/>
+ <point x="545" y="870"/>
+ <point x="660" y="870" type="curve" smooth="yes"/>
+ <point x="804" y="870"/>
+ <point x="890" y="727"/>
+ <point x="890" y="505" type="curve" smooth="yes"/>
+ <point x="890" y="279"/>
+ <point x="761" y="140"/>
+ <point x="620" y="140" type="curve" smooth="yes"/>
+ <point x="528" y="140"/>
+ <point x="477" y="164"/>
+ <point x="340" y="260" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfbuildcomp.ufo/glyphs/L_tnS_mQ_.glif b/tests/reference/ufo/psfbuildcomp.ufo/glyphs/L_tnS_mQ_.glif
new file mode 100644
index 0000000..1da1d6a
--- /dev/null
+++ b/tests/reference/ufo/psfbuildcomp.ufo/glyphs/L_tnS_mQ_.glif
@@ -0,0 +1,47 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmQ" format="2">
+ <advance width="1130"/>
+ <unicode hex="0071"/>
+ <anchor x="555" y="-500" name="L"/>
+ <anchor x="1130" y="1000" name="R"/>
+ <anchor x="555" y="1100" name="U"/>
+ <outline>
+ <contour>
+ <point x="795" y="-490" type="line"/>
+ <point x="1005" y="-490" type="line"/>
+ <point x="988" y="-405"/>
+ <point x="980" y="-310"/>
+ <point x="980" y="-150" type="curve" smooth="yes"/>
+ <point x="980" y="-26"/>
+ <point x="980" y="965"/>
+ <point x="980" y="965" type="curve"/>
+ <point x="872" y="1001"/>
+ <point x="746" y="1040"/>
+ <point x="625" y="1040" type="curve" smooth="yes"/>
+ <point x="260" y="1040"/>
+ <point x="105" y="742"/>
+ <point x="105" y="435" type="curve" smooth="yes"/>
+ <point x="105" y="117"/>
+ <point x="321" y="-25"/>
+ <point x="505" y="-25" type="curve" smooth="yes"/>
+ <point x="598" y="-25"/>
+ <point x="691" y="19"/>
+ <point x="795" y="140" type="curve"/>
+ </contour>
+ <contour>
+ <point x="795" y="365" type="line"/>
+ <point x="713" y="219"/>
+ <point x="612" y="145"/>
+ <point x="520" y="145" type="curve" smooth="yes"/>
+ <point x="412" y="145"/>
+ <point x="290" y="237"/>
+ <point x="290" y="485" type="curve" smooth="yes"/>
+ <point x="290" y="674"/>
+ <point x="376" y="870"/>
+ <point x="595" y="870" type="curve" smooth="yes"/>
+ <point x="656" y="870"/>
+ <point x="735" y="853"/>
+ <point x="795" y="830" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfbuildcomp.ufo/glyphs/L_tnS_mR_.glif b/tests/reference/ufo/psfbuildcomp.ufo/glyphs/L_tnS_mR_.glif
new file mode 100644
index 0000000..0f090a4
--- /dev/null
+++ b/tests/reference/ufo/psfbuildcomp.ufo/glyphs/L_tnS_mR_.glif
@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmR" format="2">
+ <advance width="890"/>
+ <unicode hex="0072"/>
+ <guideline x="214" y="500" angle="0"/>
+ <anchor x="270" y="0" name="H"/>
+ <anchor x="255" y="-100" name="L"/>
+ <anchor x="455" y="1100" name="U"/>
+ <outline>
+ <contour>
+ <point x="340" y="0" type="line"/>
+ <point x="340" y="580" type="line"/>
+ <point x="384" y="716"/>
+ <point x="521" y="860"/>
+ <point x="605" y="860" type="curve" smooth="yes"/>
+ <point x="684" y="860"/>
+ <point x="720" y="770"/>
+ <point x="720" y="670" type="curve"/>
+ <point x="880" y="705" type="line"/>
+ <point x="880" y="880"/>
+ <point x="817" y="1040"/>
+ <point x="650" y="1040" type="curve" smooth="yes"/>
+ <point x="559" y="1040"/>
+ <point x="422" y="964"/>
+ <point x="325" y="825" type="curve"/>
+ <point x="318" y="873"/>
+ <point x="300" y="978"/>
+ <point x="285" y="1020" type="curve"/>
+ <point x="105" y="1020" type="line"/>
+ <point x="127" y="951"/>
+ <point x="155" y="811"/>
+ <point x="155" y="615" type="curve" smooth="yes"/>
+ <point x="155" y="0" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfbuildcomp.ufo/glyphs/L_tnS_mS_.glif b/tests/reference/ufo/psfbuildcomp.ufo/glyphs/L_tnS_mS_.glif
new file mode 100644
index 0000000..ea1e7ba
--- /dev/null
+++ b/tests/reference/ufo/psfbuildcomp.ufo/glyphs/L_tnS_mS_.glif
@@ -0,0 +1,50 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmS" format="2">
+ <advance width="965"/>
+ <unicode hex="0073"/>
+ <anchor x="495" y="0" name="H"/>
+ <anchor x="495" y="-100" name="L"/>
+ <anchor x="495" y="1100" name="U"/>
+ <outline>
+ <contour>
+ <point x="835" y="960" type="line"/>
+ <point x="766" y="998"/>
+ <point x="660" y="1040"/>
+ <point x="515" y="1040" type="curve" smooth="yes"/>
+ <point x="211" y="1040"/>
+ <point x="130" y="832"/>
+ <point x="130" y="740" type="curve" smooth="yes"/>
+ <point x="130" y="616"/>
+ <point x="182" y="514"/>
+ <point x="425" y="455" type="curve" smooth="yes"/>
+ <point x="649" y="400"/>
+ <point x="700" y="345"/>
+ <point x="700" y="270" type="curve" smooth="yes"/>
+ <point x="700" y="201"/>
+ <point x="617" y="135"/>
+ <point x="500" y="135" type="curve" smooth="yes"/>
+ <point x="394" y="135"/>
+ <point x="250" y="189"/>
+ <point x="160" y="270" type="curve"/>
+ <point x="110" y="90" type="line"/>
+ <point x="189" y="28"/>
+ <point x="333" y="-25"/>
+ <point x="495" y="-25" type="curve" smooth="yes"/>
+ <point x="710" y="-25"/>
+ <point x="880" y="115"/>
+ <point x="880" y="295" type="curve" smooth="yes"/>
+ <point x="880" y="481"/>
+ <point x="731" y="559"/>
+ <point x="550" y="600" type="curve" smooth="yes"/>
+ <point x="340" y="648"/>
+ <point x="310" y="680"/>
+ <point x="310" y="750" type="curve" smooth="yes"/>
+ <point x="310" y="810"/>
+ <point x="358" y="880"/>
+ <point x="505" y="880" type="curve" smooth="yes"/>
+ <point x="629" y="880"/>
+ <point x="733" y="824"/>
+ <point x="800" y="785" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfbuildcomp.ufo/glyphs/L_tnS_mT_.glif b/tests/reference/ufo/psfbuildcomp.ufo/glyphs/L_tnS_mT_.glif
new file mode 100644
index 0000000..45d6b50
--- /dev/null
+++ b/tests/reference/ufo/psfbuildcomp.ufo/glyphs/L_tnS_mT_.glif
@@ -0,0 +1,39 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmT" format="2">
+ <advance width="835"/>
+ <unicode hex="0074"/>
+ <anchor x="475" y="0" name="H"/>
+ <anchor x="475" y="-100" name="L"/>
+ <anchor x="835" y="1000" name="R"/>
+ <anchor x="325" y="1360" name="U"/>
+ <outline>
+ <contour>
+ <point x="760" y="215" type="line"/>
+ <point x="672" y="166"/>
+ <point x="600" y="140"/>
+ <point x="543" y="140" type="curve" smooth="yes"/>
+ <point x="453" y="140"/>
+ <point x="415" y="184"/>
+ <point x="415" y="390" type="curve" smooth="yes"/>
+ <point x="415" y="528"/>
+ <point x="415" y="1320"/>
+ <point x="415" y="1320" type="curve"/>
+ <point x="230" y="1320" type="line"/>
+ <point x="230" y="1320"/>
+ <point x="230" y="435"/>
+ <point x="230" y="270" type="curve" smooth="yes"/>
+ <point x="230" y="39"/>
+ <point x="356" y="-25"/>
+ <point x="512" y="-25" type="curve" smooth="yes"/>
+ <point x="582" y="-25"/>
+ <point x="668" y="-4"/>
+ <point x="760" y="55" type="curve"/>
+ </contour>
+ <contour>
+ <point x="30" y="850" type="line"/>
+ <point x="740" y="850" type="line"/>
+ <point x="740" y="995" type="line"/>
+ <point x="30" y="995" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfbuildcomp.ufo/glyphs/L_tnS_mU_.glif b/tests/reference/ufo/psfbuildcomp.ufo/glyphs/L_tnS_mU_.glif
new file mode 100644
index 0000000..39609ad
--- /dev/null
+++ b/tests/reference/ufo/psfbuildcomp.ufo/glyphs/L_tnS_mU_.glif
@@ -0,0 +1,51 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmU" format="2">
+ <advance width="1185"/>
+ <unicode hex="0075"/>
+ <anchor x="589" y="0" name="H"/>
+ <anchor x="589" y="-100" name="L"/>
+ <anchor x="1192" y="0" name="O"/>
+ <anchor x="1185" y="1000" name="R"/>
+ <anchor x="589" y="1100" name="U"/>
+ <outline>
+ <contour>
+ <point x="1090" y="0" type="line"/>
+ <point x="1048" y="112"/>
+ <point x="1025" y="256"/>
+ <point x="1025" y="450" type="curve" smooth="yes"/>
+ <point x="1025" y="646"/>
+ <point x="1025" y="1020"/>
+ <point x="1025" y="1020" type="curve"/>
+ <point x="820" y="1020" type="line"/>
+ <point x="838" y="898"/>
+ <point x="840" y="832"/>
+ <point x="840" y="700" type="curve" smooth="yes"/>
+ <point x="840" y="420" type="line"/>
+ <point x="787" y="298"/>
+ <point x="628" y="140"/>
+ <point x="510" y="140" type="curve" smooth="yes"/>
+ <point x="383" y="140"/>
+ <point x="340" y="238"/>
+ <point x="340" y="465" type="curve" smooth="yes"/>
+ <point x="340" y="603"/>
+ <point x="340" y="1020"/>
+ <point x="340" y="1020" type="curve"/>
+ <point x="135" y="1020" type="line"/>
+ <point x="153" y="900"/>
+ <point x="155" y="827"/>
+ <point x="155" y="700" type="curve" smooth="yes"/>
+ <point x="155" y="681"/>
+ <point x="155" y="424"/>
+ <point x="155" y="405" type="curve" smooth="yes"/>
+ <point x="155" y="120"/>
+ <point x="262" y="-25"/>
+ <point x="475" y="-25" type="curve" smooth="yes"/>
+ <point x="615" y="-25"/>
+ <point x="744" y="53"/>
+ <point x="865" y="200" type="curve"/>
+ <point x="875" y="125"/>
+ <point x="901" y="46"/>
+ <point x="920" y="0" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfbuildcomp.ufo/glyphs/L_tnS_mV_.glif b/tests/reference/ufo/psfbuildcomp.ufo/glyphs/L_tnS_mV_.glif
new file mode 100644
index 0000000..3097f4b
--- /dev/null
+++ b/tests/reference/ufo/psfbuildcomp.ufo/glyphs/L_tnS_mV_.glif
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmV" format="2">
+ <advance width="1070"/>
+ <unicode hex="0076"/>
+ <anchor x="549" y="0" name="H"/>
+ <anchor x="535" y="-100" name="L"/>
+ <anchor x="725" y="0" name="O"/>
+ <anchor x="535" y="1100" name="U"/>
+ <outline>
+ <contour>
+ <point x="840" y="1020" type="line"/>
+ <point x="535" y="200" type="line"/>
+ <point x="230" y="1020" type="line"/>
+ <point x="20" y="1020" type="line"/>
+ <point x="75" y="905"/>
+ <point x="143" y="746"/>
+ <point x="175" y="665" type="curve" smooth="yes"/>
+ <point x="237" y="510"/>
+ <point x="440" y="0"/>
+ <point x="440" y="0" type="curve"/>
+ <point x="630" y="0" type="line"/>
+ <point x="630" y="0"/>
+ <point x="842" y="536"/>
+ <point x="895" y="665" type="curve" smooth="yes"/>
+ <point x="928" y="744"/>
+ <point x="993" y="905"/>
+ <point x="1050" y="1020" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfbuildcomp.ufo/glyphs/L_tnS_mW_.glif b/tests/reference/ufo/psfbuildcomp.ufo/glyphs/L_tnS_mW_.glif
new file mode 100644
index 0000000..3557415
--- /dev/null
+++ b/tests/reference/ufo/psfbuildcomp.ufo/glyphs/L_tnS_mW_.glif
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmW" format="2">
+ <advance width="1550"/>
+ <unicode hex="0077"/>
+ <anchor x="775" y="-100" name="L"/>
+ <anchor x="775" y="1100" name="U"/>
+ <outline>
+ <contour>
+ <point x="700" y="1020" type="line"/>
+ <point x="440" y="215" type="line"/>
+ <point x="230" y="1020" type="line"/>
+ <point x="45" y="1020" type="line"/>
+ <point x="92" y="867"/>
+ <point x="120" y="771"/>
+ <point x="150" y="665" type="curve" smooth="yes"/>
+ <point x="335" y="0" type="line"/>
+ <point x="525" y="0" type="line"/>
+ <point x="775" y="785" type="line"/>
+ <point x="1025" y="0" type="line"/>
+ <point x="1215" y="0" type="line"/>
+ <point x="1400" y="665" type="line" smooth="yes"/>
+ <point x="1434" y="785"/>
+ <point x="1458" y="868"/>
+ <point x="1505" y="1020" type="curve"/>
+ <point x="1320" y="1020" type="line"/>
+ <point x="1110" y="215" type="line"/>
+ <point x="850" y="1020" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfbuildcomp.ufo/glyphs/L_tnS_mX_.glif b/tests/reference/ufo/psfbuildcomp.ufo/glyphs/L_tnS_mX_.glif
new file mode 100644
index 0000000..883cba4
--- /dev/null
+++ b/tests/reference/ufo/psfbuildcomp.ufo/glyphs/L_tnS_mX_.glif
@@ -0,0 +1,40 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmX" format="2">
+ <advance width="1085"/>
+ <unicode hex="0078"/>
+ <anchor x="900" y="0" name="H"/>
+ <anchor x="542" y="-100" name="L"/>
+ <anchor x="542" y="1100" name="U"/>
+ <outline>
+ <contour>
+ <point x="805" y="0" type="line"/>
+ <point x="1035" y="0" type="line"/>
+ <point x="927" y="142"/>
+ <point x="902" y="170"/>
+ <point x="830" y="270" type="curve" smooth="yes"/>
+ <point x="290" y="1020" type="line"/>
+ <point x="60" y="1020" type="line"/>
+ <point x="168" y="887"/>
+ <point x="203" y="843"/>
+ <point x="270" y="750" type="curve"/>
+ </contour>
+ <contour>
+ <point x="489" y="616" type="line"/>
+ <point x="250" y="270" type="line" smooth="yes"/>
+ <point x="189" y="182"/>
+ <point x="160" y="143"/>
+ <point x="50" y="0" type="curve"/>
+ <point x="275" y="0" type="line"/>
+ <point x="556" y="404" type="line"/>
+ </contour>
+ <contour>
+ <point x="585" y="405" type="line"/>
+ <point x="820" y="750" type="line" smooth="yes"/>
+ <point x="883" y="842"/>
+ <point x="917" y="886"/>
+ <point x="1020" y="1020" type="curve"/>
+ <point x="795" y="1020" type="line"/>
+ <point x="520" y="615" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfbuildcomp.ufo/glyphs/L_tnS_mY_.glif b/tests/reference/ufo/psfbuildcomp.ufo/glyphs/L_tnS_mY_.glif
new file mode 100644
index 0000000..cbe0f68
--- /dev/null
+++ b/tests/reference/ufo/psfbuildcomp.ufo/glyphs/L_tnS_mY_.glif
@@ -0,0 +1,42 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmY" format="2">
+ <advance width="1060"/>
+ <unicode hex="0079"/>
+ <anchor x="795" y="-100" name="L"/>
+ <anchor x="1120" y="1000" name="R"/>
+ <anchor x="535" y="1100" name="U"/>
+ <outline>
+ <contour>
+ <point x="610" y="60" type="line"/>
+ <point x="230" y="1020" type="line"/>
+ <point x="30" y="1020" type="line"/>
+ <point x="107" y="864"/>
+ <point x="153" y="756"/>
+ <point x="190" y="665" type="curve" smooth="yes"/>
+ <point x="525" y="-165" type="line"/>
+ </contour>
+ <contour>
+ <point x="895" y="665" type="line"/>
+ <point x="928" y="758"/>
+ <point x="971" y="865"/>
+ <point x="1040" y="1020" type="curve"/>
+ <point x="840" y="1020" type="line"/>
+ <point x="840" y="1020"/>
+ <point x="564" y="230"/>
+ <point x="500" y="55" type="curve" smooth="yes"/>
+ <point x="391" y="-248"/>
+ <point x="315" y="-300"/>
+ <point x="225" y="-300" type="curve" smooth="yes"/>
+ <point x="159" y="-300"/>
+ <point x="82" y="-260"/>
+ <point x="40" y="-225" type="curve"/>
+ <point x="-20" y="-385" type="line"/>
+ <point x="53" y="-439"/>
+ <point x="134" y="-470"/>
+ <point x="225" y="-470" type="curve" smooth="yes"/>
+ <point x="395" y="-470"/>
+ <point x="516" y="-383"/>
+ <point x="655" y="0" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfbuildcomp.ufo/glyphs/N_onB_reakingH_yphen.glif b/tests/reference/ufo/psfbuildcomp.ufo/glyphs/N_onB_reakingH_yphen.glif
new file mode 100644
index 0000000..14aff81
--- /dev/null
+++ b/tests/reference/ufo/psfbuildcomp.ufo/glyphs/N_onB_reakingH_yphen.glif
@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="NonBreakingHyphen" format="2">
+ <advance width="860"/>
+ <unicode hex="2011"/>
+ <anchor x="430" y="1100" name="U"/>
+ <outline>
+ <component base="HyphenMinus"/>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfbuildcomp.ufo/glyphs/N_umS_gn.glif b/tests/reference/ufo/psfbuildcomp.ufo/glyphs/N_umS_gn.glif
new file mode 100644
index 0000000..f4625db
--- /dev/null
+++ b/tests/reference/ufo/psfbuildcomp.ufo/glyphs/N_umS_gn.glif
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="NumSgn" format="2">
+ <advance width="1200"/>
+ <unicode hex="0023"/>
+ <outline>
+ <contour>
+ <point x="487" y="1460" type="line"/>
+ <point x="127" y="200" type="line"/>
+ <point x="277" y="200" type="line"/>
+ <point x="637" y="1460" type="line"/>
+ </contour>
+ <contour>
+ <point x="25" y="575" type="line"/>
+ <point x="1116" y="575" type="line"/>
+ <point x="1116" y="725" type="line"/>
+ <point x="25" y="725" type="line"/>
+ </contour>
+ <contour>
+ <point x="84" y="960" type="line"/>
+ <point x="1175" y="960" type="line"/>
+ <point x="1175" y="1110" type="line"/>
+ <point x="84" y="1110" type="line"/>
+ </contour>
+ <contour>
+ <point x="912" y="1460" type="line"/>
+ <point x="552" y="200" type="line"/>
+ <point x="702" y="200" type="line"/>
+ <point x="1062" y="1460" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfbuildcomp.ufo/glyphs/P_ercentS_gn.glif b/tests/reference/ufo/psfbuildcomp.ufo/glyphs/P_ercentS_gn.glif
new file mode 100644
index 0000000..e81f237
--- /dev/null
+++ b/tests/reference/ufo/psfbuildcomp.ufo/glyphs/P_ercentS_gn.glif
@@ -0,0 +1,69 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="PercentSgn" format="2">
+ <advance width="1526"/>
+ <unicode hex="0025"/>
+ <outline>
+ <contour>
+ <point x="1261" y="366" type="curve" smooth="yes"/>
+ <point x="1261" y="182"/>
+ <point x="1216" y="115"/>
+ <point x="1130" y="115" type="curve" smooth="yes"/>
+ <point x="1041" y="115"/>
+ <point x="1001" y="181"/>
+ <point x="1001" y="381" type="curve" smooth="yes"/>
+ <point x="1001" y="565"/>
+ <point x="1043" y="630"/>
+ <point x="1130" y="630" type="curve" smooth="yes"/>
+ <point x="1221" y="630"/>
+ <point x="1261" y="566"/>
+ </contour>
+ <contour>
+ <point x="1426" y="379" type="curve" smooth="yes"/>
+ <point x="1426" y="652"/>
+ <point x="1310" y="770"/>
+ <point x="1135" y="770" type="curve" smooth="yes"/>
+ <point x="961" y="770"/>
+ <point x="836" y="650"/>
+ <point x="836" y="368" type="curve" smooth="yes"/>
+ <point x="836" y="86"/>
+ <point x="951" y="-25"/>
+ <point x="1126" y="-25" type="curve" smooth="yes"/>
+ <point x="1301" y="-25"/>
+ <point x="1426" y="84"/>
+ </contour>
+ <contour>
+ <point x="1073" y="1480" type="line"/>
+ <point x="291" y="-25" type="line"/>
+ <point x="459" y="-25" type="line"/>
+ <point x="1239" y="1480" type="line"/>
+ </contour>
+ <contour>
+ <point x="525" y="1076" type="curve" smooth="yes"/>
+ <point x="525" y="892"/>
+ <point x="480" y="825"/>
+ <point x="394" y="825" type="curve" smooth="yes"/>
+ <point x="305" y="825"/>
+ <point x="265" y="891"/>
+ <point x="265" y="1091" type="curve" smooth="yes"/>
+ <point x="265" y="1275"/>
+ <point x="307" y="1340"/>
+ <point x="394" y="1340" type="curve" smooth="yes"/>
+ <point x="485" y="1340"/>
+ <point x="525" y="1276"/>
+ </contour>
+ <contour>
+ <point x="690" y="1089" type="curve" smooth="yes"/>
+ <point x="690" y="1362"/>
+ <point x="574" y="1480"/>
+ <point x="399" y="1480" type="curve" smooth="yes"/>
+ <point x="225" y="1480"/>
+ <point x="100" y="1360"/>
+ <point x="100" y="1078" type="curve" smooth="yes"/>
+ <point x="100" y="796"/>
+ <point x="215" y="685"/>
+ <point x="390" y="685" type="curve" smooth="yes"/>
+ <point x="565" y="685"/>
+ <point x="690" y="794"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfbuildcomp.ufo/glyphs/P_lusS_gn.glif b/tests/reference/ufo/psfbuildcomp.ufo/glyphs/P_lusS_gn.glif
new file mode 100644
index 0000000..de1f259
--- /dev/null
+++ b/tests/reference/ufo/psfbuildcomp.ufo/glyphs/P_lusS_gn.glif
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="PlusSgn" format="2">
+ <advance width="1200"/>
+ <unicode hex="002B"/>
+ <outline>
+ <contour>
+ <point x="525" y="1180" type="line"/>
+ <point x="525" y="285" type="line"/>
+ <point x="675" y="285" type="line"/>
+ <point x="675" y="1180" type="line"/>
+ </contour>
+ <contour>
+ <point x="155" y="660" type="line"/>
+ <point x="1045" y="660" type="line"/>
+ <point x="1045" y="810" type="line"/>
+ <point x="155" y="810" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfbuildcomp.ufo/glyphs/Q_stnM_rk.glif b/tests/reference/ufo/psfbuildcomp.ufo/glyphs/Q_stnM_rk.glif
new file mode 100644
index 0000000..5526aec
--- /dev/null
+++ b/tests/reference/ufo/psfbuildcomp.ufo/glyphs/Q_stnM_rk.glif
@@ -0,0 +1,49 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="QstnMrk" format="2">
+ <advance width="1050"/>
+ <unicode hex="003F"/>
+ <outline>
+ <contour>
+ <point x="460" y="1540" type="curve" smooth="yes"/>
+ <point x="335" y="1540"/>
+ <point x="206" y="1493"/>
+ <point x="140" y="1430" type="curve"/>
+ <point x="185" y="1251" type="line"/>
+ <point x="261" y="1330"/>
+ <point x="352" y="1365"/>
+ <point x="432" y="1365" type="curve" smooth="yes"/>
+ <point x="579" y="1365"/>
+ <point x="625" y="1289"/>
+ <point x="625" y="1230" type="curve" smooth="yes"/>
+ <point x="625" y="1159"/>
+ <point x="572" y="1092"/>
+ <point x="485" y="980" type="curve" smooth="yes"/>
+ <point x="397" y="867"/>
+ <point x="355" y="730"/>
+ <point x="355" y="440" type="curve"/>
+ <point x="540" y="440" type="line"/>
+ <point x="540" y="721"/>
+ <point x="561" y="806"/>
+ <point x="665" y="927" type="curve" smooth="yes"/>
+ <point x="753" y="1028"/>
+ <point x="830" y="1117"/>
+ <point x="830" y="1240" type="curve" smooth="yes"/>
+ <point x="830" y="1422"/>
+ <point x="697" y="1540"/>
+ </contour>
+ <contour>
+ <point x="315" y="110" type="curve" smooth="yes"/>
+ <point x="315" y="36"/>
+ <point x="376" y="-25"/>
+ <point x="450" y="-25" type="curve" smooth="yes"/>
+ <point x="524" y="-25"/>
+ <point x="585" y="36"/>
+ <point x="585" y="110" type="curve" smooth="yes"/>
+ <point x="585" y="184"/>
+ <point x="524" y="245"/>
+ <point x="450" y="245" type="curve" smooth="yes"/>
+ <point x="376" y="245"/>
+ <point x="315" y="184"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfbuildcomp.ufo/glyphs/Q_uotM_rk.glif b/tests/reference/ufo/psfbuildcomp.ufo/glyphs/Q_uotM_rk.glif
new file mode 100644
index 0000000..c9f06c6
--- /dev/null
+++ b/tests/reference/ufo/psfbuildcomp.ufo/glyphs/Q_uotM_rk.glif
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="QuotMrk" format="2">
+ <advance width="1025"/>
+ <unicode hex="0022"/>
+ <outline>
+ <contour>
+ <point x="405" y="1045" type="line"/>
+ <point x="410" y="1186"/>
+ <point x="416" y="1339"/>
+ <point x="445" y="1585" type="curve"/>
+ <point x="240" y="1585" type="line"/>
+ <point x="271" y="1339"/>
+ <point x="276" y="1186"/>
+ <point x="280" y="1045" type="curve"/>
+ </contour>
+ <contour>
+ <point x="745" y="1045" type="line"/>
+ <point x="750" y="1186"/>
+ <point x="756" y="1339"/>
+ <point x="785" y="1585" type="curve"/>
+ <point x="580" y="1585" type="line"/>
+ <point x="611" y="1339"/>
+ <point x="616" y="1186"/>
+ <point x="620" y="1045" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfbuildcomp.ufo/glyphs/R_everseS_olidus.glif b/tests/reference/ufo/psfbuildcomp.ufo/glyphs/R_everseS_olidus.glif
new file mode 100644
index 0000000..d145f26
--- /dev/null
+++ b/tests/reference/ufo/psfbuildcomp.ufo/glyphs/R_everseS_olidus.glif
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="ReverseSolidus" format="2">
+ <advance width="1000"/>
+ <unicode hex="005C"/>
+ <outline>
+ <contour>
+ <point x="990" y="-245" type="line"/>
+ <point x="160" y="1600" type="line"/>
+ <point x="10" y="1600" type="line"/>
+ <point x="840" y="-245" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfbuildcomp.ufo/glyphs/R_tC_urlyB_rac.glif b/tests/reference/ufo/psfbuildcomp.ufo/glyphs/R_tC_urlyB_rac.glif
new file mode 100644
index 0000000..288a75a
--- /dev/null
+++ b/tests/reference/ufo/psfbuildcomp.ufo/glyphs/R_tC_urlyB_rac.glif
@@ -0,0 +1,47 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="RtCurlyBrac" format="2">
+ <advance width="1000"/>
+ <unicode hex="007D"/>
+ <outline>
+ <contour>
+ <point x="790" y="615" type="curve" smooth="yes"/>
+ <point x="790" y="647"/>
+ <point x="617" y="744"/>
+ <point x="590" y="780" type="curve" smooth="yes"/>
+ <point x="566" y="812"/>
+ <point x="576" y="1435"/>
+ <point x="505" y="1515" type="curve" smooth="yes"/>
+ <point x="465" y="1560"/>
+ <point x="304" y="1613"/>
+ <point x="200" y="1640" type="curve"/>
+ <point x="160" y="1500" type="line"/>
+ <point x="227" y="1477"/>
+ <point x="350" y="1428"/>
+ <point x="370" y="1400" type="curve" smooth="yes"/>
+ <point x="403" y="1353"/>
+ <point x="390" y="783"/>
+ <point x="410" y="745" type="curve" smooth="yes"/>
+ <point x="429" y="709"/>
+ <point x="566" y="637"/>
+ <point x="570" y="615" type="curve"/>
+ <point x="566" y="593"/>
+ <point x="429" y="521"/>
+ <point x="410" y="485" type="curve" smooth="yes"/>
+ <point x="390" y="447"/>
+ <point x="403" y="-123"/>
+ <point x="370" y="-170" type="curve" smooth="yes"/>
+ <point x="350" y="-198"/>
+ <point x="227" y="-247"/>
+ <point x="160" y="-270" type="curve"/>
+ <point x="200" y="-410" type="line"/>
+ <point x="304" y="-383"/>
+ <point x="465" y="-330"/>
+ <point x="505" y="-285" type="curve" smooth="yes"/>
+ <point x="576" y="-205"/>
+ <point x="566" y="418"/>
+ <point x="590" y="450" type="curve" smooth="yes"/>
+ <point x="617" y="486"/>
+ <point x="790" y="583"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfbuildcomp.ufo/glyphs/R_tP_aren.glif b/tests/reference/ufo/psfbuildcomp.ufo/glyphs/R_tP_aren.glif
new file mode 100644
index 0000000..3983f6b
--- /dev/null
+++ b/tests/reference/ufo/psfbuildcomp.ufo/glyphs/R_tP_aren.glif
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="RtParen" format="2">
+ <advance width="795"/>
+ <unicode hex="0029"/>
+ <outline>
+ <contour>
+ <point x="680" y="625" type="curve" smooth="yes"/>
+ <point x="680" y="1062"/>
+ <point x="505" y="1444"/>
+ <point x="240" y="1640" type="curve"/>
+ <point x="165" y="1485" type="line"/>
+ <point x="390" y="1280"/>
+ <point x="490" y="962"/>
+ <point x="490" y="625" type="curve" smooth="yes"/>
+ <point x="490" y="278"/>
+ <point x="390" y="-8"/>
+ <point x="165" y="-265" type="curve"/>
+ <point x="260" y="-410" type="line"/>
+ <point x="535" y="-125"/>
+ <point x="680" y="218"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfbuildcomp.ufo/glyphs/R_tS_qrB_rac.glif b/tests/reference/ufo/psfbuildcomp.ufo/glyphs/R_tS_qrB_rac.glif
new file mode 100644
index 0000000..702689b
--- /dev/null
+++ b/tests/reference/ufo/psfbuildcomp.ufo/glyphs/R_tS_qrB_rac.glif
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="RtSqrBrac" format="2">
+ <advance width="790"/>
+ <unicode hex="005D"/>
+ <outline>
+ <contour>
+ <point x="590" y="-410" type="line"/>
+ <point x="590" y="1600" type="line"/>
+ <point x="150" y="1600" type="line"/>
+ <point x="150" y="1450" type="line"/>
+ <point x="405" y="1450" type="line"/>
+ <point x="405" y="-260" type="line"/>
+ <point x="150" y="-260" type="line"/>
+ <point x="150" y="-410" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfbuildcomp.ufo/glyphs/S_emicolon.glif b/tests/reference/ufo/psfbuildcomp.ufo/glyphs/S_emicolon.glif
new file mode 100644
index 0000000..247bed0
--- /dev/null
+++ b/tests/reference/ufo/psfbuildcomp.ufo/glyphs/S_emicolon.glif
@@ -0,0 +1,38 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="Semicolon" format="2">
+ <advance width="650"/>
+ <unicode hex="003B"/>
+ <outline>
+ <contour>
+ <point x="185" y="790" type="curve" smooth="yes"/>
+ <point x="185" y="716"/>
+ <point x="246" y="655"/>
+ <point x="320" y="655" type="curve" smooth="yes"/>
+ <point x="394" y="655"/>
+ <point x="455" y="716"/>
+ <point x="455" y="790" type="curve" smooth="yes"/>
+ <point x="455" y="864"/>
+ <point x="394" y="925"/>
+ <point x="320" y="925" type="curve" smooth="yes"/>
+ <point x="246" y="925"/>
+ <point x="185" y="864"/>
+ </contour>
+ <contour>
+ <point x="185" y="50" type="line"/>
+ <point x="325" y="50" type="line"/>
+ <point x="325" y="-51"/>
+ <point x="248" y="-172"/>
+ <point x="190" y="-230" type="curve"/>
+ <point x="290" y="-270" type="line"/>
+ <point x="407" y="-160"/>
+ <point x="465" y="-37"/>
+ <point x="465" y="85" type="curve" smooth="yes"/>
+ <point x="465" y="186"/>
+ <point x="400" y="250"/>
+ <point x="320" y="250" type="curve" smooth="yes"/>
+ <point x="263" y="250"/>
+ <point x="198" y="213"/>
+ <point x="185" y="150" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfbuildcomp.ufo/glyphs/S_olidus.glif b/tests/reference/ufo/psfbuildcomp.ufo/glyphs/S_olidus.glif
new file mode 100644
index 0000000..3edff5d
--- /dev/null
+++ b/tests/reference/ufo/psfbuildcomp.ufo/glyphs/S_olidus.glif
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="Solidus" format="2">
+ <advance width="1000"/>
+ <unicode hex="002F"/>
+ <outline>
+ <contour>
+ <point x="840" y="1600" type="line"/>
+ <point x="10" y="-245" type="line"/>
+ <point x="160" y="-245" type="line"/>
+ <point x="990" y="1600" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfbuildcomp.ufo/glyphs/S_pace.glif b/tests/reference/ufo/psfbuildcomp.ufo/glyphs/S_pace.glif
new file mode 100644
index 0000000..ef0bed7
--- /dev/null
+++ b/tests/reference/ufo/psfbuildcomp.ufo/glyphs/S_pace.glif
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="Space" format="2">
+ <advance width="550"/>
+ <unicode hex="0020"/>
+ <outline/>
+</glyph>
diff --git a/tests/reference/ufo/psfbuildcomp.ufo/glyphs/T_ilde.glif b/tests/reference/ufo/psfbuildcomp.ufo/glyphs/T_ilde.glif
new file mode 100644
index 0000000..60ddaa7
--- /dev/null
+++ b/tests/reference/ufo/psfbuildcomp.ufo/glyphs/T_ilde.glif
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="Tilde" format="2">
+ <advance width="1115"/>
+ <unicode hex="007E"/>
+ <outline>
+ <contour>
+ <point x="125" y="375" type="line"/>
+ <point x="130" y="424"/>
+ <point x="162" y="465"/>
+ <point x="240" y="465" type="curve" smooth="yes"/>
+ <point x="415" y="465"/>
+ <point x="615" y="360"/>
+ <point x="845" y="360" type="curve" smooth="yes"/>
+ <point x="1004" y="360"/>
+ <point x="1080" y="482"/>
+ <point x="1080" y="610" type="curve"/>
+ <point x="975" y="610" type="line"/>
+ <point x="968" y="564"/>
+ <point x="938" y="510"/>
+ <point x="855" y="510" type="curve" smooth="yes"/>
+ <point x="619" y="510"/>
+ <point x="461" y="615"/>
+ <point x="240" y="615" type="curve" smooth="yes"/>
+ <point x="94" y="615"/>
+ <point x="20" y="497"/>
+ <point x="20" y="375" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfbuildcomp.ufo/glyphs/V_ertL_ine.glif b/tests/reference/ufo/psfbuildcomp.ufo/glyphs/V_ertL_ine.glif
new file mode 100644
index 0000000..c73e040
--- /dev/null
+++ b/tests/reference/ufo/psfbuildcomp.ufo/glyphs/V_ertL_ine.glif
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="VertLine" format="2">
+ <advance width="690"/>
+ <unicode hex="007C"/>
+ <outline>
+ <contour>
+ <point x="270" y="1600" type="line"/>
+ <point x="270" y="-390" type="line"/>
+ <point x="420" y="-390" type="line"/>
+ <point x="420" y="1600" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfbuildcomp.ufo/glyphs/_notdef.glif b/tests/reference/ufo/psfbuildcomp.ufo/glyphs/_notdef.glif
new file mode 100644
index 0000000..a3e9354
--- /dev/null
+++ b/tests/reference/ufo/psfbuildcomp.ufo/glyphs/_notdef.glif
@@ -0,0 +1,18 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name=".notdef" format="2">
+ <advance width="1400"/>
+ <outline>
+ <contour>
+ <point x="100" y="0" type="line"/>
+ <point x="1300" y="0" type="line"/>
+ <point x="1300" y="1800" type="line"/>
+ <point x="100" y="1800" type="line"/>
+ </contour>
+ <contour>
+ <point x="150" y="1750" type="line"/>
+ <point x="1250" y="1750" type="line"/>
+ <point x="1250" y="50" type="line"/>
+ <point x="150" y="50" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfbuildcomp.ufo/glyphs/_null.glif b/tests/reference/ufo/psfbuildcomp.ufo/glyphs/_null.glif
new file mode 100644
index 0000000..0b9caa6
--- /dev/null
+++ b/tests/reference/ufo/psfbuildcomp.ufo/glyphs/_null.glif
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name=".null" format="2">
+ <outline/>
+</glyph>
diff --git a/tests/reference/ufo/psfbuildcomp.ufo/glyphs/contents.plist b/tests/reference/ufo/psfbuildcomp.ufo/glyphs/contents.plist
new file mode 100644
index 0000000..6b6e31f
--- /dev/null
+++ b/tests/reference/ufo/psfbuildcomp.ufo/glyphs/contents.plist
@@ -0,0 +1,256 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+ <key>.notdef</key>
+ <string>_notdef.glif</string>
+ <key>.null</key>
+ <string>_null.glif</string>
+ <key>Ampersand</key>
+ <string>A_mpersand.glif</string>
+ <key>Apos</key>
+ <string>A_pos.glif</string>
+ <key>Asterisk</key>
+ <string>A_sterisk.glif</string>
+ <key>AtSgn</key>
+ <string>A_tS_gn.glif</string>
+ <key>CircumAccent</key>
+ <string>C_ircumA_ccent.glif</string>
+ <key>Colon</key>
+ <string>C_olon.glif</string>
+ <key>CombAcute</key>
+ <string>C_ombA_cute.glif</string>
+ <key>CombCircum</key>
+ <string>C_ombC_ircum.glif</string>
+ <key>CombDiaer</key>
+ <string>C_ombD_iaer.glif</string>
+ <key>CombGrave</key>
+ <string>C_ombG_rave.glif</string>
+ <key>CombRingAbv</key>
+ <string>C_ombR_ingA_bv.glif</string>
+ <key>CombTilde</key>
+ <string>C_ombT_ilde.glif</string>
+ <key>Comma</key>
+ <string>C_omma.glif</string>
+ <key>DigitEight</key>
+ <string>D_igitE_ight.glif</string>
+ <key>DigitFive</key>
+ <string>D_igitF_ive.glif</string>
+ <key>DigitFour</key>
+ <string>D_igitF_our.glif</string>
+ <key>DigitNine</key>
+ <string>D_igitN_ine.glif</string>
+ <key>DigitOne</key>
+ <string>D_igitO_ne.glif</string>
+ <key>DigitSeven</key>
+ <string>D_igitS_even.glif</string>
+ <key>DigitSix</key>
+ <string>D_igitS_ix.glif</string>
+ <key>DigitThree</key>
+ <string>D_igitT_hree.glif</string>
+ <key>DigitTwo</key>
+ <string>D_igitT_wo.glif</string>
+ <key>DigitZero</key>
+ <string>D_igitZ_ero.glif</string>
+ <key>DollarSgn</key>
+ <string>D_ollarS_gn.glif</string>
+ <key>DottedCirc</key>
+ <string>D_ottedC_irc.glif</string>
+ <key>EqSgn</key>
+ <string>E_qS_gn.glif</string>
+ <key>ExclamationMrk</key>
+ <string>E_xclamationM_rk.glif</string>
+ <key>FullStop</key>
+ <string>F_ullS_top.glif</string>
+ <key>GTSgn</key>
+ <string>G_T_S_gn.glif</string>
+ <key>GraveAccent</key>
+ <string>G_raveA_ccent.glif</string>
+ <key>Hyphen</key>
+ <string>H_yphen.glif</string>
+ <key>HyphenMinus</key>
+ <string>H_yphenM_inus.glif</string>
+ <key>Hyphen_Soft</key>
+ <string>H_yphen_S_oft.glif</string>
+ <key>LTSgn</key>
+ <string>L_T_S_gn.glif</string>
+ <key>LftCurlyBrac</key>
+ <string>L_ftC_urlyB_rac.glif</string>
+ <key>LftParen</key>
+ <string>L_ftP_aren.glif</string>
+ <key>LftSqrBrac</key>
+ <string>L_ftS_qrB_rac.glif</string>
+ <key>LowLine</key>
+ <string>L_owL_ine.glif</string>
+ <key>LtnCapA</key>
+ <string>L_tnC_apA_.glif</string>
+ <key>LtnCapA.alt</key>
+ <string>L_tnC_apA_.alt.glif</string>
+ <key>LtnCapADiaer</key>
+ <string>L_tnC_apA_D_iaer.glif</string>
+ <key>LtnCapB</key>
+ <string>L_tnC_apB_.glif</string>
+ <key>LtnCapC</key>
+ <string>L_tnC_apC_.glif</string>
+ <key>LtnCapCAcute</key>
+ <string>L_tnC_apC_A_cute.glif</string>
+ <key>LtnCapCAcuteCedilla</key>
+ <string>L_tnC_apC_A_cuteC_edilla.glif</string>
+ <key>LtnCapCCircum</key>
+ <string>L_tnC_apC_C_ircum.glif</string>
+ <key>LtnCapD</key>
+ <string>L_tnC_apD_.glif</string>
+ <key>LtnCapE</key>
+ <string>L_tnC_apE_.glif</string>
+ <key>LtnCapF</key>
+ <string>L_tnC_apF_.glif</string>
+ <key>LtnCapG</key>
+ <string>L_tnC_apG_.glif</string>
+ <key>LtnCapH</key>
+ <string>L_tnC_apH_.glif</string>
+ <key>LtnCapI</key>
+ <string>L_tnC_apI_.glif</string>
+ <key>LtnCapIJ</key>
+ <string>L_tnC_apI_J_.glif</string>
+ <key>LtnCapJ</key>
+ <string>L_tnC_apJ_.glif</string>
+ <key>LtnCapK</key>
+ <string>L_tnC_apK_.glif</string>
+ <key>LtnCapL</key>
+ <string>L_tnC_apL_.glif</string>
+ <key>LtnCapM</key>
+ <string>L_tnC_apM_.glif</string>
+ <key>LtnCapN</key>
+ <string>L_tnC_apN_.glif</string>
+ <key>LtnCapO</key>
+ <string>L_tnC_apO_.glif</string>
+ <key>LtnCapP</key>
+ <string>L_tnC_apP_.glif</string>
+ <key>LtnCapQ</key>
+ <string>L_tnC_apQ_.glif</string>
+ <key>LtnCapR</key>
+ <string>L_tnC_apR_.glif</string>
+ <key>LtnCapS</key>
+ <string>L_tnC_apS_.glif</string>
+ <key>LtnCapT</key>
+ <string>L_tnC_apT_.glif</string>
+ <key>LtnCapU</key>
+ <string>L_tnC_apU_.glif</string>
+ <key>LtnCapV</key>
+ <string>L_tnC_apV_.glif</string>
+ <key>LtnCapW</key>
+ <string>L_tnC_apW_.glif</string>
+ <key>LtnCapX</key>
+ <string>L_tnC_apX_.glif</string>
+ <key>LtnCapY</key>
+ <string>L_tnC_apY_.glif</string>
+ <key>LtnSmA</key>
+ <string>L_tnS_mA_.glif</string>
+ <key>LtnSmAAcute</key>
+ <string>L_tnS_mA_A_cute.glif</string>
+ <key>LtnSmACircum</key>
+ <string>L_tnS_mA_C_ircum.glif</string>
+ <key>LtnSmADiaer</key>
+ <string>L_tnS_mA_D_iaer.glif</string>
+ <key>LtnSmAGrave</key>
+ <string>L_tnS_mA_G_rave.glif</string>
+ <key>LtnSmARingAbv</key>
+ <string>L_tnS_mA_R_ingA_bv.glif</string>
+ <key>LtnSmATilde</key>
+ <string>L_tnS_mA_T_ilde.glif</string>
+ <key>LtnSmB</key>
+ <string>L_tnS_mB_.glif</string>
+ <key>LtnSmC</key>
+ <string>L_tnS_mC_.glif</string>
+ <key>LtnSmCAcute</key>
+ <string>L_tnS_mC_A_cute.glif</string>
+ <key>LtnSmCAcuteCedilla</key>
+ <string>L_tnS_mC_A_cuteC_edilla.glif</string>
+ <key>LtnSmCCircum</key>
+ <string>L_tnS_mC_C_ircum.glif</string>
+ <key>LtnSmD</key>
+ <string>L_tnS_mD_.glif</string>
+ <key>LtnSmE</key>
+ <string>L_tnS_mE_.glif</string>
+ <key>LtnSmF</key>
+ <string>L_tnS_mF_.glif</string>
+ <key>LtnSmG</key>
+ <string>L_tnS_mG_.glif</string>
+ <key>LtnSmH</key>
+ <string>L_tnS_mH_.glif</string>
+ <key>LtnSmI</key>
+ <string>L_tnS_mI_.glif</string>
+ <key>LtnSmIJ</key>
+ <string>L_tnS_mI_J_.glif</string>
+ <key>LtnSmITilde</key>
+ <string>L_tnS_mI_T_ilde.glif</string>
+ <key>LtnSmITildeGrave</key>
+ <string>L_tnS_mI_T_ildeG_rave.glif</string>
+ <key>LtnSmITildeGraveCedilla</key>
+ <string>L_tnS_mI_T_ildeG_raveC_edilla.glif</string>
+ <key>LtnSmJ</key>
+ <string>L_tnS_mJ_.glif</string>
+ <key>LtnSmK</key>
+ <string>L_tnS_mK_.glif</string>
+ <key>LtnSmL</key>
+ <string>L_tnS_mL_.glif</string>
+ <key>LtnSmM</key>
+ <string>L_tnS_mM_.glif</string>
+ <key>LtnSmN</key>
+ <string>L_tnS_mN_.glif</string>
+ <key>LtnSmO</key>
+ <string>L_tnS_mO_.glif</string>
+ <key>LtnSmP</key>
+ <string>L_tnS_mP_.glif</string>
+ <key>LtnSmQ</key>
+ <string>L_tnS_mQ_.glif</string>
+ <key>LtnSmR</key>
+ <string>L_tnS_mR_.glif</string>
+ <key>LtnSmS</key>
+ <string>L_tnS_mS_.glif</string>
+ <key>LtnSmT</key>
+ <string>L_tnS_mT_.glif</string>
+ <key>LtnSmU</key>
+ <string>L_tnS_mU_.glif</string>
+ <key>LtnSmV</key>
+ <string>L_tnS_mV_.glif</string>
+ <key>LtnSmW</key>
+ <string>L_tnS_mW_.glif</string>
+ <key>LtnSmX</key>
+ <string>L_tnS_mX_.glif</string>
+ <key>LtnSmY</key>
+ <string>L_tnS_mY_.glif</string>
+ <key>NonBreakingHyphen</key>
+ <string>N_onB_reakingH_yphen.glif</string>
+ <key>NumSgn</key>
+ <string>N_umS_gn.glif</string>
+ <key>PercentSgn</key>
+ <string>P_ercentS_gn.glif</string>
+ <key>PlusSgn</key>
+ <string>P_lusS_gn.glif</string>
+ <key>QstnMrk</key>
+ <string>Q_stnM_rk.glif</string>
+ <key>QuotMrk</key>
+ <string>Q_uotM_rk.glif</string>
+ <key>ReverseSolidus</key>
+ <string>R_everseS_olidus.glif</string>
+ <key>RtCurlyBrac</key>
+ <string>R_tC_urlyB_rac.glif</string>
+ <key>RtParen</key>
+ <string>R_tP_aren.glif</string>
+ <key>RtSqrBrac</key>
+ <string>R_tS_qrB_rac.glif</string>
+ <key>Semicolon</key>
+ <string>S_emicolon.glif</string>
+ <key>Solidus</key>
+ <string>S_olidus.glif</string>
+ <key>Space</key>
+ <string>S_pace.glif</string>
+ <key>Tilde</key>
+ <string>T_ilde.glif</string>
+ <key>VertLine</key>
+ <string>V_ertL_ine.glif</string>
+ <key>nonmarkingreturn</key>
+ <string>nonmarkingreturn.glif</string>
+</dict>
+</plist>
diff --git a/tests/reference/ufo/psfbuildcomp.ufo/glyphs/nonmarkingreturn.glif b/tests/reference/ufo/psfbuildcomp.ufo/glyphs/nonmarkingreturn.glif
new file mode 100644
index 0000000..ee41448
--- /dev/null
+++ b/tests/reference/ufo/psfbuildcomp.ufo/glyphs/nonmarkingreturn.glif
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="nonmarkingreturn" format="2">
+ <advance width="1024"/>
+ <outline/>
+</glyph>
diff --git a/tests/reference/ufo/psfbuildcomp.ufo/layercontents.plist b/tests/reference/ufo/psfbuildcomp.ufo/layercontents.plist
new file mode 100644
index 0000000..42b7482
--- /dev/null
+++ b/tests/reference/ufo/psfbuildcomp.ufo/layercontents.plist
@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<array>
+ <array>
+ <string>public.default</string>
+ <string>glyphs</string>
+ </array>
+</array>
+</plist>
diff --git a/tests/reference/ufo/psfbuildcomp.ufo/lib.plist b/tests/reference/ufo/psfbuildcomp.ufo/lib.plist
new file mode 100644
index 0000000..8b95204
--- /dev/null
+++ b/tests/reference/ufo/psfbuildcomp.ufo/lib.plist
@@ -0,0 +1,536 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+ <key>com.schriftgestaltung.Glyphs.fontUserData</key>
+ <dict/>
+ <key>com.schriftgestaltung.appVersion</key>
+ <string>1161</string>
+ <key>com.schriftgestaltung.customParameter.GSFont.DisplayStrings</key>
+ <string/>
+ <key>com.schriftgestaltung.customParameter.GSFont.disablesAutomaticAlignment</key>
+ <true/>
+ <key>com.schriftgestaltung.customParameter.GSFont.disablesLastChange</key>
+ <true/>
+ <key>com.schriftgestaltung.customParameter.GSFont.useNiceNames</key>
+ <integer>0</integer>
+ <key>com.schriftgestaltung.customParameter.GSFontMaster.customValue</key>
+ <integer>0</integer>
+ <key>com.schriftgestaltung.customParameter.GSFontMaster.customValue1</key>
+ <integer>0</integer>
+ <key>com.schriftgestaltung.customParameter.GSFontMaster.customValue2</key>
+ <integer>0</integer>
+ <key>com.schriftgestaltung.customParameter.GSFontMaster.customValue3</key>
+ <integer>0</integer>
+ <key>com.schriftgestaltung.customParameter.GSFontMaster.iconName</key>
+ <string/>
+ <key>com.schriftgestaltung.customParameter.GSFontMaster.weightValue</key>
+ <integer>400</integer>
+ <key>com.schriftgestaltung.customParameter.GSFontMaster.widthValue</key>
+ <integer>100</integer>
+ <key>com.schriftgestaltung.disablesAutomaticAlignment</key>
+ <true/>
+ <key>com.schriftgestaltung.disablesLastChange</key>
+ <true/>
+ <key>com.schriftgestaltung.fontMasterOrder</key>
+ <integer>0</integer>
+ <key>com.schriftgestaltung.glyphOrder</key>
+ <array>
+ <string>.notdef</string>
+ <string>.null</string>
+ <string>nonmarkingreturn</string>
+ <string>Space</string>
+ <string>ExclamationMrk</string>
+ <string>QuotMrk</string>
+ <string>NumSgn</string>
+ <string>DollarSgn</string>
+ <string>PercentSgn</string>
+ <string>Ampersand</string>
+ <string>Apos</string>
+ <string>LftParen</string>
+ <string>RtParen</string>
+ <string>Asterisk</string>
+ <string>PlusSgn</string>
+ <string>Comma</string>
+ <string>HyphenMinus</string>
+ <string>FullStop</string>
+ <string>Solidus</string>
+ <string>DigitZero</string>
+ <string>DigitOne</string>
+ <string>DigitTwo</string>
+ <string>DigitThree</string>
+ <string>DigitFour</string>
+ <string>DigitFive</string>
+ <string>DigitSix</string>
+ <string>DigitSeven</string>
+ <string>DigitEight</string>
+ <string>DigitNine</string>
+ <string>Colon</string>
+ <string>Semicolon</string>
+ <string>LTSgn</string>
+ <string>EqSgn</string>
+ <string>GTSgn</string>
+ <string>QstnMrk</string>
+ <string>AtSgn</string>
+ <string>LtnCapA</string>
+ <string>LtnCapA.alt</string>
+ <string>LtnCapB</string>
+ <string>LtnCapC</string>
+ <string>LtnCapD</string>
+ <string>LtnCapE</string>
+ <string>LtnCapF</string>
+ <string>LtnCapG</string>
+ <string>LtnCapH</string>
+ <string>LtnCapI</string>
+ <string>LtnCapJ</string>
+ <string>LtnCapK</string>
+ <string>LtnCapL</string>
+ <string>LtnCapM</string>
+ <string>LtnCapN</string>
+ <string>LtnCapO</string>
+ <string>LtnCapP</string>
+ <string>LtnCapQ</string>
+ <string>LtnCapR</string>
+ <string>LtnCapS</string>
+ <string>LtnCapT</string>
+ <string>LtnCapU</string>
+ <string>LtnCapV</string>
+ <string>LtnCapW</string>
+ <string>LtnCapX</string>
+ <string>LtnCapY</string>
+ <string>LftSqrBrac</string>
+ <string>ReverseSolidus</string>
+ <string>RtSqrBrac</string>
+ <string>CircumAccent</string>
+ <string>LowLine</string>
+ <string>GraveAccent</string>
+ <string>LtnSmA</string>
+ <string>LtnSmB</string>
+ <string>LtnSmC</string>
+ <string>LtnSmD</string>
+ <string>LtnSmE</string>
+ <string>LtnSmF</string>
+ <string>LtnSmG</string>
+ <string>LtnSmH</string>
+ <string>LtnSmI</string>
+ <string>LtnSmJ</string>
+ <string>LtnSmK</string>
+ <string>LtnSmL</string>
+ <string>LtnSmM</string>
+ <string>LtnSmN</string>
+ <string>LtnSmO</string>
+ <string>LtnSmP</string>
+ <string>LtnSmQ</string>
+ <string>LtnSmR</string>
+ <string>LtnSmS</string>
+ <string>LtnSmT</string>
+ <string>LtnSmU</string>
+ <string>LtnSmV</string>
+ <string>LtnSmW</string>
+ <string>LtnSmX</string>
+ <string>LtnSmY</string>
+ <string>LftCurlyBrac</string>
+ <string>VertLine</string>
+ <string>RtCurlyBrac</string>
+ <string>Tilde</string>
+ <string>LtnCapADiaer</string>
+ <string>LtnSmAAcute</string>
+ <string>LtnSmAGrave</string>
+ <string>LtnSmACircum</string>
+ <string>LtnSmADiaer</string>
+ <string>LtnSmATilde</string>
+ <string>LtnSmARingAbv</string>
+ <string>DottedCirc</string>
+ <string>Hyphen</string>
+ <string>NonBreakingHyphen</string>
+ <string>Hyphen_Soft</string>
+ <string>CombAcute</string>
+ <string>CombGrave</string>
+ <string>CombCircum</string>
+ <string>CombTilde</string>
+ <string>CombDiaer</string>
+ <string>CombRingAbv</string>
+ </array>
+ <key>com.schriftgestaltung.keyboardIncrement</key>
+ <integer>1</integer>
+ <key>com.schriftgestaltung.weight</key>
+ <string>Regular</string>
+ <key>com.schriftgestaltung.weightValue</key>
+ <integer>400</integer>
+ <key>com.schriftgestaltung.width</key>
+ <string>Regular</string>
+ <key>com.schriftgestaltung.widthValue</key>
+ <integer>100</integer>
+ <key>org.sil.lcg.toneLetters</key>
+ <dict>
+ <key>contourWidth</key>
+ <integer>480</integer>
+ <key>dotSize</key>
+ <integer>180</integer>
+ <key>dotSpacing</key>
+ <integer>200</integer>
+ <key>glyphDepth</key>
+ <integer>-25</integer>
+ <key>glyphHeight</key>
+ <integer>1600</integer>
+ <key>italicAngle</key>
+ <integer>0</integer>
+ <key>marginDotLeft</key>
+ <integer>120</integer>
+ <key>marginDotRight</key>
+ <integer>160</integer>
+ <key>marginFlatLeft</key>
+ <integer>120</integer>
+ <key>marginFlatRight</key>
+ <integer>160</integer>
+ <key>marginPointLeft</key>
+ <integer>100</integer>
+ <key>marginPointRight</key>
+ <integer>140</integer>
+ <key>strokeThickness</key>
+ <integer>120</integer>
+ </dict>
+ <key>public.glyphOrder</key>
+ <array>
+ <string>.notdef</string>
+ <string>.null</string>
+ <string>nonmarkingreturn</string>
+ <string>Space</string>
+ <string>ExclamationMrk</string>
+ <string>QuotMrk</string>
+ <string>NumSgn</string>
+ <string>DollarSgn</string>
+ <string>PercentSgn</string>
+ <string>Ampersand</string>
+ <string>Apos</string>
+ <string>LftParen</string>
+ <string>RtParen</string>
+ <string>Asterisk</string>
+ <string>PlusSgn</string>
+ <string>Comma</string>
+ <string>HyphenMinus</string>
+ <string>FullStop</string>
+ <string>Solidus</string>
+ <string>DigitZero</string>
+ <string>DigitOne</string>
+ <string>DigitTwo</string>
+ <string>DigitThree</string>
+ <string>DigitFour</string>
+ <string>DigitFive</string>
+ <string>DigitSix</string>
+ <string>DigitSeven</string>
+ <string>DigitEight</string>
+ <string>DigitNine</string>
+ <string>Colon</string>
+ <string>Semicolon</string>
+ <string>LTSgn</string>
+ <string>EqSgn</string>
+ <string>GTSgn</string>
+ <string>QstnMrk</string>
+ <string>AtSgn</string>
+ <string>LtnCapA</string>
+ <string>LtnCapA.alt</string>
+ <string>LtnCapB</string>
+ <string>LtnCapC</string>
+ <string>LtnCapD</string>
+ <string>LtnCapE</string>
+ <string>LtnCapF</string>
+ <string>LtnCapG</string>
+ <string>LtnCapH</string>
+ <string>LtnCapI</string>
+ <string>LtnCapJ</string>
+ <string>LtnCapK</string>
+ <string>LtnCapL</string>
+ <string>LtnCapM</string>
+ <string>LtnCapN</string>
+ <string>LtnCapO</string>
+ <string>LtnCapP</string>
+ <string>LtnCapQ</string>
+ <string>LtnCapR</string>
+ <string>LtnCapS</string>
+ <string>LtnCapT</string>
+ <string>LtnCapU</string>
+ <string>LtnCapV</string>
+ <string>LtnCapW</string>
+ <string>LtnCapX</string>
+ <string>LtnCapY</string>
+ <string>LftSqrBrac</string>
+ <string>ReverseSolidus</string>
+ <string>RtSqrBrac</string>
+ <string>CircumAccent</string>
+ <string>LowLine</string>
+ <string>GraveAccent</string>
+ <string>LtnSmA</string>
+ <string>LtnSmB</string>
+ <string>LtnSmC</string>
+ <string>LtnSmD</string>
+ <string>LtnSmE</string>
+ <string>LtnSmF</string>
+ <string>LtnSmG</string>
+ <string>LtnSmH</string>
+ <string>LtnSmI</string>
+ <string>LtnSmJ</string>
+ <string>LtnSmK</string>
+ <string>LtnSmL</string>
+ <string>LtnSmM</string>
+ <string>LtnSmN</string>
+ <string>LtnSmO</string>
+ <string>LtnSmP</string>
+ <string>LtnSmQ</string>
+ <string>LtnSmR</string>
+ <string>LtnSmS</string>
+ <string>LtnSmT</string>
+ <string>LtnSmU</string>
+ <string>LtnSmV</string>
+ <string>LtnSmW</string>
+ <string>LtnSmX</string>
+ <string>LtnSmY</string>
+ <string>LftCurlyBrac</string>
+ <string>VertLine</string>
+ <string>RtCurlyBrac</string>
+ <string>Tilde</string>
+ <string>LtnCapADiaer</string>
+ <string>LtnSmAAcute</string>
+ <string>LtnSmAGrave</string>
+ <string>LtnSmACircum</string>
+ <string>LtnSmADiaer</string>
+ <string>LtnSmATilde</string>
+ <string>LtnSmARingAbv</string>
+ <string>DottedCirc</string>
+ <string>Hyphen</string>
+ <string>NonBreakingHyphen</string>
+ <string>Hyphen_Soft</string>
+ <string>CombAcute</string>
+ <string>CombGrave</string>
+ <string>CombCircum</string>
+ <string>CombTilde</string>
+ <string>CombDiaer</string>
+ <string>CombRingAbv</string>
+ </array>
+ <key>public.postscriptNames</key>
+ <dict>
+ <key>Ampersand</key>
+ <string>ampersand</string>
+ <key>Apos</key>
+ <string>quotesingle</string>
+ <key>Asterisk</key>
+ <string>asterisk</string>
+ <key>AtSgn</key>
+ <string>at</string>
+ <key>CircumAccent</key>
+ <string>asciicircum</string>
+ <key>Colon</key>
+ <string>colon</string>
+ <key>CombAcute</key>
+ <string>acutecomb</string>
+ <key>CombCircum</key>
+ <string>uni0302</string>
+ <key>CombDiaer</key>
+ <string>uni0308</string>
+ <key>CombGrave</key>
+ <string>gravecomb</string>
+ <key>CombRingAbv</key>
+ <string>uni030A</string>
+ <key>CombTilde</key>
+ <string>tildecomb</string>
+ <key>Comma</key>
+ <string>comma</string>
+ <key>DigitEight</key>
+ <string>eight</string>
+ <key>DigitFive</key>
+ <string>five</string>
+ <key>DigitFour</key>
+ <string>four</string>
+ <key>DigitNine</key>
+ <string>nine</string>
+ <key>DigitOne</key>
+ <string>one</string>
+ <key>DigitSeven</key>
+ <string>seven</string>
+ <key>DigitSix</key>
+ <string>six</string>
+ <key>DigitThree</key>
+ <string>three</string>
+ <key>DigitTwo</key>
+ <string>two</string>
+ <key>DigitZero</key>
+ <string>zero</string>
+ <key>DollarSgn</key>
+ <string>dollar</string>
+ <key>DottedCirc</key>
+ <string>uni25CC</string>
+ <key>EqSgn</key>
+ <string>equal</string>
+ <key>ExclamationMrk</key>
+ <string>exclam</string>
+ <key>FullStop</key>
+ <string>period</string>
+ <key>GTSgn</key>
+ <string>greater</string>
+ <key>GraveAccent</key>
+ <string>grave</string>
+ <key>Hyphen</key>
+ <string>uni2010</string>
+ <key>HyphenMinus</key>
+ <string>hyphen</string>
+ <key>Hyphen_Soft</key>
+ <string>uni00AD</string>
+ <key>LTSgn</key>
+ <string>less</string>
+ <key>LftCurlyBrac</key>
+ <string>braceleft</string>
+ <key>LftParen</key>
+ <string>parenleft</string>
+ <key>LftSqrBrac</key>
+ <string>bracketleft</string>
+ <key>LowLine</key>
+ <string>underscore</string>
+ <key>LtnCapA</key>
+ <string>A</string>
+ <key>LtnCapA.alt</key>
+ <string>A</string>
+ <key>LtnCapADiaer</key>
+ <string>Adieresis</string>
+ <key>LtnCapB</key>
+ <string>B</string>
+ <key>LtnCapC</key>
+ <string>C</string>
+ <key>LtnCapD</key>
+ <string>D</string>
+ <key>LtnCapE</key>
+ <string>E</string>
+ <key>LtnCapF</key>
+ <string>F</string>
+ <key>LtnCapG</key>
+ <string>G</string>
+ <key>LtnCapH</key>
+ <string>H</string>
+ <key>LtnCapI</key>
+ <string>I</string>
+ <key>LtnCapJ</key>
+ <string>J</string>
+ <key>LtnCapK</key>
+ <string>K</string>
+ <key>LtnCapL</key>
+ <string>L</string>
+ <key>LtnCapM</key>
+ <string>M</string>
+ <key>LtnCapN</key>
+ <string>N</string>
+ <key>LtnCapO</key>
+ <string>O</string>
+ <key>LtnCapP</key>
+ <string>P</string>
+ <key>LtnCapQ</key>
+ <string>Q</string>
+ <key>LtnCapR</key>
+ <string>R</string>
+ <key>LtnCapS</key>
+ <string>S</string>
+ <key>LtnCapT</key>
+ <string>T</string>
+ <key>LtnCapU</key>
+ <string>U</string>
+ <key>LtnCapV</key>
+ <string>V</string>
+ <key>LtnCapW</key>
+ <string>W</string>
+ <key>LtnCapX</key>
+ <string>X</string>
+ <key>LtnCapY</key>
+ <string>Y</string>
+ <key>LtnSmA</key>
+ <string>a</string>
+ <key>LtnSmAAcute</key>
+ <string>aacute</string>
+ <key>LtnSmACircum</key>
+ <string>acircumflex</string>
+ <key>LtnSmADiaer</key>
+ <string>adieresis</string>
+ <key>LtnSmAGrave</key>
+ <string>agrave</string>
+ <key>LtnSmARingAbv</key>
+ <string>aring</string>
+ <key>LtnSmATilde</key>
+ <string>atilde</string>
+ <key>LtnSmB</key>
+ <string>b</string>
+ <key>LtnSmC</key>
+ <string>c</string>
+ <key>LtnSmD</key>
+ <string>d</string>
+ <key>LtnSmE</key>
+ <string>e</string>
+ <key>LtnSmF</key>
+ <string>f</string>
+ <key>LtnSmG</key>
+ <string>g</string>
+ <key>LtnSmH</key>
+ <string>h</string>
+ <key>LtnSmI</key>
+ <string>i</string>
+ <key>LtnSmJ</key>
+ <string>j</string>
+ <key>LtnSmK</key>
+ <string>k</string>
+ <key>LtnSmL</key>
+ <string>l</string>
+ <key>LtnSmM</key>
+ <string>m</string>
+ <key>LtnSmN</key>
+ <string>n</string>
+ <key>LtnSmO</key>
+ <string>o</string>
+ <key>LtnSmP</key>
+ <string>p</string>
+ <key>LtnSmQ</key>
+ <string>q</string>
+ <key>LtnSmR</key>
+ <string>r</string>
+ <key>LtnSmS</key>
+ <string>s</string>
+ <key>LtnSmT</key>
+ <string>t</string>
+ <key>LtnSmU</key>
+ <string>u</string>
+ <key>LtnSmV</key>
+ <string>v</string>
+ <key>LtnSmW</key>
+ <string>w</string>
+ <key>LtnSmX</key>
+ <string>x</string>
+ <key>LtnSmY</key>
+ <string>y</string>
+ <key>NonBreakingHyphen</key>
+ <string>uni2011</string>
+ <key>NumSgn</key>
+ <string>numbersign</string>
+ <key>PercentSgn</key>
+ <string>percent</string>
+ <key>PlusSgn</key>
+ <string>plus</string>
+ <key>QstnMrk</key>
+ <string>question</string>
+ <key>QuotMrk</key>
+ <string>quotedbl</string>
+ <key>ReverseSolidus</key>
+ <string>backslash</string>
+ <key>RtCurlyBrac</key>
+ <string>braceright</string>
+ <key>RtParen</key>
+ <string>parenright</string>
+ <key>RtSqrBrac</key>
+ <string>bracketright</string>
+ <key>Semicolon</key>
+ <string>semicolon</string>
+ <key>Solidus</key>
+ <string>slash</string>
+ <key>Space</key>
+ <string>space</string>
+ <key>Tilde</key>
+ <string>asciitilde</string>
+ <key>VertLine</key>
+ <string>bar</string>
+ </dict>
+</dict>
+</plist>
diff --git a/tests/reference/ufo/psfbuildcomp.ufo/metainfo.plist b/tests/reference/ufo/psfbuildcomp.ufo/metainfo.plist
new file mode 100644
index 0000000..aa10c5c
--- /dev/null
+++ b/tests/reference/ufo/psfbuildcomp.ufo/metainfo.plist
@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+ <key>creator</key>
+ <string>org.sil.scripts.pysilfont</string>
+ <key>formatVersion</key>
+ <integer>3</integer>
+</dict>
+</plist>
diff --git a/tests/reference/ufo/psfbuildcompgc.lg b/tests/reference/ufo/psfbuildcompgc.lg
new file mode 100644
index 0000000..7a3797e
--- /dev/null
+++ b/tests/reference/ufo/psfbuildcompgc.lg
@@ -0,0 +1,3 @@
+2019-04-10 15:46:32 Progress: Opening file for input: tests/input/psfbuildcomp.txt
+2019-04-10 15:46:32 Error: Invalid CD line 'LtnSmITilde = LtnSmDotlessI + CombTilde@U ^200,200 | 0129' - No glyph named 'LtnSmDotlessI'.
+2019-04-10 15:46:32 Error: Invalid CD line 'LtnSmITildeGraveCedilla = LtnSmDotlessI + CombCedilla@H + CombTilde@LtnSmDotlessI:U + CombGrave@U ^200,200 | E010 # i cedilla tilde grave' - No glyph named 'LtnSmDotlessI'.
diff --git a/tests/reference/ufo/psfchangettfglyphnames.lg b/tests/reference/ufo/psfchangettfglyphnames.lg
new file mode 100644
index 0000000..c236b6f
--- /dev/null
+++ b/tests/reference/ufo/psfchangettfglyphnames.lg
@@ -0,0 +1,4 @@
+2020-07-28 14:36:06 Progress: Running: psfchangettfglyphnames tests/input/font-psf-test/source/PsfTest-Regular.ufo tests/input/PsfTest-R.ttf local/testresults/ufo/psfchangettfglyphnames.ttf -l local/testresults/ufo/psfchangettfglyphnames.log
+2020-07-28 14:36:06 Progress: Renaming the input ttf glyphs based on production names in the UFO
+2020-07-28 14:36:06 Progress: Saving the output ttf file
+2020-07-28 14:36:06 Progress: Done
diff --git a/tests/reference/ufo/psfchangettfglyphnames.ttf b/tests/reference/ufo/psfchangettfglyphnames.ttf
new file mode 100644
index 0000000..d31345b
--- /dev/null
+++ b/tests/reference/ufo/psfchangettfglyphnames.ttf
Binary files differ
diff --git a/tests/reference/ufo/psfcheckbasicchars.lg b/tests/reference/ufo/psfcheckbasicchars.lg
new file mode 100644
index 0000000..9108807
--- /dev/null
+++ b/tests/reference/ufo/psfcheckbasicchars.lg
@@ -0,0 +1,199 @@
+2022-03-08 12:00:19 Progress: Running: psfcheckbasicchars tests/input/font-psf-test/source/PsfTest-Regular.ufo -l local/testresults/ufo/psfcheckbasicchars.log
+2022-03-08 12:00:19 Progress: Reading UFO: tests/input/font-psf-test/source/PsfTest-Regular.ufo
+2022-03-08 12:00:19 Progress: Checking fontinfo.plist metadata
+2022-03-08 12:00:19 Warning: note is present - it's use is discouraged
+2022-03-08 12:00:19 Warning: openTypeOS2FamilyClass would be removed from fontinfo Old value: [0, 0]
+2022-03-08 12:00:19 Warning: openTypeOS2Selection would be added New value: [7]
+2022-03-08 12:00:19 Progress: Checking lib.plist metadata
+2022-03-08 12:00:19 Warning: com.schriftgestaltung.disablesAutomaticAlignment would be deleted - obsolete key Old value: True
+2022-03-08 12:00:19 Warning: com.schriftgestaltung.disablesLastChange would be deleted - obsolete key Old value: True
+2022-03-08 12:00:19 Progress: Check & fix results:- Errors: 0, Changes to make: 4, Other warnings: 1
+2022-03-08 12:00:19 Progress: See log file for details
+2022-03-08 12:00:19 Warning: U+005A from the basic set has no representative glyph (Z)
+2022-03-08 12:00:19 Warning: U+007A from the basic set has no representative glyph (z)
+2022-03-08 12:00:19 Warning: U+00A0 from the basic set has no representative glyph (uni00A0, nbspace)
+2022-03-08 12:00:19 Warning: U+00A1 from the basic set has no representative glyph (exclamdown)
+2022-03-08 12:00:19 Warning: U+00A2 from the basic set has no representative glyph (cent)
+2022-03-08 12:00:19 Warning: U+00A3 from the basic set has no representative glyph (sterling)
+2022-03-08 12:00:19 Warning: U+00A4 from the basic set has no representative glyph (currency)
+2022-03-08 12:00:19 Warning: U+00A5 from the basic set has no representative glyph (yen)
+2022-03-08 12:00:19 Warning: U+00A6 from the basic set has no representative glyph (brokenbar)
+2022-03-08 12:00:19 Warning: U+00A7 from the basic set has no representative glyph (section)
+2022-03-08 12:00:19 Warning: U+00A8 from the basic set has no representative glyph (dieresis)
+2022-03-08 12:00:19 Warning: U+00A9 from the basic set has no representative glyph (copyright)
+2022-03-08 12:00:19 Warning: U+00AA from the basic set has no representative glyph (ordfeminine)
+2022-03-08 12:00:19 Warning: U+00AB from the basic set has no representative glyph (guillemotleft, guillemetleft)
+2022-03-08 12:00:19 Warning: U+00AC from the basic set has no representative glyph (logicalnot)
+2022-03-08 12:00:19 Warning: U+00AE from the basic set has no representative glyph (registered)
+2022-03-08 12:00:19 Warning: U+00AF from the basic set has no representative glyph (macron)
+2022-03-08 12:00:19 Warning: U+00B0 from the basic set has no representative glyph (degree)
+2022-03-08 12:00:19 Warning: U+00B1 from the basic set has no representative glyph (plusminus)
+2022-03-08 12:00:19 Warning: U+00B2 from the basic set has no representative glyph (uni00B2, twosuperior)
+2022-03-08 12:00:19 Warning: U+00B3 from the basic set has no representative glyph (uni00B3, threesuperior)
+2022-03-08 12:00:19 Warning: U+00B4 from the basic set has no representative glyph (acute)
+2022-03-08 12:00:19 Warning: U+00B5 from the basic set has no representative glyph (mu, micro)
+2022-03-08 12:00:19 Warning: U+00B6 from the basic set has no representative glyph (paragraph)
+2022-03-08 12:00:19 Warning: U+00B7 from the basic set has no representative glyph (periodcentered)
+2022-03-08 12:00:19 Warning: U+00B8 from the basic set has no representative glyph (cedilla)
+2022-03-08 12:00:19 Warning: U+00B9 from the basic set has no representative glyph (uni00B9, onesuperior)
+2022-03-08 12:00:19 Warning: U+00BA from the basic set has no representative glyph (ordmasculine)
+2022-03-08 12:00:19 Warning: U+00BB from the basic set has no representative glyph (guillemotright, guillemetright)
+2022-03-08 12:00:19 Warning: U+00BC from the basic set has no representative glyph (onequarter)
+2022-03-08 12:00:19 Warning: U+00BD from the basic set has no representative glyph (onehalf)
+2022-03-08 12:00:19 Warning: U+00BE from the basic set has no representative glyph (threequarters)
+2022-03-08 12:00:19 Warning: U+00BF from the basic set has no representative glyph (questiondown)
+2022-03-08 12:00:19 Warning: U+00C0 from the basic set has no representative glyph (Agrave)
+2022-03-08 12:00:19 Warning: U+00C1 from the basic set has no representative glyph (Aacute)
+2022-03-08 12:00:19 Warning: U+00C2 from the basic set has no representative glyph (Acircumflex)
+2022-03-08 12:00:19 Warning: U+00C3 from the basic set has no representative glyph (Atilde)
+2022-03-08 12:00:19 Warning: U+00C5 from the basic set has no representative glyph (Aring)
+2022-03-08 12:00:19 Warning: U+00C6 from the basic set has no representative glyph (AE)
+2022-03-08 12:00:19 Warning: U+00C7 from the basic set has no representative glyph (Ccedilla)
+2022-03-08 12:00:19 Warning: U+00C8 from the basic set has no representative glyph (Egrave)
+2022-03-08 12:00:19 Warning: U+00C9 from the basic set has no representative glyph (Eacute)
+2022-03-08 12:00:19 Warning: U+00CA from the basic set has no representative glyph (Ecircumflex)
+2022-03-08 12:00:19 Warning: U+00CB from the basic set has no representative glyph (Edieresis)
+2022-03-08 12:00:19 Warning: U+00CC from the basic set has no representative glyph (Igrave)
+2022-03-08 12:00:19 Warning: U+00CD from the basic set has no representative glyph (Iacute)
+2022-03-08 12:00:19 Warning: U+00CE from the basic set has no representative glyph (Icircumflex)
+2022-03-08 12:00:19 Warning: U+00CF from the basic set has no representative glyph (Idieresis)
+2022-03-08 12:00:19 Warning: U+00D0 from the basic set has no representative glyph (Eth)
+2022-03-08 12:00:19 Warning: U+00D1 from the basic set has no representative glyph (Ntilde)
+2022-03-08 12:00:19 Warning: U+00D2 from the basic set has no representative glyph (Ograve)
+2022-03-08 12:00:19 Warning: U+00D3 from the basic set has no representative glyph (Oacute)
+2022-03-08 12:00:19 Warning: U+00D4 from the basic set has no representative glyph (Ocircumflex)
+2022-03-08 12:00:19 Warning: U+00D5 from the basic set has no representative glyph (Otilde)
+2022-03-08 12:00:19 Warning: U+00D6 from the basic set has no representative glyph (Odieresis)
+2022-03-08 12:00:19 Warning: U+00D7 from the basic set has no representative glyph (multiply)
+2022-03-08 12:00:19 Warning: U+00D8 from the basic set has no representative glyph (Oslash)
+2022-03-08 12:00:19 Warning: U+00D9 from the basic set has no representative glyph (Ugrave)
+2022-03-08 12:00:19 Warning: U+00DA from the basic set has no representative glyph (Uacute)
+2022-03-08 12:00:19 Warning: U+00DB from the basic set has no representative glyph (Ucircumflex)
+2022-03-08 12:00:19 Warning: U+00DC from the basic set has no representative glyph (Udieresis)
+2022-03-08 12:00:19 Warning: U+00DD from the basic set has no representative glyph (Yacute)
+2022-03-08 12:00:19 Warning: U+00DE from the basic set has no representative glyph (Thorn)
+2022-03-08 12:00:19 Warning: U+00DF from the basic set has no representative glyph (germandbls)
+2022-03-08 12:00:19 Warning: U+00E6 from the basic set has no representative glyph (ae)
+2022-03-08 12:00:19 Warning: U+00E7 from the basic set has no representative glyph (ccedilla)
+2022-03-08 12:00:19 Warning: U+00E8 from the basic set has no representative glyph (egrave)
+2022-03-08 12:00:19 Warning: U+00E9 from the basic set has no representative glyph (eacute)
+2022-03-08 12:00:19 Warning: U+00EA from the basic set has no representative glyph (ecircumflex)
+2022-03-08 12:00:19 Warning: U+00EB from the basic set has no representative glyph (edieresis)
+2022-03-08 12:00:19 Warning: U+00EC from the basic set has no representative glyph (igrave)
+2022-03-08 12:00:19 Warning: U+00ED from the basic set has no representative glyph (iacute)
+2022-03-08 12:00:19 Warning: U+00EE from the basic set has no representative glyph (icircumflex)
+2022-03-08 12:00:19 Warning: U+00EF from the basic set has no representative glyph (idieresis)
+2022-03-08 12:00:19 Warning: U+00F0 from the basic set has no representative glyph (eth)
+2022-03-08 12:00:19 Warning: U+00F1 from the basic set has no representative glyph (ntilde)
+2022-03-08 12:00:19 Warning: U+00F2 from the basic set has no representative glyph (ograve)
+2022-03-08 12:00:19 Warning: U+00F3 from the basic set has no representative glyph (oacute)
+2022-03-08 12:00:19 Warning: U+00F4 from the basic set has no representative glyph (ocircumflex)
+2022-03-08 12:00:19 Warning: U+00F5 from the basic set has no representative glyph (otilde)
+2022-03-08 12:00:19 Warning: U+00F6 from the basic set has no representative glyph (odieresis)
+2022-03-08 12:00:19 Warning: U+00F7 from the basic set has no representative glyph (divide)
+2022-03-08 12:00:19 Warning: U+00F8 from the basic set has no representative glyph (oslash)
+2022-03-08 12:00:19 Warning: U+00F9 from the basic set has no representative glyph (ugrave)
+2022-03-08 12:00:19 Warning: U+00FA from the basic set has no representative glyph (uacute)
+2022-03-08 12:00:19 Warning: U+00FB from the basic set has no representative glyph (ucircumflex)
+2022-03-08 12:00:19 Warning: U+00FC from the basic set has no representative glyph (udieresis)
+2022-03-08 12:00:19 Warning: U+00FD from the basic set has no representative glyph (yacute)
+2022-03-08 12:00:19 Warning: U+00FE from the basic set has no representative glyph (thorn)
+2022-03-08 12:00:19 Warning: U+00FF from the basic set has no representative glyph (ydieresis)
+2022-03-08 12:00:19 Warning: U+0131 from the basic set has no representative glyph (dotlessi, idotless)
+2022-03-08 12:00:19 Warning: U+0152 from the basic set has no representative glyph (OE)
+2022-03-08 12:00:19 Warning: U+0153 from the basic set has no representative glyph (oe)
+2022-03-08 12:00:19 Warning: U+0160 from the basic set has no representative glyph (Scaron)
+2022-03-08 12:00:19 Warning: U+0161 from the basic set has no representative glyph (scaron)
+2022-03-08 12:00:19 Warning: U+0178 from the basic set has no representative glyph (Ydieresis)
+2022-03-08 12:00:19 Warning: U+017D from the basic set has no representative glyph (Zcaron)
+2022-03-08 12:00:19 Warning: U+017E from the basic set has no representative glyph (zcaron)
+2022-03-08 12:00:19 Warning: U+0192 from the basic set has no representative glyph (florin)
+2022-03-08 12:00:19 Warning: U+02C6 from the basic set has no representative glyph (circumflex)
+2022-03-08 12:00:19 Warning: U+02C7 from the basic set has no representative glyph (caron)
+2022-03-08 12:00:19 Warning: U+02D8 from the basic set has no representative glyph (breve)
+2022-03-08 12:00:19 Warning: U+02D9 from the basic set has no representative glyph (dotaccent)
+2022-03-08 12:00:19 Warning: U+02DA from the basic set has no representative glyph (ring)
+2022-03-08 12:00:19 Warning: U+02DB from the basic set has no representative glyph (ogonek)
+2022-03-08 12:00:19 Warning: U+02DC from the basic set has no representative glyph (tilde)
+2022-03-08 12:00:19 Warning: U+02DD from the basic set has no representative glyph (hungarumlaut)
+2022-03-08 12:00:19 Warning: U+034F from the basic set has no representative glyph (uni034F, graphemejoinercomb)
+2022-03-08 12:00:19 Warning: U+03C0 from the basic set has no representative glyph (pi)
+2022-03-08 12:00:19 Warning: U+2000 from the basic set has no representative glyph (uni2000, enquad)
+2022-03-08 12:00:19 Warning: U+2001 from the basic set has no representative glyph (uni2001, emquad)
+2022-03-08 12:00:19 Warning: U+2002 from the basic set has no representative glyph (uni2002, enspace)
+2022-03-08 12:00:19 Warning: U+2003 from the basic set has no representative glyph (uni2003, emspace)
+2022-03-08 12:00:19 Warning: U+2004 from the basic set has no representative glyph (uni2004, threeperemspace)
+2022-03-08 12:00:19 Warning: U+2005 from the basic set has no representative glyph (uni2005, fourperemspace)
+2022-03-08 12:00:19 Warning: U+2006 from the basic set has no representative glyph (uni2006, sixperemspace)
+2022-03-08 12:00:19 Warning: U+2007 from the basic set has no representative glyph (uni2007, figurespace)
+2022-03-08 12:00:19 Warning: U+2008 from the basic set has no representative glyph (uni2008, punctuationspace)
+2022-03-08 12:00:19 Warning: U+2009 from the basic set has no representative glyph (uni2009, thinspace)
+2022-03-08 12:00:19 Warning: U+200A from the basic set has no representative glyph (uni200A, hairspace)
+2022-03-08 12:00:19 Warning: U+200B from the basic set has no representative glyph (uni200B, zerowidthspace)
+2022-03-08 12:00:19 Warning: U+200C from the basic set has no representative glyph (uni200C, zerowidthnonjoiner)
+2022-03-08 12:00:19 Warning: U+200D from the basic set has no representative glyph (uni200D, zerowidthjoiner)
+2022-03-08 12:00:19 Warning: U+2012 from the basic set has no representative glyph (figuredash)
+2022-03-08 12:00:19 Warning: U+2013 from the basic set has no representative glyph (endash)
+2022-03-08 12:00:19 Warning: U+2014 from the basic set has no representative glyph (emdash)
+2022-03-08 12:00:19 Warning: U+2015 from the basic set has no representative glyph (uni2015, horizontalbar)
+2022-03-08 12:00:19 Warning: U+2018 from the basic set has no representative glyph (quoteleft)
+2022-03-08 12:00:19 Warning: U+2019 from the basic set has no representative glyph (quoteright)
+2022-03-08 12:00:19 Warning: U+201A from the basic set has no representative glyph (quotesinglbase)
+2022-03-08 12:00:19 Warning: U+201C from the basic set has no representative glyph (quotedblleft)
+2022-03-08 12:00:19 Warning: U+201D from the basic set has no representative glyph (quotedblright)
+2022-03-08 12:00:19 Warning: U+201E from the basic set has no representative glyph (quotedblbase)
+2022-03-08 12:00:19 Warning: U+2020 from the basic set has no representative glyph (dagger)
+2022-03-08 12:00:19 Warning: U+2021 from the basic set has no representative glyph (daggerdbl)
+2022-03-08 12:00:19 Warning: U+2022 from the basic set has no representative glyph (bullet)
+2022-03-08 12:00:19 Warning: U+2026 from the basic set has no representative glyph (ellipsis)
+2022-03-08 12:00:19 Warning: U+2027 from the basic set has no representative glyph (uni2027, hyphenationpoint)
+2022-03-08 12:00:19 Warning: U+2028 from the basic set has no representative glyph (uni2028, lineseparator)
+2022-03-08 12:00:19 Warning: U+2029 from the basic set has no representative glyph (uni2029, paragraphseparator)
+2022-03-08 12:00:19 Warning: U+202F from the basic set has no representative glyph (uni202F, narrownbspace)
+2022-03-08 12:00:19 Warning: U+2030 from the basic set has no representative glyph (perthousand)
+2022-03-08 12:00:19 Warning: U+2039 from the basic set has no representative glyph (guilsinglleft)
+2022-03-08 12:00:19 Warning: U+203A from the basic set has no representative glyph (guilsinglright)
+2022-03-08 12:00:19 Warning: U+2044 from the basic set has no representative glyph (fraction)
+2022-03-08 12:00:19 Warning: U+2060 from the basic set has no representative glyph (uni2060, wordjoiner)
+2022-03-08 12:00:19 Warning: U+2074 from the basic set has no representative glyph (uni2074, foursuperior)
+2022-03-08 12:00:19 Warning: U+20AC from the basic set has no representative glyph (Euro, euro)
+2022-03-08 12:00:19 Warning: U+2122 from the basic set has no representative glyph (trademark)
+2022-03-08 12:00:19 Warning: U+2126 from the basic set has no representative glyph (Omega, Ohm)
+2022-03-08 12:00:19 Warning: U+2202 from the basic set has no representative glyph (partialdiff)
+2022-03-08 12:00:19 Warning: U+2206 from the basic set has no representative glyph (Delta)
+2022-03-08 12:00:19 Warning: U+220F from the basic set has no representative glyph (product)
+2022-03-08 12:00:19 Warning: U+2211 from the basic set has no representative glyph (summation)
+2022-03-08 12:00:19 Warning: U+2212 from the basic set has no representative glyph (minus)
+2022-03-08 12:00:19 Warning: U+2215 from the basic set has no representative glyph (uni2215, divisionslash)
+2022-03-08 12:00:19 Warning: U+2219 from the basic set has no representative glyph (uni2219, bulletoperator)
+2022-03-08 12:00:19 Warning: U+221A from the basic set has no representative glyph (radical)
+2022-03-08 12:00:19 Warning: U+221E from the basic set has no representative glyph (infinity)
+2022-03-08 12:00:19 Warning: U+222B from the basic set has no representative glyph (integral)
+2022-03-08 12:00:19 Warning: U+2248 from the basic set has no representative glyph (approxequal)
+2022-03-08 12:00:19 Warning: U+2260 from the basic set has no representative glyph (notequal)
+2022-03-08 12:00:19 Warning: U+2264 from the basic set has no representative glyph (lessequal)
+2022-03-08 12:00:19 Warning: U+2265 from the basic set has no representative glyph (greaterequal)
+2022-03-08 12:00:19 Warning: U+2423 from the basic set has no representative glyph (uni2423, blank)
+2022-03-08 12:00:19 Warning: U+25CA from the basic set has no representative glyph (lozenge)
+2022-03-08 12:00:19 Warning: U+FB01 from the basic set has no representative glyph (uniFB01, fi)
+2022-03-08 12:00:19 Warning: U+FB02 from the basic set has no representative glyph (uniFB02, fl)
+2022-03-08 12:00:19 Warning: U+FE00 from the basic set has no representative glyph (uniFE00, VS1)
+2022-03-08 12:00:19 Warning: U+FE01 from the basic set has no representative glyph (uniFE01, VS2)
+2022-03-08 12:00:19 Warning: U+FE02 from the basic set has no representative glyph (uniFE02, VS3)
+2022-03-08 12:00:19 Warning: U+FE03 from the basic set has no representative glyph (uniFE03, VS4)
+2022-03-08 12:00:19 Warning: U+FE04 from the basic set has no representative glyph (uniFE04, VS5)
+2022-03-08 12:00:19 Warning: U+FE05 from the basic set has no representative glyph (uniFE05, VS6)
+2022-03-08 12:00:19 Warning: U+FE06 from the basic set has no representative glyph (uniFE06, VS7)
+2022-03-08 12:00:19 Warning: U+FE07 from the basic set has no representative glyph (uniFE07, VS8)
+2022-03-08 12:00:19 Warning: U+FE08 from the basic set has no representative glyph (uniFE08, VS9)
+2022-03-08 12:00:19 Warning: U+FE09 from the basic set has no representative glyph (uniFE09, VS10)
+2022-03-08 12:00:19 Warning: U+FE0A from the basic set has no representative glyph (uniFE0A, VS11)
+2022-03-08 12:00:19 Warning: U+FE0B from the basic set has no representative glyph (uniFE0B, VS12)
+2022-03-08 12:00:19 Warning: U+FE0C from the basic set has no representative glyph (uniFE0C, VS13)
+2022-03-08 12:00:19 Warning: U+FE0D from the basic set has no representative glyph (uniFE0D, VS14)
+2022-03-08 12:00:19 Warning: U+FE0E from the basic set has no representative glyph (uniFE0E, VS15)
+2022-03-08 12:00:19 Warning: U+FE0F from the basic set has no representative glyph (uniFE0F, VS16)
+2022-03-08 12:00:19 Warning: U+FEFF from the basic set has no representative glyph (uniFEFF, zeroWidthNoBreakSpace)
+2022-03-08 12:00:19 Warning: U+FFFC from the basic set has no representative glyph (uniFFFC, objectReplacementCharacter)
+2022-03-08 12:00:19 Warning: U+FFFD from the basic set has no representative glyph (uniFFFD, replacementCharacter)
+2022-03-08 12:00:19 Error: There are 187 required characters missing
diff --git a/tests/reference/ufo/psfcopyglyphs.lg b/tests/reference/ufo/psfcopyglyphs.lg
new file mode 100644
index 0000000..a6a070b
--- /dev/null
+++ b/tests/reference/ufo/psfcopyglyphs.lg
@@ -0,0 +1,30 @@
+2021-06-29 14:42:19 Progress: Running: psfcopyglyphs -s tests/input/font-psf-test/source/PsfTest-Regular.ufo tests/input/font-psf-test/source/PsfTest-Italic.ufo -i tests/input/psfcopyglyphs.csv -l local/testresults/ufo/psfcopyglyphs.log --rename newname --unicode usv
+2021-06-29 14:42:19 Progress: Opening file for input: tests/input/psfcopyglyphs.csv
+2021-06-29 14:42:19 Progress: Reading UFO: tests/input/font-psf-test/source/PsfTest-Italic.ufo
+2021-06-29 14:42:19 Progress: Checking fontinfo.plist metadata
+2021-06-29 14:42:19 Warning: openTypeOS2FamilyClass would be removed from fontinfo Old value: [0, 0]
+2021-06-29 14:42:19 Warning: year would be removed from fontinfo Old value: 2021
+2021-06-29 14:42:19 Warning: capHeight would be updated Old value: 1485.3, new value: 1485
+2021-06-29 14:42:19 Warning: styleMapFamilyName would be uppdated Old value: Psf test, new value: Psf Test
+2021-06-29 14:42:19 Warning: openTypeOS2TypoLineGap would be updated Old value: 1, new value: 0
+2021-06-29 14:42:19 Warning: openTypeOS2Selection would be added New value: [7]
+2021-06-29 14:42:19 Warning: openTypeNamePreferredFamilyName would be updated Old value: Psf Testing, new value: Psf Test
+2021-06-29 14:42:19 Progress: Checking lib.plist metadata
+2021-06-29 14:42:19 Warning: com.schriftgestaltung.disablesAutomaticAlignment would be deleted - obsolete key Old value: True
+2021-06-29 14:42:19 Warning: com.schriftgestaltung.disablesLastChange would be deleted - obsolete key Old value: True
+2021-06-29 14:42:19 Progress: Check & fix results:- Errors: 0, Changes to make: 9, Other warnings: 0
+2021-06-29 14:42:19 Progress: See log file for details
+2021-06-29 14:42:19 Progress: Reading UFO: tests/input/font-psf-test/source/PsfTest-Regular.ufo
+2021-06-29 14:42:19 Progress: Checking fontinfo.plist metadata
+2021-06-29 14:42:19 Warning: note is present - it's use is discouraged
+2021-06-29 14:42:19 Warning: openTypeOS2FamilyClass would be removed from fontinfo Old value: [0, 0]
+2021-06-29 14:42:19 Warning: openTypeOS2Selection would be added New value: [7]
+2021-06-29 14:42:19 Progress: Checking lib.plist metadata
+2021-06-29 14:42:19 Warning: com.schriftgestaltung.disablesAutomaticAlignment would be deleted - obsolete key Old value: True
+2021-06-29 14:42:19 Warning: com.schriftgestaltung.disablesLastChange would be deleted - obsolete key Old value: True
+2021-06-29 14:42:19 Progress: Check & fix results:- Errors: 0, Changes to make: 4, Other warnings: 1
+2021-06-29 14:42:19 Progress: See log file for details
+2021-06-29 14:42:19 Warning: Line 4: Glyph 'Colon' already present; skipping
+2021-06-29 14:42:19 Progress: Processing font for output
+2021-06-29 14:42:19 Progress: Output UFO already exists - reading for comparison
+2021-06-29 14:42:19 Progress: Writing font to local/testresults/ufo/psfcopyglyphs.ufo
diff --git a/tests/reference/ufo/psfcopyglyphs.ufo/fontinfo.plist b/tests/reference/ufo/psfcopyglyphs.ufo/fontinfo.plist
new file mode 100644
index 0000000..a4983fe
--- /dev/null
+++ b/tests/reference/ufo/psfcopyglyphs.ufo/fontinfo.plist
@@ -0,0 +1,243 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+ <key>ascender</key>
+ <integer>2100</integer>
+ <key>capHeight</key>
+ <real>1485.3</real>
+ <key>copyright</key>
+ <string>Copyright (c) 2004-2021 SIL International</string>
+ <key>descender</key>
+ <integer>-550</integer>
+ <key>familyName</key>
+ <string>Psf Test</string>
+ <key>italicAngle</key>
+ <integer>-14</integer>
+ <key>openTypeHeadCreated</key>
+ <string>2021/01/29 10:05:04</string>
+ <key>openTypeHheaAscender</key>
+ <integer>2100</integer>
+ <key>openTypeHheaDescender</key>
+ <integer>-550</integer>
+ <key>openTypeHheaLineGap</key>
+ <integer>0</integer>
+ <key>openTypeNameDescription</key>
+ <string>Copyright (c) 2004-2021 SIL International</string>
+ <key>openTypeNameDesigner</key>
+ <string>Victor Gaultney, Annie Olsen, Julie Remington, Don Collingsworth, Eric Hays, Becca Hirsbrunner</string>
+ <key>openTypeNameDesignerURL</key>
+ <string>http://scripts.sil.org/</string>
+ <key>openTypeNameLicense</key>
+ <string>Copyright (c) 2004-2021 SIL International (http://www.sil.org/) with Reserved Font Names "Andika" and "SIL".
+
+This Font Software is licensed under the SIL Open Font License, Version 1.1. This license is copied below, and is also available with a FAQ at: http://scripts.sil.org/OFL
+
+
+-----------------------------------------------------------
+SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007
+-----------------------------------------------------------
+
+PREAMBLE
+The goals of the Open Font License (OFL) are to stimulate worldwide development of collaborative font projects, to support the font creation efforts of academic and linguistic communities, and to provide a free and open framework in which fonts may be shared and improved in partnership with others.
+
+The OFL allows the licensed fonts to be used, studied, modified and redistributed freely as long as they are not sold by themselves. The fonts, including any derivative works, can be bundled, embedded, redistributed and/or sold with any software provided that any reserved names are not used by derivative works. The fonts and derivatives, however, cannot be released under any other type of license. The requirement for fonts to remain under this license does not apply to any document created using the fonts or their derivatives.
+
+DEFINITIONS
+"Font Software" refers to the set of files released by the Copyright Holder(s) under this license and clearly marked as such. This may include source files, build scripts and documentation.
+
+"Reserved Font Name" refers to any names specified as such after the copyright statement(s).
+
+"Original Version" refers to the collection of Font Software components as distributed by the Copyright Holder(s).
+
+"Modified Version" refers to any derivative made by adding to, deleting, or substituting -- in part or in whole -- any of the components of the Original Version, by changing formats or by porting the Font Software to a new environment.
+
+"Author" refers to any designer, engineer, programmer, technical writer or other person who contributed to the Font Software.
+
+PERMISSION &amp; CONDITIONS
+Permission is hereby granted, free of charge, to any person obtaining a copy of the Font Software, to use, study, copy, merge, embed, modify, redistribute, and sell modified and unmodified copies of the Font Software, subject to the following conditions:
+
+1) Neither the Font Software nor any of its individual components, in Original or Modified Versions, may be sold by itself.
+
+2) Original or Modified Versions of the Font Software may be bundled, redistributed and/or sold with any software, provided that each copy contains the above copyright notice and this license. These can be included either as stand-alone text files, human-readable headers or in the appropriate machine-readable metadata fields within text or binary files as long as those fields can be easily viewed by the user.
+
+3) No Modified Version of the Font Software may use the Reserved Font Name(s) unless explicit written permission is granted by the corresponding Copyright Holder. This restriction only applies to the primary font name as presented to the users.
+
+4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font Software shall not be used to promote, endorse or advertise any Modified Version, except to acknowledge the contribution(s) of the Copyright Holder(s) and the Author(s) or with their explicit written permission.
+
+5) The Font Software, modified or unmodified, in part or in whole, must be distributed entirely under this license, and must not be distributed under any other license. The requirement for fonts to remain under this license does not apply to any document created using the Font Software.
+
+TERMINATION
+This license becomes null and void if any of the above conditions are not met.
+
+DISCLAIMER
+THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM OTHER DEALINGS IN THE FONT SOFTWARE.</string>
+ <key>openTypeNameLicenseURL</key>
+ <string>http://scripts.sil.org/OFL</string>
+ <key>openTypeNameManufacturer</key>
+ <string>SIL International</string>
+ <key>openTypeNameManufacturerURL</key>
+ <string>http://scripts.sil.org</string>
+ <key>openTypeNamePreferredFamilyName</key>
+ <string>Psf Testing</string>
+ <key>openTypeNamePreferredSubfamilyName</key>
+ <string>Italic</string>
+ <key>openTypeNameUniqueID</key>
+ <string>SIL International: Psf Test Italic: 2022</string>
+ <key>openTypeNameVersion</key>
+ <string>Version 5.550</string>
+ <key>openTypeOS2CodePageRanges</key>
+ <array>
+ <integer>0</integer>
+ <integer>1</integer>
+ <integer>2</integer>
+ <integer>4</integer>
+ <integer>7</integer>
+ <integer>8</integer>
+ </array>
+ <key>openTypeOS2FamilyClass</key>
+ <array>
+ <integer>0</integer>
+ <integer>0</integer>
+ </array>
+ <key>openTypeOS2Panose</key>
+ <array>
+ <integer>2</integer>
+ <integer>0</integer>
+ <integer>0</integer>
+ <integer>0</integer>
+ <integer>0</integer>
+ <integer>0</integer>
+ <integer>0</integer>
+ <integer>0</integer>
+ <integer>0</integer>
+ <integer>0</integer>
+ </array>
+ <key>openTypeOS2StrikeoutPosition</key>
+ <integer>700</integer>
+ <key>openTypeOS2StrikeoutSize</key>
+ <integer>100</integer>
+ <key>openTypeOS2SubscriptXOffset</key>
+ <integer>0</integer>
+ <key>openTypeOS2SubscriptXSize</key>
+ <integer>1433</integer>
+ <key>openTypeOS2SubscriptYOffset</key>
+ <integer>286</integer>
+ <key>openTypeOS2SubscriptYSize</key>
+ <integer>1331</integer>
+ <key>openTypeOS2SuperscriptXOffset</key>
+ <integer>0</integer>
+ <key>openTypeOS2SuperscriptXSize</key>
+ <integer>1433</integer>
+ <key>openTypeOS2SuperscriptYOffset</key>
+ <integer>976</integer>
+ <key>openTypeOS2SuperscriptYSize</key>
+ <integer>1331</integer>
+ <key>openTypeOS2Type</key>
+ <array/>
+ <key>openTypeOS2TypoAscender</key>
+ <integer>2100</integer>
+ <key>openTypeOS2TypoDescender</key>
+ <integer>-550</integer>
+ <key>openTypeOS2TypoLineGap</key>
+ <integer>1</integer>
+ <key>openTypeOS2UnicodeRanges</key>
+ <array>
+ <integer>0</integer>
+ <integer>1</integer>
+ <integer>6</integer>
+ <integer>7</integer>
+ <integer>31</integer>
+ <integer>33</integer>
+ <integer>35</integer>
+ <integer>36</integer>
+ <integer>37</integer>
+ <integer>38</integer>
+ <integer>39</integer>
+ <integer>40</integer>
+ <integer>45</integer>
+ <integer>46</integer>
+ <integer>47</integer>
+ <integer>57</integer>
+ <integer>60</integer>
+ <integer>62</integer>
+ <integer>64</integer>
+ <integer>67</integer>
+ <integer>69</integer>
+ <integer>89</integer>
+ </array>
+ <key>openTypeOS2VendorID</key>
+ <string>SIL</string>
+ <key>openTypeOS2WeightClass</key>
+ <integer>400</integer>
+ <key>openTypeOS2WidthClass</key>
+ <integer>5</integer>
+ <key>openTypeOS2WinAscent</key>
+ <integer>2100</integer>
+ <key>openTypeOS2WinDescent</key>
+ <integer>550</integer>
+ <key>postscriptBlueValues</key>
+ <array>
+ <integer>-490</integer>
+ <integer>-490</integer>
+ <integer>-25</integer>
+ <integer>0</integer>
+ <integer>1020</integer>
+ <integer>1040</integer>
+ <integer>1455</integer>
+ <integer>1485</integer>
+ <integer>1600</integer>
+ <integer>1620</integer>
+ </array>
+ <key>postscriptFontName</key>
+ <string>PsfTest-Italic</string>
+ <key>postscriptFullName</key>
+ <string>Psf Test Italic</string>
+ <key>postscriptStemSnapH</key>
+ <array>
+ <integer>140</integer>
+ <integer>145</integer>
+ <integer>150</integer>
+ <integer>155</integer>
+ <integer>160</integer>
+ <integer>165</integer>
+ <integer>170</integer>
+ <integer>175</integer>
+ <integer>185</integer>
+ <integer>270</integer>
+ </array>
+ <key>postscriptStemSnapV</key>
+ <array>
+ <integer>165</integer>
+ <integer>180</integer>
+ <integer>185</integer>
+ <integer>190</integer>
+ <integer>195</integer>
+ <integer>200</integer>
+ <integer>205</integer>
+ <integer>270</integer>
+ </array>
+ <key>postscriptUnderlinePosition</key>
+ <integer>-110</integer>
+ <key>postscriptUnderlineThickness</key>
+ <integer>80</integer>
+ <key>styleMapFamilyName</key>
+ <string>Psf test</string>
+ <key>styleMapStyleName</key>
+ <string>italic</string>
+ <key>styleName</key>
+ <string>Italic</string>
+ <key>trademark</key>
+ <string>Andika is a trademark of SIL International.</string>
+ <key>unitsPerEm</key>
+ <integer>2048</integer>
+ <key>versionMajor</key>
+ <integer>5</integer>
+ <key>versionMinor</key>
+ <integer>550</integer>
+ <key>xHeight</key>
+ <integer>1040</integer>
+ <key>year</key>
+ <integer>2021</integer>
+</dict>
+</plist>
diff --git a/tests/reference/ufo/psfcopyglyphs.ufo/glyphs/A_mpergravel.glif b/tests/reference/ufo/psfcopyglyphs.ufo/glyphs/A_mpergravel.glif
new file mode 100644
index 0000000..7995f26
--- /dev/null
+++ b/tests/reference/ufo/psfcopyglyphs.ufo/glyphs/A_mpergravel.glif
@@ -0,0 +1,61 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="Ampergravel" format="2">
+ <advance width="1222"/>
+ <unicode hex="3026"/>
+ <outline>
+ <contour>
+ <point x="490" y="1485" type="curve" smooth="yes"/>
+ <point x="331" y="1485"/>
+ <point x="155" y="1412"/>
+ <point x="155" y="1190" type="curve" smooth="yes"/>
+ <point x="155" y="1010"/>
+ <point x="362" y="815"/>
+ <point x="535" y="570" type="curve" smooth="yes"/>
+ <point x="794" y="202"/>
+ <point x="973" y="-25"/>
+ <point x="1025" y="-25" type="curve" smooth="yes"/>
+ <point x="1060" y="-25"/>
+ <point x="1138" y="38"/>
+ <point x="1175" y="70" type="curve"/>
+ <point x="1080" y="110"/>
+ <point x="914" y="297"/>
+ <point x="650" y="680" type="curve" smooth="yes"/>
+ <point x="494" y="906"/>
+ <point x="315" y="1075"/>
+ <point x="315" y="1200" type="curve" smooth="yes"/>
+ <point x="315" y="1291"/>
+ <point x="398" y="1350"/>
+ <point x="475" y="1350" type="curve" smooth="yes"/>
+ <point x="555" y="1350"/>
+ <point x="630" y="1294"/>
+ <point x="630" y="1205" type="curve" smooth="yes"/>
+ <point x="630" y="1116"/>
+ <point x="523" y="1001"/>
+ <point x="350" y="840" type="curve" smooth="yes"/>
+ <point x="146" y="651"/>
+ <point x="55" y="527"/>
+ <point x="55" y="375" type="curve" smooth="yes"/>
+ <point x="55" y="151"/>
+ <point x="217" y="-25"/>
+ <point x="440" y="-25" type="curve" smooth="yes"/>
+ <point x="713" y="-25"/>
+ <point x="1002" y="274"/>
+ <point x="1080" y="435" type="curve"/>
+ <point x="975" y="570" type="line"/>
+ <point x="911" y="403"/>
+ <point x="630" y="150"/>
+ <point x="455" y="150" type="curve" smooth="yes"/>
+ <point x="310" y="150"/>
+ <point x="230" y="267"/>
+ <point x="230" y="380" type="curve" smooth="yes"/>
+ <point x="230" y="490"/>
+ <point x="296" y="587"/>
+ <point x="470" y="740" type="curve" smooth="yes"/>
+ <point x="651" y="899"/>
+ <point x="790" y="1068"/>
+ <point x="790" y="1200" type="curve" smooth="yes"/>
+ <point x="790" y="1382"/>
+ <point x="642" y="1485"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfcopyglyphs.ufo/glyphs/A_mpersand.glif b/tests/reference/ufo/psfcopyglyphs.ufo/glyphs/A_mpersand.glif
new file mode 100644
index 0000000..689cb3e
--- /dev/null
+++ b/tests/reference/ufo/psfcopyglyphs.ufo/glyphs/A_mpersand.glif
@@ -0,0 +1,61 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="Ampersand" format="2">
+ <advance width="1202"/>
+ <unicode hex="0026"/>
+ <outline>
+ <contour>
+ <point x="1054" y="559" type="line"/>
+ <point x="949" y="395"/>
+ <point x="616" y="147"/>
+ <point x="441" y="147" type="curve" smooth="yes"/>
+ <point x="318" y="147"/>
+ <point x="256" y="224"/>
+ <point x="256" y="314" type="curve" smooth="yes"/>
+ <point x="256" y="453"/>
+ <point x="369" y="575"/>
+ <point x="590" y="725" type="curve" smooth="yes"/>
+ <point x="836" y="892"/>
+ <point x="1022" y="1067"/>
+ <point x="1022" y="1223" type="curve" smooth="yes"/>
+ <point x="1022" y="1363"/>
+ <point x="894" y="1455"/>
+ <point x="762" y="1455" type="curve" smooth="yes"/>
+ <point x="504" y="1455"/>
+ <point x="378" y="1328"/>
+ <point x="378" y="1114" type="curve" smooth="yes"/>
+ <point x="378" y="953"/>
+ <point x="514" y="771"/>
+ <point x="614" y="559" type="curve" smooth="yes"/>
+ <point x="783" y="198"/>
+ <point x="906" y="-25"/>
+ <point x="958" y="-25" type="curve" smooth="yes"/>
+ <point x="993" y="-25"/>
+ <point x="1087" y="37"/>
+ <point x="1132" y="69" type="curve"/>
+ <point x="1046" y="108"/>
+ <point x="926" y="291"/>
+ <point x="756" y="666" type="curve" smooth="yes"/>
+ <point x="665" y="866"/>
+ <point x="544" y="1029"/>
+ <point x="544" y="1149" type="curve" smooth="yes"/>
+ <point x="544" y="1252"/>
+ <point x="632" y="1323"/>
+ <point x="724" y="1323" type="curve" smooth="yes"/>
+ <point x="794" y="1323"/>
+ <point x="858" y="1266"/>
+ <point x="858" y="1193" type="curve" smooth="yes"/>
+ <point x="858" y="1107"/>
+ <point x="743" y="1004"/>
+ <point x="492" y="826" type="curve" smooth="yes"/>
+ <point x="182" y="606"/>
+ <point x="73" y="439"/>
+ <point x="73" y="288" type="curve" smooth="yes"/>
+ <point x="73" y="113"/>
+ <point x="195" y="-25"/>
+ <point x="383" y="-25" type="curve" smooth="yes"/>
+ <point x="656" y="-25"/>
+ <point x="1009" y="269"/>
+ <point x="1126" y="426" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfcopyglyphs.ufo/glyphs/A_pos.glif b/tests/reference/ufo/psfcopyglyphs.ufo/glyphs/A_pos.glif
new file mode 100644
index 0000000..deb1650
--- /dev/null
+++ b/tests/reference/ufo/psfcopyglyphs.ufo/glyphs/A_pos.glif
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="Apos" format="2">
+ <advance width="585"/>
+ <unicode hex="0027"/>
+ <outline>
+ <contour>
+ <point x="560" y="1024" type="line"/>
+ <point x="599" y="1162"/>
+ <point x="643" y="1312"/>
+ <point x="732" y="1553" type="curve"/>
+ <point x="527" y="1553" type="line"/>
+ <point x="498" y="1312"/>
+ <point x="465" y="1162"/>
+ <point x="435" y="1024" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfcopyglyphs.ufo/glyphs/A_sterisk.glif b/tests/reference/ufo/psfcopyglyphs.ufo/glyphs/A_sterisk.glif
new file mode 100644
index 0000000..3027a5d
--- /dev/null
+++ b/tests/reference/ufo/psfcopyglyphs.ufo/glyphs/A_sterisk.glif
@@ -0,0 +1,51 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="Asterisk" format="2">
+ <advance width="1008"/>
+ <unicode hex="002A"/>
+ <outline>
+ <contour>
+ <point x="745" y="1568" type="line"/>
+ <point x="733" y="1438"/>
+ <point x="725" y="1359"/>
+ <point x="707" y="1274" type="curve"/>
+ <point x="644" y="1317"/>
+ <point x="587" y="1359"/>
+ <point x="498" y="1436" type="curve"/>
+ <point x="392" y="1313" type="line"/>
+ <point x="505" y="1264"/>
+ <point x="575" y="1236"/>
+ <point x="643" y="1196" type="curve"/>
+ <point x="556" y="1153"/>
+ <point x="474" y="1117"/>
+ <point x="340" y="1063" type="curve"/>
+ <point x="379" y="941" type="line"/>
+ <point x="504" y="1021"/>
+ <point x="584" y="1072"/>
+ <point x="668" y="1117" type="curve"/>
+ <point x="645" y="1034"/>
+ <point x="619" y="954"/>
+ <point x="575" y="823" type="curve"/>
+ <point x="715" y="823" type="line"/>
+ <point x="727" y="954"/>
+ <point x="741" y="1031"/>
+ <point x="758" y="1117" type="curve"/>
+ <point x="821" y="1073"/>
+ <point x="878" y="1032"/>
+ <point x="968" y="956" type="curve"/>
+ <point x="1073" y="1078" type="line"/>
+ <point x="959" y="1126"/>
+ <point x="890" y="1155"/>
+ <point x="823" y="1196" type="curve"/>
+ <point x="909" y="1236"/>
+ <point x="990" y="1273"/>
+ <point x="1126" y="1328" type="curve"/>
+ <point x="1086" y="1450" type="line"/>
+ <point x="961" y="1368"/>
+ <point x="883" y="1321"/>
+ <point x="797" y="1274" type="curve"/>
+ <point x="819" y="1359"/>
+ <point x="845" y="1438"/>
+ <point x="890" y="1568" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfcopyglyphs.ufo/glyphs/A_tS_gn.glif b/tests/reference/ufo/psfcopyglyphs.ufo/glyphs/A_tS_gn.glif
new file mode 100644
index 0000000..2cd2542
--- /dev/null
+++ b/tests/reference/ufo/psfcopyglyphs.ufo/glyphs/A_tS_gn.glif
@@ -0,0 +1,104 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="AtSgn" format="2">
+ <advance width="1682"/>
+ <unicode hex="0040"/>
+ <outline>
+ <contour>
+ <point x="1082" y="-10" type="line"/>
+ <point x="980" y="-69"/>
+ <point x="889" y="-93"/>
+ <point x="796" y="-93" type="curve" smooth="yes"/>
+ <point x="507" y="-93"/>
+ <point x="301" y="104"/>
+ <point x="301" y="414" type="curve" smooth="yes"/>
+ <point x="301" y="476"/>
+ <point x="309" y="543"/>
+ <point x="327" y="613" type="curve" smooth="yes"/>
+ <point x="425" y="1003"/>
+ <point x="782" y="1245"/>
+ <point x="1110" y="1245" type="curve" smooth="yes"/>
+ <point x="1433" y="1245"/>
+ <point x="1590" y="1060"/>
+ <point x="1590" y="813" type="curve" smooth="yes"/>
+ <point x="1590" y="760"/>
+ <point x="1582" y="705"/>
+ <point x="1568" y="647" type="curve" smooth="yes"/>
+ <point x="1510" y="413"/>
+ <point x="1365" y="309"/>
+ <point x="1297" y="309" type="curve" smooth="yes"/>
+ <point x="1261" y="309"/>
+ <point x="1238" y="344"/>
+ <point x="1238" y="420" type="curve" smooth="yes"/>
+ <point x="1238" y="468"/>
+ <point x="1247" y="533"/>
+ <point x="1268" y="617" type="curve" smooth="yes"/>
+ <point x="1354" y="960" type="line"/>
+ <point x="1276" y="995"/>
+ <point x="1155" y="1019"/>
+ <point x="1074" y="1019" type="curve" smooth="yes"/>
+ <point x="910" y="1019"/>
+ <point x="790" y="962"/>
+ <point x="673" y="828" type="curve" smooth="yes"/>
+ <point x="607" y="751"/>
+ <point x="554" y="650"/>
+ <point x="524" y="529" type="curve" smooth="yes"/>
+ <point x="514" y="488"/>
+ <point x="509" y="450"/>
+ <point x="509" y="416" type="curve" smooth="yes"/>
+ <point x="509" y="259"/>
+ <point x="609" y="179"/>
+ <point x="719" y="179" type="curve" smooth="yes"/>
+ <point x="836" y="179"/>
+ <point x="1017" y="359"/>
+ <point x="1099" y="480" type="curve"/>
+ <point x="1093" y="446"/>
+ <point x="1089" y="413"/>
+ <point x="1089" y="382" type="curve" smooth="yes"/>
+ <point x="1089" y="264"/>
+ <point x="1136" y="176"/>
+ <point x="1233" y="176" type="curve" smooth="yes"/>
+ <point x="1408" y="176"/>
+ <point x="1635" y="331"/>
+ <point x="1716" y="656" type="curve" smooth="yes"/>
+ <point x="1732" y="722"/>
+ <point x="1740" y="784"/>
+ <point x="1740" y="843" type="curve" smooth="yes"/>
+ <point x="1740" y="1161"/>
+ <point x="1513" y="1377"/>
+ <point x="1153" y="1377" type="curve" smooth="yes"/>
+ <point x="738" y="1377"/>
+ <point x="310" y="1143"/>
+ <point x="175" y="603" type="curve" smooth="yes"/>
+ <point x="155" y="522"/>
+ <point x="145" y="446"/>
+ <point x="145" y="375" type="curve" smooth="yes"/>
+ <point x="145" y="-5"/>
+ <point x="417" y="-230"/>
+ <point x="747" y="-230" type="curve" smooth="yes"/>
+ <point x="882" y="-230"/>
+ <point x="1044" y="-184"/>
+ <point x="1161" y="-116" type="curve"/>
+ </contour>
+ <contour>
+ <point x="1141" y="706" type="line"/>
+ <point x="1075" y="570"/>
+ <point x="856" y="314"/>
+ <point x="766" y="314" type="curve" smooth="yes"/>
+ <point x="712" y="314"/>
+ <point x="669" y="362"/>
+ <point x="669" y="459" type="curve" smooth="yes"/>
+ <point x="669" y="491"/>
+ <point x="674" y="530"/>
+ <point x="685" y="573" type="curve" smooth="yes"/>
+ <point x="704" y="649"/>
+ <point x="739" y="726"/>
+ <point x="780" y="774" type="curve" smooth="yes"/>
+ <point x="859" y="868"/>
+ <point x="943" y="887"/>
+ <point x="1011" y="887" type="curve" smooth="yes"/>
+ <point x="1085" y="887"/>
+ <point x="1148" y="868"/>
+ <point x="1177" y="853" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfcopyglyphs.ufo/glyphs/C_ircumA_ccent.glif b/tests/reference/ufo/psfcopyglyphs.ufo/glyphs/C_ircumA_ccent.glif
new file mode 100644
index 0000000..91ab811
--- /dev/null
+++ b/tests/reference/ufo/psfcopyglyphs.ufo/glyphs/C_ircumA_ccent.glif
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="CircumAccent" format="2">
+ <advance width="830"/>
+ <unicode hex="005E"/>
+ <anchor x="705" y="1635" name="U"/>
+ <outline>
+ <contour>
+ <point x="316" y="1147" type="line"/>
+ <point x="660" y="1421" type="line"/>
+ <point x="866" y="1147" type="line"/>
+ <point x="1015" y="1147" type="line"/>
+ <point x="761" y="1568" type="line"/>
+ <point x="591" y="1568" type="line"/>
+ <point x="166" y="1147" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfcopyglyphs.ufo/glyphs/C_olon.glif b/tests/reference/ufo/psfcopyglyphs.ufo/glyphs/C_olon.glif
new file mode 100644
index 0000000..bcccfc2
--- /dev/null
+++ b/tests/reference/ufo/psfcopyglyphs.ufo/glyphs/C_olon.glif
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="Colon" format="2">
+ <advance width="620"/>
+ <unicode hex="003A"/>
+ <outline>
+ <contour>
+ <point x="314" y="758" type="curve" smooth="yes"/>
+ <point x="314" y="696"/>
+ <point x="365" y="642"/>
+ <point x="430" y="642" type="curve" smooth="yes"/>
+ <point x="514" y="642"/>
+ <point x="590" y="712"/>
+ <point x="590" y="792" type="curve" smooth="yes"/>
+ <point x="590" y="854"/>
+ <point x="540" y="907"/>
+ <point x="476" y="907" type="curve" smooth="yes"/>
+ <point x="393" y="907"/>
+ <point x="314" y="837"/>
+ </contour>
+ <contour>
+ <point x="148" y="90" type="curve" smooth="yes"/>
+ <point x="148" y="28"/>
+ <point x="198" y="-25"/>
+ <point x="263" y="-25" type="curve" smooth="yes"/>
+ <point x="347" y="-25"/>
+ <point x="424" y="45"/>
+ <point x="424" y="125" type="curve" smooth="yes"/>
+ <point x="424" y="186"/>
+ <point x="374" y="240"/>
+ <point x="309" y="240" type="curve" smooth="yes"/>
+ <point x="225" y="240"/>
+ <point x="148" y="170"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfcopyglyphs.ufo/glyphs/C_ombA_cute.glif b/tests/reference/ufo/psfcopyglyphs.ufo/glyphs/C_ombA_cute.glif
new file mode 100644
index 0000000..a7607fe
--- /dev/null
+++ b/tests/reference/ufo/psfcopyglyphs.ufo/glyphs/C_ombA_cute.glif
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="CombAcute" format="2">
+ <unicode hex="0301"/>
+ <anchor x="-221" y="1635" name="U"/>
+ <anchor x="-355" y="1100" name="_U"/>
+ <outline>
+ <contour>
+ <point x="-99" y="1568" type="line"/>
+ <point x="-524" y="1147" type="line"/>
+ <point x="-354" y="1147" type="line"/>
+ <point x="150" y="1568" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfcopyglyphs.ufo/glyphs/C_ombC_ircum.glif b/tests/reference/ufo/psfcopyglyphs.ufo/glyphs/C_ombC_ircum.glif
new file mode 100644
index 0000000..6614f85
--- /dev/null
+++ b/tests/reference/ufo/psfcopyglyphs.ufo/glyphs/C_ombC_ircum.glif
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="CombCircum" format="2">
+ <unicode hex="0302"/>
+ <anchor x="-221" y="1635" name="U"/>
+ <anchor x="-320" y="1100" name="_U"/>
+ <outline>
+ <contour>
+ <point x="-619" y="1147" type="line"/>
+ <point x="-275" y="1421" type="line"/>
+ <point x="-69" y="1147" type="line"/>
+ <point x="80" y="1147" type="line"/>
+ <point x="-174" y="1568" type="line"/>
+ <point x="-344" y="1568" type="line"/>
+ <point x="-769" y="1147" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfcopyglyphs.ufo/glyphs/C_ombD_iaer.glif b/tests/reference/ufo/psfcopyglyphs.ufo/glyphs/C_ombD_iaer.glif
new file mode 100644
index 0000000..d6b35b7
--- /dev/null
+++ b/tests/reference/ufo/psfcopyglyphs.ufo/glyphs/C_ombD_iaer.glif
@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="CombDiaer" format="2">
+ <unicode hex="0308"/>
+ <anchor x="-253" y="1505" name="U"/>
+ <anchor x="-350" y="1100" name="_U"/>
+ <outline>
+ <contour>
+ <point x="39" y="1338" type="curve" smooth="yes"/>
+ <point x="39" y="1399"/>
+ <point x="-7" y="1450"/>
+ <point x="-72" y="1450" type="curve" smooth="yes"/>
+ <point x="-167" y="1450"/>
+ <point x="-229" y="1372"/>
+ <point x="-229" y="1299" type="curve" smooth="yes"/>
+ <point x="-229" y="1238"/>
+ <point x="-182" y="1186"/>
+ <point x="-118" y="1186" type="curve" smooth="yes"/>
+ <point x="-33" y="1186"/>
+ <point x="39" y="1259"/>
+ </contour>
+ <contour>
+ <point x="-381" y="1338" type="curve" smooth="yes"/>
+ <point x="-381" y="1399"/>
+ <point x="-427" y="1450"/>
+ <point x="-492" y="1450" type="curve" smooth="yes"/>
+ <point x="-587" y="1450"/>
+ <point x="-649" y="1372"/>
+ <point x="-649" y="1299" type="curve" smooth="yes"/>
+ <point x="-649" y="1238"/>
+ <point x="-602" y="1186"/>
+ <point x="-538" y="1186" type="curve" smooth="yes"/>
+ <point x="-453" y="1186"/>
+ <point x="-381" y="1259"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfcopyglyphs.ufo/glyphs/C_ombG_rave.glif b/tests/reference/ufo/psfcopyglyphs.ufo/glyphs/C_ombG_rave.glif
new file mode 100644
index 0000000..8869bb9
--- /dev/null
+++ b/tests/reference/ufo/psfcopyglyphs.ufo/glyphs/C_ombG_rave.glif
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="CombGrave" format="2">
+ <unicode hex="0300"/>
+ <anchor x="-201" y="1635" name="U"/>
+ <anchor x="-335" y="1100" name="_U"/>
+ <outline>
+ <contour>
+ <point x="-619" y="1568" type="line"/>
+ <point x="-284" y="1147" type="line"/>
+ <point x="-134" y="1147" type="line"/>
+ <point x="-409" y="1568" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfcopyglyphs.ufo/glyphs/C_ombR_ingA_bv.glif b/tests/reference/ufo/psfcopyglyphs.ufo/glyphs/C_ombR_ingA_bv.glif
new file mode 100644
index 0000000..38232a0
--- /dev/null
+++ b/tests/reference/ufo/psfcopyglyphs.ufo/glyphs/C_ombR_ingA_bv.glif
@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="CombRingAbv" format="2">
+ <unicode hex="030A"/>
+ <anchor x="-221" y="1635" name="U"/>
+ <anchor x="-385" y="1100" name="_U"/>
+ <outline>
+ <contour>
+ <point x="-377" y="1259" type="curve" smooth="yes"/>
+ <point x="-427" y="1259"/>
+ <point x="-456" y="1287"/>
+ <point x="-456" y="1329" type="curve" smooth="yes"/>
+ <point x="-456" y="1400"/>
+ <point x="-393" y="1455"/>
+ <point x="-328" y="1455" type="curve" smooth="yes"/>
+ <point x="-278" y="1455"/>
+ <point x="-248" y="1428"/>
+ <point x="-248" y="1385" type="curve" smooth="yes"/>
+ <point x="-248" y="1314"/>
+ <point x="-312" y="1259"/>
+ </contour>
+ <contour>
+ <point x="-573" y="1320" type="curve" smooth="yes"/>
+ <point x="-573" y="1224"/>
+ <point x="-498" y="1147"/>
+ <point x="-395" y="1147" type="curve" smooth="yes"/>
+ <point x="-257" y="1147"/>
+ <point x="-131" y="1263"/>
+ <point x="-131" y="1394" type="curve" smooth="yes"/>
+ <point x="-131" y="1491"/>
+ <point x="-206" y="1568"/>
+ <point x="-310" y="1568" type="curve" smooth="yes"/>
+ <point x="-448" y="1568"/>
+ <point x="-573" y="1451"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfcopyglyphs.ufo/glyphs/C_ombT_ilde.glif b/tests/reference/ufo/psfcopyglyphs.ufo/glyphs/C_ombT_ilde.glif
new file mode 100644
index 0000000..f79322e
--- /dev/null
+++ b/tests/reference/ufo/psfcopyglyphs.ufo/glyphs/C_ombT_ilde.glif
@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="CombTilde" format="2">
+ <unicode hex="0303"/>
+ <anchor x="-290" y="1475" name="U"/>
+ <anchor x="-385" y="1100" name="_U"/>
+ <outline>
+ <contour>
+ <point x="-646" y="1181" type="line"/>
+ <point x="-629" y="1229"/>
+ <point x="-589" y="1269"/>
+ <point x="-540" y="1269" type="curve" smooth="yes"/>
+ <point x="-503" y="1269"/>
+ <point x="-466" y="1253"/>
+ <point x="-398" y="1218" type="curve" smooth="yes"/>
+ <point x="-344" y="1190"/>
+ <point x="-296" y="1171"/>
+ <point x="-243" y="1171" type="curve" smooth="yes"/>
+ <point x="-120" y="1171"/>
+ <point x="-15" y="1286"/>
+ <point x="16" y="1411" type="curve"/>
+ <point x="-89" y="1411" type="line"/>
+ <point x="-107" y="1366"/>
+ <point x="-147" y="1323"/>
+ <point x="-194" y="1323" type="curve" smooth="yes"/>
+ <point x="-236" y="1323"/>
+ <point x="-273" y="1342"/>
+ <point x="-338" y="1370" type="curve" smooth="yes"/>
+ <point x="-401" y="1397"/>
+ <point x="-442" y="1421"/>
+ <point x="-498" y="1421" type="curve" smooth="yes"/>
+ <point x="-617" y="1421"/>
+ <point x="-721" y="1300"/>
+ <point x="-751" y="1181" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfcopyglyphs.ufo/glyphs/C_omma.glif b/tests/reference/ufo/psfcopyglyphs.ufo/glyphs/C_omma.glif
new file mode 100644
index 0000000..eaff517
--- /dev/null
+++ b/tests/reference/ufo/psfcopyglyphs.ufo/glyphs/C_omma.glif
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="Comma" format="2">
+ <advance width="630"/>
+ <unicode hex="002C"/>
+ <outline>
+ <contour>
+ <point x="137" y="49" type="line"/>
+ <point x="277" y="49" type="line"/>
+ <point x="252" y="-50"/>
+ <point x="145" y="-169"/>
+ <point x="73" y="-225" type="curve"/>
+ <point x="163" y="-265" type="line"/>
+ <point x="280" y="-175"/>
+ <point x="431" y="-28"/>
+ <point x="431" y="118" type="curve" smooth="yes"/>
+ <point x="431" y="193"/>
+ <point x="378" y="245"/>
+ <point x="311" y="245" type="curve" smooth="yes"/>
+ <point x="254" y="245"/>
+ <point x="190" y="209"/>
+ <point x="161" y="147" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfcopyglyphs.ufo/glyphs/D_igitE_ight.glif b/tests/reference/ufo/psfcopyglyphs.ufo/glyphs/D_igitE_ight.glif
new file mode 100644
index 0000000..262f860
--- /dev/null
+++ b/tests/reference/ufo/psfcopyglyphs.ufo/glyphs/D_igitE_ight.glif
@@ -0,0 +1,63 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="DigitEight" format="2">
+ <advance width="1180"/>
+ <unicode hex="0038"/>
+ <anchor x="515" y="-100" name="L"/>
+ <anchor x="922" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="542" y="-25" type="curve" smooth="yes"/>
+ <point x="839" y="-25"/>
+ <point x="1160" y="170"/>
+ <point x="1160" y="475" type="curve" smooth="yes"/>
+ <point x="1160" y="626"/>
+ <point x="1068" y="733"/>
+ <point x="988" y="779" type="curve"/>
+ <point x="1155" y="860"/>
+ <point x="1270" y="970"/>
+ <point x="1270" y="1151" type="curve" smooth="yes"/>
+ <point x="1270" y="1340"/>
+ <point x="1102" y="1455"/>
+ <point x="901" y="1455" type="curve" smooth="yes"/>
+ <point x="620" y="1455"/>
+ <point x="348" y="1292"/>
+ <point x="348" y="1018" type="curve" smooth="yes"/>
+ <point x="348" y="891"/>
+ <point x="427" y="814"/>
+ <point x="483" y="779" type="curve"/>
+ <point x="297" y="706"/>
+ <point x="115" y="549"/>
+ <point x="115" y="325" type="curve" smooth="yes"/>
+ <point x="115" y="111"/>
+ <point x="317" y="-25"/>
+ </contour>
+ <contour>
+ <point x="750" y="848" type="curve" smooth="yes"/>
+ <point x="628" y="848"/>
+ <point x="541" y="917"/>
+ <point x="541" y="1029" type="curve" smooth="yes"/>
+ <point x="541" y="1205"/>
+ <point x="704" y="1299"/>
+ <point x="862" y="1299" type="curve" smooth="yes"/>
+ <point x="985" y="1299"/>
+ <point x="1076" y="1235"/>
+ <point x="1076" y="1128" type="curve" smooth="yes"/>
+ <point x="1076" y="955"/>
+ <point x="907" y="848"/>
+ </contour>
+ <contour>
+ <point x="564" y="142" type="curve" smooth="yes"/>
+ <point x="413" y="142"/>
+ <point x="322" y="225"/>
+ <point x="322" y="350" type="curve" smooth="yes"/>
+ <point x="322" y="557"/>
+ <point x="520" y="696"/>
+ <point x="712" y="696" type="curve" smooth="yes"/>
+ <point x="864" y="696"/>
+ <point x="961" y="602"/>
+ <point x="961" y="476" type="curve" smooth="yes"/>
+ <point x="961" y="266"/>
+ <point x="753" y="142"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfcopyglyphs.ufo/glyphs/D_igitF_ive.glif b/tests/reference/ufo/psfcopyglyphs.ufo/glyphs/D_igitF_ive.glif
new file mode 100644
index 0000000..a224838
--- /dev/null
+++ b/tests/reference/ufo/psfcopyglyphs.ufo/glyphs/D_igitF_ive.glif
@@ -0,0 +1,44 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="DigitFive" format="2">
+ <advance width="1180"/>
+ <unicode hex="0035"/>
+ <anchor x="515" y="-100" name="L"/>
+ <anchor x="922" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="1296" y="1431" type="line"/>
+ <point x="491" y="1431" type="line"/>
+ <point x="302" y="671" type="line"/>
+ <point x="438" y="718"/>
+ <point x="537" y="735"/>
+ <point x="643" y="735" type="curve" smooth="yes"/>
+ <point x="784" y="735"/>
+ <point x="933" y="660"/>
+ <point x="933" y="508" type="curve" smooth="yes"/>
+ <point x="933" y="273"/>
+ <point x="710" y="152"/>
+ <point x="497" y="152" type="curve" smooth="yes"/>
+ <point x="357" y="152"/>
+ <point x="263" y="195"/>
+ <point x="170" y="284" type="curve"/>
+ <point x="89" y="78" type="line"/>
+ <point x="195" y="2"/>
+ <point x="326" y="-25"/>
+ <point x="481" y="-25" type="curve" smooth="yes"/>
+ <point x="807" y="-25"/>
+ <point x="1129" y="190"/>
+ <point x="1129" y="546" type="curve" smooth="yes"/>
+ <point x="1129" y="757"/>
+ <point x="951" y="911"/>
+ <point x="702" y="911" type="curve" smooth="yes"/>
+ <point x="629" y="911"/>
+ <point x="576" y="906"/>
+ <point x="544" y="902" type="curve"/>
+ <point x="635" y="1264" type="line"/>
+ <point x="1020" y="1264" type="line" smooth="yes"/>
+ <point x="1104" y="1264"/>
+ <point x="1179" y="1260"/>
+ <point x="1250" y="1245" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfcopyglyphs.ufo/glyphs/D_igitF_our.glif b/tests/reference/ufo/psfcopyglyphs.ufo/glyphs/D_igitF_our.glif
new file mode 100644
index 0000000..eeccb48
--- /dev/null
+++ b/tests/reference/ufo/psfcopyglyphs.ufo/glyphs/D_igitF_our.glif
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="DigitFour" format="2">
+ <advance width="1180"/>
+ <unicode hex="0034"/>
+ <anchor x="522" y="-100" name="L"/>
+ <anchor x="929" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="1161" y="387" type="line"/>
+ <point x="1199" y="539" type="line"/>
+ <point x="1009" y="539" type="line"/>
+ <point x="1236" y="1450" type="line"/>
+ <point x="1026" y="1450" type="line"/>
+ <point x="144" y="539" type="line"/>
+ <point x="106" y="387" type="line"/>
+ <point x="781" y="387" type="line"/>
+ <point x="685" y="0" type="line"/>
+ <point x="875" y="0" type="line"/>
+ <point x="971" y="387" type="line"/>
+ </contour>
+ <contour>
+ <point x="985" y="1205" type="line"/>
+ <point x="819" y="539" type="line"/>
+ <point x="337" y="539" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfcopyglyphs.ufo/glyphs/D_igitN_ine.glif b/tests/reference/ufo/psfcopyglyphs.ufo/glyphs/D_igitN_ine.glif
new file mode 100644
index 0000000..191cd79
--- /dev/null
+++ b/tests/reference/ufo/psfcopyglyphs.ufo/glyphs/D_igitN_ine.glif
@@ -0,0 +1,49 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="DigitNine" format="2">
+ <advance width="1180"/>
+ <unicode hex="0039"/>
+ <anchor x="515" y="-100" name="L"/>
+ <anchor x="922" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="157" y="94" type="line"/>
+ <point x="208" y="29"/>
+ <point x="355" y="-25"/>
+ <point x="473" y="-25" type="curve" smooth="yes"/>
+ <point x="999" y="-25"/>
+ <point x="1267" y="520"/>
+ <point x="1267" y="982" type="curve" smooth="yes"/>
+ <point x="1267" y="1248"/>
+ <point x="1127" y="1455"/>
+ <point x="866" y="1455" type="curve" smooth="yes"/>
+ <point x="596" y="1455"/>
+ <point x="303" y="1269"/>
+ <point x="303" y="932" type="curve" smooth="yes"/>
+ <point x="303" y="761"/>
+ <point x="425" y="574"/>
+ <point x="661" y="574" type="curve" smooth="yes"/>
+ <point x="852" y="574"/>
+ <point x="1036" y="683"/>
+ <point x="1172" y="840" type="curve"/>
+ <point x="1121" y="922" type="line"/>
+ <point x="1019" y="810"/>
+ <point x="872" y="745"/>
+ <point x="717" y="745" type="curve" smooth="yes"/>
+ <point x="584" y="745"/>
+ <point x="498" y="833"/>
+ <point x="498" y="956" type="curve" smooth="yes"/>
+ <point x="498" y="1146"/>
+ <point x="638" y="1284"/>
+ <point x="821" y="1284" type="curve" smooth="yes"/>
+ <point x="998" y="1284"/>
+ <point x="1073" y="1119"/>
+ <point x="1073" y="956" type="curve" smooth="yes"/>
+ <point x="1073" y="455"/>
+ <point x="760" y="147"/>
+ <point x="496" y="147" type="curve" smooth="yes"/>
+ <point x="410" y="147"/>
+ <point x="298" y="209"/>
+ <point x="249" y="285" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfcopyglyphs.ufo/glyphs/D_igitO_ne.glif b/tests/reference/ufo/psfcopyglyphs.ufo/glyphs/D_igitO_ne.glif
new file mode 100644
index 0000000..a639774
--- /dev/null
+++ b/tests/reference/ufo/psfcopyglyphs.ufo/glyphs/D_igitO_ne.glif
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="DigitOne" format="2">
+ <advance width="1180"/>
+ <unicode hex="0031"/>
+ <anchor x="515" y="-100" name="L"/>
+ <anchor x="922" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="1021" y="167" type="line"/>
+ <point x="706" y="167" type="line"/>
+ <point x="1026" y="1450" type="line"/>
+ <point x="856" y="1450" type="line"/>
+ <point x="459" y="1243" type="line"/>
+ <point x="440" y="1066" type="line"/>
+ <point x="782" y="1235" type="line"/>
+ <point x="516" y="167" type="line"/>
+ <point x="201" y="167" type="line"/>
+ <point x="160" y="0" type="line"/>
+ <point x="980" y="0" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfcopyglyphs.ufo/glyphs/D_igitS_even.glif b/tests/reference/ufo/psfcopyglyphs.ufo/glyphs/D_igitS_even.glif
new file mode 100644
index 0000000..68c6ef6
--- /dev/null
+++ b/tests/reference/ufo/psfcopyglyphs.ufo/glyphs/D_igitS_even.glif
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="DigitSeven" format="2">
+ <advance width="1180"/>
+ <unicode hex="0037"/>
+ <anchor x="515" y="-100" name="L"/>
+ <anchor x="922" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="420" y="0" type="line"/>
+ <point x="661" y="450"/>
+ <point x="972" y="877"/>
+ <point x="1367" y="1274" type="curve"/>
+ <point x="1406" y="1431" type="line"/>
+ <point x="386" y="1431" type="line"/>
+ <point x="341" y="1245" type="line"/>
+ <point x="421" y="1260"/>
+ <point x="538" y="1264"/>
+ <point x="726" y="1264" type="curve" smooth="yes"/>
+ <point x="1126" y="1264" type="line"/>
+ <point x="774" y="889"/>
+ <point x="517" y="555"/>
+ <point x="215" y="0" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfcopyglyphs.ufo/glyphs/D_igitS_ix.glif b/tests/reference/ufo/psfcopyglyphs.ufo/glyphs/D_igitS_ix.glif
new file mode 100644
index 0000000..b6be793
--- /dev/null
+++ b/tests/reference/ufo/psfcopyglyphs.ufo/glyphs/D_igitS_ix.glif
@@ -0,0 +1,49 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="DigitSix" format="2">
+ <advance width="1180"/>
+ <unicode hex="0036"/>
+ <anchor x="515" y="-100" name="L"/>
+ <anchor x="922" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="1313" y="1347" type="line"/>
+ <point x="1248" y="1418"/>
+ <point x="1135" y="1455"/>
+ <point x="1017" y="1455" type="curve" smooth="yes"/>
+ <point x="481" y="1454"/>
+ <point x="208" y="915"/>
+ <point x="208" y="475" type="curve" smooth="yes"/>
+ <point x="208" y="167"/>
+ <point x="392" y="-25"/>
+ <point x="623" y="-25" type="curve" smooth="yes"/>
+ <point x="947" y="-25"/>
+ <point x="1183" y="169"/>
+ <point x="1183" y="517" type="curve" smooth="yes"/>
+ <point x="1183" y="709"/>
+ <point x="1029" y="887"/>
+ <point x="793" y="887" type="curve" smooth="yes"/>
+ <point x="636" y="887"/>
+ <point x="432" y="784"/>
+ <point x="317" y="633" type="curve"/>
+ <point x="364" y="559" type="line"/>
+ <point x="471" y="660"/>
+ <point x="596" y="716"/>
+ <point x="751" y="716" type="curve" smooth="yes"/>
+ <point x="898" y="716"/>
+ <point x="987" y="614"/>
+ <point x="987" y="454" type="curve" smooth="yes"/>
+ <point x="987" y="263"/>
+ <point x="816" y="147"/>
+ <point x="656" y="147" type="curve" smooth="yes"/>
+ <point x="491" y="147"/>
+ <point x="403" y="284"/>
+ <point x="403" y="472" type="curve" smooth="yes"/>
+ <point x="403" y="962"/>
+ <point x="664" y="1284"/>
+ <point x="985" y="1284" type="curve" smooth="yes"/>
+ <point x="1081" y="1284"/>
+ <point x="1174" y="1235"/>
+ <point x="1222" y="1156" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfcopyglyphs.ufo/glyphs/D_igitT_hree.glif b/tests/reference/ufo/psfcopyglyphs.ufo/glyphs/D_igitT_hree.glif
new file mode 100644
index 0000000..e01df2c
--- /dev/null
+++ b/tests/reference/ufo/psfcopyglyphs.ufo/glyphs/D_igitT_hree.glif
@@ -0,0 +1,52 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="DigitThree" format="2">
+ <advance width="1180"/>
+ <unicode hex="0033"/>
+ <anchor x="515" y="-100" name="L"/>
+ <anchor x="922" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="562" y="853" type="line"/>
+ <point x="521" y="686" type="line"/>
+ <point x="591" y="686" type="line" smooth="yes"/>
+ <point x="802" y="686"/>
+ <point x="944" y="606"/>
+ <point x="944" y="476" type="curve" smooth="yes"/>
+ <point x="944" y="268"/>
+ <point x="738" y="147"/>
+ <point x="551" y="147" type="curve" smooth="yes"/>
+ <point x="371" y="147"/>
+ <point x="260" y="227"/>
+ <point x="181" y="348" type="curve"/>
+ <point x="104" y="137" type="line"/>
+ <point x="185" y="41"/>
+ <point x="341" y="-25"/>
+ <point x="518" y="-25" type="curve" smooth="yes"/>
+ <point x="815" y="-25"/>
+ <point x="1141" y="168"/>
+ <point x="1141" y="475" type="curve" smooth="yes"/>
+ <point x="1141" y="670"/>
+ <point x="973" y="763"/>
+ <point x="855" y="784" type="curve"/>
+ <point x="1046" y="827"/>
+ <point x="1266" y="955"/>
+ <point x="1266" y="1163" type="curve" smooth="yes"/>
+ <point x="1266" y="1338"/>
+ <point x="1073" y="1455"/>
+ <point x="852" y="1455" type="curve" smooth="yes"/>
+ <point x="685" y="1455"/>
+ <point x="536" y="1388"/>
+ <point x="433" y="1299" type="curve"/>
+ <point x="427" y="1132" type="line"/>
+ <point x="568" y="1246"/>
+ <point x="696" y="1284"/>
+ <point x="850" y="1284" type="curve" smooth="yes"/>
+ <point x="957" y="1284"/>
+ <point x="1068" y="1236"/>
+ <point x="1068" y="1137" type="curve" smooth="yes"/>
+ <point x="1068" y="949"/>
+ <point x="781" y="853"/>
+ <point x="632" y="853" type="curve" smooth="yes"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfcopyglyphs.ufo/glyphs/D_igitT_wo.glif b/tests/reference/ufo/psfcopyglyphs.ufo/glyphs/D_igitT_wo.glif
new file mode 100644
index 0000000..d1bbb54
--- /dev/null
+++ b/tests/reference/ufo/psfcopyglyphs.ufo/glyphs/D_igitT_wo.glif
@@ -0,0 +1,37 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="DigitTwo" format="2">
+ <advance width="1180"/>
+ <unicode hex="0032"/>
+ <anchor x="515" y="-100" name="L"/>
+ <anchor x="882" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="1063" y="176" type="line"/>
+ <point x="980" y="163"/>
+ <point x="822" y="162"/>
+ <point x="625" y="162" type="curve" smooth="yes"/>
+ <point x="370" y="162" type="line"/>
+ <point x="783" y="393"/>
+ <point x="1210" y="830"/>
+ <point x="1210" y="1098" type="curve" smooth="yes"/>
+ <point x="1210" y="1296"/>
+ <point x="1075" y="1455"/>
+ <point x="842" y="1455" type="curve" smooth="yes"/>
+ <point x="673" y="1455"/>
+ <point x="488" y="1374"/>
+ <point x="380" y="1264" type="curve"/>
+ <point x="388" y="1098" type="line"/>
+ <point x="503" y="1203"/>
+ <point x="660" y="1279"/>
+ <point x="783" y="1279" type="curve" smooth="yes"/>
+ <point x="915" y="1279"/>
+ <point x="1003" y="1199"/>
+ <point x="1003" y="1063" type="curve" smooth="yes"/>
+ <point x="1003" y="848"/>
+ <point x="506" y="386"/>
+ <point x="101" y="167" type="curve"/>
+ <point x="60" y="0" type="line"/>
+ <point x="1020" y="0" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfcopyglyphs.ufo/glyphs/D_igitZ_ero.glif b/tests/reference/ufo/psfcopyglyphs.ufo/glyphs/D_igitZ_ero.glif
new file mode 100644
index 0000000..5d1bf0e
--- /dev/null
+++ b/tests/reference/ufo/psfcopyglyphs.ufo/glyphs/D_igitZ_ero.glif
@@ -0,0 +1,49 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="DigitZero" format="2">
+ <advance width="1180"/>
+ <unicode hex="0030"/>
+ <anchor x="520" y="-100" name="L"/>
+ <anchor x="927" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="1024" y="711" type="curve" smooth="yes"/>
+ <point x="925" y="312"/>
+ <point x="747" y="142"/>
+ <point x="565" y="142" type="curve" smooth="yes"/>
+ <point x="432" y="142"/>
+ <point x="360" y="218"/>
+ <point x="360" y="383" type="curve" smooth="yes"/>
+ <point x="360" y="468"/>
+ <point x="377" y="579"/>
+ <point x="412" y="720" type="curve" smooth="yes"/>
+ <point x="512" y="1120"/>
+ <point x="678" y="1289"/>
+ <point x="871" y="1289" type="curve" smooth="yes"/>
+ <point x="1006" y="1289"/>
+ <point x="1077" y="1223"/>
+ <point x="1077" y="1051" type="curve" smooth="yes"/>
+ <point x="1077" y="966"/>
+ <point x="1060" y="854"/>
+ </contour>
+ <contour>
+ <point x="1230" y="715" type="curve" smooth="yes"/>
+ <point x="1262" y="841"/>
+ <point x="1276" y="949"/>
+ <point x="1276" y="1040" type="curve" smooth="yes"/>
+ <point x="1276" y="1335"/>
+ <point x="1124" y="1455"/>
+ <point x="902" y="1455" type="curve" smooth="yes"/>
+ <point x="613" y="1455"/>
+ <point x="344" y="1267"/>
+ <point x="206" y="716" type="curve" smooth="yes"/>
+ <point x="173" y="584"/>
+ <point x="158" y="474"/>
+ <point x="158" y="381" type="curve" smooth="yes"/>
+ <point x="158" y="104"/>
+ <point x="313" y="-25"/>
+ <point x="533" y="-25" type="curve" smooth="yes"/>
+ <point x="804" y="-25"/>
+ <point x="1086" y="138"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfcopyglyphs.ufo/glyphs/D_ollarS_gn.glif b/tests/reference/ufo/psfcopyglyphs.ufo/glyphs/D_ollarS_gn.glif
new file mode 100644
index 0000000..5c2db20
--- /dev/null
+++ b/tests/reference/ufo/psfcopyglyphs.ufo/glyphs/D_ollarS_gn.glif
@@ -0,0 +1,53 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="DollarSgn" format="2">
+ <advance width="1180"/>
+ <unicode hex="0024"/>
+ <outline>
+ <contour>
+ <point x="1225" y="1280" type="line"/>
+ <point x="1119" y="1337"/>
+ <point x="1023" y="1361"/>
+ <point x="882" y="1361" type="curve" smooth="yes"/>
+ <point x="513" y="1361"/>
+ <point x="354" y="1182"/>
+ <point x="354" y="992" type="curve" smooth="yes"/>
+ <point x="354" y="837"/>
+ <point x="446" y="771"/>
+ <point x="639" y="650" type="curve" smooth="yes"/>
+ <point x="844" y="521"/>
+ <point x="919" y="439"/>
+ <point x="919" y="357" type="curve" smooth="yes"/>
+ <point x="919" y="244"/>
+ <point x="826" y="158"/>
+ <point x="635" y="158" type="curve" smooth="yes"/>
+ <point x="469" y="158"/>
+ <point x="314" y="266"/>
+ <point x="251" y="347" type="curve"/>
+ <point x="163" y="162" type="line"/>
+ <point x="304" y="58"/>
+ <point x="453" y="0"/>
+ <point x="606" y="0" type="curve" smooth="yes"/>
+ <point x="872" y="0"/>
+ <point x="1102" y="119"/>
+ <point x="1102" y="381" type="curve" smooth="yes"/>
+ <point x="1102" y="528"/>
+ <point x="981" y="657"/>
+ <point x="801" y="771" type="curve" smooth="yes"/>
+ <point x="610" y="892"/>
+ <point x="535" y="943"/>
+ <point x="535" y="1024" type="curve" smooth="yes"/>
+ <point x="535" y="1116"/>
+ <point x="657" y="1203"/>
+ <point x="832" y="1203" type="curve" smooth="yes"/>
+ <point x="950" y="1203"/>
+ <point x="1031" y="1176"/>
+ <point x="1144" y="1104" type="curve"/>
+ </contour>
+ <contour>
+ <point x="878" y="1568" type="line"/>
+ <point x="434" y="-216" type="line"/>
+ <point x="574" y="-216" type="line"/>
+ <point x="1018" y="1568" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfcopyglyphs.ufo/glyphs/D_ottedC_irc.glif b/tests/reference/ufo/psfcopyglyphs.ufo/glyphs/D_ottedC_irc.glif
new file mode 100644
index 0000000..2cdf8fd
--- /dev/null
+++ b/tests/reference/ufo/psfcopyglyphs.ufo/glyphs/D_ottedC_irc.glif
@@ -0,0 +1,235 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="DottedCirc" format="2">
+ <advance width="1086"/>
+ <unicode hex="25CC"/>
+ <anchor x="493" y="0" name="H"/>
+ <anchor x="468" y="-100" name="L"/>
+ <anchor x="750" y="0" name="O"/>
+ <anchor x="743" y="1000" name="U"/>
+ <outline>
+ <contour>
+ <point x="588" y="834" type="curve" smooth="yes"/>
+ <point x="588" y="858"/>
+ <point x="571" y="867"/>
+ <point x="553" y="867" type="curve" smooth="yes"/>
+ <point x="521" y="867"/>
+ <point x="491" y="837"/>
+ <point x="491" y="809" type="curve" smooth="yes"/>
+ <point x="491" y="788"/>
+ <point x="508" y="773"/>
+ <point x="530" y="773" type="curve" smooth="yes"/>
+ <point x="564" y="773"/>
+ <point x="588" y="805"/>
+ </contour>
+ <contour>
+ <point x="677" y="124" type="curve" smooth="yes"/>
+ <point x="647" y="124"/>
+ <point x="620" y="93"/>
+ <point x="620" y="67" type="curve" smooth="yes"/>
+ <point x="620" y="46"/>
+ <point x="636" y="30"/>
+ <point x="657" y="30" type="curve" smooth="yes"/>
+ <point x="687" y="30"/>
+ <point x="718" y="60"/>
+ <point x="718" y="86" type="curve" smooth="yes"/>
+ <point x="718" y="109"/>
+ <point x="700" y="124"/>
+ </contour>
+ <contour>
+ <point x="396" y="780" type="curve" smooth="yes"/>
+ <point x="369" y="780"/>
+ <point x="336" y="753"/>
+ <point x="336" y="722" type="curve" smooth="yes"/>
+ <point x="336" y="702"/>
+ <point x="351" y="687"/>
+ <point x="374" y="687" type="curve" smooth="yes"/>
+ <point x="403" y="687"/>
+ <point x="434" y="711"/>
+ <point x="434" y="744" type="curve" smooth="yes"/>
+ <point x="434" y="764"/>
+ <point x="414" y="780"/>
+ </contour>
+ <contour>
+ <point x="873" y="175" type="curve" smooth="yes"/>
+ <point x="872" y="199"/>
+ <point x="854" y="211"/>
+ <point x="833" y="211" type="curve" smooth="yes"/>
+ <point x="803" y="211"/>
+ <point x="774" y="183"/>
+ <point x="774" y="153" type="curve" smooth="yes"/>
+ <point x="774" y="133"/>
+ <point x="789" y="119"/>
+ <point x="812" y="119" type="curve" smooth="yes"/>
+ <point x="843" y="119"/>
+ <point x="873" y="146"/>
+ </contour>
+ <contour>
+ <point x="313" y="612" type="curve" smooth="yes"/>
+ <point x="312" y="633"/>
+ <point x="296" y="650"/>
+ <point x="275" y="650" type="curve" smooth="yes"/>
+ <point x="247" y="650"/>
+ <point x="215" y="623"/>
+ <point x="215" y="592" type="curve" smooth="yes"/>
+ <point x="215" y="573"/>
+ <point x="227" y="556"/>
+ <point x="251" y="556" type="curve" smooth="yes"/>
+ <point x="278" y="556"/>
+ <point x="313" y="581"/>
+ </contour>
+ <contour>
+ <point x="994" y="306" type="curve" smooth="yes"/>
+ <point x="993" y="327"/>
+ <point x="978" y="341"/>
+ <point x="958" y="341" type="curve" smooth="yes"/>
+ <point x="933" y="341"/>
+ <point x="896" y="321"/>
+ <point x="896" y="284" type="curve" smooth="yes"/>
+ <point x="896" y="265"/>
+ <point x="909" y="249"/>
+ <point x="934" y="249" type="curve" smooth="yes"/>
+ <point x="963" y="249"/>
+ <point x="994" y="275"/>
+ </contour>
+ <contour>
+ <point x="205" y="495" type="curve" smooth="yes"/>
+ <point x="175" y="495"/>
+ <point x="145" y="468"/>
+ <point x="145" y="438" type="curve" smooth="yes"/>
+ <point x="145" y="418"/>
+ <point x="159" y="402"/>
+ <point x="183" y="402" type="curve" smooth="yes"/>
+ <point x="208" y="402"/>
+ <point x="244" y="428"/>
+ <point x="244" y="459" type="curve" smooth="yes"/>
+ <point x="244" y="479"/>
+ <point x="227" y="495"/>
+ </contour>
+ <contour>
+ <point x="1026" y="496" type="curve" smooth="yes"/>
+ <point x="999" y="496"/>
+ <point x="965" y="469"/>
+ <point x="965" y="438" type="curve" smooth="yes"/>
+ <point x="965" y="418"/>
+ <point x="979" y="403"/>
+ <point x="1004" y="403" type="curve" smooth="yes"/>
+ <point x="1033" y="403"/>
+ <point x="1064" y="431"/>
+ <point x="1064" y="460" type="curve" smooth="yes"/>
+ <point x="1064" y="480"/>
+ <point x="1048" y="496"/>
+ </contour>
+ <contour>
+ <point x="237" y="307" type="curve" smooth="yes"/>
+ <point x="237" y="327"/>
+ <point x="221" y="341"/>
+ <point x="199" y="341" type="curve" smooth="yes"/>
+ <point x="169" y="341"/>
+ <point x="138" y="314"/>
+ <point x="138" y="285" type="curve" smooth="yes"/>
+ <point x="138" y="263"/>
+ <point x="153" y="248"/>
+ <point x="175" y="248" type="curve" smooth="yes"/>
+ <point x="206" y="248"/>
+ <point x="237" y="278"/>
+ </contour>
+ <contour>
+ <point x="1071" y="613" type="curve" smooth="yes"/>
+ <point x="1071" y="634"/>
+ <point x="1055" y="650"/>
+ <point x="1034" y="650" type="curve" smooth="yes"/>
+ <point x="1003" y="650"/>
+ <point x="973" y="619"/>
+ <point x="973" y="590" type="curve" smooth="yes"/>
+ <point x="973" y="570"/>
+ <point x="989" y="556"/>
+ <point x="1009" y="556" type="curve" smooth="yes"/>
+ <point x="1041" y="556"/>
+ <point x="1071" y="585"/>
+ </contour>
+ <contour>
+ <point x="292" y="177" type="curve" smooth="yes"/>
+ <point x="292" y="197"/>
+ <point x="277" y="211"/>
+ <point x="253" y="211" type="curve" smooth="yes"/>
+ <point x="224" y="211"/>
+ <point x="194" y="181"/>
+ <point x="194" y="154" type="curve" smooth="yes"/>
+ <point x="194" y="134"/>
+ <point x="211" y="118"/>
+ <point x="232" y="118" type="curve" smooth="yes"/>
+ <point x="262" y="118"/>
+ <point x="292" y="148"/>
+ </contour>
+ <contour>
+ <point x="917" y="724" type="curve" smooth="yes"/>
+ <point x="917" y="704"/>
+ <point x="931" y="686"/>
+ <point x="954" y="686" type="curve" smooth="yes"/>
+ <point x="984" y="686"/>
+ <point x="1014" y="716"/>
+ <point x="1014" y="745" type="curve" smooth="yes"/>
+ <point x="1014" y="765"/>
+ <point x="1000" y="780"/>
+ <point x="977" y="780" type="curve" smooth="yes"/>
+ <point x="947" y="780"/>
+ <point x="917" y="753"/>
+ </contour>
+ <contour>
+ <point x="403" y="87" type="curve" smooth="yes"/>
+ <point x="403" y="107"/>
+ <point x="390" y="123"/>
+ <point x="367" y="123" type="curve" smooth="yes"/>
+ <point x="339" y="123"/>
+ <point x="305" y="96"/>
+ <point x="305" y="68" type="curve" smooth="yes"/>
+ <point x="305" y="49"/>
+ <point x="320" y="30"/>
+ <point x="343" y="30" type="curve" smooth="yes"/>
+ <point x="371" y="30"/>
+ <point x="403" y="56"/>
+ </contour>
+ <contour>
+ <point x="806" y="810" type="curve" smooth="yes"/>
+ <point x="806" y="791"/>
+ <point x="819" y="773"/>
+ <point x="842" y="773" type="curve" smooth="yes"/>
+ <point x="869" y="773"/>
+ <point x="903" y="799"/>
+ <point x="903" y="830" type="curve" smooth="yes"/>
+ <point x="903" y="850"/>
+ <point x="889" y="867"/>
+ <point x="866" y="867" type="curve" smooth="yes"/>
+ <point x="836" y="867"/>
+ <point x="806" y="839"/>
+ </contour>
+ <contour>
+ <point x="553" y="57" type="curve" smooth="yes"/>
+ <point x="553" y="78"/>
+ <point x="538" y="93"/>
+ <point x="516" y="93" type="curve" smooth="yes"/>
+ <point x="485" y="93"/>
+ <point x="456" y="65"/>
+ <point x="456" y="36" type="curve" smooth="yes"/>
+ <point x="456" y="16"/>
+ <point x="471" y="0"/>
+ <point x="493" y="0" type="curve" smooth="yes"/>
+ <point x="523" y="0"/>
+ <point x="553" y="27"/>
+ </contour>
+ <contour>
+ <point x="656" y="839" type="curve" smooth="yes"/>
+ <point x="656" y="819"/>
+ <point x="671" y="805"/>
+ <point x="693" y="805" type="curve" smooth="yes"/>
+ <point x="721" y="805"/>
+ <point x="754" y="830"/>
+ <point x="754" y="861" type="curve" smooth="yes"/>
+ <point x="754" y="882"/>
+ <point x="738" y="898"/>
+ <point x="716" y="898" type="curve" smooth="yes"/>
+ <point x="685" y="898"/>
+ <point x="656" y="868"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfcopyglyphs.ufo/glyphs/E_qS_gn.glif b/tests/reference/ufo/psfcopyglyphs.ufo/glyphs/E_qS_gn.glif
new file mode 100644
index 0000000..3d756e8
--- /dev/null
+++ b/tests/reference/ufo/psfcopyglyphs.ufo/glyphs/E_qS_gn.glif
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="EqSgn" format="2">
+ <advance width="1180"/>
+ <unicode hex="003D"/>
+ <outline>
+ <contour>
+ <point x="177" y="470" type="line"/>
+ <point x="1137" y="470" type="line"/>
+ <point x="1173" y="617" type="line"/>
+ <point x="213" y="617" type="line"/>
+ </contour>
+ <contour>
+ <point x="262" y="813" type="line"/>
+ <point x="1222" y="813" type="line"/>
+ <point x="1259" y="960" type="line"/>
+ <point x="299" y="960" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfcopyglyphs.ufo/glyphs/E_xclamationM_rk.glif b/tests/reference/ufo/psfcopyglyphs.ufo/glyphs/E_xclamationM_rk.glif
new file mode 100644
index 0000000..a1c14d9
--- /dev/null
+++ b/tests/reference/ufo/psfcopyglyphs.ufo/glyphs/E_xclamationM_rk.glif
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="ExclamationMrk" format="2">
+ <advance width="744"/>
+ <unicode hex="0021"/>
+ <outline>
+ <contour>
+ <point x="497" y="431" type="line"/>
+ <point x="574" y="715"/>
+ <point x="653" y="1054"/>
+ <point x="799" y="1480" type="curve"/>
+ <point x="544" y="1480" type="line"/>
+ <point x="475" y="1054"/>
+ <point x="386" y="715"/>
+ <point x="322" y="431" type="curve"/>
+ </contour>
+ <contour>
+ <point x="188" y="90" type="curve" smooth="yes"/>
+ <point x="188" y="28"/>
+ <point x="238" y="-25"/>
+ <point x="303" y="-25" type="curve" smooth="yes"/>
+ <point x="387" y="-25"/>
+ <point x="464" y="45"/>
+ <point x="464" y="125" type="curve" smooth="yes"/>
+ <point x="464" y="186"/>
+ <point x="414" y="240"/>
+ <point x="349" y="240" type="curve" smooth="yes"/>
+ <point x="265" y="240"/>
+ <point x="188" y="170"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfcopyglyphs.ufo/glyphs/F_ullS_top.glif b/tests/reference/ufo/psfcopyglyphs.ufo/glyphs/F_ullS_top.glif
new file mode 100644
index 0000000..a6c4d08
--- /dev/null
+++ b/tests/reference/ufo/psfcopyglyphs.ufo/glyphs/F_ullS_top.glif
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="FullStop" format="2">
+ <advance width="620"/>
+ <unicode hex="002E"/>
+ <outline>
+ <contour>
+ <point x="148" y="90" type="curve" smooth="yes"/>
+ <point x="148" y="28"/>
+ <point x="198" y="-25"/>
+ <point x="263" y="-25" type="curve" smooth="yes"/>
+ <point x="347" y="-25"/>
+ <point x="424" y="45"/>
+ <point x="424" y="125" type="curve" smooth="yes"/>
+ <point x="424" y="186"/>
+ <point x="374" y="240"/>
+ <point x="309" y="240" type="curve" smooth="yes"/>
+ <point x="225" y="240"/>
+ <point x="148" y="170"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfcopyglyphs.ufo/glyphs/F_ullstart.glif b/tests/reference/ufo/psfcopyglyphs.ufo/glyphs/F_ullstart.glif
new file mode 100644
index 0000000..42c72b2
--- /dev/null
+++ b/tests/reference/ufo/psfcopyglyphs.ufo/glyphs/F_ullstart.glif
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="Fullstart" format="2">
+ <advance width="640"/>
+ <outline>
+ <contour>
+ <point x="185" y="110" type="curve" smooth="yes"/>
+ <point x="185" y="36"/>
+ <point x="246" y="-25"/>
+ <point x="320" y="-25" type="curve" smooth="yes"/>
+ <point x="394" y="-25"/>
+ <point x="455" y="36"/>
+ <point x="455" y="110" type="curve" smooth="yes"/>
+ <point x="455" y="184"/>
+ <point x="394" y="245"/>
+ <point x="320" y="245" type="curve" smooth="yes"/>
+ <point x="246" y="245"/>
+ <point x="185" y="184"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfcopyglyphs.ufo/glyphs/G_T_S_gn.glif b/tests/reference/ufo/psfcopyglyphs.ufo/glyphs/G_T_S_gn.glif
new file mode 100644
index 0000000..12da8b3
--- /dev/null
+++ b/tests/reference/ufo/psfcopyglyphs.ufo/glyphs/G_T_S_gn.glif
@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="GTSgn" format="2">
+ <advance width="1180"/>
+ <unicode hex="003E"/>
+ <outline>
+ <contour>
+ <point x="312" y="1014" type="line"/>
+ <point x="1028" y="725" type="line"/>
+ <point x="163" y="417" type="line"/>
+ <point x="119" y="240" type="line"/>
+ <point x="1197" y="632" type="line"/>
+ <point x="1239" y="799" type="line"/>
+ <point x="356" y="1191" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfcopyglyphs.ufo/glyphs/G_raveA_ccent.glif b/tests/reference/ufo/psfcopyglyphs.ufo/glyphs/G_raveA_ccent.glif
new file mode 100644
index 0000000..48adfc4
--- /dev/null
+++ b/tests/reference/ufo/psfcopyglyphs.ufo/glyphs/G_raveA_ccent.glif
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="GraveAccent" format="2">
+ <advance width="560"/>
+ <unicode hex="0060"/>
+ <anchor x="738" y="1635" name="U"/>
+ <outline>
+ <contour>
+ <point x="261" y="1568" type="line"/>
+ <point x="596" y="1147" type="line"/>
+ <point x="746" y="1147" type="line"/>
+ <point x="471" y="1568" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfcopyglyphs.ufo/glyphs/H_yphen.glif b/tests/reference/ufo/psfcopyglyphs.ufo/glyphs/H_yphen.glif
new file mode 100644
index 0000000..ae8cad5
--- /dev/null
+++ b/tests/reference/ufo/psfcopyglyphs.ufo/glyphs/H_yphen.glif
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="Hyphen" format="2">
+ <advance width="840"/>
+ <unicode hex="2010"/>
+ <anchor x="645" y="1100" name="U"/>
+ <outline>
+ <contour>
+ <point x="155" y="544" type="line"/>
+ <point x="855" y="544" type="line"/>
+ <point x="892" y="691" type="line"/>
+ <point x="192" y="691" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfcopyglyphs.ufo/glyphs/H_yphenM_inus.glif b/tests/reference/ufo/psfcopyglyphs.ufo/glyphs/H_yphenM_inus.glif
new file mode 100644
index 0000000..155b460
--- /dev/null
+++ b/tests/reference/ufo/psfcopyglyphs.ufo/glyphs/H_yphenM_inus.glif
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="HyphenMinus" format="2">
+ <advance width="840"/>
+ <unicode hex="002D"/>
+ <anchor x="645" y="1100" name="U"/>
+ <outline>
+ <contour>
+ <point x="155" y="544" type="line"/>
+ <point x="855" y="544" type="line"/>
+ <point x="892" y="691" type="line"/>
+ <point x="192" y="691" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfcopyglyphs.ufo/glyphs/H_yphen_S_oft.glif b/tests/reference/ufo/psfcopyglyphs.ufo/glyphs/H_yphen_S_oft.glif
new file mode 100644
index 0000000..0c7b834
--- /dev/null
+++ b/tests/reference/ufo/psfcopyglyphs.ufo/glyphs/H_yphen_S_oft.glif
@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="Hyphen_Soft" format="2">
+ <advance width="840"/>
+ <unicode hex="00AD"/>
+ <anchor x="645" y="1100" name="U"/>
+ <outline>
+ <component base="HyphenMinus"/>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfcopyglyphs.ufo/glyphs/L_T_S_gn.glif b/tests/reference/ufo/psfcopyglyphs.ufo/glyphs/L_T_S_gn.glif
new file mode 100644
index 0000000..3c857a5
--- /dev/null
+++ b/tests/reference/ufo/psfcopyglyphs.ufo/glyphs/L_T_S_gn.glif
@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LTSgn" format="2">
+ <advance width="1180"/>
+ <unicode hex="003C"/>
+ <outline>
+ <contour>
+ <point x="1123" y="417" type="line"/>
+ <point x="408" y="705" type="line"/>
+ <point x="1272" y="1014" type="line"/>
+ <point x="1316" y="1191" type="line"/>
+ <point x="239" y="799" type="line"/>
+ <point x="197" y="632" type="line"/>
+ <point x="1079" y="240" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfcopyglyphs.ufo/glyphs/L_ftC_urlyB_rac.glif b/tests/reference/ufo/psfcopyglyphs.ufo/glyphs/L_ftC_urlyB_rac.glif
new file mode 100644
index 0000000..4f8c90c
--- /dev/null
+++ b/tests/reference/ufo/psfcopyglyphs.ufo/glyphs/L_ftC_urlyB_rac.glif
@@ -0,0 +1,50 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LftCurlyBrac" format="2">
+ <advance width="980"/>
+ <unicode hex="007B"/>
+ <outline>
+ <contour>
+ <point x="713" y="-265" type="line"/>
+ <point x="660" y="-250"/>
+ <point x="526" y="-188"/>
+ <point x="526" y="-158" type="curve" smooth="yes"/>
+ <point x="526" y="-59"/>
+ <point x="649" y="404"/>
+ <point x="649" y="469" type="curve" smooth="yes"/>
+ <point x="649" y="509"/>
+ <point x="520" y="577"/>
+ <point x="520" y="602" type="curve" smooth="yes"/>
+ <point x="520" y="620"/>
+ <point x="688" y="700"/>
+ <point x="712" y="730" type="curve" smooth="yes"/>
+ <point x="741" y="767"/>
+ <point x="867" y="1326"/>
+ <point x="912" y="1372" type="curve" smooth="yes"/>
+ <point x="938" y="1399"/>
+ <point x="1073" y="1447"/>
+ <point x="1146" y="1470" type="curve"/>
+ <point x="1140" y="1607" type="line"/>
+ <point x="1030" y="1581"/>
+ <point x="856" y="1529"/>
+ <point x="805" y="1485" type="curve" smooth="yes"/>
+ <point x="714" y="1406"/>
+ <point x="572" y="796"/>
+ <point x="540" y="764" type="curve" smooth="yes"/>
+ <point x="504" y="729"/>
+ <point x="300" y="633"/>
+ <point x="300" y="601" type="curve" smooth="yes"/>
+ <point x="300" y="560"/>
+ <point x="460" y="468"/>
+ <point x="460" y="432" type="curve" smooth="yes"/>
+ <point x="460" y="362"/>
+ <point x="355" y="-53"/>
+ <point x="355" y="-219" type="curve" smooth="yes"/>
+ <point x="355" y="-247"/>
+ <point x="358" y="-268"/>
+ <point x="365" y="-279" type="curve" smooth="yes"/>
+ <point x="394" y="-323"/>
+ <point x="542" y="-375"/>
+ <point x="639" y="-402" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfcopyglyphs.ufo/glyphs/L_ftP_aren.glif b/tests/reference/ufo/psfcopyglyphs.ufo/glyphs/L_ftP_aren.glif
new file mode 100644
index 0000000..bc65fc1
--- /dev/null
+++ b/tests/reference/ufo/psfcopyglyphs.ufo/glyphs/L_ftP_aren.glif
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LftParen" format="2">
+ <advance width="775"/>
+ <unicode hex="0028"/>
+ <outline>
+ <contour>
+ <point x="895" y="1607" type="line"/>
+ <point x="582" y="1415"/>
+ <point x="314" y="1061"/>
+ <point x="207" y="633" type="curve" smooth="yes"/>
+ <point x="176" y="508"/>
+ <point x="161" y="386"/>
+ <point x="161" y="270" type="curve" smooth="yes"/>
+ <point x="161" y="17"/>
+ <point x="233" y="-211"/>
+ <point x="374" y="-402" type="curve"/>
+ <point x="505" y="-260" type="line"/>
+ <point x="397" y="-102"/>
+ <point x="348" y="75"/>
+ <point x="348" y="270" type="curve" smooth="yes"/>
+ <point x="348" y="385"/>
+ <point x="365" y="506"/>
+ <point x="397" y="633" type="curve" smooth="yes"/>
+ <point x="484" y="982"/>
+ <point x="647" y="1254"/>
+ <point x="932" y="1455" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfcopyglyphs.ufo/glyphs/L_ftS_qrB_rac.glif b/tests/reference/ufo/psfcopyglyphs.ufo/glyphs/L_ftS_qrB_rac.glif
new file mode 100644
index 0000000..6d064d1
--- /dev/null
+++ b/tests/reference/ufo/psfcopyglyphs.ufo/glyphs/L_ftS_qrB_rac.glif
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LftSqrBrac" format="2">
+ <advance width="770"/>
+ <unicode hex="005B"/>
+ <outline>
+ <contour>
+ <point x="484" y="-402" type="line"/>
+ <point x="521" y="-255" type="line"/>
+ <point x="266" y="-255" type="line"/>
+ <point x="679" y="1421" type="line"/>
+ <point x="934" y="1421" type="line"/>
+ <point x="970" y="1568" type="line"/>
+ <point x="530" y="1568" type="line"/>
+ <point x="44" y="-402" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfcopyglyphs.ufo/glyphs/L_owL_ine.glif b/tests/reference/ufo/psfcopyglyphs.ufo/glyphs/L_owL_ine.glif
new file mode 100644
index 0000000..879d36b
--- /dev/null
+++ b/tests/reference/ufo/psfcopyglyphs.ufo/glyphs/L_owL_ine.glif
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LowLine" format="2">
+ <advance width="1254"/>
+ <unicode hex="005F"/>
+ <outline>
+ <contour>
+ <point x="-138" y="-314" type="line"/>
+ <point x="1135" y="-314" type="line"/>
+ <point x="1172" y="-167" type="line"/>
+ <point x="-101" y="-167" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfcopyglyphs.ufo/glyphs/L_tnC_apA_.alt.glif b/tests/reference/ufo/psfcopyglyphs.ufo/glyphs/L_tnC_apA_.alt.glif
new file mode 100644
index 0000000..6cb1336
--- /dev/null
+++ b/tests/reference/ufo/psfcopyglyphs.ufo/glyphs/L_tnC_apA_.alt.glif
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnCapA.alt" format="2">
+ <advance width="1395"/>
+ <unicode hex="3029"/>
+ <anchor x="668" y="1460" name="H"/>
+ <anchor x="688" y="1560" name="L"/>
+ <anchor x="-75" y="1460" name="O"/>
+ <anchor x="688" y="-70" name="U"/>
+ <outline>
+ <contour>
+ <point x="1130" y="1460" type="line"/>
+ <point x="996" y="1075" type="line"/>
+ <point x="381" y="1075" type="line"/>
+ <point x="245" y="1460" type="line"/>
+ <point x="40" y="1460" type="line"/>
+ <point x="75" y="1380"/>
+ <point x="113" y="1291"/>
+ <point x="180" y="1105" type="curve" smooth="yes"/>
+ <point x="580" y="0" type="line"/>
+ <point x="795" y="0" type="line"/>
+ <point x="1195" y="1105" type="line" smooth="yes"/>
+ <point x="1263" y="1292"/>
+ <point x="1299" y="1379"/>
+ <point x="1335" y="1460" type="curve"/>
+ </contour>
+ <contour>
+ <point x="435" y="920" type="line"/>
+ <point x="942" y="920" type="line"/>
+ <point x="690" y="195" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfcopyglyphs.ufo/glyphs/L_tnC_apA_.glif b/tests/reference/ufo/psfcopyglyphs.ufo/glyphs/L_tnC_apA_.glif
new file mode 100644
index 0000000..3a14b0e
--- /dev/null
+++ b/tests/reference/ufo/psfcopyglyphs.ufo/glyphs/L_tnC_apA_.glif
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnCapA" format="2">
+ <advance width="1395"/>
+ <unicode hex="0041"/>
+ <anchor x="1170" y="0" name="H"/>
+ <anchor x="602" y="-100" name="L"/>
+ <anchor x="1390" y="0" name="O"/>
+ <anchor x="1009" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="1080" y="0" type="line"/>
+ <point x="1275" y="0" type="line"/>
+ <point x="1259" y="78"/>
+ <point x="1243" y="166"/>
+ <point x="1221" y="348" type="curve" smooth="yes"/>
+ <point x="1091" y="1431" type="line"/>
+ <point x="876" y="1431" type="line"/>
+ <point x="206" y="348" type="line" smooth="yes"/>
+ <point x="93" y="165"/>
+ <point x="35" y="79"/>
+ <point x="-20" y="0" type="curve"/>
+ <point x="195" y="0" type="line"/>
+ <point x="422" y="377" type="line"/>
+ <point x="1038" y="377" type="line"/>
+ </contour>
+ <contour>
+ <point x="944" y="1240" type="line"/>
+ <point x="1022" y="529" type="line"/>
+ <point x="514" y="529" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfcopyglyphs.ufo/glyphs/L_tnC_apA_D_iaer.glif b/tests/reference/ufo/psfcopyglyphs.ufo/glyphs/L_tnC_apA_D_iaer.glif
new file mode 100644
index 0000000..6c3502c
--- /dev/null
+++ b/tests/reference/ufo/psfcopyglyphs.ufo/glyphs/L_tnC_apA_D_iaer.glif
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnCapADiaer" format="2">
+ <advance width="1395"/>
+ <unicode hex="00C4"/>
+ <anchor x="1170" y="0" name="H"/>
+ <anchor x="602" y="-100" name="L"/>
+ <anchor x="1390" y="0" name="O"/>
+ <anchor x="1106" y="1935" name="U"/>
+ <outline>
+ <component base="LtnCapA"/>
+ <component base="CombDiaer" xOffset="1359" yOffset="430"/>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfcopyglyphs.ufo/glyphs/L_tnC_apB_.glif b/tests/reference/ufo/psfcopyglyphs.ufo/glyphs/L_tnC_apB_.glif
new file mode 100644
index 0000000..5445f93
--- /dev/null
+++ b/tests/reference/ufo/psfcopyglyphs.ufo/glyphs/L_tnC_apB_.glif
@@ -0,0 +1,62 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnCapB" format="2">
+ <advance width="1271"/>
+ <unicode hex="0042"/>
+ <anchor x="530" y="-100" name="L"/>
+ <anchor x="937" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="625" y="1284" type="line"/>
+ <point x="667" y="1286"/>
+ <point x="733" y="1289"/>
+ <point x="811" y="1289" type="curve" smooth="yes"/>
+ <point x="993" y="1289"/>
+ <point x="1080" y="1230"/>
+ <point x="1080" y="1105" type="curve" smooth="yes"/>
+ <point x="1080" y="932"/>
+ <point x="931" y="838"/>
+ <point x="698" y="838" type="curve" smooth="yes"/>
+ <point x="513" y="838" type="line"/>
+ </contour>
+ <contour>
+ <point x="226" y="446" type="line"/>
+ <point x="178" y="252"/>
+ <point x="134" y="78"/>
+ <point x="100" y="0" type="curve"/>
+ <point x="151" y="-5"/>
+ <point x="359" y="-10"/>
+ <point x="562" y="-10" type="curve" smooth="yes"/>
+ <point x="960" y="-10"/>
+ <point x="1201" y="149"/>
+ <point x="1201" y="453" type="curve" smooth="yes"/>
+ <point x="1201" y="644"/>
+ <point x="1067" y="736"/>
+ <point x="955" y="764" type="curve"/>
+ <point x="1155" y="819"/>
+ <point x="1283" y="941"/>
+ <point x="1283" y="1140" type="curve" smooth="yes"/>
+ <point x="1283" y="1310"/>
+ <point x="1136" y="1441"/>
+ <point x="869" y="1441" type="curve" smooth="yes"/>
+ <point x="700" y="1441"/>
+ <point x="546" y="1437"/>
+ <point x="456" y="1431" type="curve"/>
+ <point x="452" y="1352"/>
+ <point x="407" y="1172"/>
+ <point x="359" y="980" type="curve" smooth="yes"/>
+ </contour>
+ <contour>
+ <point x="476" y="686" type="line"/>
+ <point x="721" y="686" type="line" smooth="yes"/>
+ <point x="892" y="686"/>
+ <point x="1011" y="598"/>
+ <point x="1011" y="450" type="curve" smooth="yes"/>
+ <point x="1011" y="218"/>
+ <point x="806" y="147"/>
+ <point x="586" y="147" type="curve" smooth="yes"/>
+ <point x="474" y="147"/>
+ <point x="379" y="150"/>
+ <point x="342" y="152" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfcopyglyphs.ufo/glyphs/L_tnC_apC_.glif b/tests/reference/ufo/psfcopyglyphs.ufo/glyphs/L_tnC_apC_.glif
new file mode 100644
index 0000000..c2e4948
--- /dev/null
+++ b/tests/reference/ufo/psfcopyglyphs.ufo/glyphs/L_tnC_apC_.glif
@@ -0,0 +1,38 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnCapC" format="2">
+ <advance width="1341"/>
+ <unicode hex="0043"/>
+ <anchor x="690" y="0" name="H"/>
+ <anchor x="665" y="-100" name="L"/>
+ <anchor x="1072" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="1237" y="318" type="line"/>
+ <point x="1115" y="222"/>
+ <point x="934" y="147"/>
+ <point x="752" y="147" type="curve" smooth="yes"/>
+ <point x="537" y="147"/>
+ <point x="385" y="304"/>
+ <point x="385" y="532" type="curve" smooth="yes"/>
+ <point x="385" y="964"/>
+ <point x="704" y="1289"/>
+ <point x="1037" y="1289" type="curve" smooth="yes"/>
+ <point x="1168" y="1289"/>
+ <point x="1310" y="1235"/>
+ <point x="1385" y="1132" type="curve"/>
+ <point x="1489" y="1308" type="line"/>
+ <point x="1388" y="1408"/>
+ <point x="1201" y="1455"/>
+ <point x="1058" y="1455" type="curve" smooth="yes"/>
+ <point x="645" y="1455"/>
+ <point x="185" y="1093"/>
+ <point x="185" y="513" type="curve" smooth="yes"/>
+ <point x="185" y="202"/>
+ <point x="381" y="-25"/>
+ <point x="709" y="-25" type="curve" smooth="yes"/>
+ <point x="896" y="-25"/>
+ <point x="1087" y="21"/>
+ <point x="1230" y="127" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfcopyglyphs.ufo/glyphs/L_tnC_apD_.glif b/tests/reference/ufo/psfcopyglyphs.ufo/glyphs/L_tnC_apD_.glif
new file mode 100644
index 0000000..3b93811
--- /dev/null
+++ b/tests/reference/ufo/psfcopyglyphs.ufo/glyphs/L_tnC_apD_.glif
@@ -0,0 +1,51 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnCapD" format="2">
+ <advance width="1421"/>
+ <unicode hex="0044"/>
+ <anchor x="630" y="-100" name="L"/>
+ <anchor x="1037" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="226" y="446" type="line"/>
+ <point x="176" y="252"/>
+ <point x="134" y="78"/>
+ <point x="100" y="0" type="curve"/>
+ <point x="100" y="0"/>
+ <point x="414" y="-10"/>
+ <point x="542" y="-10" type="curve" smooth="yes"/>
+ <point x="985" y="-10"/>
+ <point x="1299" y="181"/>
+ <point x="1415" y="648" type="curve" smooth="yes"/>
+ <point x="1437" y="738"/>
+ <point x="1447" y="819"/>
+ <point x="1447" y="891" type="curve" smooth="yes"/>
+ <point x="1447" y="1279"/>
+ <point x="1188" y="1441"/>
+ <point x="894" y="1441" type="curve" smooth="yes"/>
+ <point x="759" y="1441"/>
+ <point x="543" y="1437"/>
+ <point x="456" y="1431" type="curve"/>
+ <point x="452" y="1352"/>
+ <point x="407" y="1172"/>
+ <point x="359" y="980" type="curve" smooth="yes"/>
+ </contour>
+ <contour>
+ <point x="623" y="1279" type="line"/>
+ <point x="674" y="1281"/>
+ <point x="764" y="1284"/>
+ <point x="830" y="1284" type="curve" smooth="yes"/>
+ <point x="1105" y="1284"/>
+ <point x="1246" y="1140"/>
+ <point x="1246" y="850" type="curve" smooth="yes"/>
+ <point x="1246" y="784"/>
+ <point x="1236" y="710"/>
+ <point x="1216" y="629" type="curve" smooth="yes"/>
+ <point x="1134" y="300"/>
+ <point x="925" y="152"/>
+ <point x="572" y="152" type="curve" smooth="yes"/>
+ <point x="477" y="152"/>
+ <point x="391" y="158"/>
+ <point x="345" y="162" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfcopyglyphs.ufo/glyphs/L_tnC_apE_.glif b/tests/reference/ufo/psfcopyglyphs.ufo/glyphs/L_tnC_apE_.glif
new file mode 100644
index 0000000..8b5f8b9
--- /dev/null
+++ b/tests/reference/ufo/psfcopyglyphs.ufo/glyphs/L_tnC_apE_.glif
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnCapE" format="2">
+ <advance width="1140"/>
+ <unicode hex="0045"/>
+ <anchor x="540" y="0" name="H"/>
+ <anchor x="515" y="-100" name="L"/>
+ <anchor x="857" y="0" name="O"/>
+ <anchor x="1400" y="1200" name="R"/>
+ <anchor x="922" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="511" y="828" type="line"/>
+ <point x="621" y="1269" type="line"/>
+ <point x="1266" y="1269" type="line"/>
+ <point x="1306" y="1431" type="line"/>
+ <point x="456" y="1431" type="line"/>
+ <point x="452" y="1352"/>
+ <point x="413" y="1197"/>
+ <point x="365" y="1005" type="curve" smooth="yes"/>
+ <point x="221" y="426" type="line" smooth="yes"/>
+ <point x="173" y="233"/>
+ <point x="134" y="78"/>
+ <point x="100" y="0" type="curve"/>
+ <point x="980" y="0" type="line"/>
+ <point x="1023" y="176" type="line"/>
+ <point x="940" y="163"/>
+ <point x="806" y="162"/>
+ <point x="609" y="162" type="curve" smooth="yes"/>
+ <point x="345" y="162" type="line"/>
+ <point x="472" y="671" type="line"/>
+ <point x="1042" y="671" type="line"/>
+ <point x="1081" y="828" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfcopyglyphs.ufo/glyphs/L_tnC_apF_.glif b/tests/reference/ufo/psfcopyglyphs.ufo/glyphs/L_tnC_apF_.glif
new file mode 100644
index 0000000..cbc1726
--- /dev/null
+++ b/tests/reference/ufo/psfcopyglyphs.ufo/glyphs/L_tnC_apF_.glif
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnCapF" format="2">
+ <advance width="1130"/>
+ <unicode hex="0046"/>
+ <anchor x="510" y="-100" name="L"/>
+ <anchor x="917" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="508" y="818" type="line"/>
+ <point x="621" y="1269" type="line"/>
+ <point x="1286" y="1269" type="line"/>
+ <point x="1326" y="1431" type="line"/>
+ <point x="456" y="1431" type="line"/>
+ <point x="452" y="1352"/>
+ <point x="412" y="1193"/>
+ <point x="364" y="1000" type="curve" smooth="yes"/>
+ <point x="221" y="426" type="line" smooth="yes"/>
+ <point x="173" y="233"/>
+ <point x="134" y="78"/>
+ <point x="100" y="0" type="curve"/>
+ <point x="320" y="0" type="line"/>
+ <point x="323" y="76"/>
+ <point x="362" y="232"/>
+ <point x="411" y="426" type="curve" smooth="yes"/>
+ <point x="470" y="662" type="line"/>
+ <point x="1050" y="662" type="line"/>
+ <point x="1088" y="818" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfcopyglyphs.ufo/glyphs/L_tnC_apG_.glif b/tests/reference/ufo/psfcopyglyphs.ufo/glyphs/L_tnC_apG_.glif
new file mode 100644
index 0000000..c39b75a
--- /dev/null
+++ b/tests/reference/ufo/psfcopyglyphs.ufo/glyphs/L_tnC_apG_.glif
@@ -0,0 +1,48 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnCapG" format="2">
+ <advance width="1406"/>
+ <unicode hex="0047"/>
+ <anchor x="685" y="0" name="H"/>
+ <anchor x="660" y="-100" name="L"/>
+ <anchor x="1067" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="1403" y="710" type="line"/>
+ <point x="863" y="710" type="line"/>
+ <point x="822" y="548" type="line"/>
+ <point x="1172" y="548" type="line"/>
+ <point x="1090" y="220" type="line"/>
+ <point x="1012" y="176"/>
+ <point x="858" y="147"/>
+ <point x="739" y="147" type="curve" smooth="yes"/>
+ <point x="520" y="147"/>
+ <point x="384" y="272"/>
+ <point x="384" y="493" type="curve" smooth="yes"/>
+ <point x="384" y="560"/>
+ <point x="394" y="636"/>
+ <point x="415" y="720" type="curve" smooth="yes"/>
+ <point x="500" y="1062"/>
+ <point x="747" y="1289"/>
+ <point x="1052" y="1289" type="curve" smooth="yes"/>
+ <point x="1195" y="1289"/>
+ <point x="1335" y="1233"/>
+ <point x="1425" y="1122" type="curve"/>
+ <point x="1534" y="1298" type="line"/>
+ <point x="1409" y="1405"/>
+ <point x="1235" y="1455"/>
+ <point x="1063" y="1455" type="curve" smooth="yes"/>
+ <point x="680" y="1455"/>
+ <point x="334" y="1195"/>
+ <point x="217" y="726" type="curve" smooth="yes"/>
+ <point x="195" y="639"/>
+ <point x="185" y="559"/>
+ <point x="185" y="486" type="curve" smooth="yes"/>
+ <point x="185" y="162"/>
+ <point x="406" y="-25"/>
+ <point x="714" y="-25" type="curve" smooth="yes"/>
+ <point x="907" y="-25"/>
+ <point x="1149" y="50"/>
+ <point x="1258" y="132" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfcopyglyphs.ufo/glyphs/L_tnC_apH_.glif b/tests/reference/ufo/psfcopyglyphs.ufo/glyphs/L_tnC_apH_.glif
new file mode 100644
index 0000000..f454288
--- /dev/null
+++ b/tests/reference/ufo/psfcopyglyphs.ufo/glyphs/L_tnC_apH_.glif
@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnCapH" format="2">
+ <advance width="1455"/>
+ <unicode hex="0048"/>
+ <anchor x="225" y="0" name="H"/>
+ <anchor x="640" y="-100" name="L"/>
+ <anchor x="1047" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="1230" y="0" type="line"/>
+ <point x="1234" y="78"/>
+ <point x="1273" y="233"/>
+ <point x="1321" y="426" type="curve" smooth="yes"/>
+ <point x="1465" y="1005" type="line" smooth="yes"/>
+ <point x="1513" y="1198"/>
+ <point x="1552" y="1352"/>
+ <point x="1586" y="1431" type="curve"/>
+ <point x="1381" y="1431" type="line"/>
+ <point x="1228" y="818" type="line"/>
+ <point x="508" y="818" type="line"/>
+ <point x="661" y="1431" type="line"/>
+ <point x="456" y="1431" type="line"/>
+ <point x="452" y="1352"/>
+ <point x="413" y="1197"/>
+ <point x="365" y="1005" type="curve" smooth="yes"/>
+ <point x="221" y="426" type="line" smooth="yes"/>
+ <point x="173" y="233"/>
+ <point x="134" y="78"/>
+ <point x="100" y="0" type="curve"/>
+ <point x="305" y="0" type="line"/>
+ <point x="470" y="662" type="line"/>
+ <point x="1190" y="662" type="line"/>
+ <point x="1025" y="0" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfcopyglyphs.ufo/glyphs/L_tnC_apI_.glif b/tests/reference/ufo/psfcopyglyphs.ufo/glyphs/L_tnC_apI_.glif
new file mode 100644
index 0000000..78b151c
--- /dev/null
+++ b/tests/reference/ufo/psfcopyglyphs.ufo/glyphs/L_tnC_apI_.glif
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnCapI" format="2">
+ <advance width="955"/>
+ <unicode hex="0049"/>
+ <anchor x="417" y="0" name="H"/>
+ <anchor x="392" y="-100" name="L"/>
+ <anchor x="613" y="0" name="O"/>
+ <anchor x="1215" y="1200" name="R"/>
+ <anchor x="799" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="436" y="1431" type="line"/>
+ <point x="401" y="1289" type="line"/>
+ <point x="641" y="1289" type="line"/>
+ <point x="355" y="142" type="line"/>
+ <point x="115" y="142" type="line"/>
+ <point x="80" y="0" type="line"/>
+ <point x="755" y="0" type="line"/>
+ <point x="790" y="142" type="line"/>
+ <point x="545" y="142" type="line"/>
+ <point x="831" y="1289" type="line"/>
+ <point x="1076" y="1289" type="line"/>
+ <point x="1111" y="1431" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfcopyglyphs.ufo/glyphs/L_tnC_apJ_.glif b/tests/reference/ufo/psfcopyglyphs.ufo/glyphs/L_tnC_apJ_.glif
new file mode 100644
index 0000000..417d1f8
--- /dev/null
+++ b/tests/reference/ufo/psfcopyglyphs.ufo/glyphs/L_tnC_apJ_.glif
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnCapJ" format="2">
+ <advance width="996"/>
+ <unicode hex="004A"/>
+ <anchor x="325" y="-100" name="L"/>
+ <anchor x="997" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="871" y="1431" type="line"/>
+ <point x="858" y="1327"/>
+ <point x="817" y="1151"/>
+ <point x="769" y="960" type="curve" smooth="yes"/>
+ <point x="648" y="475" type="line" smooth="yes"/>
+ <point x="592" y="251"/>
+ <point x="484" y="152"/>
+ <point x="337" y="152" type="curve" smooth="yes"/>
+ <point x="245" y="152"/>
+ <point x="145" y="224"/>
+ <point x="97" y="299" type="curve"/>
+ <point x="6" y="118" type="line"/>
+ <point x="58" y="39"/>
+ <point x="193" y="-25"/>
+ <point x="298" y="-25" type="curve" smooth="yes"/>
+ <point x="555" y="-25"/>
+ <point x="749" y="117"/>
+ <point x="850" y="524" type="curve" smooth="yes"/>
+ <point x="1076" y="1431" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfcopyglyphs.ufo/glyphs/L_tnC_apK_.glif b/tests/reference/ufo/psfcopyglyphs.ufo/glyphs/L_tnC_apK_.glif
new file mode 100644
index 0000000..8e54a6d
--- /dev/null
+++ b/tests/reference/ufo/psfcopyglyphs.ufo/glyphs/L_tnC_apK_.glif
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnCapK" format="2">
+ <advance width="1261"/>
+ <unicode hex="004B"/>
+ <anchor x="210" y="0" name="H"/>
+ <anchor x="610" y="-100" name="L"/>
+ <anchor x="972" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="1221" y="1431" type="line"/>
+ <point x="406" y="689" type="line"/>
+ <point x="547" y="730" type="line"/>
+ <point x="660" y="725" type="line"/>
+ <point x="1461" y="1431" type="line"/>
+ </contour>
+ <contour>
+ <point x="1170" y="0" type="line"/>
+ <point x="615" y="823" type="line"/>
+ <point x="469" y="720" type="line"/>
+ <point x="925" y="0" type="line"/>
+ </contour>
+ <contour>
+ <point x="661" y="1431" type="line"/>
+ <point x="456" y="1431" type="line"/>
+ <point x="452" y="1352"/>
+ <point x="413" y="1197"/>
+ <point x="365" y="1005" type="curve" smooth="yes"/>
+ <point x="221" y="426" type="line" smooth="yes"/>
+ <point x="173" y="233"/>
+ <point x="134" y="78"/>
+ <point x="100" y="0" type="curve"/>
+ <point x="305" y="0" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfcopyglyphs.ufo/glyphs/L_tnC_apL_.glif b/tests/reference/ufo/psfcopyglyphs.ufo/glyphs/L_tnC_apL_.glif
new file mode 100644
index 0000000..d2eb932
--- /dev/null
+++ b/tests/reference/ufo/psfcopyglyphs.ufo/glyphs/L_tnC_apL_.glif
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnCapL" format="2">
+ <advance width="1060"/>
+ <unicode hex="004C"/>
+ <anchor x="532" y="0" name="H"/>
+ <anchor x="507" y="-100" name="L"/>
+ <anchor x="780" y="1200" name="R"/>
+ <anchor x="914" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="345" y="162" type="line"/>
+ <point x="661" y="1431" type="line"/>
+ <point x="456" y="1431" type="line"/>
+ <point x="452" y="1352"/>
+ <point x="413" y="1197"/>
+ <point x="365" y="1005" type="curve" smooth="yes"/>
+ <point x="221" y="426" type="line" smooth="yes"/>
+ <point x="173" y="233"/>
+ <point x="134" y="78"/>
+ <point x="100" y="0" type="curve"/>
+ <point x="965" y="0" type="line"/>
+ <point x="1008" y="176" type="line"/>
+ <point x="925" y="163"/>
+ <point x="766" y="162"/>
+ <point x="569" y="162" type="curve" smooth="yes"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfcopyglyphs.ufo/glyphs/L_tnC_apM_.glif b/tests/reference/ufo/psfcopyglyphs.ufo/glyphs/L_tnC_apM_.glif
new file mode 100644
index 0000000..7c3c824
--- /dev/null
+++ b/tests/reference/ufo/psfcopyglyphs.ufo/glyphs/L_tnC_apM_.glif
@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnCapM" format="2">
+ <advance width="1785"/>
+ <unicode hex="004D"/>
+ <anchor x="800" y="-100" name="L"/>
+ <anchor x="1207" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="880" y="201" type="line"/>
+ <point x="751" y="1431" type="line"/>
+ <point x="591" y="1431" type="line"/>
+ <point x="740" y="0" type="line"/>
+ <point x="935" y="0" type="line"/>
+ <point x="1793" y="1431" type="line"/>
+ <point x="1616" y="1431" type="line"/>
+ </contour>
+ <contour>
+ <point x="536" y="1431" type="line"/>
+ <point x="536" y="1431"/>
+ <point x="184" y="194"/>
+ <point x="110" y="0" type="curve"/>
+ <point x="295" y="0" type="line"/>
+ <point x="621" y="1181" type="line"/>
+ <point x="711" y="1431" type="line"/>
+ </contour>
+ <contour>
+ <point x="1560" y="0" type="line"/>
+ <point x="1579" y="194"/>
+ <point x="1846" y="1431"/>
+ <point x="1846" y="1431" type="curve"/>
+ <point x="1671" y="1431" type="line"/>
+ <point x="1641" y="1181" type="line"/>
+ <point x="1375" y="0" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfcopyglyphs.ufo/glyphs/L_tnC_apN_.glif b/tests/reference/ufo/psfcopyglyphs.ufo/glyphs/L_tnC_apN_.glif
new file mode 100644
index 0000000..7306669
--- /dev/null
+++ b/tests/reference/ufo/psfcopyglyphs.ufo/glyphs/L_tnC_apN_.glif
@@ -0,0 +1,37 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnCapN" format="2">
+ <advance width="1480"/>
+ <unicode hex="004E"/>
+ <anchor x="1170" y="0" name="H"/>
+ <anchor x="652" y="-100" name="L"/>
+ <anchor x="1059" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="491" y="1328" type="line"/>
+ <point x="1075" y="0" type="line"/>
+ <point x="1219" y="98" type="line"/>
+ <point x="636" y="1431" type="line"/>
+ </contour>
+ <contour>
+ <point x="1075" y="0" type="line"/>
+ <point x="1250" y="0" type="line"/>
+ <point x="1500" y="1005" type="line" smooth="yes"/>
+ <point x="1548" y="1198"/>
+ <point x="1588" y="1352"/>
+ <point x="1621" y="1431" type="curve"/>
+ <point x="1431" y="1431" type="line"/>
+ </contour>
+ <contour>
+ <point x="636" y="1431" type="line"/>
+ <point x="446" y="1431" type="line"/>
+ <point x="442" y="1352"/>
+ <point x="403" y="1197"/>
+ <point x="355" y="1005" type="curve" smooth="yes"/>
+ <point x="211" y="426" type="line" smooth="yes"/>
+ <point x="163" y="233"/>
+ <point x="124" y="78"/>
+ <point x="90" y="0" type="curve"/>
+ <point x="280" y="0" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfcopyglyphs.ufo/glyphs/L_tnC_apO_.glif b/tests/reference/ufo/psfcopyglyphs.ufo/glyphs/L_tnC_apO_.glif
new file mode 100644
index 0000000..19c4886
--- /dev/null
+++ b/tests/reference/ufo/psfcopyglyphs.ufo/glyphs/L_tnC_apO_.glif
@@ -0,0 +1,40 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnCapO" format="2">
+ <advance width="1447"/>
+ <unicode hex="004F"/>
+ <anchor x="657" y="0" name="H"/>
+ <anchor x="632" y="-100" name="L"/>
+ <anchor x="896" y="0" name="O"/>
+ <anchor x="1700" y="1200" name="R"/>
+ <anchor x="1039" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="719" y="147" type="curve" smooth="yes"/>
+ <point x="514" y="147"/>
+ <point x="386" y="300"/>
+ <point x="386" y="541" type="curve" smooth="yes"/>
+ <point x="386" y="871"/>
+ <point x="606" y="1284"/>
+ <point x="963" y="1284" type="curve" smooth="yes"/>
+ <point x="1164" y="1284"/>
+ <point x="1291" y="1133"/>
+ <point x="1291" y="892" type="curve" smooth="yes"/>
+ <point x="1291" y="563"/>
+ <point x="1077" y="147"/>
+ </contour>
+ <contour>
+ <point x="1492" y="931" type="curve" smooth="yes"/>
+ <point x="1492" y="1263"/>
+ <point x="1278" y="1455"/>
+ <point x="1015" y="1455" type="curve" smooth="yes"/>
+ <point x="599" y="1455"/>
+ <point x="185" y="1036"/>
+ <point x="185" y="500" type="curve" smooth="yes"/>
+ <point x="185" y="167"/>
+ <point x="400" y="-25"/>
+ <point x="666" y="-25" type="curve" smooth="yes"/>
+ <point x="1078" y="-25"/>
+ <point x="1492" y="395"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfcopyglyphs.ufo/glyphs/L_tnC_apP_.glif b/tests/reference/ufo/psfcopyglyphs.ufo/glyphs/L_tnC_apP_.glif
new file mode 100644
index 0000000..5b51a57
--- /dev/null
+++ b/tests/reference/ufo/psfcopyglyphs.ufo/glyphs/L_tnC_apP_.glif
@@ -0,0 +1,50 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnCapP" format="2">
+ <advance width="1190"/>
+ <unicode hex="0050"/>
+ <anchor x="552" y="-100" name="L"/>
+ <anchor x="959" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="443" y="554" type="line"/>
+ <point x="506" y="547"/>
+ <point x="597" y="544"/>
+ <point x="670" y="544" type="curve" smooth="yes"/>
+ <point x="1058" y="544"/>
+ <point x="1321" y="733"/>
+ <point x="1321" y="1084" type="curve" smooth="yes"/>
+ <point x="1321" y="1302"/>
+ <point x="1141" y="1441"/>
+ <point x="864" y="1441" type="curve" smooth="yes"/>
+ <point x="651" y="1441"/>
+ <point x="456" y="1431"/>
+ <point x="456" y="1431" type="curve"/>
+ <point x="452" y="1352"/>
+ <point x="407" y="1172"/>
+ <point x="359" y="980" type="curve"/>
+ <point x="221" y="426" type="line" smooth="yes"/>
+ <point x="173" y="233"/>
+ <point x="134" y="78"/>
+ <point x="100" y="0" type="curve"/>
+ <point x="320" y="0" type="line"/>
+ <point x="324" y="76"/>
+ <point x="362" y="232"/>
+ <point x="411" y="426" type="curve" smooth="yes"/>
+ </contour>
+ <contour>
+ <point x="623" y="1279" type="line"/>
+ <point x="692" y="1282"/>
+ <point x="721" y="1284"/>
+ <point x="815" y="1284" type="curve" smooth="yes"/>
+ <point x="1036" y="1284"/>
+ <point x="1121" y="1172"/>
+ <point x="1121" y="1048" type="curve" smooth="yes"/>
+ <point x="1121" y="845"/>
+ <point x="968" y="696"/>
+ <point x="693" y="696" type="curve" smooth="yes"/>
+ <point x="618" y="696"/>
+ <point x="542" y="698"/>
+ <point x="481" y="706" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfcopyglyphs.ufo/glyphs/L_tnC_apQ_.glif b/tests/reference/ufo/psfcopyglyphs.ufo/glyphs/L_tnC_apQ_.glif
new file mode 100644
index 0000000..3dcbc8d
--- /dev/null
+++ b/tests/reference/ufo/psfcopyglyphs.ufo/glyphs/L_tnC_apQ_.glif
@@ -0,0 +1,52 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnCapQ" format="2">
+ <advance width="1459"/>
+ <unicode hex="0051"/>
+ <anchor x="589" y="-270" name="L"/>
+ <anchor x="1039" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="1495" y="939" type="curve" smooth="yes"/>
+ <point x="1495" y="1266"/>
+ <point x="1306" y="1455"/>
+ <point x="1026" y="1455" type="curve" smooth="yes"/>
+ <point x="703" y="1455"/>
+ <point x="332" y="1195"/>
+ <point x="215" y="726" type="curve" smooth="yes"/>
+ <point x="194" y="642"/>
+ <point x="185" y="564"/>
+ <point x="185" y="492" type="curve" smooth="yes"/>
+ <point x="185" y="165"/>
+ <point x="388" y="-25"/>
+ <point x="652" y="-25" type="curve" smooth="yes"/>
+ <point x="714" y="-25"/>
+ <point x="781" y="-17"/>
+ <point x="829" y="0" type="curve"/>
+ <point x="898" y="0"/>
+ <point x="1133" y="-186"/>
+ <point x="1217" y="-186" type="curve" smooth="yes"/>
+ <point x="1271" y="-186"/>
+ <point x="1355" y="-79"/>
+ <point x="1388" y="-44" type="curve"/>
+ <point x="1258" y="-27"/>
+ <point x="1155" y="27"/>
+ <point x="1049" y="103" type="curve"/>
+ <point x="1253" y="217"/>
+ <point x="1495" y="528"/>
+ </contour>
+ <contour>
+ <point x="690" y="147" type="curve" smooth="yes"/>
+ <point x="492" y="147"/>
+ <point x="384" y="284"/>
+ <point x="384" y="508" type="curve" smooth="yes"/>
+ <point x="384" y="856"/>
+ <point x="609" y="1284"/>
+ <point x="994" y="1284" type="curve" smooth="yes"/>
+ <point x="1188" y="1284"/>
+ <point x="1295" y="1149"/>
+ <point x="1295" y="925" type="curve" smooth="yes"/>
+ <point x="1295" y="490"/>
+ <point x="985" y="147"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfcopyglyphs.ufo/glyphs/L_tnC_apR_.glif b/tests/reference/ufo/psfcopyglyphs.ufo/glyphs/L_tnC_apR_.glif
new file mode 100644
index 0000000..c8f8186
--- /dev/null
+++ b/tests/reference/ufo/psfcopyglyphs.ufo/glyphs/L_tnC_apR_.glif
@@ -0,0 +1,55 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnCapR" format="2">
+ <advance width="1295"/>
+ <unicode hex="0052"/>
+ <anchor x="590" y="0" name="H"/>
+ <anchor x="525" y="-100" name="L"/>
+ <anchor x="932" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="457" y="613" type="line"/>
+ <point x="712" y="613" type="line" smooth="yes"/>
+ <point x="1010" y="613"/>
+ <point x="1303" y="784"/>
+ <point x="1303" y="1114" type="curve" smooth="yes"/>
+ <point x="1303" y="1326"/>
+ <point x="1114" y="1441"/>
+ <point x="844" y="1441" type="curve" smooth="yes"/>
+ <point x="610" y="1441"/>
+ <point x="456" y="1431"/>
+ <point x="456" y="1431" type="curve"/>
+ <point x="452" y="1352"/>
+ <point x="407" y="1172"/>
+ <point x="359" y="980" type="curve" smooth="yes"/>
+ <point x="221" y="426" type="line"/>
+ <point x="173" y="233"/>
+ <point x="134" y="78"/>
+ <point x="100" y="0" type="curve"/>
+ <point x="320" y="0" type="line"/>
+ <point x="324" y="76"/>
+ <point x="363" y="233"/>
+ <point x="411" y="426" type="curve"/>
+ </contour>
+ <contour>
+ <point x="623" y="1279" type="line"/>
+ <point x="677" y="1281"/>
+ <point x="725" y="1284"/>
+ <point x="795" y="1284" type="curve" smooth="yes"/>
+ <point x="1003" y="1284"/>
+ <point x="1104" y="1203"/>
+ <point x="1104" y="1076" type="curve" smooth="yes"/>
+ <point x="1104" y="856"/>
+ <point x="921" y="764"/>
+ <point x="685" y="764" type="curve" smooth="yes"/>
+ <point x="495" y="764" type="line"/>
+ </contour>
+ <contour>
+ <point x="656" y="622" type="line"/>
+ <point x="930" y="0" type="line"/>
+ <point x="1185" y="0" type="line"/>
+ <point x="1122" y="89"/>
+ <point x="864" y="602"/>
+ <point x="828" y="676" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfcopyglyphs.ufo/glyphs/L_tnC_apS_.glif b/tests/reference/ufo/psfcopyglyphs.ufo/glyphs/L_tnC_apS_.glif
new file mode 100644
index 0000000..01e9f47
--- /dev/null
+++ b/tests/reference/ufo/psfcopyglyphs.ufo/glyphs/L_tnC_apS_.glif
@@ -0,0 +1,50 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnCapS" format="2">
+ <advance width="1155"/>
+ <unicode hex="0053"/>
+ <anchor x="520" y="0" name="H"/>
+ <anchor x="495" y="-100" name="L"/>
+ <anchor x="902" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="1260" y="1347" type="line"/>
+ <point x="1146" y="1419"/>
+ <point x="1021" y="1455"/>
+ <point x="867" y="1455" type="curve" smooth="yes"/>
+ <point x="549" y="1455"/>
+ <point x="320" y="1303"/>
+ <point x="320" y="1040" type="curve" smooth="yes"/>
+ <point x="320" y="901"/>
+ <point x="438" y="794"/>
+ <point x="622" y="691" type="curve" smooth="yes"/>
+ <point x="877" y="549"/>
+ <point x="914" y="461"/>
+ <point x="914" y="378" type="curve" smooth="yes"/>
+ <point x="914" y="256"/>
+ <point x="792" y="147"/>
+ <point x="621" y="147" type="curve" smooth="yes"/>
+ <point x="473" y="147"/>
+ <point x="278" y="235"/>
+ <point x="161" y="378" type="curve"/>
+ <point x="65" y="187" type="line"/>
+ <point x="178" y="73"/>
+ <point x="365" y="-25"/>
+ <point x="558" y="-25" type="curve" smooth="yes"/>
+ <point x="852" y="-25"/>
+ <point x="1114" y="115"/>
+ <point x="1114" y="414" type="curve" smooth="yes"/>
+ <point x="1114" y="526"/>
+ <point x="1057" y="679"/>
+ <point x="800" y="828" type="curve" smooth="yes"/>
+ <point x="597" y="946"/>
+ <point x="510" y="1005"/>
+ <point x="510" y="1079" type="curve" smooth="yes"/>
+ <point x="510" y="1210"/>
+ <point x="659" y="1284"/>
+ <point x="845" y="1284" type="curve" smooth="yes"/>
+ <point x="959" y="1284"/>
+ <point x="1075" y="1240"/>
+ <point x="1173" y="1156" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfcopyglyphs.ufo/glyphs/L_tnC_apT_.glif b/tests/reference/ufo/psfcopyglyphs.ufo/glyphs/L_tnC_apT_.glif
new file mode 100644
index 0000000..0eeece4
--- /dev/null
+++ b/tests/reference/ufo/psfcopyglyphs.ufo/glyphs/L_tnC_apT_.glif
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnCapT" format="2">
+ <advance width="1245"/>
+ <unicode hex="0054"/>
+ <anchor x="562" y="0" name="H"/>
+ <anchor x="562" y="-100" name="L"/>
+ <anchor x="944" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="341" y="1431" type="line"/>
+ <point x="296" y="1250" type="line"/>
+ <point x="380" y="1266"/>
+ <point x="457" y="1269"/>
+ <point x="546" y="1269" type="curve" smooth="yes"/>
+ <point x="781" y="1269" type="line"/>
+ <point x="571" y="426" type="line" smooth="yes"/>
+ <point x="523" y="233"/>
+ <point x="481" y="78"/>
+ <point x="445" y="0" type="curve"/>
+ <point x="675" y="0" type="line"/>
+ <point x="677" y="78"/>
+ <point x="713" y="233"/>
+ <point x="761" y="426" type="curve" smooth="yes"/>
+ <point x="971" y="1269" type="line"/>
+ <point x="1211" y="1269" type="line" smooth="yes"/>
+ <point x="1301" y="1269"/>
+ <point x="1375" y="1266"/>
+ <point x="1451" y="1250" type="curve"/>
+ <point x="1496" y="1431" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfcopyglyphs.ufo/glyphs/L_tnC_apU_.glif b/tests/reference/ufo/psfcopyglyphs.ufo/glyphs/L_tnC_apU_.glif
new file mode 100644
index 0000000..9576e20
--- /dev/null
+++ b/tests/reference/ufo/psfcopyglyphs.ufo/glyphs/L_tnC_apU_.glif
@@ -0,0 +1,44 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnCapU" format="2">
+ <advance width="1420"/>
+ <unicode hex="0055"/>
+ <anchor x="647" y="0" name="H"/>
+ <anchor x="622" y="-100" name="L"/>
+ <anchor x="865" y="0" name="O"/>
+ <anchor x="1640" y="1200" name="R"/>
+ <anchor x="1029" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="1346" y="1431" type="line"/>
+ <point x="1126" y="549" type="line" smooth="yes"/>
+ <point x="1055" y="264"/>
+ <point x="916" y="132"/>
+ <point x="682" y="132" type="curve" smooth="yes"/>
+ <point x="485" y="132"/>
+ <point x="421" y="244"/>
+ <point x="421" y="391" type="curve" smooth="yes"/>
+ <point x="421" y="451"/>
+ <point x="431" y="516"/>
+ <point x="448" y="582" type="curve" smooth="yes"/>
+ <point x="661" y="1431" type="line"/>
+ <point x="456" y="1431" type="line"/>
+ <point x="451" y="1352"/>
+ <point x="414" y="1198"/>
+ <point x="365" y="1005" type="curve" smooth="yes"/>
+ <point x="251" y="552" type="line" smooth="yes"/>
+ <point x="236" y="493"/>
+ <point x="228" y="435"/>
+ <point x="228" y="379" type="curve" smooth="yes"/>
+ <point x="228" y="157"/>
+ <point x="351" y="-25"/>
+ <point x="643" y="-25" type="curve" smooth="yes"/>
+ <point x="1020" y="-25"/>
+ <point x="1223" y="177"/>
+ <point x="1299" y="480" type="curve" smooth="yes"/>
+ <point x="1430" y="1005" type="line" smooth="yes"/>
+ <point x="1480" y="1207"/>
+ <point x="1519" y="1352"/>
+ <point x="1551" y="1431" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfcopyglyphs.ufo/glyphs/L_tnC_apV_.glif b/tests/reference/ufo/psfcopyglyphs.ufo/glyphs/L_tnC_apV_.glif
new file mode 100644
index 0000000..2bf8b96
--- /dev/null
+++ b/tests/reference/ufo/psfcopyglyphs.ufo/glyphs/L_tnC_apV_.glif
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnCapV" format="2">
+ <advance width="1345"/>
+ <unicode hex="0056"/>
+ <anchor x="620" y="0" name="H"/>
+ <anchor x="587" y="-100" name="L"/>
+ <anchor x="820" y="0" name="O"/>
+ <anchor x="994" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="1381" y="1431" type="line"/>
+ <point x="654" y="191" type="line"/>
+ <point x="536" y="1431" type="line"/>
+ <point x="331" y="1431" type="line"/>
+ <point x="344" y="1350"/>
+ <point x="355" y="1262"/>
+ <point x="377" y="1073" type="curve" smooth="yes"/>
+ <point x="500" y="0" type="line"/>
+ <point x="725" y="0" type="line"/>
+ <point x="1377" y="1073" type="line" smooth="yes"/>
+ <point x="1492" y="1263"/>
+ <point x="1550" y="1350"/>
+ <point x="1606" y="1431" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfcopyglyphs.ufo/glyphs/L_tnC_apW_.glif b/tests/reference/ufo/psfcopyglyphs.ufo/glyphs/L_tnC_apW_.glif
new file mode 100644
index 0000000..553ea17
--- /dev/null
+++ b/tests/reference/ufo/psfcopyglyphs.ufo/glyphs/L_tnC_apW_.glif
@@ -0,0 +1,44 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnCapW" format="2">
+ <advance width="2060"/>
+ <unicode hex="0057"/>
+ <anchor x="942" y="-100" name="L"/>
+ <anchor x="1349" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="1535" y="0" type="line"/>
+ <point x="2107" y="1073" type="line" smooth="yes"/>
+ <point x="2208" y="1263"/>
+ <point x="2259" y="1350"/>
+ <point x="2311" y="1431" type="curve"/>
+ <point x="2081" y="1431" type="line"/>
+ <point x="1431" y="127" type="line"/>
+ <point x="1420" y="0" type="line"/>
+ </contour>
+ <contour>
+ <point x="1310" y="0" type="line"/>
+ <point x="1420" y="0" type="line"/>
+ <point x="1461" y="127" type="line"/>
+ <point x="1406" y="1431" type="line"/>
+ <point x="1231" y="1431" type="line"/>
+ <point x="1248" y="1279" type="line"/>
+ </contour>
+ <contour>
+ <point x="625" y="0" type="line"/>
+ <point x="1406" y="1431" type="line"/>
+ <point x="1221" y="1431" type="line"/>
+ <point x="521" y="127" type="line"/>
+ <point x="521" y="0" type="line"/>
+ </contour>
+ <contour>
+ <point x="546" y="1431" type="line"/>
+ <point x="336" y="1431" type="line"/>
+ <point x="348" y="1353"/>
+ <point x="355" y="1260"/>
+ <point x="362" y="1073" type="curve" smooth="yes"/>
+ <point x="400" y="0" type="line"/>
+ <point x="521" y="0" type="line"/>
+ <point x="551" y="127" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfcopyglyphs.ufo/glyphs/L_tnC_apX_.glif b/tests/reference/ufo/psfcopyglyphs.ufo/glyphs/L_tnC_apX_.glif
new file mode 100644
index 0000000..2da5787
--- /dev/null
+++ b/tests/reference/ufo/psfcopyglyphs.ufo/glyphs/L_tnC_apX_.glif
@@ -0,0 +1,39 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnCapX" format="2">
+ <advance width="1305"/>
+ <unicode hex="0058"/>
+ <anchor x="565" y="-100" name="L"/>
+ <anchor x="972" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="970" y="0" type="line"/>
+ <point x="1190" y="0" type="line"/>
+ <point x="1148" y="80"/>
+ <point x="1125" y="124"/>
+ <point x="1045" y="329" type="curve" smooth="yes"/>
+ <point x="611" y="1431" type="line"/>
+ <point x="386" y="1431" type="line"/>
+ <point x="430" y="1348"/>
+ <point x="462" y="1289"/>
+ <point x="541" y="1088" type="curve" smooth="yes"/>
+ </contour>
+ <contour>
+ <point x="752" y="872" type="line"/>
+ <point x="278" y="333" type="line" smooth="yes"/>
+ <point x="98" y="129"/>
+ <point x="53" y="84"/>
+ <point x="-30" y="0" type="curve"/>
+ <point x="210" y="0" type="line"/>
+ <point x="750" y="622" type="line"/>
+ </contour>
+ <contour>
+ <point x="765" y="622" type="line"/>
+ <point x="1183" y="1088" type="line" smooth="yes"/>
+ <point x="1360" y="1285"/>
+ <point x="1425" y="1355"/>
+ <point x="1506" y="1431" type="curve"/>
+ <point x="1261" y="1431" type="line"/>
+ <point x="767" y="872" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfcopyglyphs.ufo/glyphs/L_tnC_apY_.glif b/tests/reference/ufo/psfcopyglyphs.ufo/glyphs/L_tnC_apY_.glif
new file mode 100644
index 0000000..9ec65ef
--- /dev/null
+++ b/tests/reference/ufo/psfcopyglyphs.ufo/glyphs/L_tnC_apY_.glif
@@ -0,0 +1,39 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnCapY" format="2">
+ <advance width="1300"/>
+ <unicode hex="0059"/>
+ <anchor x="565" y="-100" name="L"/>
+ <anchor x="972" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="331" y="1431" type="line"/>
+ <point x="407" y="1285"/>
+ <point x="446" y="1173"/>
+ <point x="490" y="1044" type="curve"/>
+ <point x="661" y="549" type="line"/>
+ <point x="829" y="661" type="line"/>
+ <point x="551" y="1431" type="line"/>
+ </contour>
+ <contour>
+ <point x="1321" y="1431" type="line"/>
+ <point x="684" y="661" type="line"/>
+ <point x="796" y="549" type="line"/>
+ <point x="1215" y="1044" type="line" smooth="yes"/>
+ <point x="1322" y="1171"/>
+ <point x="1402" y="1265"/>
+ <point x="1561" y="1431" type="curve"/>
+ </contour>
+ <contour>
+ <point x="700" y="0" type="line"/>
+ <point x="704" y="78"/>
+ <point x="743" y="233"/>
+ <point x="791" y="426" type="curve" smooth="yes"/>
+ <point x="854" y="681" type="line"/>
+ <point x="664" y="681" type="line"/>
+ <point x="601" y="426" type="line" smooth="yes"/>
+ <point x="553" y="233"/>
+ <point x="514" y="78"/>
+ <point x="480" y="0" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfcopyglyphs.ufo/glyphs/L_tnS_mA_.glif b/tests/reference/ufo/psfcopyglyphs.ufo/glyphs/L_tnS_mA_.glif
new file mode 100644
index 0000000..586e494
--- /dev/null
+++ b/tests/reference/ufo/psfcopyglyphs.ufo/glyphs/L_tnS_mA_.glif
@@ -0,0 +1,77 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmA" format="2">
+ <advance width="1107"/>
+ <unicode hex="0061"/>
+ <anchor x="860" y="0" name="H"/>
+ <anchor x="455" y="-100" name="L"/>
+ <anchor x="1065" y="0" name="O"/>
+ <anchor x="1310" y="1000" name="R"/>
+ <anchor x="755" y="1100" name="U"/>
+ <outline>
+ <contour>
+ <point x="972" y="0" type="line"/>
+ <point x="965" y="48"/>
+ <point x="960" y="98"/>
+ <point x="960" y="149" type="curve" smooth="yes"/>
+ <point x="960" y="214"/>
+ <point x="967" y="284"/>
+ <point x="987" y="363" type="curve"/>
+ <point x="1077" y="726" type="line"/>
+ <point x="1081" y="744"/>
+ <point x="1084" y="762"/>
+ <point x="1084" y="779" type="curve" smooth="yes"/>
+ <point x="1084" y="912"/>
+ <point x="955" y="1019"/>
+ <point x="751" y="1019" type="curve" smooth="yes"/>
+ <point x="599" y="1019"/>
+ <point x="502" y="974"/>
+ <point x="389" y="931" type="curve"/>
+ <point x="373" y="889"/>
+ <point x="343" y="783"/>
+ <point x="331" y="740" type="curve"/>
+ <point x="468" y="820"/>
+ <point x="560" y="862"/>
+ <point x="666" y="862" type="curve" smooth="yes"/>
+ <point x="798" y="862"/>
+ <point x="885" y="810"/>
+ <point x="885" y="718" type="curve" smooth="yes"/>
+ <point x="885" y="705"/>
+ <point x="884" y="691"/>
+ <point x="880" y="677" type="curve" smooth="yes"/>
+ <point x="867" y="622" type="line"/>
+ <point x="825" y="619"/>
+ <point x="661" y="605"/>
+ <point x="591" y="598" type="curve" smooth="yes"/>
+ <point x="282" y="568"/>
+ <point x="102" y="415"/>
+ <point x="102" y="233" type="curve" smooth="yes"/>
+ <point x="102" y="103"/>
+ <point x="223" y="-25"/>
+ <point x="390" y="-25" type="curve" smooth="yes"/>
+ <point x="514" y="-25"/>
+ <point x="674" y="47"/>
+ <point x="779" y="152" type="curve"/>
+ <point x="779" y="89"/>
+ <point x="787" y="31"/>
+ <point x="792" y="0" type="curve"/>
+ </contour>
+ <contour>
+ <point x="791" y="319" type="line"/>
+ <point x="674" y="191"/>
+ <point x="553" y="137"/>
+ <point x="451" y="137" type="curve" smooth="yes"/>
+ <point x="355" y="137"/>
+ <point x="290" y="192"/>
+ <point x="290" y="264" type="curve" smooth="yes"/>
+ <point x="290" y="274"/>
+ <point x="291" y="285"/>
+ <point x="294" y="296" type="curve" smooth="yes"/>
+ <point x="315" y="380"/>
+ <point x="432" y="450"/>
+ <point x="566" y="461" type="curve" smooth="yes"/>
+ <point x="631" y="466"/>
+ <point x="782" y="483"/>
+ <point x="832" y="485" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfcopyglyphs.ufo/glyphs/L_tnS_mA_A_cute.glif b/tests/reference/ufo/psfcopyglyphs.ufo/glyphs/L_tnS_mA_A_cute.glif
new file mode 100644
index 0000000..198d6db
--- /dev/null
+++ b/tests/reference/ufo/psfcopyglyphs.ufo/glyphs/L_tnS_mA_A_cute.glif
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmAAcute" format="2">
+ <advance width="1107"/>
+ <unicode hex="00E1"/>
+ <anchor x="860" y="0" name="H"/>
+ <anchor x="455" y="-100" name="L"/>
+ <anchor x="1065" y="0" name="O"/>
+ <anchor x="1310" y="1000" name="R"/>
+ <anchor x="889" y="1635" name="U"/>
+ <outline>
+ <component base="LtnSmA"/>
+ <component base="CombAcute" xOffset="1110"/>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfcopyglyphs.ufo/glyphs/L_tnS_mA_C_ircum.glif b/tests/reference/ufo/psfcopyglyphs.ufo/glyphs/L_tnS_mA_C_ircum.glif
new file mode 100644
index 0000000..f5cfb16
--- /dev/null
+++ b/tests/reference/ufo/psfcopyglyphs.ufo/glyphs/L_tnS_mA_C_ircum.glif
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmACircum" format="2">
+ <advance width="1107"/>
+ <unicode hex="00E2"/>
+ <anchor x="860" y="0" name="H"/>
+ <anchor x="455" y="-100" name="L"/>
+ <anchor x="1065" y="0" name="O"/>
+ <anchor x="1310" y="1000" name="R"/>
+ <anchor x="854" y="1635" name="U"/>
+ <outline>
+ <component base="LtnSmA"/>
+ <component base="CombCircum" xOffset="1075"/>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfcopyglyphs.ufo/glyphs/L_tnS_mA_D_iaer.glif b/tests/reference/ufo/psfcopyglyphs.ufo/glyphs/L_tnS_mA_D_iaer.glif
new file mode 100644
index 0000000..6f05301
--- /dev/null
+++ b/tests/reference/ufo/psfcopyglyphs.ufo/glyphs/L_tnS_mA_D_iaer.glif
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmADiaer" format="2">
+ <advance width="1107"/>
+ <unicode hex="00E4"/>
+ <anchor x="860" y="0" name="H"/>
+ <anchor x="455" y="-100" name="L"/>
+ <anchor x="1065" y="0" name="O"/>
+ <anchor x="1310" y="1000" name="R"/>
+ <anchor x="852" y="1505" name="U"/>
+ <outline>
+ <component base="LtnSmA"/>
+ <component base="CombDiaer" xOffset="1105"/>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfcopyglyphs.ufo/glyphs/L_tnS_mA_G_rave.glif b/tests/reference/ufo/psfcopyglyphs.ufo/glyphs/L_tnS_mA_G_rave.glif
new file mode 100644
index 0000000..9048920
--- /dev/null
+++ b/tests/reference/ufo/psfcopyglyphs.ufo/glyphs/L_tnS_mA_G_rave.glif
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmAGrave" format="2">
+ <advance width="1107"/>
+ <unicode hex="00E0"/>
+ <anchor x="860" y="0" name="H"/>
+ <anchor x="455" y="-100" name="L"/>
+ <anchor x="1065" y="0" name="O"/>
+ <anchor x="1310" y="1000" name="R"/>
+ <anchor x="889" y="1635" name="U"/>
+ <outline>
+ <component base="LtnSmA"/>
+ <component base="CombGrave" xOffset="1090"/>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfcopyglyphs.ufo/glyphs/L_tnS_mA_R_ingA_bv.glif b/tests/reference/ufo/psfcopyglyphs.ufo/glyphs/L_tnS_mA_R_ingA_bv.glif
new file mode 100644
index 0000000..8ada58f
--- /dev/null
+++ b/tests/reference/ufo/psfcopyglyphs.ufo/glyphs/L_tnS_mA_R_ingA_bv.glif
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmARingAbv" format="2">
+ <advance width="1107"/>
+ <unicode hex="00E5"/>
+ <anchor x="860" y="0" name="H"/>
+ <anchor x="455" y="-100" name="L"/>
+ <anchor x="1065" y="0" name="O"/>
+ <anchor x="1310" y="1000" name="R"/>
+ <anchor x="919" y="1635" name="U"/>
+ <outline>
+ <component base="LtnSmA"/>
+ <component base="CombRingAbv" xOffset="1140"/>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfcopyglyphs.ufo/glyphs/L_tnS_mA_T_ilde.glif b/tests/reference/ufo/psfcopyglyphs.ufo/glyphs/L_tnS_mA_T_ilde.glif
new file mode 100644
index 0000000..c29348b
--- /dev/null
+++ b/tests/reference/ufo/psfcopyglyphs.ufo/glyphs/L_tnS_mA_T_ilde.glif
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmATilde" format="2">
+ <advance width="1107"/>
+ <unicode hex="00E3"/>
+ <anchor x="860" y="0" name="H"/>
+ <anchor x="455" y="-100" name="L"/>
+ <anchor x="1065" y="0" name="O"/>
+ <anchor x="1310" y="1000" name="R"/>
+ <anchor x="850" y="1475" name="U"/>
+ <outline>
+ <component base="LtnSmA"/>
+ <component base="CombTilde" xOffset="1140"/>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfcopyglyphs.ufo/glyphs/L_tnS_mB_.glif b/tests/reference/ufo/psfcopyglyphs.ufo/glyphs/L_tnS_mB_.glif
new file mode 100644
index 0000000..b3a3696
--- /dev/null
+++ b/tests/reference/ufo/psfcopyglyphs.ufo/glyphs/L_tnS_mB_.glif
@@ -0,0 +1,55 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmB" format="2">
+ <advance width="1144"/>
+ <unicode hex="0062"/>
+ <anchor x="530" y="0" name="H"/>
+ <anchor x="505" y="-100" name="L"/>
+ <anchor x="1345" y="1000" name="R"/>
+ <anchor x="938" y="1635" name="U"/>
+ <outline>
+ <contour>
+ <point x="437" y="1570" type="line"/>
+ <point x="437" y="1456"/>
+ <point x="402" y="1246"/>
+ <point x="367" y="1105" type="curve" smooth="yes"/>
+ <point x="110" y="85" type="line"/>
+ <point x="198" y="44"/>
+ <point x="355" y="-25"/>
+ <point x="517" y="-25" type="curve" smooth="yes"/>
+ <point x="675" y="-25"/>
+ <point x="795" y="24"/>
+ <point x="907" y="125" type="curve" smooth="yes"/>
+ <point x="1050" y="255"/>
+ <point x="1162" y="466"/>
+ <point x="1162" y="695" type="curve" smooth="yes"/>
+ <point x="1162" y="930"/>
+ <point x="1046" y="1020"/>
+ <point x="907" y="1020" type="curve" smooth="yes"/>
+ <point x="754" y="1020"/>
+ <point x="584" y="878"/>
+ <point x="456" y="719" type="curve"/>
+ <point x="552" y="1105" type="line" smooth="yes"/>
+ <point x="600" y="1296"/>
+ <point x="627" y="1508"/>
+ <point x="627" y="1570" type="curve"/>
+ </contour>
+ <contour>
+ <point x="382" y="429" type="line"/>
+ <point x="485" y="617"/>
+ <point x="708" y="850"/>
+ <point x="822" y="850" type="curve" smooth="yes"/>
+ <point x="913" y="850"/>
+ <point x="972" y="784"/>
+ <point x="972" y="635" type="curve" smooth="yes"/>
+ <point x="972" y="469"/>
+ <point x="909" y="336"/>
+ <point x="822" y="250" type="curve" smooth="yes"/>
+ <point x="741" y="169"/>
+ <point x="638" y="125"/>
+ <point x="552" y="125" type="curve" smooth="yes"/>
+ <point x="466" y="125"/>
+ <point x="376" y="167"/>
+ <point x="325" y="200" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfcopyglyphs.ufo/glyphs/L_tnS_mC_.glif b/tests/reference/ufo/psfcopyglyphs.ufo/glyphs/L_tnS_mC_.glif
new file mode 100644
index 0000000..f54fbe9
--- /dev/null
+++ b/tests/reference/ufo/psfcopyglyphs.ufo/glyphs/L_tnS_mC_.glif
@@ -0,0 +1,39 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmC" format="2">
+ <advance width="989"/>
+ <unicode hex="0063"/>
+ <anchor x="520" y="0" name="H"/>
+ <anchor x="495" y="-100" name="L"/>
+ <anchor x="1210" y="1000" name="R"/>
+ <anchor x="785" y="1100" name="U"/>
+ <outline>
+ <contour>
+ <point x="917" y="255" type="line"/>
+ <point x="811" y="179"/>
+ <point x="703" y="137"/>
+ <point x="583" y="137" type="curve" smooth="yes"/>
+ <point x="427" y="137"/>
+ <point x="331" y="239"/>
+ <point x="331" y="406" type="curve" smooth="yes"/>
+ <point x="331" y="619"/>
+ <point x="499" y="858"/>
+ <point x="742" y="858" type="curve" smooth="yes"/>
+ <point x="845" y="858"/>
+ <point x="924" y="824"/>
+ <point x="998" y="760" type="curve"/>
+ <point x="1077" y="936" type="line"/>
+ <point x="1016" y="985"/>
+ <point x="902" y="1020"/>
+ <point x="789" y="1020" type="curve" smooth="yes"/>
+ <point x="420" y="1020"/>
+ <point x="139" y="737"/>
+ <point x="139" y="381" type="curve" smooth="yes"/>
+ <point x="139" y="130"/>
+ <point x="309" y="-25"/>
+ <point x="532" y="-25" type="curve" smooth="yes"/>
+ <point x="682" y="-25"/>
+ <point x="785" y="9"/>
+ <point x="904" y="83" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfcopyglyphs.ufo/glyphs/L_tnS_mD_.glif b/tests/reference/ufo/psfcopyglyphs.ufo/glyphs/L_tnS_mD_.glif
new file mode 100644
index 0000000..4ea9ea1
--- /dev/null
+++ b/tests/reference/ufo/psfcopyglyphs.ufo/glyphs/L_tnS_mD_.glif
@@ -0,0 +1,65 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmD" format="2">
+ <advance width="1197"/>
+ <unicode hex="0064"/>
+ <anchor x="545" y="0" name="H"/>
+ <anchor x="520" y="-100" name="L"/>
+ <anchor x="1380" y="1000" name="R"/>
+ <anchor x="953" y="1635" name="U"/>
+ <outline>
+ <contour>
+ <point x="1144" y="1570" type="line"/>
+ <point x="1144" y="1456"/>
+ <point x="1114" y="1327"/>
+ <point x="1079" y="1175" type="curve" smooth="yes"/>
+ <point x="1024" y="935" type="line"/>
+ <point x="957" y="978"/>
+ <point x="854" y="1020"/>
+ <point x="759" y="1020" type="curve" smooth="yes"/>
+ <point x="650" y="1020"/>
+ <point x="534" y="979"/>
+ <point x="429" y="895" type="curve" smooth="yes"/>
+ <point x="262" y="761"/>
+ <point x="139" y="532"/>
+ <point x="139" y="288" type="curve" smooth="yes"/>
+ <point x="139" y="94"/>
+ <point x="250" y="-25"/>
+ <point x="424" y="-25" type="curve" smooth="yes"/>
+ <point x="563" y="-25"/>
+ <point x="791" y="141"/>
+ <point x="899" y="305" type="curve"/>
+ <point x="875" y="196"/>
+ <point x="869" y="93"/>
+ <point x="869" y="0" type="curve"/>
+ <point x="1052" y="0" type="line"/>
+ <point x="1048" y="23"/>
+ <point x="1047" y="53"/>
+ <point x="1047" y="90" type="curve" smooth="yes"/>
+ <point x="1047" y="190"/>
+ <point x="1063" y="340"/>
+ <point x="1107" y="520" type="curve" smooth="yes"/>
+ <point x="1267" y="1175" type="line" smooth="yes"/>
+ <point x="1310" y="1351"/>
+ <point x="1337" y="1475"/>
+ <point x="1337" y="1570" type="curve"/>
+ </contour>
+ <contour>
+ <point x="930" y="545" type="line"/>
+ <point x="846" y="370"/>
+ <point x="592" y="130"/>
+ <point x="479" y="130" type="curve" smooth="yes"/>
+ <point x="374" y="130"/>
+ <point x="330" y="195"/>
+ <point x="330" y="316" type="curve" smooth="yes"/>
+ <point x="330" y="460"/>
+ <point x="397" y="649"/>
+ <point x="509" y="760" type="curve" smooth="yes"/>
+ <point x="572" y="822"/>
+ <point x="643" y="855"/>
+ <point x="734" y="855" type="curve" smooth="yes"/>
+ <point x="835" y="855"/>
+ <point x="898" y="832"/>
+ <point x="984" y="780" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfcopyglyphs.ufo/glyphs/L_tnS_mE_.glif b/tests/reference/ufo/psfcopyglyphs.ufo/glyphs/L_tnS_mE_.glif
new file mode 100644
index 0000000..a3a6490
--- /dev/null
+++ b/tests/reference/ufo/psfcopyglyphs.ufo/glyphs/L_tnS_mE_.glif
@@ -0,0 +1,52 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmE" format="2">
+ <advance width="1042"/>
+ <unicode hex="0065"/>
+ <anchor x="485" y="0" name="H"/>
+ <anchor x="484" y="-100" name="L"/>
+ <anchor x="840" y="0" name="O"/>
+ <anchor x="1285" y="1000" name="R"/>
+ <anchor x="784" y="1100" name="U"/>
+ <outline>
+ <contour>
+ <point x="967" y="270" type="line"/>
+ <point x="854" y="189"/>
+ <point x="700" y="135"/>
+ <point x="567" y="135" type="curve" smooth="yes"/>
+ <point x="386" y="135"/>
+ <point x="317" y="263"/>
+ <point x="317" y="420" type="curve" smooth="yes"/>
+ <point x="317" y="686"/>
+ <point x="522" y="872"/>
+ <point x="720" y="872" type="curve" smooth="yes"/>
+ <point x="813" y="872"/>
+ <point x="883" y="823"/>
+ <point x="883" y="753" type="curve" smooth="yes"/>
+ <point x="883" y="660"/>
+ <point x="766" y="590"/>
+ <point x="539" y="590" type="curve" smooth="yes"/>
+ <point x="468" y="590"/>
+ <point x="382" y="596"/>
+ <point x="279" y="610" type="curve"/>
+ <point x="279" y="477" type="line"/>
+ <point x="391" y="461"/>
+ <point x="487" y="453"/>
+ <point x="569" y="453" type="curve" smooth="yes"/>
+ <point x="931" y="453"/>
+ <point x="1077" y="609"/>
+ <point x="1077" y="791" type="curve" smooth="yes"/>
+ <point x="1077" y="899"/>
+ <point x="986" y="1020"/>
+ <point x="772" y="1020" type="curve" smooth="yes"/>
+ <point x="399" y="1020"/>
+ <point x="137" y="710"/>
+ <point x="137" y="380" type="curve" smooth="yes"/>
+ <point x="137" y="147"/>
+ <point x="258" y="-25"/>
+ <point x="523" y="-25" type="curve" smooth="yes"/>
+ <point x="689" y="-25"/>
+ <point x="849" y="26"/>
+ <point x="955" y="83" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfcopyglyphs.ufo/glyphs/L_tnS_mF_.glif b/tests/reference/ufo/psfcopyglyphs.ufo/glyphs/L_tnS_mF_.glif
new file mode 100644
index 0000000..ede52a9
--- /dev/null
+++ b/tests/reference/ufo/psfcopyglyphs.ufo/glyphs/L_tnS_mF_.glif
@@ -0,0 +1,44 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmF" format="2">
+ <advance width="756"/>
+ <unicode hex="0066"/>
+ <anchor x="290" y="0" name="H"/>
+ <anchor x="315" y="-100" name="L"/>
+ <anchor x="908" y="1635" name="U"/>
+ <outline>
+ <contour>
+ <point x="180" y="833" type="line"/>
+ <point x="835" y="833" type="line"/>
+ <point x="871" y="975" type="line"/>
+ <point x="216" y="975" type="line"/>
+ </contour>
+ <contour>
+ <point x="1106" y="1519" type="line"/>
+ <point x="1062" y="1555"/>
+ <point x="981" y="1588"/>
+ <point x="903" y="1588" type="curve" smooth="yes"/>
+ <point x="687" y="1588"/>
+ <point x="533" y="1478"/>
+ <point x="448" y="1147" type="curve" smooth="yes"/>
+ <point x="403" y="972"/>
+ <point x="244" y="334"/>
+ <point x="223" y="0" type="curve"/>
+ <point x="436" y="0" type="line"/>
+ <point x="430" y="28"/>
+ <point x="427" y="66"/>
+ <point x="427" y="110" type="curve" smooth="yes"/>
+ <point x="427" y="213"/>
+ <point x="447" y="351"/>
+ <point x="476" y="484" type="curve" smooth="yes"/>
+ <point x="510" y="641"/>
+ <point x="558" y="846"/>
+ <point x="641" y="1186" type="curve" smooth="yes"/>
+ <point x="682" y="1353"/>
+ <point x="758" y="1421"/>
+ <point x="862" y="1421" type="curve" smooth="yes"/>
+ <point x="920" y="1421"/>
+ <point x="988" y="1392"/>
+ <point x="1022" y="1362" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfcopyglyphs.ufo/glyphs/L_tnS_mG_.glif b/tests/reference/ufo/psfcopyglyphs.ufo/glyphs/L_tnS_mG_.glif
new file mode 100644
index 0000000..8931f8d
--- /dev/null
+++ b/tests/reference/ufo/psfcopyglyphs.ufo/glyphs/L_tnS_mG_.glif
@@ -0,0 +1,100 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmG" format="2">
+ <advance width="1075"/>
+ <unicode hex="0067"/>
+ <anchor x="368" y="-465" name="H"/>
+ <anchor x="351" y="-535" name="L"/>
+ <anchor x="1285" y="1000" name="R"/>
+ <anchor x="730" y="1100" name="U"/>
+ <outline>
+ <contour>
+ <point x="360" y="389" type="line"/>
+ <point x="277" y="352"/>
+ <point x="168" y="266"/>
+ <point x="168" y="176" type="curve" smooth="yes"/>
+ <point x="168" y="96"/>
+ <point x="246" y="33"/>
+ <point x="483" y="-5" type="curve" smooth="yes"/>
+ <point x="707" y="-41"/>
+ <point x="781" y="-94"/>
+ <point x="781" y="-151" type="curve" smooth="yes"/>
+ <point x="781" y="-256"/>
+ <point x="580" y="-353"/>
+ <point x="411" y="-353" type="curve" smooth="yes"/>
+ <point x="202" y="-353"/>
+ <point x="104" y="-271"/>
+ <point x="104" y="-196" type="curve" smooth="yes"/>
+ <point x="104" y="-189"/>
+ <point x="104" y="-183"/>
+ <point x="106" y="-176" type="curve" smooth="yes"/>
+ <point x="120" y="-119"/>
+ <point x="170" y="-55"/>
+ <point x="409" y="20" type="curve"/>
+ <point x="410" y="48"/>
+ <point x="248" y="73"/>
+ <point x="248" y="73" type="curve"/>
+ <point x="53" y="12"/>
+ <point x="-51" y="-77"/>
+ <point x="-78" y="-186" type="curve" smooth="yes"/>
+ <point x="-82" y="-201"/>
+ <point x="-84" y="-217"/>
+ <point x="-84" y="-231" type="curve" smooth="yes"/>
+ <point x="-84" y="-396"/>
+ <point x="158" y="-495"/>
+ <point x="371" y="-495" type="curve" smooth="yes"/>
+ <point x="632" y="-495"/>
+ <point x="972" y="-360"/>
+ <point x="972" y="-125" type="curve" smooth="yes"/>
+ <point x="972" y="0"/>
+ <point x="849" y="90"/>
+ <point x="619" y="127" type="curve" smooth="yes"/>
+ <point x="403" y="162"/>
+ <point x="341" y="184"/>
+ <point x="341" y="218" type="curve" smooth="yes"/>
+ <point x="341" y="263"/>
+ <point x="447" y="325"/>
+ <point x="522" y="342" type="curve"/>
+ </contour>
+ <contour>
+ <point x="1244" y="1019" type="line"/>
+ <point x="1143" y="1012"/>
+ <point x="1002" y="977"/>
+ <point x="899" y="921" type="curve"/>
+ <point x="936" y="809" type="line"/>
+ <point x="1037" y="846"/>
+ <point x="1121" y="860"/>
+ <point x="1194" y="862" type="curve"/>
+ </contour>
+ <contour>
+ <point x="212" y="613" type="curve" smooth="yes"/>
+ <point x="212" y="449"/>
+ <point x="356" y="319"/>
+ <point x="554" y="319" type="curve" smooth="yes"/>
+ <point x="791" y="319"/>
+ <point x="1030" y="495"/>
+ <point x="1030" y="729" type="curve" smooth="yes"/>
+ <point x="1030" y="894"/>
+ <point x="887" y="1019"/>
+ <point x="689" y="1019" type="curve" smooth="yes"/>
+ <point x="441" y="1019"/>
+ <point x="212" y="847"/>
+ </contour>
+ <contour>
+ <point x="857" y="704" type="curve" smooth="yes"/>
+ <point x="857" y="555"/>
+ <point x="712" y="456"/>
+ <point x="578" y="456" type="curve" smooth="yes"/>
+ <point x="463" y="456"/>
+ <point x="385" y="530"/>
+ <point x="385" y="628" type="curve" smooth="yes"/>
+ <point x="385" y="643"/>
+ <point x="387" y="660"/>
+ <point x="391" y="676" type="curve" smooth="yes"/>
+ <point x="421" y="797"/>
+ <point x="530" y="877"/>
+ <point x="663" y="877" type="curve" smooth="yes"/>
+ <point x="779" y="877"/>
+ <point x="857" y="802"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfcopyglyphs.ufo/glyphs/L_tnS_mH_.glif b/tests/reference/ufo/psfcopyglyphs.ufo/glyphs/L_tnS_mH_.glif
new file mode 100644
index 0000000..08afbac
--- /dev/null
+++ b/tests/reference/ufo/psfcopyglyphs.ufo/glyphs/L_tnS_mH_.glif
@@ -0,0 +1,54 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmH" format="2">
+ <advance width="1185"/>
+ <unicode hex="0068"/>
+ <anchor x="190" y="0" name="H"/>
+ <anchor x="550" y="-100" name="L"/>
+ <anchor x="933" y="1635" name="U"/>
+ <outline>
+ <contour>
+ <point x="1055" y="0" type="line"/>
+ <point x="1047" y="30"/>
+ <point x="1043" y="65"/>
+ <point x="1043" y="102" type="curve" smooth="yes"/>
+ <point x="1043" y="143"/>
+ <point x="1048" y="188"/>
+ <point x="1055" y="238" type="curve" smooth="yes"/>
+ <point x="1069" y="327"/>
+ <point x="1170" y="636"/>
+ <point x="1170" y="745" type="curve" smooth="yes"/>
+ <point x="1170" y="917"/>
+ <point x="1095" y="1020"/>
+ <point x="930" y="1020" type="curve" smooth="yes"/>
+ <point x="760" y="1020"/>
+ <point x="591" y="877"/>
+ <point x="475" y="723" type="curve"/>
+ <point x="571" y="1105" type="line" smooth="yes"/>
+ <point x="609" y="1259"/>
+ <point x="645" y="1482"/>
+ <point x="645" y="1570" type="curve"/>
+ <point x="455" y="1570" type="line"/>
+ <point x="455" y="1456"/>
+ <point x="423" y="1257"/>
+ <point x="385" y="1105" type="curve" smooth="yes"/>
+ <point x="110" y="0" type="line"/>
+ <point x="295" y="0" type="line"/>
+ <point x="397" y="408" type="line"/>
+ <point x="492" y="612"/>
+ <point x="717" y="850"/>
+ <point x="840" y="850" type="curve" smooth="yes"/>
+ <point x="937" y="850"/>
+ <point x="970" y="798"/>
+ <point x="970" y="680" type="curve" smooth="yes"/>
+ <point x="970" y="592"/>
+ <point x="886" y="319"/>
+ <point x="872" y="203" type="curve" smooth="yes"/>
+ <point x="867" y="158"/>
+ <point x="864" y="115"/>
+ <point x="864" y="77" type="curve" smooth="yes"/>
+ <point x="864" y="48"/>
+ <point x="866" y="21"/>
+ <point x="870" y="0" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfcopyglyphs.ufo/glyphs/L_tnS_mI_.glif b/tests/reference/ufo/psfcopyglyphs.ufo/glyphs/L_tnS_mI_.glif
new file mode 100644
index 0000000..65ed550
--- /dev/null
+++ b/tests/reference/ufo/psfcopyglyphs.ufo/glyphs/L_tnS_mI_.glif
@@ -0,0 +1,50 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmI" format="2">
+ <advance width="554"/>
+ <unicode hex="0069"/>
+ <anchor x="235" y="0" name="H"/>
+ <anchor x="250" y="-100" name="L"/>
+ <anchor x="455" y="0" name="O"/>
+ <anchor x="745" y="1000" name="R"/>
+ <anchor x="472" y="1100" name="U"/>
+ <outline>
+ <contour>
+ <point x="361" y="1297" type="curve" smooth="yes"/>
+ <point x="361" y="1237"/>
+ <point x="404" y="1186"/>
+ <point x="467" y="1186" type="curve" smooth="yes"/>
+ <point x="552" y="1186"/>
+ <point x="624" y="1259"/>
+ <point x="624" y="1338" type="curve" smooth="yes"/>
+ <point x="624" y="1399"/>
+ <point x="578" y="1450"/>
+ <point x="513" y="1450" type="curve" smooth="yes"/>
+ <point x="428" y="1450"/>
+ <point x="361" y="1375"/>
+ </contour>
+ <contour>
+ <point x="335" y="1000" type="line"/>
+ <point x="335" y="886"/>
+ <point x="286" y="688"/>
+ <point x="246" y="537" type="curve" smooth="yes"/>
+ <point x="207" y="388" type="line" smooth="yes"/>
+ <point x="180" y="284"/>
+ <point x="165" y="172"/>
+ <point x="165" y="87" type="curve" smooth="yes"/>
+ <point x="165" y="53"/>
+ <point x="167" y="24"/>
+ <point x="172" y="0" type="curve"/>
+ <point x="372" y="0" type="line"/>
+ <point x="365" y="37"/>
+ <point x="360" y="85"/>
+ <point x="360" y="136" type="curve" smooth="yes"/>
+ <point x="360" y="208"/>
+ <point x="368" y="287"/>
+ <point x="386" y="357" type="curve" smooth="yes"/>
+ <point x="431" y="536" type="line" smooth="yes"/>
+ <point x="476" y="712"/>
+ <point x="525" y="912"/>
+ <point x="525" y="1000" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfcopyglyphs.ufo/glyphs/L_tnS_mJ_.glif b/tests/reference/ufo/psfcopyglyphs.ufo/glyphs/L_tnS_mJ_.glif
new file mode 100644
index 0000000..e9e18b8
--- /dev/null
+++ b/tests/reference/ufo/psfcopyglyphs.ufo/glyphs/L_tnS_mJ_.glif
@@ -0,0 +1,45 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmJ" format="2">
+ <advance width="602"/>
+ <unicode hex="006A"/>
+ <anchor x="-60" y="-500" name="L"/>
+ <anchor x="510" y="1100" name="U"/>
+ <outline>
+ <contour>
+ <point x="370" y="1000" type="line"/>
+ <point x="370" y="856"/>
+ <point x="288" y="374"/>
+ <point x="214" y="77" type="curve" smooth="yes"/>
+ <point x="152" y="-173"/>
+ <point x="29" y="-295"/>
+ <point x="-77" y="-295" type="curve" smooth="yes"/>
+ <point x="-133" y="-295"/>
+ <point x="-217" y="-264"/>
+ <point x="-253" y="-229" type="curve"/>
+ <point x="-328" y="-397" type="line"/>
+ <point x="-278" y="-437"/>
+ <point x="-170" y="-465"/>
+ <point x="-114" y="-465" type="curve" smooth="yes"/>
+ <point x="103" y="-465"/>
+ <point x="303" y="-314"/>
+ <point x="396" y="66" type="curve" smooth="yes"/>
+ <point x="455" y="307"/>
+ <point x="560" y="872"/>
+ <point x="560" y="1000" type="curve"/>
+ </contour>
+ <contour>
+ <point x="397" y="1297" type="curve" smooth="yes"/>
+ <point x="397" y="1237"/>
+ <point x="440" y="1186"/>
+ <point x="503" y="1186" type="curve" smooth="yes"/>
+ <point x="588" y="1186"/>
+ <point x="660" y="1259"/>
+ <point x="660" y="1338" type="curve" smooth="yes"/>
+ <point x="660" y="1399"/>
+ <point x="614" y="1450"/>
+ <point x="549" y="1450" type="curve" smooth="yes"/>
+ <point x="464" y="1450"/>
+ <point x="397" y="1375"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfcopyglyphs.ufo/glyphs/L_tnS_mK_.glif b/tests/reference/ufo/psfcopyglyphs.ufo/glyphs/L_tnS_mK_.glif
new file mode 100644
index 0000000..28fbc71
--- /dev/null
+++ b/tests/reference/ufo/psfcopyglyphs.ufo/glyphs/L_tnS_mK_.glif
@@ -0,0 +1,50 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmK" format="2">
+ <advance width="1059"/>
+ <unicode hex="006B"/>
+ <anchor x="840" y="0" name="H"/>
+ <anchor x="537" y="-100" name="L"/>
+ <anchor x="1225" y="1000" name="R"/>
+ <anchor x="920" y="1635" name="U"/>
+ <outline>
+ <contour>
+ <point x="295" y="0" type="line"/>
+ <point x="570" y="1105" type="line" smooth="yes"/>
+ <point x="614" y="1280"/>
+ <point x="645" y="1482"/>
+ <point x="645" y="1570" type="curve"/>
+ <point x="455" y="1570" type="line"/>
+ <point x="455" y="1456"/>
+ <point x="424" y="1259"/>
+ <point x="386" y="1107" type="curve" smooth="yes"/>
+ <point x="338" y="915"/>
+ <point x="110" y="0"/>
+ <point x="110" y="0" type="curve"/>
+ </contour>
+ <contour>
+ <point x="909" y="1000" type="line"/>
+ <point x="885" y="863"/>
+ <point x="654" y="700"/>
+ <point x="379" y="539" type="curve"/>
+ <point x="386" y="540"/>
+ <point x="393" y="540"/>
+ <point x="400" y="540" type="curve" smooth="yes"/>
+ <point x="467" y="540"/>
+ <point x="559" y="514"/>
+ <point x="559" y="514" type="curve"/>
+ <point x="902" y="702"/>
+ <point x="1134" y="884"/>
+ <point x="1134" y="1000" type="curve"/>
+ </contour>
+ <contour>
+ <point x="1010" y="0" type="line"/>
+ <point x="863" y="238"/>
+ <point x="718" y="600"/>
+ <point x="527" y="600" type="curve"/>
+ <point x="385" y="529" type="line"/>
+ <point x="540" y="529"/>
+ <point x="667" y="246"/>
+ <point x="775" y="0" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfcopyglyphs.ufo/glyphs/L_tnS_mL_.glif b/tests/reference/ufo/psfcopyglyphs.ufo/glyphs/L_tnS_mL_.glif
new file mode 100644
index 0000000..06d68fd
--- /dev/null
+++ b/tests/reference/ufo/psfcopyglyphs.ufo/glyphs/L_tnS_mL_.glif
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmL" format="2">
+ <advance width="575"/>
+ <unicode hex="006C"/>
+ <anchor x="230" y="0" name="H"/>
+ <anchor x="255" y="-100" name="L"/>
+ <anchor x="740" y="1000" name="R"/>
+ <anchor x="630" y="1635" name="U"/>
+ <outline>
+ <contour>
+ <point x="465" y="1570" type="line"/>
+ <point x="465" y="1456"/>
+ <point x="434" y="1259"/>
+ <point x="396" y="1107" type="curve" smooth="yes"/>
+ <point x="241" y="489" type="line" smooth="yes"/>
+ <point x="204" y="343"/>
+ <point x="186" y="220"/>
+ <point x="186" y="104" type="curve" smooth="yes"/>
+ <point x="186" y="69"/>
+ <point x="188" y="34"/>
+ <point x="191" y="0" type="curve"/>
+ <point x="391" y="0" type="line"/>
+ <point x="386" y="32"/>
+ <point x="384" y="70"/>
+ <point x="384" y="112" type="curve" smooth="yes"/>
+ <point x="384" y="230"/>
+ <point x="402" y="380"/>
+ <point x="436" y="517" type="curve" smooth="yes"/>
+ <point x="580" y="1105" type="line" smooth="yes"/>
+ <point x="623" y="1280"/>
+ <point x="655" y="1482"/>
+ <point x="655" y="1570" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfcopyglyphs.ufo/glyphs/L_tnS_mM_.glif b/tests/reference/ufo/psfcopyglyphs.ufo/glyphs/L_tnS_mM_.glif
new file mode 100644
index 0000000..a6b80db
--- /dev/null
+++ b/tests/reference/ufo/psfcopyglyphs.ufo/glyphs/L_tnS_mM_.glif
@@ -0,0 +1,80 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmM" format="2">
+ <advance width="1680"/>
+ <unicode hex="006D"/>
+ <anchor x="805" y="0" name="H"/>
+ <anchor x="780" y="-100" name="L"/>
+ <anchor x="1080" y="1100" name="U"/>
+ <outline>
+ <contour>
+ <point x="1520" y="0" type="line"/>
+ <point x="1512" y="30"/>
+ <point x="1510" y="65"/>
+ <point x="1510" y="102" type="curve" smooth="yes"/>
+ <point x="1510" y="143"/>
+ <point x="1515" y="188"/>
+ <point x="1522" y="238" type="curve" smooth="yes"/>
+ <point x="1536" y="327"/>
+ <point x="1655" y="691"/>
+ <point x="1655" y="800" type="curve" smooth="yes"/>
+ <point x="1655" y="930"/>
+ <point x="1594" y="1020"/>
+ <point x="1445" y="1020" type="curve" smooth="yes"/>
+ <point x="1292" y="1020"/>
+ <point x="1124" y="867"/>
+ <point x="1026" y="680" type="curve"/>
+ <point x="1030" y="704"/>
+ <point x="1045" y="778"/>
+ <point x="1045" y="800" type="curve" smooth="yes"/>
+ <point x="1045" y="932"/>
+ <point x="982" y="1020"/>
+ <point x="860" y="1020" type="curve" smooth="yes"/>
+ <point x="717" y="1020"/>
+ <point x="563" y="879"/>
+ <point x="446" y="680" type="curve"/>
+ <point x="466" y="753"/>
+ <point x="476" y="880"/>
+ <point x="476" y="961" type="curve" smooth="yes"/>
+ <point x="476" y="976"/>
+ <point x="476" y="989"/>
+ <point x="475" y="1000" type="curve"/>
+ <point x="295" y="1000" type="line"/>
+ <point x="296" y="983"/>
+ <point x="296" y="964"/>
+ <point x="296" y="945" type="curve" smooth="yes"/>
+ <point x="296" y="825"/>
+ <point x="283" y="680"/>
+ <point x="262" y="595" type="curve" smooth="yes"/>
+ <point x="115" y="0" type="line"/>
+ <point x="300" y="0" type="line"/>
+ <point x="389" y="359" type="line"/>
+ <point x="475" y="573"/>
+ <point x="685" y="850"/>
+ <point x="775" y="850" type="curve" smooth="yes"/>
+ <point x="833" y="850"/>
+ <point x="865" y="813"/>
+ <point x="865" y="720" type="curve" smooth="yes"/>
+ <point x="865" y="679"/>
+ <point x="846" y="583"/>
+ <point x="822" y="486" type="curve" smooth="yes"/>
+ <point x="700" y="0" type="line"/>
+ <point x="885" y="0" type="line"/>
+ <point x="974" y="359" type="line"/>
+ <point x="1032" y="531"/>
+ <point x="1242" y="850"/>
+ <point x="1357" y="850" type="curve" smooth="yes"/>
+ <point x="1425" y="850"/>
+ <point x="1457" y="813"/>
+ <point x="1457" y="720" type="curve" smooth="yes"/>
+ <point x="1457" y="632"/>
+ <point x="1349" y="319"/>
+ <point x="1335" y="203" type="curve" smooth="yes"/>
+ <point x="1330" y="158"/>
+ <point x="1327" y="115"/>
+ <point x="1327" y="77" type="curve" smooth="yes"/>
+ <point x="1327" y="48"/>
+ <point x="1331" y="21"/>
+ <point x="1335" y="0" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfcopyglyphs.ufo/glyphs/L_tnS_mN_.glif b/tests/reference/ufo/psfcopyglyphs.ufo/glyphs/L_tnS_mN_.glif
new file mode 100644
index 0000000..1f38f20
--- /dev/null
+++ b/tests/reference/ufo/psfcopyglyphs.ufo/glyphs/L_tnS_mN_.glif
@@ -0,0 +1,57 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmN" format="2">
+ <advance width="1195"/>
+ <unicode hex="006E"/>
+ <anchor x="540" y="0" name="H"/>
+ <anchor x="565" y="-100" name="L"/>
+ <anchor x="815" y="1100" name="U"/>
+ <outline>
+ <contour>
+ <point x="1060" y="0" type="line"/>
+ <point x="1052" y="30"/>
+ <point x="1050" y="65"/>
+ <point x="1050" y="102" type="curve" smooth="yes"/>
+ <point x="1050" y="143"/>
+ <point x="1055" y="188"/>
+ <point x="1062" y="238" type="curve" smooth="yes"/>
+ <point x="1075" y="327"/>
+ <point x="1175" y="636"/>
+ <point x="1175" y="745" type="curve" smooth="yes"/>
+ <point x="1175" y="917"/>
+ <point x="1100" y="1020"/>
+ <point x="935" y="1020" type="curve" smooth="yes"/>
+ <point x="755" y="1020"/>
+ <point x="581" y="870"/>
+ <point x="445" y="672" type="curve"/>
+ <point x="463" y="740"/>
+ <point x="477" y="873"/>
+ <point x="477" y="957" type="curve" smooth="yes"/>
+ <point x="477" y="973"/>
+ <point x="476" y="988"/>
+ <point x="475" y="1000" type="curve"/>
+ <point x="295" y="1000" type="line"/>
+ <point x="295" y="961" type="line" smooth="yes"/>
+ <point x="295" y="833"/>
+ <point x="283" y="679"/>
+ <point x="262" y="595" type="curve" smooth="yes"/>
+ <point x="115" y="0" type="line"/>
+ <point x="300" y="0" type="line"/>
+ <point x="392" y="370" type="line"/>
+ <point x="478" y="573"/>
+ <point x="708" y="850"/>
+ <point x="835" y="850" type="curve" smooth="yes"/>
+ <point x="927" y="850"/>
+ <point x="975" y="798"/>
+ <point x="975" y="680" type="curve" smooth="yes"/>
+ <point x="975" y="592"/>
+ <point x="888" y="319"/>
+ <point x="875" y="203" type="curve" smooth="yes"/>
+ <point x="870" y="158"/>
+ <point x="867" y="115"/>
+ <point x="867" y="77" type="curve" smooth="yes"/>
+ <point x="867" y="48"/>
+ <point x="871" y="21"/>
+ <point x="875" y="0" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfcopyglyphs.ufo/glyphs/L_tnS_mO_.glif b/tests/reference/ufo/psfcopyglyphs.ufo/glyphs/L_tnS_mO_.glif
new file mode 100644
index 0000000..bec7b9e
--- /dev/null
+++ b/tests/reference/ufo/psfcopyglyphs.ufo/glyphs/L_tnS_mO_.glif
@@ -0,0 +1,40 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmO" format="2">
+ <advance width="1133"/>
+ <unicode hex="006F"/>
+ <anchor x="510" y="0" name="H"/>
+ <anchor x="505" y="-100" name="L"/>
+ <anchor x="800" y="0" name="O"/>
+ <anchor x="1330" y="1000" name="R"/>
+ <anchor x="785" y="1100" name="U"/>
+ <outline>
+ <contour>
+ <point x="142" y="344" type="curve" smooth="yes"/>
+ <point x="142" y="114"/>
+ <point x="306" y="-25"/>
+ <point x="530" y="-25" type="curve" smooth="yes"/>
+ <point x="896" y="-25"/>
+ <point x="1138" y="314"/>
+ <point x="1138" y="648" type="curve" smooth="yes"/>
+ <point x="1138" y="879"/>
+ <point x="985" y="1020"/>
+ <point x="761" y="1020" type="curve" smooth="yes"/>
+ <point x="387" y="1020"/>
+ <point x="142" y="677"/>
+ </contour>
+ <contour>
+ <point x="721" y="862" type="curve" smooth="yes"/>
+ <point x="859" y="862"/>
+ <point x="947" y="767"/>
+ <point x="947" y="611" type="curve" smooth="yes"/>
+ <point x="947" y="391"/>
+ <point x="795" y="132"/>
+ <point x="559" y="132" type="curve" smooth="yes"/>
+ <point x="421" y="132"/>
+ <point x="333" y="226"/>
+ <point x="333" y="380" type="curve" smooth="yes"/>
+ <point x="333" y="599"/>
+ <point x="486" y="862"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfcopyglyphs.ufo/glyphs/L_tnS_mP_.glif b/tests/reference/ufo/psfcopyglyphs.ufo/glyphs/L_tnS_mP_.glif
new file mode 100644
index 0000000..f9e06b1
--- /dev/null
+++ b/tests/reference/ufo/psfcopyglyphs.ufo/glyphs/L_tnS_mP_.glif
@@ -0,0 +1,66 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmP" format="2">
+ <advance width="1185"/>
+ <unicode hex="0070"/>
+ <anchor x="105" y="-435" name="H"/>
+ <anchor x="405" y="-500" name="L"/>
+ <anchor x="1360" y="1000" name="R"/>
+ <anchor x="805" y="1100" name="U"/>
+ <outline>
+ <contour>
+ <point x="215" y="-480" type="line"/>
+ <point x="215" y="-388"/>
+ <point x="229" y="-282"/>
+ <point x="255" y="-175" type="curve" smooth="yes"/>
+ <point x="320" y="85" type="line"/>
+ <point x="399" y="20"/>
+ <point x="468" y="-25"/>
+ <point x="575" y="-25" type="curve" smooth="yes"/>
+ <point x="685" y="-25"/>
+ <point x="797" y="9"/>
+ <point x="895" y="85" type="curve" smooth="yes"/>
+ <point x="1063" y="215"/>
+ <point x="1185" y="438"/>
+ <point x="1185" y="680" type="curve" smooth="yes"/>
+ <point x="1185" y="878"/>
+ <point x="1101" y="1020"/>
+ <point x="920" y="1020" type="curve" smooth="yes"/>
+ <point x="757" y="1020"/>
+ <point x="559" y="842"/>
+ <point x="452" y="680" type="curve"/>
+ <point x="468" y="760"/>
+ <point x="477" y="860"/>
+ <point x="477" y="940" type="curve" smooth="yes"/>
+ <point x="477" y="962"/>
+ <point x="477" y="982"/>
+ <point x="475" y="1000" type="curve"/>
+ <point x="295" y="1000" type="line"/>
+ <point x="295" y="971" type="line" smooth="yes"/>
+ <point x="295" y="819"/>
+ <point x="273" y="625"/>
+ <point x="235" y="475" type="curve" smooth="yes"/>
+ <point x="70" y="-175" type="line" smooth="yes"/>
+ <point x="43" y="-281"/>
+ <point x="20" y="-398"/>
+ <point x="20" y="-480" type="curve"/>
+ </contour>
+ <contour>
+ <point x="407" y="432" type="line"/>
+ <point x="544" y="656"/>
+ <point x="732" y="850"/>
+ <point x="840" y="850" type="curve" smooth="yes"/>
+ <point x="939" y="850"/>
+ <point x="990" y="763"/>
+ <point x="990" y="630" type="curve" smooth="yes"/>
+ <point x="990" y="491"/>
+ <point x="926" y="322"/>
+ <point x="815" y="220" type="curve" smooth="yes"/>
+ <point x="759" y="168"/>
+ <point x="693" y="135"/>
+ <point x="615" y="135" type="curve" smooth="yes"/>
+ <point x="523" y="135"/>
+ <point x="479" y="161"/>
+ <point x="365" y="255" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfcopyglyphs.ufo/glyphs/L_tnS_mQ_.glif b/tests/reference/ufo/psfcopyglyphs.ufo/glyphs/L_tnS_mQ_.glif
new file mode 100644
index 0000000..58d9f87
--- /dev/null
+++ b/tests/reference/ufo/psfcopyglyphs.ufo/glyphs/L_tnS_mQ_.glif
@@ -0,0 +1,54 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmQ" format="2">
+ <advance width="1115"/>
+ <unicode hex="0071"/>
+ <anchor x="370" y="-500" name="L"/>
+ <anchor x="1320" y="1000" name="R"/>
+ <anchor x="770" y="1100" name="U"/>
+ <outline>
+ <contour>
+ <point x="843" y="-480" type="line"/>
+ <point x="843" y="-391"/>
+ <point x="858" y="-294"/>
+ <point x="885" y="-185" type="curve" smooth="yes"/>
+ <point x="1165" y="945" type="line"/>
+ <point x="1066" y="980"/>
+ <point x="946" y="1020"/>
+ <point x="825" y="1020" type="curve" smooth="yes"/>
+ <point x="675" y="1020"/>
+ <point x="550" y="977"/>
+ <point x="440" y="890" type="curve" smooth="yes"/>
+ <point x="260" y="747"/>
+ <point x="135" y="505"/>
+ <point x="135" y="285" type="curve" smooth="yes"/>
+ <point x="135" y="73"/>
+ <point x="261" y="-25"/>
+ <point x="380" y="-25" type="curve" smooth="yes"/>
+ <point x="524" y="-25"/>
+ <point x="751" y="172"/>
+ <point x="825" y="300" type="curve"/>
+ <point x="693" y="-180" type="line" smooth="yes"/>
+ <point x="662" y="-294"/>
+ <point x="648" y="-414"/>
+ <point x="648" y="-480" type="curve"/>
+ </contour>
+ <contour>
+ <point x="885" y="565" type="line"/>
+ <point x="807" y="413"/>
+ <point x="550" y="140"/>
+ <point x="455" y="140" type="curve" smooth="yes"/>
+ <point x="376" y="140"/>
+ <point x="330" y="199"/>
+ <point x="330" y="330" type="curve" smooth="yes"/>
+ <point x="330" y="481"/>
+ <point x="400" y="658"/>
+ <point x="515" y="760" type="curve" smooth="yes"/>
+ <point x="580" y="817"/>
+ <point x="658" y="855"/>
+ <point x="750" y="855" type="curve" smooth="yes"/>
+ <point x="811" y="855"/>
+ <point x="893" y="840"/>
+ <point x="947" y="817" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfcopyglyphs.ufo/glyphs/L_tnS_mR_.glif b/tests/reference/ufo/psfcopyglyphs.ufo/glyphs/L_tnS_mR_.glif
new file mode 100644
index 0000000..8037612
--- /dev/null
+++ b/tests/reference/ufo/psfcopyglyphs.ufo/glyphs/L_tnS_mR_.glif
@@ -0,0 +1,42 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmR" format="2">
+ <advance width="910"/>
+ <unicode hex="0072"/>
+ <anchor x="210" y="0" name="H"/>
+ <anchor x="220" y="-100" name="L"/>
+ <anchor x="670" y="1100" name="U"/>
+ <outline>
+ <contour>
+ <point x="300" y="0" type="line"/>
+ <point x="402" y="415" type="line"/>
+ <point x="502" y="602"/>
+ <point x="703" y="850"/>
+ <point x="785" y="850" type="curve" smooth="yes"/>
+ <point x="831" y="850"/>
+ <point x="855" y="801"/>
+ <point x="855" y="740" type="curve" smooth="yes"/>
+ <point x="855" y="715"/>
+ <point x="852" y="689"/>
+ <point x="845" y="660" type="curve"/>
+ <point x="1010" y="690" type="line"/>
+ <point x="1022" y="737"/>
+ <point x="1030" y="783"/>
+ <point x="1030" y="825" type="curve" smooth="yes"/>
+ <point x="1030" y="935"/>
+ <point x="986" y="1020"/>
+ <point x="865" y="1020" type="curve" smooth="yes"/>
+ <point x="735" y="1020"/>
+ <point x="575" y="867"/>
+ <point x="445" y="675" type="curve"/>
+ <point x="467" y="773"/>
+ <point x="475" y="929"/>
+ <point x="475" y="1000" type="curve"/>
+ <point x="295" y="1000" type="line"/>
+ <point x="295" y="961" type="line" smooth="yes"/>
+ <point x="295" y="833"/>
+ <point x="283" y="679"/>
+ <point x="262" y="595" type="curve" smooth="yes"/>
+ <point x="115" y="0" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfcopyglyphs.ufo/glyphs/L_tnS_mS_.glif b/tests/reference/ufo/psfcopyglyphs.ufo/glyphs/L_tnS_mS_.glif
new file mode 100644
index 0000000..848ddda
--- /dev/null
+++ b/tests/reference/ufo/psfcopyglyphs.ufo/glyphs/L_tnS_mS_.glif
@@ -0,0 +1,50 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmS" format="2">
+ <advance width="945"/>
+ <unicode hex="0073"/>
+ <anchor x="435" y="0" name="H"/>
+ <anchor x="440" y="-100" name="L"/>
+ <anchor x="710" y="1100" name="U"/>
+ <outline>
+ <contour>
+ <point x="990" y="941" type="line"/>
+ <point x="930" y="978"/>
+ <point x="815" y="1020"/>
+ <point x="640" y="1020" type="curve" smooth="yes"/>
+ <point x="384" y="1020"/>
+ <point x="230" y="881"/>
+ <point x="230" y="716" type="curve" smooth="yes"/>
+ <point x="230" y="614"/>
+ <point x="320" y="533"/>
+ <point x="466" y="461" type="curve" smooth="yes"/>
+ <point x="638" y="376"/>
+ <point x="700" y="333"/>
+ <point x="700" y="265" type="curve" smooth="yes"/>
+ <point x="700" y="188"/>
+ <point x="621" y="132"/>
+ <point x="532" y="132" type="curve" smooth="yes"/>
+ <point x="376" y="132"/>
+ <point x="244" y="216"/>
+ <point x="159" y="325" type="curve"/>
+ <point x="71" y="158" type="line"/>
+ <point x="160" y="60"/>
+ <point x="296" y="-25"/>
+ <point x="488" y="-25" type="curve" smooth="yes"/>
+ <point x="713" y="-25"/>
+ <point x="891" y="106"/>
+ <point x="891" y="306" type="curve" smooth="yes"/>
+ <point x="891" y="432"/>
+ <point x="774" y="515"/>
+ <point x="626" y="593" type="curve" smooth="yes"/>
+ <point x="476" y="672"/>
+ <point x="418" y="695"/>
+ <point x="418" y="753" type="curve" smooth="yes"/>
+ <point x="418" y="822"/>
+ <point x="494" y="862"/>
+ <point x="619" y="862" type="curve" smooth="yes"/>
+ <point x="743" y="862"/>
+ <point x="854" y="808"/>
+ <point x="911" y="769" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfcopyglyphs.ufo/glyphs/L_tnS_mT_.glif b/tests/reference/ufo/psfcopyglyphs.ufo/glyphs/L_tnS_mT_.glif
new file mode 100644
index 0000000..0eddfe9
--- /dev/null
+++ b/tests/reference/ufo/psfcopyglyphs.ufo/glyphs/L_tnS_mT_.glif
@@ -0,0 +1,45 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmT" format="2">
+ <advance width="815"/>
+ <unicode hex="0074"/>
+ <anchor x="455" y="0" name="H"/>
+ <anchor x="390" y="-100" name="L"/>
+ <anchor x="1025" y="1000" name="R"/>
+ <anchor x="605" y="1360" name="U"/>
+ <outline>
+ <contour>
+ <point x="752" y="211" type="line"/>
+ <point x="665" y="169"/>
+ <point x="593" y="134"/>
+ <point x="527" y="134" type="curve" smooth="yes"/>
+ <point x="448" y="134"/>
+ <point x="425" y="188"/>
+ <point x="425" y="247" type="curve" smooth="yes"/>
+ <point x="425" y="274"/>
+ <point x="429" y="301"/>
+ <point x="434" y="326" type="curve" smooth="yes"/>
+ <point x="470" y="519"/>
+ <point x="564" y="843"/>
+ <point x="677" y="1294" type="curve"/>
+ <point x="492" y="1294" type="line"/>
+ <point x="377" y="841"/>
+ <point x="263" y="429"/>
+ <point x="243" y="301" type="curve" smooth="yes"/>
+ <point x="238" y="269"/>
+ <point x="236" y="240"/>
+ <point x="236" y="213" type="curve" smooth="yes"/>
+ <point x="236" y="41"/>
+ <point x="330" y="-25"/>
+ <point x="465" y="-25" type="curve" smooth="yes"/>
+ <point x="535" y="-25"/>
+ <point x="634" y="-6"/>
+ <point x="740" y="52" type="curve"/>
+ </contour>
+ <contour>
+ <point x="177" y="833" type="line"/>
+ <point x="887" y="833" type="line"/>
+ <point x="923" y="975" type="line"/>
+ <point x="213" y="975" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfcopyglyphs.ufo/glyphs/L_tnS_mU_.glif b/tests/reference/ufo/psfcopyglyphs.ufo/glyphs/L_tnS_mU_.glif
new file mode 100644
index 0000000..0eda3d2
--- /dev/null
+++ b/tests/reference/ufo/psfcopyglyphs.ufo/glyphs/L_tnS_mU_.glif
@@ -0,0 +1,57 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmU" format="2">
+ <advance width="1175"/>
+ <unicode hex="0075"/>
+ <anchor x="465" y="0" name="H"/>
+ <anchor x="504" y="-100" name="L"/>
+ <anchor x="640" y="0" name="O"/>
+ <anchor x="1375" y="1000" name="R"/>
+ <anchor x="804" y="1100" name="U"/>
+ <outline>
+ <contour>
+ <point x="1040" y="0" type="line"/>
+ <point x="1036" y="29"/>
+ <point x="1035" y="62"/>
+ <point x="1035" y="100" type="curve" smooth="yes"/>
+ <point x="1035" y="206"/>
+ <point x="1054" y="341"/>
+ <point x="1080" y="455" type="curve" smooth="yes"/>
+ <point x="1135" y="689"/>
+ <point x="1197" y="895"/>
+ <point x="1205" y="1000" type="curve"/>
+ <point x="1010" y="1000" type="line"/>
+ <point x="1003" y="882"/>
+ <point x="971" y="769"/>
+ <point x="920" y="565" type="curve"/>
+ <point x="827" y="376"/>
+ <point x="573" y="135"/>
+ <point x="475" y="135" type="curve" smooth="yes"/>
+ <point x="409" y="135"/>
+ <point x="365" y="181"/>
+ <point x="365" y="280" type="curve" smooth="yes"/>
+ <point x="365" y="347"/>
+ <point x="407" y="500"/>
+ <point x="459" y="702" type="curve" smooth="yes"/>
+ <point x="494" y="837"/>
+ <point x="515" y="925"/>
+ <point x="520" y="1000" type="curve"/>
+ <point x="325" y="1000" type="line"/>
+ <point x="313" y="882"/>
+ <point x="295" y="809"/>
+ <point x="265" y="685" type="curve" smooth="yes"/>
+ <point x="195" y="395" type="line" smooth="yes"/>
+ <point x="179" y="330"/>
+ <point x="170" y="275"/>
+ <point x="170" y="225" type="curve" smooth="yes"/>
+ <point x="170" y="60"/>
+ <point x="257" y="-25"/>
+ <point x="410" y="-25" type="curve" smooth="yes"/>
+ <point x="551" y="-25"/>
+ <point x="745" y="118"/>
+ <point x="880" y="305" type="curve"/>
+ <point x="861" y="196"/>
+ <point x="860" y="98"/>
+ <point x="860" y="0" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfcopyglyphs.ufo/glyphs/L_tnS_mV_.glif b/tests/reference/ufo/psfcopyglyphs.ufo/glyphs/L_tnS_mV_.glif
new file mode 100644
index 0000000..33e91d6
--- /dev/null
+++ b/tests/reference/ufo/psfcopyglyphs.ufo/glyphs/L_tnS_mV_.glif
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmV" format="2">
+ <advance width="941"/>
+ <unicode hex="0076"/>
+ <anchor x="359" y="0" name="H"/>
+ <anchor x="350" y="-100" name="L"/>
+ <anchor x="565" y="0" name="O"/>
+ <anchor x="650" y="1100" name="U"/>
+ <outline>
+ <contour>
+ <point x="180" y="1000" type="line"/>
+ <point x="232" y="825"/>
+ <point x="256" y="602"/>
+ <point x="256" y="354" type="curve" smooth="yes"/>
+ <point x="256" y="241"/>
+ <point x="251" y="122"/>
+ <point x="241" y="0" type="curve"/>
+ <point x="441" y="0" type="line"/>
+ <point x="744" y="336"/>
+ <point x="1056" y="765"/>
+ <point x="1056" y="1000" type="curve"/>
+ <point x="856" y="1000" type="line"/>
+ <point x="856" y="769"/>
+ <point x="606" y="394"/>
+ <point x="404" y="176" type="curve"/>
+ <point x="421" y="277"/>
+ <point x="429" y="402"/>
+ <point x="429" y="526" type="curve" smooth="yes"/>
+ <point x="429" y="707"/>
+ <point x="412" y="887"/>
+ <point x="380" y="1000" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfcopyglyphs.ufo/glyphs/L_tnS_mW_.glif b/tests/reference/ufo/psfcopyglyphs.ufo/glyphs/L_tnS_mW_.glif
new file mode 100644
index 0000000..1daea7c
--- /dev/null
+++ b/tests/reference/ufo/psfcopyglyphs.ufo/glyphs/L_tnS_mW_.glif
@@ -0,0 +1,50 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmW" format="2">
+ <advance width="1555"/>
+ <unicode hex="0077"/>
+ <anchor x="690" y="-100" name="L"/>
+ <anchor x="990" y="1100" name="U"/>
+ <outline>
+ <contour>
+ <point x="858" y="1000" type="line"/>
+ <point x="743" y="739"/>
+ <point x="588" y="466"/>
+ <point x="388" y="181" type="curve"/>
+ <point x="417" y="339"/>
+ <point x="430" y="500"/>
+ <point x="430" y="644" type="curve" smooth="yes"/>
+ <point x="430" y="784"/>
+ <point x="418" y="908"/>
+ <point x="395" y="1000" type="curve"/>
+ <point x="195" y="1000" type="line"/>
+ <point x="234" y="873"/>
+ <point x="256" y="688"/>
+ <point x="256" y="472" type="curve" smooth="yes"/>
+ <point x="256" y="326"/>
+ <point x="246" y="166"/>
+ <point x="225" y="0" type="curve"/>
+ <point x="425" y="0" type="line"/>
+ <point x="632" y="298"/>
+ <point x="825" y="583"/>
+ <point x="896" y="765" type="curve"/>
+ <point x="920" y="478"/>
+ <point x="912" y="233"/>
+ <point x="915" y="0" type="curve"/>
+ <point x="1115" y="0" type="line"/>
+ <point x="1362" y="330"/>
+ <point x="1642" y="777"/>
+ <point x="1645" y="1000" type="curve"/>
+ <point x="1445" y="1000" type="line"/>
+ <point x="1445" y="990" type="line"/>
+ <point x="1445" y="797"/>
+ <point x="1242" y="417"/>
+ <point x="1063" y="181" type="curve"/>
+ <point x="1064" y="221"/>
+ <point x="1064" y="260"/>
+ <point x="1064" y="298" type="curve" smooth="yes"/>
+ <point x="1064" y="577"/>
+ <point x="1046" y="811"/>
+ <point x="1020" y="1000" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfcopyglyphs.ufo/glyphs/L_tnS_mX_.glif b/tests/reference/ufo/psfcopyglyphs.ufo/glyphs/L_tnS_mX_.glif
new file mode 100644
index 0000000..5508ff9
--- /dev/null
+++ b/tests/reference/ufo/psfcopyglyphs.ufo/glyphs/L_tnS_mX_.glif
@@ -0,0 +1,40 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmX" format="2">
+ <advance width="1009"/>
+ <unicode hex="0078"/>
+ <anchor x="840" y="0" name="H"/>
+ <anchor x="457" y="-100" name="L"/>
+ <anchor x="657" y="1100" name="U"/>
+ <outline>
+ <contour>
+ <point x="945" y="0" type="line"/>
+ <point x="765" y="133"/>
+ <point x="558" y="867"/>
+ <point x="439" y="1000" type="curve"/>
+ <point x="181" y="1000" type="line"/>
+ <point x="410" y="832"/>
+ <point x="578" y="141"/>
+ <point x="698" y="0" type="curve"/>
+ </contour>
+ <contour>
+ <point x="504" y="572" type="line"/>
+ <point x="286" y="463"/>
+ <point x="57" y="230"/>
+ <point x="30" y="0" type="curve"/>
+ <point x="230" y="0" type="line"/>
+ <point x="231" y="156"/>
+ <point x="375" y="380"/>
+ <point x="563" y="467" type="curve"/>
+ </contour>
+ <contour>
+ <point x="659" y="471" type="line"/>
+ <point x="838" y="591"/>
+ <point x="1092" y="798"/>
+ <point x="1099" y="1000" type="curve"/>
+ <point x="889" y="1000" type="line"/>
+ <point x="883" y="842"/>
+ <point x="758" y="675"/>
+ <point x="601" y="581" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfcopyglyphs.ufo/glyphs/L_tnS_mY_.glif b/tests/reference/ufo/psfcopyglyphs.ufo/glyphs/L_tnS_mY_.glif
new file mode 100644
index 0000000..b9000c5
--- /dev/null
+++ b/tests/reference/ufo/psfcopyglyphs.ufo/glyphs/L_tnS_mY_.glif
@@ -0,0 +1,45 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmY" format="2">
+ <advance width="976"/>
+ <unicode hex="0079"/>
+ <anchor x="710" y="-100" name="L"/>
+ <anchor x="1270" y="1000" name="R"/>
+ <anchor x="630" y="1100" name="U"/>
+ <outline>
+ <contour>
+ <point x="132" y="1000" type="line"/>
+ <point x="270" y="825"/>
+ <point x="398" y="406"/>
+ <point x="403" y="-16" type="curve"/>
+ <point x="263" y="-232"/>
+ <point x="145" y="-295"/>
+ <point x="64" y="-295" type="curve" smooth="yes"/>
+ <point x="-2" y="-295"/>
+ <point x="-69" y="-254"/>
+ <point x="-102" y="-220" type="curve"/>
+ <point x="-200" y="-377" type="line"/>
+ <point x="-141" y="-430"/>
+ <point x="-68" y="-465"/>
+ <point x="23" y="-465" type="curve" smooth="yes"/>
+ <point x="193" y="-465"/>
+ <point x="369" y="-371"/>
+ <point x="609" y="0" type="curve" smooth="yes"/>
+ <point x="877" y="414"/>
+ <point x="1056" y="808"/>
+ <point x="1056" y="964" type="curve" smooth="yes"/>
+ <point x="1056" y="978"/>
+ <point x="1055" y="990"/>
+ <point x="1052" y="1000" type="curve"/>
+ <point x="852" y="1000" type="line"/>
+ <point x="856" y="984"/>
+ <point x="858" y="967"/>
+ <point x="858" y="946" type="curve" smooth="yes"/>
+ <point x="858" y="783"/>
+ <point x="722" y="472"/>
+ <point x="548" y="189" type="curve"/>
+ <point x="548" y="484"/>
+ <point x="447" y="866"/>
+ <point x="347" y="1000" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfcopyglyphs.ufo/glyphs/N_onB_reakingH_yphen.glif b/tests/reference/ufo/psfcopyglyphs.ufo/glyphs/N_onB_reakingH_yphen.glif
new file mode 100644
index 0000000..e7d9c06
--- /dev/null
+++ b/tests/reference/ufo/psfcopyglyphs.ufo/glyphs/N_onB_reakingH_yphen.glif
@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="NonBreakingHyphen" format="2">
+ <advance width="840"/>
+ <unicode hex="2011"/>
+ <anchor x="645" y="1100" name="U"/>
+ <outline>
+ <component base="HyphenMinus"/>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfcopyglyphs.ufo/glyphs/N_umS_gn.glif b/tests/reference/ufo/psfcopyglyphs.ufo/glyphs/N_umS_gn.glif
new file mode 100644
index 0000000..b7506f7
--- /dev/null
+++ b/tests/reference/ufo/psfcopyglyphs.ufo/glyphs/N_umS_gn.glif
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="NumSgn" format="2">
+ <advance width="1180"/>
+ <unicode hex="0023"/>
+ <outline>
+ <contour>
+ <point x="739" y="1333" type="line"/>
+ <point x="91" y="98" type="line"/>
+ <point x="261" y="98" type="line"/>
+ <point x="909" y="1333" type="line"/>
+ </contour>
+ <contour>
+ <point x="80" y="465" type="line"/>
+ <point x="1171" y="465" type="line"/>
+ <point x="1208" y="612" type="line"/>
+ <point x="117" y="612" type="line"/>
+ </contour>
+ <contour>
+ <point x="234" y="843" type="line"/>
+ <point x="1325" y="843" type="line"/>
+ <point x="1361" y="990" type="line"/>
+ <point x="270" y="990" type="line"/>
+ </contour>
+ <contour>
+ <point x="1164" y="1333" type="line"/>
+ <point x="516" y="98" type="line"/>
+ <point x="686" y="98" type="line"/>
+ <point x="1334" y="1333" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfcopyglyphs.ufo/glyphs/P_ercentS_gn.glif b/tests/reference/ufo/psfcopyglyphs.ufo/glyphs/P_ercentS_gn.glif
new file mode 100644
index 0000000..84241ea
--- /dev/null
+++ b/tests/reference/ufo/psfcopyglyphs.ufo/glyphs/P_ercentS_gn.glif
@@ -0,0 +1,93 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="PercentSgn" format="2">
+ <advance width="1506"/>
+ <unicode hex="0025"/>
+ <outline>
+ <contour>
+ <point x="1300" y="349" type="curve" smooth="yes"/>
+ <point x="1255" y="168"/>
+ <point x="1204" y="113"/>
+ <point x="1118" y="113" type="curve" smooth="yes"/>
+ <point x="1056" y="113"/>
+ <point x="1021" y="148"/>
+ <point x="1021" y="235" type="curve" smooth="yes"/>
+ <point x="1021" y="274"/>
+ <point x="1028" y="322"/>
+ <point x="1043" y="383" type="curve" smooth="yes"/>
+ <point x="1088" y="564"/>
+ <point x="1136" y="617"/>
+ <point x="1223" y="617" type="curve" smooth="yes"/>
+ <point x="1286" y="617"/>
+ <point x="1322" y="582"/>
+ <point x="1322" y="496" type="curve" smooth="yes"/>
+ <point x="1322" y="458"/>
+ <point x="1315" y="409"/>
+ </contour>
+ <contour>
+ <point x="1468" y="361" type="curve" smooth="yes"/>
+ <point x="1483" y="419"/>
+ <point x="1489" y="470"/>
+ <point x="1489" y="515" type="curve" smooth="yes"/>
+ <point x="1489" y="677"/>
+ <point x="1400" y="755"/>
+ <point x="1263" y="755" type="curve" smooth="yes"/>
+ <point x="1089" y="755"/>
+ <point x="945" y="647"/>
+ <point x="876" y="371" type="curve" smooth="yes"/>
+ <point x="861" y="310"/>
+ <point x="854" y="256"/>
+ <point x="854" y="210" type="curve" smooth="yes"/>
+ <point x="854" y="47"/>
+ <point x="943" y="-25"/>
+ <point x="1079" y="-25" type="curve" smooth="yes"/>
+ <point x="1254" y="-25"/>
+ <point x="1396" y="72"/>
+ </contour>
+ <contour>
+ <point x="1369" y="1450" type="line"/>
+ <point x="219" y="-25" type="line"/>
+ <point x="397" y="-25" type="line"/>
+ <point x="1545" y="1450" type="line"/>
+ </contour>
+ <contour>
+ <point x="717" y="1044" type="curve" smooth="yes"/>
+ <point x="672" y="864"/>
+ <point x="621" y="809"/>
+ <point x="535" y="809" type="curve" smooth="yes"/>
+ <point x="474" y="809"/>
+ <point x="439" y="844"/>
+ <point x="439" y="930" type="curve" smooth="yes"/>
+ <point x="439" y="969"/>
+ <point x="446" y="1018"/>
+ <point x="461" y="1079" type="curve" smooth="yes"/>
+ <point x="506" y="1260"/>
+ <point x="554" y="1313"/>
+ <point x="641" y="1313" type="curve" smooth="yes"/>
+ <point x="704" y="1313"/>
+ <point x="739" y="1278"/>
+ <point x="739" y="1192" type="curve" smooth="yes"/>
+ <point x="739" y="1153"/>
+ <point x="732" y="1105"/>
+ </contour>
+ <contour>
+ <point x="886" y="1057" type="curve" smooth="yes"/>
+ <point x="900" y="1114"/>
+ <point x="907" y="1166"/>
+ <point x="907" y="1210" type="curve" smooth="yes"/>
+ <point x="907" y="1373"/>
+ <point x="817" y="1450"/>
+ <point x="680" y="1450" type="curve" smooth="yes"/>
+ <point x="506" y="1450"/>
+ <point x="362" y="1343"/>
+ <point x="293" y="1066" type="curve" smooth="yes"/>
+ <point x="278" y="1005"/>
+ <point x="271" y="952"/>
+ <point x="271" y="906" type="curve" smooth="yes"/>
+ <point x="271" y="743"/>
+ <point x="360" y="671"/>
+ <point x="497" y="671" type="curve" smooth="yes"/>
+ <point x="672" y="671"/>
+ <point x="813" y="768"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfcopyglyphs.ufo/glyphs/P_lusS_gn.glif b/tests/reference/ufo/psfcopyglyphs.ufo/glyphs/P_lusS_gn.glif
new file mode 100644
index 0000000..8c4577e
--- /dev/null
+++ b/tests/reference/ufo/psfcopyglyphs.ufo/glyphs/P_lusS_gn.glif
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="PlusSgn" format="2">
+ <advance width="1180"/>
+ <unicode hex="002B"/>
+ <outline>
+ <contour>
+ <point x="748" y="1156" type="line"/>
+ <point x="529" y="279" type="line"/>
+ <point x="684" y="279" type="line"/>
+ <point x="903" y="1156" type="line"/>
+ </contour>
+ <contour>
+ <point x="256" y="647" type="line"/>
+ <point x="1146" y="647" type="line"/>
+ <point x="1182" y="794" type="line"/>
+ <point x="292" y="794" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfcopyglyphs.ufo/glyphs/Q_stnM_rk.glif b/tests/reference/ufo/psfcopyglyphs.ufo/glyphs/Q_stnM_rk.glif
new file mode 100644
index 0000000..8b14a6c
--- /dev/null
+++ b/tests/reference/ufo/psfcopyglyphs.ufo/glyphs/Q_stnM_rk.glif
@@ -0,0 +1,49 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="QstnMrk" format="2">
+ <advance width="1030"/>
+ <unicode hex="003F"/>
+ <outline>
+ <contour>
+ <point x="419" y="1226" type="line"/>
+ <point x="514" y="1303"/>
+ <point x="615" y="1338"/>
+ <point x="685" y="1338" type="curve" smooth="yes"/>
+ <point x="800" y="1338"/>
+ <point x="858" y="1294"/>
+ <point x="858" y="1222" type="curve" smooth="yes"/>
+ <point x="858" y="1122"/>
+ <point x="713" y="1017"/>
+ <point x="654" y="960" type="curve" smooth="yes"/>
+ <point x="538" y="850"/>
+ <point x="473" y="715"/>
+ <point x="402" y="431" type="curve"/>
+ <point x="587" y="431" type="line"/>
+ <point x="656" y="707"/>
+ <point x="697" y="778"/>
+ <point x="831" y="901" type="curve" smooth="yes"/>
+ <point x="949" y="1010"/>
+ <point x="1072" y="1146"/>
+ <point x="1072" y="1272" type="curve" smooth="yes"/>
+ <point x="1072" y="1409"/>
+ <point x="947" y="1509"/>
+ <point x="746" y="1509" type="curve" smooth="yes"/>
+ <point x="631" y="1509"/>
+ <point x="500" y="1463"/>
+ <point x="419" y="1401" type="curve"/>
+ </contour>
+ <contour>
+ <point x="278" y="90" type="curve" smooth="yes"/>
+ <point x="278" y="28"/>
+ <point x="328" y="-25"/>
+ <point x="393" y="-25" type="curve" smooth="yes"/>
+ <point x="477" y="-25"/>
+ <point x="554" y="45"/>
+ <point x="554" y="125" type="curve" smooth="yes"/>
+ <point x="554" y="186"/>
+ <point x="504" y="240"/>
+ <point x="439" y="240" type="curve" smooth="yes"/>
+ <point x="355" y="240"/>
+ <point x="278" y="170"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfcopyglyphs.ufo/glyphs/Q_uotM_rk.glif b/tests/reference/ufo/psfcopyglyphs.ufo/glyphs/Q_uotM_rk.glif
new file mode 100644
index 0000000..4a8357b
--- /dev/null
+++ b/tests/reference/ufo/psfcopyglyphs.ufo/glyphs/Q_uotM_rk.glif
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="QuotMrk" format="2">
+ <advance width="1005"/>
+ <unicode hex="0022"/>
+ <outline>
+ <contour>
+ <point x="600" y="1024" type="line"/>
+ <point x="639" y="1162"/>
+ <point x="683" y="1312"/>
+ <point x="772" y="1553" type="curve"/>
+ <point x="567" y="1553" type="line"/>
+ <point x="538" y="1312"/>
+ <point x="505" y="1162"/>
+ <point x="475" y="1024" type="curve"/>
+ </contour>
+ <contour>
+ <point x="940" y="1024" type="line"/>
+ <point x="979" y="1162"/>
+ <point x="1023" y="1312"/>
+ <point x="1112" y="1553" type="curve"/>
+ <point x="907" y="1553" type="line"/>
+ <point x="878" y="1312"/>
+ <point x="845" y="1162"/>
+ <point x="815" y="1024" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfcopyglyphs.ufo/glyphs/R_everseS_olidus.glif b/tests/reference/ufo/psfcopyglyphs.ufo/glyphs/R_everseS_olidus.glif
new file mode 100644
index 0000000..f146267
--- /dev/null
+++ b/tests/reference/ufo/psfcopyglyphs.ufo/glyphs/R_everseS_olidus.glif
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="ReverseSolidus" format="2">
+ <advance width="1005"/>
+ <unicode hex="005C"/>
+ <outline>
+ <contour>
+ <point x="473" y="1538" type="line"/>
+ <point x="656" y="-123" type="line"/>
+ <point x="799" y="-93" type="line"/>
+ <point x="620" y="1568" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfcopyglyphs.ufo/glyphs/R_tC_urlyB_rac.glif b/tests/reference/ufo/psfcopyglyphs.ufo/glyphs/R_tC_urlyB_rac.glif
new file mode 100644
index 0000000..82df531
--- /dev/null
+++ b/tests/reference/ufo/psfcopyglyphs.ufo/glyphs/R_tC_urlyB_rac.glif
@@ -0,0 +1,50 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="RtCurlyBrac" format="2">
+ <advance width="980"/>
+ <unicode hex="007D"/>
+ <outline>
+ <contour>
+ <point x="466" y="1470" type="line"/>
+ <point x="513" y="1452"/>
+ <point x="653" y="1397"/>
+ <point x="653" y="1366" type="curve" smooth="yes"/>
+ <point x="653" y="1238"/>
+ <point x="531" y="801"/>
+ <point x="531" y="737" type="curve" smooth="yes"/>
+ <point x="531" y="701"/>
+ <point x="660" y="627"/>
+ <point x="660" y="603" type="curve" smooth="yes"/>
+ <point x="660" y="585"/>
+ <point x="496" y="511"/>
+ <point x="468" y="475" type="curve" smooth="yes"/>
+ <point x="439" y="438"/>
+ <point x="312" y="-121"/>
+ <point x="268" y="-167" type="curve" smooth="yes"/>
+ <point x="241" y="-194"/>
+ <point x="106" y="-242"/>
+ <point x="33" y="-265" type="curve"/>
+ <point x="39" y="-402" type="line"/>
+ <point x="150" y="-375"/>
+ <point x="324" y="-323"/>
+ <point x="375" y="-279" type="curve" smooth="yes"/>
+ <point x="465" y="-201"/>
+ <point x="608" y="410"/>
+ <point x="639" y="441" type="curve" smooth="yes"/>
+ <point x="675" y="476"/>
+ <point x="880" y="571"/>
+ <point x="880" y="607" type="curve" smooth="yes"/>
+ <point x="880" y="639"/>
+ <point x="719" y="740"/>
+ <point x="719" y="771" type="curve" smooth="yes"/>
+ <point x="719" y="839"/>
+ <point x="825" y="1259"/>
+ <point x="825" y="1425" type="curve" smooth="yes"/>
+ <point x="825" y="1453"/>
+ <point x="822" y="1474"/>
+ <point x="815" y="1485" type="curve" smooth="yes"/>
+ <point x="786" y="1529"/>
+ <point x="638" y="1581"/>
+ <point x="540" y="1607" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfcopyglyphs.ufo/glyphs/R_tP_aren.glif b/tests/reference/ufo/psfcopyglyphs.ufo/glyphs/R_tP_aren.glif
new file mode 100644
index 0000000..3950e09
--- /dev/null
+++ b/tests/reference/ufo/psfcopyglyphs.ufo/glyphs/R_tP_aren.glif
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="RtParen" format="2">
+ <advance width="775"/>
+ <unicode hex="0029"/>
+ <outline>
+ <contour>
+ <point x="467" y="1455" type="line"/>
+ <point x="578" y="1327"/>
+ <point x="628" y="1146"/>
+ <point x="628" y="946" type="curve" smooth="yes"/>
+ <point x="628" y="832"/>
+ <point x="612" y="713"/>
+ <point x="582" y="593" type="curve" smooth="yes"/>
+ <point x="497" y="252"/>
+ <point x="328" y="-8"/>
+ <point x="40" y="-260" type="curve"/>
+ <point x="99" y="-402" type="line"/>
+ <point x="444" y="-123"/>
+ <point x="673" y="194"/>
+ <point x="772" y="593" type="curve" smooth="yes"/>
+ <point x="804" y="719"/>
+ <point x="819" y="843"/>
+ <point x="819" y="959" type="curve" smooth="yes"/>
+ <point x="819" y="1236"/>
+ <point x="733" y="1472"/>
+ <point x="580" y="1607" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfcopyglyphs.ufo/glyphs/R_tS_qrB_rac.glif b/tests/reference/ufo/psfcopyglyphs.ufo/glyphs/R_tS_qrB_rac.glif
new file mode 100644
index 0000000..4c13a82
--- /dev/null
+++ b/tests/reference/ufo/psfcopyglyphs.ufo/glyphs/R_tS_qrB_rac.glif
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="RtSqrBrac" format="2">
+ <advance width="770"/>
+ <unicode hex="005D"/>
+ <outline>
+ <contour>
+ <point x="434" y="-402" type="line"/>
+ <point x="920" y="1568" type="line"/>
+ <point x="480" y="1568" type="line"/>
+ <point x="444" y="1421" type="line"/>
+ <point x="699" y="1421" type="line"/>
+ <point x="286" y="-255" type="line"/>
+ <point x="31" y="-255" type="line"/>
+ <point x="-6" y="-402" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfcopyglyphs.ufo/glyphs/S_emicolon.glif b/tests/reference/ufo/psfcopyglyphs.ufo/glyphs/S_emicolon.glif
new file mode 100644
index 0000000..be971ac
--- /dev/null
+++ b/tests/reference/ufo/psfcopyglyphs.ufo/glyphs/S_emicolon.glif
@@ -0,0 +1,38 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="Semicolon" format="2">
+ <advance width="630"/>
+ <unicode hex="003B"/>
+ <outline>
+ <contour>
+ <point x="314" y="758" type="curve" smooth="yes"/>
+ <point x="314" y="696"/>
+ <point x="365" y="642"/>
+ <point x="430" y="642" type="curve" smooth="yes"/>
+ <point x="514" y="642"/>
+ <point x="590" y="712"/>
+ <point x="590" y="792" type="curve" smooth="yes"/>
+ <point x="590" y="854"/>
+ <point x="540" y="907"/>
+ <point x="476" y="907" type="curve" smooth="yes"/>
+ <point x="393" y="907"/>
+ <point x="314" y="837"/>
+ </contour>
+ <contour>
+ <point x="137" y="49" type="line"/>
+ <point x="277" y="49" type="line"/>
+ <point x="252" y="-50"/>
+ <point x="145" y="-169"/>
+ <point x="73" y="-225" type="curve"/>
+ <point x="163" y="-265" type="line"/>
+ <point x="280" y="-175"/>
+ <point x="431" y="-28"/>
+ <point x="431" y="118" type="curve" smooth="yes"/>
+ <point x="431" y="193"/>
+ <point x="378" y="245"/>
+ <point x="311" y="245" type="curve" smooth="yes"/>
+ <point x="254" y="245"/>
+ <point x="190" y="209"/>
+ <point x="161" y="147" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfcopyglyphs.ufo/glyphs/S_olidus.glif b/tests/reference/ufo/psfcopyglyphs.ufo/glyphs/S_olidus.glif
new file mode 100644
index 0000000..589697b
--- /dev/null
+++ b/tests/reference/ufo/psfcopyglyphs.ufo/glyphs/S_olidus.glif
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="Solidus" format="2">
+ <advance width="980"/>
+ <unicode hex="002F"/>
+ <outline>
+ <contour>
+ <point x="1160" y="1568" type="line"/>
+ <point x="-119" y="-240" type="line"/>
+ <point x="50" y="-240" type="line"/>
+ <point x="1330" y="1568" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfcopyglyphs.ufo/glyphs/S_pace.glif b/tests/reference/ufo/psfcopyglyphs.ufo/glyphs/S_pace.glif
new file mode 100644
index 0000000..c49f0f2
--- /dev/null
+++ b/tests/reference/ufo/psfcopyglyphs.ufo/glyphs/S_pace.glif
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="Space" format="2">
+ <advance width="530"/>
+ <unicode hex="0020"/>
+ <outline/>
+</glyph>
diff --git a/tests/reference/ufo/psfcopyglyphs.ufo/glyphs/S_tar.glif b/tests/reference/ufo/psfcopyglyphs.ufo/glyphs/S_tar.glif
new file mode 100644
index 0000000..1fa9f6f
--- /dev/null
+++ b/tests/reference/ufo/psfcopyglyphs.ufo/glyphs/S_tar.glif
@@ -0,0 +1,51 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="Star" format="2">
+ <advance width="1028"/>
+ <unicode hex="3027"/>
+ <outline>
+ <contour>
+ <point x="560" y="1600" type="curve"/>
+ <point x="415" y="1600" type="line"/>
+ <point x="434" y="1467"/>
+ <point x="447" y="1387"/>
+ <point x="450" y="1300" type="curve"/>
+ <point x="376" y="1344"/>
+ <point x="309" y="1387"/>
+ <point x="200" y="1465" type="curve"/>
+ <point x="125" y="1340" type="line"/>
+ <point x="250" y="1290"/>
+ <point x="327" y="1261"/>
+ <point x="405" y="1220" type="curve"/>
+ <point x="329" y="1177"/>
+ <point x="256" y="1140"/>
+ <point x="135" y="1085" type="curve"/>
+ <point x="205" y="960" type="line"/>
+ <point x="310" y="1042"/>
+ <point x="377" y="1094"/>
+ <point x="450" y="1140" type="curve"/>
+ <point x="448" y="1055"/>
+ <point x="442" y="973"/>
+ <point x="430" y="840" type="curve"/>
+ <point x="570" y="840" type="line"/>
+ <point x="550" y="973"/>
+ <point x="544" y="1052"/>
+ <point x="540" y="1140" type="curve"/>
+ <point x="614" y="1095"/>
+ <point x="681" y="1053"/>
+ <point x="790" y="975" type="curve"/>
+ <point x="865" y="1100" type="line"/>
+ <point x="739" y="1149"/>
+ <point x="663" y="1179"/>
+ <point x="585" y="1220" type="curve"/>
+ <point x="661" y="1261"/>
+ <point x="733" y="1299"/>
+ <point x="855" y="1355" type="curve"/>
+ <point x="785" y="1480" type="line"/>
+ <point x="680" y="1396"/>
+ <point x="614" y="1348"/>
+ <point x="540" y="1300" type="curve"/>
+ <point x="541" y="1387"/>
+ <point x="547" y="1467"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfcopyglyphs.ufo/glyphs/T_ilde.glif b/tests/reference/ufo/psfcopyglyphs.ufo/glyphs/T_ilde.glif
new file mode 100644
index 0000000..bf260b8
--- /dev/null
+++ b/tests/reference/ufo/psfcopyglyphs.ufo/glyphs/T_ilde.glif
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="Tilde" format="2">
+ <advance width="1095"/>
+ <unicode hex="007E"/>
+ <outline>
+ <contour>
+ <point x="156" y="368" type="line"/>
+ <point x="173" y="416"/>
+ <point x="215" y="456"/>
+ <point x="293" y="456" type="curve" smooth="yes"/>
+ <point x="468" y="456"/>
+ <point x="643" y="353"/>
+ <point x="873" y="353" type="curve" smooth="yes"/>
+ <point x="1032" y="353"/>
+ <point x="1137" y="472"/>
+ <point x="1169" y="598" type="curve"/>
+ <point x="1064" y="598" type="line"/>
+ <point x="1045" y="553"/>
+ <point x="1002" y="500"/>
+ <point x="919" y="500" type="curve" smooth="yes"/>
+ <point x="683" y="500"/>
+ <point x="551" y="603"/>
+ <point x="330" y="603" type="curve" smooth="yes"/>
+ <point x="184" y="603"/>
+ <point x="81" y="487"/>
+ <point x="51" y="368" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfcopyglyphs.ufo/glyphs/V_ertL_ine.glif b/tests/reference/ufo/psfcopyglyphs.ufo/glyphs/V_ertL_ine.glif
new file mode 100644
index 0000000..445d622
--- /dev/null
+++ b/tests/reference/ufo/psfcopyglyphs.ufo/glyphs/V_ertL_ine.glif
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="VertLine" format="2">
+ <advance width="670"/>
+ <unicode hex="007C"/>
+ <outline>
+ <contour>
+ <point x="602" y="1578" type="line"/>
+ <point x="112" y="-392" type="line"/>
+ <point x="262" y="-392" type="line"/>
+ <point x="752" y="1578" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfcopyglyphs.ufo/glyphs/_notdef.glif b/tests/reference/ufo/psfcopyglyphs.ufo/glyphs/_notdef.glif
new file mode 100644
index 0000000..a3e9354
--- /dev/null
+++ b/tests/reference/ufo/psfcopyglyphs.ufo/glyphs/_notdef.glif
@@ -0,0 +1,18 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name=".notdef" format="2">
+ <advance width="1400"/>
+ <outline>
+ <contour>
+ <point x="100" y="0" type="line"/>
+ <point x="1300" y="0" type="line"/>
+ <point x="1300" y="1800" type="line"/>
+ <point x="100" y="1800" type="line"/>
+ </contour>
+ <contour>
+ <point x="150" y="1750" type="line"/>
+ <point x="1250" y="1750" type="line"/>
+ <point x="1250" y="50" type="line"/>
+ <point x="150" y="50" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfcopyglyphs.ufo/glyphs/_null.glif b/tests/reference/ufo/psfcopyglyphs.ufo/glyphs/_null.glif
new file mode 100644
index 0000000..0b9caa6
--- /dev/null
+++ b/tests/reference/ufo/psfcopyglyphs.ufo/glyphs/_null.glif
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name=".null" format="2">
+ <outline/>
+</glyph>
diff --git a/tests/reference/ufo/psfcopyglyphs.ufo/glyphs/contents.plist b/tests/reference/ufo/psfcopyglyphs.ufo/glyphs/contents.plist
new file mode 100644
index 0000000..733cd3b
--- /dev/null
+++ b/tests/reference/ufo/psfcopyglyphs.ufo/glyphs/contents.plist
@@ -0,0 +1,240 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+ <key>.notdef</key>
+ <string>_notdef.glif</string>
+ <key>.null</key>
+ <string>_null.glif</string>
+ <key>Ampergravel</key>
+ <string>A_mpergravel.glif</string>
+ <key>Ampersand</key>
+ <string>A_mpersand.glif</string>
+ <key>Apos</key>
+ <string>A_pos.glif</string>
+ <key>Asterisk</key>
+ <string>A_sterisk.glif</string>
+ <key>AtSgn</key>
+ <string>A_tS_gn.glif</string>
+ <key>CircumAccent</key>
+ <string>C_ircumA_ccent.glif</string>
+ <key>Colon</key>
+ <string>C_olon.glif</string>
+ <key>CombAcute</key>
+ <string>C_ombA_cute.glif</string>
+ <key>CombCircum</key>
+ <string>C_ombC_ircum.glif</string>
+ <key>CombDiaer</key>
+ <string>C_ombD_iaer.glif</string>
+ <key>CombGrave</key>
+ <string>C_ombG_rave.glif</string>
+ <key>CombRingAbv</key>
+ <string>C_ombR_ingA_bv.glif</string>
+ <key>CombTilde</key>
+ <string>C_ombT_ilde.glif</string>
+ <key>Comma</key>
+ <string>C_omma.glif</string>
+ <key>DigitEight</key>
+ <string>D_igitE_ight.glif</string>
+ <key>DigitFive</key>
+ <string>D_igitF_ive.glif</string>
+ <key>DigitFour</key>
+ <string>D_igitF_our.glif</string>
+ <key>DigitNine</key>
+ <string>D_igitN_ine.glif</string>
+ <key>DigitOne</key>
+ <string>D_igitO_ne.glif</string>
+ <key>DigitSeven</key>
+ <string>D_igitS_even.glif</string>
+ <key>DigitSix</key>
+ <string>D_igitS_ix.glif</string>
+ <key>DigitThree</key>
+ <string>D_igitT_hree.glif</string>
+ <key>DigitTwo</key>
+ <string>D_igitT_wo.glif</string>
+ <key>DigitZero</key>
+ <string>D_igitZ_ero.glif</string>
+ <key>DollarSgn</key>
+ <string>D_ollarS_gn.glif</string>
+ <key>DottedCirc</key>
+ <string>D_ottedC_irc.glif</string>
+ <key>EqSgn</key>
+ <string>E_qS_gn.glif</string>
+ <key>ExclamationMrk</key>
+ <string>E_xclamationM_rk.glif</string>
+ <key>FullStop</key>
+ <string>F_ullS_top.glif</string>
+ <key>Fullstart</key>
+ <string>F_ullstart.glif</string>
+ <key>GTSgn</key>
+ <string>G_T_S_gn.glif</string>
+ <key>GraveAccent</key>
+ <string>G_raveA_ccent.glif</string>
+ <key>Hyphen</key>
+ <string>H_yphen.glif</string>
+ <key>HyphenMinus</key>
+ <string>H_yphenM_inus.glif</string>
+ <key>Hyphen_Soft</key>
+ <string>H_yphen_S_oft.glif</string>
+ <key>LTSgn</key>
+ <string>L_T_S_gn.glif</string>
+ <key>LftCurlyBrac</key>
+ <string>L_ftC_urlyB_rac.glif</string>
+ <key>LftParen</key>
+ <string>L_ftP_aren.glif</string>
+ <key>LftSqrBrac</key>
+ <string>L_ftS_qrB_rac.glif</string>
+ <key>LowLine</key>
+ <string>L_owL_ine.glif</string>
+ <key>LtnCapA</key>
+ <string>L_tnC_apA_.glif</string>
+ <key>LtnCapA.alt</key>
+ <string>L_tnC_apA_.alt.glif</string>
+ <key>LtnCapADiaer</key>
+ <string>L_tnC_apA_D_iaer.glif</string>
+ <key>LtnCapB</key>
+ <string>L_tnC_apB_.glif</string>
+ <key>LtnCapC</key>
+ <string>L_tnC_apC_.glif</string>
+ <key>LtnCapD</key>
+ <string>L_tnC_apD_.glif</string>
+ <key>LtnCapE</key>
+ <string>L_tnC_apE_.glif</string>
+ <key>LtnCapF</key>
+ <string>L_tnC_apF_.glif</string>
+ <key>LtnCapG</key>
+ <string>L_tnC_apG_.glif</string>
+ <key>LtnCapH</key>
+ <string>L_tnC_apH_.glif</string>
+ <key>LtnCapI</key>
+ <string>L_tnC_apI_.glif</string>
+ <key>LtnCapJ</key>
+ <string>L_tnC_apJ_.glif</string>
+ <key>LtnCapK</key>
+ <string>L_tnC_apK_.glif</string>
+ <key>LtnCapL</key>
+ <string>L_tnC_apL_.glif</string>
+ <key>LtnCapM</key>
+ <string>L_tnC_apM_.glif</string>
+ <key>LtnCapN</key>
+ <string>L_tnC_apN_.glif</string>
+ <key>LtnCapO</key>
+ <string>L_tnC_apO_.glif</string>
+ <key>LtnCapP</key>
+ <string>L_tnC_apP_.glif</string>
+ <key>LtnCapQ</key>
+ <string>L_tnC_apQ_.glif</string>
+ <key>LtnCapR</key>
+ <string>L_tnC_apR_.glif</string>
+ <key>LtnCapS</key>
+ <string>L_tnC_apS_.glif</string>
+ <key>LtnCapT</key>
+ <string>L_tnC_apT_.glif</string>
+ <key>LtnCapU</key>
+ <string>L_tnC_apU_.glif</string>
+ <key>LtnCapV</key>
+ <string>L_tnC_apV_.glif</string>
+ <key>LtnCapW</key>
+ <string>L_tnC_apW_.glif</string>
+ <key>LtnCapX</key>
+ <string>L_tnC_apX_.glif</string>
+ <key>LtnCapY</key>
+ <string>L_tnC_apY_.glif</string>
+ <key>LtnSmA</key>
+ <string>L_tnS_mA_.glif</string>
+ <key>LtnSmAAcute</key>
+ <string>L_tnS_mA_A_cute.glif</string>
+ <key>LtnSmACircum</key>
+ <string>L_tnS_mA_C_ircum.glif</string>
+ <key>LtnSmADiaer</key>
+ <string>L_tnS_mA_D_iaer.glif</string>
+ <key>LtnSmAGrave</key>
+ <string>L_tnS_mA_G_rave.glif</string>
+ <key>LtnSmARingAbv</key>
+ <string>L_tnS_mA_R_ingA_bv.glif</string>
+ <key>LtnSmATilde</key>
+ <string>L_tnS_mA_T_ilde.glif</string>
+ <key>LtnSmB</key>
+ <string>L_tnS_mB_.glif</string>
+ <key>LtnSmC</key>
+ <string>L_tnS_mC_.glif</string>
+ <key>LtnSmD</key>
+ <string>L_tnS_mD_.glif</string>
+ <key>LtnSmE</key>
+ <string>L_tnS_mE_.glif</string>
+ <key>LtnSmF</key>
+ <string>L_tnS_mF_.glif</string>
+ <key>LtnSmG</key>
+ <string>L_tnS_mG_.glif</string>
+ <key>LtnSmH</key>
+ <string>L_tnS_mH_.glif</string>
+ <key>LtnSmI</key>
+ <string>L_tnS_mI_.glif</string>
+ <key>LtnSmJ</key>
+ <string>L_tnS_mJ_.glif</string>
+ <key>LtnSmK</key>
+ <string>L_tnS_mK_.glif</string>
+ <key>LtnSmL</key>
+ <string>L_tnS_mL_.glif</string>
+ <key>LtnSmM</key>
+ <string>L_tnS_mM_.glif</string>
+ <key>LtnSmN</key>
+ <string>L_tnS_mN_.glif</string>
+ <key>LtnSmO</key>
+ <string>L_tnS_mO_.glif</string>
+ <key>LtnSmP</key>
+ <string>L_tnS_mP_.glif</string>
+ <key>LtnSmQ</key>
+ <string>L_tnS_mQ_.glif</string>
+ <key>LtnSmR</key>
+ <string>L_tnS_mR_.glif</string>
+ <key>LtnSmS</key>
+ <string>L_tnS_mS_.glif</string>
+ <key>LtnSmT</key>
+ <string>L_tnS_mT_.glif</string>
+ <key>LtnSmU</key>
+ <string>L_tnS_mU_.glif</string>
+ <key>LtnSmV</key>
+ <string>L_tnS_mV_.glif</string>
+ <key>LtnSmW</key>
+ <string>L_tnS_mW_.glif</string>
+ <key>LtnSmX</key>
+ <string>L_tnS_mX_.glif</string>
+ <key>LtnSmY</key>
+ <string>L_tnS_mY_.glif</string>
+ <key>NonBreakingHyphen</key>
+ <string>N_onB_reakingH_yphen.glif</string>
+ <key>NumSgn</key>
+ <string>N_umS_gn.glif</string>
+ <key>PercentSgn</key>
+ <string>P_ercentS_gn.glif</string>
+ <key>PlusSgn</key>
+ <string>P_lusS_gn.glif</string>
+ <key>QstnMrk</key>
+ <string>Q_stnM_rk.glif</string>
+ <key>QuotMrk</key>
+ <string>Q_uotM_rk.glif</string>
+ <key>ReverseSolidus</key>
+ <string>R_everseS_olidus.glif</string>
+ <key>RtCurlyBrac</key>
+ <string>R_tC_urlyB_rac.glif</string>
+ <key>RtParen</key>
+ <string>R_tP_aren.glif</string>
+ <key>RtSqrBrac</key>
+ <string>R_tS_qrB_rac.glif</string>
+ <key>Semicolon</key>
+ <string>S_emicolon.glif</string>
+ <key>Solidus</key>
+ <string>S_olidus.glif</string>
+ <key>Space</key>
+ <string>S_pace.glif</string>
+ <key>Star</key>
+ <string>S_tar.glif</string>
+ <key>Tilde</key>
+ <string>T_ilde.glif</string>
+ <key>VertLine</key>
+ <string>V_ertL_ine.glif</string>
+ <key>nonmarkingreturn</key>
+ <string>nonmarkingreturn.glif</string>
+</dict>
+</plist>
diff --git a/tests/reference/ufo/psfcopyglyphs.ufo/glyphs/nonmarkingreturn.glif b/tests/reference/ufo/psfcopyglyphs.ufo/glyphs/nonmarkingreturn.glif
new file mode 100644
index 0000000..9a63f06
--- /dev/null
+++ b/tests/reference/ufo/psfcopyglyphs.ufo/glyphs/nonmarkingreturn.glif
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="nonmarkingreturn" format="2">
+ <advance width="1004"/>
+ <outline/>
+</glyph>
diff --git a/tests/reference/ufo/psfcopyglyphs.ufo/layercontents.plist b/tests/reference/ufo/psfcopyglyphs.ufo/layercontents.plist
new file mode 100644
index 0000000..42b7482
--- /dev/null
+++ b/tests/reference/ufo/psfcopyglyphs.ufo/layercontents.plist
@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<array>
+ <array>
+ <string>public.default</string>
+ <string>glyphs</string>
+ </array>
+</array>
+</plist>
diff --git a/tests/reference/ufo/psfcopyglyphs.ufo/lib.plist b/tests/reference/ufo/psfcopyglyphs.ufo/lib.plist
new file mode 100644
index 0000000..43413a8
--- /dev/null
+++ b/tests/reference/ufo/psfcopyglyphs.ufo/lib.plist
@@ -0,0 +1,538 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+ <key>com.schriftgestaltung.Glyphs.fontUserData</key>
+ <dict/>
+ <key>com.schriftgestaltung.appVersion</key>
+ <string>1161</string>
+ <key>com.schriftgestaltung.customName</key>
+ <string>Italic</string>
+ <key>com.schriftgestaltung.customParameter.GSFont.DisplayStrings</key>
+ <string/>
+ <key>com.schriftgestaltung.customParameter.GSFont.disablesAutomaticAlignment</key>
+ <true/>
+ <key>com.schriftgestaltung.customParameter.GSFont.disablesLastChange</key>
+ <true/>
+ <key>com.schriftgestaltung.customParameter.GSFont.useNiceNames</key>
+ <integer>0</integer>
+ <key>com.schriftgestaltung.customParameter.GSFontMaster.customValue</key>
+ <integer>0</integer>
+ <key>com.schriftgestaltung.customParameter.GSFontMaster.customValue1</key>
+ <integer>0</integer>
+ <key>com.schriftgestaltung.customParameter.GSFontMaster.customValue2</key>
+ <integer>0</integer>
+ <key>com.schriftgestaltung.customParameter.GSFontMaster.customValue3</key>
+ <integer>0</integer>
+ <key>com.schriftgestaltung.customParameter.GSFontMaster.iconName</key>
+ <string/>
+ <key>com.schriftgestaltung.customParameter.GSFontMaster.weightValue</key>
+ <integer>400</integer>
+ <key>com.schriftgestaltung.customParameter.GSFontMaster.widthValue</key>
+ <integer>100</integer>
+ <key>com.schriftgestaltung.disablesAutomaticAlignment</key>
+ <true/>
+ <key>com.schriftgestaltung.disablesLastChange</key>
+ <true/>
+ <key>com.schriftgestaltung.fontMasterOrder</key>
+ <integer>0</integer>
+ <key>com.schriftgestaltung.glyphOrder</key>
+ <array>
+ <string>.notdef</string>
+ <string>.null</string>
+ <string>nonmarkingreturn</string>
+ <string>Space</string>
+ <string>ExclamationMrk</string>
+ <string>QuotMrk</string>
+ <string>NumSgn</string>
+ <string>DollarSgn</string>
+ <string>PercentSgn</string>
+ <string>Ampersand</string>
+ <string>Apos</string>
+ <string>LftParen</string>
+ <string>RtParen</string>
+ <string>Asterisk</string>
+ <string>PlusSgn</string>
+ <string>Comma</string>
+ <string>HyphenMinus</string>
+ <string>FullStop</string>
+ <string>Solidus</string>
+ <string>DigitZero</string>
+ <string>DigitOne</string>
+ <string>DigitTwo</string>
+ <string>DigitThree</string>
+ <string>DigitFour</string>
+ <string>DigitFive</string>
+ <string>DigitSix</string>
+ <string>DigitSeven</string>
+ <string>DigitEight</string>
+ <string>DigitNine</string>
+ <string>Colon</string>
+ <string>Semicolon</string>
+ <string>LTSgn</string>
+ <string>EqSgn</string>
+ <string>GTSgn</string>
+ <string>QstnMrk</string>
+ <string>AtSgn</string>
+ <string>LtnCapA</string>
+ <string>LtnCapA.alt</string>
+ <string>LtnCapB</string>
+ <string>LtnCapC</string>
+ <string>LtnCapD</string>
+ <string>LtnCapE</string>
+ <string>LtnCapF</string>
+ <string>LtnCapG</string>
+ <string>LtnCapH</string>
+ <string>LtnCapI</string>
+ <string>LtnCapJ</string>
+ <string>LtnCapK</string>
+ <string>LtnCapL</string>
+ <string>LtnCapM</string>
+ <string>LtnCapN</string>
+ <string>LtnCapO</string>
+ <string>LtnCapP</string>
+ <string>LtnCapQ</string>
+ <string>LtnCapR</string>
+ <string>LtnCapS</string>
+ <string>LtnCapT</string>
+ <string>LtnCapU</string>
+ <string>LtnCapV</string>
+ <string>LtnCapW</string>
+ <string>LtnCapX</string>
+ <string>LtnCapY</string>
+ <string>LftSqrBrac</string>
+ <string>ReverseSolidus</string>
+ <string>RtSqrBrac</string>
+ <string>CircumAccent</string>
+ <string>LowLine</string>
+ <string>GraveAccent</string>
+ <string>LtnSmA</string>
+ <string>LtnSmB</string>
+ <string>LtnSmC</string>
+ <string>LtnSmD</string>
+ <string>LtnSmE</string>
+ <string>LtnSmF</string>
+ <string>LtnSmG</string>
+ <string>LtnSmH</string>
+ <string>LtnSmI</string>
+ <string>LtnSmJ</string>
+ <string>LtnSmK</string>
+ <string>LtnSmL</string>
+ <string>LtnSmM</string>
+ <string>LtnSmN</string>
+ <string>LtnSmO</string>
+ <string>LtnSmP</string>
+ <string>LtnSmQ</string>
+ <string>LtnSmR</string>
+ <string>LtnSmS</string>
+ <string>LtnSmT</string>
+ <string>LtnSmU</string>
+ <string>LtnSmV</string>
+ <string>LtnSmW</string>
+ <string>LtnSmX</string>
+ <string>LtnSmY</string>
+ <string>LftCurlyBrac</string>
+ <string>VertLine</string>
+ <string>RtCurlyBrac</string>
+ <string>Tilde</string>
+ <string>LtnCapADiaer</string>
+ <string>LtnSmAAcute</string>
+ <string>LtnSmAGrave</string>
+ <string>LtnSmACircum</string>
+ <string>LtnSmADiaer</string>
+ <string>LtnSmATilde</string>
+ <string>LtnSmARingAbv</string>
+ <string>DottedCirc</string>
+ <string>Hyphen</string>
+ <string>NonBreakingHyphen</string>
+ <string>Hyphen_Soft</string>
+ <string>CombAcute</string>
+ <string>CombGrave</string>
+ <string>CombCircum</string>
+ <string>CombTilde</string>
+ <string>CombDiaer</string>
+ <string>CombRingAbv</string>
+ </array>
+ <key>com.schriftgestaltung.keyboardIncrement</key>
+ <integer>1</integer>
+ <key>com.schriftgestaltung.weight</key>
+ <string>Regular</string>
+ <key>com.schriftgestaltung.weightValue</key>
+ <integer>400</integer>
+ <key>com.schriftgestaltung.width</key>
+ <string>Regular</string>
+ <key>com.schriftgestaltung.widthValue</key>
+ <integer>100</integer>
+ <key>org.sil.lcg.toneLetters</key>
+ <dict>
+ <key>contourWidth</key>
+ <integer>480</integer>
+ <key>dotSize</key>
+ <integer>180</integer>
+ <key>dotSpacing</key>
+ <integer>200</integer>
+ <key>glyphDepth</key>
+ <integer>-25</integer>
+ <key>glyphHeight</key>
+ <integer>1600</integer>
+ <key>italicAngle</key>
+ <integer>14</integer>
+ <key>marginDotLeft</key>
+ <integer>120</integer>
+ <key>marginDotRight</key>
+ <integer>160</integer>
+ <key>marginFlatLeft</key>
+ <integer>120</integer>
+ <key>marginFlatRight</key>
+ <integer>160</integer>
+ <key>marginPointLeft</key>
+ <integer>100</integer>
+ <key>marginPointRight</key>
+ <integer>140</integer>
+ <key>strokeThickness</key>
+ <integer>120</integer>
+ </dict>
+ <key>public.glyphOrder</key>
+ <array>
+ <string>.notdef</string>
+ <string>.null</string>
+ <string>nonmarkingreturn</string>
+ <string>Space</string>
+ <string>ExclamationMrk</string>
+ <string>QuotMrk</string>
+ <string>NumSgn</string>
+ <string>DollarSgn</string>
+ <string>PercentSgn</string>
+ <string>Ampersand</string>
+ <string>Apos</string>
+ <string>LftParen</string>
+ <string>RtParen</string>
+ <string>Asterisk</string>
+ <string>PlusSgn</string>
+ <string>Comma</string>
+ <string>HyphenMinus</string>
+ <string>FullStop</string>
+ <string>Solidus</string>
+ <string>DigitZero</string>
+ <string>DigitOne</string>
+ <string>DigitTwo</string>
+ <string>DigitThree</string>
+ <string>DigitFour</string>
+ <string>DigitFive</string>
+ <string>DigitSix</string>
+ <string>DigitSeven</string>
+ <string>DigitEight</string>
+ <string>DigitNine</string>
+ <string>Colon</string>
+ <string>Semicolon</string>
+ <string>LTSgn</string>
+ <string>EqSgn</string>
+ <string>GTSgn</string>
+ <string>QstnMrk</string>
+ <string>AtSgn</string>
+ <string>LtnCapA</string>
+ <string>LtnCapA.alt</string>
+ <string>LtnCapB</string>
+ <string>LtnCapC</string>
+ <string>LtnCapD</string>
+ <string>LtnCapE</string>
+ <string>LtnCapF</string>
+ <string>LtnCapG</string>
+ <string>LtnCapH</string>
+ <string>LtnCapI</string>
+ <string>LtnCapJ</string>
+ <string>LtnCapK</string>
+ <string>LtnCapL</string>
+ <string>LtnCapM</string>
+ <string>LtnCapN</string>
+ <string>LtnCapO</string>
+ <string>LtnCapP</string>
+ <string>LtnCapQ</string>
+ <string>LtnCapR</string>
+ <string>LtnCapS</string>
+ <string>LtnCapT</string>
+ <string>LtnCapU</string>
+ <string>LtnCapV</string>
+ <string>LtnCapW</string>
+ <string>LtnCapX</string>
+ <string>LtnCapY</string>
+ <string>LftSqrBrac</string>
+ <string>ReverseSolidus</string>
+ <string>RtSqrBrac</string>
+ <string>CircumAccent</string>
+ <string>LowLine</string>
+ <string>GraveAccent</string>
+ <string>LtnSmA</string>
+ <string>LtnSmB</string>
+ <string>LtnSmC</string>
+ <string>LtnSmD</string>
+ <string>LtnSmE</string>
+ <string>LtnSmF</string>
+ <string>LtnSmG</string>
+ <string>LtnSmH</string>
+ <string>LtnSmI</string>
+ <string>LtnSmJ</string>
+ <string>LtnSmK</string>
+ <string>LtnSmL</string>
+ <string>LtnSmM</string>
+ <string>LtnSmN</string>
+ <string>LtnSmO</string>
+ <string>LtnSmP</string>
+ <string>LtnSmQ</string>
+ <string>LtnSmR</string>
+ <string>LtnSmS</string>
+ <string>LtnSmT</string>
+ <string>LtnSmU</string>
+ <string>LtnSmV</string>
+ <string>LtnSmW</string>
+ <string>LtnSmX</string>
+ <string>LtnSmY</string>
+ <string>LftCurlyBrac</string>
+ <string>VertLine</string>
+ <string>RtCurlyBrac</string>
+ <string>Tilde</string>
+ <string>LtnCapADiaer</string>
+ <string>LtnSmAAcute</string>
+ <string>LtnSmAGrave</string>
+ <string>LtnSmACircum</string>
+ <string>LtnSmADiaer</string>
+ <string>LtnSmATilde</string>
+ <string>LtnSmARingAbv</string>
+ <string>DottedCirc</string>
+ <string>Hyphen</string>
+ <string>NonBreakingHyphen</string>
+ <string>Hyphen_Soft</string>
+ <string>CombAcute</string>
+ <string>CombGrave</string>
+ <string>CombCircum</string>
+ <string>CombTilde</string>
+ <string>CombDiaer</string>
+ <string>CombRingAbv</string>
+ </array>
+ <key>public.postscriptNames</key>
+ <dict>
+ <key>Ampersand</key>
+ <string>ampersand</string>
+ <key>Apos</key>
+ <string>quotesingle</string>
+ <key>Asterisk</key>
+ <string>asterisk</string>
+ <key>AtSgn</key>
+ <string>at</string>
+ <key>CircumAccent</key>
+ <string>asciicircum</string>
+ <key>Colon</key>
+ <string>colon</string>
+ <key>CombAcute</key>
+ <string>acutecomb</string>
+ <key>CombCircum</key>
+ <string>uni0302</string>
+ <key>CombDiaer</key>
+ <string>uni0308</string>
+ <key>CombGrave</key>
+ <string>gravecomb</string>
+ <key>CombRingAbv</key>
+ <string>uni030A</string>
+ <key>CombTilde</key>
+ <string>tildecomb</string>
+ <key>Comma</key>
+ <string>comma</string>
+ <key>DigitEight</key>
+ <string>eight</string>
+ <key>DigitFive</key>
+ <string>five</string>
+ <key>DigitFour</key>
+ <string>four</string>
+ <key>DigitNine</key>
+ <string>nine</string>
+ <key>DigitOne</key>
+ <string>one</string>
+ <key>DigitSeven</key>
+ <string>seven</string>
+ <key>DigitSix</key>
+ <string>six</string>
+ <key>DigitThree</key>
+ <string>three</string>
+ <key>DigitTwo</key>
+ <string>two</string>
+ <key>DigitZero</key>
+ <string>zero</string>
+ <key>DollarSgn</key>
+ <string>dollar</string>
+ <key>DottedCirc</key>
+ <string>uni25CC</string>
+ <key>EqSgn</key>
+ <string>equal</string>
+ <key>ExclamationMrk</key>
+ <string>exclam</string>
+ <key>FullStop</key>
+ <string>period</string>
+ <key>GTSgn</key>
+ <string>greater</string>
+ <key>GraveAccent</key>
+ <string>grave</string>
+ <key>Hyphen</key>
+ <string>uni2010</string>
+ <key>HyphenMinus</key>
+ <string>hyphen</string>
+ <key>Hyphen_Soft</key>
+ <string>uni00AD</string>
+ <key>LTSgn</key>
+ <string>less</string>
+ <key>LftCurlyBrac</key>
+ <string>braceleft</string>
+ <key>LftParen</key>
+ <string>parenleft</string>
+ <key>LftSqrBrac</key>
+ <string>bracketleft</string>
+ <key>LowLine</key>
+ <string>underscore</string>
+ <key>LtnCapA</key>
+ <string>A</string>
+ <key>LtnCapA.alt</key>
+ <string>A</string>
+ <key>LtnCapADiaer</key>
+ <string>Adieresis</string>
+ <key>LtnCapB</key>
+ <string>B</string>
+ <key>LtnCapC</key>
+ <string>C</string>
+ <key>LtnCapD</key>
+ <string>D</string>
+ <key>LtnCapE</key>
+ <string>E</string>
+ <key>LtnCapF</key>
+ <string>F</string>
+ <key>LtnCapG</key>
+ <string>G</string>
+ <key>LtnCapH</key>
+ <string>H</string>
+ <key>LtnCapI</key>
+ <string>I</string>
+ <key>LtnCapJ</key>
+ <string>J</string>
+ <key>LtnCapK</key>
+ <string>K</string>
+ <key>LtnCapL</key>
+ <string>L</string>
+ <key>LtnCapM</key>
+ <string>M</string>
+ <key>LtnCapN</key>
+ <string>N</string>
+ <key>LtnCapO</key>
+ <string>O</string>
+ <key>LtnCapP</key>
+ <string>P</string>
+ <key>LtnCapQ</key>
+ <string>Q</string>
+ <key>LtnCapR</key>
+ <string>R</string>
+ <key>LtnCapS</key>
+ <string>S</string>
+ <key>LtnCapT</key>
+ <string>T</string>
+ <key>LtnCapU</key>
+ <string>U</string>
+ <key>LtnCapV</key>
+ <string>V</string>
+ <key>LtnCapW</key>
+ <string>W</string>
+ <key>LtnCapX</key>
+ <string>X</string>
+ <key>LtnCapY</key>
+ <string>Y</string>
+ <key>LtnSmA</key>
+ <string>a</string>
+ <key>LtnSmAAcute</key>
+ <string>aacute</string>
+ <key>LtnSmACircum</key>
+ <string>acircumflex</string>
+ <key>LtnSmADiaer</key>
+ <string>adieresis</string>
+ <key>LtnSmAGrave</key>
+ <string>agrave</string>
+ <key>LtnSmARingAbv</key>
+ <string>aring</string>
+ <key>LtnSmATilde</key>
+ <string>atilde</string>
+ <key>LtnSmB</key>
+ <string>b</string>
+ <key>LtnSmC</key>
+ <string>c</string>
+ <key>LtnSmD</key>
+ <string>d</string>
+ <key>LtnSmE</key>
+ <string>e</string>
+ <key>LtnSmF</key>
+ <string>f</string>
+ <key>LtnSmG</key>
+ <string>g</string>
+ <key>LtnSmH</key>
+ <string>h</string>
+ <key>LtnSmI</key>
+ <string>i</string>
+ <key>LtnSmJ</key>
+ <string>j</string>
+ <key>LtnSmK</key>
+ <string>k</string>
+ <key>LtnSmL</key>
+ <string>l</string>
+ <key>LtnSmM</key>
+ <string>m</string>
+ <key>LtnSmN</key>
+ <string>n</string>
+ <key>LtnSmO</key>
+ <string>o</string>
+ <key>LtnSmP</key>
+ <string>p</string>
+ <key>LtnSmQ</key>
+ <string>q</string>
+ <key>LtnSmR</key>
+ <string>r</string>
+ <key>LtnSmS</key>
+ <string>s</string>
+ <key>LtnSmT</key>
+ <string>t</string>
+ <key>LtnSmU</key>
+ <string>u</string>
+ <key>LtnSmV</key>
+ <string>v</string>
+ <key>LtnSmW</key>
+ <string>w</string>
+ <key>LtnSmX</key>
+ <string>x</string>
+ <key>LtnSmY</key>
+ <string>y</string>
+ <key>NonBreakingHyphen</key>
+ <string>uni2011</string>
+ <key>NumSgn</key>
+ <string>numbersign</string>
+ <key>PercentSgn</key>
+ <string>percent</string>
+ <key>PlusSgn</key>
+ <string>plus</string>
+ <key>QstnMrk</key>
+ <string>question</string>
+ <key>QuotMrk</key>
+ <string>quotedbl</string>
+ <key>ReverseSolidus</key>
+ <string>backslash</string>
+ <key>RtCurlyBrac</key>
+ <string>braceright</string>
+ <key>RtParen</key>
+ <string>parenright</string>
+ <key>RtSqrBrac</key>
+ <string>bracketright</string>
+ <key>Semicolon</key>
+ <string>semicolon</string>
+ <key>Solidus</key>
+ <string>slash</string>
+ <key>Space</key>
+ <string>space</string>
+ <key>Tilde</key>
+ <string>asciitilde</string>
+ <key>VertLine</key>
+ <string>bar</string>
+ </dict>
+</dict>
+</plist>
diff --git a/tests/reference/ufo/psfcopyglyphs.ufo/metainfo.plist b/tests/reference/ufo/psfcopyglyphs.ufo/metainfo.plist
new file mode 100644
index 0000000..aa10c5c
--- /dev/null
+++ b/tests/reference/ufo/psfcopyglyphs.ufo/metainfo.plist
@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+ <key>creator</key>
+ <string>org.sil.scripts.pysilfont</string>
+ <key>formatVersion</key>
+ <integer>3</integer>
+</dict>
+</plist>
diff --git a/tests/reference/ufo/psfdeleteglyphs.lg b/tests/reference/ufo/psfdeleteglyphs.lg
new file mode 100644
index 0000000..b004fde
--- /dev/null
+++ b/tests/reference/ufo/psfdeleteglyphs.lg
@@ -0,0 +1,27 @@
+2021-06-29 14:42:19 Progress: Running: psfdeleteglyphs tests/input/font-psf-test/source/PsfTest-Regular.ufo -i tests/input/psfdeleteglyphs.txt -l local/testresults/ufo/psfdeleteglyphs.log -p loglevel=i -p scrlevel=w
+2021-06-29 14:42:19 Progress: Opening file for input: tests/input/psfdeleteglyphs.txt
+2021-06-29 14:42:19 Progress: Reading UFO: tests/input/font-psf-test/source/PsfTest-Regular.ufo
+2021-06-29 14:42:19 Info: Processing Glyph Layer 0: public.defaultglyphs
+2021-06-29 14:42:19 Progress: Checking fontinfo.plist metadata
+2021-06-29 14:42:19 Warning: note is present - it's use is discouraged
+2021-06-29 14:42:19 Warning: openTypeOS2FamilyClass would be removed from fontinfo Old value: [0, 0]
+2021-06-29 14:42:19 Info: Types: Old - list, New - NoneType
+2021-06-29 14:42:19 Warning: openTypeOS2Selection would be added New value: [7]
+2021-06-29 14:42:19 Info: Types: Old - NoneType, New - list
+2021-06-29 14:42:19 Progress: Checking lib.plist metadata
+2021-06-29 14:42:19 Warning: com.schriftgestaltung.disablesAutomaticAlignment would be deleted - obsolete key Old value: True
+2021-06-29 14:42:19 Info: Types: Old - bool, New - NoneType
+2021-06-29 14:42:19 Warning: com.schriftgestaltung.disablesLastChange would be deleted - obsolete key Old value: True
+2021-06-29 14:42:19 Info: Types: Old - bool, New - NoneType
+2021-06-29 14:42:19 Progress: Check & fix results:- Errors: 0, Changes to make: 4, Other warnings: 1
+2021-06-29 14:42:19 Info: Deleted glyphs:
+2021-06-29 14:42:19 Info: Apos deleted from: Default layer
+2021-06-29 14:42:19 Info: Apos is still in public.glyphOrder, public.postscriptNames, com.schriftgestaltung.glyphOrder
+2021-06-29 14:42:19 Info: Comma deleted from: Default layer
+2021-06-29 14:42:19 Info: Comma is still in public.glyphOrder, public.postscriptNames, com.schriftgestaltung.glyphOrder
+2021-06-29 14:42:19 Progress: 2 glyphs deleted. Set logging to I to see details
+2021-06-29 14:42:19 Warning: 2 of the deleted glyphs are still in some lib.plist entries.
+2021-06-29 14:42:19 Progress: Processing font for output
+2021-06-29 14:42:19 Progress: Output UFO already exists - reading for comparison
+2021-06-29 14:42:19 Progress: Writing font to local/testresults/ufo/psfdeleteglyphs.ufo
+2021-06-29 14:42:19 Info: Processing glyphs directory
diff --git a/tests/reference/ufo/psfdeleteglyphs.ufo/fontinfo.plist b/tests/reference/ufo/psfdeleteglyphs.ufo/fontinfo.plist
new file mode 100644
index 0000000..c151323
--- /dev/null
+++ b/tests/reference/ufo/psfdeleteglyphs.ufo/fontinfo.plist
@@ -0,0 +1,260 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+ <key>ascender</key>
+ <integer>2100</integer>
+ <key>capHeight</key>
+ <integer>1485</integer>
+ <key>copyright</key>
+ <string>Copyright (c) 2004-2021 SIL International</string>
+ <key>descender</key>
+ <integer>-550</integer>
+ <key>familyName</key>
+ <string>Psf Test</string>
+ <key>guidelines</key>
+ <array>
+ <dict>
+ <key>angle</key>
+ <integer>0</integer>
+ <key>x</key>
+ <integer>1084</integer>
+ <key>y</key>
+ <integer>1040</integer>
+ </dict>
+ <dict>
+ <key>y</key>
+ <integer>1250</integer>
+ </dict>
+ </array>
+ <key>note</key>
+ <string>Test note
+Second line
+
+Third line
+</string>
+ <key>openTypeHeadCreated</key>
+ <string>2021/01/29 10:05:04</string>
+ <key>openTypeHheaAscender</key>
+ <integer>2100</integer>
+ <key>openTypeHheaDescender</key>
+ <integer>-550</integer>
+ <key>openTypeHheaLineGap</key>
+ <integer>0</integer>
+ <key>openTypeNameDescription</key>
+ <string>Copyright (c) 2004-2021 SIL International</string>
+ <key>openTypeNameDesigner</key>
+ <string>Victor Gaultney, Annie Olsen, Julie Remington, Don Collingsworth, Eric Hays, Becca Hirsbrunner</string>
+ <key>openTypeNameDesignerURL</key>
+ <string>http://scripts.sil.org/</string>
+ <key>openTypeNameLicense</key>
+ <string>Copyright (c) 2004-2021 SIL International (http://www.sil.org/) with Reserved Font Names "Andika" and "SIL".
+
+This Font Software is licensed under the SIL Open Font License, Version 1.1. This license is copied below, and is also available with a FAQ at: http://scripts.sil.org/OFL
+
+
+-----------------------------------------------------------
+SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007
+-----------------------------------------------------------
+
+PREAMBLE
+The goals of the Open Font License (OFL) are to stimulate worldwide development of collaborative font projects, to support the font creation efforts of academic and linguistic communities, and to provide a free and open framework in which fonts may be shared and improved in partnership with others.
+
+The OFL allows the licensed fonts to be used, studied, modified and redistributed freely as long as they are not sold by themselves. The fonts, including any derivative works, can be bundled, embedded, redistributed and/or sold with any software provided that any reserved names are not used by derivative works. The fonts and derivatives, however, cannot be released under any other type of license. The requirement for fonts to remain under this license does not apply to any document created using the fonts or their derivatives.
+
+DEFINITIONS
+"Font Software" refers to the set of files released by the Copyright Holder(s) under this license and clearly marked as such. This may include source files, build scripts and documentation.
+
+"Reserved Font Name" refers to any names specified as such after the copyright statement(s).
+
+"Original Version" refers to the collection of Font Software components as distributed by the Copyright Holder(s).
+
+"Modified Version" refers to any derivative made by adding to, deleting, or substituting -- in part or in whole -- any of the components of the Original Version, by changing formats or by porting the Font Software to a new environment.
+
+"Author" refers to any designer, engineer, programmer, technical writer or other person who contributed to the Font Software.
+
+PERMISSION &amp; CONDITIONS
+Permission is hereby granted, free of charge, to any person obtaining a copy of the Font Software, to use, study, copy, merge, embed, modify, redistribute, and sell modified and unmodified copies of the Font Software, subject to the following conditions:
+
+1) Neither the Font Software nor any of its individual components, in Original or Modified Versions, may be sold by itself.
+
+2) Original or Modified Versions of the Font Software may be bundled, redistributed and/or sold with any software, provided that each copy contains the above copyright notice and this license. These can be included either as stand-alone text files, human-readable headers or in the appropriate machine-readable metadata fields within text or binary files as long as those fields can be easily viewed by the user.
+
+3) No Modified Version of the Font Software may use the Reserved Font Name(s) unless explicit written permission is granted by the corresponding Copyright Holder. This restriction only applies to the primary font name as presented to the users.
+
+4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font Software shall not be used to promote, endorse or advertise any Modified Version, except to acknowledge the contribution(s) of the Copyright Holder(s) and the Author(s) or with their explicit written permission.
+
+5) The Font Software, modified or unmodified, in part or in whole, must be distributed entirely under this license, and must not be distributed under any other license. The requirement for fonts to remain under this license does not apply to any document created using the Font Software.
+
+TERMINATION
+This license becomes null and void if any of the above conditions are not met.
+
+DISCLAIMER
+THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM OTHER DEALINGS IN THE FONT SOFTWARE.</string>
+ <key>openTypeNameLicenseURL</key>
+ <string>http://scripts.sil.org/OFL</string>
+ <key>openTypeNameManufacturer</key>
+ <string>SIL International</string>
+ <key>openTypeNameManufacturerURL</key>
+ <string>http://scripts.sil.org</string>
+ <key>openTypeNamePreferredFamilyName</key>
+ <string>Psf Test</string>
+ <key>openTypeNamePreferredSubfamilyName</key>
+ <string>Regular</string>
+ <key>openTypeNameUniqueID</key>
+ <string>SIL International: Psf Test Regular: 2022</string>
+ <key>openTypeNameVersion</key>
+ <string>Version 5.550</string>
+ <key>openTypeOS2CodePageRanges</key>
+ <array>
+ <integer>0</integer>
+ <integer>1</integer>
+ <integer>2</integer>
+ <integer>4</integer>
+ <integer>7</integer>
+ <integer>8</integer>
+ </array>
+ <key>openTypeOS2FamilyClass</key>
+ <array>
+ <integer>0</integer>
+ <integer>0</integer>
+ </array>
+ <key>openTypeOS2Panose</key>
+ <array>
+ <integer>2</integer>
+ <integer>0</integer>
+ <integer>0</integer>
+ <integer>0</integer>
+ <integer>0</integer>
+ <integer>0</integer>
+ <integer>0</integer>
+ <integer>0</integer>
+ <integer>0</integer>
+ <integer>0</integer>
+ </array>
+ <key>openTypeOS2StrikeoutPosition</key>
+ <integer>700</integer>
+ <key>openTypeOS2StrikeoutSize</key>
+ <integer>100</integer>
+ <key>openTypeOS2SubscriptXOffset</key>
+ <integer>0</integer>
+ <key>openTypeOS2SubscriptXSize</key>
+ <integer>1433</integer>
+ <key>openTypeOS2SubscriptYOffset</key>
+ <integer>286</integer>
+ <key>openTypeOS2SubscriptYSize</key>
+ <integer>1331</integer>
+ <key>openTypeOS2SuperscriptXOffset</key>
+ <integer>0</integer>
+ <key>openTypeOS2SuperscriptXSize</key>
+ <integer>1433</integer>
+ <key>openTypeOS2SuperscriptYOffset</key>
+ <integer>976</integer>
+ <key>openTypeOS2SuperscriptYSize</key>
+ <integer>1331</integer>
+ <key>openTypeOS2Type</key>
+ <array/>
+ <key>openTypeOS2TypoAscender</key>
+ <integer>2100</integer>
+ <key>openTypeOS2TypoDescender</key>
+ <integer>-550</integer>
+ <key>openTypeOS2TypoLineGap</key>
+ <integer>0</integer>
+ <key>openTypeOS2UnicodeRanges</key>
+ <array>
+ <integer>0</integer>
+ <integer>1</integer>
+ <integer>6</integer>
+ <integer>7</integer>
+ <integer>31</integer>
+ <integer>33</integer>
+ <integer>35</integer>
+ <integer>36</integer>
+ <integer>37</integer>
+ <integer>38</integer>
+ <integer>39</integer>
+ <integer>40</integer>
+ <integer>45</integer>
+ <integer>46</integer>
+ <integer>47</integer>
+ <integer>57</integer>
+ <integer>60</integer>
+ <integer>62</integer>
+ <integer>64</integer>
+ <integer>67</integer>
+ <integer>69</integer>
+ <integer>89</integer>
+ </array>
+ <key>openTypeOS2VendorID</key>
+ <string>SIL</string>
+ <key>openTypeOS2WeightClass</key>
+ <integer>400</integer>
+ <key>openTypeOS2WidthClass</key>
+ <integer>5</integer>
+ <key>openTypeOS2WinAscent</key>
+ <integer>2100</integer>
+ <key>openTypeOS2WinDescent</key>
+ <integer>550</integer>
+ <key>postscriptBlueValues</key>
+ <array>
+ <integer>-490</integer>
+ <integer>-490</integer>
+ <integer>-25</integer>
+ <integer>0</integer>
+ <integer>1020</integer>
+ <integer>1040</integer>
+ <integer>1455</integer>
+ <integer>1485</integer>
+ <integer>1600</integer>
+ <integer>1620</integer>
+ </array>
+ <key>postscriptFontName</key>
+ <string>PsfTest-Regular</string>
+ <key>postscriptFullName</key>
+ <string>Psf Test Regular</string>
+ <key>postscriptStemSnapH</key>
+ <array>
+ <integer>140</integer>
+ <integer>145</integer>
+ <integer>150</integer>
+ <integer>155</integer>
+ <integer>160</integer>
+ <integer>165</integer>
+ <integer>170</integer>
+ <integer>175</integer>
+ <integer>185</integer>
+ <integer>270</integer>
+ </array>
+ <key>postscriptStemSnapV</key>
+ <array>
+ <integer>165</integer>
+ <integer>180</integer>
+ <integer>185</integer>
+ <integer>190</integer>
+ <integer>195</integer>
+ <integer>200</integer>
+ <integer>205</integer>
+ <integer>270</integer>
+ </array>
+ <key>postscriptUnderlinePosition</key>
+ <integer>-110</integer>
+ <key>postscriptUnderlineThickness</key>
+ <integer>80</integer>
+ <key>styleMapFamilyName</key>
+ <string>Psf Test</string>
+ <key>styleMapStyleName</key>
+ <string>regular</string>
+ <key>styleName</key>
+ <string>Regular</string>
+ <key>trademark</key>
+ <string>Andika is a trademark of SIL International.</string>
+ <key>unitsPerEm</key>
+ <integer>2048</integer>
+ <key>versionMajor</key>
+ <integer>5</integer>
+ <key>versionMinor</key>
+ <integer>550</integer>
+ <key>xHeight</key>
+ <integer>1040</integer>
+</dict>
+</plist>
diff --git a/tests/reference/ufo/psfdeleteglyphs.ufo/glyphs/A_mpersand.glif b/tests/reference/ufo/psfdeleteglyphs.ufo/glyphs/A_mpersand.glif
new file mode 100644
index 0000000..c2cef04
--- /dev/null
+++ b/tests/reference/ufo/psfdeleteglyphs.ufo/glyphs/A_mpersand.glif
@@ -0,0 +1,61 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="Ampersand" format="2">
+ <advance width="1222"/>
+ <unicode hex="0026"/>
+ <outline>
+ <contour>
+ <point x="490" y="1485" type="curve" smooth="yes"/>
+ <point x="331" y="1485"/>
+ <point x="155" y="1412"/>
+ <point x="155" y="1190" type="curve" smooth="yes"/>
+ <point x="155" y="1010"/>
+ <point x="362" y="815"/>
+ <point x="535" y="570" type="curve" smooth="yes"/>
+ <point x="794" y="202"/>
+ <point x="973" y="-25"/>
+ <point x="1025" y="-25" type="curve" smooth="yes"/>
+ <point x="1060" y="-25"/>
+ <point x="1138" y="38"/>
+ <point x="1175" y="70" type="curve"/>
+ <point x="1080" y="110"/>
+ <point x="914" y="297"/>
+ <point x="650" y="680" type="curve" smooth="yes"/>
+ <point x="494" y="906"/>
+ <point x="315" y="1075"/>
+ <point x="315" y="1200" type="curve" smooth="yes"/>
+ <point x="315" y="1291"/>
+ <point x="398" y="1350"/>
+ <point x="475" y="1350" type="curve" smooth="yes"/>
+ <point x="555" y="1350"/>
+ <point x="630" y="1294"/>
+ <point x="630" y="1205" type="curve" smooth="yes"/>
+ <point x="630" y="1116"/>
+ <point x="523" y="1001"/>
+ <point x="350" y="840" type="curve" smooth="yes"/>
+ <point x="146" y="651"/>
+ <point x="55" y="527"/>
+ <point x="55" y="375" type="curve" smooth="yes"/>
+ <point x="55" y="151"/>
+ <point x="217" y="-25"/>
+ <point x="440" y="-25" type="curve" smooth="yes"/>
+ <point x="713" y="-25"/>
+ <point x="1002" y="274"/>
+ <point x="1080" y="435" type="curve"/>
+ <point x="975" y="570" type="line"/>
+ <point x="911" y="403"/>
+ <point x="630" y="150"/>
+ <point x="455" y="150" type="curve" smooth="yes"/>
+ <point x="310" y="150"/>
+ <point x="230" y="267"/>
+ <point x="230" y="380" type="curve" smooth="yes"/>
+ <point x="230" y="490"/>
+ <point x="296" y="587"/>
+ <point x="470" y="740" type="curve" smooth="yes"/>
+ <point x="651" y="899"/>
+ <point x="790" y="1068"/>
+ <point x="790" y="1200" type="curve" smooth="yes"/>
+ <point x="790" y="1382"/>
+ <point x="642" y="1485"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfdeleteglyphs.ufo/glyphs/A_sterisk.glif b/tests/reference/ufo/psfdeleteglyphs.ufo/glyphs/A_sterisk.glif
new file mode 100644
index 0000000..850d344
--- /dev/null
+++ b/tests/reference/ufo/psfdeleteglyphs.ufo/glyphs/A_sterisk.glif
@@ -0,0 +1,51 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="Asterisk" format="2">
+ <advance width="1028"/>
+ <unicode hex="002A"/>
+ <outline>
+ <contour>
+ <point x="560" y="1600" type="curve"/>
+ <point x="415" y="1600" type="line"/>
+ <point x="434" y="1467"/>
+ <point x="447" y="1387"/>
+ <point x="450" y="1300" type="curve"/>
+ <point x="376" y="1344"/>
+ <point x="309" y="1387"/>
+ <point x="200" y="1465" type="curve"/>
+ <point x="125" y="1340" type="line"/>
+ <point x="250" y="1290"/>
+ <point x="327" y="1261"/>
+ <point x="405" y="1220" type="curve"/>
+ <point x="329" y="1177"/>
+ <point x="256" y="1140"/>
+ <point x="135" y="1085" type="curve"/>
+ <point x="205" y="960" type="line"/>
+ <point x="310" y="1042"/>
+ <point x="377" y="1094"/>
+ <point x="450" y="1140" type="curve"/>
+ <point x="448" y="1055"/>
+ <point x="442" y="973"/>
+ <point x="430" y="840" type="curve"/>
+ <point x="570" y="840" type="line"/>
+ <point x="550" y="973"/>
+ <point x="544" y="1052"/>
+ <point x="540" y="1140" type="curve"/>
+ <point x="614" y="1095"/>
+ <point x="681" y="1053"/>
+ <point x="790" y="975" type="curve"/>
+ <point x="865" y="1100" type="line"/>
+ <point x="739" y="1149"/>
+ <point x="663" y="1179"/>
+ <point x="585" y="1220" type="curve"/>
+ <point x="661" y="1261"/>
+ <point x="733" y="1299"/>
+ <point x="855" y="1355" type="curve"/>
+ <point x="785" y="1480" type="line"/>
+ <point x="680" y="1396"/>
+ <point x="614" y="1348"/>
+ <point x="540" y="1300" type="curve"/>
+ <point x="541" y="1387"/>
+ <point x="547" y="1467"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfdeleteglyphs.ufo/glyphs/A_tS_gn.glif b/tests/reference/ufo/psfdeleteglyphs.ufo/glyphs/A_tS_gn.glif
new file mode 100644
index 0000000..681014d
--- /dev/null
+++ b/tests/reference/ufo/psfdeleteglyphs.ufo/glyphs/A_tS_gn.glif
@@ -0,0 +1,80 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="AtSgn" format="2">
+ <advance width="1702"/>
+ <unicode hex="0040"/>
+ <outline>
+ <contour>
+ <point x="1605" y="700" type="curve" smooth="yes"/>
+ <point x="1605" y="1127"/>
+ <point x="1307" y="1405"/>
+ <point x="880" y="1405" type="curve" smooth="yes"/>
+ <point x="465" y="1405"/>
+ <point x="95" y="1126"/>
+ <point x="95" y="575" type="curve" smooth="yes"/>
+ <point x="95" y="48"/>
+ <point x="464" y="-235"/>
+ <point x="855" y="-235" type="curve" smooth="yes"/>
+ <point x="990" y="-235"/>
+ <point x="1150" y="-188"/>
+ <point x="1250" y="-118" type="curve"/>
+ <point x="1145" y="-10" type="line"/>
+ <point x="1058" y="-70"/>
+ <point x="963" y="-95"/>
+ <point x="870" y="-95" type="curve" smooth="yes"/>
+ <point x="523" y="-95"/>
+ <point x="240" y="174"/>
+ <point x="240" y="605" type="curve" smooth="yes"/>
+ <point x="240" y="1003"/>
+ <point x="542" y="1270"/>
+ <point x="870" y="1270" type="curve" smooth="yes"/>
+ <point x="1263" y="1270"/>
+ <point x="1465" y="1002"/>
+ <point x="1465" y="670" type="curve" smooth="yes"/>
+ <point x="1465" y="432"/>
+ <point x="1348" y="315"/>
+ <point x="1280" y="315" type="curve" smooth="yes"/>
+ <point x="1221" y="315"/>
+ <point x="1175" y="410"/>
+ <point x="1175" y="630" type="curve" smooth="yes"/>
+ <point x="1175" y="980" type="line"/>
+ <point x="1088" y="1015"/>
+ <point x="961" y="1040"/>
+ <point x="880" y="1040" type="curve" smooth="yes"/>
+ <point x="716" y="1040"/>
+ <point x="613" y="971"/>
+ <point x="530" y="835" type="curve" smooth="yes"/>
+ <point x="483" y="756"/>
+ <point x="455" y="653"/>
+ <point x="455" y="530" type="curve" smooth="yes"/>
+ <point x="455" y="294"/>
+ <point x="601" y="183"/>
+ <point x="735" y="183" type="curve" smooth="yes"/>
+ <point x="852" y="183"/>
+ <point x="988" y="366"/>
+ <point x="1040" y="490" type="curve"/>
+ <point x="1050" y="322"/>
+ <point x="1128" y="180"/>
+ <point x="1250" y="180" type="curve" smooth="yes"/>
+ <point x="1425" y="180"/>
+ <point x="1605" y="368"/>
+ </contour>
+ <contour>
+ <point x="850" y="905" type="curve" smooth="yes"/>
+ <point x="924" y="905"/>
+ <point x="992" y="886"/>
+ <point x="1025" y="870" type="curve"/>
+ <point x="1025" y="720" type="line"/>
+ <point x="993" y="582"/>
+ <point x="838" y="320"/>
+ <point x="748" y="320" type="curve" smooth="yes"/>
+ <point x="676" y="320"/>
+ <point x="605" y="398"/>
+ <point x="605" y="575" type="curve" smooth="yes"/>
+ <point x="605" y="652"/>
+ <point x="621" y="731"/>
+ <point x="650" y="780" type="curve" smooth="yes"/>
+ <point x="706" y="876"/>
+ <point x="782" y="905"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfdeleteglyphs.ufo/glyphs/C_ircumA_ccent.glif b/tests/reference/ufo/psfdeleteglyphs.ufo/glyphs/C_ircumA_ccent.glif
new file mode 100644
index 0000000..60bd1cf
--- /dev/null
+++ b/tests/reference/ufo/psfdeleteglyphs.ufo/glyphs/C_ircumA_ccent.glif
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="CircumAccent" format="2">
+ <advance width="850"/>
+ <unicode hex="005E"/>
+ <outline>
+ <component base="CombCircum" xOffset="995"/>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfdeleteglyphs.ufo/glyphs/C_olon.glif b/tests/reference/ufo/psfdeleteglyphs.ufo/glyphs/C_olon.glif
new file mode 100644
index 0000000..3cfbbc1
--- /dev/null
+++ b/tests/reference/ufo/psfdeleteglyphs.ufo/glyphs/C_olon.glif
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="Colon" format="2">
+ <advance width="640"/>
+ <unicode hex="003A"/>
+ <outline>
+ <contour>
+ <point x="185" y="790" type="curve" smooth="yes"/>
+ <point x="185" y="716"/>
+ <point x="246" y="655"/>
+ <point x="320" y="655" type="curve" smooth="yes"/>
+ <point x="394" y="655"/>
+ <point x="455" y="716"/>
+ <point x="455" y="790" type="curve" smooth="yes"/>
+ <point x="455" y="864"/>
+ <point x="394" y="925"/>
+ <point x="320" y="925" type="curve" smooth="yes"/>
+ <point x="246" y="925"/>
+ <point x="185" y="864"/>
+ </contour>
+ <contour>
+ <point x="185" y="110" type="curve" smooth="yes"/>
+ <point x="185" y="36"/>
+ <point x="246" y="-25"/>
+ <point x="320" y="-25" type="curve" smooth="yes"/>
+ <point x="394" y="-25"/>
+ <point x="455" y="36"/>
+ <point x="455" y="110" type="curve" smooth="yes"/>
+ <point x="455" y="184"/>
+ <point x="394" y="245"/>
+ <point x="320" y="245" type="curve" smooth="yes"/>
+ <point x="246" y="245"/>
+ <point x="185" y="184"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfdeleteglyphs.ufo/glyphs/C_ombA_cute.glif b/tests/reference/ufo/psfdeleteglyphs.ufo/glyphs/C_ombA_cute.glif
new file mode 100644
index 0000000..bb13221
--- /dev/null
+++ b/tests/reference/ufo/psfdeleteglyphs.ufo/glyphs/C_ombA_cute.glif
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="CombAcute" format="2">
+ <unicode hex="0301"/>
+ <anchor x="-570" y="1635" name="U"/>
+ <anchor x="-570" y="1100" name="_U"/>
+ <outline>
+ <contour>
+ <point x="-400" y="1600" type="line"/>
+ <point x="-750" y="1170" type="line"/>
+ <point x="-590" y="1170" type="line"/>
+ <point x="-170" y="1600" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfdeleteglyphs.ufo/glyphs/C_ombC_ircum.glif b/tests/reference/ufo/psfdeleteglyphs.ufo/glyphs/C_ombC_ircum.glif
new file mode 100644
index 0000000..fa444ec
--- /dev/null
+++ b/tests/reference/ufo/psfdeleteglyphs.ufo/glyphs/C_ombC_ircum.glif
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="CombCircum" format="2">
+ <unicode hex="0302"/>
+ <anchor x="-570" y="1635" name="U"/>
+ <anchor x="-570" y="1100" name="_U"/>
+ <outline>
+ <contour>
+ <point x="-845" y="1170" type="line"/>
+ <point x="-570" y="1450" type="line"/>
+ <point x="-295" y="1170" type="line"/>
+ <point x="-145" y="1170" type="line"/>
+ <point x="-485" y="1600" type="line"/>
+ <point x="-655" y="1600" type="line"/>
+ <point x="-995" y="1170" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfdeleteglyphs.ufo/glyphs/C_ombD_iaer.glif b/tests/reference/ufo/psfdeleteglyphs.ufo/glyphs/C_ombD_iaer.glif
new file mode 100644
index 0000000..f7540ef
--- /dev/null
+++ b/tests/reference/ufo/psfdeleteglyphs.ufo/glyphs/C_ombD_iaer.glif
@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="CombDiaer" format="2">
+ <unicode hex="0308"/>
+ <anchor x="-570" y="1505" name="U"/>
+ <anchor x="-570" y="1100" name="_U"/>
+ <outline>
+ <contour>
+ <point x="-490" y="1345" type="curve" smooth="yes"/>
+ <point x="-490" y="1271"/>
+ <point x="-434" y="1210"/>
+ <point x="-360" y="1210" type="curve" smooth="yes"/>
+ <point x="-285" y="1210"/>
+ <point x="-230" y="1271"/>
+ <point x="-230" y="1345" type="curve" smooth="yes"/>
+ <point x="-230" y="1419"/>
+ <point x="-285" y="1480"/>
+ <point x="-360" y="1480" type="curve" smooth="yes"/>
+ <point x="-434" y="1480"/>
+ <point x="-490" y="1419"/>
+ </contour>
+ <contour>
+ <point x="-910" y="1345" type="curve" smooth="yes"/>
+ <point x="-910" y="1271"/>
+ <point x="-854" y="1210"/>
+ <point x="-780" y="1210" type="curve" smooth="yes"/>
+ <point x="-705" y="1210"/>
+ <point x="-650" y="1271"/>
+ <point x="-650" y="1345" type="curve" smooth="yes"/>
+ <point x="-650" y="1419"/>
+ <point x="-705" y="1480"/>
+ <point x="-780" y="1480" type="curve" smooth="yes"/>
+ <point x="-854" y="1480"/>
+ <point x="-910" y="1419"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfdeleteglyphs.ufo/glyphs/C_ombG_rave.glif b/tests/reference/ufo/psfdeleteglyphs.ufo/glyphs/C_ombG_rave.glif
new file mode 100644
index 0000000..c33b56a
--- /dev/null
+++ b/tests/reference/ufo/psfdeleteglyphs.ufo/glyphs/C_ombG_rave.glif
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="CombGrave" format="2">
+ <unicode hex="0300"/>
+ <anchor x="-550" y="1635" name="U"/>
+ <anchor x="-550" y="1100" name="_U"/>
+ <outline>
+ <contour>
+ <point x="-940" y="1600" type="line"/>
+ <point x="-520" y="1170" type="line"/>
+ <point x="-360" y="1170" type="line"/>
+ <point x="-710" y="1600" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfdeleteglyphs.ufo/glyphs/C_ombR_ingA_bv.glif b/tests/reference/ufo/psfdeleteglyphs.ufo/glyphs/C_ombR_ingA_bv.glif
new file mode 100644
index 0000000..b019e05
--- /dev/null
+++ b/tests/reference/ufo/psfdeleteglyphs.ufo/glyphs/C_ombR_ingA_bv.glif
@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="CombRingAbv" format="2">
+ <unicode hex="030A"/>
+ <anchor x="-570" y="1635" name="U"/>
+ <anchor x="-572" y="1100" name="_U"/>
+ <outline>
+ <contour>
+ <point x="-470" y="1385" type="curve" smooth="yes"/>
+ <point x="-470" y="1325"/>
+ <point x="-510" y="1285"/>
+ <point x="-570" y="1285" type="curve" smooth="yes"/>
+ <point x="-630" y="1285"/>
+ <point x="-670" y="1325"/>
+ <point x="-670" y="1385" type="curve" smooth="yes"/>
+ <point x="-670" y="1445"/>
+ <point x="-630" y="1485"/>
+ <point x="-570" y="1485" type="curve" smooth="yes"/>
+ <point x="-510" y="1485"/>
+ <point x="-470" y="1445"/>
+ </contour>
+ <contour>
+ <point x="-785" y="1385" type="curve" smooth="yes"/>
+ <point x="-785" y="1265"/>
+ <point x="-690" y="1170"/>
+ <point x="-570" y="1170" type="curve" smooth="yes"/>
+ <point x="-450" y="1170"/>
+ <point x="-355" y="1265"/>
+ <point x="-355" y="1385" type="curve" smooth="yes"/>
+ <point x="-355" y="1505"/>
+ <point x="-450" y="1600"/>
+ <point x="-570" y="1600" type="curve" smooth="yes"/>
+ <point x="-690" y="1600"/>
+ <point x="-785" y="1505"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfdeleteglyphs.ufo/glyphs/C_ombT_ilde.glif b/tests/reference/ufo/psfdeleteglyphs.ufo/glyphs/C_ombT_ilde.glif
new file mode 100644
index 0000000..88d5ca7
--- /dev/null
+++ b/tests/reference/ufo/psfdeleteglyphs.ufo/glyphs/C_ombT_ilde.glif
@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="CombTilde" format="2">
+ <unicode hex="0303"/>
+ <anchor x="-575" y="1475" name="U"/>
+ <anchor x="-575" y="1100" name="_U"/>
+ <outline>
+ <contour>
+ <point x="-820" y="1205" type="line"/>
+ <point x="-815" y="1254"/>
+ <point x="-784" y="1290"/>
+ <point x="-735" y="1290" type="curve" smooth="yes"/>
+ <point x="-698" y="1290"/>
+ <point x="-657" y="1274"/>
+ <point x="-580" y="1238" type="curve" smooth="yes"/>
+ <point x="-519" y="1210"/>
+ <point x="-466" y="1190"/>
+ <point x="-413" y="1190" type="curve" smooth="yes"/>
+ <point x="-290" y="1190"/>
+ <point x="-215" y="1312"/>
+ <point x="-215" y="1440" type="curve"/>
+ <point x="-320" y="1440" type="line"/>
+ <point x="-327" y="1394"/>
+ <point x="-358" y="1355"/>
+ <point x="-405" y="1355" type="curve" smooth="yes"/>
+ <point x="-447" y="1355"/>
+ <point x="-488" y="1374"/>
+ <point x="-560" y="1403" type="curve" smooth="yes"/>
+ <point x="-630" y="1431"/>
+ <point x="-677" y="1455"/>
+ <point x="-733" y="1455" type="curve" smooth="yes"/>
+ <point x="-852" y="1455"/>
+ <point x="-925" y="1327"/>
+ <point x="-925" y="1205" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfdeleteglyphs.ufo/glyphs/D_igitE_ight.glif b/tests/reference/ufo/psfdeleteglyphs.ufo/glyphs/D_igitE_ight.glif
new file mode 100644
index 0000000..b7e540a
--- /dev/null
+++ b/tests/reference/ufo/psfdeleteglyphs.ufo/glyphs/D_igitE_ight.glif
@@ -0,0 +1,63 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="DigitEight" format="2">
+ <advance width="1200"/>
+ <unicode hex="0038"/>
+ <anchor x="600" y="-100" name="L"/>
+ <anchor x="600" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="600" y="-25" type="curve" smooth="yes"/>
+ <point x="857" y="-25"/>
+ <point x="1110" y="134"/>
+ <point x="1110" y="405" type="curve" smooth="yes"/>
+ <point x="1110" y="611"/>
+ <point x="965" y="739"/>
+ <point x="855" y="795" type="curve"/>
+ <point x="933" y="844"/>
+ <point x="1050" y="923"/>
+ <point x="1050" y="1105" type="curve" smooth="yes"/>
+ <point x="1050" y="1350"/>
+ <point x="840" y="1485"/>
+ <point x="610" y="1485" type="curve" smooth="yes"/>
+ <point x="381" y="1485"/>
+ <point x="150" y="1350"/>
+ <point x="150" y="1105" type="curve" smooth="yes"/>
+ <point x="150" y="923"/>
+ <point x="272" y="838"/>
+ <point x="350" y="795" type="curve"/>
+ <point x="221" y="725"/>
+ <point x="90" y="611"/>
+ <point x="90" y="405" type="curve" smooth="yes"/>
+ <point x="90" y="134"/>
+ <point x="344" y="-25"/>
+ </contour>
+ <contour>
+ <point x="860" y="1105" type="curve" smooth="yes"/>
+ <point x="860" y="949"/>
+ <point x="743" y="865"/>
+ <point x="600" y="865" type="curve" smooth="yes"/>
+ <point x="457" y="865"/>
+ <point x="340" y="949"/>
+ <point x="340" y="1105" type="curve" smooth="yes"/>
+ <point x="340" y="1252"/>
+ <point x="457" y="1325"/>
+ <point x="600" y="1325" type="curve" smooth="yes"/>
+ <point x="743" y="1325"/>
+ <point x="860" y="1252"/>
+ </contour>
+ <contour>
+ <point x="910" y="425" type="curve" smooth="yes"/>
+ <point x="910" y="250"/>
+ <point x="778" y="145"/>
+ <point x="600" y="145" type="curve" smooth="yes"/>
+ <point x="420" y="145"/>
+ <point x="290" y="250"/>
+ <point x="290" y="425" type="curve" smooth="yes"/>
+ <point x="290" y="592"/>
+ <point x="420" y="710"/>
+ <point x="600" y="710" type="curve" smooth="yes"/>
+ <point x="778" y="710"/>
+ <point x="910" y="592"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfdeleteglyphs.ufo/glyphs/D_igitF_ive.glif b/tests/reference/ufo/psfdeleteglyphs.ufo/glyphs/D_igitF_ive.glif
new file mode 100644
index 0000000..cb2dd85
--- /dev/null
+++ b/tests/reference/ufo/psfdeleteglyphs.ufo/glyphs/D_igitF_ive.glif
@@ -0,0 +1,44 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="DigitFive" format="2">
+ <advance width="1200"/>
+ <unicode hex="0035"/>
+ <anchor x="600" y="-100" name="L"/>
+ <anchor x="600" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="195" y="685" type="line"/>
+ <point x="319" y="733"/>
+ <point x="404" y="750"/>
+ <point x="510" y="750" type="curve" smooth="yes"/>
+ <point x="670" y="750"/>
+ <point x="870" y="672"/>
+ <point x="870" y="470" type="curve" smooth="yes"/>
+ <point x="870" y="268"/>
+ <point x="730" y="155"/>
+ <point x="530" y="155" type="curve" smooth="yes"/>
+ <point x="390" y="155"/>
+ <point x="294" y="182"/>
+ <point x="160" y="290" type="curve"/>
+ <point x="130" y="80" type="line"/>
+ <point x="255" y="2"/>
+ <point x="363" y="-25"/>
+ <point x="518" y="-25" type="curve" smooth="yes"/>
+ <point x="831" y="-25"/>
+ <point x="1060" y="163"/>
+ <point x="1060" y="475" type="curve" smooth="yes"/>
+ <point x="1060" y="742"/>
+ <point x="832" y="930"/>
+ <point x="545" y="930" type="curve" smooth="yes"/>
+ <point x="472" y="930"/>
+ <point x="411" y="924"/>
+ <point x="380" y="920" type="curve"/>
+ <point x="380" y="1290" type="line"/>
+ <point x="765" y="1290" type="line"/>
+ <point x="849" y="1290"/>
+ <point x="925" y="1286"/>
+ <point x="1000" y="1270" type="curve"/>
+ <point x="1000" y="1460" type="line"/>
+ <point x="195" y="1460" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfdeleteglyphs.ufo/glyphs/D_igitF_our.glif b/tests/reference/ufo/psfdeleteglyphs.ufo/glyphs/D_igitF_our.glif
new file mode 100644
index 0000000..d9a5610
--- /dev/null
+++ b/tests/reference/ufo/psfdeleteglyphs.ufo/glyphs/D_igitF_our.glif
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="DigitFour" format="2">
+ <advance width="1200"/>
+ <unicode hex="0034"/>
+ <anchor x="607" y="-100" name="L"/>
+ <anchor x="607" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="1125" y="395" type="line"/>
+ <point x="1125" y="550" type="line"/>
+ <point x="935" y="550" type="line"/>
+ <point x="935" y="1480" type="line"/>
+ <point x="745" y="1480" type="line"/>
+ <point x="90" y="550" type="line"/>
+ <point x="90" y="395" type="line"/>
+ <point x="745" y="395" type="line"/>
+ <point x="745" y="0" type="line"/>
+ <point x="935" y="0" type="line"/>
+ <point x="935" y="395" type="line"/>
+ </contour>
+ <contour>
+ <point x="745" y="1230" type="line"/>
+ <point x="745" y="550" type="line"/>
+ <point x="263" y="550" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfdeleteglyphs.ufo/glyphs/D_igitN_ine.glif b/tests/reference/ufo/psfdeleteglyphs.ufo/glyphs/D_igitN_ine.glif
new file mode 100644
index 0000000..0ce656a
--- /dev/null
+++ b/tests/reference/ufo/psfdeleteglyphs.ufo/glyphs/D_igitN_ine.glif
@@ -0,0 +1,49 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="DigitNine" format="2">
+ <advance width="1200"/>
+ <unicode hex="0039"/>
+ <anchor x="600" y="-100" name="L"/>
+ <anchor x="600" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="193" y="65" type="line"/>
+ <point x="297" y="-5"/>
+ <point x="383" y="-25"/>
+ <point x="501" y="-25" type="curve" smooth="yes"/>
+ <point x="976" y="-25"/>
+ <point x="1114" y="411"/>
+ <point x="1114" y="780" type="curve" smooth="yes"/>
+ <point x="1114" y="1198"/>
+ <point x="926" y="1485"/>
+ <point x="616" y="1485" type="curve" smooth="yes"/>
+ <point x="349" y="1485"/>
+ <point x="112" y="1306"/>
+ <point x="112" y="1002" type="curve" smooth="yes"/>
+ <point x="112" y="773"/>
+ <point x="281" y="586"/>
+ <point x="559" y="586" type="curve" smooth="yes"/>
+ <point x="750" y="586"/>
+ <point x="922" y="717"/>
+ <point x="1019" y="878" type="curve"/>
+ <point x="948" y="961" type="line"/>
+ <point x="874" y="847"/>
+ <point x="738" y="760"/>
+ <point x="583" y="760" type="curve" smooth="yes"/>
+ <point x="424" y="760"/>
+ <point x="306" y="860"/>
+ <point x="306" y="1036" type="curve" smooth="yes"/>
+ <point x="306" y="1196"/>
+ <point x="420" y="1310"/>
+ <point x="596" y="1310" type="curve" smooth="yes"/>
+ <point x="837" y="1310"/>
+ <point x="919" y="1065"/>
+ <point x="919" y="813" type="curve" smooth="yes"/>
+ <point x="919" y="326"/>
+ <point x="748" y="150"/>
+ <point x="511" y="150" type="curve" smooth="yes"/>
+ <point x="415" y="150"/>
+ <point x="323" y="174"/>
+ <point x="237" y="260" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfdeleteglyphs.ufo/glyphs/D_igitO_ne.glif b/tests/reference/ufo/psfdeleteglyphs.ufo/glyphs/D_igitO_ne.glif
new file mode 100644
index 0000000..42c7708
--- /dev/null
+++ b/tests/reference/ufo/psfdeleteglyphs.ufo/glyphs/D_igitO_ne.glif
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="DigitOne" format="2">
+ <advance width="1200"/>
+ <unicode hex="0031"/>
+ <anchor x="600" y="-100" name="L"/>
+ <anchor x="600" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="535" y="170" type="line"/>
+ <point x="220" y="170" type="line"/>
+ <point x="220" y="0" type="line"/>
+ <point x="1040" y="0" type="line"/>
+ <point x="1040" y="170" type="line"/>
+ <point x="725" y="170" type="line"/>
+ <point x="725" y="1480" type="line"/>
+ <point x="555" y="1480" type="line"/>
+ <point x="210" y="1268" type="line"/>
+ <point x="235" y="1088" type="line"/>
+ <point x="535" y="1260" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfdeleteglyphs.ufo/glyphs/D_igitS_even.glif b/tests/reference/ufo/psfdeleteglyphs.ufo/glyphs/D_igitS_even.glif
new file mode 100644
index 0000000..c9ca97e
--- /dev/null
+++ b/tests/reference/ufo/psfdeleteglyphs.ufo/glyphs/D_igitS_even.glif
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="DigitSeven" format="2">
+ <advance width="1200"/>
+ <unicode hex="0037"/>
+ <anchor x="600" y="-100" name="L"/>
+ <anchor x="600" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="460" y="0" type="line"/>
+ <point x="589" y="459"/>
+ <point x="794" y="895"/>
+ <point x="1090" y="1300" type="curve"/>
+ <point x="1090" y="1460" type="line"/>
+ <point x="100" y="1460" type="line"/>
+ <point x="100" y="1275" type="line"/>
+ <point x="176" y="1291"/>
+ <point x="292" y="1295"/>
+ <point x="480" y="1295" type="curve" smooth="yes"/>
+ <point x="870" y="1295" type="line"/>
+ <point x="612" y="912"/>
+ <point x="439" y="566"/>
+ <point x="275" y="0" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfdeleteglyphs.ufo/glyphs/D_igitS_ix.glif b/tests/reference/ufo/psfdeleteglyphs.ufo/glyphs/D_igitS_ix.glif
new file mode 100644
index 0000000..ec0acdb
--- /dev/null
+++ b/tests/reference/ufo/psfdeleteglyphs.ufo/glyphs/D_igitS_ix.glif
@@ -0,0 +1,49 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="DigitSix" format="2">
+ <advance width="1200"/>
+ <unicode hex="0036"/>
+ <anchor x="600" y="-100" name="L"/>
+ <anchor x="600" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="1033" y="1395" type="line"/>
+ <point x="929" y="1465"/>
+ <point x="843" y="1485"/>
+ <point x="725" y="1485" type="curve" smooth="yes"/>
+ <point x="250" y="1485"/>
+ <point x="110" y="1049"/>
+ <point x="110" y="680" type="curve" smooth="yes"/>
+ <point x="110" y="242"/>
+ <point x="290" y="-25"/>
+ <point x="600" y="-25" type="curve" smooth="yes"/>
+ <point x="907" y="-25"/>
+ <point x="1115" y="166"/>
+ <point x="1115" y="470" type="curve" smooth="yes"/>
+ <point x="1115" y="719"/>
+ <point x="943" y="895"/>
+ <point x="665" y="895" type="curve" smooth="yes"/>
+ <point x="474" y="895"/>
+ <point x="328" y="780"/>
+ <point x="215" y="625" type="curve"/>
+ <point x="280" y="550" type="line"/>
+ <point x="362" y="653"/>
+ <point x="490" y="720"/>
+ <point x="645" y="720" type="curve" smooth="yes"/>
+ <point x="824" y="720"/>
+ <point x="920" y="611"/>
+ <point x="920" y="435" type="curve" smooth="yes"/>
+ <point x="920" y="275"/>
+ <point x="806" y="150"/>
+ <point x="630" y="150" type="curve" smooth="yes"/>
+ <point x="409" y="150"/>
+ <point x="305" y="393"/>
+ <point x="305" y="645" type="curve" smooth="yes"/>
+ <point x="305" y="1132"/>
+ <point x="478" y="1310"/>
+ <point x="715" y="1310" type="curve" smooth="yes"/>
+ <point x="811" y="1310"/>
+ <point x="903" y="1286"/>
+ <point x="989" y="1200" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfdeleteglyphs.ufo/glyphs/D_igitT_hree.glif b/tests/reference/ufo/psfdeleteglyphs.ufo/glyphs/D_igitT_hree.glif
new file mode 100644
index 0000000..3242c12
--- /dev/null
+++ b/tests/reference/ufo/psfdeleteglyphs.ufo/glyphs/D_igitT_hree.glif
@@ -0,0 +1,52 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="DigitThree" format="2">
+ <advance width="1200"/>
+ <unicode hex="0033"/>
+ <anchor x="600" y="-100" name="L"/>
+ <anchor x="600" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="410" y="870" type="line"/>
+ <point x="410" y="700" type="line"/>
+ <point x="480" y="700" type="line"/>
+ <point x="716" y="700"/>
+ <point x="895" y="588"/>
+ <point x="895" y="425" type="curve" smooth="yes"/>
+ <point x="895" y="241"/>
+ <point x="718" y="150"/>
+ <point x="565" y="150" type="curve" smooth="yes"/>
+ <point x="385" y="150"/>
+ <point x="244" y="232"/>
+ <point x="135" y="355" type="curve"/>
+ <point x="110" y="140" type="line"/>
+ <point x="215" y="42"/>
+ <point x="368" y="-25"/>
+ <point x="545" y="-25" type="curve" smooth="yes"/>
+ <point x="834" y="-25"/>
+ <point x="1090" y="170"/>
+ <point x="1090" y="405" type="curve" smooth="yes"/>
+ <point x="1090" y="672"/>
+ <point x="862" y="776"/>
+ <point x="720" y="800" type="curve"/>
+ <point x="862" y="829"/>
+ <point x="1040" y="957"/>
+ <point x="1040" y="1140" type="curve" smooth="yes"/>
+ <point x="1040" y="1354"/>
+ <point x="828" y="1485"/>
+ <point x="580" y="1485" type="curve"/>
+ <point x="413" y="1485"/>
+ <point x="260" y="1416"/>
+ <point x="180" y="1325" type="curve"/>
+ <point x="215" y="1155" type="line"/>
+ <point x="328" y="1271"/>
+ <point x="436" y="1310"/>
+ <point x="590" y="1310" type="curve" smooth="yes"/>
+ <point x="711" y="1310"/>
+ <point x="850" y="1250"/>
+ <point x="850" y="1115" type="curve" smooth="yes"/>
+ <point x="850" y="991"/>
+ <point x="679" y="870"/>
+ <point x="480" y="870" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfdeleteglyphs.ufo/glyphs/D_igitT_wo.glif b/tests/reference/ufo/psfdeleteglyphs.ufo/glyphs/D_igitT_wo.glif
new file mode 100644
index 0000000..c179477
--- /dev/null
+++ b/tests/reference/ufo/psfdeleteglyphs.ufo/glyphs/D_igitT_wo.glif
@@ -0,0 +1,37 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="DigitTwo" format="2">
+ <advance width="1200"/>
+ <unicode hex="0032"/>
+ <anchor x="600" y="-100" name="L"/>
+ <anchor x="560" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="1080" y="180" type="line"/>
+ <point x="1000" y="166"/>
+ <point x="842" y="165"/>
+ <point x="645" y="165" type="curve" smooth="yes"/>
+ <point x="390" y="165" type="line"/>
+ <point x="609" y="352"/>
+ <point x="1010" y="729"/>
+ <point x="1010" y="1065" type="curve" smooth="yes"/>
+ <point x="1010" y="1323"/>
+ <point x="800" y="1485"/>
+ <point x="560" y="1485" type="curve" smooth="yes"/>
+ <point x="391" y="1485"/>
+ <point x="206" y="1402"/>
+ <point x="125" y="1290" type="curve"/>
+ <point x="170" y="1120" type="line"/>
+ <point x="259" y="1228"/>
+ <point x="402" y="1305"/>
+ <point x="525" y="1305" type="curve" smooth="yes"/>
+ <point x="668" y="1305"/>
+ <point x="810" y="1233"/>
+ <point x="810" y="1045" type="curve" smooth="yes"/>
+ <point x="810" y="768"/>
+ <point x="391" y="365"/>
+ <point x="120" y="170" type="curve"/>
+ <point x="120" y="0" type="line"/>
+ <point x="1080" y="0" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfdeleteglyphs.ufo/glyphs/D_igitZ_ero.glif b/tests/reference/ufo/psfdeleteglyphs.ufo/glyphs/D_igitZ_ero.glif
new file mode 100644
index 0000000..d976d0f
--- /dev/null
+++ b/tests/reference/ufo/psfdeleteglyphs.ufo/glyphs/D_igitZ_ero.glif
@@ -0,0 +1,37 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="DigitZero" format="2">
+ <advance width="1200"/>
+ <unicode hex="0030"/>
+ <anchor x="605" y="-100" name="L"/>
+ <anchor x="605" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="910" y="715" type="curve" smooth="yes"/>
+ <point x="910" y="308"/>
+ <point x="792" y="145"/>
+ <point x="600" y="145" type="curve" smooth="yes"/>
+ <point x="402" y="145"/>
+ <point x="290" y="305"/>
+ <point x="290" y="745" type="curve" smooth="yes"/>
+ <point x="290" y="1153"/>
+ <point x="407" y="1315"/>
+ <point x="600" y="1315" type="curve" smooth="yes"/>
+ <point x="802" y="1315"/>
+ <point x="910" y="1156"/>
+ </contour>
+ <contour>
+ <point x="1110" y="740" type="curve" smooth="yes"/>
+ <point x="1110" y="1286"/>
+ <point x="900" y="1485"/>
+ <point x="610" y="1485" type="curve" smooth="yes"/>
+ <point x="321" y="1485"/>
+ <point x="90" y="1283"/>
+ <point x="90" y="720" type="curve" smooth="yes"/>
+ <point x="90" y="155"/>
+ <point x="301" y="-25"/>
+ <point x="590" y="-25" type="curve" smooth="yes"/>
+ <point x="881" y="-25"/>
+ <point x="1110" y="151"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfdeleteglyphs.ufo/glyphs/D_ollarS_gn.glif b/tests/reference/ufo/psfdeleteglyphs.ufo/glyphs/D_ollarS_gn.glif
new file mode 100644
index 0000000..52136d8
--- /dev/null
+++ b/tests/reference/ufo/psfdeleteglyphs.ufo/glyphs/D_ollarS_gn.glif
@@ -0,0 +1,53 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="DollarSgn" format="2">
+ <advance width="1200"/>
+ <unicode hex="0024"/>
+ <outline>
+ <contour>
+ <point x="553" y="1600" type="line"/>
+ <point x="553" y="-220" type="line"/>
+ <point x="683" y="-220" type="line"/>
+ <point x="683" y="1600" type="line"/>
+ </contour>
+ <contour>
+ <point x="986" y="1306" type="line"/>
+ <point x="866" y="1364"/>
+ <point x="764" y="1389"/>
+ <point x="623" y="1389" type="curve" smooth="yes"/>
+ <point x="317" y="1389"/>
+ <point x="190" y="1173"/>
+ <point x="190" y="1017" type="curve" smooth="yes"/>
+ <point x="190" y="860"/>
+ <point x="253" y="739"/>
+ <point x="540" y="653" type="curve" smooth="yes"/>
+ <point x="827" y="567"/>
+ <point x="871" y="492"/>
+ <point x="871" y="396" type="curve" smooth="yes"/>
+ <point x="871" y="247"/>
+ <point x="734" y="161"/>
+ <point x="586" y="161" type="curve" smooth="yes"/>
+ <point x="450" y="161"/>
+ <point x="316" y="207"/>
+ <point x="195" y="313" type="curve"/>
+ <point x="153" y="124" type="line"/>
+ <point x="247" y="52"/>
+ <point x="408" y="0"/>
+ <point x="586" y="0" type="curve" smooth="yes"/>
+ <point x="837" y="0"/>
+ <point x="1046" y="167"/>
+ <point x="1046" y="414" type="curve" smooth="yes"/>
+ <point x="1046" y="613"/>
+ <point x="912" y="725"/>
+ <point x="669" y="796" type="curve" smooth="yes"/>
+ <point x="406" y="873"/>
+ <point x="365" y="929"/>
+ <point x="365" y="1030" type="curve" smooth="yes"/>
+ <point x="365" y="1132"/>
+ <point x="466" y="1228"/>
+ <point x="613" y="1228" type="curve" smooth="yes"/>
+ <point x="731" y="1228"/>
+ <point x="818" y="1200"/>
+ <point x="949" y="1127" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfdeleteglyphs.ufo/glyphs/D_ottedC_irc.glif b/tests/reference/ufo/psfdeleteglyphs.ufo/glyphs/D_ottedC_irc.glif
new file mode 100644
index 0000000..4cf5cb4
--- /dev/null
+++ b/tests/reference/ufo/psfdeleteglyphs.ufo/glyphs/D_ottedC_irc.glif
@@ -0,0 +1,235 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="DottedCirc" format="2">
+ <advance width="1106"/>
+ <unicode hex="25CC"/>
+ <anchor x="553" y="0" name="H"/>
+ <anchor x="553" y="-100" name="L"/>
+ <anchor x="810" y="0" name="O"/>
+ <anchor x="553" y="1000" name="U"/>
+ <outline>
+ <contour>
+ <point x="443" y="837" type="curve" smooth="yes"/>
+ <point x="443" y="864"/>
+ <point x="423" y="885"/>
+ <point x="398" y="885" type="curve" smooth="yes"/>
+ <point x="371" y="885"/>
+ <point x="348" y="861"/>
+ <point x="348" y="837" type="curve" smooth="yes"/>
+ <point x="348" y="809"/>
+ <point x="372" y="789"/>
+ <point x="398" y="789" type="curve" smooth="yes"/>
+ <point x="425" y="789"/>
+ <point x="443" y="812"/>
+ </contour>
+ <contour>
+ <point x="758" y="79" type="curve" smooth="yes"/>
+ <point x="758" y="106"/>
+ <point x="736" y="127"/>
+ <point x="710" y="127" type="curve" smooth="yes"/>
+ <point x="685" y="127"/>
+ <point x="662" y="103"/>
+ <point x="662" y="80" type="curve" smooth="yes"/>
+ <point x="662" y="52"/>
+ <point x="686" y="31"/>
+ <point x="710" y="31" type="curve" smooth="yes"/>
+ <point x="737" y="31"/>
+ <point x="758" y="55"/>
+ </contour>
+ <contour>
+ <point x="310" y="749" type="curve" smooth="yes"/>
+ <point x="310" y="775"/>
+ <point x="288" y="796"/>
+ <point x="263" y="796" type="curve" smooth="yes"/>
+ <point x="238" y="796"/>
+ <point x="215" y="774"/>
+ <point x="215" y="747" type="curve" smooth="yes"/>
+ <point x="215" y="722"/>
+ <point x="236" y="701"/>
+ <point x="263" y="701" type="curve" smooth="yes"/>
+ <point x="291" y="701"/>
+ <point x="310" y="720"/>
+ </contour>
+ <contour>
+ <point x="891" y="168" type="curve" smooth="yes"/>
+ <point x="891" y="197"/>
+ <point x="870" y="215"/>
+ <point x="843" y="215" type="curve" smooth="yes"/>
+ <point x="817" y="215"/>
+ <point x="795" y="194"/>
+ <point x="795" y="168" type="curve" smooth="yes"/>
+ <point x="795" y="143"/>
+ <point x="816" y="121"/>
+ <point x="843" y="121" type="curve" smooth="yes"/>
+ <point x="871" y="121"/>
+ <point x="891" y="143"/>
+ </contour>
+ <contour>
+ <point x="222" y="613" type="curve" smooth="yes"/>
+ <point x="222" y="640"/>
+ <point x="199" y="663"/>
+ <point x="173" y="663" type="curve" smooth="yes"/>
+ <point x="149" y="663"/>
+ <point x="126" y="642"/>
+ <point x="126" y="615" type="curve" smooth="yes"/>
+ <point x="126" y="591"/>
+ <point x="145" y="567"/>
+ <point x="173" y="567" type="curve" smooth="yes"/>
+ <point x="197" y="567"/>
+ <point x="222" y="587"/>
+ </contour>
+ <contour>
+ <point x="980" y="301" type="curve" smooth="yes"/>
+ <point x="980" y="327"/>
+ <point x="957" y="348"/>
+ <point x="932" y="348" type="curve" smooth="yes"/>
+ <point x="908" y="348"/>
+ <point x="884" y="332"/>
+ <point x="884" y="301" type="curve" smooth="yes"/>
+ <point x="884" y="277"/>
+ <point x="902" y="254"/>
+ <point x="932" y="254" type="curve" smooth="yes"/>
+ <point x="957" y="254"/>
+ <point x="980" y="274"/>
+ </contour>
+ <contour>
+ <point x="191" y="459" type="curve" smooth="yes"/>
+ <point x="191" y="484"/>
+ <point x="168" y="505"/>
+ <point x="143" y="505" type="curve" smooth="yes"/>
+ <point x="116" y="505"/>
+ <point x="95" y="484"/>
+ <point x="95" y="458" type="curve" smooth="yes"/>
+ <point x="95" y="433"/>
+ <point x="115" y="410"/>
+ <point x="143" y="410" type="curve" smooth="yes"/>
+ <point x="167" y="410"/>
+ <point x="191" y="432"/>
+ </contour>
+ <contour>
+ <point x="1011" y="458" type="curve" smooth="yes"/>
+ <point x="1011" y="484"/>
+ <point x="990" y="506"/>
+ <point x="964" y="506" type="curve" smooth="yes"/>
+ <point x="940" y="506"/>
+ <point x="915" y="484"/>
+ <point x="915" y="457" type="curve" smooth="yes"/>
+ <point x="915" y="433"/>
+ <point x="936" y="411"/>
+ <point x="964" y="411" type="curve" smooth="yes"/>
+ <point x="990" y="411"/>
+ <point x="1011" y="433"/>
+ </contour>
+ <contour>
+ <point x="222" y="302" type="curve" smooth="yes"/>
+ <point x="222" y="328"/>
+ <point x="200" y="348"/>
+ <point x="174" y="348" type="curve" smooth="yes"/>
+ <point x="147" y="348"/>
+ <point x="126" y="326"/>
+ <point x="126" y="302" type="curve" smooth="yes"/>
+ <point x="126" y="275"/>
+ <point x="149" y="253"/>
+ <point x="174" y="253" type="curve" smooth="yes"/>
+ <point x="201" y="253"/>
+ <point x="222" y="277"/>
+ </contour>
+ <contour>
+ <point x="980" y="615" type="curve" smooth="yes"/>
+ <point x="980" y="642"/>
+ <point x="955" y="663"/>
+ <point x="931" y="663" type="curve" smooth="yes"/>
+ <point x="904" y="663"/>
+ <point x="885" y="638"/>
+ <point x="885" y="614" type="curve" smooth="yes"/>
+ <point x="885" y="588"/>
+ <point x="907" y="567"/>
+ <point x="931" y="567" type="curve" smooth="yes"/>
+ <point x="959" y="567"/>
+ <point x="980" y="591"/>
+ </contour>
+ <contour>
+ <point x="310" y="168" type="curve" smooth="yes"/>
+ <point x="310" y="195"/>
+ <point x="291" y="215"/>
+ <point x="263" y="215" type="curve" smooth="yes"/>
+ <point x="238" y="215"/>
+ <point x="215" y="190"/>
+ <point x="215" y="168" type="curve" smooth="yes"/>
+ <point x="215" y="143"/>
+ <point x="238" y="120"/>
+ <point x="263" y="120" type="curve" smooth="yes"/>
+ <point x="289" y="120"/>
+ <point x="310" y="143"/>
+ </contour>
+ <contour>
+ <point x="890" y="748" type="curve" smooth="yes"/>
+ <point x="890" y="774"/>
+ <point x="870" y="796"/>
+ <point x="843" y="796" type="curve" smooth="yes"/>
+ <point x="815" y="796"/>
+ <point x="796" y="773"/>
+ <point x="796" y="748" type="curve" smooth="yes"/>
+ <point x="796" y="724"/>
+ <point x="817" y="700"/>
+ <point x="843" y="700" type="curve" smooth="yes"/>
+ <point x="869" y="700"/>
+ <point x="890" y="722"/>
+ </contour>
+ <contour>
+ <point x="444" y="78" type="curve" smooth="yes"/>
+ <point x="444" y="102"/>
+ <point x="423" y="126"/>
+ <point x="396" y="126" type="curve" smooth="yes"/>
+ <point x="370" y="126"/>
+ <point x="348" y="102"/>
+ <point x="348" y="78" type="curve" smooth="yes"/>
+ <point x="348" y="55"/>
+ <point x="370" y="31"/>
+ <point x="396" y="31" type="curve" smooth="yes"/>
+ <point x="420" y="31"/>
+ <point x="444" y="51"/>
+ </contour>
+ <contour>
+ <point x="758" y="836" type="curve" smooth="yes"/>
+ <point x="758" y="861"/>
+ <point x="737" y="885"/>
+ <point x="710" y="885" type="curve" smooth="yes"/>
+ <point x="684" y="885"/>
+ <point x="663" y="862"/>
+ <point x="663" y="838" type="curve" smooth="yes"/>
+ <point x="663" y="814"/>
+ <point x="683" y="789"/>
+ <point x="710" y="789" type="curve" smooth="yes"/>
+ <point x="734" y="789"/>
+ <point x="758" y="809"/>
+ </contour>
+ <contour>
+ <point x="601" y="47" type="curve" smooth="yes"/>
+ <point x="601" y="73"/>
+ <point x="579" y="95"/>
+ <point x="553" y="95" type="curve" smooth="yes"/>
+ <point x="527" y="95"/>
+ <point x="506" y="73"/>
+ <point x="506" y="47" type="curve" smooth="yes"/>
+ <point x="506" y="21"/>
+ <point x="527" y="0"/>
+ <point x="553" y="0" type="curve" smooth="yes"/>
+ <point x="579" y="0"/>
+ <point x="601" y="21"/>
+ </contour>
+ <contour>
+ <point x="601" y="868" type="curve" smooth="yes"/>
+ <point x="601" y="894"/>
+ <point x="579" y="916"/>
+ <point x="553" y="916" type="curve" smooth="yes"/>
+ <point x="527" y="916"/>
+ <point x="506" y="894"/>
+ <point x="506" y="868" type="curve" smooth="yes"/>
+ <point x="506" y="842"/>
+ <point x="527" y="821"/>
+ <point x="553" y="821" type="curve" smooth="yes"/>
+ <point x="579" y="821"/>
+ <point x="601" y="842"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfdeleteglyphs.ufo/glyphs/E_qS_gn.glif b/tests/reference/ufo/psfdeleteglyphs.ufo/glyphs/E_qS_gn.glif
new file mode 100644
index 0000000..1315ffa
--- /dev/null
+++ b/tests/reference/ufo/psfdeleteglyphs.ufo/glyphs/E_qS_gn.glif
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="EqSgn" format="2">
+ <advance width="1200"/>
+ <unicode hex="003D"/>
+ <outline>
+ <contour>
+ <point x="120" y="480" type="line"/>
+ <point x="1080" y="480" type="line"/>
+ <point x="1080" y="630" type="line"/>
+ <point x="120" y="630" type="line"/>
+ </contour>
+ <contour>
+ <point x="120" y="830" type="line"/>
+ <point x="1080" y="830" type="line"/>
+ <point x="1080" y="980" type="line"/>
+ <point x="120" y="980" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfdeleteglyphs.ufo/glyphs/E_xclamationM_rk.glif b/tests/reference/ufo/psfdeleteglyphs.ufo/glyphs/E_xclamationM_rk.glif
new file mode 100644
index 0000000..e683644
--- /dev/null
+++ b/tests/reference/ufo/psfdeleteglyphs.ufo/glyphs/E_xclamationM_rk.glif
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="ExclamationMrk" format="2">
+ <advance width="764"/>
+ <unicode hex="0021"/>
+ <outline>
+ <contour>
+ <point x="450" y="440" type="line"/>
+ <point x="456" y="730"/>
+ <point x="451" y="1076"/>
+ <point x="490" y="1510" type="curve"/>
+ <point x="235" y="1510" type="line"/>
+ <point x="273" y="1076"/>
+ <point x="268" y="730"/>
+ <point x="275" y="440" type="curve"/>
+ </contour>
+ <contour>
+ <point x="225" y="110" type="curve" smooth="yes"/>
+ <point x="225" y="36"/>
+ <point x="286" y="-25"/>
+ <point x="360" y="-25" type="curve" smooth="yes"/>
+ <point x="434" y="-25"/>
+ <point x="495" y="36"/>
+ <point x="495" y="110" type="curve" smooth="yes"/>
+ <point x="495" y="184"/>
+ <point x="434" y="245"/>
+ <point x="360" y="245" type="curve" smooth="yes"/>
+ <point x="286" y="245"/>
+ <point x="225" y="184"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfdeleteglyphs.ufo/glyphs/F_ullS_top.glif b/tests/reference/ufo/psfdeleteglyphs.ufo/glyphs/F_ullS_top.glif
new file mode 100644
index 0000000..9f3a3f0
--- /dev/null
+++ b/tests/reference/ufo/psfdeleteglyphs.ufo/glyphs/F_ullS_top.glif
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="FullStop" format="2">
+ <advance width="640"/>
+ <unicode hex="002E"/>
+ <outline>
+ <contour>
+ <point x="185" y="110" type="curve" smooth="yes"/>
+ <point x="185" y="36"/>
+ <point x="246" y="-25"/>
+ <point x="320" y="-25" type="curve" smooth="yes"/>
+ <point x="394" y="-25"/>
+ <point x="455" y="36"/>
+ <point x="455" y="110" type="curve" smooth="yes"/>
+ <point x="455" y="184"/>
+ <point x="394" y="245"/>
+ <point x="320" y="245" type="curve" smooth="yes"/>
+ <point x="246" y="245"/>
+ <point x="185" y="184"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfdeleteglyphs.ufo/glyphs/G_T_S_gn.glif b/tests/reference/ufo/psfdeleteglyphs.ufo/glyphs/G_T_S_gn.glif
new file mode 100644
index 0000000..c591997
--- /dev/null
+++ b/tests/reference/ufo/psfdeleteglyphs.ufo/glyphs/G_T_S_gn.glif
@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="GTSgn" format="2">
+ <advance width="1200"/>
+ <unicode hex="003E"/>
+ <outline>
+ <contour>
+ <point x="120" y="1035" type="line"/>
+ <point x="910" y="730" type="line"/>
+ <point x="120" y="425" type="line"/>
+ <point x="120" y="245" type="line"/>
+ <point x="1100" y="645" type="line"/>
+ <point x="1100" y="815" type="line"/>
+ <point x="120" y="1215" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfdeleteglyphs.ufo/glyphs/G_raveA_ccent.glif b/tests/reference/ufo/psfdeleteglyphs.ufo/glyphs/G_raveA_ccent.glif
new file mode 100644
index 0000000..a0a0004
--- /dev/null
+++ b/tests/reference/ufo/psfdeleteglyphs.ufo/glyphs/G_raveA_ccent.glif
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="GraveAccent" format="2">
+ <advance width="580"/>
+ <unicode hex="0060"/>
+ <outline>
+ <component base="CombGrave" xOffset="940"/>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfdeleteglyphs.ufo/glyphs/H_yphen.glif b/tests/reference/ufo/psfdeleteglyphs.ufo/glyphs/H_yphen.glif
new file mode 100644
index 0000000..fabf6ce
--- /dev/null
+++ b/tests/reference/ufo/psfdeleteglyphs.ufo/glyphs/H_yphen.glif
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="Hyphen" format="2">
+ <advance width="860"/>
+ <unicode hex="2010"/>
+ <anchor x="430" y="1100" name="U"/>
+ <outline>
+ <contour>
+ <point x="80" y="555" type="line"/>
+ <point x="780" y="555" type="line"/>
+ <point x="780" y="705" type="line"/>
+ <point x="80" y="705" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfdeleteglyphs.ufo/glyphs/H_yphenM_inus.glif b/tests/reference/ufo/psfdeleteglyphs.ufo/glyphs/H_yphenM_inus.glif
new file mode 100644
index 0000000..bc3f4eb
--- /dev/null
+++ b/tests/reference/ufo/psfdeleteglyphs.ufo/glyphs/H_yphenM_inus.glif
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="HyphenMinus" format="2">
+ <advance width="860"/>
+ <unicode hex="002D"/>
+ <anchor x="430" y="1100" name="U"/>
+ <outline>
+ <contour>
+ <point x="80" y="555" type="line"/>
+ <point x="780" y="555" type="line"/>
+ <point x="780" y="705" type="line"/>
+ <point x="80" y="705" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfdeleteglyphs.ufo/glyphs/H_yphen_S_oft.glif b/tests/reference/ufo/psfdeleteglyphs.ufo/glyphs/H_yphen_S_oft.glif
new file mode 100644
index 0000000..293b653
--- /dev/null
+++ b/tests/reference/ufo/psfdeleteglyphs.ufo/glyphs/H_yphen_S_oft.glif
@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="Hyphen_Soft" format="2">
+ <advance width="860"/>
+ <unicode hex="00AD"/>
+ <anchor x="430" y="1100" name="U"/>
+ <outline>
+ <component base="HyphenMinus"/>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfdeleteglyphs.ufo/glyphs/L_T_S_gn.glif b/tests/reference/ufo/psfdeleteglyphs.ufo/glyphs/L_T_S_gn.glif
new file mode 100644
index 0000000..db9ae78
--- /dev/null
+++ b/tests/reference/ufo/psfdeleteglyphs.ufo/glyphs/L_T_S_gn.glif
@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LTSgn" format="2">
+ <advance width="1200"/>
+ <unicode hex="003C"/>
+ <outline>
+ <contour>
+ <point x="1080" y="425" type="line"/>
+ <point x="290" y="730" type="line"/>
+ <point x="1080" y="1035" type="line"/>
+ <point x="1080" y="1215" type="line"/>
+ <point x="100" y="815" type="line"/>
+ <point x="100" y="645" type="line"/>
+ <point x="1080" y="245" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfdeleteglyphs.ufo/glyphs/L_ftC_urlyB_rac.glif b/tests/reference/ufo/psfdeleteglyphs.ufo/glyphs/L_ftC_urlyB_rac.glif
new file mode 100644
index 0000000..bc7ef03
--- /dev/null
+++ b/tests/reference/ufo/psfdeleteglyphs.ufo/glyphs/L_ftC_urlyB_rac.glif
@@ -0,0 +1,47 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LftCurlyBrac" format="2">
+ <advance width="1000"/>
+ <unicode hex="007B"/>
+ <outline>
+ <contour>
+ <point x="210" y="615" type="curve" smooth="yes"/>
+ <point x="210" y="583"/>
+ <point x="383" y="486"/>
+ <point x="410" y="450" type="curve" smooth="yes"/>
+ <point x="434" y="418"/>
+ <point x="424" y="-205"/>
+ <point x="495" y="-285" type="curve" smooth="yes"/>
+ <point x="535" y="-330"/>
+ <point x="696" y="-383"/>
+ <point x="800" y="-410" type="curve"/>
+ <point x="840" y="-270" type="line"/>
+ <point x="773" y="-247"/>
+ <point x="650" y="-198"/>
+ <point x="630" y="-170" type="curve" smooth="yes"/>
+ <point x="597" y="-123"/>
+ <point x="610" y="447"/>
+ <point x="590" y="485" type="curve" smooth="yes"/>
+ <point x="571" y="521"/>
+ <point x="434" y="593"/>
+ <point x="430" y="615" type="curve"/>
+ <point x="434" y="637"/>
+ <point x="571" y="709"/>
+ <point x="590" y="745" type="curve" smooth="yes"/>
+ <point x="610" y="783"/>
+ <point x="597" y="1353"/>
+ <point x="630" y="1400" type="curve" smooth="yes"/>
+ <point x="650" y="1428"/>
+ <point x="773" y="1477"/>
+ <point x="840" y="1500" type="curve"/>
+ <point x="800" y="1640" type="line"/>
+ <point x="696" y="1613"/>
+ <point x="535" y="1560"/>
+ <point x="495" y="1515" type="curve" smooth="yes"/>
+ <point x="424" y="1435"/>
+ <point x="434" y="812"/>
+ <point x="410" y="780" type="curve" smooth="yes"/>
+ <point x="383" y="744"/>
+ <point x="210" y="647"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfdeleteglyphs.ufo/glyphs/L_ftP_aren.glif b/tests/reference/ufo/psfdeleteglyphs.ufo/glyphs/L_ftP_aren.glif
new file mode 100644
index 0000000..a4b9814
--- /dev/null
+++ b/tests/reference/ufo/psfdeleteglyphs.ufo/glyphs/L_ftP_aren.glif
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LftParen" format="2">
+ <advance width="795"/>
+ <unicode hex="0028"/>
+ <outline>
+ <contour>
+ <point x="115" y="625" type="curve" smooth="yes"/>
+ <point x="115" y="218"/>
+ <point x="260" y="-125"/>
+ <point x="535" y="-410" type="curve"/>
+ <point x="630" y="-265" type="line"/>
+ <point x="395" y="-8"/>
+ <point x="305" y="278"/>
+ <point x="305" y="625" type="curve" smooth="yes"/>
+ <point x="305" y="982"/>
+ <point x="395" y="1280"/>
+ <point x="630" y="1485" type="curve"/>
+ <point x="555" y="1640" type="line"/>
+ <point x="290" y="1444"/>
+ <point x="115" y="1062"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfdeleteglyphs.ufo/glyphs/L_ftS_qrB_rac.glif b/tests/reference/ufo/psfdeleteglyphs.ufo/glyphs/L_ftS_qrB_rac.glif
new file mode 100644
index 0000000..e97ed98
--- /dev/null
+++ b/tests/reference/ufo/psfdeleteglyphs.ufo/glyphs/L_ftS_qrB_rac.glif
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LftSqrBrac" format="2">
+ <advance width="790"/>
+ <unicode hex="005B"/>
+ <outline>
+ <contour>
+ <point x="640" y="-410" type="line"/>
+ <point x="640" y="-260" type="line"/>
+ <point x="385" y="-260" type="line"/>
+ <point x="385" y="1450" type="line"/>
+ <point x="640" y="1450" type="line"/>
+ <point x="640" y="1600" type="line"/>
+ <point x="200" y="1600" type="line"/>
+ <point x="200" y="-410" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfdeleteglyphs.ufo/glyphs/L_owL_ine.glif b/tests/reference/ufo/psfdeleteglyphs.ufo/glyphs/L_owL_ine.glif
new file mode 100644
index 0000000..2fc71eb
--- /dev/null
+++ b/tests/reference/ufo/psfdeleteglyphs.ufo/glyphs/L_owL_ine.glif
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LowLine" format="2">
+ <advance width="1274"/>
+ <unicode hex="005F"/>
+ <outline>
+ <contour>
+ <point x="0" y="-320" type="line"/>
+ <point x="1274" y="-320" type="line"/>
+ <point x="1274" y="-170" type="line"/>
+ <point x="0" y="-170" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfdeleteglyphs.ufo/glyphs/L_tnC_apA_.alt.glif b/tests/reference/ufo/psfdeleteglyphs.ufo/glyphs/L_tnC_apA_.alt.glif
new file mode 100644
index 0000000..fbdfff2
--- /dev/null
+++ b/tests/reference/ufo/psfdeleteglyphs.ufo/glyphs/L_tnC_apA_.alt.glif
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnCapA.alt" format="2">
+ <advance width="1395"/>
+ <anchor x="668" y="1460" name="H"/>
+ <anchor x="688" y="1560" name="L"/>
+ <anchor x="-75" y="1460" name="O"/>
+ <anchor x="688" y="-70" name="U"/>
+ <outline>
+ <contour>
+ <point x="1130" y="1460" type="line"/>
+ <point x="996" y="1075" type="line"/>
+ <point x="381" y="1075" type="line"/>
+ <point x="245" y="1460" type="line"/>
+ <point x="40" y="1460" type="line"/>
+ <point x="75" y="1380"/>
+ <point x="113" y="1291"/>
+ <point x="180" y="1105" type="curve" smooth="yes"/>
+ <point x="580" y="0" type="line"/>
+ <point x="795" y="0" type="line"/>
+ <point x="1195" y="1105" type="line" smooth="yes"/>
+ <point x="1263" y="1292"/>
+ <point x="1299" y="1379"/>
+ <point x="1335" y="1460" type="curve"/>
+ </contour>
+ <contour>
+ <point x="435" y="920" type="line"/>
+ <point x="942" y="920" type="line"/>
+ <point x="690" y="195" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfdeleteglyphs.ufo/glyphs/L_tnC_apA_.glif b/tests/reference/ufo/psfdeleteglyphs.ufo/glyphs/L_tnC_apA_.glif
new file mode 100644
index 0000000..3c64e18
--- /dev/null
+++ b/tests/reference/ufo/psfdeleteglyphs.ufo/glyphs/L_tnC_apA_.glif
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnCapA" format="2">
+ <advance width="1395"/>
+ <unicode hex="0041"/>
+ <anchor x="707" y="0" name="H"/>
+ <anchor x="687" y="-100" name="L"/>
+ <anchor x="1450" y="0" name="O"/>
+ <anchor x="687" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="245" y="0" type="line"/>
+ <point x="379" y="385" type="line"/>
+ <point x="994" y="385" type="line"/>
+ <point x="1130" y="0" type="line"/>
+ <point x="1335" y="0" type="line"/>
+ <point x="1300" y="80"/>
+ <point x="1262" y="169"/>
+ <point x="1195" y="355" type="curve" smooth="yes"/>
+ <point x="795" y="1460" type="line"/>
+ <point x="580" y="1460" type="line"/>
+ <point x="180" y="355" type="line" smooth="yes"/>
+ <point x="112" y="168"/>
+ <point x="76" y="81"/>
+ <point x="40" y="0" type="curve"/>
+ </contour>
+ <contour>
+ <point x="940" y="540" type="line"/>
+ <point x="433" y="540" type="line"/>
+ <point x="685" y="1265" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfdeleteglyphs.ufo/glyphs/L_tnC_apA_D_iaer.glif b/tests/reference/ufo/psfdeleteglyphs.ufo/glyphs/L_tnC_apA_D_iaer.glif
new file mode 100644
index 0000000..b74cc60
--- /dev/null
+++ b/tests/reference/ufo/psfdeleteglyphs.ufo/glyphs/L_tnC_apA_D_iaer.glif
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnCapADiaer" format="2">
+ <advance width="1395"/>
+ <unicode hex="00C4"/>
+ <anchor x="707" y="0" name="H"/>
+ <anchor x="687" y="-100" name="L"/>
+ <anchor x="1450" y="0" name="O"/>
+ <anchor x="687" y="1935" name="U"/>
+ <outline>
+ <component base="LtnCapA"/>
+ <component base="CombDiaer" xOffset="1257" yOffset="430"/>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfdeleteglyphs.ufo/glyphs/L_tnC_apB_.glif b/tests/reference/ufo/psfdeleteglyphs.ufo/glyphs/L_tnC_apB_.glif
new file mode 100644
index 0000000..415122e
--- /dev/null
+++ b/tests/reference/ufo/psfdeleteglyphs.ufo/glyphs/L_tnC_apB_.glif
@@ -0,0 +1,62 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnCapB" format="2">
+ <advance width="1285"/>
+ <unicode hex="0042"/>
+ <anchor x="615" y="-100" name="L"/>
+ <anchor x="615" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="365" y="1310" type="line"/>
+ <point x="407" y="1312"/>
+ <point x="512" y="1315"/>
+ <point x="590" y="1315" type="curve" smooth="yes"/>
+ <point x="791" y="1315"/>
+ <point x="870" y="1239"/>
+ <point x="870" y="1090" type="curve" smooth="yes"/>
+ <point x="870" y="951"/>
+ <point x="774" y="855"/>
+ <point x="560" y="855" type="curve" smooth="yes"/>
+ <point x="365" y="855" type="line"/>
+ </contour>
+ <contour>
+ <point x="175" y="455" type="line"/>
+ <point x="175" y="257"/>
+ <point x="175" y="80"/>
+ <point x="160" y="0" type="curve"/>
+ <point x="213" y="-5"/>
+ <point x="402" y="-10"/>
+ <point x="605" y="-10" type="curve" smooth="yes"/>
+ <point x="988" y="-10"/>
+ <point x="1140" y="177"/>
+ <point x="1140" y="420" type="curve" smooth="yes"/>
+ <point x="1140" y="669"/>
+ <point x="974" y="759"/>
+ <point x="820" y="800" type="curve"/>
+ <point x="956" y="852"/>
+ <point x="1065" y="952"/>
+ <point x="1065" y="1120" type="curve" smooth="yes"/>
+ <point x="1065" y="1381"/>
+ <point x="897" y="1470"/>
+ <point x="600" y="1470" type="curve" smooth="yes"/>
+ <point x="431" y="1470"/>
+ <point x="248" y="1466"/>
+ <point x="160" y="1460" type="curve"/>
+ <point x="175" y="1380"/>
+ <point x="175" y="1196"/>
+ <point x="175" y="1000" type="curve" smooth="yes"/>
+ </contour>
+ <contour>
+ <point x="365" y="700" type="line"/>
+ <point x="600" y="700" type="line" smooth="yes"/>
+ <point x="833" y="700"/>
+ <point x="945" y="604"/>
+ <point x="945" y="420" type="curve" smooth="yes"/>
+ <point x="945" y="212"/>
+ <point x="781" y="150"/>
+ <point x="610" y="150" type="curve" smooth="yes"/>
+ <point x="498" y="150"/>
+ <point x="402" y="153"/>
+ <point x="365" y="155" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfdeleteglyphs.ufo/glyphs/L_tnC_apC_.glif b/tests/reference/ufo/psfdeleteglyphs.ufo/glyphs/L_tnC_apC_.glif
new file mode 100644
index 0000000..daf4f2d
--- /dev/null
+++ b/tests/reference/ufo/psfdeleteglyphs.ufo/glyphs/L_tnC_apC_.glif
@@ -0,0 +1,38 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnCapC" format="2">
+ <advance width="1355"/>
+ <unicode hex="0043"/>
+ <anchor x="750" y="0" name="H"/>
+ <anchor x="750" y="-100" name="L"/>
+ <anchor x="750" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="1190" y="335" type="line"/>
+ <point x="1078" y="223"/>
+ <point x="912" y="150"/>
+ <point x="760" y="150" type="curve" smooth="yes"/>
+ <point x="489" y="150"/>
+ <point x="290" y="376"/>
+ <point x="290" y="735" type="curve" smooth="yes"/>
+ <point x="290" y="1119"/>
+ <point x="491" y="1315"/>
+ <point x="770" y="1315" type="curve" smooth="yes"/>
+ <point x="891" y="1315"/>
+ <point x="1030" y="1278"/>
+ <point x="1155" y="1165" type="curve"/>
+ <point x="1215" y="1345" type="line"/>
+ <point x="1072" y="1452"/>
+ <point x="913" y="1485"/>
+ <point x="770" y="1485" type="curve" smooth="yes"/>
+ <point x="418" y="1485"/>
+ <point x="95" y="1225"/>
+ <point x="95" y="710" type="curve" smooth="yes"/>
+ <point x="95" y="260"/>
+ <point x="346" y="-25"/>
+ <point x="750" y="-25" type="curve" smooth="yes"/>
+ <point x="902" y="-25"/>
+ <point x="1114" y="32"/>
+ <point x="1230" y="140" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfdeleteglyphs.ufo/glyphs/L_tnC_apD_.glif b/tests/reference/ufo/psfdeleteglyphs.ufo/glyphs/L_tnC_apD_.glif
new file mode 100644
index 0000000..9154a06
--- /dev/null
+++ b/tests/reference/ufo/psfdeleteglyphs.ufo/glyphs/L_tnC_apD_.glif
@@ -0,0 +1,45 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnCapD" format="2">
+ <advance width="1435"/>
+ <unicode hex="0044"/>
+ <anchor x="715" y="-100" name="L"/>
+ <anchor x="715" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="175" y="455" type="line"/>
+ <point x="174" y="257"/>
+ <point x="175" y="80"/>
+ <point x="160" y="0" type="curve"/>
+ <point x="160" y="0"/>
+ <point x="467" y="-10"/>
+ <point x="595" y="-10" type="curve" smooth="yes"/>
+ <point x="888" y="-10"/>
+ <point x="1315" y="145"/>
+ <point x="1315" y="740" type="curve" smooth="yes"/>
+ <point x="1315" y="1394"/>
+ <point x="829" y="1470"/>
+ <point x="615" y="1470" type="curve" smooth="yes"/>
+ <point x="480" y="1470"/>
+ <point x="245" y="1466"/>
+ <point x="160" y="1460" type="curve"/>
+ <point x="175" y="1380"/>
+ <point x="175" y="1196"/>
+ <point x="175" y="1000" type="curve" smooth="yes"/>
+ </contour>
+ <contour>
+ <point x="365" y="1305" type="line"/>
+ <point x="415" y="1307"/>
+ <point x="524" y="1310"/>
+ <point x="590" y="1310" type="curve" smooth="yes"/>
+ <point x="878" y="1310"/>
+ <point x="1120" y="1167"/>
+ <point x="1120" y="720" type="curve" smooth="yes"/>
+ <point x="1120" y="308"/>
+ <point x="853" y="155"/>
+ <point x="585" y="155" type="curve" smooth="yes"/>
+ <point x="490" y="155"/>
+ <point x="412" y="161"/>
+ <point x="365" y="165" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfdeleteglyphs.ufo/glyphs/L_tnC_apE_.glif b/tests/reference/ufo/psfdeleteglyphs.ufo/glyphs/L_tnC_apE_.glif
new file mode 100644
index 0000000..e5d0043
--- /dev/null
+++ b/tests/reference/ufo/psfdeleteglyphs.ufo/glyphs/L_tnC_apE_.glif
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnCapE" format="2">
+ <advance width="1160"/>
+ <unicode hex="0045"/>
+ <anchor x="600" y="0" name="H"/>
+ <anchor x="600" y="-100" name="L"/>
+ <anchor x="917" y="0" name="O"/>
+ <anchor x="1160" y="1200" name="R"/>
+ <anchor x="600" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="365" y="845" type="line"/>
+ <point x="365" y="1295" type="line"/>
+ <point x="1010" y="1295" type="line"/>
+ <point x="1010" y="1460" type="line"/>
+ <point x="160" y="1460" type="line"/>
+ <point x="175" y="1380"/>
+ <point x="175" y="1222"/>
+ <point x="175" y="1025" type="curve" smooth="yes"/>
+ <point x="175" y="435" type="line" smooth="yes"/>
+ <point x="175" y="238"/>
+ <point x="175" y="80"/>
+ <point x="160" y="0" type="curve"/>
+ <point x="1040" y="0" type="line"/>
+ <point x="1040" y="180" type="line"/>
+ <point x="960" y="166"/>
+ <point x="826" y="165"/>
+ <point x="629" y="165" type="curve" smooth="yes"/>
+ <point x="365" y="165" type="line"/>
+ <point x="365" y="685" type="line"/>
+ <point x="935" y="685" type="line"/>
+ <point x="935" y="845" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfdeleteglyphs.ufo/glyphs/L_tnC_apF_.glif b/tests/reference/ufo/psfdeleteglyphs.ufo/glyphs/L_tnC_apF_.glif
new file mode 100644
index 0000000..deb38fb
--- /dev/null
+++ b/tests/reference/ufo/psfdeleteglyphs.ufo/glyphs/L_tnC_apF_.glif
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnCapF" format="2">
+ <advance width="1150"/>
+ <unicode hex="0046"/>
+ <anchor x="595" y="-100" name="L"/>
+ <anchor x="595" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="365" y="835" type="line"/>
+ <point x="365" y="1295" type="line"/>
+ <point x="1030" y="1295" type="line"/>
+ <point x="1030" y="1460" type="line"/>
+ <point x="160" y="1460" type="line"/>
+ <point x="175" y="1380"/>
+ <point x="175" y="1217"/>
+ <point x="175" y="1020" type="curve" smooth="yes"/>
+ <point x="175" y="435" type="line" smooth="yes"/>
+ <point x="175" y="238"/>
+ <point x="175" y="80"/>
+ <point x="160" y="0" type="curve"/>
+ <point x="380" y="0" type="line"/>
+ <point x="365" y="78"/>
+ <point x="365" y="237"/>
+ <point x="365" y="435" type="curve" smooth="yes"/>
+ <point x="365" y="675" type="line"/>
+ <point x="945" y="675" type="line"/>
+ <point x="945" y="835" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfdeleteglyphs.ufo/glyphs/L_tnC_apG_.glif b/tests/reference/ufo/psfdeleteglyphs.ufo/glyphs/L_tnC_apG_.glif
new file mode 100644
index 0000000..477d223
--- /dev/null
+++ b/tests/reference/ufo/psfdeleteglyphs.ufo/glyphs/L_tnC_apG_.glif
@@ -0,0 +1,42 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnCapG" format="2">
+ <advance width="1420"/>
+ <unicode hex="0047"/>
+ <anchor x="745" y="0" name="H"/>
+ <anchor x="745" y="-100" name="L"/>
+ <anchor x="745" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="1275" y="745" type="line"/>
+ <point x="735" y="745" type="line"/>
+ <point x="735" y="580" type="line"/>
+ <point x="1085" y="580" type="line"/>
+ <point x="1085" y="245" type="line"/>
+ <point x="963" y="171"/>
+ <point x="876" y="150"/>
+ <point x="757" y="150" type="curve" smooth="yes"/>
+ <point x="471" y="150"/>
+ <point x="290" y="377"/>
+ <point x="290" y="745" type="curve" smooth="yes"/>
+ <point x="290" y="1094"/>
+ <point x="480" y="1315"/>
+ <point x="785" y="1315" type="curve" smooth="yes"/>
+ <point x="918" y="1315"/>
+ <point x="1046" y="1286"/>
+ <point x="1195" y="1165" type="curve"/>
+ <point x="1260" y="1345" type="line"/>
+ <point x="1085" y="1462"/>
+ <point x="947" y="1485"/>
+ <point x="785" y="1485" type="curve" smooth="yes"/>
+ <point x="402" y="1485"/>
+ <point x="95" y="1199"/>
+ <point x="95" y="720" type="curve" smooth="yes"/>
+ <point x="95" y="241"/>
+ <point x="367" y="-25"/>
+ <point x="745" y="-25" type="curve" smooth="yes"/>
+ <point x="918" y="-25"/>
+ <point x="1070" y="11"/>
+ <point x="1275" y="155" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfdeleteglyphs.ufo/glyphs/L_tnC_apH_.glif b/tests/reference/ufo/psfdeleteglyphs.ufo/glyphs/L_tnC_apH_.glif
new file mode 100644
index 0000000..5924270
--- /dev/null
+++ b/tests/reference/ufo/psfdeleteglyphs.ufo/glyphs/L_tnC_apH_.glif
@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnCapH" format="2">
+ <advance width="1475"/>
+ <unicode hex="0048"/>
+ <anchor x="285" y="0" name="H"/>
+ <anchor x="725" y="-100" name="L"/>
+ <anchor x="725" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="1290" y="0" type="line"/>
+ <point x="1275" y="80"/>
+ <point x="1275" y="238"/>
+ <point x="1275" y="435" type="curve" smooth="yes"/>
+ <point x="1275" y="1025" type="line" smooth="yes"/>
+ <point x="1275" y="1222"/>
+ <point x="1275" y="1380"/>
+ <point x="1290" y="1460" type="curve"/>
+ <point x="1085" y="1460" type="line"/>
+ <point x="1085" y="835" type="line"/>
+ <point x="365" y="835" type="line"/>
+ <point x="365" y="1460" type="line"/>
+ <point x="160" y="1460" type="line"/>
+ <point x="175" y="1380"/>
+ <point x="175" y="1222"/>
+ <point x="175" y="1025" type="curve" smooth="yes"/>
+ <point x="175" y="435" type="line" smooth="yes"/>
+ <point x="175" y="238"/>
+ <point x="175" y="80"/>
+ <point x="160" y="0" type="curve"/>
+ <point x="365" y="0" type="line"/>
+ <point x="365" y="675" type="line"/>
+ <point x="1085" y="675" type="line"/>
+ <point x="1085" y="0" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfdeleteglyphs.ufo/glyphs/L_tnC_apI_.glif b/tests/reference/ufo/psfdeleteglyphs.ufo/glyphs/L_tnC_apI_.glif
new file mode 100644
index 0000000..c6001c3
--- /dev/null
+++ b/tests/reference/ufo/psfdeleteglyphs.ufo/glyphs/L_tnC_apI_.glif
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnCapI" format="2">
+ <advance width="975"/>
+ <unicode hex="0049"/>
+ <anchor x="477" y="0" name="H"/>
+ <anchor x="477" y="-100" name="L"/>
+ <anchor x="673" y="0" name="O"/>
+ <anchor x="975" y="1200" name="R"/>
+ <anchor x="477" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="140" y="1460" type="line"/>
+ <point x="140" y="1315" type="line"/>
+ <point x="380" y="1315" type="line"/>
+ <point x="380" y="145" type="line"/>
+ <point x="140" y="145" type="line"/>
+ <point x="140" y="0" type="line"/>
+ <point x="815" y="0" type="line"/>
+ <point x="815" y="145" type="line"/>
+ <point x="570" y="145" type="line"/>
+ <point x="570" y="1315" type="line"/>
+ <point x="815" y="1315" type="line"/>
+ <point x="815" y="1460" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfdeleteglyphs.ufo/glyphs/L_tnC_apJ_.glif b/tests/reference/ufo/psfdeleteglyphs.ufo/glyphs/L_tnC_apJ_.glif
new file mode 100644
index 0000000..457e39d
--- /dev/null
+++ b/tests/reference/ufo/psfdeleteglyphs.ufo/glyphs/L_tnC_apJ_.glif
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnCapJ" format="2">
+ <advance width="965"/>
+ <unicode hex="004A"/>
+ <anchor x="410" y="-100" name="L"/>
+ <anchor x="675" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="575" y="1460" type="line"/>
+ <point x="588" y="1354"/>
+ <point x="590" y="1175"/>
+ <point x="590" y="980" type="curve"/>
+ <point x="590" y="485" type="line" smooth="yes"/>
+ <point x="590" y="256"/>
+ <point x="487" y="155"/>
+ <point x="340" y="155" type="curve" smooth="yes"/>
+ <point x="248" y="155"/>
+ <point x="147" y="198"/>
+ <point x="80" y="275" type="curve"/>
+ <point x="35" y="90" type="line"/>
+ <point x="106" y="9"/>
+ <point x="250" y="-25"/>
+ <point x="345" y="-25" type="curve" smooth="yes"/>
+ <point x="602" y="-25"/>
+ <point x="780" y="119"/>
+ <point x="780" y="535" type="curve" smooth="yes"/>
+ <point x="780" y="1460" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfdeleteglyphs.ufo/glyphs/L_tnC_apK_.glif b/tests/reference/ufo/psfdeleteglyphs.ufo/glyphs/L_tnC_apK_.glif
new file mode 100644
index 0000000..b3f4cdd
--- /dev/null
+++ b/tests/reference/ufo/psfdeleteglyphs.ufo/glyphs/L_tnC_apK_.glif
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnCapK" format="2">
+ <advance width="1310"/>
+ <unicode hex="004B"/>
+ <anchor x="270" y="0" name="H"/>
+ <anchor x="695" y="-100" name="L"/>
+ <anchor x="650" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="925" y="1460" type="line"/>
+ <point x="295" y="703" type="line"/>
+ <point x="425" y="745" type="line"/>
+ <point x="530" y="740" type="line"/>
+ <point x="1165" y="1460" type="line"/>
+ </contour>
+ <contour>
+ <point x="350" y="735" type="line"/>
+ <point x="985" y="0" type="line"/>
+ <point x="1230" y="0" type="line"/>
+ <point x="485" y="860" type="line"/>
+ </contour>
+ <contour>
+ <point x="365" y="1460" type="line"/>
+ <point x="160" y="1460" type="line"/>
+ <point x="175" y="1380"/>
+ <point x="175" y="1222"/>
+ <point x="175" y="1025" type="curve" smooth="yes"/>
+ <point x="175" y="435" type="line" smooth="yes"/>
+ <point x="175" y="238"/>
+ <point x="175" y="80"/>
+ <point x="160" y="0" type="curve"/>
+ <point x="365" y="0" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfdeleteglyphs.ufo/glyphs/L_tnC_apL_.glif b/tests/reference/ufo/psfdeleteglyphs.ufo/glyphs/L_tnC_apL_.glif
new file mode 100644
index 0000000..3d5883a
--- /dev/null
+++ b/tests/reference/ufo/psfdeleteglyphs.ufo/glyphs/L_tnC_apL_.glif
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnCapL" format="2">
+ <advance width="1080"/>
+ <unicode hex="004C"/>
+ <anchor x="592" y="0" name="H"/>
+ <anchor x="592" y="-100" name="L"/>
+ <anchor x="540" y="1200" name="R"/>
+ <anchor x="592" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="365" y="165" type="line"/>
+ <point x="365" y="1460" type="line"/>
+ <point x="160" y="1460" type="line"/>
+ <point x="175" y="1380"/>
+ <point x="175" y="1222"/>
+ <point x="175" y="1025" type="curve" smooth="yes"/>
+ <point x="175" y="435" type="line" smooth="yes"/>
+ <point x="175" y="238"/>
+ <point x="175" y="80"/>
+ <point x="160" y="0" type="curve"/>
+ <point x="1025" y="0" type="line"/>
+ <point x="1025" y="180" type="line"/>
+ <point x="945" y="166"/>
+ <point x="786" y="165"/>
+ <point x="589" y="165" type="curve" smooth="yes"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfdeleteglyphs.ufo/glyphs/L_tnC_apM_.glif b/tests/reference/ufo/psfdeleteglyphs.ufo/glyphs/L_tnC_apM_.glif
new file mode 100644
index 0000000..fbdf3b1
--- /dev/null
+++ b/tests/reference/ufo/psfdeleteglyphs.ufo/glyphs/L_tnC_apM_.glif
@@ -0,0 +1,37 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnCapM" format="2">
+ <advance width="1795"/>
+ <unicode hex="004D"/>
+ <anchor x="1521" y="0" name="H"/>
+ <anchor x="885" y="-100" name="L"/>
+ <anchor x="885" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="885" y="205" type="line"/>
+ <point x="455" y="1460" type="line"/>
+ <point x="285" y="1460" type="line"/>
+ <point x="790" y="0" type="line"/>
+ <point x="985" y="0" type="line"/>
+ <point x="1487" y="1460" type="line"/>
+ <point x="1320" y="1460" type="line"/>
+ </contour>
+ <contour>
+ <point x="230" y="1460" type="line"/>
+ <point x="230" y="1460"/>
+ <point x="186" y="198"/>
+ <point x="160" y="0" type="curve"/>
+ <point x="345" y="0" type="line"/>
+ <point x="377" y="1205" type="line"/>
+ <point x="405" y="1460" type="line"/>
+ </contour>
+ <contour>
+ <point x="1610" y="0" type="line"/>
+ <point x="1581" y="198"/>
+ <point x="1540" y="1460"/>
+ <point x="1540" y="1460" type="curve"/>
+ <point x="1365" y="1460" type="line"/>
+ <point x="1397" y="1205" type="line"/>
+ <point x="1425" y="0" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfdeleteglyphs.ufo/glyphs/L_tnC_apN_.glif b/tests/reference/ufo/psfdeleteglyphs.ufo/glyphs/L_tnC_apN_.glif
new file mode 100644
index 0000000..360e6e6
--- /dev/null
+++ b/tests/reference/ufo/psfdeleteglyphs.ufo/glyphs/L_tnC_apN_.glif
@@ -0,0 +1,37 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnCapN" format="2">
+ <advance width="1500"/>
+ <unicode hex="004E"/>
+ <anchor x="1230" y="0" name="H"/>
+ <anchor x="737" y="-100" name="L"/>
+ <anchor x="737" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="200" y="1355" type="line"/>
+ <point x="1135" y="0" type="line"/>
+ <point x="1275" y="100" type="line"/>
+ <point x="340" y="1460" type="line"/>
+ </contour>
+ <contour>
+ <point x="1135" y="0" type="line"/>
+ <point x="1300" y="0" type="line"/>
+ <point x="1300" y="1025" type="line" smooth="yes"/>
+ <point x="1300" y="1222"/>
+ <point x="1301" y="1380"/>
+ <point x="1315" y="1460" type="curve"/>
+ <point x="1135" y="1460" type="line"/>
+ </contour>
+ <contour>
+ <point x="340" y="1460" type="line"/>
+ <point x="160" y="1460" type="line"/>
+ <point x="175" y="1380"/>
+ <point x="175" y="1222"/>
+ <point x="175" y="1025" type="curve" smooth="yes"/>
+ <point x="175" y="435" type="line" smooth="yes"/>
+ <point x="175" y="238"/>
+ <point x="175" y="80"/>
+ <point x="160" y="0" type="curve"/>
+ <point x="340" y="0" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfdeleteglyphs.ufo/glyphs/L_tnC_apO_.glif b/tests/reference/ufo/psfdeleteglyphs.ufo/glyphs/L_tnC_apO_.glif
new file mode 100644
index 0000000..e351c3d
--- /dev/null
+++ b/tests/reference/ufo/psfdeleteglyphs.ufo/glyphs/L_tnC_apO_.glif
@@ -0,0 +1,40 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnCapO" format="2">
+ <advance width="1460"/>
+ <unicode hex="004F"/>
+ <anchor x="717" y="0" name="H"/>
+ <anchor x="717" y="-100" name="L"/>
+ <anchor x="994" y="0" name="O"/>
+ <anchor x="1460" y="1200" name="R"/>
+ <anchor x="717" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="1145" y="715" type="curve" smooth="yes"/>
+ <point x="1145" y="360"/>
+ <point x="965" y="150"/>
+ <point x="720" y="150" type="curve" smooth="yes"/>
+ <point x="460" y="150"/>
+ <point x="290" y="380"/>
+ <point x="290" y="745" type="curve" smooth="yes"/>
+ <point x="290" y="1091"/>
+ <point x="467" y="1310"/>
+ <point x="720" y="1310" type="curve" smooth="yes"/>
+ <point x="974" y="1310"/>
+ <point x="1145" y="1084"/>
+ </contour>
+ <contour>
+ <point x="1340" y="740" type="curve" smooth="yes"/>
+ <point x="1340" y="1219"/>
+ <point x="1048" y="1485"/>
+ <point x="730" y="1485" type="curve" smooth="yes"/>
+ <point x="407" y="1485"/>
+ <point x="95" y="1199"/>
+ <point x="95" y="720" type="curve" smooth="yes"/>
+ <point x="95" y="241"/>
+ <point x="388" y="-25"/>
+ <point x="710" y="-25" type="curve" smooth="yes"/>
+ <point x="1029" y="-25"/>
+ <point x="1340" y="260"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfdeleteglyphs.ufo/glyphs/L_tnC_apP_.glif b/tests/reference/ufo/psfdeleteglyphs.ufo/glyphs/L_tnC_apP_.glif
new file mode 100644
index 0000000..9f29954
--- /dev/null
+++ b/tests/reference/ufo/psfdeleteglyphs.ufo/glyphs/L_tnC_apP_.glif
@@ -0,0 +1,50 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnCapP" format="2">
+ <advance width="1195"/>
+ <unicode hex="0050"/>
+ <anchor x="637" y="-100" name="L"/>
+ <anchor x="637" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="365" y="565" type="line"/>
+ <point x="430" y="558"/>
+ <point x="512" y="555"/>
+ <point x="585" y="555" type="curve" smooth="yes"/>
+ <point x="914" y="555"/>
+ <point x="1115" y="736"/>
+ <point x="1115" y="1030" type="curve" smooth="yes"/>
+ <point x="1115" y="1322"/>
+ <point x="908" y="1470"/>
+ <point x="585" y="1470" type="curve" smooth="yes"/>
+ <point x="372" y="1470"/>
+ <point x="160" y="1460"/>
+ <point x="160" y="1460" type="curve"/>
+ <point x="175" y="1380"/>
+ <point x="175" y="1196"/>
+ <point x="175" y="1000" type="curve"/>
+ <point x="175" y="435" type="line" smooth="yes"/>
+ <point x="175" y="238"/>
+ <point x="175" y="80"/>
+ <point x="160" y="0" type="curve"/>
+ <point x="380" y="0" type="line"/>
+ <point x="366" y="78"/>
+ <point x="365" y="237"/>
+ <point x="365" y="435" type="curve" smooth="yes"/>
+ </contour>
+ <contour>
+ <point x="365" y="1305" type="line"/>
+ <point x="433" y="1308"/>
+ <point x="481" y="1310"/>
+ <point x="575" y="1310" type="curve" smooth="yes"/>
+ <point x="841" y="1310"/>
+ <point x="925" y="1170"/>
+ <point x="925" y="1010" type="curve" smooth="yes"/>
+ <point x="925" y="849"/>
+ <point x="850" y="710"/>
+ <point x="570" y="710" type="curve" smooth="yes"/>
+ <point x="495" y="710"/>
+ <point x="428" y="712"/>
+ <point x="365" y="720" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfdeleteglyphs.ufo/glyphs/L_tnC_apQ_.glif b/tests/reference/ufo/psfdeleteglyphs.ufo/glyphs/L_tnC_apQ_.glif
new file mode 100644
index 0000000..ddd0351
--- /dev/null
+++ b/tests/reference/ufo/psfdeleteglyphs.ufo/glyphs/L_tnC_apQ_.glif
@@ -0,0 +1,49 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnCapQ" format="2">
+ <advance width="1475"/>
+ <unicode hex="0051"/>
+ <anchor x="717" y="-270" name="L"/>
+ <anchor x="717" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="1340" y="740" type="curve" smooth="yes"/>
+ <point x="1340" y="1219"/>
+ <point x="1053" y="1485"/>
+ <point x="730" y="1485" type="curve" smooth="yes"/>
+ <point x="407" y="1485"/>
+ <point x="95" y="1199"/>
+ <point x="95" y="720" type="curve" smooth="yes"/>
+ <point x="95" y="241"/>
+ <point x="383" y="-25"/>
+ <point x="705" y="-25" type="curve" smooth="yes"/>
+ <point x="767" y="-25"/>
+ <point x="818" y="-18"/>
+ <point x="875" y="0" type="curve"/>
+ <point x="944" y="0"/>
+ <point x="1236" y="-190"/>
+ <point x="1320" y="-190" type="curve" smooth="yes"/>
+ <point x="1374" y="-190"/>
+ <point x="1431" y="-81"/>
+ <point x="1455" y="-45" type="curve"/>
+ <point x="1321" y="-28"/>
+ <point x="1205" y="28"/>
+ <point x="1080" y="105" type="curve"/>
+ <point x="1256" y="236"/>
+ <point x="1340" y="479"/>
+ </contour>
+ <contour>
+ <point x="1145" y="715" type="curve" smooth="yes"/>
+ <point x="1145" y="360"/>
+ <point x="965" y="150"/>
+ <point x="720" y="150" type="curve" smooth="yes"/>
+ <point x="460" y="150"/>
+ <point x="290" y="380"/>
+ <point x="290" y="745" type="curve" smooth="yes"/>
+ <point x="290" y="1091"/>
+ <point x="467" y="1310"/>
+ <point x="720" y="1310" type="curve" smooth="yes"/>
+ <point x="974" y="1310"/>
+ <point x="1145" y="1084"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfdeleteglyphs.ufo/glyphs/L_tnC_apR_.glif b/tests/reference/ufo/psfdeleteglyphs.ufo/glyphs/L_tnC_apR_.glif
new file mode 100644
index 0000000..cd9e037
--- /dev/null
+++ b/tests/reference/ufo/psfdeleteglyphs.ufo/glyphs/L_tnC_apR_.glif
@@ -0,0 +1,55 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnCapR" format="2">
+ <advance width="1305"/>
+ <unicode hex="0052"/>
+ <anchor x="285" y="0" name="H"/>
+ <anchor x="610" y="-100" name="L"/>
+ <anchor x="610" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="365" y="625" type="line"/>
+ <point x="620" y="625" type="line"/>
+ <point x="805" y="625"/>
+ <point x="1090" y="743"/>
+ <point x="1090" y="1060" type="curve" smooth="yes"/>
+ <point x="1090" y="1349"/>
+ <point x="876" y="1470"/>
+ <point x="565" y="1470" type="curve" smooth="yes"/>
+ <point x="331" y="1470"/>
+ <point x="160" y="1460"/>
+ <point x="160" y="1460" type="curve"/>
+ <point x="175" y="1380"/>
+ <point x="175" y="1196"/>
+ <point x="175" y="1000" type="curve" smooth="yes"/>
+ <point x="175" y="435" type="line"/>
+ <point x="175" y="238"/>
+ <point x="175" y="80"/>
+ <point x="160" y="0" type="curve"/>
+ <point x="380" y="0" type="line"/>
+ <point x="366" y="78"/>
+ <point x="365" y="238"/>
+ <point x="365" y="435" type="curve"/>
+ </contour>
+ <contour>
+ <point x="365" y="1305" type="line"/>
+ <point x="418" y="1307"/>
+ <point x="485" y="1310"/>
+ <point x="555" y="1310" type="curve" smooth="yes"/>
+ <point x="800" y="1310"/>
+ <point x="900" y="1216"/>
+ <point x="900" y="1045" type="curve" smooth="yes"/>
+ <point x="900" y="879"/>
+ <point x="780" y="780"/>
+ <point x="555" y="780" type="curve"/>
+ <point x="365" y="780" type="line"/>
+ </contour>
+ <contour>
+ <point x="561" y="635" type="line"/>
+ <point x="990" y="0" type="line"/>
+ <point x="1245" y="0" type="line"/>
+ <point x="1178" y="73"/>
+ <point x="715" y="710"/>
+ <point x="715" y="710" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfdeleteglyphs.ufo/glyphs/L_tnC_apS_.glif b/tests/reference/ufo/psfdeleteglyphs.ufo/glyphs/L_tnC_apS_.glif
new file mode 100644
index 0000000..92da6b0
--- /dev/null
+++ b/tests/reference/ufo/psfdeleteglyphs.ufo/glyphs/L_tnC_apS_.glif
@@ -0,0 +1,50 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnCapS" format="2">
+ <advance width="1175"/>
+ <unicode hex="0053"/>
+ <anchor x="580" y="0" name="H"/>
+ <anchor x="580" y="-100" name="L"/>
+ <anchor x="580" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="1000" y="1395" type="line"/>
+ <point x="870" y="1458"/>
+ <point x="759" y="1485"/>
+ <point x="605" y="1485" type="curve" smooth="yes"/>
+ <point x="273" y="1485"/>
+ <point x="135" y="1250"/>
+ <point x="135" y="1080" type="curve" smooth="yes"/>
+ <point x="135" y="910"/>
+ <point x="203" y="778"/>
+ <point x="515" y="685" type="curve" smooth="yes"/>
+ <point x="827" y="591"/>
+ <point x="875" y="510"/>
+ <point x="875" y="405" type="curve" smooth="yes"/>
+ <point x="875" y="243"/>
+ <point x="726" y="150"/>
+ <point x="565" y="150" type="curve" smooth="yes"/>
+ <point x="417" y="150"/>
+ <point x="272" y="200"/>
+ <point x="140" y="315" type="curve"/>
+ <point x="95" y="110" type="line"/>
+ <point x="197" y="31"/>
+ <point x="372" y="-25"/>
+ <point x="565" y="-25" type="curve" smooth="yes"/>
+ <point x="838" y="-25"/>
+ <point x="1065" y="157"/>
+ <point x="1065" y="425" type="curve" smooth="yes"/>
+ <point x="1065" y="641"/>
+ <point x="920" y="762"/>
+ <point x="655" y="840" type="curve" smooth="yes"/>
+ <point x="370" y="923"/>
+ <point x="325" y="985"/>
+ <point x="325" y="1095" type="curve" smooth="yes"/>
+ <point x="325" y="1205"/>
+ <point x="435" y="1310"/>
+ <point x="595" y="1310" type="curve" smooth="yes"/>
+ <point x="723" y="1310"/>
+ <point x="817" y="1279"/>
+ <point x="960" y="1200" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfdeleteglyphs.ufo/glyphs/L_tnC_apT_.glif b/tests/reference/ufo/psfdeleteglyphs.ufo/glyphs/L_tnC_apT_.glif
new file mode 100644
index 0000000..124138f
--- /dev/null
+++ b/tests/reference/ufo/psfdeleteglyphs.ufo/glyphs/L_tnC_apT_.glif
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnCapT" format="2">
+ <advance width="1265"/>
+ <unicode hex="0054"/>
+ <anchor x="622" y="0" name="H"/>
+ <anchor x="622" y="-100" name="L"/>
+ <anchor x="622" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="45" y="1460" type="line"/>
+ <point x="45" y="1275" type="line"/>
+ <point x="125" y="1292"/>
+ <point x="201" y="1295"/>
+ <point x="290" y="1295" type="curve" smooth="yes"/>
+ <point x="525" y="1295" type="line"/>
+ <point x="525" y="435" type="line" smooth="yes"/>
+ <point x="525" y="238"/>
+ <point x="522" y="80"/>
+ <point x="505" y="0" type="curve"/>
+ <point x="735" y="0" type="line"/>
+ <point x="718" y="80"/>
+ <point x="715" y="238"/>
+ <point x="715" y="435" type="curve" smooth="yes"/>
+ <point x="715" y="1295" type="line"/>
+ <point x="955" y="1295" type="line" smooth="yes"/>
+ <point x="1045" y="1295"/>
+ <point x="1120" y="1292"/>
+ <point x="1200" y="1275" type="curve"/>
+ <point x="1200" y="1460" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfdeleteglyphs.ufo/glyphs/L_tnC_apU_.glif b/tests/reference/ufo/psfdeleteglyphs.ufo/glyphs/L_tnC_apU_.glif
new file mode 100644
index 0000000..7afa08d
--- /dev/null
+++ b/tests/reference/ufo/psfdeleteglyphs.ufo/glyphs/L_tnC_apU_.glif
@@ -0,0 +1,38 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnCapU" format="2">
+ <advance width="1440"/>
+ <unicode hex="0055"/>
+ <anchor x="707" y="0" name="H"/>
+ <anchor x="707" y="-100" name="L"/>
+ <anchor x="1026" y="0" name="O"/>
+ <anchor x="1400" y="1200" name="R"/>
+ <anchor x="707" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="1050" y="1460" type="line"/>
+ <point x="1050" y="560" type="line" smooth="yes"/>
+ <point x="1050" y="299"/>
+ <point x="968" y="135"/>
+ <point x="710" y="135" type="curve" smooth="yes"/>
+ <point x="447" y="135"/>
+ <point x="365" y="299"/>
+ <point x="365" y="560" type="curve" smooth="yes"/>
+ <point x="365" y="1460" type="line"/>
+ <point x="160" y="1460" type="line"/>
+ <point x="174" y="1380"/>
+ <point x="175" y="1222"/>
+ <point x="175" y="1025" type="curve" smooth="yes"/>
+ <point x="175" y="515" type="line"/>
+ <point x="175" y="190"/>
+ <point x="345" y="-25"/>
+ <point x="710" y="-25" type="curve" smooth="yes"/>
+ <point x="1071" y="-25"/>
+ <point x="1240" y="190"/>
+ <point x="1240" y="515" type="curve"/>
+ <point x="1240" y="1025" type="line" smooth="yes"/>
+ <point x="1240" y="1232"/>
+ <point x="1242" y="1380"/>
+ <point x="1255" y="1460" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfdeleteglyphs.ufo/glyphs/L_tnC_apV_.glif b/tests/reference/ufo/psfdeleteglyphs.ufo/glyphs/L_tnC_apV_.glif
new file mode 100644
index 0000000..86c76b5
--- /dev/null
+++ b/tests/reference/ufo/psfdeleteglyphs.ufo/glyphs/L_tnC_apV_.glif
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnCapV" format="2">
+ <advance width="1365"/>
+ <unicode hex="0056"/>
+ <anchor x="680" y="0" name="H"/>
+ <anchor x="672" y="-100" name="L"/>
+ <anchor x="880" y="0" name="O"/>
+ <anchor x="672" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="1095" y="1460" type="line"/>
+ <point x="672" y="195" type="line"/>
+ <point x="250" y="1460" type="line"/>
+ <point x="35" y="1460" type="line"/>
+ <point x="68" y="1378"/>
+ <point x="101" y="1288"/>
+ <point x="170" y="1095" type="curve" smooth="yes"/>
+ <point x="560" y="0" type="line"/>
+ <point x="785" y="0" type="line"/>
+ <point x="1170" y="1095" type="line" smooth="yes"/>
+ <point x="1238" y="1289"/>
+ <point x="1274" y="1378"/>
+ <point x="1310" y="1460" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfdeleteglyphs.ufo/glyphs/L_tnC_apW_.glif b/tests/reference/ufo/psfdeleteglyphs.ufo/glyphs/L_tnC_apW_.glif
new file mode 100644
index 0000000..b1f4961
--- /dev/null
+++ b/tests/reference/ufo/psfdeleteglyphs.ufo/glyphs/L_tnC_apW_.glif
@@ -0,0 +1,45 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnCapW" format="2">
+ <advance width="2080"/>
+ <unicode hex="0057"/>
+ <anchor x="1027" y="-100" name="L"/>
+ <anchor x="1027" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="1480" y="0" type="line"/>
+ <point x="1595" y="0" type="line"/>
+ <point x="1900" y="1095" type="line" smooth="yes"/>
+ <point x="1954" y="1289"/>
+ <point x="1983" y="1378"/>
+ <point x="2015" y="1460" type="curve"/>
+ <point x="1795" y="1460" type="line"/>
+ <point x="1470" y="130" type="line"/>
+ </contour>
+ <contour>
+ <point x="1120" y="1460" type="line"/>
+ <point x="935" y="1460" type="line"/>
+ <point x="990" y="1305" type="line"/>
+ <point x="1370" y="0" type="line"/>
+ <point x="1480" y="0" type="line"/>
+ <point x="1500" y="130" type="line"/>
+ </contour>
+ <contour>
+ <point x="580" y="0" type="line"/>
+ <point x="685" y="0" type="line"/>
+ <point x="1065" y="1305" type="line"/>
+ <point x="1120" y="1460" type="line"/>
+ <point x="935" y="1460" type="line"/>
+ <point x="560" y="130" type="line"/>
+ </contour>
+ <contour>
+ <point x="260" y="1460" type="line"/>
+ <point x="40" y="1460" type="line"/>
+ <point x="71" y="1381"/>
+ <point x="102" y="1286"/>
+ <point x="155" y="1095" type="curve" smooth="yes"/>
+ <point x="460" y="0" type="line"/>
+ <point x="580" y="0" type="line"/>
+ <point x="590" y="130" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfdeleteglyphs.ufo/glyphs/L_tnC_apX_.glif b/tests/reference/ufo/psfdeleteglyphs.ufo/glyphs/L_tnC_apX_.glif
new file mode 100644
index 0000000..7472407
--- /dev/null
+++ b/tests/reference/ufo/psfdeleteglyphs.ufo/glyphs/L_tnC_apX_.glif
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnCapX" format="2">
+ <advance width="1325"/>
+ <unicode hex="0058"/>
+ <anchor x="650" y="-100" name="L"/>
+ <anchor x="650" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="537" y="781" type="line"/>
+ <point x="265" y="340" type="line" smooth="yes"/>
+ <point x="136" y="132"/>
+ <point x="103" y="86"/>
+ <point x="40" y="0" type="curve"/>
+ <point x="270" y="0" type="line"/>
+ <point x="642" y="614" type="line"/>
+ <point x="1030" y="0" type="line"/>
+ <point x="1260" y="0" type="line"/>
+ <point x="1199" y="82"/>
+ <point x="1165" y="127"/>
+ <point x="1033" y="336" type="curve" smooth="yes"/>
+ <point x="761" y="767" type="line"/>
+ <point x="972" y="1110" type="line" smooth="yes"/>
+ <point x="1097" y="1313"/>
+ <point x="1148" y="1383"/>
+ <point x="1210" y="1460" type="curve"/>
+ <point x="975" y="1460" type="line"/>
+ <point x="656" y="934" type="line"/>
+ <point x="325" y="1460" type="line"/>
+ <point x="90" y="1460" type="line"/>
+ <point x="154" y="1376"/>
+ <point x="201" y="1315"/>
+ <point x="330" y="1110" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfdeleteglyphs.ufo/glyphs/L_tnC_apY_.glif b/tests/reference/ufo/psfdeleteglyphs.ufo/glyphs/L_tnC_apY_.glif
new file mode 100644
index 0000000..c2c5f54
--- /dev/null
+++ b/tests/reference/ufo/psfdeleteglyphs.ufo/glyphs/L_tnC_apY_.glif
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnCapY" format="2">
+ <advance width="1320"/>
+ <unicode hex="0059"/>
+ <anchor x="650" y="-100" name="L"/>
+ <anchor x="650" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="35" y="1460" type="line"/>
+ <point x="147" y="1311"/>
+ <point x="213" y="1197"/>
+ <point x="290" y="1065" type="curve" smooth="yes"/>
+ <point x="555" y="611" type="line"/>
+ <point x="555" y="435" type="line" smooth="yes"/>
+ <point x="555" y="238"/>
+ <point x="555" y="80"/>
+ <point x="540" y="0" type="curve"/>
+ <point x="760" y="0" type="line"/>
+ <point x="745" y="80"/>
+ <point x="745" y="238"/>
+ <point x="745" y="435" type="curve" smooth="yes"/>
+ <point x="745" y="603" type="line"/>
+ <point x="1015" y="1065" type="line" smooth="yes"/>
+ <point x="1091" y="1195"/>
+ <point x="1147" y="1291"/>
+ <point x="1265" y="1460" type="curve"/>
+ <point x="1035" y="1460" type="line"/>
+ <point x="660" y="799" type="line"/>
+ <point x="265" y="1460" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfdeleteglyphs.ufo/glyphs/L_tnS_mA_.glif b/tests/reference/ufo/psfdeleteglyphs.ufo/glyphs/L_tnS_mA_.glif
new file mode 100644
index 0000000..20f7261
--- /dev/null
+++ b/tests/reference/ufo/psfdeleteglyphs.ufo/glyphs/L_tnS_mA_.glif
@@ -0,0 +1,76 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmA" format="2">
+ <advance width="1120"/>
+ <unicode hex="0061"/>
+ <note>
+
+
+
+
+ GlyphNote A
+
+
+
+
+ </note>
+ <anchor x="540" y="0" name="H"/>
+ <anchor x="540" y="-100" name="L"/>
+ <anchor x="1125" y="0" name="O"/>
+ <anchor x="1120" y="1000" name="R"/>
+ <anchor x="540" y="1100" name="U"/>
+ <outline>
+ <contour>
+ <point x="950" y="760" type="line"/>
+ <point x="950" y="919"/>
+ <point x="800" y="1040"/>
+ <point x="570" y="1040" type="curve" smooth="yes"/>
+ <point x="418" y="1040"/>
+ <point x="312" y="994"/>
+ <point x="209" y="950" type="curve"/>
+ <point x="203" y="907"/>
+ <point x="200" y="799"/>
+ <point x="199" y="755" type="curve"/>
+ <point x="316" y="837"/>
+ <point x="419" y="880"/>
+ <point x="525" y="880" type="curve" smooth="yes"/>
+ <point x="675" y="880"/>
+ <point x="765" y="831"/>
+ <point x="765" y="710" type="curve" smooth="yes"/>
+ <point x="765" y="635" type="line"/>
+ <point x="724" y="632"/>
+ <point x="564" y="617"/>
+ <point x="495" y="610" type="curve" smooth="yes"/>
+ <point x="186" y="580"/>
+ <point x="95" y="407"/>
+ <point x="95" y="255" type="curve" smooth="yes"/>
+ <point x="95" y="107"/>
+ <point x="232" y="-25"/>
+ <point x="420" y="-25" type="curve" smooth="yes"/>
+ <point x="544" y="-25"/>
+ <point x="677" y="29"/>
+ <point x="795" y="155" type="curve"/>
+ <point x="809" y="91"/>
+ <point x="833" y="32"/>
+ <point x="845" y="0" type="curve"/>
+ <point x="1025" y="0" type="line"/>
+ <point x="981" y="112"/>
+ <point x="950" y="226"/>
+ <point x="950" y="370" type="curve"/>
+ </contour>
+ <contour>
+ <point x="765" y="325" type="line"/>
+ <point x="644" y="164"/>
+ <point x="552" y="140"/>
+ <point x="450" y="140" type="curve" smooth="yes"/>
+ <point x="340" y="140"/>
+ <point x="275" y="191"/>
+ <point x="275" y="280" type="curve" smooth="yes"/>
+ <point x="275" y="372"/>
+ <point x="335" y="450"/>
+ <point x="505" y="470" type="curve" smooth="yes"/>
+ <point x="568" y="478"/>
+ <point x="715" y="493"/>
+ <point x="765" y="495" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfdeleteglyphs.ufo/glyphs/L_tnS_mA_A_cute.glif b/tests/reference/ufo/psfdeleteglyphs.ufo/glyphs/L_tnS_mA_A_cute.glif
new file mode 100644
index 0000000..2ab1b23
--- /dev/null
+++ b/tests/reference/ufo/psfdeleteglyphs.ufo/glyphs/L_tnS_mA_A_cute.glif
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmAAcute" format="2">
+ <advance width="1120"/>
+ <unicode hex="00E1"/>
+ <anchor x="540" y="0" name="H"/>
+ <anchor x="540" y="-100" name="L"/>
+ <anchor x="1125" y="0" name="O"/>
+ <anchor x="1120" y="1000" name="R"/>
+ <anchor x="540" y="1635" name="U"/>
+ <outline>
+ <component base="LtnSmA"/>
+ <component base="CombAcute" xOffset="1110"/>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfdeleteglyphs.ufo/glyphs/L_tnS_mA_C_ircum.glif b/tests/reference/ufo/psfdeleteglyphs.ufo/glyphs/L_tnS_mA_C_ircum.glif
new file mode 100644
index 0000000..6551c45
--- /dev/null
+++ b/tests/reference/ufo/psfdeleteglyphs.ufo/glyphs/L_tnS_mA_C_ircum.glif
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmACircum" format="2">
+ <advance width="1120"/>
+ <unicode hex="00E2"/>
+ <anchor x="540" y="0" name="H"/>
+ <anchor x="540" y="-100" name="L"/>
+ <anchor x="1125" y="0" name="O"/>
+ <anchor x="1120" y="1000" name="R"/>
+ <anchor x="540" y="1635" name="U"/>
+ <outline>
+ <component base="LtnSmA"/>
+ <component base="CombCircum" xOffset="1110"/>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfdeleteglyphs.ufo/glyphs/L_tnS_mA_D_iaer.glif b/tests/reference/ufo/psfdeleteglyphs.ufo/glyphs/L_tnS_mA_D_iaer.glif
new file mode 100644
index 0000000..61c5d3f
--- /dev/null
+++ b/tests/reference/ufo/psfdeleteglyphs.ufo/glyphs/L_tnS_mA_D_iaer.glif
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmADiaer" format="2">
+ <advance width="1120"/>
+ <unicode hex="00E4"/>
+ <anchor x="540" y="0" name="H"/>
+ <anchor x="540" y="-100" name="L"/>
+ <anchor x="1125" y="0" name="O"/>
+ <anchor x="1120" y="1000" name="R"/>
+ <anchor x="540" y="1505" name="U"/>
+ <outline>
+ <component base="LtnSmA"/>
+ <component base="CombDiaer" xOffset="1110"/>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfdeleteglyphs.ufo/glyphs/L_tnS_mA_G_rave.glif b/tests/reference/ufo/psfdeleteglyphs.ufo/glyphs/L_tnS_mA_G_rave.glif
new file mode 100644
index 0000000..9879252
--- /dev/null
+++ b/tests/reference/ufo/psfdeleteglyphs.ufo/glyphs/L_tnS_mA_G_rave.glif
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmAGrave" format="2">
+ <advance width="1120"/>
+ <unicode hex="00E0"/>
+ <anchor x="540" y="0" name="H"/>
+ <anchor x="540" y="-100" name="L"/>
+ <anchor x="1125" y="0" name="O"/>
+ <anchor x="1120" y="1000" name="R"/>
+ <anchor x="540" y="1635" name="U"/>
+ <outline>
+ <component base="LtnSmA"/>
+ <component base="CombGrave" xOffset="1090"/>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfdeleteglyphs.ufo/glyphs/L_tnS_mA_R_ingA_bv.glif b/tests/reference/ufo/psfdeleteglyphs.ufo/glyphs/L_tnS_mA_R_ingA_bv.glif
new file mode 100644
index 0000000..ae3b838
--- /dev/null
+++ b/tests/reference/ufo/psfdeleteglyphs.ufo/glyphs/L_tnS_mA_R_ingA_bv.glif
@@ -0,0 +1,41 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmARingAbv" format="2">
+ <advance width="1120"/>
+ <unicode hex="00E5"/>
+ <anchor x="540" y="0" name="H"/>
+ <anchor x="540" y="-100" name="L"/>
+ <anchor x="1125" y="0" name="O"/>
+ <anchor x="1120" y="1000" name="R"/>
+ <anchor x="542" y="1635" name="U"/>
+ <outline>
+ <component base="LtnSmA"/>
+ <contour>
+ <point x="642" y="1385" type="curve" smooth="yes"/>
+ <point x="642" y="1325"/>
+ <point x="602" y="1285"/>
+ <point x="542" y="1285" type="curve" smooth="yes"/>
+ <point x="482" y="1285"/>
+ <point x="442" y="1325"/>
+ <point x="442" y="1385" type="curve" smooth="yes"/>
+ <point x="442" y="1445"/>
+ <point x="482" y="1485"/>
+ <point x="542" y="1485" type="curve" smooth="yes"/>
+ <point x="602" y="1485"/>
+ <point x="642" y="1445"/>
+ </contour>
+ <contour>
+ <point x="327" y="1385" type="curve" smooth="yes"/>
+ <point x="327" y="1265"/>
+ <point x="422" y="1170"/>
+ <point x="542" y="1170" type="curve" smooth="yes"/>
+ <point x="662" y="1170"/>
+ <point x="757" y="1265"/>
+ <point x="757" y="1385" type="curve" smooth="yes"/>
+ <point x="757" y="1505"/>
+ <point x="662" y="1600"/>
+ <point x="542" y="1600" type="curve" smooth="yes"/>
+ <point x="422" y="1600"/>
+ <point x="327" y="1505"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfdeleteglyphs.ufo/glyphs/L_tnS_mA_T_ilde.glif b/tests/reference/ufo/psfdeleteglyphs.ufo/glyphs/L_tnS_mA_T_ilde.glif
new file mode 100644
index 0000000..cf21919
--- /dev/null
+++ b/tests/reference/ufo/psfdeleteglyphs.ufo/glyphs/L_tnS_mA_T_ilde.glif
@@ -0,0 +1,41 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmATilde" format="2">
+ <advance width="1120"/>
+ <unicode hex="00E3"/>
+ <anchor x="540" y="0" name="H"/>
+ <anchor x="540" y="-100" name="L"/>
+ <anchor x="1125" y="0" name="O"/>
+ <anchor x="1120" y="1000" name="R"/>
+ <anchor x="540" y="1475" name="U"/>
+ <outline>
+ <component base="LtnSmA"/>
+ <contour>
+ <point x="295" y="1205" type="line"/>
+ <point x="300" y="1254"/>
+ <point x="331" y="1290"/>
+ <point x="380" y="1290" type="curve" smooth="yes"/>
+ <point x="417" y="1290"/>
+ <point x="458" y="1274"/>
+ <point x="535" y="1238" type="curve" smooth="yes"/>
+ <point x="596" y="1210"/>
+ <point x="649" y="1190"/>
+ <point x="702" y="1190" type="curve" smooth="yes"/>
+ <point x="825" y="1190"/>
+ <point x="900" y="1312"/>
+ <point x="900" y="1440" type="curve"/>
+ <point x="795" y="1440" type="line"/>
+ <point x="788" y="1394"/>
+ <point x="757" y="1355"/>
+ <point x="710" y="1355" type="curve" smooth="yes"/>
+ <point x="668" y="1355"/>
+ <point x="627" y="1374"/>
+ <point x="555" y="1403" type="curve" smooth="yes"/>
+ <point x="485" y="1431"/>
+ <point x="438" y="1455"/>
+ <point x="382" y="1455" type="curve" smooth="yes"/>
+ <point x="263" y="1455"/>
+ <point x="190" y="1327"/>
+ <point x="190" y="1205" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfdeleteglyphs.ufo/glyphs/L_tnS_mB_.glif b/tests/reference/ufo/psfdeleteglyphs.ufo/glyphs/L_tnS_mB_.glif
new file mode 100644
index 0000000..67ff8ac
--- /dev/null
+++ b/tests/reference/ufo/psfdeleteglyphs.ufo/glyphs/L_tnS_mB_.glif
@@ -0,0 +1,50 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmB" format="2">
+ <advance width="1155"/>
+ <unicode hex="0062"/>
+ <anchor x="590" y="0" name="H"/>
+ <anchor x="590" y="-100" name="L"/>
+ <anchor x="1155" y="1000" name="R"/>
+ <anchor x="590" y="1635" name="U"/>
+ <outline>
+ <contour>
+ <point x="130" y="1600" type="line"/>
+ <point x="145" y="1488"/>
+ <point x="145" y="1273"/>
+ <point x="145" y="1130" type="curve" smooth="yes"/>
+ <point x="145" y="936"/>
+ <point x="145" y="228"/>
+ <point x="145" y="65" type="curve"/>
+ <point x="272" y="26"/>
+ <point x="413" y="-25"/>
+ <point x="575" y="-25" type="curve" smooth="yes"/>
+ <point x="870" y="-25"/>
+ <point x="1060" y="197"/>
+ <point x="1060" y="540" type="curve" smooth="yes"/>
+ <point x="1060" y="832"/>
+ <point x="917" y="1040"/>
+ <point x="715" y="1040" type="curve" smooth="yes"/>
+ <point x="547" y="1040"/>
+ <point x="423" y="947"/>
+ <point x="330" y="825" type="curve"/>
+ <point x="330" y="916"/>
+ <point x="330" y="1600"/>
+ <point x="330" y="1600" type="curve"/>
+ </contour>
+ <contour>
+ <point x="330" y="585" type="line"/>
+ <point x="398" y="751"/>
+ <point x="531" y="865"/>
+ <point x="655" y="865" type="curve" smooth="yes"/>
+ <point x="799" y="865"/>
+ <point x="880" y="727"/>
+ <point x="880" y="505" type="curve" smooth="yes"/>
+ <point x="880" y="280"/>
+ <point x="752" y="130"/>
+ <point x="575" y="130" type="curve" smooth="yes"/>
+ <point x="489" y="130"/>
+ <point x="428" y="144"/>
+ <point x="330" y="185" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfdeleteglyphs.ufo/glyphs/L_tnS_mC_.glif b/tests/reference/ufo/psfdeleteglyphs.ufo/glyphs/L_tnS_mC_.glif
new file mode 100644
index 0000000..7c403fb
--- /dev/null
+++ b/tests/reference/ufo/psfdeleteglyphs.ufo/glyphs/L_tnS_mC_.glif
@@ -0,0 +1,39 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmC" format="2">
+ <advance width="1020"/>
+ <unicode hex="0063"/>
+ <anchor x="580" y="0" name="H"/>
+ <anchor x="580" y="-100" name="L"/>
+ <anchor x="1020" y="1000" name="R"/>
+ <anchor x="570" y="1100" name="U"/>
+ <outline>
+ <contour>
+ <point x="905" y="260" type="line"/>
+ <point x="818" y="183"/>
+ <point x="720" y="140"/>
+ <point x="600" y="140" type="curve" smooth="yes"/>
+ <point x="406" y="140"/>
+ <point x="285" y="285"/>
+ <point x="285" y="500" type="curve" smooth="yes"/>
+ <point x="285" y="736"/>
+ <point x="422" y="875"/>
+ <point x="600" y="875" type="curve" smooth="yes"/>
+ <point x="703" y="875"/>
+ <point x="790" y="841"/>
+ <point x="880" y="775" type="curve"/>
+ <point x="915" y="955" type="line"/>
+ <point x="842" y="1005"/>
+ <point x="748" y="1040"/>
+ <point x="615" y="1040" type="curve" smooth="yes"/>
+ <point x="297" y="1040"/>
+ <point x="95" y="792"/>
+ <point x="95" y="490" type="curve" smooth="yes"/>
+ <point x="95" y="171"/>
+ <point x="312" y="-25"/>
+ <point x="580" y="-25" type="curve" smooth="yes"/>
+ <point x="730" y="-25"/>
+ <point x="824" y="9"/>
+ <point x="925" y="85" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfdeleteglyphs.ufo/glyphs/L_tnS_mD_.glif b/tests/reference/ufo/psfdeleteglyphs.ufo/glyphs/L_tnS_mD_.glif
new file mode 100644
index 0000000..13547d4
--- /dev/null
+++ b/tests/reference/ufo/psfdeleteglyphs.ufo/glyphs/L_tnS_mD_.glif
@@ -0,0 +1,53 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmD" format="2">
+ <advance width="1190"/>
+ <unicode hex="0064"/>
+ <anchor x="605" y="0" name="H"/>
+ <anchor x="605" y="-100" name="L"/>
+ <anchor x="1190" y="1000" name="R"/>
+ <anchor x="605" y="1635" name="U"/>
+ <outline>
+ <contour>
+ <point x="1030" y="1600" type="line"/>
+ <point x="820" y="1600" type="line"/>
+ <point x="839" y="1516"/>
+ <point x="845" y="1395"/>
+ <point x="845" y="1235" type="curve"/>
+ <point x="845" y="955" type="line"/>
+ <point x="767" y="999"/>
+ <point x="665" y="1040"/>
+ <point x="580" y="1040" type="curve" smooth="yes"/>
+ <point x="312" y="1040"/>
+ <point x="105" y="814"/>
+ <point x="105" y="460" type="curve" smooth="yes"/>
+ <point x="105" y="167"/>
+ <point x="261" y="-25"/>
+ <point x="505" y="-25" type="curve" smooth="yes"/>
+ <point x="652" y="-25"/>
+ <point x="775" y="50"/>
+ <point x="870" y="185" type="curve"/>
+ <point x="887" y="111"/>
+ <point x="910" y="34"/>
+ <point x="925" y="0" type="curve"/>
+ <point x="1105" y="0" type="line"/>
+ <point x="1062" y="112"/>
+ <point x="1030" y="278"/>
+ <point x="1030" y="530" type="curve"/>
+ </contour>
+ <contour>
+ <point x="845" y="400" type="line"/>
+ <point x="790" y="268"/>
+ <point x="662" y="135"/>
+ <point x="540" y="135" type="curve" smooth="yes"/>
+ <point x="366" y="135"/>
+ <point x="290" y="258"/>
+ <point x="290" y="490" type="curve" smooth="yes"/>
+ <point x="290" y="727"/>
+ <point x="429" y="870"/>
+ <point x="580" y="870" type="curve" smooth="yes"/>
+ <point x="681" y="870"/>
+ <point x="746" y="848"/>
+ <point x="845" y="795" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfdeleteglyphs.ufo/glyphs/L_tnS_mE_.glif b/tests/reference/ufo/psfdeleteglyphs.ufo/glyphs/L_tnS_mE_.glif
new file mode 100644
index 0000000..f231440
--- /dev/null
+++ b/tests/reference/ufo/psfdeleteglyphs.ufo/glyphs/L_tnS_mE_.glif
@@ -0,0 +1,45 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmE" format="2">
+ <advance width="1095"/>
+ <unicode hex="0065"/>
+ <anchor x="545" y="0" name="H"/>
+ <anchor x="569" y="-100" name="L"/>
+ <anchor x="925" y="0" name="O"/>
+ <anchor x="1095" y="1000" name="R"/>
+ <anchor x="569" y="1100" name="U"/>
+ <outline>
+ <contour>
+ <point x="989" y="485" type="line"/>
+ <point x="990" y="503"/>
+ <point x="990" y="545"/>
+ <point x="990" y="563" type="curve" smooth="yes"/>
+ <point x="990" y="788"/>
+ <point x="905" y="1040"/>
+ <point x="575" y="1040" type="curve" smooth="yes"/>
+ <point x="279" y="1040"/>
+ <point x="95" y="826"/>
+ <point x="95" y="495" type="curve" smooth="yes"/>
+ <point x="95" y="155"/>
+ <point x="320" y="-25"/>
+ <point x="575" y="-25" type="curve" smooth="yes"/>
+ <point x="729" y="-25"/>
+ <point x="853" y="2"/>
+ <point x="995" y="75" type="curve"/>
+ <point x="975" y="240" type="line"/>
+ <point x="853" y="166"/>
+ <point x="729" y="140"/>
+ <point x="600" y="140" type="curve" smooth="yes"/>
+ <point x="414" y="140"/>
+ <point x="280" y="258"/>
+ <point x="280" y="505" type="curve" smooth="yes"/>
+ <point x="280" y="770"/>
+ <point x="385" y="890"/>
+ <point x="560" y="890" type="curve" smooth="yes"/>
+ <point x="705" y="890"/>
+ <point x="810" y="797"/>
+ <point x="810" y="625" type="curve"/>
+ <point x="245" y="625" type="line"/>
+ <point x="245" y="485" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfdeleteglyphs.ufo/glyphs/L_tnS_mF_.glif b/tests/reference/ufo/psfdeleteglyphs.ufo/glyphs/L_tnS_mF_.glif
new file mode 100644
index 0000000..56c0b15
--- /dev/null
+++ b/tests/reference/ufo/psfdeleteglyphs.ufo/glyphs/L_tnS_mF_.glif
@@ -0,0 +1,39 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmF" format="2">
+ <advance width="750"/>
+ <unicode hex="0066"/>
+ <anchor x="370" y="0" name="H"/>
+ <anchor x="335" y="-100" name="L"/>
+ <anchor x="560" y="1635" name="U"/>
+ <outline>
+ <contour>
+ <point x="40" y="850" type="line"/>
+ <point x="240" y="850" type="line"/>
+ <point x="240" y="0" type="line"/>
+ <point x="455" y="0" type="line"/>
+ <point x="433" y="105"/>
+ <point x="425" y="300"/>
+ <point x="425" y="494" type="curve" smooth="yes"/>
+ <point x="425" y="850" type="line"/>
+ <point x="695" y="850" type="line"/>
+ <point x="695" y="995" type="line"/>
+ <point x="425" y="995" type="line"/>
+ <point x="425" y="1210" type="line" smooth="yes"/>
+ <point x="425" y="1381"/>
+ <point x="481" y="1450"/>
+ <point x="585" y="1450" type="curve" smooth="yes"/>
+ <point x="643" y="1450"/>
+ <point x="710" y="1427"/>
+ <point x="760" y="1390" type="curve"/>
+ <point x="805" y="1550" type="line"/>
+ <point x="743" y="1594"/>
+ <point x="663" y="1620"/>
+ <point x="585" y="1620" type="curve" smooth="yes"/>
+ <point x="369" y="1620"/>
+ <point x="240" y="1470"/>
+ <point x="240" y="1170" type="curve" smooth="yes"/>
+ <point x="240" y="995" type="line"/>
+ <point x="40" y="995" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfdeleteglyphs.ufo/glyphs/L_tnS_mG_.glif b/tests/reference/ufo/psfdeleteglyphs.ufo/glyphs/L_tnS_mG_.glif
new file mode 100644
index 0000000..236da64
--- /dev/null
+++ b/tests/reference/ufo/psfdeleteglyphs.ufo/glyphs/L_tnS_mG_.glif
@@ -0,0 +1,91 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmG" format="2">
+ <advance width="1095"/>
+ <unicode hex="0067"/>
+ <anchor x="545" y="-432" name="H"/>
+ <anchor x="545" y="-535" name="L"/>
+ <anchor x="1095" y="1000" name="R"/>
+ <anchor x="515" y="1100" name="U"/>
+ <outline>
+ <contour>
+ <point x="330" y="395" type="line"/>
+ <point x="234" y="357"/>
+ <point x="180" y="275"/>
+ <point x="180" y="215" type="curve" smooth="yes"/>
+ <point x="180" y="121"/>
+ <point x="263" y="27"/>
+ <point x="545" y="-5" type="curve" smooth="yes"/>
+ <point x="805" y="-35"/>
+ <point x="880" y="-90"/>
+ <point x="880" y="-170" type="curve" smooth="yes"/>
+ <point x="880" y="-255"/>
+ <point x="731" y="-360"/>
+ <point x="550" y="-360" type="curve" smooth="yes"/>
+ <point x="323" y="-360"/>
+ <point x="215" y="-261"/>
+ <point x="215" y="-180" type="curve" smooth="yes"/>
+ <point x="215" y="-121"/>
+ <point x="244" y="-56"/>
+ <point x="465" y="20" type="curve"/>
+ <point x="459" y="49"/>
+ <point x="290" y="75"/>
+ <point x="290" y="75" type="curve"/>
+ <point x="113" y="2"/>
+ <point x="30" y="-89"/>
+ <point x="30" y="-200" type="curve" smooth="yes"/>
+ <point x="30" y="-409"/>
+ <point x="303" y="-505"/>
+ <point x="535" y="-505" type="curve" smooth="yes"/>
+ <point x="777" y="-505"/>
+ <point x="1065" y="-375"/>
+ <point x="1065" y="-160" type="curve" smooth="yes"/>
+ <point x="1065" y="-8"/>
+ <point x="967" y="90"/>
+ <point x="670" y="125" type="curve" smooth="yes"/>
+ <point x="410" y="156"/>
+ <point x="345" y="198"/>
+ <point x="345" y="235" type="curve" smooth="yes"/>
+ <point x="345" y="271"/>
+ <point x="384" y="316"/>
+ <point x="500" y="350" type="curve"/>
+ </contour>
+ <contour>
+ <point x="1050" y="1040" type="line"/>
+ <point x="951" y="1033"/>
+ <point x="819" y="997"/>
+ <point x="730" y="940" type="curve"/>
+ <point x="795" y="825" type="line"/>
+ <point x="887" y="863"/>
+ <point x="967" y="878"/>
+ <point x="1040" y="880" type="curve"/>
+ </contour>
+ <contour>
+ <point x="115" y="680" type="curve" smooth="yes"/>
+ <point x="115" y="476"/>
+ <point x="289" y="325"/>
+ <point x="515" y="325" type="curve" smooth="yes"/>
+ <point x="742" y="325"/>
+ <point x="915" y="476"/>
+ <point x="915" y="680" type="curve" smooth="yes"/>
+ <point x="915" y="884"/>
+ <point x="742" y="1040"/>
+ <point x="515" y="1040" type="curve" smooth="yes"/>
+ <point x="289" y="1040"/>
+ <point x="115" y="884"/>
+ </contour>
+ <contour>
+ <point x="285" y="680" type="curve" smooth="yes"/>
+ <point x="285" y="803"/>
+ <point x="382" y="895"/>
+ <point x="515" y="895" type="curve" smooth="yes"/>
+ <point x="649" y="895"/>
+ <point x="745" y="803"/>
+ <point x="745" y="680" type="curve" smooth="yes"/>
+ <point x="745" y="557"/>
+ <point x="649" y="465"/>
+ <point x="515" y="465" type="curve" smooth="yes"/>
+ <point x="382" y="465"/>
+ <point x="285" y="557"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfdeleteglyphs.ufo/glyphs/L_tnS_mH_.glif b/tests/reference/ufo/psfdeleteglyphs.ufo/glyphs/L_tnS_mH_.glif
new file mode 100644
index 0000000..bad060c
--- /dev/null
+++ b/tests/reference/ufo/psfdeleteglyphs.ufo/glyphs/L_tnS_mH_.glif
@@ -0,0 +1,43 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmH" format="2">
+ <advance width="1175"/>
+ <unicode hex="0068"/>
+ <anchor x="250" y="0" name="H"/>
+ <anchor x="585" y="-100" name="L"/>
+ <anchor x="585" y="1635" name="U"/>
+ <outline>
+ <contour>
+ <point x="1040" y="0" type="line"/>
+ <point x="1040" y="0"/>
+ <point x="1040" y="459"/>
+ <point x="1040" y="625" type="curve" smooth="yes"/>
+ <point x="1040" y="900"/>
+ <point x="923" y="1040"/>
+ <point x="710" y="1040" type="curve" smooth="yes"/>
+ <point x="570" y="1040"/>
+ <point x="428" y="969"/>
+ <point x="330" y="830" type="curve"/>
+ <point x="330" y="877"/>
+ <point x="330" y="1600"/>
+ <point x="330" y="1600" type="curve"/>
+ <point x="130" y="1600" type="line"/>
+ <point x="145" y="1514"/>
+ <point x="145" y="1345"/>
+ <point x="145" y="1130" type="curve" smooth="yes"/>
+ <point x="145" y="935"/>
+ <point x="145" y="0"/>
+ <point x="145" y="0" type="curve"/>
+ <point x="330" y="0" type="line"/>
+ <point x="330" y="580" type="line"/>
+ <point x="374" y="716"/>
+ <point x="511" y="865"/>
+ <point x="655" y="865" type="curve" smooth="yes"/>
+ <point x="789" y="865"/>
+ <point x="855" y="800"/>
+ <point x="855" y="550" type="curve" smooth="yes"/>
+ <point x="855" y="413"/>
+ <point x="855" y="0"/>
+ <point x="855" y="0" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfdeleteglyphs.ufo/glyphs/L_tnS_mI_.glif b/tests/reference/ufo/psfdeleteglyphs.ufo/glyphs/L_tnS_mI_.glif
new file mode 100644
index 0000000..369347b
--- /dev/null
+++ b/tests/reference/ufo/psfdeleteglyphs.ufo/glyphs/L_tnS_mI_.glif
@@ -0,0 +1,40 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmI" format="2">
+ <advance width="565"/>
+ <unicode hex="0069"/>
+ <anchor x="282" y="0" name="H"/>
+ <anchor x="285" y="-100" name="L"/>
+ <anchor x="500" y="0" name="O"/>
+ <anchor x="555" y="1000" name="R"/>
+ <anchor x="282" y="1100" name="U"/>
+ <outline>
+ <contour>
+ <point x="375" y="1020" type="line"/>
+ <point x="175" y="1020" type="line"/>
+ <point x="188" y="915"/>
+ <point x="190" y="725"/>
+ <point x="190" y="530" type="curve" smooth="yes"/>
+ <point x="190" y="336"/>
+ <point x="190" y="0"/>
+ <point x="190" y="0" type="curve"/>
+ <point x="395" y="0" type="line"/>
+ <point x="382" y="107"/>
+ <point x="375" y="346"/>
+ <point x="375" y="475" type="curve" smooth="yes"/>
+ </contour>
+ <contour>
+ <point x="155" y="1345" type="curve" smooth="yes"/>
+ <point x="155" y="1271"/>
+ <point x="206" y="1210"/>
+ <point x="280" y="1210" type="curve" smooth="yes"/>
+ <point x="355" y="1210"/>
+ <point x="410" y="1271"/>
+ <point x="410" y="1345" type="curve" smooth="yes"/>
+ <point x="410" y="1419"/>
+ <point x="355" y="1480"/>
+ <point x="280" y="1480" type="curve" smooth="yes"/>
+ <point x="206" y="1480"/>
+ <point x="155" y="1419"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfdeleteglyphs.ufo/glyphs/L_tnS_mJ_.glif b/tests/reference/ufo/psfdeleteglyphs.ufo/glyphs/L_tnS_mJ_.glif
new file mode 100644
index 0000000..87f74c6
--- /dev/null
+++ b/tests/reference/ufo/psfdeleteglyphs.ufo/glyphs/L_tnS_mJ_.glif
@@ -0,0 +1,44 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmJ" format="2">
+ <advance width="595"/>
+ <unicode hex="006A"/>
+ <anchor x="125" y="-500" name="L"/>
+ <anchor x="313" y="1100" name="U"/>
+ <outline>
+ <contour>
+ <point x="405" y="1020" type="line"/>
+ <point x="205" y="1020" type="line"/>
+ <point x="218" y="915"/>
+ <point x="220" y="725"/>
+ <point x="220" y="530" type="curve"/>
+ <point x="220" y="-25" type="line"/>
+ <point x="220" y="-222"/>
+ <point x="147" y="-300"/>
+ <point x="40" y="-300" type="curve" smooth="yes"/>
+ <point x="-16" y="-300"/>
+ <point x="-111" y="-273"/>
+ <point x="-155" y="-240" type="curve"/>
+ <point x="-190" y="-405" type="line"/>
+ <point x="-130" y="-446"/>
+ <point x="-26" y="-470"/>
+ <point x="30" y="-470" type="curve" smooth="yes"/>
+ <point x="258" y="-470"/>
+ <point x="405" y="-348"/>
+ <point x="405" y="25" type="curve" smooth="yes"/>
+ </contour>
+ <contour>
+ <point x="185" y="1345" type="curve" smooth="yes"/>
+ <point x="185" y="1271"/>
+ <point x="236" y="1210"/>
+ <point x="310" y="1210" type="curve" smooth="yes"/>
+ <point x="385" y="1210"/>
+ <point x="440" y="1271"/>
+ <point x="440" y="1345" type="curve" smooth="yes"/>
+ <point x="440" y="1419"/>
+ <point x="385" y="1480"/>
+ <point x="310" y="1480" type="curve" smooth="yes"/>
+ <point x="236" y="1480"/>
+ <point x="185" y="1419"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfdeleteglyphs.ufo/glyphs/L_tnS_mK_.glif b/tests/reference/ufo/psfdeleteglyphs.ufo/glyphs/L_tnS_mK_.glif
new file mode 100644
index 0000000..d1b00cb
--- /dev/null
+++ b/tests/reference/ufo/psfdeleteglyphs.ufo/glyphs/L_tnS_mK_.glif
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmK" format="2">
+ <advance width="1035"/>
+ <unicode hex="006B"/>
+ <guideline x="500" y="774" angle="314"/>
+ <anchor x="243" y="0" name="H"/>
+ <anchor x="572" y="-100" name="L"/>
+ <anchor x="1035" y="1000" name="R"/>
+ <anchor x="572" y="1635" name="U"/>
+ <outline>
+ <contour>
+ <point x="330" y="0" type="line"/>
+ <point x="330" y="1600" type="line"/>
+ <point x="130" y="1600" type="line"/>
+ <point x="145" y="1514"/>
+ <point x="145" y="1345"/>
+ <point x="145" y="1130" type="curve" smooth="yes"/>
+ <point x="145" y="934"/>
+ <point x="145" y="0"/>
+ <point x="145" y="0" type="curve"/>
+ </contour>
+ <contour>
+ <point x="735" y="1020" type="line"/>
+ <point x="280" y="550" type="line"/>
+ <point x="436" y="524" type="line"/>
+ <point x="985" y="1020" type="line"/>
+ </contour>
+ <contour>
+ <point x="305" y="550" type="line"/>
+ <point x="770" y="0" type="line"/>
+ <point x="1015" y="0" type="line"/>
+ <point x="410" y="660" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfdeleteglyphs.ufo/glyphs/L_tnS_mL_.glif b/tests/reference/ufo/psfdeleteglyphs.ufo/glyphs/L_tnS_mL_.glif
new file mode 100644
index 0000000..4378793
--- /dev/null
+++ b/tests/reference/ufo/psfdeleteglyphs.ufo/glyphs/L_tnS_mL_.glif
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmL" format="2">
+ <advance width="565"/>
+ <unicode hex="006C"/>
+ <guideline x="500" y="874" angle="340"/>
+ <anchor x="290" y="0" name="H"/>
+ <anchor x="290" y="-100" name="L"/>
+ <anchor x="550" y="1000" name="R"/>
+ <anchor x="282" y="1635" name="U"/>
+ <outline>
+ <contour>
+ <point x="375" y="1600" type="line"/>
+ <point x="170" y="1600" type="line"/>
+ <point x="183" y="1485"/>
+ <point x="190" y="1324"/>
+ <point x="190" y="1130" type="curve"/>
+ <point x="190" y="0" type="line"/>
+ <point x="395" y="0" type="line"/>
+ <point x="382" y="109"/>
+ <point x="375" y="346"/>
+ <point x="375" y="475" type="curve" smooth="yes"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfdeleteglyphs.ufo/glyphs/L_tnS_mM_.glif b/tests/reference/ufo/psfdeleteglyphs.ufo/glyphs/L_tnS_mM_.glif
new file mode 100644
index 0000000..4498bb1
--- /dev/null
+++ b/tests/reference/ufo/psfdeleteglyphs.ufo/glyphs/L_tnS_mM_.glif
@@ -0,0 +1,52 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmM" format="2">
+ <advance width="1685"/>
+ <unicode hex="006D"/>
+ <anchor x="1450" y="0" name="H"/>
+ <anchor x="865" y="-100" name="L"/>
+ <anchor x="865" y="1100" name="U"/>
+ <outline>
+ <contour>
+ <point x="945" y="660" type="line"/>
+ <point x="1003" y="785"/>
+ <point x="1102" y="865"/>
+ <point x="1200" y="865" type="curve" smooth="yes"/>
+ <point x="1312" y="865"/>
+ <point x="1345" y="808"/>
+ <point x="1345" y="550" type="curve" smooth="yes"/>
+ <point x="1345" y="0" type="line"/>
+ <point x="1530" y="0" type="line"/>
+ <point x="1530" y="660" type="line" smooth="yes"/>
+ <point x="1530" y="907"/>
+ <point x="1463" y="1040"/>
+ <point x="1260" y="1040" type="curve" smooth="yes"/>
+ <point x="1155" y="1040"/>
+ <point x="1046" y="1007"/>
+ <point x="921" y="872" type="curve"/>
+ <point x="888" y="960"/>
+ <point x="806" y="1040"/>
+ <point x="675" y="1040" type="curve" smooth="yes"/>
+ <point x="560" y="1040"/>
+ <point x="459" y="1006"/>
+ <point x="337" y="865" type="curve"/>
+ <point x="330" y="913"/>
+ <point x="320" y="978"/>
+ <point x="305" y="1020" type="curve"/>
+ <point x="125" y="1020" type="line"/>
+ <point x="146" y="951"/>
+ <point x="175" y="811"/>
+ <point x="175" y="615" type="curve" smooth="yes"/>
+ <point x="175" y="0" type="line"/>
+ <point x="360" y="0" type="line"/>
+ <point x="360" y="660" type="line"/>
+ <point x="413" y="780"/>
+ <point x="517" y="865"/>
+ <point x="615" y="865" type="curve" smooth="yes"/>
+ <point x="727" y="865"/>
+ <point x="760" y="818"/>
+ <point x="760" y="570" type="curve" smooth="yes"/>
+ <point x="760" y="0" type="line"/>
+ <point x="945" y="0" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfdeleteglyphs.ufo/glyphs/L_tnS_mN_.glif b/tests/reference/ufo/psfdeleteglyphs.ufo/glyphs/L_tnS_mN_.glif
new file mode 100644
index 0000000..5534dd8
--- /dev/null
+++ b/tests/reference/ufo/psfdeleteglyphs.ufo/glyphs/L_tnS_mN_.glif
@@ -0,0 +1,43 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmN" format="2">
+ <advance width="1185"/>
+ <unicode hex="006E"/>
+ <anchor x="970" y="0" name="H"/>
+ <anchor x="600" y="-100" name="L"/>
+ <anchor x="600" y="1100" name="U"/>
+ <outline>
+ <contour>
+ <point x="1050" y="0" type="line"/>
+ <point x="1050" y="0"/>
+ <point x="1050" y="459"/>
+ <point x="1050" y="625" type="curve" smooth="yes"/>
+ <point x="1050" y="900"/>
+ <point x="933" y="1040"/>
+ <point x="720" y="1040" type="curve" smooth="yes"/>
+ <point x="579" y="1040"/>
+ <point x="452" y="977"/>
+ <point x="325" y="825" type="curve"/>
+ <point x="318" y="873"/>
+ <point x="300" y="978"/>
+ <point x="285" y="1020" type="curve"/>
+ <point x="105" y="1020" type="line"/>
+ <point x="127" y="951"/>
+ <point x="155" y="811"/>
+ <point x="155" y="615" type="curve" smooth="yes"/>
+ <point x="155" y="420"/>
+ <point x="155" y="0"/>
+ <point x="155" y="0" type="curve"/>
+ <point x="340" y="0" type="line"/>
+ <point x="340" y="580" type="line"/>
+ <point x="384" y="716"/>
+ <point x="521" y="865"/>
+ <point x="665" y="865" type="curve" smooth="yes"/>
+ <point x="800" y="865"/>
+ <point x="865" y="800"/>
+ <point x="865" y="550" type="curve" smooth="yes"/>
+ <point x="865" y="413"/>
+ <point x="865" y="0"/>
+ <point x="865" y="0" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfdeleteglyphs.ufo/glyphs/L_tnS_mO_.glif b/tests/reference/ufo/psfdeleteglyphs.ufo/glyphs/L_tnS_mO_.glif
new file mode 100644
index 0000000..ee9b6c6
--- /dev/null
+++ b/tests/reference/ufo/psfdeleteglyphs.ufo/glyphs/L_tnS_mO_.glif
@@ -0,0 +1,40 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmO" format="2">
+ <advance width="1140"/>
+ <unicode hex="006F"/>
+ <anchor x="570" y="0" name="H"/>
+ <anchor x="570" y="-100" name="L"/>
+ <anchor x="835" y="0" name="O"/>
+ <anchor x="1140" y="1000" name="R"/>
+ <anchor x="570" y="1100" name="U"/>
+ <outline>
+ <contour>
+ <point x="95" y="505" type="curve" smooth="yes"/>
+ <point x="95" y="161"/>
+ <point x="286" y="-25"/>
+ <point x="560" y="-25" type="curve" smooth="yes"/>
+ <point x="823" y="-25"/>
+ <point x="1045" y="161"/>
+ <point x="1045" y="505" type="curve" smooth="yes"/>
+ <point x="1045" y="849"/>
+ <point x="855" y="1040"/>
+ <point x="580" y="1040" type="curve" smooth="yes"/>
+ <point x="317" y="1040"/>
+ <point x="95" y="849"/>
+ </contour>
+ <contour>
+ <point x="280" y="505" type="curve" smooth="yes"/>
+ <point x="280" y="739"/>
+ <point x="408" y="880"/>
+ <point x="570" y="880" type="curve" smooth="yes"/>
+ <point x="742" y="880"/>
+ <point x="860" y="739"/>
+ <point x="860" y="505" type="curve" smooth="yes"/>
+ <point x="860" y="272"/>
+ <point x="731" y="135"/>
+ <point x="570" y="135" type="curve" smooth="yes"/>
+ <point x="398" y="135"/>
+ <point x="280" y="272"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfdeleteglyphs.ufo/glyphs/L_tnS_mP_.glif b/tests/reference/ufo/psfdeleteglyphs.ufo/glyphs/L_tnS_mP_.glif
new file mode 100644
index 0000000..e960bc9
--- /dev/null
+++ b/tests/reference/ufo/psfdeleteglyphs.ufo/glyphs/L_tnS_mP_.glif
@@ -0,0 +1,56 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmP" format="2">
+ <advance width="1170"/>
+ <unicode hex="0070"/>
+ <guideline x="214" y="-490" angle="0"/>
+ <anchor x="265" y="-435" name="H"/>
+ <anchor x="590" y="-500" name="L"/>
+ <anchor x="1170" y="1000" name="R"/>
+ <anchor x="590" y="1100" name="U"/>
+ <outline>
+ <contour>
+ <point x="105" y="1020" type="line"/>
+ <point x="150" y="907"/>
+ <point x="155" y="734"/>
+ <point x="155" y="485" type="curve" smooth="yes"/>
+ <point x="155" y="291"/>
+ <point x="155" y="-490"/>
+ <point x="155" y="-490" type="curve"/>
+ <point x="365" y="-490" type="line"/>
+ <point x="348" y="-405"/>
+ <point x="340" y="-310"/>
+ <point x="340" y="-150" type="curve"/>
+ <point x="340" y="85" type="line"/>
+ <point x="435" y="18"/>
+ <point x="513" y="-25"/>
+ <point x="620" y="-25" type="curve" smooth="yes"/>
+ <point x="871" y="-25"/>
+ <point x="1075" y="193"/>
+ <point x="1075" y="535" type="curve" smooth="yes"/>
+ <point x="1075" y="828"/>
+ <point x="923" y="1040"/>
+ <point x="695" y="1040" type="curve" smooth="yes"/>
+ <point x="547" y="1040"/>
+ <point x="419" y="954"/>
+ <point x="325" y="830" type="curve"/>
+ <point x="316" y="922"/>
+ <point x="300" y="986"/>
+ <point x="285" y="1020" type="curve"/>
+ </contour>
+ <contour>
+ <point x="340" y="575" type="line"/>
+ <point x="414" y="768"/>
+ <point x="545" y="870"/>
+ <point x="660" y="870" type="curve" smooth="yes"/>
+ <point x="804" y="870"/>
+ <point x="890" y="727"/>
+ <point x="890" y="505" type="curve" smooth="yes"/>
+ <point x="890" y="279"/>
+ <point x="761" y="140"/>
+ <point x="620" y="140" type="curve" smooth="yes"/>
+ <point x="528" y="140"/>
+ <point x="477" y="164"/>
+ <point x="340" y="260" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfdeleteglyphs.ufo/glyphs/L_tnS_mQ_.glif b/tests/reference/ufo/psfdeleteglyphs.ufo/glyphs/L_tnS_mQ_.glif
new file mode 100644
index 0000000..1da1d6a
--- /dev/null
+++ b/tests/reference/ufo/psfdeleteglyphs.ufo/glyphs/L_tnS_mQ_.glif
@@ -0,0 +1,47 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmQ" format="2">
+ <advance width="1130"/>
+ <unicode hex="0071"/>
+ <anchor x="555" y="-500" name="L"/>
+ <anchor x="1130" y="1000" name="R"/>
+ <anchor x="555" y="1100" name="U"/>
+ <outline>
+ <contour>
+ <point x="795" y="-490" type="line"/>
+ <point x="1005" y="-490" type="line"/>
+ <point x="988" y="-405"/>
+ <point x="980" y="-310"/>
+ <point x="980" y="-150" type="curve" smooth="yes"/>
+ <point x="980" y="-26"/>
+ <point x="980" y="965"/>
+ <point x="980" y="965" type="curve"/>
+ <point x="872" y="1001"/>
+ <point x="746" y="1040"/>
+ <point x="625" y="1040" type="curve" smooth="yes"/>
+ <point x="260" y="1040"/>
+ <point x="105" y="742"/>
+ <point x="105" y="435" type="curve" smooth="yes"/>
+ <point x="105" y="117"/>
+ <point x="321" y="-25"/>
+ <point x="505" y="-25" type="curve" smooth="yes"/>
+ <point x="598" y="-25"/>
+ <point x="691" y="19"/>
+ <point x="795" y="140" type="curve"/>
+ </contour>
+ <contour>
+ <point x="795" y="365" type="line"/>
+ <point x="713" y="219"/>
+ <point x="612" y="145"/>
+ <point x="520" y="145" type="curve" smooth="yes"/>
+ <point x="412" y="145"/>
+ <point x="290" y="237"/>
+ <point x="290" y="485" type="curve" smooth="yes"/>
+ <point x="290" y="674"/>
+ <point x="376" y="870"/>
+ <point x="595" y="870" type="curve" smooth="yes"/>
+ <point x="656" y="870"/>
+ <point x="735" y="853"/>
+ <point x="795" y="830" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfdeleteglyphs.ufo/glyphs/L_tnS_mR_.glif b/tests/reference/ufo/psfdeleteglyphs.ufo/glyphs/L_tnS_mR_.glif
new file mode 100644
index 0000000..0f090a4
--- /dev/null
+++ b/tests/reference/ufo/psfdeleteglyphs.ufo/glyphs/L_tnS_mR_.glif
@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmR" format="2">
+ <advance width="890"/>
+ <unicode hex="0072"/>
+ <guideline x="214" y="500" angle="0"/>
+ <anchor x="270" y="0" name="H"/>
+ <anchor x="255" y="-100" name="L"/>
+ <anchor x="455" y="1100" name="U"/>
+ <outline>
+ <contour>
+ <point x="340" y="0" type="line"/>
+ <point x="340" y="580" type="line"/>
+ <point x="384" y="716"/>
+ <point x="521" y="860"/>
+ <point x="605" y="860" type="curve" smooth="yes"/>
+ <point x="684" y="860"/>
+ <point x="720" y="770"/>
+ <point x="720" y="670" type="curve"/>
+ <point x="880" y="705" type="line"/>
+ <point x="880" y="880"/>
+ <point x="817" y="1040"/>
+ <point x="650" y="1040" type="curve" smooth="yes"/>
+ <point x="559" y="1040"/>
+ <point x="422" y="964"/>
+ <point x="325" y="825" type="curve"/>
+ <point x="318" y="873"/>
+ <point x="300" y="978"/>
+ <point x="285" y="1020" type="curve"/>
+ <point x="105" y="1020" type="line"/>
+ <point x="127" y="951"/>
+ <point x="155" y="811"/>
+ <point x="155" y="615" type="curve" smooth="yes"/>
+ <point x="155" y="0" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfdeleteglyphs.ufo/glyphs/L_tnS_mS_.glif b/tests/reference/ufo/psfdeleteglyphs.ufo/glyphs/L_tnS_mS_.glif
new file mode 100644
index 0000000..ea1e7ba
--- /dev/null
+++ b/tests/reference/ufo/psfdeleteglyphs.ufo/glyphs/L_tnS_mS_.glif
@@ -0,0 +1,50 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmS" format="2">
+ <advance width="965"/>
+ <unicode hex="0073"/>
+ <anchor x="495" y="0" name="H"/>
+ <anchor x="495" y="-100" name="L"/>
+ <anchor x="495" y="1100" name="U"/>
+ <outline>
+ <contour>
+ <point x="835" y="960" type="line"/>
+ <point x="766" y="998"/>
+ <point x="660" y="1040"/>
+ <point x="515" y="1040" type="curve" smooth="yes"/>
+ <point x="211" y="1040"/>
+ <point x="130" y="832"/>
+ <point x="130" y="740" type="curve" smooth="yes"/>
+ <point x="130" y="616"/>
+ <point x="182" y="514"/>
+ <point x="425" y="455" type="curve" smooth="yes"/>
+ <point x="649" y="400"/>
+ <point x="700" y="345"/>
+ <point x="700" y="270" type="curve" smooth="yes"/>
+ <point x="700" y="201"/>
+ <point x="617" y="135"/>
+ <point x="500" y="135" type="curve" smooth="yes"/>
+ <point x="394" y="135"/>
+ <point x="250" y="189"/>
+ <point x="160" y="270" type="curve"/>
+ <point x="110" y="90" type="line"/>
+ <point x="189" y="28"/>
+ <point x="333" y="-25"/>
+ <point x="495" y="-25" type="curve" smooth="yes"/>
+ <point x="710" y="-25"/>
+ <point x="880" y="115"/>
+ <point x="880" y="295" type="curve" smooth="yes"/>
+ <point x="880" y="481"/>
+ <point x="731" y="559"/>
+ <point x="550" y="600" type="curve" smooth="yes"/>
+ <point x="340" y="648"/>
+ <point x="310" y="680"/>
+ <point x="310" y="750" type="curve" smooth="yes"/>
+ <point x="310" y="810"/>
+ <point x="358" y="880"/>
+ <point x="505" y="880" type="curve" smooth="yes"/>
+ <point x="629" y="880"/>
+ <point x="733" y="824"/>
+ <point x="800" y="785" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfdeleteglyphs.ufo/glyphs/L_tnS_mT_.glif b/tests/reference/ufo/psfdeleteglyphs.ufo/glyphs/L_tnS_mT_.glif
new file mode 100644
index 0000000..45d6b50
--- /dev/null
+++ b/tests/reference/ufo/psfdeleteglyphs.ufo/glyphs/L_tnS_mT_.glif
@@ -0,0 +1,39 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmT" format="2">
+ <advance width="835"/>
+ <unicode hex="0074"/>
+ <anchor x="475" y="0" name="H"/>
+ <anchor x="475" y="-100" name="L"/>
+ <anchor x="835" y="1000" name="R"/>
+ <anchor x="325" y="1360" name="U"/>
+ <outline>
+ <contour>
+ <point x="760" y="215" type="line"/>
+ <point x="672" y="166"/>
+ <point x="600" y="140"/>
+ <point x="543" y="140" type="curve" smooth="yes"/>
+ <point x="453" y="140"/>
+ <point x="415" y="184"/>
+ <point x="415" y="390" type="curve" smooth="yes"/>
+ <point x="415" y="528"/>
+ <point x="415" y="1320"/>
+ <point x="415" y="1320" type="curve"/>
+ <point x="230" y="1320" type="line"/>
+ <point x="230" y="1320"/>
+ <point x="230" y="435"/>
+ <point x="230" y="270" type="curve" smooth="yes"/>
+ <point x="230" y="39"/>
+ <point x="356" y="-25"/>
+ <point x="512" y="-25" type="curve" smooth="yes"/>
+ <point x="582" y="-25"/>
+ <point x="668" y="-4"/>
+ <point x="760" y="55" type="curve"/>
+ </contour>
+ <contour>
+ <point x="30" y="850" type="line"/>
+ <point x="740" y="850" type="line"/>
+ <point x="740" y="995" type="line"/>
+ <point x="30" y="995" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfdeleteglyphs.ufo/glyphs/L_tnS_mU_.glif b/tests/reference/ufo/psfdeleteglyphs.ufo/glyphs/L_tnS_mU_.glif
new file mode 100644
index 0000000..39609ad
--- /dev/null
+++ b/tests/reference/ufo/psfdeleteglyphs.ufo/glyphs/L_tnS_mU_.glif
@@ -0,0 +1,51 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmU" format="2">
+ <advance width="1185"/>
+ <unicode hex="0075"/>
+ <anchor x="589" y="0" name="H"/>
+ <anchor x="589" y="-100" name="L"/>
+ <anchor x="1192" y="0" name="O"/>
+ <anchor x="1185" y="1000" name="R"/>
+ <anchor x="589" y="1100" name="U"/>
+ <outline>
+ <contour>
+ <point x="1090" y="0" type="line"/>
+ <point x="1048" y="112"/>
+ <point x="1025" y="256"/>
+ <point x="1025" y="450" type="curve" smooth="yes"/>
+ <point x="1025" y="646"/>
+ <point x="1025" y="1020"/>
+ <point x="1025" y="1020" type="curve"/>
+ <point x="820" y="1020" type="line"/>
+ <point x="838" y="898"/>
+ <point x="840" y="832"/>
+ <point x="840" y="700" type="curve" smooth="yes"/>
+ <point x="840" y="420" type="line"/>
+ <point x="787" y="298"/>
+ <point x="628" y="140"/>
+ <point x="510" y="140" type="curve" smooth="yes"/>
+ <point x="383" y="140"/>
+ <point x="340" y="238"/>
+ <point x="340" y="465" type="curve" smooth="yes"/>
+ <point x="340" y="603"/>
+ <point x="340" y="1020"/>
+ <point x="340" y="1020" type="curve"/>
+ <point x="135" y="1020" type="line"/>
+ <point x="153" y="900"/>
+ <point x="155" y="827"/>
+ <point x="155" y="700" type="curve" smooth="yes"/>
+ <point x="155" y="681"/>
+ <point x="155" y="424"/>
+ <point x="155" y="405" type="curve" smooth="yes"/>
+ <point x="155" y="120"/>
+ <point x="262" y="-25"/>
+ <point x="475" y="-25" type="curve" smooth="yes"/>
+ <point x="615" y="-25"/>
+ <point x="744" y="53"/>
+ <point x="865" y="200" type="curve"/>
+ <point x="875" y="125"/>
+ <point x="901" y="46"/>
+ <point x="920" y="0" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfdeleteglyphs.ufo/glyphs/L_tnS_mV_.glif b/tests/reference/ufo/psfdeleteglyphs.ufo/glyphs/L_tnS_mV_.glif
new file mode 100644
index 0000000..3097f4b
--- /dev/null
+++ b/tests/reference/ufo/psfdeleteglyphs.ufo/glyphs/L_tnS_mV_.glif
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmV" format="2">
+ <advance width="1070"/>
+ <unicode hex="0076"/>
+ <anchor x="549" y="0" name="H"/>
+ <anchor x="535" y="-100" name="L"/>
+ <anchor x="725" y="0" name="O"/>
+ <anchor x="535" y="1100" name="U"/>
+ <outline>
+ <contour>
+ <point x="840" y="1020" type="line"/>
+ <point x="535" y="200" type="line"/>
+ <point x="230" y="1020" type="line"/>
+ <point x="20" y="1020" type="line"/>
+ <point x="75" y="905"/>
+ <point x="143" y="746"/>
+ <point x="175" y="665" type="curve" smooth="yes"/>
+ <point x="237" y="510"/>
+ <point x="440" y="0"/>
+ <point x="440" y="0" type="curve"/>
+ <point x="630" y="0" type="line"/>
+ <point x="630" y="0"/>
+ <point x="842" y="536"/>
+ <point x="895" y="665" type="curve" smooth="yes"/>
+ <point x="928" y="744"/>
+ <point x="993" y="905"/>
+ <point x="1050" y="1020" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfdeleteglyphs.ufo/glyphs/L_tnS_mW_.glif b/tests/reference/ufo/psfdeleteglyphs.ufo/glyphs/L_tnS_mW_.glif
new file mode 100644
index 0000000..3557415
--- /dev/null
+++ b/tests/reference/ufo/psfdeleteglyphs.ufo/glyphs/L_tnS_mW_.glif
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmW" format="2">
+ <advance width="1550"/>
+ <unicode hex="0077"/>
+ <anchor x="775" y="-100" name="L"/>
+ <anchor x="775" y="1100" name="U"/>
+ <outline>
+ <contour>
+ <point x="700" y="1020" type="line"/>
+ <point x="440" y="215" type="line"/>
+ <point x="230" y="1020" type="line"/>
+ <point x="45" y="1020" type="line"/>
+ <point x="92" y="867"/>
+ <point x="120" y="771"/>
+ <point x="150" y="665" type="curve" smooth="yes"/>
+ <point x="335" y="0" type="line"/>
+ <point x="525" y="0" type="line"/>
+ <point x="775" y="785" type="line"/>
+ <point x="1025" y="0" type="line"/>
+ <point x="1215" y="0" type="line"/>
+ <point x="1400" y="665" type="line" smooth="yes"/>
+ <point x="1434" y="785"/>
+ <point x="1458" y="868"/>
+ <point x="1505" y="1020" type="curve"/>
+ <point x="1320" y="1020" type="line"/>
+ <point x="1110" y="215" type="line"/>
+ <point x="850" y="1020" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfdeleteglyphs.ufo/glyphs/L_tnS_mX_.glif b/tests/reference/ufo/psfdeleteglyphs.ufo/glyphs/L_tnS_mX_.glif
new file mode 100644
index 0000000..883cba4
--- /dev/null
+++ b/tests/reference/ufo/psfdeleteglyphs.ufo/glyphs/L_tnS_mX_.glif
@@ -0,0 +1,40 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmX" format="2">
+ <advance width="1085"/>
+ <unicode hex="0078"/>
+ <anchor x="900" y="0" name="H"/>
+ <anchor x="542" y="-100" name="L"/>
+ <anchor x="542" y="1100" name="U"/>
+ <outline>
+ <contour>
+ <point x="805" y="0" type="line"/>
+ <point x="1035" y="0" type="line"/>
+ <point x="927" y="142"/>
+ <point x="902" y="170"/>
+ <point x="830" y="270" type="curve" smooth="yes"/>
+ <point x="290" y="1020" type="line"/>
+ <point x="60" y="1020" type="line"/>
+ <point x="168" y="887"/>
+ <point x="203" y="843"/>
+ <point x="270" y="750" type="curve"/>
+ </contour>
+ <contour>
+ <point x="489" y="616" type="line"/>
+ <point x="250" y="270" type="line" smooth="yes"/>
+ <point x="189" y="182"/>
+ <point x="160" y="143"/>
+ <point x="50" y="0" type="curve"/>
+ <point x="275" y="0" type="line"/>
+ <point x="556" y="404" type="line"/>
+ </contour>
+ <contour>
+ <point x="585" y="405" type="line"/>
+ <point x="820" y="750" type="line" smooth="yes"/>
+ <point x="883" y="842"/>
+ <point x="917" y="886"/>
+ <point x="1020" y="1020" type="curve"/>
+ <point x="795" y="1020" type="line"/>
+ <point x="520" y="615" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfdeleteglyphs.ufo/glyphs/L_tnS_mY_.glif b/tests/reference/ufo/psfdeleteglyphs.ufo/glyphs/L_tnS_mY_.glif
new file mode 100644
index 0000000..cbe0f68
--- /dev/null
+++ b/tests/reference/ufo/psfdeleteglyphs.ufo/glyphs/L_tnS_mY_.glif
@@ -0,0 +1,42 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmY" format="2">
+ <advance width="1060"/>
+ <unicode hex="0079"/>
+ <anchor x="795" y="-100" name="L"/>
+ <anchor x="1120" y="1000" name="R"/>
+ <anchor x="535" y="1100" name="U"/>
+ <outline>
+ <contour>
+ <point x="610" y="60" type="line"/>
+ <point x="230" y="1020" type="line"/>
+ <point x="30" y="1020" type="line"/>
+ <point x="107" y="864"/>
+ <point x="153" y="756"/>
+ <point x="190" y="665" type="curve" smooth="yes"/>
+ <point x="525" y="-165" type="line"/>
+ </contour>
+ <contour>
+ <point x="895" y="665" type="line"/>
+ <point x="928" y="758"/>
+ <point x="971" y="865"/>
+ <point x="1040" y="1020" type="curve"/>
+ <point x="840" y="1020" type="line"/>
+ <point x="840" y="1020"/>
+ <point x="564" y="230"/>
+ <point x="500" y="55" type="curve" smooth="yes"/>
+ <point x="391" y="-248"/>
+ <point x="315" y="-300"/>
+ <point x="225" y="-300" type="curve" smooth="yes"/>
+ <point x="159" y="-300"/>
+ <point x="82" y="-260"/>
+ <point x="40" y="-225" type="curve"/>
+ <point x="-20" y="-385" type="line"/>
+ <point x="53" y="-439"/>
+ <point x="134" y="-470"/>
+ <point x="225" y="-470" type="curve" smooth="yes"/>
+ <point x="395" y="-470"/>
+ <point x="516" y="-383"/>
+ <point x="655" y="0" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfdeleteglyphs.ufo/glyphs/N_onB_reakingH_yphen.glif b/tests/reference/ufo/psfdeleteglyphs.ufo/glyphs/N_onB_reakingH_yphen.glif
new file mode 100644
index 0000000..14aff81
--- /dev/null
+++ b/tests/reference/ufo/psfdeleteglyphs.ufo/glyphs/N_onB_reakingH_yphen.glif
@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="NonBreakingHyphen" format="2">
+ <advance width="860"/>
+ <unicode hex="2011"/>
+ <anchor x="430" y="1100" name="U"/>
+ <outline>
+ <component base="HyphenMinus"/>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfdeleteglyphs.ufo/glyphs/N_umS_gn.glif b/tests/reference/ufo/psfdeleteglyphs.ufo/glyphs/N_umS_gn.glif
new file mode 100644
index 0000000..f4625db
--- /dev/null
+++ b/tests/reference/ufo/psfdeleteglyphs.ufo/glyphs/N_umS_gn.glif
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="NumSgn" format="2">
+ <advance width="1200"/>
+ <unicode hex="0023"/>
+ <outline>
+ <contour>
+ <point x="487" y="1460" type="line"/>
+ <point x="127" y="200" type="line"/>
+ <point x="277" y="200" type="line"/>
+ <point x="637" y="1460" type="line"/>
+ </contour>
+ <contour>
+ <point x="25" y="575" type="line"/>
+ <point x="1116" y="575" type="line"/>
+ <point x="1116" y="725" type="line"/>
+ <point x="25" y="725" type="line"/>
+ </contour>
+ <contour>
+ <point x="84" y="960" type="line"/>
+ <point x="1175" y="960" type="line"/>
+ <point x="1175" y="1110" type="line"/>
+ <point x="84" y="1110" type="line"/>
+ </contour>
+ <contour>
+ <point x="912" y="1460" type="line"/>
+ <point x="552" y="200" type="line"/>
+ <point x="702" y="200" type="line"/>
+ <point x="1062" y="1460" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfdeleteglyphs.ufo/glyphs/P_ercentS_gn.glif b/tests/reference/ufo/psfdeleteglyphs.ufo/glyphs/P_ercentS_gn.glif
new file mode 100644
index 0000000..e81f237
--- /dev/null
+++ b/tests/reference/ufo/psfdeleteglyphs.ufo/glyphs/P_ercentS_gn.glif
@@ -0,0 +1,69 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="PercentSgn" format="2">
+ <advance width="1526"/>
+ <unicode hex="0025"/>
+ <outline>
+ <contour>
+ <point x="1261" y="366" type="curve" smooth="yes"/>
+ <point x="1261" y="182"/>
+ <point x="1216" y="115"/>
+ <point x="1130" y="115" type="curve" smooth="yes"/>
+ <point x="1041" y="115"/>
+ <point x="1001" y="181"/>
+ <point x="1001" y="381" type="curve" smooth="yes"/>
+ <point x="1001" y="565"/>
+ <point x="1043" y="630"/>
+ <point x="1130" y="630" type="curve" smooth="yes"/>
+ <point x="1221" y="630"/>
+ <point x="1261" y="566"/>
+ </contour>
+ <contour>
+ <point x="1426" y="379" type="curve" smooth="yes"/>
+ <point x="1426" y="652"/>
+ <point x="1310" y="770"/>
+ <point x="1135" y="770" type="curve" smooth="yes"/>
+ <point x="961" y="770"/>
+ <point x="836" y="650"/>
+ <point x="836" y="368" type="curve" smooth="yes"/>
+ <point x="836" y="86"/>
+ <point x="951" y="-25"/>
+ <point x="1126" y="-25" type="curve" smooth="yes"/>
+ <point x="1301" y="-25"/>
+ <point x="1426" y="84"/>
+ </contour>
+ <contour>
+ <point x="1073" y="1480" type="line"/>
+ <point x="291" y="-25" type="line"/>
+ <point x="459" y="-25" type="line"/>
+ <point x="1239" y="1480" type="line"/>
+ </contour>
+ <contour>
+ <point x="525" y="1076" type="curve" smooth="yes"/>
+ <point x="525" y="892"/>
+ <point x="480" y="825"/>
+ <point x="394" y="825" type="curve" smooth="yes"/>
+ <point x="305" y="825"/>
+ <point x="265" y="891"/>
+ <point x="265" y="1091" type="curve" smooth="yes"/>
+ <point x="265" y="1275"/>
+ <point x="307" y="1340"/>
+ <point x="394" y="1340" type="curve" smooth="yes"/>
+ <point x="485" y="1340"/>
+ <point x="525" y="1276"/>
+ </contour>
+ <contour>
+ <point x="690" y="1089" type="curve" smooth="yes"/>
+ <point x="690" y="1362"/>
+ <point x="574" y="1480"/>
+ <point x="399" y="1480" type="curve" smooth="yes"/>
+ <point x="225" y="1480"/>
+ <point x="100" y="1360"/>
+ <point x="100" y="1078" type="curve" smooth="yes"/>
+ <point x="100" y="796"/>
+ <point x="215" y="685"/>
+ <point x="390" y="685" type="curve" smooth="yes"/>
+ <point x="565" y="685"/>
+ <point x="690" y="794"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfdeleteglyphs.ufo/glyphs/P_lusS_gn.glif b/tests/reference/ufo/psfdeleteglyphs.ufo/glyphs/P_lusS_gn.glif
new file mode 100644
index 0000000..de1f259
--- /dev/null
+++ b/tests/reference/ufo/psfdeleteglyphs.ufo/glyphs/P_lusS_gn.glif
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="PlusSgn" format="2">
+ <advance width="1200"/>
+ <unicode hex="002B"/>
+ <outline>
+ <contour>
+ <point x="525" y="1180" type="line"/>
+ <point x="525" y="285" type="line"/>
+ <point x="675" y="285" type="line"/>
+ <point x="675" y="1180" type="line"/>
+ </contour>
+ <contour>
+ <point x="155" y="660" type="line"/>
+ <point x="1045" y="660" type="line"/>
+ <point x="1045" y="810" type="line"/>
+ <point x="155" y="810" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfdeleteglyphs.ufo/glyphs/Q_stnM_rk.glif b/tests/reference/ufo/psfdeleteglyphs.ufo/glyphs/Q_stnM_rk.glif
new file mode 100644
index 0000000..5526aec
--- /dev/null
+++ b/tests/reference/ufo/psfdeleteglyphs.ufo/glyphs/Q_stnM_rk.glif
@@ -0,0 +1,49 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="QstnMrk" format="2">
+ <advance width="1050"/>
+ <unicode hex="003F"/>
+ <outline>
+ <contour>
+ <point x="460" y="1540" type="curve" smooth="yes"/>
+ <point x="335" y="1540"/>
+ <point x="206" y="1493"/>
+ <point x="140" y="1430" type="curve"/>
+ <point x="185" y="1251" type="line"/>
+ <point x="261" y="1330"/>
+ <point x="352" y="1365"/>
+ <point x="432" y="1365" type="curve" smooth="yes"/>
+ <point x="579" y="1365"/>
+ <point x="625" y="1289"/>
+ <point x="625" y="1230" type="curve" smooth="yes"/>
+ <point x="625" y="1159"/>
+ <point x="572" y="1092"/>
+ <point x="485" y="980" type="curve" smooth="yes"/>
+ <point x="397" y="867"/>
+ <point x="355" y="730"/>
+ <point x="355" y="440" type="curve"/>
+ <point x="540" y="440" type="line"/>
+ <point x="540" y="721"/>
+ <point x="561" y="806"/>
+ <point x="665" y="927" type="curve" smooth="yes"/>
+ <point x="753" y="1028"/>
+ <point x="830" y="1117"/>
+ <point x="830" y="1240" type="curve" smooth="yes"/>
+ <point x="830" y="1422"/>
+ <point x="697" y="1540"/>
+ </contour>
+ <contour>
+ <point x="315" y="110" type="curve" smooth="yes"/>
+ <point x="315" y="36"/>
+ <point x="376" y="-25"/>
+ <point x="450" y="-25" type="curve" smooth="yes"/>
+ <point x="524" y="-25"/>
+ <point x="585" y="36"/>
+ <point x="585" y="110" type="curve" smooth="yes"/>
+ <point x="585" y="184"/>
+ <point x="524" y="245"/>
+ <point x="450" y="245" type="curve" smooth="yes"/>
+ <point x="376" y="245"/>
+ <point x="315" y="184"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfdeleteglyphs.ufo/glyphs/Q_uotM_rk.glif b/tests/reference/ufo/psfdeleteglyphs.ufo/glyphs/Q_uotM_rk.glif
new file mode 100644
index 0000000..c9f06c6
--- /dev/null
+++ b/tests/reference/ufo/psfdeleteglyphs.ufo/glyphs/Q_uotM_rk.glif
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="QuotMrk" format="2">
+ <advance width="1025"/>
+ <unicode hex="0022"/>
+ <outline>
+ <contour>
+ <point x="405" y="1045" type="line"/>
+ <point x="410" y="1186"/>
+ <point x="416" y="1339"/>
+ <point x="445" y="1585" type="curve"/>
+ <point x="240" y="1585" type="line"/>
+ <point x="271" y="1339"/>
+ <point x="276" y="1186"/>
+ <point x="280" y="1045" type="curve"/>
+ </contour>
+ <contour>
+ <point x="745" y="1045" type="line"/>
+ <point x="750" y="1186"/>
+ <point x="756" y="1339"/>
+ <point x="785" y="1585" type="curve"/>
+ <point x="580" y="1585" type="line"/>
+ <point x="611" y="1339"/>
+ <point x="616" y="1186"/>
+ <point x="620" y="1045" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfdeleteglyphs.ufo/glyphs/R_everseS_olidus.glif b/tests/reference/ufo/psfdeleteglyphs.ufo/glyphs/R_everseS_olidus.glif
new file mode 100644
index 0000000..d145f26
--- /dev/null
+++ b/tests/reference/ufo/psfdeleteglyphs.ufo/glyphs/R_everseS_olidus.glif
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="ReverseSolidus" format="2">
+ <advance width="1000"/>
+ <unicode hex="005C"/>
+ <outline>
+ <contour>
+ <point x="990" y="-245" type="line"/>
+ <point x="160" y="1600" type="line"/>
+ <point x="10" y="1600" type="line"/>
+ <point x="840" y="-245" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfdeleteglyphs.ufo/glyphs/R_tC_urlyB_rac.glif b/tests/reference/ufo/psfdeleteglyphs.ufo/glyphs/R_tC_urlyB_rac.glif
new file mode 100644
index 0000000..288a75a
--- /dev/null
+++ b/tests/reference/ufo/psfdeleteglyphs.ufo/glyphs/R_tC_urlyB_rac.glif
@@ -0,0 +1,47 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="RtCurlyBrac" format="2">
+ <advance width="1000"/>
+ <unicode hex="007D"/>
+ <outline>
+ <contour>
+ <point x="790" y="615" type="curve" smooth="yes"/>
+ <point x="790" y="647"/>
+ <point x="617" y="744"/>
+ <point x="590" y="780" type="curve" smooth="yes"/>
+ <point x="566" y="812"/>
+ <point x="576" y="1435"/>
+ <point x="505" y="1515" type="curve" smooth="yes"/>
+ <point x="465" y="1560"/>
+ <point x="304" y="1613"/>
+ <point x="200" y="1640" type="curve"/>
+ <point x="160" y="1500" type="line"/>
+ <point x="227" y="1477"/>
+ <point x="350" y="1428"/>
+ <point x="370" y="1400" type="curve" smooth="yes"/>
+ <point x="403" y="1353"/>
+ <point x="390" y="783"/>
+ <point x="410" y="745" type="curve" smooth="yes"/>
+ <point x="429" y="709"/>
+ <point x="566" y="637"/>
+ <point x="570" y="615" type="curve"/>
+ <point x="566" y="593"/>
+ <point x="429" y="521"/>
+ <point x="410" y="485" type="curve" smooth="yes"/>
+ <point x="390" y="447"/>
+ <point x="403" y="-123"/>
+ <point x="370" y="-170" type="curve" smooth="yes"/>
+ <point x="350" y="-198"/>
+ <point x="227" y="-247"/>
+ <point x="160" y="-270" type="curve"/>
+ <point x="200" y="-410" type="line"/>
+ <point x="304" y="-383"/>
+ <point x="465" y="-330"/>
+ <point x="505" y="-285" type="curve" smooth="yes"/>
+ <point x="576" y="-205"/>
+ <point x="566" y="418"/>
+ <point x="590" y="450" type="curve" smooth="yes"/>
+ <point x="617" y="486"/>
+ <point x="790" y="583"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfdeleteglyphs.ufo/glyphs/R_tP_aren.glif b/tests/reference/ufo/psfdeleteglyphs.ufo/glyphs/R_tP_aren.glif
new file mode 100644
index 0000000..3983f6b
--- /dev/null
+++ b/tests/reference/ufo/psfdeleteglyphs.ufo/glyphs/R_tP_aren.glif
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="RtParen" format="2">
+ <advance width="795"/>
+ <unicode hex="0029"/>
+ <outline>
+ <contour>
+ <point x="680" y="625" type="curve" smooth="yes"/>
+ <point x="680" y="1062"/>
+ <point x="505" y="1444"/>
+ <point x="240" y="1640" type="curve"/>
+ <point x="165" y="1485" type="line"/>
+ <point x="390" y="1280"/>
+ <point x="490" y="962"/>
+ <point x="490" y="625" type="curve" smooth="yes"/>
+ <point x="490" y="278"/>
+ <point x="390" y="-8"/>
+ <point x="165" y="-265" type="curve"/>
+ <point x="260" y="-410" type="line"/>
+ <point x="535" y="-125"/>
+ <point x="680" y="218"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfdeleteglyphs.ufo/glyphs/R_tS_qrB_rac.glif b/tests/reference/ufo/psfdeleteglyphs.ufo/glyphs/R_tS_qrB_rac.glif
new file mode 100644
index 0000000..702689b
--- /dev/null
+++ b/tests/reference/ufo/psfdeleteglyphs.ufo/glyphs/R_tS_qrB_rac.glif
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="RtSqrBrac" format="2">
+ <advance width="790"/>
+ <unicode hex="005D"/>
+ <outline>
+ <contour>
+ <point x="590" y="-410" type="line"/>
+ <point x="590" y="1600" type="line"/>
+ <point x="150" y="1600" type="line"/>
+ <point x="150" y="1450" type="line"/>
+ <point x="405" y="1450" type="line"/>
+ <point x="405" y="-260" type="line"/>
+ <point x="150" y="-260" type="line"/>
+ <point x="150" y="-410" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfdeleteglyphs.ufo/glyphs/S_emicolon.glif b/tests/reference/ufo/psfdeleteglyphs.ufo/glyphs/S_emicolon.glif
new file mode 100644
index 0000000..247bed0
--- /dev/null
+++ b/tests/reference/ufo/psfdeleteglyphs.ufo/glyphs/S_emicolon.glif
@@ -0,0 +1,38 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="Semicolon" format="2">
+ <advance width="650"/>
+ <unicode hex="003B"/>
+ <outline>
+ <contour>
+ <point x="185" y="790" type="curve" smooth="yes"/>
+ <point x="185" y="716"/>
+ <point x="246" y="655"/>
+ <point x="320" y="655" type="curve" smooth="yes"/>
+ <point x="394" y="655"/>
+ <point x="455" y="716"/>
+ <point x="455" y="790" type="curve" smooth="yes"/>
+ <point x="455" y="864"/>
+ <point x="394" y="925"/>
+ <point x="320" y="925" type="curve" smooth="yes"/>
+ <point x="246" y="925"/>
+ <point x="185" y="864"/>
+ </contour>
+ <contour>
+ <point x="185" y="50" type="line"/>
+ <point x="325" y="50" type="line"/>
+ <point x="325" y="-51"/>
+ <point x="248" y="-172"/>
+ <point x="190" y="-230" type="curve"/>
+ <point x="290" y="-270" type="line"/>
+ <point x="407" y="-160"/>
+ <point x="465" y="-37"/>
+ <point x="465" y="85" type="curve" smooth="yes"/>
+ <point x="465" y="186"/>
+ <point x="400" y="250"/>
+ <point x="320" y="250" type="curve" smooth="yes"/>
+ <point x="263" y="250"/>
+ <point x="198" y="213"/>
+ <point x="185" y="150" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfdeleteglyphs.ufo/glyphs/S_olidus.glif b/tests/reference/ufo/psfdeleteglyphs.ufo/glyphs/S_olidus.glif
new file mode 100644
index 0000000..3edff5d
--- /dev/null
+++ b/tests/reference/ufo/psfdeleteglyphs.ufo/glyphs/S_olidus.glif
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="Solidus" format="2">
+ <advance width="1000"/>
+ <unicode hex="002F"/>
+ <outline>
+ <contour>
+ <point x="840" y="1600" type="line"/>
+ <point x="10" y="-245" type="line"/>
+ <point x="160" y="-245" type="line"/>
+ <point x="990" y="1600" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfdeleteglyphs.ufo/glyphs/S_pace.glif b/tests/reference/ufo/psfdeleteglyphs.ufo/glyphs/S_pace.glif
new file mode 100644
index 0000000..ef0bed7
--- /dev/null
+++ b/tests/reference/ufo/psfdeleteglyphs.ufo/glyphs/S_pace.glif
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="Space" format="2">
+ <advance width="550"/>
+ <unicode hex="0020"/>
+ <outline/>
+</glyph>
diff --git a/tests/reference/ufo/psfdeleteglyphs.ufo/glyphs/T_ilde.glif b/tests/reference/ufo/psfdeleteglyphs.ufo/glyphs/T_ilde.glif
new file mode 100644
index 0000000..60ddaa7
--- /dev/null
+++ b/tests/reference/ufo/psfdeleteglyphs.ufo/glyphs/T_ilde.glif
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="Tilde" format="2">
+ <advance width="1115"/>
+ <unicode hex="007E"/>
+ <outline>
+ <contour>
+ <point x="125" y="375" type="line"/>
+ <point x="130" y="424"/>
+ <point x="162" y="465"/>
+ <point x="240" y="465" type="curve" smooth="yes"/>
+ <point x="415" y="465"/>
+ <point x="615" y="360"/>
+ <point x="845" y="360" type="curve" smooth="yes"/>
+ <point x="1004" y="360"/>
+ <point x="1080" y="482"/>
+ <point x="1080" y="610" type="curve"/>
+ <point x="975" y="610" type="line"/>
+ <point x="968" y="564"/>
+ <point x="938" y="510"/>
+ <point x="855" y="510" type="curve" smooth="yes"/>
+ <point x="619" y="510"/>
+ <point x="461" y="615"/>
+ <point x="240" y="615" type="curve" smooth="yes"/>
+ <point x="94" y="615"/>
+ <point x="20" y="497"/>
+ <point x="20" y="375" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfdeleteglyphs.ufo/glyphs/V_ertL_ine.glif b/tests/reference/ufo/psfdeleteglyphs.ufo/glyphs/V_ertL_ine.glif
new file mode 100644
index 0000000..c73e040
--- /dev/null
+++ b/tests/reference/ufo/psfdeleteglyphs.ufo/glyphs/V_ertL_ine.glif
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="VertLine" format="2">
+ <advance width="690"/>
+ <unicode hex="007C"/>
+ <outline>
+ <contour>
+ <point x="270" y="1600" type="line"/>
+ <point x="270" y="-390" type="line"/>
+ <point x="420" y="-390" type="line"/>
+ <point x="420" y="1600" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfdeleteglyphs.ufo/glyphs/_notdef.glif b/tests/reference/ufo/psfdeleteglyphs.ufo/glyphs/_notdef.glif
new file mode 100644
index 0000000..a3e9354
--- /dev/null
+++ b/tests/reference/ufo/psfdeleteglyphs.ufo/glyphs/_notdef.glif
@@ -0,0 +1,18 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name=".notdef" format="2">
+ <advance width="1400"/>
+ <outline>
+ <contour>
+ <point x="100" y="0" type="line"/>
+ <point x="1300" y="0" type="line"/>
+ <point x="1300" y="1800" type="line"/>
+ <point x="100" y="1800" type="line"/>
+ </contour>
+ <contour>
+ <point x="150" y="1750" type="line"/>
+ <point x="1250" y="1750" type="line"/>
+ <point x="1250" y="50" type="line"/>
+ <point x="150" y="50" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfdeleteglyphs.ufo/glyphs/_null.glif b/tests/reference/ufo/psfdeleteglyphs.ufo/glyphs/_null.glif
new file mode 100644
index 0000000..0b9caa6
--- /dev/null
+++ b/tests/reference/ufo/psfdeleteglyphs.ufo/glyphs/_null.glif
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name=".null" format="2">
+ <outline/>
+</glyph>
diff --git a/tests/reference/ufo/psfdeleteglyphs.ufo/glyphs/contents.plist b/tests/reference/ufo/psfdeleteglyphs.ufo/glyphs/contents.plist
new file mode 100644
index 0000000..c440ebe
--- /dev/null
+++ b/tests/reference/ufo/psfdeleteglyphs.ufo/glyphs/contents.plist
@@ -0,0 +1,230 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+ <key>.notdef</key>
+ <string>_notdef.glif</string>
+ <key>.null</key>
+ <string>_null.glif</string>
+ <key>Ampersand</key>
+ <string>A_mpersand.glif</string>
+ <key>Asterisk</key>
+ <string>A_sterisk.glif</string>
+ <key>AtSgn</key>
+ <string>A_tS_gn.glif</string>
+ <key>CircumAccent</key>
+ <string>C_ircumA_ccent.glif</string>
+ <key>Colon</key>
+ <string>C_olon.glif</string>
+ <key>CombAcute</key>
+ <string>C_ombA_cute.glif</string>
+ <key>CombCircum</key>
+ <string>C_ombC_ircum.glif</string>
+ <key>CombDiaer</key>
+ <string>C_ombD_iaer.glif</string>
+ <key>CombGrave</key>
+ <string>C_ombG_rave.glif</string>
+ <key>CombRingAbv</key>
+ <string>C_ombR_ingA_bv.glif</string>
+ <key>CombTilde</key>
+ <string>C_ombT_ilde.glif</string>
+ <key>DigitEight</key>
+ <string>D_igitE_ight.glif</string>
+ <key>DigitFive</key>
+ <string>D_igitF_ive.glif</string>
+ <key>DigitFour</key>
+ <string>D_igitF_our.glif</string>
+ <key>DigitNine</key>
+ <string>D_igitN_ine.glif</string>
+ <key>DigitOne</key>
+ <string>D_igitO_ne.glif</string>
+ <key>DigitSeven</key>
+ <string>D_igitS_even.glif</string>
+ <key>DigitSix</key>
+ <string>D_igitS_ix.glif</string>
+ <key>DigitThree</key>
+ <string>D_igitT_hree.glif</string>
+ <key>DigitTwo</key>
+ <string>D_igitT_wo.glif</string>
+ <key>DigitZero</key>
+ <string>D_igitZ_ero.glif</string>
+ <key>DollarSgn</key>
+ <string>D_ollarS_gn.glif</string>
+ <key>DottedCirc</key>
+ <string>D_ottedC_irc.glif</string>
+ <key>EqSgn</key>
+ <string>E_qS_gn.glif</string>
+ <key>ExclamationMrk</key>
+ <string>E_xclamationM_rk.glif</string>
+ <key>FullStop</key>
+ <string>F_ullS_top.glif</string>
+ <key>GTSgn</key>
+ <string>G_T_S_gn.glif</string>
+ <key>GraveAccent</key>
+ <string>G_raveA_ccent.glif</string>
+ <key>Hyphen</key>
+ <string>H_yphen.glif</string>
+ <key>HyphenMinus</key>
+ <string>H_yphenM_inus.glif</string>
+ <key>Hyphen_Soft</key>
+ <string>H_yphen_S_oft.glif</string>
+ <key>LTSgn</key>
+ <string>L_T_S_gn.glif</string>
+ <key>LftCurlyBrac</key>
+ <string>L_ftC_urlyB_rac.glif</string>
+ <key>LftParen</key>
+ <string>L_ftP_aren.glif</string>
+ <key>LftSqrBrac</key>
+ <string>L_ftS_qrB_rac.glif</string>
+ <key>LowLine</key>
+ <string>L_owL_ine.glif</string>
+ <key>LtnCapA</key>
+ <string>L_tnC_apA_.glif</string>
+ <key>LtnCapA.alt</key>
+ <string>L_tnC_apA_.alt.glif</string>
+ <key>LtnCapADiaer</key>
+ <string>L_tnC_apA_D_iaer.glif</string>
+ <key>LtnCapB</key>
+ <string>L_tnC_apB_.glif</string>
+ <key>LtnCapC</key>
+ <string>L_tnC_apC_.glif</string>
+ <key>LtnCapD</key>
+ <string>L_tnC_apD_.glif</string>
+ <key>LtnCapE</key>
+ <string>L_tnC_apE_.glif</string>
+ <key>LtnCapF</key>
+ <string>L_tnC_apF_.glif</string>
+ <key>LtnCapG</key>
+ <string>L_tnC_apG_.glif</string>
+ <key>LtnCapH</key>
+ <string>L_tnC_apH_.glif</string>
+ <key>LtnCapI</key>
+ <string>L_tnC_apI_.glif</string>
+ <key>LtnCapJ</key>
+ <string>L_tnC_apJ_.glif</string>
+ <key>LtnCapK</key>
+ <string>L_tnC_apK_.glif</string>
+ <key>LtnCapL</key>
+ <string>L_tnC_apL_.glif</string>
+ <key>LtnCapM</key>
+ <string>L_tnC_apM_.glif</string>
+ <key>LtnCapN</key>
+ <string>L_tnC_apN_.glif</string>
+ <key>LtnCapO</key>
+ <string>L_tnC_apO_.glif</string>
+ <key>LtnCapP</key>
+ <string>L_tnC_apP_.glif</string>
+ <key>LtnCapQ</key>
+ <string>L_tnC_apQ_.glif</string>
+ <key>LtnCapR</key>
+ <string>L_tnC_apR_.glif</string>
+ <key>LtnCapS</key>
+ <string>L_tnC_apS_.glif</string>
+ <key>LtnCapT</key>
+ <string>L_tnC_apT_.glif</string>
+ <key>LtnCapU</key>
+ <string>L_tnC_apU_.glif</string>
+ <key>LtnCapV</key>
+ <string>L_tnC_apV_.glif</string>
+ <key>LtnCapW</key>
+ <string>L_tnC_apW_.glif</string>
+ <key>LtnCapX</key>
+ <string>L_tnC_apX_.glif</string>
+ <key>LtnCapY</key>
+ <string>L_tnC_apY_.glif</string>
+ <key>LtnSmA</key>
+ <string>L_tnS_mA_.glif</string>
+ <key>LtnSmAAcute</key>
+ <string>L_tnS_mA_A_cute.glif</string>
+ <key>LtnSmACircum</key>
+ <string>L_tnS_mA_C_ircum.glif</string>
+ <key>LtnSmADiaer</key>
+ <string>L_tnS_mA_D_iaer.glif</string>
+ <key>LtnSmAGrave</key>
+ <string>L_tnS_mA_G_rave.glif</string>
+ <key>LtnSmARingAbv</key>
+ <string>L_tnS_mA_R_ingA_bv.glif</string>
+ <key>LtnSmATilde</key>
+ <string>L_tnS_mA_T_ilde.glif</string>
+ <key>LtnSmB</key>
+ <string>L_tnS_mB_.glif</string>
+ <key>LtnSmC</key>
+ <string>L_tnS_mC_.glif</string>
+ <key>LtnSmD</key>
+ <string>L_tnS_mD_.glif</string>
+ <key>LtnSmE</key>
+ <string>L_tnS_mE_.glif</string>
+ <key>LtnSmF</key>
+ <string>L_tnS_mF_.glif</string>
+ <key>LtnSmG</key>
+ <string>L_tnS_mG_.glif</string>
+ <key>LtnSmH</key>
+ <string>L_tnS_mH_.glif</string>
+ <key>LtnSmI</key>
+ <string>L_tnS_mI_.glif</string>
+ <key>LtnSmJ</key>
+ <string>L_tnS_mJ_.glif</string>
+ <key>LtnSmK</key>
+ <string>L_tnS_mK_.glif</string>
+ <key>LtnSmL</key>
+ <string>L_tnS_mL_.glif</string>
+ <key>LtnSmM</key>
+ <string>L_tnS_mM_.glif</string>
+ <key>LtnSmN</key>
+ <string>L_tnS_mN_.glif</string>
+ <key>LtnSmO</key>
+ <string>L_tnS_mO_.glif</string>
+ <key>LtnSmP</key>
+ <string>L_tnS_mP_.glif</string>
+ <key>LtnSmQ</key>
+ <string>L_tnS_mQ_.glif</string>
+ <key>LtnSmR</key>
+ <string>L_tnS_mR_.glif</string>
+ <key>LtnSmS</key>
+ <string>L_tnS_mS_.glif</string>
+ <key>LtnSmT</key>
+ <string>L_tnS_mT_.glif</string>
+ <key>LtnSmU</key>
+ <string>L_tnS_mU_.glif</string>
+ <key>LtnSmV</key>
+ <string>L_tnS_mV_.glif</string>
+ <key>LtnSmW</key>
+ <string>L_tnS_mW_.glif</string>
+ <key>LtnSmX</key>
+ <string>L_tnS_mX_.glif</string>
+ <key>LtnSmY</key>
+ <string>L_tnS_mY_.glif</string>
+ <key>NonBreakingHyphen</key>
+ <string>N_onB_reakingH_yphen.glif</string>
+ <key>NumSgn</key>
+ <string>N_umS_gn.glif</string>
+ <key>PercentSgn</key>
+ <string>P_ercentS_gn.glif</string>
+ <key>PlusSgn</key>
+ <string>P_lusS_gn.glif</string>
+ <key>QstnMrk</key>
+ <string>Q_stnM_rk.glif</string>
+ <key>QuotMrk</key>
+ <string>Q_uotM_rk.glif</string>
+ <key>ReverseSolidus</key>
+ <string>R_everseS_olidus.glif</string>
+ <key>RtCurlyBrac</key>
+ <string>R_tC_urlyB_rac.glif</string>
+ <key>RtParen</key>
+ <string>R_tP_aren.glif</string>
+ <key>RtSqrBrac</key>
+ <string>R_tS_qrB_rac.glif</string>
+ <key>Semicolon</key>
+ <string>S_emicolon.glif</string>
+ <key>Solidus</key>
+ <string>S_olidus.glif</string>
+ <key>Space</key>
+ <string>S_pace.glif</string>
+ <key>Tilde</key>
+ <string>T_ilde.glif</string>
+ <key>VertLine</key>
+ <string>V_ertL_ine.glif</string>
+ <key>nonmarkingreturn</key>
+ <string>nonmarkingreturn.glif</string>
+</dict>
+</plist>
diff --git a/tests/reference/ufo/psfdeleteglyphs.ufo/glyphs/nonmarkingreturn.glif b/tests/reference/ufo/psfdeleteglyphs.ufo/glyphs/nonmarkingreturn.glif
new file mode 100644
index 0000000..ee41448
--- /dev/null
+++ b/tests/reference/ufo/psfdeleteglyphs.ufo/glyphs/nonmarkingreturn.glif
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="nonmarkingreturn" format="2">
+ <advance width="1024"/>
+ <outline/>
+</glyph>
diff --git a/tests/reference/ufo/psfdeleteglyphs.ufo/layercontents.plist b/tests/reference/ufo/psfdeleteglyphs.ufo/layercontents.plist
new file mode 100644
index 0000000..42b7482
--- /dev/null
+++ b/tests/reference/ufo/psfdeleteglyphs.ufo/layercontents.plist
@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<array>
+ <array>
+ <string>public.default</string>
+ <string>glyphs</string>
+ </array>
+</array>
+</plist>
diff --git a/tests/reference/ufo/psfdeleteglyphs.ufo/lib.plist b/tests/reference/ufo/psfdeleteglyphs.ufo/lib.plist
new file mode 100644
index 0000000..8b95204
--- /dev/null
+++ b/tests/reference/ufo/psfdeleteglyphs.ufo/lib.plist
@@ -0,0 +1,536 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+ <key>com.schriftgestaltung.Glyphs.fontUserData</key>
+ <dict/>
+ <key>com.schriftgestaltung.appVersion</key>
+ <string>1161</string>
+ <key>com.schriftgestaltung.customParameter.GSFont.DisplayStrings</key>
+ <string/>
+ <key>com.schriftgestaltung.customParameter.GSFont.disablesAutomaticAlignment</key>
+ <true/>
+ <key>com.schriftgestaltung.customParameter.GSFont.disablesLastChange</key>
+ <true/>
+ <key>com.schriftgestaltung.customParameter.GSFont.useNiceNames</key>
+ <integer>0</integer>
+ <key>com.schriftgestaltung.customParameter.GSFontMaster.customValue</key>
+ <integer>0</integer>
+ <key>com.schriftgestaltung.customParameter.GSFontMaster.customValue1</key>
+ <integer>0</integer>
+ <key>com.schriftgestaltung.customParameter.GSFontMaster.customValue2</key>
+ <integer>0</integer>
+ <key>com.schriftgestaltung.customParameter.GSFontMaster.customValue3</key>
+ <integer>0</integer>
+ <key>com.schriftgestaltung.customParameter.GSFontMaster.iconName</key>
+ <string/>
+ <key>com.schriftgestaltung.customParameter.GSFontMaster.weightValue</key>
+ <integer>400</integer>
+ <key>com.schriftgestaltung.customParameter.GSFontMaster.widthValue</key>
+ <integer>100</integer>
+ <key>com.schriftgestaltung.disablesAutomaticAlignment</key>
+ <true/>
+ <key>com.schriftgestaltung.disablesLastChange</key>
+ <true/>
+ <key>com.schriftgestaltung.fontMasterOrder</key>
+ <integer>0</integer>
+ <key>com.schriftgestaltung.glyphOrder</key>
+ <array>
+ <string>.notdef</string>
+ <string>.null</string>
+ <string>nonmarkingreturn</string>
+ <string>Space</string>
+ <string>ExclamationMrk</string>
+ <string>QuotMrk</string>
+ <string>NumSgn</string>
+ <string>DollarSgn</string>
+ <string>PercentSgn</string>
+ <string>Ampersand</string>
+ <string>Apos</string>
+ <string>LftParen</string>
+ <string>RtParen</string>
+ <string>Asterisk</string>
+ <string>PlusSgn</string>
+ <string>Comma</string>
+ <string>HyphenMinus</string>
+ <string>FullStop</string>
+ <string>Solidus</string>
+ <string>DigitZero</string>
+ <string>DigitOne</string>
+ <string>DigitTwo</string>
+ <string>DigitThree</string>
+ <string>DigitFour</string>
+ <string>DigitFive</string>
+ <string>DigitSix</string>
+ <string>DigitSeven</string>
+ <string>DigitEight</string>
+ <string>DigitNine</string>
+ <string>Colon</string>
+ <string>Semicolon</string>
+ <string>LTSgn</string>
+ <string>EqSgn</string>
+ <string>GTSgn</string>
+ <string>QstnMrk</string>
+ <string>AtSgn</string>
+ <string>LtnCapA</string>
+ <string>LtnCapA.alt</string>
+ <string>LtnCapB</string>
+ <string>LtnCapC</string>
+ <string>LtnCapD</string>
+ <string>LtnCapE</string>
+ <string>LtnCapF</string>
+ <string>LtnCapG</string>
+ <string>LtnCapH</string>
+ <string>LtnCapI</string>
+ <string>LtnCapJ</string>
+ <string>LtnCapK</string>
+ <string>LtnCapL</string>
+ <string>LtnCapM</string>
+ <string>LtnCapN</string>
+ <string>LtnCapO</string>
+ <string>LtnCapP</string>
+ <string>LtnCapQ</string>
+ <string>LtnCapR</string>
+ <string>LtnCapS</string>
+ <string>LtnCapT</string>
+ <string>LtnCapU</string>
+ <string>LtnCapV</string>
+ <string>LtnCapW</string>
+ <string>LtnCapX</string>
+ <string>LtnCapY</string>
+ <string>LftSqrBrac</string>
+ <string>ReverseSolidus</string>
+ <string>RtSqrBrac</string>
+ <string>CircumAccent</string>
+ <string>LowLine</string>
+ <string>GraveAccent</string>
+ <string>LtnSmA</string>
+ <string>LtnSmB</string>
+ <string>LtnSmC</string>
+ <string>LtnSmD</string>
+ <string>LtnSmE</string>
+ <string>LtnSmF</string>
+ <string>LtnSmG</string>
+ <string>LtnSmH</string>
+ <string>LtnSmI</string>
+ <string>LtnSmJ</string>
+ <string>LtnSmK</string>
+ <string>LtnSmL</string>
+ <string>LtnSmM</string>
+ <string>LtnSmN</string>
+ <string>LtnSmO</string>
+ <string>LtnSmP</string>
+ <string>LtnSmQ</string>
+ <string>LtnSmR</string>
+ <string>LtnSmS</string>
+ <string>LtnSmT</string>
+ <string>LtnSmU</string>
+ <string>LtnSmV</string>
+ <string>LtnSmW</string>
+ <string>LtnSmX</string>
+ <string>LtnSmY</string>
+ <string>LftCurlyBrac</string>
+ <string>VertLine</string>
+ <string>RtCurlyBrac</string>
+ <string>Tilde</string>
+ <string>LtnCapADiaer</string>
+ <string>LtnSmAAcute</string>
+ <string>LtnSmAGrave</string>
+ <string>LtnSmACircum</string>
+ <string>LtnSmADiaer</string>
+ <string>LtnSmATilde</string>
+ <string>LtnSmARingAbv</string>
+ <string>DottedCirc</string>
+ <string>Hyphen</string>
+ <string>NonBreakingHyphen</string>
+ <string>Hyphen_Soft</string>
+ <string>CombAcute</string>
+ <string>CombGrave</string>
+ <string>CombCircum</string>
+ <string>CombTilde</string>
+ <string>CombDiaer</string>
+ <string>CombRingAbv</string>
+ </array>
+ <key>com.schriftgestaltung.keyboardIncrement</key>
+ <integer>1</integer>
+ <key>com.schriftgestaltung.weight</key>
+ <string>Regular</string>
+ <key>com.schriftgestaltung.weightValue</key>
+ <integer>400</integer>
+ <key>com.schriftgestaltung.width</key>
+ <string>Regular</string>
+ <key>com.schriftgestaltung.widthValue</key>
+ <integer>100</integer>
+ <key>org.sil.lcg.toneLetters</key>
+ <dict>
+ <key>contourWidth</key>
+ <integer>480</integer>
+ <key>dotSize</key>
+ <integer>180</integer>
+ <key>dotSpacing</key>
+ <integer>200</integer>
+ <key>glyphDepth</key>
+ <integer>-25</integer>
+ <key>glyphHeight</key>
+ <integer>1600</integer>
+ <key>italicAngle</key>
+ <integer>0</integer>
+ <key>marginDotLeft</key>
+ <integer>120</integer>
+ <key>marginDotRight</key>
+ <integer>160</integer>
+ <key>marginFlatLeft</key>
+ <integer>120</integer>
+ <key>marginFlatRight</key>
+ <integer>160</integer>
+ <key>marginPointLeft</key>
+ <integer>100</integer>
+ <key>marginPointRight</key>
+ <integer>140</integer>
+ <key>strokeThickness</key>
+ <integer>120</integer>
+ </dict>
+ <key>public.glyphOrder</key>
+ <array>
+ <string>.notdef</string>
+ <string>.null</string>
+ <string>nonmarkingreturn</string>
+ <string>Space</string>
+ <string>ExclamationMrk</string>
+ <string>QuotMrk</string>
+ <string>NumSgn</string>
+ <string>DollarSgn</string>
+ <string>PercentSgn</string>
+ <string>Ampersand</string>
+ <string>Apos</string>
+ <string>LftParen</string>
+ <string>RtParen</string>
+ <string>Asterisk</string>
+ <string>PlusSgn</string>
+ <string>Comma</string>
+ <string>HyphenMinus</string>
+ <string>FullStop</string>
+ <string>Solidus</string>
+ <string>DigitZero</string>
+ <string>DigitOne</string>
+ <string>DigitTwo</string>
+ <string>DigitThree</string>
+ <string>DigitFour</string>
+ <string>DigitFive</string>
+ <string>DigitSix</string>
+ <string>DigitSeven</string>
+ <string>DigitEight</string>
+ <string>DigitNine</string>
+ <string>Colon</string>
+ <string>Semicolon</string>
+ <string>LTSgn</string>
+ <string>EqSgn</string>
+ <string>GTSgn</string>
+ <string>QstnMrk</string>
+ <string>AtSgn</string>
+ <string>LtnCapA</string>
+ <string>LtnCapA.alt</string>
+ <string>LtnCapB</string>
+ <string>LtnCapC</string>
+ <string>LtnCapD</string>
+ <string>LtnCapE</string>
+ <string>LtnCapF</string>
+ <string>LtnCapG</string>
+ <string>LtnCapH</string>
+ <string>LtnCapI</string>
+ <string>LtnCapJ</string>
+ <string>LtnCapK</string>
+ <string>LtnCapL</string>
+ <string>LtnCapM</string>
+ <string>LtnCapN</string>
+ <string>LtnCapO</string>
+ <string>LtnCapP</string>
+ <string>LtnCapQ</string>
+ <string>LtnCapR</string>
+ <string>LtnCapS</string>
+ <string>LtnCapT</string>
+ <string>LtnCapU</string>
+ <string>LtnCapV</string>
+ <string>LtnCapW</string>
+ <string>LtnCapX</string>
+ <string>LtnCapY</string>
+ <string>LftSqrBrac</string>
+ <string>ReverseSolidus</string>
+ <string>RtSqrBrac</string>
+ <string>CircumAccent</string>
+ <string>LowLine</string>
+ <string>GraveAccent</string>
+ <string>LtnSmA</string>
+ <string>LtnSmB</string>
+ <string>LtnSmC</string>
+ <string>LtnSmD</string>
+ <string>LtnSmE</string>
+ <string>LtnSmF</string>
+ <string>LtnSmG</string>
+ <string>LtnSmH</string>
+ <string>LtnSmI</string>
+ <string>LtnSmJ</string>
+ <string>LtnSmK</string>
+ <string>LtnSmL</string>
+ <string>LtnSmM</string>
+ <string>LtnSmN</string>
+ <string>LtnSmO</string>
+ <string>LtnSmP</string>
+ <string>LtnSmQ</string>
+ <string>LtnSmR</string>
+ <string>LtnSmS</string>
+ <string>LtnSmT</string>
+ <string>LtnSmU</string>
+ <string>LtnSmV</string>
+ <string>LtnSmW</string>
+ <string>LtnSmX</string>
+ <string>LtnSmY</string>
+ <string>LftCurlyBrac</string>
+ <string>VertLine</string>
+ <string>RtCurlyBrac</string>
+ <string>Tilde</string>
+ <string>LtnCapADiaer</string>
+ <string>LtnSmAAcute</string>
+ <string>LtnSmAGrave</string>
+ <string>LtnSmACircum</string>
+ <string>LtnSmADiaer</string>
+ <string>LtnSmATilde</string>
+ <string>LtnSmARingAbv</string>
+ <string>DottedCirc</string>
+ <string>Hyphen</string>
+ <string>NonBreakingHyphen</string>
+ <string>Hyphen_Soft</string>
+ <string>CombAcute</string>
+ <string>CombGrave</string>
+ <string>CombCircum</string>
+ <string>CombTilde</string>
+ <string>CombDiaer</string>
+ <string>CombRingAbv</string>
+ </array>
+ <key>public.postscriptNames</key>
+ <dict>
+ <key>Ampersand</key>
+ <string>ampersand</string>
+ <key>Apos</key>
+ <string>quotesingle</string>
+ <key>Asterisk</key>
+ <string>asterisk</string>
+ <key>AtSgn</key>
+ <string>at</string>
+ <key>CircumAccent</key>
+ <string>asciicircum</string>
+ <key>Colon</key>
+ <string>colon</string>
+ <key>CombAcute</key>
+ <string>acutecomb</string>
+ <key>CombCircum</key>
+ <string>uni0302</string>
+ <key>CombDiaer</key>
+ <string>uni0308</string>
+ <key>CombGrave</key>
+ <string>gravecomb</string>
+ <key>CombRingAbv</key>
+ <string>uni030A</string>
+ <key>CombTilde</key>
+ <string>tildecomb</string>
+ <key>Comma</key>
+ <string>comma</string>
+ <key>DigitEight</key>
+ <string>eight</string>
+ <key>DigitFive</key>
+ <string>five</string>
+ <key>DigitFour</key>
+ <string>four</string>
+ <key>DigitNine</key>
+ <string>nine</string>
+ <key>DigitOne</key>
+ <string>one</string>
+ <key>DigitSeven</key>
+ <string>seven</string>
+ <key>DigitSix</key>
+ <string>six</string>
+ <key>DigitThree</key>
+ <string>three</string>
+ <key>DigitTwo</key>
+ <string>two</string>
+ <key>DigitZero</key>
+ <string>zero</string>
+ <key>DollarSgn</key>
+ <string>dollar</string>
+ <key>DottedCirc</key>
+ <string>uni25CC</string>
+ <key>EqSgn</key>
+ <string>equal</string>
+ <key>ExclamationMrk</key>
+ <string>exclam</string>
+ <key>FullStop</key>
+ <string>period</string>
+ <key>GTSgn</key>
+ <string>greater</string>
+ <key>GraveAccent</key>
+ <string>grave</string>
+ <key>Hyphen</key>
+ <string>uni2010</string>
+ <key>HyphenMinus</key>
+ <string>hyphen</string>
+ <key>Hyphen_Soft</key>
+ <string>uni00AD</string>
+ <key>LTSgn</key>
+ <string>less</string>
+ <key>LftCurlyBrac</key>
+ <string>braceleft</string>
+ <key>LftParen</key>
+ <string>parenleft</string>
+ <key>LftSqrBrac</key>
+ <string>bracketleft</string>
+ <key>LowLine</key>
+ <string>underscore</string>
+ <key>LtnCapA</key>
+ <string>A</string>
+ <key>LtnCapA.alt</key>
+ <string>A</string>
+ <key>LtnCapADiaer</key>
+ <string>Adieresis</string>
+ <key>LtnCapB</key>
+ <string>B</string>
+ <key>LtnCapC</key>
+ <string>C</string>
+ <key>LtnCapD</key>
+ <string>D</string>
+ <key>LtnCapE</key>
+ <string>E</string>
+ <key>LtnCapF</key>
+ <string>F</string>
+ <key>LtnCapG</key>
+ <string>G</string>
+ <key>LtnCapH</key>
+ <string>H</string>
+ <key>LtnCapI</key>
+ <string>I</string>
+ <key>LtnCapJ</key>
+ <string>J</string>
+ <key>LtnCapK</key>
+ <string>K</string>
+ <key>LtnCapL</key>
+ <string>L</string>
+ <key>LtnCapM</key>
+ <string>M</string>
+ <key>LtnCapN</key>
+ <string>N</string>
+ <key>LtnCapO</key>
+ <string>O</string>
+ <key>LtnCapP</key>
+ <string>P</string>
+ <key>LtnCapQ</key>
+ <string>Q</string>
+ <key>LtnCapR</key>
+ <string>R</string>
+ <key>LtnCapS</key>
+ <string>S</string>
+ <key>LtnCapT</key>
+ <string>T</string>
+ <key>LtnCapU</key>
+ <string>U</string>
+ <key>LtnCapV</key>
+ <string>V</string>
+ <key>LtnCapW</key>
+ <string>W</string>
+ <key>LtnCapX</key>
+ <string>X</string>
+ <key>LtnCapY</key>
+ <string>Y</string>
+ <key>LtnSmA</key>
+ <string>a</string>
+ <key>LtnSmAAcute</key>
+ <string>aacute</string>
+ <key>LtnSmACircum</key>
+ <string>acircumflex</string>
+ <key>LtnSmADiaer</key>
+ <string>adieresis</string>
+ <key>LtnSmAGrave</key>
+ <string>agrave</string>
+ <key>LtnSmARingAbv</key>
+ <string>aring</string>
+ <key>LtnSmATilde</key>
+ <string>atilde</string>
+ <key>LtnSmB</key>
+ <string>b</string>
+ <key>LtnSmC</key>
+ <string>c</string>
+ <key>LtnSmD</key>
+ <string>d</string>
+ <key>LtnSmE</key>
+ <string>e</string>
+ <key>LtnSmF</key>
+ <string>f</string>
+ <key>LtnSmG</key>
+ <string>g</string>
+ <key>LtnSmH</key>
+ <string>h</string>
+ <key>LtnSmI</key>
+ <string>i</string>
+ <key>LtnSmJ</key>
+ <string>j</string>
+ <key>LtnSmK</key>
+ <string>k</string>
+ <key>LtnSmL</key>
+ <string>l</string>
+ <key>LtnSmM</key>
+ <string>m</string>
+ <key>LtnSmN</key>
+ <string>n</string>
+ <key>LtnSmO</key>
+ <string>o</string>
+ <key>LtnSmP</key>
+ <string>p</string>
+ <key>LtnSmQ</key>
+ <string>q</string>
+ <key>LtnSmR</key>
+ <string>r</string>
+ <key>LtnSmS</key>
+ <string>s</string>
+ <key>LtnSmT</key>
+ <string>t</string>
+ <key>LtnSmU</key>
+ <string>u</string>
+ <key>LtnSmV</key>
+ <string>v</string>
+ <key>LtnSmW</key>
+ <string>w</string>
+ <key>LtnSmX</key>
+ <string>x</string>
+ <key>LtnSmY</key>
+ <string>y</string>
+ <key>NonBreakingHyphen</key>
+ <string>uni2011</string>
+ <key>NumSgn</key>
+ <string>numbersign</string>
+ <key>PercentSgn</key>
+ <string>percent</string>
+ <key>PlusSgn</key>
+ <string>plus</string>
+ <key>QstnMrk</key>
+ <string>question</string>
+ <key>QuotMrk</key>
+ <string>quotedbl</string>
+ <key>ReverseSolidus</key>
+ <string>backslash</string>
+ <key>RtCurlyBrac</key>
+ <string>braceright</string>
+ <key>RtParen</key>
+ <string>parenright</string>
+ <key>RtSqrBrac</key>
+ <string>bracketright</string>
+ <key>Semicolon</key>
+ <string>semicolon</string>
+ <key>Solidus</key>
+ <string>slash</string>
+ <key>Space</key>
+ <string>space</string>
+ <key>Tilde</key>
+ <string>asciitilde</string>
+ <key>VertLine</key>
+ <string>bar</string>
+ </dict>
+</dict>
+</plist>
diff --git a/tests/reference/ufo/psfdeleteglyphs.ufo/metainfo.plist b/tests/reference/ufo/psfdeleteglyphs.ufo/metainfo.plist
new file mode 100644
index 0000000..aa10c5c
--- /dev/null
+++ b/tests/reference/ufo/psfdeleteglyphs.ufo/metainfo.plist
@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+ <key>creator</key>
+ <string>org.sil.scripts.pysilfont</string>
+ <key>formatVersion</key>
+ <integer>3</integer>
+</dict>
+</plist>
diff --git a/tests/reference/ufo/psfexportanchors.lg b/tests/reference/ufo/psfexportanchors.lg
new file mode 100644
index 0000000..4dd54bf
--- /dev/null
+++ b/tests/reference/ufo/psfexportanchors.lg
@@ -0,0 +1,17 @@
+2021-06-29 14:42:19 Progress: Running: psfexportanchors tests/input/font-psf-test/source/PsfTest-Italic.ufo local/testresults/ufo/psfexportanchors.xml -l local/testresults/ufo/psfexportanchors.log
+2021-06-29 14:42:19 Progress: Opening file for output: @cwd@/local/testresults/ufo/psfexportanchors.xml
+2021-06-29 14:42:19 Progress: Reading UFO: tests/input/font-psf-test/source/PsfTest-Italic.ufo
+2021-06-29 14:42:20 Progress: Checking fontinfo.plist metadata
+2021-06-29 14:42:20 Warning: openTypeOS2FamilyClass would be removed from fontinfo Old value: [0, 0]
+2021-06-29 14:42:20 Warning: year would be removed from fontinfo Old value: 2021
+2021-06-29 14:42:20 Warning: capHeight would be updated Old value: 1485.3, new value: 1485
+2021-06-29 14:42:20 Warning: styleMapFamilyName would be uppdated Old value: Psf test, new value: Psf Test
+2021-06-29 14:42:20 Warning: openTypeOS2TypoLineGap would be updated Old value: 1, new value: 0
+2021-06-29 14:42:20 Warning: openTypeOS2Selection would be added New value: [7]
+2021-06-29 14:42:20 Warning: openTypeNamePreferredFamilyName would be updated Old value: Psf Testing, new value: Psf Test
+2021-06-29 14:42:20 Progress: Checking lib.plist metadata
+2021-06-29 14:42:20 Warning: com.schriftgestaltung.disablesAutomaticAlignment would be deleted - obsolete key Old value: True
+2021-06-29 14:42:20 Warning: com.schriftgestaltung.disablesLastChange would be deleted - obsolete key Old value: True
+2021-06-29 14:42:20 Progress: Check & fix results:- Errors: 0, Changes to make: 9, Other warnings: 0
+2021-06-29 14:42:20 Progress: See log file for details
+2021-06-29 14:42:20 Warning: LtnCapA.alt in public.glyphOrder list but absent from UFO
diff --git a/tests/reference/ufo/psfexportanchors.xml b/tests/reference/ufo/psfexportanchors.xml
new file mode 100644
index 0000000..45d2cc3
--- /dev/null
+++ b/tests/reference/ufo/psfexportanchors.xml
@@ -0,0 +1,928 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<font name="PsfTest-Italic" upem="2048">
+<glyph PSName=".notdef"/>
+<glyph PSName=".null"/>
+<glyph PSName="nonmarkingreturn"/>
+<glyph PSName="Space" UID="0020"/>
+<glyph PSName="ExclamationMrk" UID="0021"/>
+<glyph PSName="QuotMrk" UID="0022"/>
+<glyph PSName="NumSgn" UID="0023"/>
+<glyph PSName="DollarSgn" UID="0024"/>
+<glyph PSName="PercentSgn" UID="0025"/>
+<glyph PSName="Ampersand" UID="0026"/>
+<glyph PSName="Apos" UID="0027"/>
+<glyph PSName="LftParen" UID="0028"/>
+<glyph PSName="RtParen" UID="0029"/>
+<glyph PSName="Asterisk" UID="002A"/>
+<glyph PSName="PlusSgn" UID="002B"/>
+<glyph PSName="Comma" UID="002C"/>
+<glyph PSName="HyphenMinus" UID="002D">
+ <point type="U">
+ <location x="645" y="1100"/>
+ </point>
+</glyph>
+<glyph PSName="FullStop" UID="002E"/>
+<glyph PSName="Solidus" UID="002F"/>
+<glyph PSName="DigitZero" UID="0030">
+ <point type="L">
+ <location x="520" y="-100"/>
+ </point>
+ <point type="U">
+ <location x="927" y="1530"/>
+ </point>
+</glyph>
+<glyph PSName="DigitOne" UID="0031">
+ <point type="L">
+ <location x="515" y="-100"/>
+ </point>
+ <point type="U">
+ <location x="922" y="1530"/>
+ </point>
+</glyph>
+<glyph PSName="DigitTwo" UID="0032">
+ <point type="L">
+ <location x="515" y="-100"/>
+ </point>
+ <point type="U">
+ <location x="882" y="1530"/>
+ </point>
+</glyph>
+<glyph PSName="DigitThree" UID="0033">
+ <point type="L">
+ <location x="515" y="-100"/>
+ </point>
+ <point type="U">
+ <location x="922" y="1530"/>
+ </point>
+</glyph>
+<glyph PSName="DigitFour" UID="0034">
+ <point type="L">
+ <location x="522" y="-100"/>
+ </point>
+ <point type="U">
+ <location x="929" y="1530"/>
+ </point>
+</glyph>
+<glyph PSName="DigitFive" UID="0035">
+ <point type="L">
+ <location x="515" y="-100"/>
+ </point>
+ <point type="U">
+ <location x="922" y="1530"/>
+ </point>
+</glyph>
+<glyph PSName="DigitSix" UID="0036">
+ <point type="L">
+ <location x="515" y="-100"/>
+ </point>
+ <point type="U">
+ <location x="922" y="1530"/>
+ </point>
+</glyph>
+<glyph PSName="DigitSeven" UID="0037">
+ <point type="L">
+ <location x="515" y="-100"/>
+ </point>
+ <point type="U">
+ <location x="922" y="1530"/>
+ </point>
+</glyph>
+<glyph PSName="DigitEight" UID="0038">
+ <point type="L">
+ <location x="515" y="-100"/>
+ </point>
+ <point type="U">
+ <location x="922" y="1530"/>
+ </point>
+</glyph>
+<glyph PSName="DigitNine" UID="0039">
+ <point type="L">
+ <location x="515" y="-100"/>
+ </point>
+ <point type="U">
+ <location x="922" y="1530"/>
+ </point>
+</glyph>
+<glyph PSName="Colon" UID="003A"/>
+<glyph PSName="Semicolon" UID="003B"/>
+<glyph PSName="LTSgn" UID="003C"/>
+<glyph PSName="EqSgn" UID="003D"/>
+<glyph PSName="GTSgn" UID="003E"/>
+<glyph PSName="QstnMrk" UID="003F"/>
+<glyph PSName="AtSgn" UID="0040"/>
+<glyph PSName="LtnCapA" UID="0041">
+ <point type="H">
+ <location x="1170" y="0"/>
+ </point>
+ <point type="L">
+ <location x="602" y="-100"/>
+ </point>
+ <point type="O">
+ <location x="1390" y="0"/>
+ </point>
+ <point type="U">
+ <location x="1009" y="1530"/>
+ </point>
+</glyph>
+<glyph PSName="LtnCapB" UID="0042">
+ <point type="L">
+ <location x="530" y="-100"/>
+ </point>
+ <point type="U">
+ <location x="937" y="1530"/>
+ </point>
+</glyph>
+<glyph PSName="LtnCapC" UID="0043">
+ <point type="H">
+ <location x="690" y="0"/>
+ </point>
+ <point type="L">
+ <location x="665" y="-100"/>
+ </point>
+ <point type="U">
+ <location x="1072" y="1530"/>
+ </point>
+</glyph>
+<glyph PSName="LtnCapD" UID="0044">
+ <point type="L">
+ <location x="630" y="-100"/>
+ </point>
+ <point type="U">
+ <location x="1037" y="1530"/>
+ </point>
+</glyph>
+<glyph PSName="LtnCapE" UID="0045">
+ <point type="H">
+ <location x="540" y="0"/>
+ </point>
+ <point type="L">
+ <location x="515" y="-100"/>
+ </point>
+ <point type="O">
+ <location x="857" y="0"/>
+ </point>
+ <point type="R">
+ <location x="1400" y="1200"/>
+ </point>
+ <point type="U">
+ <location x="922" y="1530"/>
+ </point>
+</glyph>
+<glyph PSName="LtnCapF" UID="0046">
+ <point type="L">
+ <location x="510" y="-100"/>
+ </point>
+ <point type="U">
+ <location x="917" y="1530"/>
+ </point>
+</glyph>
+<glyph PSName="LtnCapG" UID="0047">
+ <point type="H">
+ <location x="685" y="0"/>
+ </point>
+ <point type="L">
+ <location x="660" y="-100"/>
+ </point>
+ <point type="U">
+ <location x="1067" y="1530"/>
+ </point>
+</glyph>
+<glyph PSName="LtnCapH" UID="0048">
+ <point type="H">
+ <location x="225" y="0"/>
+ </point>
+ <point type="L">
+ <location x="640" y="-100"/>
+ </point>
+ <point type="U">
+ <location x="1047" y="1530"/>
+ </point>
+</glyph>
+<glyph PSName="LtnCapI" UID="0049">
+ <point type="H">
+ <location x="417" y="0"/>
+ </point>
+ <point type="L">
+ <location x="392" y="-100"/>
+ </point>
+ <point type="O">
+ <location x="613" y="0"/>
+ </point>
+ <point type="R">
+ <location x="1215" y="1200"/>
+ </point>
+ <point type="U">
+ <location x="799" y="1530"/>
+ </point>
+</glyph>
+<glyph PSName="LtnCapJ" UID="004A">
+ <point type="L">
+ <location x="325" y="-100"/>
+ </point>
+ <point type="U">
+ <location x="997" y="1530"/>
+ </point>
+</glyph>
+<glyph PSName="LtnCapK" UID="004B">
+ <point type="H">
+ <location x="210" y="0"/>
+ </point>
+ <point type="L">
+ <location x="610" y="-100"/>
+ </point>
+ <point type="U">
+ <location x="972" y="1530"/>
+ </point>
+</glyph>
+<glyph PSName="LtnCapL" UID="004C">
+ <point type="H">
+ <location x="532" y="0"/>
+ </point>
+ <point type="L">
+ <location x="507" y="-100"/>
+ </point>
+ <point type="R">
+ <location x="780" y="1200"/>
+ </point>
+ <point type="U">
+ <location x="914" y="1530"/>
+ </point>
+</glyph>
+<glyph PSName="LtnCapM" UID="004D">
+ <point type="L">
+ <location x="800" y="-100"/>
+ </point>
+ <point type="U">
+ <location x="1207" y="1530"/>
+ </point>
+</glyph>
+<glyph PSName="LtnCapN" UID="004E">
+ <point type="H">
+ <location x="1170" y="0"/>
+ </point>
+ <point type="L">
+ <location x="652" y="-100"/>
+ </point>
+ <point type="U">
+ <location x="1059" y="1530"/>
+ </point>
+</glyph>
+<glyph PSName="LtnCapO" UID="004F">
+ <point type="H">
+ <location x="657" y="0"/>
+ </point>
+ <point type="L">
+ <location x="632" y="-100"/>
+ </point>
+ <point type="O">
+ <location x="896" y="0"/>
+ </point>
+ <point type="R">
+ <location x="1700" y="1200"/>
+ </point>
+ <point type="U">
+ <location x="1039" y="1530"/>
+ </point>
+</glyph>
+<glyph PSName="LtnCapP" UID="0050">
+ <point type="L">
+ <location x="552" y="-100"/>
+ </point>
+ <point type="U">
+ <location x="959" y="1530"/>
+ </point>
+</glyph>
+<glyph PSName="LtnCapQ" UID="0051">
+ <point type="L">
+ <location x="589" y="-270"/>
+ </point>
+ <point type="U">
+ <location x="1039" y="1530"/>
+ </point>
+</glyph>
+<glyph PSName="LtnCapR" UID="0052">
+ <point type="H">
+ <location x="590" y="0"/>
+ </point>
+ <point type="L">
+ <location x="525" y="-100"/>
+ </point>
+ <point type="U">
+ <location x="932" y="1530"/>
+ </point>
+</glyph>
+<glyph PSName="LtnCapS" UID="0053">
+ <point type="H">
+ <location x="520" y="0"/>
+ </point>
+ <point type="L">
+ <location x="495" y="-100"/>
+ </point>
+ <point type="U">
+ <location x="902" y="1530"/>
+ </point>
+</glyph>
+<glyph PSName="LtnCapT" UID="0054">
+ <point type="H">
+ <location x="562" y="0"/>
+ </point>
+ <point type="L">
+ <location x="562" y="-100"/>
+ </point>
+ <point type="U">
+ <location x="944" y="1530"/>
+ </point>
+</glyph>
+<glyph PSName="LtnCapU" UID="0055">
+ <point type="H">
+ <location x="647" y="0"/>
+ </point>
+ <point type="L">
+ <location x="622" y="-100"/>
+ </point>
+ <point type="O">
+ <location x="865" y="0"/>
+ </point>
+ <point type="R">
+ <location x="1640" y="1200"/>
+ </point>
+ <point type="U">
+ <location x="1029" y="1530"/>
+ </point>
+</glyph>
+<glyph PSName="LtnCapV" UID="0056">
+ <point type="H">
+ <location x="620" y="0"/>
+ </point>
+ <point type="L">
+ <location x="587" y="-100"/>
+ </point>
+ <point type="O">
+ <location x="820" y="0"/>
+ </point>
+ <point type="U">
+ <location x="994" y="1530"/>
+ </point>
+</glyph>
+<glyph PSName="LtnCapW" UID="0057">
+ <point type="L">
+ <location x="942" y="-100"/>
+ </point>
+ <point type="U">
+ <location x="1349" y="1530"/>
+ </point>
+</glyph>
+<glyph PSName="LtnCapX" UID="0058">
+ <point type="L">
+ <location x="565" y="-100"/>
+ </point>
+ <point type="U">
+ <location x="972" y="1530"/>
+ </point>
+</glyph>
+<glyph PSName="LtnCapY" UID="0059">
+ <point type="L">
+ <location x="565" y="-100"/>
+ </point>
+ <point type="U">
+ <location x="972" y="1530"/>
+ </point>
+</glyph>
+<glyph PSName="LftSqrBrac" UID="005B"/>
+<glyph PSName="ReverseSolidus" UID="005C"/>
+<glyph PSName="RtSqrBrac" UID="005D"/>
+<glyph PSName="CircumAccent" UID="005E">
+ <point type="U">
+ <location x="705" y="1635"/>
+ </point>
+</glyph>
+<glyph PSName="LowLine" UID="005F"/>
+<glyph PSName="GraveAccent" UID="0060">
+ <point type="U">
+ <location x="738" y="1635"/>
+ </point>
+</glyph>
+<glyph PSName="LtnSmA" UID="0061">
+ <point type="H">
+ <location x="860" y="0"/>
+ </point>
+ <point type="L">
+ <location x="455" y="-100"/>
+ </point>
+ <point type="O">
+ <location x="1065" y="0"/>
+ </point>
+ <point type="R">
+ <location x="1310" y="1000"/>
+ </point>
+ <point type="U">
+ <location x="755" y="1100"/>
+ </point>
+</glyph>
+<glyph PSName="LtnSmB" UID="0062">
+ <point type="H">
+ <location x="530" y="0"/>
+ </point>
+ <point type="L">
+ <location x="505" y="-100"/>
+ </point>
+ <point type="R">
+ <location x="1345" y="1000"/>
+ </point>
+ <point type="U">
+ <location x="938" y="1635"/>
+ </point>
+</glyph>
+<glyph PSName="LtnSmC" UID="0063">
+ <point type="H">
+ <location x="520" y="0"/>
+ </point>
+ <point type="L">
+ <location x="495" y="-100"/>
+ </point>
+ <point type="R">
+ <location x="1210" y="1000"/>
+ </point>
+ <point type="U">
+ <location x="785" y="1100"/>
+ </point>
+</glyph>
+<glyph PSName="LtnSmD" UID="0064">
+ <point type="H">
+ <location x="545" y="0"/>
+ </point>
+ <point type="L">
+ <location x="520" y="-100"/>
+ </point>
+ <point type="R">
+ <location x="1380" y="1000"/>
+ </point>
+ <point type="U">
+ <location x="953" y="1635"/>
+ </point>
+</glyph>
+<glyph PSName="LtnSmE" UID="0065">
+ <point type="H">
+ <location x="485" y="0"/>
+ </point>
+ <point type="L">
+ <location x="484" y="-100"/>
+ </point>
+ <point type="O">
+ <location x="840" y="0"/>
+ </point>
+ <point type="R">
+ <location x="1285" y="1000"/>
+ </point>
+ <point type="U">
+ <location x="784" y="1100"/>
+ </point>
+</glyph>
+<glyph PSName="LtnSmF" UID="0066">
+ <point type="H">
+ <location x="290" y="0"/>
+ </point>
+ <point type="L">
+ <location x="315" y="-100"/>
+ </point>
+ <point type="U">
+ <location x="908" y="1635"/>
+ </point>
+</glyph>
+<glyph PSName="LtnSmG" UID="0067">
+ <point type="H">
+ <location x="368" y="-465"/>
+ </point>
+ <point type="L">
+ <location x="351" y="-535"/>
+ </point>
+ <point type="R">
+ <location x="1285" y="1000"/>
+ </point>
+ <point type="U">
+ <location x="730" y="1100"/>
+ </point>
+</glyph>
+<glyph PSName="LtnSmH" UID="0068">
+ <point type="H">
+ <location x="190" y="0"/>
+ </point>
+ <point type="L">
+ <location x="550" y="-100"/>
+ </point>
+ <point type="U">
+ <location x="933" y="1635"/>
+ </point>
+</glyph>
+<glyph PSName="LtnSmI" UID="0069">
+ <point type="H">
+ <location x="235" y="0"/>
+ </point>
+ <point type="L">
+ <location x="250" y="-100"/>
+ </point>
+ <point type="O">
+ <location x="455" y="0"/>
+ </point>
+ <point type="R">
+ <location x="745" y="1000"/>
+ </point>
+ <point type="U">
+ <location x="472" y="1100"/>
+ </point>
+</glyph>
+<glyph PSName="LtnSmJ" UID="006A">
+ <point type="L">
+ <location x="-60" y="-500"/>
+ </point>
+ <point type="U">
+ <location x="510" y="1100"/>
+ </point>
+</glyph>
+<glyph PSName="LtnSmK" UID="006B">
+ <point type="H">
+ <location x="840" y="0"/>
+ </point>
+ <point type="L">
+ <location x="537" y="-100"/>
+ </point>
+ <point type="R">
+ <location x="1225" y="1000"/>
+ </point>
+ <point type="U">
+ <location x="920" y="1635"/>
+ </point>
+</glyph>
+<glyph PSName="LtnSmL" UID="006C">
+ <point type="H">
+ <location x="230" y="0"/>
+ </point>
+ <point type="L">
+ <location x="255" y="-100"/>
+ </point>
+ <point type="R">
+ <location x="740" y="1000"/>
+ </point>
+ <point type="U">
+ <location x="630" y="1635"/>
+ </point>
+</glyph>
+<glyph PSName="LtnSmM" UID="006D">
+ <point type="H">
+ <location x="805" y="0"/>
+ </point>
+ <point type="L">
+ <location x="780" y="-100"/>
+ </point>
+ <point type="U">
+ <location x="1080" y="1100"/>
+ </point>
+</glyph>
+<glyph PSName="LtnSmN" UID="006E">
+ <point type="H">
+ <location x="540" y="0"/>
+ </point>
+ <point type="L">
+ <location x="565" y="-100"/>
+ </point>
+ <point type="U">
+ <location x="815" y="1100"/>
+ </point>
+</glyph>
+<glyph PSName="LtnSmO" UID="006F">
+ <point type="H">
+ <location x="510" y="0"/>
+ </point>
+ <point type="L">
+ <location x="505" y="-100"/>
+ </point>
+ <point type="O">
+ <location x="800" y="0"/>
+ </point>
+ <point type="R">
+ <location x="1330" y="1000"/>
+ </point>
+ <point type="U">
+ <location x="785" y="1100"/>
+ </point>
+</glyph>
+<glyph PSName="LtnSmP" UID="0070">
+ <point type="H">
+ <location x="105" y="-435"/>
+ </point>
+ <point type="L">
+ <location x="405" y="-500"/>
+ </point>
+ <point type="R">
+ <location x="1360" y="1000"/>
+ </point>
+ <point type="U">
+ <location x="805" y="1100"/>
+ </point>
+</glyph>
+<glyph PSName="LtnSmQ" UID="0071">
+ <point type="L">
+ <location x="370" y="-500"/>
+ </point>
+ <point type="R">
+ <location x="1320" y="1000"/>
+ </point>
+ <point type="U">
+ <location x="770" y="1100"/>
+ </point>
+</glyph>
+<glyph PSName="LtnSmR" UID="0072">
+ <point type="H">
+ <location x="210" y="0"/>
+ </point>
+ <point type="L">
+ <location x="220" y="-100"/>
+ </point>
+ <point type="U">
+ <location x="670" y="1100"/>
+ </point>
+</glyph>
+<glyph PSName="LtnSmS" UID="0073">
+ <point type="H">
+ <location x="435" y="0"/>
+ </point>
+ <point type="L">
+ <location x="440" y="-100"/>
+ </point>
+ <point type="U">
+ <location x="710" y="1100"/>
+ </point>
+</glyph>
+<glyph PSName="LtnSmT" UID="0074">
+ <point type="H">
+ <location x="455" y="0"/>
+ </point>
+ <point type="L">
+ <location x="390" y="-100"/>
+ </point>
+ <point type="R">
+ <location x="1025" y="1000"/>
+ </point>
+ <point type="U">
+ <location x="605" y="1360"/>
+ </point>
+</glyph>
+<glyph PSName="LtnSmU" UID="0075">
+ <point type="H">
+ <location x="465" y="0"/>
+ </point>
+ <point type="L">
+ <location x="504" y="-100"/>
+ </point>
+ <point type="O">
+ <location x="640" y="0"/>
+ </point>
+ <point type="R">
+ <location x="1375" y="1000"/>
+ </point>
+ <point type="U">
+ <location x="804" y="1100"/>
+ </point>
+</glyph>
+<glyph PSName="LtnSmV" UID="0076">
+ <point type="H">
+ <location x="359" y="0"/>
+ </point>
+ <point type="L">
+ <location x="350" y="-100"/>
+ </point>
+ <point type="O">
+ <location x="565" y="0"/>
+ </point>
+ <point type="U">
+ <location x="650" y="1100"/>
+ </point>
+</glyph>
+<glyph PSName="LtnSmW" UID="0077">
+ <point type="L">
+ <location x="690" y="-100"/>
+ </point>
+ <point type="U">
+ <location x="990" y="1100"/>
+ </point>
+</glyph>
+<glyph PSName="LtnSmX" UID="0078">
+ <point type="H">
+ <location x="840" y="0"/>
+ </point>
+ <point type="L">
+ <location x="457" y="-100"/>
+ </point>
+ <point type="U">
+ <location x="657" y="1100"/>
+ </point>
+</glyph>
+<glyph PSName="LtnSmY" UID="0079">
+ <point type="L">
+ <location x="710" y="-100"/>
+ </point>
+ <point type="R">
+ <location x="1270" y="1000"/>
+ </point>
+ <point type="U">
+ <location x="630" y="1100"/>
+ </point>
+</glyph>
+<glyph PSName="LftCurlyBrac" UID="007B"/>
+<glyph PSName="VertLine" UID="007C"/>
+<glyph PSName="RtCurlyBrac" UID="007D"/>
+<glyph PSName="Tilde" UID="007E"/>
+<glyph PSName="LtnCapADiaer" UID="00C4">
+ <point type="H">
+ <location x="1170" y="0"/>
+ </point>
+ <point type="L">
+ <location x="602" y="-100"/>
+ </point>
+ <point type="O">
+ <location x="1390" y="0"/>
+ </point>
+ <point type="U">
+ <location x="1106" y="1935"/>
+ </point>
+</glyph>
+<glyph PSName="LtnSmAAcute" UID="00E1">
+ <point type="H">
+ <location x="860" y="0"/>
+ </point>
+ <point type="L">
+ <location x="455" y="-100"/>
+ </point>
+ <point type="O">
+ <location x="1065" y="0"/>
+ </point>
+ <point type="R">
+ <location x="1310" y="1000"/>
+ </point>
+ <point type="U">
+ <location x="889" y="1635"/>
+ </point>
+</glyph>
+<glyph PSName="LtnSmAGrave" UID="00E0">
+ <point type="H">
+ <location x="860" y="0"/>
+ </point>
+ <point type="L">
+ <location x="455" y="-100"/>
+ </point>
+ <point type="O">
+ <location x="1065" y="0"/>
+ </point>
+ <point type="R">
+ <location x="1310" y="1000"/>
+ </point>
+ <point type="U">
+ <location x="889" y="1635"/>
+ </point>
+</glyph>
+<glyph PSName="LtnSmACircum" UID="00E2">
+ <point type="H">
+ <location x="860" y="0"/>
+ </point>
+ <point type="L">
+ <location x="455" y="-100"/>
+ </point>
+ <point type="O">
+ <location x="1065" y="0"/>
+ </point>
+ <point type="R">
+ <location x="1310" y="1000"/>
+ </point>
+ <point type="U">
+ <location x="854" y="1635"/>
+ </point>
+</glyph>
+<glyph PSName="LtnSmADiaer" UID="00E4">
+ <point type="H">
+ <location x="860" y="0"/>
+ </point>
+ <point type="L">
+ <location x="455" y="-100"/>
+ </point>
+ <point type="O">
+ <location x="1065" y="0"/>
+ </point>
+ <point type="R">
+ <location x="1310" y="1000"/>
+ </point>
+ <point type="U">
+ <location x="852" y="1505"/>
+ </point>
+</glyph>
+<glyph PSName="LtnSmATilde" UID="00E3">
+ <point type="H">
+ <location x="860" y="0"/>
+ </point>
+ <point type="L">
+ <location x="455" y="-100"/>
+ </point>
+ <point type="O">
+ <location x="1065" y="0"/>
+ </point>
+ <point type="R">
+ <location x="1310" y="1000"/>
+ </point>
+ <point type="U">
+ <location x="850" y="1475"/>
+ </point>
+</glyph>
+<glyph PSName="LtnSmARingAbv" UID="00E5">
+ <point type="H">
+ <location x="860" y="0"/>
+ </point>
+ <point type="L">
+ <location x="455" y="-100"/>
+ </point>
+ <point type="O">
+ <location x="1065" y="0"/>
+ </point>
+ <point type="R">
+ <location x="1310" y="1000"/>
+ </point>
+ <point type="U">
+ <location x="919" y="1635"/>
+ </point>
+</glyph>
+<glyph PSName="DottedCirc" UID="25CC">
+ <point type="H">
+ <location x="493" y="0"/>
+ </point>
+ <point type="L">
+ <location x="468" y="-100"/>
+ </point>
+ <point type="O">
+ <location x="750" y="0"/>
+ </point>
+ <point type="U">
+ <location x="743" y="1000"/>
+ </point>
+</glyph>
+<glyph PSName="Hyphen" UID="2010">
+ <point type="U">
+ <location x="645" y="1100"/>
+ </point>
+</glyph>
+<glyph PSName="NonBreakingHyphen" UID="2011">
+ <point type="U">
+ <location x="645" y="1100"/>
+ </point>
+</glyph>
+<glyph PSName="Hyphen_Soft" UID="00AD">
+ <point type="U">
+ <location x="645" y="1100"/>
+ </point>
+</glyph>
+<glyph PSName="CombAcute" UID="0301">
+ <point type="U">
+ <location x="-221" y="1635"/>
+ </point>
+ <point type="_U">
+ <location x="-355" y="1100"/>
+ </point>
+</glyph>
+<glyph PSName="CombGrave" UID="0300">
+ <point type="U">
+ <location x="-201" y="1635"/>
+ </point>
+ <point type="_U">
+ <location x="-335" y="1100"/>
+ </point>
+</glyph>
+<glyph PSName="CombCircum" UID="0302">
+ <point type="U">
+ <location x="-221" y="1635"/>
+ </point>
+ <point type="_U">
+ <location x="-320" y="1100"/>
+ </point>
+</glyph>
+<glyph PSName="CombTilde" UID="0303">
+ <point type="U">
+ <location x="-290" y="1475"/>
+ </point>
+ <point type="_U">
+ <location x="-385" y="1100"/>
+ </point>
+</glyph>
+<glyph PSName="CombDiaer" UID="0308">
+ <point type="U">
+ <location x="-253" y="1505"/>
+ </point>
+ <point type="_U">
+ <location x="-350" y="1100"/>
+ </point>
+</glyph>
+<glyph PSName="CombRingAbv" UID="030A">
+ <point type="U">
+ <location x="-221" y="1635"/>
+ </point>
+ <point type="_U">
+ <location x="-385" y="1100"/>
+ </point>
+</glyph>
+</font>
diff --git a/tests/reference/ufo/psfexportunicodes.csv b/tests/reference/ufo/psfexportunicodes.csv
new file mode 100644
index 0000000..741c210
--- /dev/null
+++ b/tests/reference/ufo/psfexportunicodes.csv
@@ -0,0 +1,113 @@
+# 2018-09-19 20:11:23 psfexportunicodes
+# tests/input/font-psf-test/source/PsfTest-BoldItalic.ufo -o local/testresults/ufo/psfexportunicodes.csv -l local/testresults/ufo/psfexportunicodes.log
+
+Ampersand,0026
+Apos,0027
+Asterisk,002A
+AtSgn,0040
+CircumAccent,005E
+Colon,003A
+CombAcute,0301
+CombCircum,0302
+CombDiaer,0308
+CombGrave,0300
+CombRingAbv,030A
+CombTilde,0303
+Comma,002C
+DigitEight,0038
+DigitFive,0035
+DigitFour,0034
+DigitNine,0039
+DigitOne,0031
+DigitSeven,0037
+DigitSix,0036
+DigitThree,0033
+DigitTwo,0032
+DigitZero,0030
+DollarSgn,0024
+DottedCirc,25CC
+EqSgn,003D
+ExclamationMrk,0021
+FullStop,002E
+GTSgn,003E
+GraveAccent,0060
+Hyphen,2010
+HyphenMinus,002D
+Hyphen_Soft,00AD
+LTSgn,003C
+LftCurlyBrac,007B
+LftParen,0028
+LftSqrBrac,005B
+LowLine,005F
+LtnCapA,0041
+LtnCapADiaer,00C4
+LtnCapB,0042
+LtnCapC,0043
+LtnCapD,0044
+LtnCapE,0045
+LtnCapF,0046
+LtnCapG,0047
+LtnCapH,0048
+LtnCapI,0049
+LtnCapJ,004A
+LtnCapK,004B
+LtnCapL,004C
+LtnCapM,004D
+LtnCapN,004E
+LtnCapO,004F
+LtnCapP,0050
+LtnCapQ,0051
+LtnCapR,0052
+LtnCapS,0053
+LtnCapT,0054
+LtnCapU,0055
+LtnCapV,0056
+LtnCapW,0057
+LtnCapX,0058
+LtnCapY,0059
+LtnSmA,0061
+LtnSmAAcute,00E1
+LtnSmACircum,00E2
+LtnSmADiaer,00E4
+LtnSmAGrave,00E0
+LtnSmARingAbv,00E5
+LtnSmATilde,00E3
+LtnSmB,0062
+LtnSmC,0063
+LtnSmD,0064
+LtnSmE,0065
+LtnSmF,0066
+LtnSmG,0067
+LtnSmH,0068
+LtnSmI,0069
+LtnSmJ,006A
+LtnSmK,006B
+LtnSmL,006C
+LtnSmM,006D
+LtnSmN,006E
+LtnSmO,006F
+LtnSmP,0070
+LtnSmQ,0071
+LtnSmR,0072
+LtnSmS,0073
+LtnSmT,0074
+LtnSmU,0075
+LtnSmV,0076
+LtnSmW,0077
+LtnSmX,0078
+LtnSmY,0079
+NonBreakingHyphen,2011
+NumSgn,0023
+PercentSgn,0025
+PlusSgn,002B
+QstnMrk,003F
+QuotMrk,0022
+ReverseSolidus,005C
+RtCurlyBrac,007D
+RtParen,0029
+RtSqrBrac,005D
+Semicolon,003B
+Solidus,002F
+Space,0020
+Tilde,007E
+VertLine,007C
diff --git a/tests/reference/ufo/psfexportunicodes.lg b/tests/reference/ufo/psfexportunicodes.lg
new file mode 100644
index 0000000..89b9e5a
--- /dev/null
+++ b/tests/reference/ufo/psfexportunicodes.lg
@@ -0,0 +1,14 @@
+2021-06-29 14:42:20 Progress: Running: psfexportunicodes tests/input/font-psf-test/source/PsfTest-BoldItalic.ufo -o local/testresults/ufo/psfexportunicodes.csv -l local/testresults/ufo/psfexportunicodes.log
+2021-06-29 14:42:20 Progress: Opening file for output: @cwd@/local/testresults/ufo/psfexportunicodes.csv
+2021-06-29 14:42:20 Progress: Reading UFO: tests/input/font-psf-test/source/PsfTest-BoldItalic.ufo
+2021-06-29 14:42:20 Progress: Checking fontinfo.plist metadata
+2021-06-29 14:42:20 Warning: macintoshFONDName would be removed from fontinfo Old value: My Test
+2021-06-29 14:42:20 Warning: openTypeOS2FamilyClass would be removed from fontinfo Old value: [0, 0]
+2021-06-29 14:42:20 Warning: postscriptFamilyBlues would be removed from fontinfo Old value: []
+2021-06-29 14:42:20 Warning: openTypeOS2Selection would be added New value: [7]
+2021-06-29 14:42:20 Warning: openTypeHheaAscender would be updated Old value: 2200, new value: 2100
+2021-06-29 14:42:20 Progress: Checking lib.plist metadata
+2021-06-29 14:42:20 Warning: com.schriftgestaltung.disablesAutomaticAlignment would be deleted - obsolete key Old value: True
+2021-06-29 14:42:20 Warning: com.schriftgestaltung.disablesLastChange would be deleted - obsolete key Old value: True
+2021-06-29 14:42:20 Progress: Check & fix results:- Errors: 0, Changes to make: 7, Other warnings: 0
+2021-06-29 14:42:20 Progress: See log file for details
diff --git a/tests/reference/ufo/psfgenftml.ftml b/tests/reference/ufo/psfgenftml.ftml
new file mode 100644
index 0000000..e385e33
--- /dev/null
+++ b/tests/reference/ufo/psfgenftml.ftml
@@ -0,0 +1,66 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<?xml-stylesheet href="ftml.xsl" type="text/xsl"?>
+<ftml version="1.0">
+ <head>
+ <title>ftml_builder test</title>
+ </head>
+ <testgroup background="#f0f0f0" label="Rendering Check">
+ <test label="check">
+ <string>RenderingUnknown</string>
+ </test>
+ </testgroup>
+ <testgroup label="Encoded characters">
+ <test label="U+0020">
+ <comment>Space</comment>
+ <string>\u00F130 \u00F131 ! " # $ % &amp; ' ( ) * + , - . / 0 1 2 3 4 5 6 7 8 9 : ; &lt; = &gt; ? @ A B C</string>
+ </test>
+ <test label="U+0043" rtl="True">
+ <comment>LtnCapC</comment>
+ <string>C</string>
+ </test>
+ <test label="U+0044">
+ <comment>LtnCapD</comment>
+ <string>D E F G H I J K L M N O P Q R S T U V W X Y</string>
+ </test>
+ <test label="U+005B">
+ <comment>LftSqrBrac</comment>
+ <string>[ \ ] ^ _ ` a b c d e f g h i j k l m n o p q r s t u v w x y</string>
+ </test>
+ <test label="U+007B">
+ <comment>LftCurlyBrac</comment>
+ <string>{ | } ~</string>
+ </test>
+ <test label="U+00AD">
+ <comment>Hyphen_Soft</comment>
+ <string>\u0000AD</string>
+ </test>
+ <test label="U+00C4">
+ <comment>LtnCapADiaer</comment>
+ <string>\u0000C4</string>
+ </test>
+ <test label="U+00E0">
+ <comment>LtnSmAGrave</comment>
+ <string>\u0000E0 \u0000E1 \u0000E2 \u0000E3 \u0000E4 \u0000E5</string>
+ </test>
+ <test label="U+0300">
+ <comment>CombGrave</comment>
+ <string>\u0025CC\u000300 \u0025CC\u000301 \u0025CC\u000302 \u0025CC\u000303</string>
+ </test>
+ <test label="U+0308">
+ <comment>CombDiaer</comment>
+ <string>\u0025CC\u000308</string>
+ </test>
+ <test label="U+030A">
+ <comment>CombRingAbv</comment>
+ <string>\u0025CC\u00030A</string>
+ </test>
+ <test label="U+2010">
+ <comment>Hyphen</comment>
+ <string>\u002010 \u002011</string>
+ </test>
+ <test label="U+25CC">
+ <comment>DottedCirc</comment>
+ <string>\u0025CC</string>
+ </test>
+ </testgroup>
+</ftml>
diff --git a/tests/reference/ufo/psfgenftml.lg b/tests/reference/ufo/psfgenftml.lg
new file mode 100644
index 0000000..0f1a72c
--- /dev/null
+++ b/tests/reference/ufo/psfgenftml.lg
@@ -0,0 +1,19 @@
+2021-06-29 14:42:20 Progress: Running: psfgenftml -i tests/input/psfgenftml.csv -l local/testresults/ufo/psfgenftml.log tests/input/font-psf-test/source/PsfTest-Italic.ufo local/testresults/ufo/psfgenftml.ftml
+2021-06-29 14:42:20 Progress: Opening file for output: @cwd@/local/testresults/ufo/psfgenftml.ftml
+2021-06-29 14:42:20 Progress: Opening file for input: tests/input/psfgenftml.csv
+2021-06-29 14:42:20 Progress: Reading UFO: tests/input/font-psf-test/source/PsfTest-Italic.ufo
+2021-06-29 14:42:20 Progress: Checking fontinfo.plist metadata
+2021-06-29 14:42:20 Warning: openTypeOS2FamilyClass would be removed from fontinfo Old value: [0, 0]
+2021-06-29 14:42:20 Warning: year would be removed from fontinfo Old value: 2021
+2021-06-29 14:42:20 Warning: capHeight would be updated Old value: 1485.3, new value: 1485
+2021-06-29 14:42:20 Warning: styleMapFamilyName would be uppdated Old value: Psf test, new value: Psf Test
+2021-06-29 14:42:20 Warning: openTypeOS2TypoLineGap would be updated Old value: 1, new value: 0
+2021-06-29 14:42:20 Warning: openTypeOS2Selection would be added New value: [7]
+2021-06-29 14:42:20 Warning: openTypeNamePreferredFamilyName would be updated Old value: Psf Testing, new value: Psf Test
+2021-06-29 14:42:20 Progress: Checking lib.plist metadata
+2021-06-29 14:42:20 Warning: com.schriftgestaltung.disablesAutomaticAlignment would be deleted - obsolete key Old value: True
+2021-06-29 14:42:20 Warning: com.schriftgestaltung.disablesLastChange would be deleted - obsolete key Old value: True
+2021-06-29 14:42:20 Progress: Check & fix results:- Errors: 0, Changes to make: 9, Other warnings: 0
+2021-06-29 14:42:20 Progress: See log file for details
+2021-06-29 14:42:21 Warning: glyph_data line 39: psname A previously seen; ignored
+2021-06-29 14:42:21 Warning: glyph_data line 116: empty glyph name in glyph_data; ignored
diff --git a/tests/reference/ufo/psfglyphs2ufo.lg b/tests/reference/ufo/psfglyphs2ufo.lg
new file mode 100644
index 0000000..249bf00
--- /dev/null
+++ b/tests/reference/ufo/psfglyphs2ufo.lg
@@ -0,0 +1,13 @@
+2020-10-22 11:30:51 Progress: Running: psfglyphs2ufo --nofea tests/input/font-psf-test/source/PsfTestRoman.glyphs local/testresults/ufo/psfglyphs2ufo -l local/testresults/ufo/psfglyphs2ufo.log
+2020-10-22 11:30:51 Progress: Fixing data in PsfTest-Regular
+2020-10-22 11:30:51 Progress: Checking lib.plist
+2020-10-22 11:30:51 Progress: Checking fontinfo.plist
+2020-10-22 11:30:51 Progress: Writing out local/testresults/ufo/psfglyphs2ufo/PsfTest-Regular.ufo
+2020-10-22 11:30:51 Progress: Fixing data in PsfTest-Bold
+2020-10-22 11:30:51 Progress: Checking lib.plist
+2020-10-22 11:30:51 Progress: Checking fontinfo.plist
+2020-10-22 11:30:51 Progress: Writing out local/testresults/ufo/psfglyphs2ufo/PsfTest-Bold.ufo
+2020-10-22 11:30:51 Error: The following obsolete keys were found. They may have been in the original UFO or you may have an old version of glyphsLib installed
+ PsfTest-Regular: com.schriftgestaltung.disablesAutomaticAlignment, com.schriftgestaltung.disablesLastChange,
+ PsfTest-Bold: com.schriftgestaltung.disablesAutomaticAlignment, com.schriftgestaltung.disablesLastChange,
+
diff --git a/tests/reference/ufo/psfglyphs2ufo/PsfTest-Bold.ufo/fontinfo.plist b/tests/reference/ufo/psfglyphs2ufo/PsfTest-Bold.ufo/fontinfo.plist
new file mode 100644
index 0000000..7986300
--- /dev/null
+++ b/tests/reference/ufo/psfglyphs2ufo/PsfTest-Bold.ufo/fontinfo.plist
@@ -0,0 +1,245 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+ <key>ascender</key>
+ <integer>2100</integer>
+ <key>capHeight</key>
+ <integer>1485</integer>
+ <key>copyright</key>
+ <string>Copyright (c) 2004-2021 SIL International</string>
+ <key>descender</key>
+ <integer>-550</integer>
+ <key>familyName</key>
+ <string>Psf Test</string>
+ <key>note</key>
+ <string>Test note
+Second line
+
+Third line
+</string>
+ <key>openTypeHeadCreated</key>
+ <string>2021/10/22 11:32:25</string>
+ <key>openTypeHheaAscender</key>
+ <integer>2100</integer>
+ <key>openTypeHheaDescender</key>
+ <integer>-550</integer>
+ <key>openTypeHheaLineGap</key>
+ <integer>0</integer>
+ <key>openTypeNameDescription</key>
+ <string>Copyright (c) 2004-2021 SIL International</string>
+ <key>openTypeNameDesigner</key>
+ <string>Victor Gaultney, Annie Olsen, Julie Remington, Don Collingsworth, Eric Hays, Becca Hirsbrunner</string>
+ <key>openTypeNameDesignerURL</key>
+ <string>http://scripts.sil.org/</string>
+ <key>openTypeNameLicense</key>
+ <string>Copyright (c) 2004-2021 SIL International (http://www.sil.org/) with Reserved Font Names "Andika" and "SIL".
+
+This Font Software is licensed under the SIL Open Font License, Version 1.1. This license is copied below, and is also available with a FAQ at: http://scripts.sil.org/OFL
+
+
+-----------------------------------------------------------
+SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007
+-----------------------------------------------------------
+
+PREAMBLE
+The goals of the Open Font License (OFL) are to stimulate worldwide development of collaborative font projects, to support the font creation efforts of academic and linguistic communities, and to provide a free and open framework in which fonts may be shared and improved in partnership with others.
+
+The OFL allows the licensed fonts to be used, studied, modified and redistributed freely as long as they are not sold by themselves. The fonts, including any derivative works, can be bundled, embedded, redistributed and/or sold with any software provided that any reserved names are not used by derivative works. The fonts and derivatives, however, cannot be released under any other type of license. The requirement for fonts to remain under this license does not apply to any document created using the fonts or their derivatives.
+
+DEFINITIONS
+"Font Software" refers to the set of files released by the Copyright Holder(s) under this license and clearly marked as such. This may include source files, build scripts and documentation.
+
+"Reserved Font Name" refers to any names specified as such after the copyright statement(s).
+
+"Original Version" refers to the collection of Font Software components as distributed by the Copyright Holder(s).
+
+"Modified Version" refers to any derivative made by adding to, deleting, or substituting -- in part or in whole -- any of the components of the Original Version, by changing formats or by porting the Font Software to a new environment.
+
+"Author" refers to any designer, engineer, programmer, technical writer or other person who contributed to the Font Software.
+
+PERMISSION &amp; CONDITIONS
+Permission is hereby granted, free of charge, to any person obtaining a copy of the Font Software, to use, study, copy, merge, embed, modify, redistribute, and sell modified and unmodified copies of the Font Software, subject to the following conditions:
+
+1) Neither the Font Software nor any of its individual components, in Original or Modified Versions, may be sold by itself.
+
+2) Original or Modified Versions of the Font Software may be bundled, redistributed and/or sold with any software, provided that each copy contains the above copyright notice and this license. These can be included either as stand-alone text files, human-readable headers or in the appropriate machine-readable metadata fields within text or binary files as long as those fields can be easily viewed by the user.
+
+3) No Modified Version of the Font Software may use the Reserved Font Name(s) unless explicit written permission is granted by the corresponding Copyright Holder. This restriction only applies to the primary font name as presented to the users.
+
+4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font Software shall not be used to promote, endorse or advertise any Modified Version, except to acknowledge the contribution(s) of the Copyright Holder(s) and the Author(s) or with their explicit written permission.
+
+5) The Font Software, modified or unmodified, in part or in whole, must be distributed entirely under this license, and must not be distributed under any other license. The requirement for fonts to remain under this license does not apply to any document created using the Font Software.
+
+TERMINATION
+This license becomes null and void if any of the above conditions are not met.
+
+DISCLAIMER
+THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM OTHER DEALINGS IN THE FONT SOFTWARE.</string>
+ <key>openTypeNameLicenseURL</key>
+ <string>http://scripts.sil.org/OFL</string>
+ <key>openTypeNameManufacturer</key>
+ <string>SIL International</string>
+ <key>openTypeNameManufacturerURL</key>
+ <string>http://scripts.sil.org</string>
+ <key>openTypeNamePreferredFamilyName</key>
+ <string>Psf Test</string>
+ <key>openTypeNamePreferredSubfamilyName</key>
+ <string>Bold</string>
+ <key>openTypeNameUniqueID</key>
+ <string>SIL International: Psf Test Bold: 2022</string>
+ <key>openTypeNameVersion</key>
+ <string>Version 5.550</string>
+ <key>openTypeOS2CodePageRanges</key>
+ <array>
+ <integer>0</integer>
+ <integer>1</integer>
+ <integer>2</integer>
+ <integer>4</integer>
+ <integer>7</integer>
+ <integer>8</integer>
+ </array>
+ <key>openTypeOS2FamilyClass</key>
+ <array>
+ <integer>0</integer>
+ <integer>0</integer>
+ </array>
+ <key>openTypeOS2Panose</key>
+ <array>
+ <integer>2</integer>
+ <integer>0</integer>
+ <integer>0</integer>
+ <integer>0</integer>
+ <integer>0</integer>
+ <integer>0</integer>
+ <integer>0</integer>
+ <integer>0</integer>
+ <integer>0</integer>
+ <integer>0</integer>
+ </array>
+ <key>openTypeOS2StrikeoutPosition</key>
+ <integer>700</integer>
+ <key>openTypeOS2StrikeoutSize</key>
+ <integer>100</integer>
+ <key>openTypeOS2SubscriptXOffset</key>
+ <integer>0</integer>
+ <key>openTypeOS2SubscriptXSize</key>
+ <integer>1433</integer>
+ <key>openTypeOS2SubscriptYOffset</key>
+ <integer>286</integer>
+ <key>openTypeOS2SubscriptYSize</key>
+ <integer>1331</integer>
+ <key>openTypeOS2SuperscriptXOffset</key>
+ <integer>0</integer>
+ <key>openTypeOS2SuperscriptXSize</key>
+ <integer>1433</integer>
+ <key>openTypeOS2SuperscriptYOffset</key>
+ <integer>976</integer>
+ <key>openTypeOS2SuperscriptYSize</key>
+ <integer>1331</integer>
+ <key>openTypeOS2Type</key>
+ <array/>
+ <key>openTypeOS2TypoAscender</key>
+ <integer>2100</integer>
+ <key>openTypeOS2TypoDescender</key>
+ <integer>-550</integer>
+ <key>openTypeOS2TypoLineGap</key>
+ <integer>0</integer>
+ <key>openTypeOS2UnicodeRanges</key>
+ <array>
+ <integer>0</integer>
+ <integer>1</integer>
+ <integer>6</integer>
+ <integer>7</integer>
+ <integer>31</integer>
+ <integer>33</integer>
+ <integer>35</integer>
+ <integer>36</integer>
+ <integer>37</integer>
+ <integer>38</integer>
+ <integer>39</integer>
+ <integer>40</integer>
+ <integer>45</integer>
+ <integer>46</integer>
+ <integer>47</integer>
+ <integer>57</integer>
+ <integer>60</integer>
+ <integer>62</integer>
+ <integer>64</integer>
+ <integer>67</integer>
+ <integer>69</integer>
+ <integer>89</integer>
+ </array>
+ <key>openTypeOS2VendorID</key>
+ <string>SIL</string>
+ <key>openTypeOS2WeightClass</key>
+ <integer>700</integer>
+ <key>openTypeOS2WidthClass</key>
+ <integer>5</integer>
+ <key>openTypeOS2WinAscent</key>
+ <integer>2100</integer>
+ <key>openTypeOS2WinDescent</key>
+ <integer>550</integer>
+ <key>postscriptBlueValues</key>
+ <array>
+ <integer>-490</integer>
+ <integer>-490</integer>
+ <integer>-25</integer>
+ <integer>0</integer>
+ <integer>1020</integer>
+ <integer>1040</integer>
+ <integer>1455</integer>
+ <integer>1485</integer>
+ <integer>1600</integer>
+ <integer>1620</integer>
+ </array>
+ <key>postscriptFontName</key>
+ <string>PsfTest-Bold</string>
+ <key>postscriptFullName</key>
+ <string>Psf Test Bold</string>
+ <key>postscriptStemSnapH</key>
+ <array>
+ <integer>140</integer>
+ <integer>145</integer>
+ <integer>150</integer>
+ <integer>155</integer>
+ <integer>160</integer>
+ <integer>165</integer>
+ <integer>170</integer>
+ <integer>175</integer>
+ <integer>185</integer>
+ <integer>270</integer>
+ </array>
+ <key>postscriptStemSnapV</key>
+ <array>
+ <integer>165</integer>
+ <integer>180</integer>
+ <integer>185</integer>
+ <integer>190</integer>
+ <integer>195</integer>
+ <integer>200</integer>
+ <integer>205</integer>
+ <integer>270</integer>
+ </array>
+ <key>postscriptUnderlinePosition</key>
+ <integer>-110</integer>
+ <key>postscriptUnderlineThickness</key>
+ <integer>80</integer>
+ <key>styleMapFamilyName</key>
+ <string>Psf Test</string>
+ <key>styleMapStyleName</key>
+ <string>bold</string>
+ <key>styleName</key>
+ <string>Bold</string>
+ <key>trademark</key>
+ <string>Andika is a trademark of SIL International.</string>
+ <key>unitsPerEm</key>
+ <integer>2048</integer>
+ <key>versionMajor</key>
+ <integer>5</integer>
+ <key>versionMinor</key>
+ <integer>550</integer>
+ <key>xHeight</key>
+ <integer>1040</integer>
+</dict>
+</plist>
diff --git a/tests/reference/ufo/psfglyphs2ufo/PsfTest-Bold.ufo/glyphs/A_mpersand.glif b/tests/reference/ufo/psfglyphs2ufo/PsfTest-Bold.ufo/glyphs/A_mpersand.glif
new file mode 100644
index 0000000..f2749f2
--- /dev/null
+++ b/tests/reference/ufo/psfglyphs2ufo/PsfTest-Bold.ufo/glyphs/A_mpersand.glif
@@ -0,0 +1,61 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="Ampersand" format="2">
+ <advance width="1355"/>
+ <unicode hex="0026"/>
+ <outline>
+ <contour>
+ <point x="1060" y="600" type="line"/>
+ <point x="996" y="433"/>
+ <point x="715" y="190"/>
+ <point x="540" y="190" type="curve" smooth="yes"/>
+ <point x="425" y="190"/>
+ <point x="335" y="257"/>
+ <point x="335" y="370" type="curve" smooth="yes"/>
+ <point x="335" y="480"/>
+ <point x="411" y="547"/>
+ <point x="585" y="700" type="curve" smooth="yes"/>
+ <point x="766" y="859"/>
+ <point x="925" y="1048"/>
+ <point x="925" y="1190" type="curve" smooth="yes"/>
+ <point x="925" y="1372"/>
+ <point x="777" y="1485"/>
+ <point x="575" y="1485" type="curve" smooth="yes"/>
+ <point x="366" y="1485"/>
+ <point x="190" y="1372"/>
+ <point x="190" y="1160" type="curve" smooth="yes"/>
+ <point x="190" y="1000"/>
+ <point x="407" y="785"/>
+ <point x="590" y="540" type="curve" smooth="yes"/>
+ <point x="859" y="179"/>
+ <point x="1038" y="-25"/>
+ <point x="1090" y="-25" type="curve" smooth="yes"/>
+ <point x="1125" y="-25"/>
+ <point x="1253" y="58"/>
+ <point x="1290" y="90" type="curve"/>
+ <point x="1195" y="130"/>
+ <point x="1060" y="305"/>
+ <point x="785" y="680" type="curve" smooth="yes"/>
+ <point x="619" y="906"/>
+ <point x="420" y="1085"/>
+ <point x="420" y="1170" type="curve" smooth="yes"/>
+ <point x="420" y="1241"/>
+ <point x="483" y="1310"/>
+ <point x="560" y="1310" type="curve" smooth="yes"/>
+ <point x="640" y="1310"/>
+ <point x="695" y="1254"/>
+ <point x="695" y="1175" type="curve" smooth="yes"/>
+ <point x="695" y="1106"/>
+ <point x="628" y="1001"/>
+ <point x="455" y="840" type="curve" smooth="yes"/>
+ <point x="251" y="651"/>
+ <point x="90" y="527"/>
+ <point x="90" y="344" type="curve" smooth="yes"/>
+ <point x="90" y="121"/>
+ <point x="242" y="-25"/>
+ <point x="525" y="-25" type="curve" smooth="yes"/>
+ <point x="808" y="-25"/>
+ <point x="1117" y="264"/>
+ <point x="1195" y="425" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfglyphs2ufo/PsfTest-Bold.ufo/glyphs/A_pos.glif b/tests/reference/ufo/psfglyphs2ufo/PsfTest-Bold.ufo/glyphs/A_pos.glif
new file mode 100644
index 0000000..61494e8
--- /dev/null
+++ b/tests/reference/ufo/psfglyphs2ufo/PsfTest-Bold.ufo/glyphs/A_pos.glif
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="Apos" format="2">
+ <advance width="625"/>
+ <unicode hex="0027"/>
+ <outline>
+ <contour>
+ <point x="400" y="1045" type="line"/>
+ <point x="405" y="1186"/>
+ <point x="406" y="1339"/>
+ <point x="435" y="1585" type="curve"/>
+ <point x="190" y="1585" type="line"/>
+ <point x="221" y="1339"/>
+ <point x="221" y="1186"/>
+ <point x="225" y="1045" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfglyphs2ufo/PsfTest-Bold.ufo/glyphs/A_sterisk.glif b/tests/reference/ufo/psfglyphs2ufo/PsfTest-Bold.ufo/glyphs/A_sterisk.glif
new file mode 100644
index 0000000..ed9d25e
--- /dev/null
+++ b/tests/reference/ufo/psfglyphs2ufo/PsfTest-Bold.ufo/glyphs/A_sterisk.glif
@@ -0,0 +1,51 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="Asterisk" format="2">
+ <advance width="1040"/>
+ <unicode hex="002A"/>
+ <outline>
+ <contour>
+ <point x="827" y="1493" type="line"/>
+ <point x="747" y="1426"/>
+ <point x="679" y="1367"/>
+ <point x="594" y="1308" type="curve"/>
+ <point x="599" y="1405"/>
+ <point x="609" y="1486"/>
+ <point x="624" y="1600" type="curve"/>
+ <point x="425" y="1600" type="line"/>
+ <point x="444" y="1497"/>
+ <point x="460" y="1412"/>
+ <point x="468" y="1308" type="curve"/>
+ <point x="383" y="1360"/>
+ <point x="312" y="1408"/>
+ <point x="228" y="1476" type="curve"/>
+ <point x="126" y="1306" type="line"/>
+ <point x="231" y="1271"/>
+ <point x="331" y="1234"/>
+ <point x="412" y="1196" type="curve"/>
+ <point x="328" y="1153"/>
+ <point x="243" y="1120"/>
+ <point x="136" y="1077" type="curve"/>
+ <point x="237" y="897" type="line"/>
+ <point x="316" y="968"/>
+ <point x="382" y="1026"/>
+ <point x="466" y="1087" type="curve"/>
+ <point x="459" y="983"/>
+ <point x="449" y="896"/>
+ <point x="431" y="793" type="curve"/>
+ <point x="632" y="793" type="line"/>
+ <point x="610" y="906"/>
+ <point x="602" y="987"/>
+ <point x="593" y="1084" type="curve"/>
+ <point x="682" y="1027"/>
+ <point x="747" y="981"/>
+ <point x="830" y="914" type="curve"/>
+ <point x="936" y="1089" type="line"/>
+ <point x="827" y="1127"/>
+ <point x="743" y="1155"/>
+ <point x="651" y="1196" type="curve"/>
+ <point x="738" y="1241"/>
+ <point x="820" y="1277"/>
+ <point x="924" y="1321" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfglyphs2ufo/PsfTest-Bold.ufo/glyphs/A_tS_gn.glif b/tests/reference/ufo/psfglyphs2ufo/PsfTest-Bold.ufo/glyphs/A_tS_gn.glif
new file mode 100644
index 0000000..47fee96
--- /dev/null
+++ b/tests/reference/ufo/psfglyphs2ufo/PsfTest-Bold.ufo/glyphs/A_tS_gn.glif
@@ -0,0 +1,80 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="AtSgn" format="2">
+ <advance width="1742"/>
+ <unicode hex="0040"/>
+ <outline>
+ <contour>
+ <point x="1140" y="10" type="line"/>
+ <point x="1077" y="-34"/>
+ <point x="988" y="-60"/>
+ <point x="895" y="-60" type="curve" smooth="yes"/>
+ <point x="558" y="-60"/>
+ <point x="290" y="204"/>
+ <point x="290" y="605" type="curve" smooth="yes"/>
+ <point x="290" y="973"/>
+ <point x="557" y="1240"/>
+ <point x="895" y="1240" type="curve" smooth="yes"/>
+ <point x="1278" y="1240"/>
+ <point x="1460" y="992"/>
+ <point x="1460" y="670" type="curve" smooth="yes"/>
+ <point x="1460" y="452"/>
+ <point x="1363" y="335"/>
+ <point x="1305" y="335" type="curve" smooth="yes"/>
+ <point x="1256" y="335"/>
+ <point x="1220" y="430"/>
+ <point x="1220" y="650" type="curve" smooth="yes"/>
+ <point x="1220" y="980" type="line"/>
+ <point x="1133" y="1015"/>
+ <point x="986" y="1040"/>
+ <point x="905" y="1040" type="curve" smooth="yes"/>
+ <point x="741" y="1040"/>
+ <point x="618" y="961"/>
+ <point x="535" y="825" type="curve" smooth="yes"/>
+ <point x="488" y="746"/>
+ <point x="460" y="653"/>
+ <point x="460" y="530" type="curve" smooth="yes"/>
+ <point x="460" y="304"/>
+ <point x="606" y="163"/>
+ <point x="740" y="163" type="curve" smooth="yes"/>
+ <point x="867" y="163"/>
+ <point x="1013" y="331"/>
+ <point x="1065" y="455" type="curve"/>
+ <point x="1075" y="287"/>
+ <point x="1153" y="160"/>
+ <point x="1275" y="160" type="curve" smooth="yes"/>
+ <point x="1450" y="160"/>
+ <point x="1650" y="358"/>
+ <point x="1650" y="700" type="curve" smooth="yes"/>
+ <point x="1650" y="1137"/>
+ <point x="1342" y="1425"/>
+ <point x="905" y="1425" type="curve" smooth="yes"/>
+ <point x="480" y="1425"/>
+ <point x="90" y="1136"/>
+ <point x="90" y="575" type="curve" smooth="yes"/>
+ <point x="90" y="38"/>
+ <point x="479" y="-245"/>
+ <point x="880" y="-245" type="curve" smooth="yes"/>
+ <point x="1015" y="-245"/>
+ <point x="1175" y="-198"/>
+ <point x="1275" y="-128" type="curve"/>
+ </contour>
+ <contour>
+ <point x="1020" y="710" type="line"/>
+ <point x="988" y="572"/>
+ <point x="863" y="350"/>
+ <point x="773" y="350" type="curve" smooth="yes"/>
+ <point x="701" y="350"/>
+ <point x="660" y="428"/>
+ <point x="660" y="575" type="curve" smooth="yes"/>
+ <point x="660" y="652"/>
+ <point x="682" y="737"/>
+ <point x="720" y="786" type="curve" smooth="yes"/>
+ <point x="756" y="831"/>
+ <point x="807" y="855"/>
+ <point x="875" y="855" type="curve" smooth="yes"/>
+ <point x="949" y="855"/>
+ <point x="987" y="836"/>
+ <point x="1020" y="820" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfglyphs2ufo/PsfTest-Bold.ufo/glyphs/C_ircumA_ccent.glif b/tests/reference/ufo/psfglyphs2ufo/PsfTest-Bold.ufo/glyphs/C_ircumA_ccent.glif
new file mode 100644
index 0000000..7258b7d
--- /dev/null
+++ b/tests/reference/ufo/psfglyphs2ufo/PsfTest-Bold.ufo/glyphs/C_ircumA_ccent.glif
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="CircumAccent" format="2">
+ <advance width="880"/>
+ <unicode hex="005E"/>
+ <anchor x="440" y="1635" name="U"/>
+ <outline>
+ <contour>
+ <point x="888" y="1200" type="line"/>
+ <point x="598" y="1600" type="line"/>
+ <point x="298" y="1600" type="line"/>
+ <point x="8" y="1200" type="line"/>
+ <point x="248" y="1200" type="line"/>
+ <point x="448" y="1430" type="line"/>
+ <point x="648" y="1200" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfglyphs2ufo/PsfTest-Bold.ufo/glyphs/C_olon.glif b/tests/reference/ufo/psfglyphs2ufo/PsfTest-Bold.ufo/glyphs/C_olon.glif
new file mode 100644
index 0000000..ae4801a
--- /dev/null
+++ b/tests/reference/ufo/psfglyphs2ufo/PsfTest-Bold.ufo/glyphs/C_olon.glif
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="Colon" format="2">
+ <advance width="710"/>
+ <unicode hex="003A"/>
+ <outline>
+ <contour>
+ <point x="200" y="150" type="curve" smooth="yes"/>
+ <point x="200" y="46"/>
+ <point x="274" y="-25"/>
+ <point x="375" y="-25" type="curve" smooth="yes"/>
+ <point x="477" y="-25"/>
+ <point x="550" y="46"/>
+ <point x="550" y="150" type="curve" smooth="yes"/>
+ <point x="550" y="252"/>
+ <point x="477" y="325"/>
+ <point x="375" y="325" type="curve" smooth="yes"/>
+ <point x="274" y="325"/>
+ <point x="200" y="252"/>
+ </contour>
+ <contour>
+ <point x="200" y="750" type="curve" smooth="yes"/>
+ <point x="200" y="646"/>
+ <point x="274" y="575"/>
+ <point x="375" y="575" type="curve" smooth="yes"/>
+ <point x="477" y="575"/>
+ <point x="550" y="646"/>
+ <point x="550" y="750" type="curve" smooth="yes"/>
+ <point x="550" y="852"/>
+ <point x="477" y="925"/>
+ <point x="375" y="925" type="curve" smooth="yes"/>
+ <point x="274" y="925"/>
+ <point x="200" y="852"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfglyphs2ufo/PsfTest-Bold.ufo/glyphs/C_ombA_cute.glif b/tests/reference/ufo/psfglyphs2ufo/PsfTest-Bold.ufo/glyphs/C_ombA_cute.glif
new file mode 100644
index 0000000..5574223
--- /dev/null
+++ b/tests/reference/ufo/psfglyphs2ufo/PsfTest-Bold.ufo/glyphs/C_ombA_cute.glif
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="CombAcute" format="2">
+ <unicode hex="0301"/>
+ <anchor x="-600" y="1635" name="U"/>
+ <anchor x="-540" y="1100" name="_U"/>
+ <outline>
+ <contour>
+ <point x="-470" y="1600" type="line"/>
+ <point x="-760" y="1200" type="line"/>
+ <point x="-520" y="1200" type="line"/>
+ <point x="-120" y="1600" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfglyphs2ufo/PsfTest-Bold.ufo/glyphs/C_ombC_ircum.glif b/tests/reference/ufo/psfglyphs2ufo/PsfTest-Bold.ufo/glyphs/C_ombC_ircum.glif
new file mode 100644
index 0000000..ca30491
--- /dev/null
+++ b/tests/reference/ufo/psfglyphs2ufo/PsfTest-Bold.ufo/glyphs/C_ombC_ircum.glif
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="CombCircum" format="2">
+ <unicode hex="0302"/>
+ <anchor x="-588" y="1635" name="U"/>
+ <anchor x="-580" y="1100" name="_U"/>
+ <outline>
+ <contour>
+ <point x="-140" y="1200" type="line"/>
+ <point x="-430" y="1600" type="line"/>
+ <point x="-730" y="1600" type="line"/>
+ <point x="-1020" y="1200" type="line"/>
+ <point x="-780" y="1200" type="line"/>
+ <point x="-580" y="1430" type="line"/>
+ <point x="-380" y="1200" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfglyphs2ufo/PsfTest-Bold.ufo/glyphs/C_ombD_iaer.glif b/tests/reference/ufo/psfglyphs2ufo/PsfTest-Bold.ufo/glyphs/C_ombD_iaer.glif
new file mode 100644
index 0000000..5a15368
--- /dev/null
+++ b/tests/reference/ufo/psfglyphs2ufo/PsfTest-Bold.ufo/glyphs/C_ombD_iaer.glif
@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="CombDiaer" format="2">
+ <unicode hex="0308"/>
+ <anchor x="-580" y="1585" name="U"/>
+ <anchor x="-580" y="1100" name="_U"/>
+ <outline>
+ <contour>
+ <point x="-510" y="1385" type="curve" smooth="yes"/>
+ <point x="-510" y="1281"/>
+ <point x="-436" y="1210"/>
+ <point x="-335" y="1210" type="curve" smooth="yes"/>
+ <point x="-233" y="1210"/>
+ <point x="-160" y="1281"/>
+ <point x="-160" y="1385" type="curve" smooth="yes"/>
+ <point x="-160" y="1487"/>
+ <point x="-233" y="1560"/>
+ <point x="-335" y="1560" type="curve" smooth="yes"/>
+ <point x="-436" y="1560"/>
+ <point x="-510" y="1487"/>
+ </contour>
+ <contour>
+ <point x="-1000" y="1385" type="curve" smooth="yes"/>
+ <point x="-1000" y="1281"/>
+ <point x="-926" y="1210"/>
+ <point x="-825" y="1210" type="curve" smooth="yes"/>
+ <point x="-723" y="1210"/>
+ <point x="-650" y="1281"/>
+ <point x="-650" y="1385" type="curve" smooth="yes"/>
+ <point x="-650" y="1487"/>
+ <point x="-723" y="1560"/>
+ <point x="-825" y="1560" type="curve" smooth="yes"/>
+ <point x="-926" y="1560"/>
+ <point x="-1000" y="1487"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfglyphs2ufo/PsfTest-Bold.ufo/glyphs/C_ombG_rave.glif b/tests/reference/ufo/psfglyphs2ufo/PsfTest-Bold.ufo/glyphs/C_ombG_rave.glif
new file mode 100644
index 0000000..33bed8f
--- /dev/null
+++ b/tests/reference/ufo/psfglyphs2ufo/PsfTest-Bold.ufo/glyphs/C_ombG_rave.glif
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="CombGrave" format="2">
+ <unicode hex="0300"/>
+ <anchor x="-590" y="1635" name="U"/>
+ <anchor x="-630" y="1100" name="_U"/>
+ <outline>
+ <contour>
+ <point x="-1050" y="1600" type="line"/>
+ <point x="-650" y="1200" type="line"/>
+ <point x="-410" y="1200" type="line"/>
+ <point x="-700" y="1600" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfglyphs2ufo/PsfTest-Bold.ufo/glyphs/C_ombR_ingA_bv.glif b/tests/reference/ufo/psfglyphs2ufo/PsfTest-Bold.ufo/glyphs/C_ombR_ingA_bv.glif
new file mode 100644
index 0000000..7e03146
--- /dev/null
+++ b/tests/reference/ufo/psfglyphs2ufo/PsfTest-Bold.ufo/glyphs/C_ombR_ingA_bv.glif
@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="CombRingAbv" format="2">
+ <unicode hex="030A"/>
+ <anchor x="-570" y="1635" name="U"/>
+ <anchor x="-572" y="1100" name="_U"/>
+ <outline>
+ <contour>
+ <point x="-475" y="1400" type="curve" smooth="yes"/>
+ <point x="-475" y="1345"/>
+ <point x="-515" y="1305"/>
+ <point x="-570" y="1305" type="curve" smooth="yes"/>
+ <point x="-625" y="1305"/>
+ <point x="-665" y="1345"/>
+ <point x="-665" y="1400" type="curve" smooth="yes"/>
+ <point x="-665" y="1455"/>
+ <point x="-625" y="1495"/>
+ <point x="-570" y="1495" type="curve" smooth="yes"/>
+ <point x="-515" y="1495"/>
+ <point x="-475" y="1455"/>
+ </contour>
+ <contour>
+ <point x="-815" y="1400" type="curve" smooth="yes"/>
+ <point x="-815" y="1260"/>
+ <point x="-710" y="1160"/>
+ <point x="-570" y="1160" type="curve" smooth="yes"/>
+ <point x="-430" y="1160"/>
+ <point x="-325" y="1260"/>
+ <point x="-325" y="1400" type="curve" smooth="yes"/>
+ <point x="-325" y="1540"/>
+ <point x="-430" y="1640"/>
+ <point x="-570" y="1640" type="curve" smooth="yes"/>
+ <point x="-710" y="1640"/>
+ <point x="-815" y="1540"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfglyphs2ufo/PsfTest-Bold.ufo/glyphs/C_ombT_ilde.glif b/tests/reference/ufo/psfglyphs2ufo/PsfTest-Bold.ufo/glyphs/C_ombT_ilde.glif
new file mode 100644
index 0000000..ee23af5
--- /dev/null
+++ b/tests/reference/ufo/psfglyphs2ufo/PsfTest-Bold.ufo/glyphs/C_ombT_ilde.glif
@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="CombTilde" format="2">
+ <unicode hex="0303"/>
+ <anchor x="-580" y="1490" name="U"/>
+ <anchor x="-580" y="1100" name="_U"/>
+ <outline>
+ <contour>
+ <point x="-830" y="1190" type="line"/>
+ <point x="-824" y="1232"/>
+ <point x="-803" y="1280"/>
+ <point x="-753" y="1280" type="curve" smooth="yes"/>
+ <point x="-710" y="1280"/>
+ <point x="-653" y="1264"/>
+ <point x="-570" y="1229" type="curve" smooth="yes"/>
+ <point x="-500" y="1199"/>
+ <point x="-448" y="1180"/>
+ <point x="-386" y="1180" type="curve" smooth="yes"/>
+ <point x="-250" y="1180"/>
+ <point x="-155" y="1307"/>
+ <point x="-155" y="1480" type="curve"/>
+ <point x="-310" y="1480" type="line"/>
+ <point x="-318" y="1438"/>
+ <point x="-340" y="1390"/>
+ <point x="-387" y="1390" type="curve" smooth="yes"/>
+ <point x="-435" y="1390"/>
+ <point x="-472" y="1408"/>
+ <point x="-550" y="1437" type="curve" smooth="yes"/>
+ <point x="-629" y="1466"/>
+ <point x="-695" y="1490"/>
+ <point x="-760" y="1490" type="curve" smooth="yes"/>
+ <point x="-892" y="1490"/>
+ <point x="-985" y="1349"/>
+ <point x="-985" y="1190" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfglyphs2ufo/PsfTest-Bold.ufo/glyphs/C_omma.glif b/tests/reference/ufo/psfglyphs2ufo/PsfTest-Bold.ufo/glyphs/C_omma.glif
new file mode 100644
index 0000000..9d4845e
--- /dev/null
+++ b/tests/reference/ufo/psfglyphs2ufo/PsfTest-Bold.ufo/glyphs/C_omma.glif
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="Comma" format="2">
+ <advance width="665"/>
+ <unicode hex="002C"/>
+ <outline>
+ <contour>
+ <point x="185" y="50" type="line"/>
+ <point x="345" y="50" type="line"/>
+ <point x="345" y="-34"/>
+ <point x="290" y="-153"/>
+ <point x="185" y="-265" type="curve"/>
+ <point x="330" y="-335" type="line"/>
+ <point x="454" y="-228"/>
+ <point x="560" y="-49"/>
+ <point x="560" y="130" type="curve" smooth="yes"/>
+ <point x="560" y="254"/>
+ <point x="489" y="340"/>
+ <point x="375" y="340" type="curve" smooth="yes"/>
+ <point x="262" y="340"/>
+ <point x="185" y="255"/>
+ <point x="185" y="180" type="curve" smooth="yes"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfglyphs2ufo/PsfTest-Bold.ufo/glyphs/D_igitE_ight.glif b/tests/reference/ufo/psfglyphs2ufo/PsfTest-Bold.ufo/glyphs/D_igitE_ight.glif
new file mode 100644
index 0000000..a59fff4
--- /dev/null
+++ b/tests/reference/ufo/psfglyphs2ufo/PsfTest-Bold.ufo/glyphs/D_igitE_ight.glif
@@ -0,0 +1,63 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="DigitEight" format="2">
+ <advance width="1200"/>
+ <unicode hex="0038"/>
+ <anchor x="600" y="-100" name="L"/>
+ <anchor x="600" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="600" y="-25" type="curve" smooth="yes"/>
+ <point x="877" y="-25"/>
+ <point x="1130" y="144"/>
+ <point x="1130" y="415" type="curve" smooth="yes"/>
+ <point x="1130" y="641"/>
+ <point x="985" y="739"/>
+ <point x="875" y="795" type="curve"/>
+ <point x="953" y="841"/>
+ <point x="1060" y="923"/>
+ <point x="1060" y="1105" type="curve" smooth="yes"/>
+ <point x="1060" y="1350"/>
+ <point x="860" y="1485"/>
+ <point x="610" y="1485" type="curve" smooth="yes"/>
+ <point x="361" y="1485"/>
+ <point x="140" y="1350"/>
+ <point x="140" y="1105" type="curve" smooth="yes"/>
+ <point x="140" y="923"/>
+ <point x="252" y="838"/>
+ <point x="330" y="795" type="curve"/>
+ <point x="201" y="725"/>
+ <point x="70" y="631"/>
+ <point x="70" y="405" type="curve" smooth="yes"/>
+ <point x="70" y="134"/>
+ <point x="324" y="-25"/>
+ </contour>
+ <contour>
+ <point x="810" y="1100" type="curve" smooth="yes"/>
+ <point x="810" y="974"/>
+ <point x="733" y="895"/>
+ <point x="600" y="895" type="curve" smooth="yes"/>
+ <point x="467" y="895"/>
+ <point x="390" y="974"/>
+ <point x="390" y="1100" type="curve" smooth="yes"/>
+ <point x="390" y="1217"/>
+ <point x="477" y="1290"/>
+ <point x="600" y="1290" type="curve" smooth="yes"/>
+ <point x="743" y="1290"/>
+ <point x="810" y="1207"/>
+ </contour>
+ <contour>
+ <point x="865" y="435" type="curve" smooth="yes"/>
+ <point x="865" y="300"/>
+ <point x="768" y="185"/>
+ <point x="600" y="185" type="curve" smooth="yes"/>
+ <point x="440" y="185"/>
+ <point x="335" y="300"/>
+ <point x="335" y="435" type="curve" smooth="yes"/>
+ <point x="335" y="582"/>
+ <point x="450" y="680"/>
+ <point x="600" y="680" type="curve" smooth="yes"/>
+ <point x="748" y="680"/>
+ <point x="865" y="582"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfglyphs2ufo/PsfTest-Bold.ufo/glyphs/D_igitF_ive.glif b/tests/reference/ufo/psfglyphs2ufo/PsfTest-Bold.ufo/glyphs/D_igitF_ive.glif
new file mode 100644
index 0000000..102780d
--- /dev/null
+++ b/tests/reference/ufo/psfglyphs2ufo/PsfTest-Bold.ufo/glyphs/D_igitF_ive.glif
@@ -0,0 +1,44 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="DigitFive" format="2">
+ <advance width="1200"/>
+ <unicode hex="0035"/>
+ <anchor x="600" y="-100" name="L"/>
+ <anchor x="600" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="175" y="645" type="line"/>
+ <point x="299" y="693"/>
+ <point x="404" y="710"/>
+ <point x="510" y="710" type="curve" smooth="yes"/>
+ <point x="670" y="710"/>
+ <point x="810" y="632"/>
+ <point x="810" y="470" type="curve" smooth="yes"/>
+ <point x="810" y="318"/>
+ <point x="690" y="215"/>
+ <point x="530" y="215" type="curve" smooth="yes"/>
+ <point x="390" y="215"/>
+ <point x="274" y="252"/>
+ <point x="140" y="360" type="curve"/>
+ <point x="100" y="80" type="line"/>
+ <point x="225" y="2"/>
+ <point x="365" y="-25"/>
+ <point x="520" y="-25" type="curve" smooth="yes"/>
+ <point x="833" y="-25"/>
+ <point x="1090" y="163"/>
+ <point x="1090" y="475" type="curve" smooth="yes"/>
+ <point x="1090" y="752"/>
+ <point x="882" y="930"/>
+ <point x="605" y="930" type="curve" smooth="yes"/>
+ <point x="543" y="930"/>
+ <point x="468" y="911"/>
+ <point x="435" y="895" type="curve"/>
+ <point x="435" y="1215" type="line"/>
+ <point x="765" y="1215" type="line" smooth="yes"/>
+ <point x="849" y="1215"/>
+ <point x="955" y="1211"/>
+ <point x="1030" y="1195" type="curve"/>
+ <point x="1030" y="1460" type="line"/>
+ <point x="175" y="1460" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfglyphs2ufo/PsfTest-Bold.ufo/glyphs/D_igitF_our.glif b/tests/reference/ufo/psfglyphs2ufo/PsfTest-Bold.ufo/glyphs/D_igitF_our.glif
new file mode 100644
index 0000000..7d2cbe6
--- /dev/null
+++ b/tests/reference/ufo/psfglyphs2ufo/PsfTest-Bold.ufo/glyphs/D_igitF_our.glif
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="DigitFour" format="2">
+ <advance width="1200"/>
+ <unicode hex="0034"/>
+ <anchor x="607" y="-100" name="L"/>
+ <anchor x="607" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="1155" y="345" type="line"/>
+ <point x="1155" y="570" type="line"/>
+ <point x="995" y="570" type="line"/>
+ <point x="995" y="1460" type="line"/>
+ <point x="695" y="1460" type="line"/>
+ <point x="60" y="570" type="line"/>
+ <point x="60" y="345" type="line"/>
+ <point x="730" y="345" type="line"/>
+ <point x="730" y="0" type="line"/>
+ <point x="995" y="0" type="line"/>
+ <point x="995" y="345" type="line"/>
+ </contour>
+ <contour>
+ <point x="730" y="1145" type="line"/>
+ <point x="730" y="570" type="line"/>
+ <point x="305" y="570" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfglyphs2ufo/PsfTest-Bold.ufo/glyphs/D_igitN_ine.glif b/tests/reference/ufo/psfglyphs2ufo/PsfTest-Bold.ufo/glyphs/D_igitN_ine.glif
new file mode 100644
index 0000000..b1e153b
--- /dev/null
+++ b/tests/reference/ufo/psfglyphs2ufo/PsfTest-Bold.ufo/glyphs/D_igitN_ine.glif
@@ -0,0 +1,49 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="DigitNine" format="2">
+ <advance width="1200"/>
+ <unicode hex="0039"/>
+ <anchor x="600" y="-100" name="L"/>
+ <anchor x="600" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="154" y="65" type="line"/>
+ <point x="248" y="5"/>
+ <point x="364" y="-25"/>
+ <point x="492" y="-25" type="curve" smooth="yes"/>
+ <point x="967" y="-25"/>
+ <point x="1135" y="411"/>
+ <point x="1135" y="780" type="curve" smooth="yes"/>
+ <point x="1135" y="1150"/>
+ <point x="977" y="1485"/>
+ <point x="589" y="1485" type="curve" smooth="yes"/>
+ <point x="310" y="1485"/>
+ <point x="70" y="1300"/>
+ <point x="70" y="1002" type="curve" smooth="yes"/>
+ <point x="70" y="763"/>
+ <point x="272" y="576"/>
+ <point x="550" y="576" type="curve" smooth="yes"/>
+ <point x="741" y="576"/>
+ <point x="913" y="707"/>
+ <point x="1010" y="868" type="curve"/>
+ <point x="939" y="991" type="line"/>
+ <point x="865" y="877"/>
+ <point x="729" y="790"/>
+ <point x="574" y="790" type="curve" smooth="yes"/>
+ <point x="425" y="790"/>
+ <point x="326" y="890"/>
+ <point x="326" y="1036" type="curve" smooth="yes"/>
+ <point x="326" y="1153"/>
+ <point x="425" y="1250"/>
+ <point x="573" y="1250" type="curve" smooth="yes"/>
+ <point x="773" y="1250"/>
+ <point x="870" y="1102"/>
+ <point x="870" y="813" type="curve" smooth="yes"/>
+ <point x="870" y="326"/>
+ <point x="699" y="210"/>
+ <point x="502" y="210" type="curve" smooth="yes"/>
+ <point x="406" y="210"/>
+ <point x="294" y="234"/>
+ <point x="208" y="320" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfglyphs2ufo/PsfTest-Bold.ufo/glyphs/D_igitO_ne.glif b/tests/reference/ufo/psfglyphs2ufo/PsfTest-Bold.ufo/glyphs/D_igitO_ne.glif
new file mode 100644
index 0000000..c744b9f
--- /dev/null
+++ b/tests/reference/ufo/psfglyphs2ufo/PsfTest-Bold.ufo/glyphs/D_igitO_ne.glif
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="DigitOne" format="2">
+ <advance width="1200"/>
+ <unicode hex="0031"/>
+ <anchor x="600" y="-100" name="L"/>
+ <anchor x="600" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="1075" y="0" type="line"/>
+ <point x="1075" y="235" type="line"/>
+ <point x="767" y="235" type="line"/>
+ <point x="767" y="1460" type="line"/>
+ <point x="492" y="1460" type="line"/>
+ <point x="177" y="1278" type="line"/>
+ <point x="212" y="1018" type="line"/>
+ <point x="492" y="1170" type="line"/>
+ <point x="492" y="235" type="line"/>
+ <point x="185" y="235" type="line"/>
+ <point x="185" y="0" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfglyphs2ufo/PsfTest-Bold.ufo/glyphs/D_igitS_even.glif b/tests/reference/ufo/psfglyphs2ufo/PsfTest-Bold.ufo/glyphs/D_igitS_even.glif
new file mode 100644
index 0000000..63fb1c4
--- /dev/null
+++ b/tests/reference/ufo/psfglyphs2ufo/PsfTest-Bold.ufo/glyphs/D_igitS_even.glif
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="DigitSeven" format="2">
+ <advance width="1200"/>
+ <unicode hex="0037"/>
+ <anchor x="600" y="-100" name="L"/>
+ <anchor x="600" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="520" y="0" type="line"/>
+ <point x="649" y="459"/>
+ <point x="834" y="855"/>
+ <point x="1130" y="1260" type="curve"/>
+ <point x="1130" y="1460" type="line"/>
+ <point x="100" y="1460" type="line"/>
+ <point x="100" y="1195" type="line"/>
+ <point x="176" y="1211"/>
+ <point x="292" y="1215"/>
+ <point x="480" y="1215" type="curve" smooth="yes"/>
+ <point x="800" y="1215" type="line"/>
+ <point x="542" y="842"/>
+ <point x="409" y="566"/>
+ <point x="235" y="0" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfglyphs2ufo/PsfTest-Bold.ufo/glyphs/D_igitS_ix.glif b/tests/reference/ufo/psfglyphs2ufo/PsfTest-Bold.ufo/glyphs/D_igitS_ix.glif
new file mode 100644
index 0000000..7526cc6
--- /dev/null
+++ b/tests/reference/ufo/psfglyphs2ufo/PsfTest-Bold.ufo/glyphs/D_igitS_ix.glif
@@ -0,0 +1,49 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="DigitSix" format="2">
+ <advance width="1200"/>
+ <unicode hex="0036"/>
+ <anchor x="610" y="-100" name="L"/>
+ <anchor x="610" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="1073" y="1395" type="line"/>
+ <point x="969" y="1465"/>
+ <point x="873" y="1485"/>
+ <point x="735" y="1485" type="curve" smooth="yes"/>
+ <point x="260" y="1485"/>
+ <point x="90" y="1069"/>
+ <point x="90" y="680" type="curve" smooth="yes"/>
+ <point x="90" y="223"/>
+ <point x="297" y="-25"/>
+ <point x="652" y="-25" type="curve" smooth="yes"/>
+ <point x="955" y="-25"/>
+ <point x="1155" y="179"/>
+ <point x="1155" y="470" type="curve" smooth="yes"/>
+ <point x="1155" y="729"/>
+ <point x="963" y="925"/>
+ <point x="675" y="925" type="curve" smooth="yes"/>
+ <point x="484" y="925"/>
+ <point x="338" y="810"/>
+ <point x="225" y="655" type="curve"/>
+ <point x="290" y="540" type="line"/>
+ <point x="372" y="643"/>
+ <point x="500" y="710"/>
+ <point x="655" y="710" type="curve" smooth="yes"/>
+ <point x="814" y="710"/>
+ <point x="900" y="601"/>
+ <point x="900" y="455" type="curve" smooth="yes"/>
+ <point x="900" y="329"/>
+ <point x="803" y="210"/>
+ <point x="656" y="210" type="curve" smooth="yes"/>
+ <point x="474" y="210"/>
+ <point x="355" y="386"/>
+ <point x="355" y="645" type="curve" smooth="yes"/>
+ <point x="355" y="1132"/>
+ <point x="528" y="1250"/>
+ <point x="725" y="1250" type="curve" smooth="yes"/>
+ <point x="821" y="1250"/>
+ <point x="923" y="1226"/>
+ <point x="1009" y="1140" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfglyphs2ufo/PsfTest-Bold.ufo/glyphs/D_igitT_hree.glif b/tests/reference/ufo/psfglyphs2ufo/PsfTest-Bold.ufo/glyphs/D_igitT_hree.glif
new file mode 100644
index 0000000..883bd62
--- /dev/null
+++ b/tests/reference/ufo/psfglyphs2ufo/PsfTest-Bold.ufo/glyphs/D_igitT_hree.glif
@@ -0,0 +1,52 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="DigitThree" format="2">
+ <advance width="1200"/>
+ <unicode hex="0033"/>
+ <anchor x="600" y="-100" name="L"/>
+ <anchor x="600" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="390" y="885" type="line"/>
+ <point x="390" y="645" type="line"/>
+ <point x="480" y="645" type="line" smooth="yes"/>
+ <point x="706" y="645"/>
+ <point x="835" y="548"/>
+ <point x="835" y="425" type="curve" smooth="yes"/>
+ <point x="835" y="291"/>
+ <point x="708" y="210"/>
+ <point x="565" y="210" type="curve" smooth="yes"/>
+ <point x="405" y="210"/>
+ <point x="244" y="282"/>
+ <point x="135" y="405" type="curve"/>
+ <point x="100" y="130" type="line"/>
+ <point x="205" y="32"/>
+ <point x="368" y="-25"/>
+ <point x="545" y="-25" type="curve" smooth="yes"/>
+ <point x="874" y="-25"/>
+ <point x="1120" y="170"/>
+ <point x="1120" y="405" type="curve" smooth="yes"/>
+ <point x="1120" y="672"/>
+ <point x="892" y="756"/>
+ <point x="750" y="780" type="curve"/>
+ <point x="892" y="809"/>
+ <point x="1070" y="957"/>
+ <point x="1070" y="1140" type="curve" smooth="yes"/>
+ <point x="1070" y="1354"/>
+ <point x="868" y="1485"/>
+ <point x="580" y="1485" type="curve" smooth="yes"/>
+ <point x="413" y="1485"/>
+ <point x="240" y="1416"/>
+ <point x="160" y="1325" type="curve"/>
+ <point x="195" y="1095" type="line"/>
+ <point x="308" y="1211"/>
+ <point x="436" y="1250"/>
+ <point x="590" y="1250" type="curve" smooth="yes"/>
+ <point x="689" y="1250"/>
+ <point x="791" y="1193"/>
+ <point x="791" y="1102" type="curve" smooth="yes"/>
+ <point x="791" y="994"/>
+ <point x="662" y="885"/>
+ <point x="480" y="885" type="curve" smooth="yes"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfglyphs2ufo/PsfTest-Bold.ufo/glyphs/D_igitT_wo.glif b/tests/reference/ufo/psfglyphs2ufo/PsfTest-Bold.ufo/glyphs/D_igitT_wo.glif
new file mode 100644
index 0000000..1d73732
--- /dev/null
+++ b/tests/reference/ufo/psfglyphs2ufo/PsfTest-Bold.ufo/glyphs/D_igitT_wo.glif
@@ -0,0 +1,37 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="DigitTwo" format="2">
+ <advance width="1200"/>
+ <unicode hex="0032"/>
+ <anchor x="600" y="-100" name="L"/>
+ <anchor x="560" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="1090" y="260" type="line"/>
+ <point x="1010" y="246"/>
+ <point x="942" y="245"/>
+ <point x="745" y="245" type="curve" smooth="yes"/>
+ <point x="480" y="245" type="line"/>
+ <point x="699" y="422"/>
+ <point x="1046" y="739"/>
+ <point x="1046" y="1065" type="curve" smooth="yes"/>
+ <point x="1046" y="1323"/>
+ <point x="850" y="1485"/>
+ <point x="560" y="1485" type="curve" smooth="yes"/>
+ <point x="391" y="1485"/>
+ <point x="196" y="1402"/>
+ <point x="105" y="1290" type="curve"/>
+ <point x="170" y="1050" type="line"/>
+ <point x="259" y="1158"/>
+ <point x="412" y="1235"/>
+ <point x="535" y="1235" type="curve" smooth="yes"/>
+ <point x="688" y="1235"/>
+ <point x="758" y="1133"/>
+ <point x="758" y="1015" type="curve" smooth="yes"/>
+ <point x="758" y="758"/>
+ <point x="381" y="415"/>
+ <point x="110" y="220" type="curve"/>
+ <point x="110" y="0" type="line"/>
+ <point x="1090" y="0" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfglyphs2ufo/PsfTest-Bold.ufo/glyphs/D_igitZ_ero.glif b/tests/reference/ufo/psfglyphs2ufo/PsfTest-Bold.ufo/glyphs/D_igitZ_ero.glif
new file mode 100644
index 0000000..01f4532
--- /dev/null
+++ b/tests/reference/ufo/psfglyphs2ufo/PsfTest-Bold.ufo/glyphs/D_igitZ_ero.glif
@@ -0,0 +1,37 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="DigitZero" format="2">
+ <advance width="1200"/>
+ <unicode hex="0030"/>
+ <anchor x="605" y="-100" name="L"/>
+ <anchor x="605" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="850" y="715" type="curve" smooth="yes"/>
+ <point x="850" y="368"/>
+ <point x="762" y="205"/>
+ <point x="600" y="205" type="curve" smooth="yes"/>
+ <point x="432" y="205"/>
+ <point x="350" y="375"/>
+ <point x="350" y="745" type="curve" smooth="yes"/>
+ <point x="350" y="1093"/>
+ <point x="437" y="1255"/>
+ <point x="600" y="1255" type="curve" smooth="yes"/>
+ <point x="772" y="1255"/>
+ <point x="850" y="1086"/>
+ </contour>
+ <contour>
+ <point x="1135" y="740" type="curve" smooth="yes"/>
+ <point x="1135" y="1286"/>
+ <point x="950" y="1485"/>
+ <point x="610" y="1485" type="curve" smooth="yes"/>
+ <point x="291" y="1485"/>
+ <point x="65" y="1283"/>
+ <point x="65" y="720" type="curve" smooth="yes"/>
+ <point x="65" y="165"/>
+ <point x="271" y="-25"/>
+ <point x="590" y="-25" type="curve" smooth="yes"/>
+ <point x="911" y="-25"/>
+ <point x="1135" y="161"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfglyphs2ufo/PsfTest-Bold.ufo/glyphs/D_ollarS_gn.glif b/tests/reference/ufo/psfglyphs2ufo/PsfTest-Bold.ufo/glyphs/D_ollarS_gn.glif
new file mode 100644
index 0000000..f8b49cd
--- /dev/null
+++ b/tests/reference/ufo/psfglyphs2ufo/PsfTest-Bold.ufo/glyphs/D_ollarS_gn.glif
@@ -0,0 +1,57 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="DollarSgn" format="2">
+ <advance width="1200"/>
+ <unicode hex="0024"/>
+ <outline>
+ <contour>
+ <point x="1006" y="1316" type="line"/>
+ <point x="886" y="1374"/>
+ <point x="764" y="1389"/>
+ <point x="623" y="1389" type="curve" smooth="yes"/>
+ <point x="317" y="1389"/>
+ <point x="150" y="1203"/>
+ <point x="150" y="1017" type="curve" smooth="yes"/>
+ <point x="150" y="830"/>
+ <point x="275" y="730"/>
+ <point x="540" y="623" type="curve" smooth="yes"/>
+ <point x="802" y="517"/>
+ <point x="851" y="472"/>
+ <point x="851" y="386" type="curve" smooth="yes"/>
+ <point x="851" y="267"/>
+ <point x="744" y="211"/>
+ <point x="586" y="211" type="curve" smooth="yes"/>
+ <point x="440" y="211"/>
+ <point x="297" y="281"/>
+ <point x="195" y="383" type="curve"/>
+ <point x="123" y="124" type="line"/>
+ <point x="216" y="49"/>
+ <point x="388" y="0"/>
+ <point x="586" y="0" type="curve" smooth="yes"/>
+ <point x="847" y="0"/>
+ <point x="1086" y="147"/>
+ <point x="1086" y="414" type="curve" smooth="yes"/>
+ <point x="1086" y="633"/>
+ <point x="927" y="723"/>
+ <point x="679" y="826" type="curve" smooth="yes"/>
+ <point x="431" y="929"/>
+ <point x="385" y="969"/>
+ <point x="385" y="1040" type="curve" smooth="yes"/>
+ <point x="385" y="1132"/>
+ <point x="466" y="1188"/>
+ <point x="613" y="1188" type="curve" smooth="yes"/>
+ <point x="741" y="1188"/>
+ <point x="876" y="1154"/>
+ <point x="949" y="1077" type="curve"/>
+ </contour>
+ <contour>
+ <point x="548" y="1600" type="line"/>
+ <point x="548" y="788" type="line"/>
+ <point x="518" y="726" type="line"/>
+ <point x="518" y="-220" type="line"/>
+ <point x="688" y="-220" type="line"/>
+ <point x="688" y="668" type="line"/>
+ <point x="718" y="734" type="line"/>
+ <point x="718" y="1600" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfglyphs2ufo/PsfTest-Bold.ufo/glyphs/D_ottedC_irc.glif b/tests/reference/ufo/psfglyphs2ufo/PsfTest-Bold.ufo/glyphs/D_ottedC_irc.glif
new file mode 100644
index 0000000..4cf5cb4
--- /dev/null
+++ b/tests/reference/ufo/psfglyphs2ufo/PsfTest-Bold.ufo/glyphs/D_ottedC_irc.glif
@@ -0,0 +1,235 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="DottedCirc" format="2">
+ <advance width="1106"/>
+ <unicode hex="25CC"/>
+ <anchor x="553" y="0" name="H"/>
+ <anchor x="553" y="-100" name="L"/>
+ <anchor x="810" y="0" name="O"/>
+ <anchor x="553" y="1000" name="U"/>
+ <outline>
+ <contour>
+ <point x="443" y="837" type="curve" smooth="yes"/>
+ <point x="443" y="864"/>
+ <point x="423" y="885"/>
+ <point x="398" y="885" type="curve" smooth="yes"/>
+ <point x="371" y="885"/>
+ <point x="348" y="861"/>
+ <point x="348" y="837" type="curve" smooth="yes"/>
+ <point x="348" y="809"/>
+ <point x="372" y="789"/>
+ <point x="398" y="789" type="curve" smooth="yes"/>
+ <point x="425" y="789"/>
+ <point x="443" y="812"/>
+ </contour>
+ <contour>
+ <point x="758" y="79" type="curve" smooth="yes"/>
+ <point x="758" y="106"/>
+ <point x="736" y="127"/>
+ <point x="710" y="127" type="curve" smooth="yes"/>
+ <point x="685" y="127"/>
+ <point x="662" y="103"/>
+ <point x="662" y="80" type="curve" smooth="yes"/>
+ <point x="662" y="52"/>
+ <point x="686" y="31"/>
+ <point x="710" y="31" type="curve" smooth="yes"/>
+ <point x="737" y="31"/>
+ <point x="758" y="55"/>
+ </contour>
+ <contour>
+ <point x="310" y="749" type="curve" smooth="yes"/>
+ <point x="310" y="775"/>
+ <point x="288" y="796"/>
+ <point x="263" y="796" type="curve" smooth="yes"/>
+ <point x="238" y="796"/>
+ <point x="215" y="774"/>
+ <point x="215" y="747" type="curve" smooth="yes"/>
+ <point x="215" y="722"/>
+ <point x="236" y="701"/>
+ <point x="263" y="701" type="curve" smooth="yes"/>
+ <point x="291" y="701"/>
+ <point x="310" y="720"/>
+ </contour>
+ <contour>
+ <point x="891" y="168" type="curve" smooth="yes"/>
+ <point x="891" y="197"/>
+ <point x="870" y="215"/>
+ <point x="843" y="215" type="curve" smooth="yes"/>
+ <point x="817" y="215"/>
+ <point x="795" y="194"/>
+ <point x="795" y="168" type="curve" smooth="yes"/>
+ <point x="795" y="143"/>
+ <point x="816" y="121"/>
+ <point x="843" y="121" type="curve" smooth="yes"/>
+ <point x="871" y="121"/>
+ <point x="891" y="143"/>
+ </contour>
+ <contour>
+ <point x="222" y="613" type="curve" smooth="yes"/>
+ <point x="222" y="640"/>
+ <point x="199" y="663"/>
+ <point x="173" y="663" type="curve" smooth="yes"/>
+ <point x="149" y="663"/>
+ <point x="126" y="642"/>
+ <point x="126" y="615" type="curve" smooth="yes"/>
+ <point x="126" y="591"/>
+ <point x="145" y="567"/>
+ <point x="173" y="567" type="curve" smooth="yes"/>
+ <point x="197" y="567"/>
+ <point x="222" y="587"/>
+ </contour>
+ <contour>
+ <point x="980" y="301" type="curve" smooth="yes"/>
+ <point x="980" y="327"/>
+ <point x="957" y="348"/>
+ <point x="932" y="348" type="curve" smooth="yes"/>
+ <point x="908" y="348"/>
+ <point x="884" y="332"/>
+ <point x="884" y="301" type="curve" smooth="yes"/>
+ <point x="884" y="277"/>
+ <point x="902" y="254"/>
+ <point x="932" y="254" type="curve" smooth="yes"/>
+ <point x="957" y="254"/>
+ <point x="980" y="274"/>
+ </contour>
+ <contour>
+ <point x="191" y="459" type="curve" smooth="yes"/>
+ <point x="191" y="484"/>
+ <point x="168" y="505"/>
+ <point x="143" y="505" type="curve" smooth="yes"/>
+ <point x="116" y="505"/>
+ <point x="95" y="484"/>
+ <point x="95" y="458" type="curve" smooth="yes"/>
+ <point x="95" y="433"/>
+ <point x="115" y="410"/>
+ <point x="143" y="410" type="curve" smooth="yes"/>
+ <point x="167" y="410"/>
+ <point x="191" y="432"/>
+ </contour>
+ <contour>
+ <point x="1011" y="458" type="curve" smooth="yes"/>
+ <point x="1011" y="484"/>
+ <point x="990" y="506"/>
+ <point x="964" y="506" type="curve" smooth="yes"/>
+ <point x="940" y="506"/>
+ <point x="915" y="484"/>
+ <point x="915" y="457" type="curve" smooth="yes"/>
+ <point x="915" y="433"/>
+ <point x="936" y="411"/>
+ <point x="964" y="411" type="curve" smooth="yes"/>
+ <point x="990" y="411"/>
+ <point x="1011" y="433"/>
+ </contour>
+ <contour>
+ <point x="222" y="302" type="curve" smooth="yes"/>
+ <point x="222" y="328"/>
+ <point x="200" y="348"/>
+ <point x="174" y="348" type="curve" smooth="yes"/>
+ <point x="147" y="348"/>
+ <point x="126" y="326"/>
+ <point x="126" y="302" type="curve" smooth="yes"/>
+ <point x="126" y="275"/>
+ <point x="149" y="253"/>
+ <point x="174" y="253" type="curve" smooth="yes"/>
+ <point x="201" y="253"/>
+ <point x="222" y="277"/>
+ </contour>
+ <contour>
+ <point x="980" y="615" type="curve" smooth="yes"/>
+ <point x="980" y="642"/>
+ <point x="955" y="663"/>
+ <point x="931" y="663" type="curve" smooth="yes"/>
+ <point x="904" y="663"/>
+ <point x="885" y="638"/>
+ <point x="885" y="614" type="curve" smooth="yes"/>
+ <point x="885" y="588"/>
+ <point x="907" y="567"/>
+ <point x="931" y="567" type="curve" smooth="yes"/>
+ <point x="959" y="567"/>
+ <point x="980" y="591"/>
+ </contour>
+ <contour>
+ <point x="310" y="168" type="curve" smooth="yes"/>
+ <point x="310" y="195"/>
+ <point x="291" y="215"/>
+ <point x="263" y="215" type="curve" smooth="yes"/>
+ <point x="238" y="215"/>
+ <point x="215" y="190"/>
+ <point x="215" y="168" type="curve" smooth="yes"/>
+ <point x="215" y="143"/>
+ <point x="238" y="120"/>
+ <point x="263" y="120" type="curve" smooth="yes"/>
+ <point x="289" y="120"/>
+ <point x="310" y="143"/>
+ </contour>
+ <contour>
+ <point x="890" y="748" type="curve" smooth="yes"/>
+ <point x="890" y="774"/>
+ <point x="870" y="796"/>
+ <point x="843" y="796" type="curve" smooth="yes"/>
+ <point x="815" y="796"/>
+ <point x="796" y="773"/>
+ <point x="796" y="748" type="curve" smooth="yes"/>
+ <point x="796" y="724"/>
+ <point x="817" y="700"/>
+ <point x="843" y="700" type="curve" smooth="yes"/>
+ <point x="869" y="700"/>
+ <point x="890" y="722"/>
+ </contour>
+ <contour>
+ <point x="444" y="78" type="curve" smooth="yes"/>
+ <point x="444" y="102"/>
+ <point x="423" y="126"/>
+ <point x="396" y="126" type="curve" smooth="yes"/>
+ <point x="370" y="126"/>
+ <point x="348" y="102"/>
+ <point x="348" y="78" type="curve" smooth="yes"/>
+ <point x="348" y="55"/>
+ <point x="370" y="31"/>
+ <point x="396" y="31" type="curve" smooth="yes"/>
+ <point x="420" y="31"/>
+ <point x="444" y="51"/>
+ </contour>
+ <contour>
+ <point x="758" y="836" type="curve" smooth="yes"/>
+ <point x="758" y="861"/>
+ <point x="737" y="885"/>
+ <point x="710" y="885" type="curve" smooth="yes"/>
+ <point x="684" y="885"/>
+ <point x="663" y="862"/>
+ <point x="663" y="838" type="curve" smooth="yes"/>
+ <point x="663" y="814"/>
+ <point x="683" y="789"/>
+ <point x="710" y="789" type="curve" smooth="yes"/>
+ <point x="734" y="789"/>
+ <point x="758" y="809"/>
+ </contour>
+ <contour>
+ <point x="601" y="47" type="curve" smooth="yes"/>
+ <point x="601" y="73"/>
+ <point x="579" y="95"/>
+ <point x="553" y="95" type="curve" smooth="yes"/>
+ <point x="527" y="95"/>
+ <point x="506" y="73"/>
+ <point x="506" y="47" type="curve" smooth="yes"/>
+ <point x="506" y="21"/>
+ <point x="527" y="0"/>
+ <point x="553" y="0" type="curve" smooth="yes"/>
+ <point x="579" y="0"/>
+ <point x="601" y="21"/>
+ </contour>
+ <contour>
+ <point x="601" y="868" type="curve" smooth="yes"/>
+ <point x="601" y="894"/>
+ <point x="579" y="916"/>
+ <point x="553" y="916" type="curve" smooth="yes"/>
+ <point x="527" y="916"/>
+ <point x="506" y="894"/>
+ <point x="506" y="868" type="curve" smooth="yes"/>
+ <point x="506" y="842"/>
+ <point x="527" y="821"/>
+ <point x="553" y="821" type="curve" smooth="yes"/>
+ <point x="579" y="821"/>
+ <point x="601" y="842"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfglyphs2ufo/PsfTest-Bold.ufo/glyphs/E_qS_gn.glif b/tests/reference/ufo/psfglyphs2ufo/PsfTest-Bold.ufo/glyphs/E_qS_gn.glif
new file mode 100644
index 0000000..9eeb2ef
--- /dev/null
+++ b/tests/reference/ufo/psfglyphs2ufo/PsfTest-Bold.ufo/glyphs/E_qS_gn.glif
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="EqSgn" format="2">
+ <advance width="1200"/>
+ <unicode hex="003D"/>
+ <outline>
+ <contour>
+ <point x="120" y="440" type="line"/>
+ <point x="1080" y="440" type="line"/>
+ <point x="1080" y="650" type="line"/>
+ <point x="120" y="650" type="line"/>
+ </contour>
+ <contour>
+ <point x="120" y="810" type="line"/>
+ <point x="1080" y="810" type="line"/>
+ <point x="1080" y="1020" type="line"/>
+ <point x="120" y="1020" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfglyphs2ufo/PsfTest-Bold.ufo/glyphs/E_xclamationM_rk.glif b/tests/reference/ufo/psfglyphs2ufo/PsfTest-Bold.ufo/glyphs/E_xclamationM_rk.glif
new file mode 100644
index 0000000..cfdf1a6
--- /dev/null
+++ b/tests/reference/ufo/psfglyphs2ufo/PsfTest-Bold.ufo/glyphs/E_xclamationM_rk.glif
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="ExclamationMrk" format="2">
+ <advance width="780"/>
+ <unicode hex="0021"/>
+ <outline>
+ <contour>
+ <point x="530" y="500" type="line"/>
+ <point x="536" y="790"/>
+ <point x="531" y="1076"/>
+ <point x="570" y="1510" type="curve"/>
+ <point x="235" y="1510" type="line"/>
+ <point x="273" y="1076"/>
+ <point x="268" y="790"/>
+ <point x="275" y="500" type="curve"/>
+ </contour>
+ <contour>
+ <point x="230" y="150" type="curve" smooth="yes"/>
+ <point x="230" y="46"/>
+ <point x="304" y="-25"/>
+ <point x="405" y="-25" type="curve" smooth="yes"/>
+ <point x="507" y="-25"/>
+ <point x="580" y="46"/>
+ <point x="580" y="150" type="curve" smooth="yes"/>
+ <point x="580" y="252"/>
+ <point x="507" y="325"/>
+ <point x="405" y="325" type="curve" smooth="yes"/>
+ <point x="304" y="325"/>
+ <point x="230" y="252"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfglyphs2ufo/PsfTest-Bold.ufo/glyphs/F_ullS_top.glif b/tests/reference/ufo/psfglyphs2ufo/PsfTest-Bold.ufo/glyphs/F_ullS_top.glif
new file mode 100644
index 0000000..b05d598
--- /dev/null
+++ b/tests/reference/ufo/psfglyphs2ufo/PsfTest-Bold.ufo/glyphs/F_ullS_top.glif
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="FullStop" format="2">
+ <advance width="710"/>
+ <unicode hex="002E"/>
+ <outline>
+ <contour>
+ <point x="200" y="150" type="curve" smooth="yes"/>
+ <point x="200" y="46"/>
+ <point x="274" y="-25"/>
+ <point x="375" y="-25" type="curve" smooth="yes"/>
+ <point x="477" y="-25"/>
+ <point x="550" y="46"/>
+ <point x="550" y="150" type="curve" smooth="yes"/>
+ <point x="550" y="252"/>
+ <point x="477" y="325"/>
+ <point x="375" y="325" type="curve" smooth="yes"/>
+ <point x="274" y="325"/>
+ <point x="200" y="252"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfglyphs2ufo/PsfTest-Bold.ufo/glyphs/G_T_S_gn.glif b/tests/reference/ufo/psfglyphs2ufo/PsfTest-Bold.ufo/glyphs/G_T_S_gn.glif
new file mode 100644
index 0000000..650e4d2
--- /dev/null
+++ b/tests/reference/ufo/psfglyphs2ufo/PsfTest-Bold.ufo/glyphs/G_T_S_gn.glif
@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="GTSgn" format="2">
+ <advance width="1200"/>
+ <unicode hex="003E"/>
+ <outline>
+ <contour>
+ <point x="130" y="245" type="line"/>
+ <point x="1090" y="635" type="line"/>
+ <point x="1090" y="825" type="line"/>
+ <point x="130" y="1215" type="line"/>
+ <point x="130" y="985" type="line"/>
+ <point x="810" y="730" type="line"/>
+ <point x="130" y="475" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfglyphs2ufo/PsfTest-Bold.ufo/glyphs/G_raveA_ccent.glif b/tests/reference/ufo/psfglyphs2ufo/PsfTest-Bold.ufo/glyphs/G_raveA_ccent.glif
new file mode 100644
index 0000000..83a5f21
--- /dev/null
+++ b/tests/reference/ufo/psfglyphs2ufo/PsfTest-Bold.ufo/glyphs/G_raveA_ccent.glif
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="GraveAccent" format="2">
+ <advance width="640"/>
+ <unicode hex="0060"/>
+ <anchor x="500" y="1635" name="U"/>
+ <outline>
+ <contour>
+ <point x="0" y="1600" type="line"/>
+ <point x="400" y="1200" type="line"/>
+ <point x="640" y="1200" type="line"/>
+ <point x="350" y="1600" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfglyphs2ufo/PsfTest-Bold.ufo/glyphs/H_yphen.glif b/tests/reference/ufo/psfglyphs2ufo/PsfTest-Bold.ufo/glyphs/H_yphen.glif
new file mode 100644
index 0000000..d79c70a
--- /dev/null
+++ b/tests/reference/ufo/psfglyphs2ufo/PsfTest-Bold.ufo/glyphs/H_yphen.glif
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="Hyphen" format="2">
+ <advance width="880"/>
+ <unicode hex="2010"/>
+ <anchor x="440" y="1100" name="U"/>
+ <outline>
+ <contour>
+ <point x="70" y="525" type="line"/>
+ <point x="810" y="525" type="line"/>
+ <point x="810" y="735" type="line"/>
+ <point x="70" y="735" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfglyphs2ufo/PsfTest-Bold.ufo/glyphs/H_yphenM_inus.glif b/tests/reference/ufo/psfglyphs2ufo/PsfTest-Bold.ufo/glyphs/H_yphenM_inus.glif
new file mode 100644
index 0000000..b88bdd4
--- /dev/null
+++ b/tests/reference/ufo/psfglyphs2ufo/PsfTest-Bold.ufo/glyphs/H_yphenM_inus.glif
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="HyphenMinus" format="2">
+ <advance width="895"/>
+ <unicode hex="002D"/>
+ <anchor x="450" y="1100" name="U"/>
+ <outline>
+ <contour>
+ <point x="80" y="525" type="line"/>
+ <point x="815" y="525" type="line"/>
+ <point x="815" y="735" type="line"/>
+ <point x="80" y="735" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfglyphs2ufo/PsfTest-Bold.ufo/glyphs/H_yphen_S_oft.glif b/tests/reference/ufo/psfglyphs2ufo/PsfTest-Bold.ufo/glyphs/H_yphen_S_oft.glif
new file mode 100644
index 0000000..916f8cf
--- /dev/null
+++ b/tests/reference/ufo/psfglyphs2ufo/PsfTest-Bold.ufo/glyphs/H_yphen_S_oft.glif
@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="Hyphen_Soft" format="2">
+ <advance width="895"/>
+ <unicode hex="00AD"/>
+ <anchor x="450" y="1100" name="U"/>
+ <outline>
+ <component base="HyphenMinus"/>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfglyphs2ufo/PsfTest-Bold.ufo/glyphs/L_T_S_gn.glif b/tests/reference/ufo/psfglyphs2ufo/PsfTest-Bold.ufo/glyphs/L_T_S_gn.glif
new file mode 100644
index 0000000..ab92cf3
--- /dev/null
+++ b/tests/reference/ufo/psfglyphs2ufo/PsfTest-Bold.ufo/glyphs/L_T_S_gn.glif
@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LTSgn" format="2">
+ <advance width="1200"/>
+ <unicode hex="003C"/>
+ <outline>
+ <contour>
+ <point x="1070" y="475" type="line"/>
+ <point x="390" y="730" type="line"/>
+ <point x="1070" y="985" type="line"/>
+ <point x="1070" y="1215" type="line"/>
+ <point x="110" y="825" type="line"/>
+ <point x="110" y="635" type="line"/>
+ <point x="1070" y="245" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfglyphs2ufo/PsfTest-Bold.ufo/glyphs/L_ftC_urlyB_rac.glif b/tests/reference/ufo/psfglyphs2ufo/PsfTest-Bold.ufo/glyphs/L_ftC_urlyB_rac.glif
new file mode 100644
index 0000000..2370b56
--- /dev/null
+++ b/tests/reference/ufo/psfglyphs2ufo/PsfTest-Bold.ufo/glyphs/L_ftC_urlyB_rac.glif
@@ -0,0 +1,47 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LftCurlyBrac" format="2">
+ <advance width="1040"/>
+ <unicode hex="007B"/>
+ <outline>
+ <contour>
+ <point x="895" y="-179" type="line"/>
+ <point x="828" y="-160"/>
+ <point x="704" y="-122"/>
+ <point x="685" y="-100" type="curve" smooth="yes"/>
+ <point x="650" y="-60"/>
+ <point x="663" y="411"/>
+ <point x="645" y="445" type="curve" smooth="yes"/>
+ <point x="621" y="491"/>
+ <point x="483" y="580"/>
+ <point x="483" y="615" type="curve" smooth="yes"/>
+ <point x="483" y="650"/>
+ <point x="620" y="740"/>
+ <point x="643" y="785" type="curve" smooth="yes"/>
+ <point x="661" y="820"/>
+ <point x="650" y="1289"/>
+ <point x="685" y="1330" type="curve" smooth="yes"/>
+ <point x="702" y="1351"/>
+ <point x="807" y="1390"/>
+ <point x="870" y="1409" type="curve"/>
+ <point x="820" y="1640" type="line"/>
+ <point x="692" y="1613"/>
+ <point x="502" y="1562"/>
+ <point x="455" y="1515" type="curve" smooth="yes"/>
+ <point x="381" y="1442"/>
+ <point x="392" y="852"/>
+ <point x="370" y="820" type="curve" smooth="yes"/>
+ <point x="340" y="777"/>
+ <point x="170" y="670"/>
+ <point x="170" y="615" type="curve" smooth="yes"/>
+ <point x="170" y="560"/>
+ <point x="340" y="453"/>
+ <point x="370" y="410" type="curve" smooth="yes"/>
+ <point x="392" y="378"/>
+ <point x="380" y="-213"/>
+ <point x="455" y="-285" type="curve" smooth="yes"/>
+ <point x="505" y="-333"/>
+ <point x="709" y="-383"/>
+ <point x="845" y="-410" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfglyphs2ufo/PsfTest-Bold.ufo/glyphs/L_ftP_aren.glif b/tests/reference/ufo/psfglyphs2ufo/PsfTest-Bold.ufo/glyphs/L_ftP_aren.glif
new file mode 100644
index 0000000..99e1982
--- /dev/null
+++ b/tests/reference/ufo/psfglyphs2ufo/PsfTest-Bold.ufo/glyphs/L_ftP_aren.glif
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LftParen" format="2">
+ <advance width="860"/>
+ <unicode hex="0028"/>
+ <outline>
+ <contour>
+ <point x="555" y="1640" type="line"/>
+ <point x="290" y="1444"/>
+ <point x="115" y="1062"/>
+ <point x="115" y="625" type="curve" smooth="yes"/>
+ <point x="115" y="218"/>
+ <point x="260" y="-125"/>
+ <point x="535" y="-410" type="curve"/>
+ <point x="686" y="-240" type="line"/>
+ <point x="462" y="11"/>
+ <point x="376" y="335"/>
+ <point x="376" y="635" type="curve" smooth="yes"/>
+ <point x="376" y="938"/>
+ <point x="466" y="1261"/>
+ <point x="676" y="1455" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfglyphs2ufo/PsfTest-Bold.ufo/glyphs/L_ftS_qrB_rac.glif b/tests/reference/ufo/psfglyphs2ufo/PsfTest-Bold.ufo/glyphs/L_ftS_qrB_rac.glif
new file mode 100644
index 0000000..dcf019b
--- /dev/null
+++ b/tests/reference/ufo/psfglyphs2ufo/PsfTest-Bold.ufo/glyphs/L_ftS_qrB_rac.glif
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LftSqrBrac" format="2">
+ <advance width="850"/>
+ <unicode hex="005B"/>
+ <outline>
+ <contour>
+ <point x="710" y="-410" type="line"/>
+ <point x="710" y="-200" type="line"/>
+ <point x="470" y="-200" type="line"/>
+ <point x="470" y="1390" type="line"/>
+ <point x="710" y="1390" type="line"/>
+ <point x="710" y="1600" type="line"/>
+ <point x="190" y="1600" type="line"/>
+ <point x="190" y="-410" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfglyphs2ufo/PsfTest-Bold.ufo/glyphs/L_owL_ine.glif b/tests/reference/ufo/psfglyphs2ufo/PsfTest-Bold.ufo/glyphs/L_owL_ine.glif
new file mode 100644
index 0000000..225c4ce
--- /dev/null
+++ b/tests/reference/ufo/psfglyphs2ufo/PsfTest-Bold.ufo/glyphs/L_owL_ine.glif
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LowLine" format="2">
+ <advance width="1274"/>
+ <unicode hex="005F"/>
+ <outline>
+ <contour>
+ <point x="0" y="-350" type="line"/>
+ <point x="1274" y="-350" type="line"/>
+ <point x="1274" y="-140" type="line"/>
+ <point x="0" y="-140" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfglyphs2ufo/PsfTest-Bold.ufo/glyphs/L_tnC_apA_.alt.glif b/tests/reference/ufo/psfglyphs2ufo/PsfTest-Bold.ufo/glyphs/L_tnC_apA_.alt.glif
new file mode 100644
index 0000000..cf1b900
--- /dev/null
+++ b/tests/reference/ufo/psfglyphs2ufo/PsfTest-Bold.ufo/glyphs/L_tnC_apA_.alt.glif
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnCapA.alt" format="2">
+ <advance width="1485"/>
+ <anchor x="1275" y="0" name="H"/>
+ <anchor x="732" y="-100" name="L"/>
+ <anchor x="1495" y="0" name="O"/>
+ <anchor x="732" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="1115" y="0" type="line"/>
+ <point x="1408" y="0" type="line"/>
+ <point x="1373" y="80"/>
+ <point x="1341" y="168"/>
+ <point x="1278" y="355" type="curve" smooth="yes"/>
+ <point x="908" y="1460" type="line"/>
+ <point x="552" y="1460" type="line"/>
+ <point x="182" y="355" type="line" smooth="yes"/>
+ <point x="119" y="166"/>
+ <point x="88" y="81"/>
+ <point x="52" y="0" type="curve"/>
+ <point x="350" y="0" type="line"/>
+ <point x="460" y="355" type="line"/>
+ <point x="1004" y="355" type="line"/>
+ </contour>
+ <contour>
+ <point x="730" y="1228" type="line"/>
+ <point x="936" y="570" type="line"/>
+ <point x="526" y="570" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfglyphs2ufo/PsfTest-Bold.ufo/glyphs/L_tnC_apA_.glif b/tests/reference/ufo/psfglyphs2ufo/PsfTest-Bold.ufo/glyphs/L_tnC_apA_.glif
new file mode 100644
index 0000000..9fa1f45
--- /dev/null
+++ b/tests/reference/ufo/psfglyphs2ufo/PsfTest-Bold.ufo/glyphs/L_tnC_apA_.glif
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnCapA" format="2">
+ <advance width="1485"/>
+ <unicode hex="0041"/>
+ <anchor x="1275" y="0" name="H"/>
+ <anchor x="732" y="-100" name="L"/>
+ <anchor x="1495" y="0" name="O"/>
+ <anchor x="732" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="1115" y="0" type="line"/>
+ <point x="1408" y="0" type="line"/>
+ <point x="1373" y="80"/>
+ <point x="1341" y="168"/>
+ <point x="1278" y="355" type="curve" smooth="yes"/>
+ <point x="908" y="1460" type="line"/>
+ <point x="552" y="1460" type="line"/>
+ <point x="182" y="355" type="line" smooth="yes"/>
+ <point x="119" y="166"/>
+ <point x="88" y="81"/>
+ <point x="52" y="0" type="curve"/>
+ <point x="350" y="0" type="line"/>
+ <point x="460" y="355" type="line"/>
+ <point x="1004" y="355" type="line"/>
+ </contour>
+ <contour>
+ <point x="730" y="1228" type="line"/>
+ <point x="936" y="570" type="line"/>
+ <point x="526" y="570" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfglyphs2ufo/PsfTest-Bold.ufo/glyphs/L_tnC_apA_D_iaer.glif b/tests/reference/ufo/psfglyphs2ufo/PsfTest-Bold.ufo/glyphs/L_tnC_apA_D_iaer.glif
new file mode 100644
index 0000000..79101d0
--- /dev/null
+++ b/tests/reference/ufo/psfglyphs2ufo/PsfTest-Bold.ufo/glyphs/L_tnC_apA_D_iaer.glif
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnCapADiaer" format="2">
+ <advance width="1485"/>
+ <unicode hex="00C4"/>
+ <anchor x="1275" y="0" name="H"/>
+ <anchor x="732" y="-100" name="L"/>
+ <anchor x="1495" y="0" name="O"/>
+ <anchor x="732" y="2015" name="U"/>
+ <outline>
+ <component base="LtnCapA"/>
+ <component base="CombDiaer" xOffset="1312" yOffset="430"/>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfglyphs2ufo/PsfTest-Bold.ufo/glyphs/L_tnC_apB_.glif b/tests/reference/ufo/psfglyphs2ufo/PsfTest-Bold.ufo/glyphs/L_tnC_apB_.glif
new file mode 100644
index 0000000..df49e47
--- /dev/null
+++ b/tests/reference/ufo/psfglyphs2ufo/PsfTest-Bold.ufo/glyphs/L_tnC_apB_.glif
@@ -0,0 +1,62 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnCapB" format="2">
+ <advance width="1385"/>
+ <unicode hex="0042"/>
+ <anchor x="670" y="-100" name="L"/>
+ <anchor x="670" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="450" y="1248" type="line"/>
+ <point x="487" y="1250"/>
+ <point x="562" y="1253"/>
+ <point x="631" y="1253" type="curve" smooth="yes"/>
+ <point x="818" y="1253"/>
+ <point x="897" y="1196"/>
+ <point x="897" y="1077" type="curve" smooth="yes"/>
+ <point x="897" y="951"/>
+ <point x="794" y="875"/>
+ <point x="605" y="875" type="curve" smooth="yes"/>
+ <point x="450" y="875" type="line"/>
+ </contour>
+ <contour>
+ <point x="1245" y="430" type="curve" smooth="yes"/>
+ <point x="1245" y="672"/>
+ <point x="1084" y="760"/>
+ <point x="935" y="800" type="curve"/>
+ <point x="1065" y="850"/>
+ <point x="1170" y="947"/>
+ <point x="1170" y="1110" type="curve" smooth="yes"/>
+ <point x="1170" y="1378"/>
+ <point x="937" y="1470"/>
+ <point x="615" y="1470" type="curve" smooth="yes"/>
+ <point x="422" y="1470"/>
+ <point x="248" y="1466"/>
+ <point x="150" y="1460" type="curve"/>
+ <point x="165" y="1380"/>
+ <point x="165" y="1196"/>
+ <point x="165" y="1000" type="curve" smooth="yes"/>
+ <point x="165" y="455" type="line" smooth="yes"/>
+ <point x="165" y="257"/>
+ <point x="165" y="80"/>
+ <point x="150" y="0" type="curve"/>
+ <point x="150" y="0"/>
+ <point x="401" y="-10"/>
+ <point x="631" y="-10" type="curve" smooth="yes"/>
+ <point x="1055" y="-10"/>
+ <point x="1245" y="181"/>
+ </contour>
+ <contour>
+ <point x="450" y="658" type="line"/>
+ <point x="643" y="658" type="line" smooth="yes"/>
+ <point x="853" y="658"/>
+ <point x="972" y="587"/>
+ <point x="972" y="450" type="curve" smooth="yes"/>
+ <point x="972" y="269"/>
+ <point x="826" y="215"/>
+ <point x="652" y="215" type="curve" smooth="yes"/>
+ <point x="552" y="215"/>
+ <point x="483" y="218"/>
+ <point x="450" y="220" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfglyphs2ufo/PsfTest-Bold.ufo/glyphs/L_tnC_apC_.glif b/tests/reference/ufo/psfglyphs2ufo/PsfTest-Bold.ufo/glyphs/L_tnC_apC_.glif
new file mode 100644
index 0000000..78c5238
--- /dev/null
+++ b/tests/reference/ufo/psfglyphs2ufo/PsfTest-Bold.ufo/glyphs/L_tnC_apC_.glif
@@ -0,0 +1,38 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnCapC" format="2">
+ <advance width="1385"/>
+ <unicode hex="0043"/>
+ <anchor x="745" y="0" name="H"/>
+ <anchor x="745" y="-100" name="L"/>
+ <anchor x="745" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="1215" y="405" type="line"/>
+ <point x="1105" y="293"/>
+ <point x="940" y="220"/>
+ <point x="790" y="220" type="curve" smooth="yes"/>
+ <point x="531" y="220"/>
+ <point x="375" y="413"/>
+ <point x="375" y="735" type="curve" smooth="yes"/>
+ <point x="375" y="1074"/>
+ <point x="557" y="1245"/>
+ <point x="800" y="1245" type="curve" smooth="yes"/>
+ <point x="931" y="1245"/>
+ <point x="1053" y="1205"/>
+ <point x="1180" y="1105" type="curve"/>
+ <point x="1250" y="1345" type="line"/>
+ <point x="1106" y="1449"/>
+ <point x="969" y="1485"/>
+ <point x="785" y="1485" type="curve" smooth="yes"/>
+ <point x="413" y="1485"/>
+ <point x="90" y="1225"/>
+ <point x="90" y="710" type="curve" smooth="yes"/>
+ <point x="90" y="260"/>
+ <point x="341" y="-25"/>
+ <point x="755" y="-25" type="curve" smooth="yes"/>
+ <point x="926" y="-25"/>
+ <point x="1142" y="42"/>
+ <point x="1265" y="140" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfglyphs2ufo/PsfTest-Bold.ufo/glyphs/L_tnC_apD_.glif b/tests/reference/ufo/psfglyphs2ufo/PsfTest-Bold.ufo/glyphs/L_tnC_apD_.glif
new file mode 100644
index 0000000..4dd3b9c
--- /dev/null
+++ b/tests/reference/ufo/psfglyphs2ufo/PsfTest-Bold.ufo/glyphs/L_tnC_apD_.glif
@@ -0,0 +1,45 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnCapD" format="2">
+ <advance width="1485"/>
+ <unicode hex="0044"/>
+ <anchor x="800" y="-100" name="L"/>
+ <anchor x="800" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="165" y="455" type="line"/>
+ <point x="164" y="257"/>
+ <point x="165" y="80"/>
+ <point x="150" y="0" type="curve"/>
+ <point x="150" y="0"/>
+ <point x="474" y="-10"/>
+ <point x="609" y="-10" type="curve" smooth="yes"/>
+ <point x="919" y="-10"/>
+ <point x="1370" y="145"/>
+ <point x="1370" y="740" type="curve" smooth="yes"/>
+ <point x="1370" y="1374"/>
+ <point x="906" y="1470"/>
+ <point x="630" y="1470" type="curve" smooth="yes"/>
+ <point x="487" y="1470"/>
+ <point x="239" y="1466"/>
+ <point x="150" y="1460" type="curve"/>
+ <point x="165" y="1380"/>
+ <point x="165" y="1196"/>
+ <point x="165" y="1000" type="curve" smooth="yes"/>
+ </contour>
+ <contour>
+ <point x="450" y="1241" type="line"/>
+ <point x="492" y="1243"/>
+ <point x="582" y="1246"/>
+ <point x="637" y="1246" type="curve" smooth="yes"/>
+ <point x="897" y="1246"/>
+ <point x="1078" y="1118"/>
+ <point x="1078" y="720" type="curve" smooth="yes"/>
+ <point x="1078" y="357"/>
+ <point x="856" y="221"/>
+ <point x="633" y="221" type="curve" smooth="yes"/>
+ <point x="554" y="221"/>
+ <point x="489" y="227"/>
+ <point x="450" y="231" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfglyphs2ufo/PsfTest-Bold.ufo/glyphs/L_tnC_apE_.glif b/tests/reference/ufo/psfglyphs2ufo/PsfTest-Bold.ufo/glyphs/L_tnC_apE_.glif
new file mode 100644
index 0000000..9572dfd
--- /dev/null
+++ b/tests/reference/ufo/psfglyphs2ufo/PsfTest-Bold.ufo/glyphs/L_tnC_apE_.glif
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnCapE" format="2">
+ <advance width="1212"/>
+ <unicode hex="0045"/>
+ <anchor x="610" y="0" name="H"/>
+ <anchor x="610" y="-100" name="L"/>
+ <anchor x="1004" y="0" name="O"/>
+ <anchor x="1247" y="1200" name="R"/>
+ <anchor x="610" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="450" y="875" type="line"/>
+ <point x="450" y="1230" type="line"/>
+ <point x="1072" y="1230" type="line"/>
+ <point x="1072" y="1460" type="line"/>
+ <point x="150" y="1460" type="line"/>
+ <point x="165" y="1380"/>
+ <point x="165" y="1222"/>
+ <point x="165" y="1025" type="curve" smooth="yes"/>
+ <point x="165" y="435" type="line" smooth="yes"/>
+ <point x="165" y="238"/>
+ <point x="165" y="80"/>
+ <point x="150" y="0" type="curve"/>
+ <point x="1102" y="0" type="line"/>
+ <point x="1102" y="245" type="line"/>
+ <point x="1024" y="231"/>
+ <point x="899" y="230"/>
+ <point x="708" y="230" type="curve" smooth="yes"/>
+ <point x="450" y="230" type="line"/>
+ <point x="450" y="650" type="line"/>
+ <point x="997" y="650" type="line"/>
+ <point x="997" y="875" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfglyphs2ufo/PsfTest-Bold.ufo/glyphs/L_tnC_apF_.glif b/tests/reference/ufo/psfglyphs2ufo/PsfTest-Bold.ufo/glyphs/L_tnC_apF_.glif
new file mode 100644
index 0000000..9f4f14b
--- /dev/null
+++ b/tests/reference/ufo/psfglyphs2ufo/PsfTest-Bold.ufo/glyphs/L_tnC_apF_.glif
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnCapF" format="2">
+ <advance width="1200"/>
+ <unicode hex="0046"/>
+ <anchor x="630" y="-100" name="L"/>
+ <anchor x="630" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="450" y="860" type="line"/>
+ <point x="450" y="1230" type="line"/>
+ <point x="1090" y="1230" type="line"/>
+ <point x="1090" y="1460" type="line"/>
+ <point x="150" y="1460" type="line"/>
+ <point x="165" y="1380"/>
+ <point x="165" y="1217"/>
+ <point x="165" y="1020" type="curve" smooth="yes"/>
+ <point x="165" y="435" type="line" smooth="yes"/>
+ <point x="165" y="238"/>
+ <point x="165" y="80"/>
+ <point x="150" y="0" type="curve"/>
+ <point x="465" y="0" type="line"/>
+ <point x="450" y="73"/>
+ <point x="450" y="222"/>
+ <point x="450" y="408" type="curve" smooth="yes"/>
+ <point x="450" y="635" type="line"/>
+ <point x="1005" y="635" type="line"/>
+ <point x="1005" y="860" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfglyphs2ufo/PsfTest-Bold.ufo/glyphs/L_tnC_apG_.glif b/tests/reference/ufo/psfglyphs2ufo/PsfTest-Bold.ufo/glyphs/L_tnC_apG_.glif
new file mode 100644
index 0000000..8358b8a
--- /dev/null
+++ b/tests/reference/ufo/psfglyphs2ufo/PsfTest-Bold.ufo/glyphs/L_tnC_apG_.glif
@@ -0,0 +1,42 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnCapG" format="2">
+ <advance width="1472"/>
+ <unicode hex="0047"/>
+ <anchor x="807" y="0" name="H"/>
+ <anchor x="807" y="-100" name="L"/>
+ <anchor x="807" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="1337" y="785" type="line"/>
+ <point x="767" y="785" type="line"/>
+ <point x="767" y="560" type="line"/>
+ <point x="1082" y="560" type="line"/>
+ <point x="1082" y="294" type="line"/>
+ <point x="966" y="236"/>
+ <point x="883" y="220"/>
+ <point x="769" y="220" type="curve" smooth="yes"/>
+ <point x="532" y="220"/>
+ <point x="375" y="420"/>
+ <point x="375" y="745" type="curve" smooth="yes"/>
+ <point x="375" y="1048"/>
+ <point x="545" y="1245"/>
+ <point x="810" y="1245" type="curve" smooth="yes"/>
+ <point x="953" y="1245"/>
+ <point x="1097" y="1205"/>
+ <point x="1236" y="1107" type="curve"/>
+ <point x="1322" y="1345" type="line"/>
+ <point x="1137" y="1462"/>
+ <point x="989" y="1485"/>
+ <point x="818" y="1485" type="curve" smooth="yes"/>
+ <point x="403" y="1485"/>
+ <point x="90" y="1199"/>
+ <point x="90" y="720" type="curve" smooth="yes"/>
+ <point x="90" y="241"/>
+ <point x="377" y="-25"/>
+ <point x="777" y="-25" type="curve" smooth="yes"/>
+ <point x="960" y="-25"/>
+ <point x="1120" y="11"/>
+ <point x="1337" y="155" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfglyphs2ufo/PsfTest-Bold.ufo/glyphs/L_tnC_apH_.glif b/tests/reference/ufo/psfglyphs2ufo/PsfTest-Bold.ufo/glyphs/L_tnC_apH_.glif
new file mode 100644
index 0000000..2e2e5e6
--- /dev/null
+++ b/tests/reference/ufo/psfglyphs2ufo/PsfTest-Bold.ufo/glyphs/L_tnC_apH_.glif
@@ -0,0 +1,40 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnCapH" format="2">
+ <advance width="1515"/>
+ <unicode hex="0048"/>
+ <anchor x="305" y="0" name="H"/>
+ <anchor x="745" y="-100" name="L"/>
+ <anchor x="745" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="1040" y="1460" type="line"/>
+ <point x="1040" y="860" type="line"/>
+ <point x="450" y="860" type="line"/>
+ <point x="450" y="1460" type="line"/>
+ <point x="150" y="1460" type="line"/>
+ <point x="165" y="1380"/>
+ <point x="165" y="1227"/>
+ <point x="165" y="1030" type="curve" smooth="yes"/>
+ <point x="165" y="430" type="line" smooth="yes"/>
+ <point x="165" y="233"/>
+ <point x="165" y="80"/>
+ <point x="150" y="0" type="curve"/>
+ <point x="150" y="0"/>
+ <point x="450" y="0"/>
+ <point x="450" y="0" type="curve"/>
+ <point x="450" y="635" type="line"/>
+ <point x="1040" y="635" type="line"/>
+ <point x="1040" y="0" type="line"/>
+ <point x="1040" y="0"/>
+ <point x="1340" y="0"/>
+ <point x="1340" y="0" type="curve"/>
+ <point x="1325" y="80"/>
+ <point x="1325" y="233"/>
+ <point x="1325" y="430" type="curve" smooth="yes"/>
+ <point x="1325" y="1030" type="line" smooth="yes"/>
+ <point x="1325" y="1227"/>
+ <point x="1325" y="1380"/>
+ <point x="1340" y="1460" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfglyphs2ufo/PsfTest-Bold.ufo/glyphs/L_tnC_apI_.glif b/tests/reference/ufo/psfglyphs2ufo/PsfTest-Bold.ufo/glyphs/L_tnC_apI_.glif
new file mode 100644
index 0000000..388486b
--- /dev/null
+++ b/tests/reference/ufo/psfglyphs2ufo/PsfTest-Bold.ufo/glyphs/L_tnC_apI_.glif
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnCapI" format="2">
+ <advance width="1045"/>
+ <unicode hex="0049"/>
+ <anchor x="520" y="0" name="H"/>
+ <anchor x="516" y="-100" name="L"/>
+ <anchor x="712" y="0" name="O"/>
+ <anchor x="1014" y="1200" name="R"/>
+ <anchor x="520" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="130" y="1460" type="line"/>
+ <point x="130" y="1255" type="line"/>
+ <point x="370" y="1255" type="line"/>
+ <point x="370" y="205" type="line"/>
+ <point x="130" y="205" type="line"/>
+ <point x="130" y="0" type="line"/>
+ <point x="895" y="0" type="line"/>
+ <point x="895" y="205" type="line"/>
+ <point x="655" y="205" type="line"/>
+ <point x="655" y="1255" type="line"/>
+ <point x="895" y="1255" type="line"/>
+ <point x="895" y="1460" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfglyphs2ufo/PsfTest-Bold.ufo/glyphs/L_tnC_apJ_.glif b/tests/reference/ufo/psfglyphs2ufo/PsfTest-Bold.ufo/glyphs/L_tnC_apJ_.glif
new file mode 100644
index 0000000..8ee9ce3
--- /dev/null
+++ b/tests/reference/ufo/psfglyphs2ufo/PsfTest-Bold.ufo/glyphs/L_tnC_apJ_.glif
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnCapJ" format="2">
+ <advance width="1030"/>
+ <unicode hex="004A"/>
+ <anchor x="415" y="-100" name="L"/>
+ <anchor x="705" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="555" y="1460" type="line"/>
+ <point x="568" y="1354"/>
+ <point x="570" y="1175"/>
+ <point x="570" y="980" type="curve" smooth="yes"/>
+ <point x="570" y="558" type="line" smooth="yes"/>
+ <point x="570" y="383"/>
+ <point x="540" y="227"/>
+ <point x="365" y="227" type="curve" smooth="yes"/>
+ <point x="264" y="227"/>
+ <point x="153" y="270"/>
+ <point x="79" y="347" type="curve"/>
+ <point x="30" y="90" type="line"/>
+ <point x="109" y="9"/>
+ <point x="258" y="-25"/>
+ <point x="363" y="-25" type="curve" smooth="yes"/>
+ <point x="658" y="-25"/>
+ <point x="855" y="129"/>
+ <point x="855" y="535" type="curve" smooth="yes"/>
+ <point x="855" y="618"/>
+ <point x="855" y="1460"/>
+ <point x="855" y="1460" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfglyphs2ufo/PsfTest-Bold.ufo/glyphs/L_tnC_apK_.glif b/tests/reference/ufo/psfglyphs2ufo/PsfTest-Bold.ufo/glyphs/L_tnC_apK_.glif
new file mode 100644
index 0000000..abb6ff7
--- /dev/null
+++ b/tests/reference/ufo/psfglyphs2ufo/PsfTest-Bold.ufo/glyphs/L_tnC_apK_.glif
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnCapK" format="2">
+ <advance width="1430"/>
+ <unicode hex="004B"/>
+ <anchor x="320" y="0" name="H"/>
+ <anchor x="740" y="-100" name="L"/>
+ <anchor x="725" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="944" y="1460" type="line"/>
+ <point x="371" y="732" type="line"/>
+ <point x="579" y="676" type="line"/>
+ <point x="1280" y="1460" type="line"/>
+ </contour>
+ <contour>
+ <point x="389" y="731" type="line"/>
+ <point x="990" y="0" type="line"/>
+ <point x="1360" y="0" type="line"/>
+ <point x="614" y="829" type="line"/>
+ </contour>
+ <contour>
+ <point x="450" y="1460" type="line"/>
+ <point x="150" y="1460" type="line"/>
+ <point x="165" y="1380"/>
+ <point x="165" y="1222"/>
+ <point x="165" y="1025" type="curve" smooth="yes"/>
+ <point x="165" y="435" type="line" smooth="yes"/>
+ <point x="165" y="238"/>
+ <point x="165" y="80"/>
+ <point x="150" y="0" type="curve"/>
+ <point x="450" y="0" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfglyphs2ufo/PsfTest-Bold.ufo/glyphs/L_tnC_apL_.glif b/tests/reference/ufo/psfglyphs2ufo/PsfTest-Bold.ufo/glyphs/L_tnC_apL_.glif
new file mode 100644
index 0000000..e1c1e2e
--- /dev/null
+++ b/tests/reference/ufo/psfglyphs2ufo/PsfTest-Bold.ufo/glyphs/L_tnC_apL_.glif
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnCapL" format="2">
+ <advance width="1130"/>
+ <unicode hex="004C"/>
+ <anchor x="620" y="0" name="H"/>
+ <anchor x="620" y="-100" name="L"/>
+ <anchor x="650" y="1200" name="R"/>
+ <anchor x="620" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="450" y="230" type="line"/>
+ <point x="450" y="1460" type="line"/>
+ <point x="150" y="1460" type="line"/>
+ <point x="165" y="1380"/>
+ <point x="165" y="1222"/>
+ <point x="165" y="1025" type="curve" smooth="yes"/>
+ <point x="165" y="435" type="line" smooth="yes"/>
+ <point x="165" y="238"/>
+ <point x="165" y="80"/>
+ <point x="150" y="0" type="curve"/>
+ <point x="1085" y="0" type="line"/>
+ <point x="1085" y="245" type="line"/>
+ <point x="1008" y="231"/>
+ <point x="855" y="230"/>
+ <point x="666" y="230" type="curve" smooth="yes"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfglyphs2ufo/PsfTest-Bold.ufo/glyphs/L_tnC_apM_.glif b/tests/reference/ufo/psfglyphs2ufo/PsfTest-Bold.ufo/glyphs/L_tnC_apM_.glif
new file mode 100644
index 0000000..8da241e
--- /dev/null
+++ b/tests/reference/ufo/psfglyphs2ufo/PsfTest-Bold.ufo/glyphs/L_tnC_apM_.glif
@@ -0,0 +1,38 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnCapM" format="2">
+ <advance width="1855"/>
+ <unicode hex="004D"/>
+ <anchor x="915" y="-100" name="L"/>
+ <anchor x="915" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="917" y="275" type="line"/>
+ <point x="575" y="1460" type="line"/>
+ <point x="315" y="1460" type="line"/>
+ <point x="436" y="1170" type="line"/>
+ <point x="770" y="0" type="line"/>
+ <point x="1065" y="0" type="line"/>
+ <point x="1397" y="1170" type="line"/>
+ <point x="1517" y="1460" type="line"/>
+ <point x="1260" y="1460" type="line"/>
+ </contour>
+ <contour>
+ <point x="220" y="1460" type="line"/>
+ <point x="220" y="1460"/>
+ <point x="176" y="198"/>
+ <point x="150" y="0" type="curve"/>
+ <point x="420" y="0" type="line"/>
+ <point x="449" y="1205" type="line"/>
+ <point x="485" y="1460" type="line"/>
+ </contour>
+ <contour>
+ <point x="1680" y="0" type="line"/>
+ <point x="1651" y="198"/>
+ <point x="1610" y="1460"/>
+ <point x="1610" y="1460" type="curve"/>
+ <point x="1340" y="1460" type="line"/>
+ <point x="1385" y="1205" type="line"/>
+ <point x="1410" y="0" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfglyphs2ufo/PsfTest-Bold.ufo/glyphs/L_tnC_apN_.glif b/tests/reference/ufo/psfglyphs2ufo/PsfTest-Bold.ufo/glyphs/L_tnC_apN_.glif
new file mode 100644
index 0000000..aa2b5c4
--- /dev/null
+++ b/tests/reference/ufo/psfglyphs2ufo/PsfTest-Bold.ufo/glyphs/L_tnC_apN_.glif
@@ -0,0 +1,37 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnCapN" format="2">
+ <advance width="1545"/>
+ <unicode hex="004E"/>
+ <anchor x="1240" y="0" name="H"/>
+ <anchor x="765" y="-100" name="L"/>
+ <anchor x="765" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="223" y="1310" type="line"/>
+ <point x="1095" y="0" type="line"/>
+ <point x="1297" y="150" type="line"/>
+ <point x="425" y="1460" type="line"/>
+ </contour>
+ <contour>
+ <point x="1095" y="0" type="line"/>
+ <point x="1355" y="0" type="line"/>
+ <point x="1355" y="1025" type="line" smooth="yes"/>
+ <point x="1355" y="1222"/>
+ <point x="1356" y="1380"/>
+ <point x="1370" y="1460" type="curve"/>
+ <point x="1095" y="1460" type="line"/>
+ </contour>
+ <contour>
+ <point x="425" y="1460" type="line"/>
+ <point x="150" y="1460" type="line"/>
+ <point x="165" y="1380"/>
+ <point x="165" y="1222"/>
+ <point x="165" y="1025" type="curve" smooth="yes"/>
+ <point x="165" y="435" type="line" smooth="yes"/>
+ <point x="165" y="238"/>
+ <point x="165" y="80"/>
+ <point x="150" y="0" type="curve"/>
+ <point x="425" y="0" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfglyphs2ufo/PsfTest-Bold.ufo/glyphs/L_tnC_apO_.glif b/tests/reference/ufo/psfglyphs2ufo/PsfTest-Bold.ufo/glyphs/L_tnC_apO_.glif
new file mode 100644
index 0000000..10479ad
--- /dev/null
+++ b/tests/reference/ufo/psfglyphs2ufo/PsfTest-Bold.ufo/glyphs/L_tnC_apO_.glif
@@ -0,0 +1,40 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnCapO" format="2">
+ <advance width="1500"/>
+ <unicode hex="004F"/>
+ <anchor x="740" y="0" name="H"/>
+ <anchor x="740" y="-100" name="L"/>
+ <anchor x="976" y="0" name="O"/>
+ <anchor x="1480" y="1200" name="R"/>
+ <anchor x="740" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="1100" y="715" type="curve" smooth="yes"/>
+ <point x="1100" y="404"/>
+ <point x="940" y="220"/>
+ <point x="740" y="220" type="curve" smooth="yes"/>
+ <point x="524" y="220"/>
+ <point x="375" y="423"/>
+ <point x="375" y="745" type="curve" smooth="yes"/>
+ <point x="375" y="1048"/>
+ <point x="529" y="1240"/>
+ <point x="740" y="1240" type="curve" smooth="yes"/>
+ <point x="951" y="1240"/>
+ <point x="1100" y="1041"/>
+ </contour>
+ <contour>
+ <point x="1385" y="740" type="curve" smooth="yes"/>
+ <point x="1385" y="1219"/>
+ <point x="1091" y="1485"/>
+ <point x="750" y="1485" type="curve" smooth="yes"/>
+ <point x="404" y="1485"/>
+ <point x="90" y="1199"/>
+ <point x="90" y="720" type="curve" smooth="yes"/>
+ <point x="90" y="241"/>
+ <point x="385" y="-25"/>
+ <point x="730" y="-25" type="curve" smooth="yes"/>
+ <point x="1072" y="-25"/>
+ <point x="1385" y="260"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfglyphs2ufo/PsfTest-Bold.ufo/glyphs/L_tnC_apP_.glif b/tests/reference/ufo/psfglyphs2ufo/PsfTest-Bold.ufo/glyphs/L_tnC_apP_.glif
new file mode 100644
index 0000000..18e9ee0
--- /dev/null
+++ b/tests/reference/ufo/psfglyphs2ufo/PsfTest-Bold.ufo/glyphs/L_tnC_apP_.glif
@@ -0,0 +1,50 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnCapP" format="2">
+ <advance width="1275"/>
+ <unicode hex="0050"/>
+ <anchor x="685" y="-100" name="L"/>
+ <anchor x="685" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="450" y="523" type="line"/>
+ <point x="515" y="516"/>
+ <point x="575" y="513"/>
+ <point x="648" y="513" type="curve" smooth="yes"/>
+ <point x="977" y="513"/>
+ <point x="1200" y="702"/>
+ <point x="1200" y="1010" type="curve" smooth="yes"/>
+ <point x="1200" y="1316"/>
+ <point x="981" y="1470"/>
+ <point x="658" y="1470" type="curve" smooth="yes"/>
+ <point x="445" y="1470"/>
+ <point x="150" y="1460"/>
+ <point x="150" y="1460" type="curve"/>
+ <point x="165" y="1380"/>
+ <point x="165" y="1196"/>
+ <point x="165" y="1000" type="curve" smooth="yes"/>
+ <point x="165" y="435" type="line" smooth="yes"/>
+ <point x="165" y="238"/>
+ <point x="165" y="80"/>
+ <point x="150" y="0" type="curve"/>
+ <point x="465" y="0" type="line"/>
+ <point x="451" y="78"/>
+ <point x="450" y="237"/>
+ <point x="450" y="435" type="curve" smooth="yes"/>
+ </contour>
+ <contour>
+ <point x="450" y="1240" type="line"/>
+ <point x="506" y="1243"/>
+ <point x="544" y="1245"/>
+ <point x="622" y="1245" type="curve" smooth="yes"/>
+ <point x="833" y="1245"/>
+ <point x="915" y="1145"/>
+ <point x="915" y="1000" type="curve" smooth="yes"/>
+ <point x="915" y="820"/>
+ <point x="811" y="730"/>
+ <point x="618" y="730" type="curve" smooth="yes"/>
+ <point x="556" y="730"/>
+ <point x="493" y="733"/>
+ <point x="450" y="740" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfglyphs2ufo/PsfTest-Bold.ufo/glyphs/L_tnC_apQ_.glif b/tests/reference/ufo/psfglyphs2ufo/PsfTest-Bold.ufo/glyphs/L_tnC_apQ_.glif
new file mode 100644
index 0000000..433087c
--- /dev/null
+++ b/tests/reference/ufo/psfglyphs2ufo/PsfTest-Bold.ufo/glyphs/L_tnC_apQ_.glif
@@ -0,0 +1,49 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnCapQ" format="2">
+ <advance width="1545"/>
+ <unicode hex="0051"/>
+ <anchor x="747" y="-270" name="L"/>
+ <anchor x="747" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="1385" y="740" type="curve" smooth="yes"/>
+ <point x="1385" y="1219"/>
+ <point x="1091" y="1485"/>
+ <point x="750" y="1485" type="curve" smooth="yes"/>
+ <point x="404" y="1485"/>
+ <point x="90" y="1199"/>
+ <point x="90" y="720" type="curve" smooth="yes"/>
+ <point x="90" y="241"/>
+ <point x="385" y="-25"/>
+ <point x="730" y="-25" type="curve" smooth="yes"/>
+ <point x="807" y="-25"/>
+ <point x="840" y="-23"/>
+ <point x="889" y="-15" type="curve"/>
+ <point x="958" y="-15"/>
+ <point x="1266" y="-228"/>
+ <point x="1350" y="-228" type="curve" smooth="yes"/>
+ <point x="1424" y="-228"/>
+ <point x="1502" y="-68"/>
+ <point x="1535" y="-15" type="curve"/>
+ <point x="1394" y="1"/>
+ <point x="1277" y="68"/>
+ <point x="1146" y="142" type="curve"/>
+ <point x="1294" y="283"/>
+ <point x="1385" y="471"/>
+ </contour>
+ <contour>
+ <point x="1100" y="715" type="curve" smooth="yes"/>
+ <point x="1100" y="404"/>
+ <point x="943" y="220"/>
+ <point x="740" y="220" type="curve" smooth="yes"/>
+ <point x="524" y="220"/>
+ <point x="375" y="423"/>
+ <point x="375" y="745" type="curve" smooth="yes"/>
+ <point x="375" y="1048"/>
+ <point x="529" y="1240"/>
+ <point x="740" y="1240" type="curve" smooth="yes"/>
+ <point x="951" y="1240"/>
+ <point x="1100" y="1041"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfglyphs2ufo/PsfTest-Bold.ufo/glyphs/L_tnC_apR_.glif b/tests/reference/ufo/psfglyphs2ufo/PsfTest-Bold.ufo/glyphs/L_tnC_apR_.glif
new file mode 100644
index 0000000..6103056
--- /dev/null
+++ b/tests/reference/ufo/psfglyphs2ufo/PsfTest-Bold.ufo/glyphs/L_tnC_apR_.glif
@@ -0,0 +1,55 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnCapR" format="2">
+ <advance width="1380"/>
+ <unicode hex="0052"/>
+ <anchor x="690" y="0" name="H"/>
+ <anchor x="690" y="-100" name="L"/>
+ <anchor x="660" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="450" y="585" type="line"/>
+ <point x="625" y="585" type="line" smooth="yes"/>
+ <point x="910" y="585"/>
+ <point x="1175" y="723"/>
+ <point x="1175" y="1040" type="curve" smooth="yes"/>
+ <point x="1175" y="1329"/>
+ <point x="961" y="1470"/>
+ <point x="650" y="1470" type="curve" smooth="yes"/>
+ <point x="416" y="1470"/>
+ <point x="150" y="1460"/>
+ <point x="150" y="1460" type="curve"/>
+ <point x="165" y="1380"/>
+ <point x="165" y="1196"/>
+ <point x="165" y="1000" type="curve" smooth="yes"/>
+ <point x="165" y="435" type="line" smooth="yes"/>
+ <point x="165" y="238"/>
+ <point x="165" y="80"/>
+ <point x="150" y="0" type="curve"/>
+ <point x="465" y="0" type="line"/>
+ <point x="451" y="78"/>
+ <point x="450" y="238"/>
+ <point x="450" y="435" type="curve" smooth="yes"/>
+ </contour>
+ <contour>
+ <point x="450" y="1240" type="line"/>
+ <point x="503" y="1243"/>
+ <point x="537" y="1245"/>
+ <point x="615" y="1245" type="curve" smooth="yes"/>
+ <point x="792" y="1245"/>
+ <point x="890" y="1186"/>
+ <point x="890" y="1035" type="curve" smooth="yes"/>
+ <point x="890" y="859"/>
+ <point x="780" y="800"/>
+ <point x="605" y="800" type="curve" smooth="yes"/>
+ <point x="450" y="800" type="line"/>
+ </contour>
+ <contour>
+ <point x="556" y="635" type="line"/>
+ <point x="975" y="0" type="line"/>
+ <point x="1330" y="0" type="line"/>
+ <point x="1263" y="73"/>
+ <point x="827" y="687"/>
+ <point x="827" y="687" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfglyphs2ufo/PsfTest-Bold.ufo/glyphs/L_tnC_apS_.glif b/tests/reference/ufo/psfglyphs2ufo/PsfTest-Bold.ufo/glyphs/L_tnC_apS_.glif
new file mode 100644
index 0000000..486ff77
--- /dev/null
+++ b/tests/reference/ufo/psfglyphs2ufo/PsfTest-Bold.ufo/glyphs/L_tnC_apS_.glif
@@ -0,0 +1,50 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnCapS" format="2">
+ <advance width="1243"/>
+ <unicode hex="0053"/>
+ <anchor x="616" y="0" name="H"/>
+ <anchor x="616" y="-100" name="L"/>
+ <anchor x="616" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="1075" y="1395" type="line"/>
+ <point x="932" y="1458"/>
+ <point x="810" y="1485"/>
+ <point x="640" y="1485" type="curve" smooth="yes"/>
+ <point x="280" y="1485"/>
+ <point x="130" y="1239"/>
+ <point x="130" y="1060" type="curve" smooth="yes"/>
+ <point x="130" y="882"/>
+ <point x="196" y="754"/>
+ <point x="510" y="655" type="curve" smooth="yes"/>
+ <point x="800" y="563"/>
+ <point x="851" y="504"/>
+ <point x="851" y="420" type="curve" smooth="yes"/>
+ <point x="851" y="293"/>
+ <point x="730" y="220"/>
+ <point x="600" y="220" type="curve" smooth="yes"/>
+ <point x="439" y="220"/>
+ <point x="283" y="270"/>
+ <point x="140" y="385" type="curve"/>
+ <point x="90" y="110" type="line"/>
+ <point x="201" y="31"/>
+ <point x="391" y="-25"/>
+ <point x="600" y="-25" type="curve" smooth="yes"/>
+ <point x="895" y="-25"/>
+ <point x="1138" y="169"/>
+ <point x="1138" y="455" type="curve" smooth="yes"/>
+ <point x="1138" y="666"/>
+ <point x="994" y="787"/>
+ <point x="727" y="870" type="curve" smooth="yes"/>
+ <point x="464" y="952"/>
+ <point x="416" y="994"/>
+ <point x="416" y="1080" type="curve" smooth="yes"/>
+ <point x="416" y="1162"/>
+ <point x="506" y="1245"/>
+ <point x="630" y="1245" type="curve" smooth="yes"/>
+ <point x="771" y="1245"/>
+ <point x="873" y="1209"/>
+ <point x="1030" y="1130" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfglyphs2ufo/PsfTest-Bold.ufo/glyphs/L_tnC_apT_.glif b/tests/reference/ufo/psfglyphs2ufo/PsfTest-Bold.ufo/glyphs/L_tnC_apT_.glif
new file mode 100644
index 0000000..5f87c10
--- /dev/null
+++ b/tests/reference/ufo/psfglyphs2ufo/PsfTest-Bold.ufo/glyphs/L_tnC_apT_.glif
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnCapT" format="2">
+ <advance width="1275"/>
+ <unicode hex="0054"/>
+ <anchor x="632" y="0" name="H"/>
+ <anchor x="632" y="-100" name="L"/>
+ <anchor x="632" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="45" y="1460" type="line"/>
+ <point x="45" y="1210" type="line"/>
+ <point x="117" y="1227"/>
+ <point x="196" y="1230"/>
+ <point x="276" y="1230" type="curve" smooth="yes"/>
+ <point x="488" y="1230" type="line"/>
+ <point x="488" y="413" type="line" smooth="yes"/>
+ <point x="488" y="226"/>
+ <point x="485" y="76"/>
+ <point x="468" y="0" type="curve"/>
+ <point x="793" y="0" type="line"/>
+ <point x="776" y="76"/>
+ <point x="773" y="226"/>
+ <point x="773" y="413" type="curve" smooth="yes"/>
+ <point x="773" y="1230" type="line"/>
+ <point x="989" y="1230" type="line" smooth="yes"/>
+ <point x="1070" y="1230"/>
+ <point x="1148" y="1227"/>
+ <point x="1220" y="1210" type="curve"/>
+ <point x="1220" y="1460" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfglyphs2ufo/PsfTest-Bold.ufo/glyphs/L_tnC_apU_.glif b/tests/reference/ufo/psfglyphs2ufo/PsfTest-Bold.ufo/glyphs/L_tnC_apU_.glif
new file mode 100644
index 0000000..b3f6b6f
--- /dev/null
+++ b/tests/reference/ufo/psfglyphs2ufo/PsfTest-Bold.ufo/glyphs/L_tnC_apU_.glif
@@ -0,0 +1,38 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnCapU" format="2">
+ <advance width="1490"/>
+ <unicode hex="0055"/>
+ <anchor x="732" y="0" name="H"/>
+ <anchor x="732" y="-100" name="L"/>
+ <anchor x="950" y="0" name="O"/>
+ <anchor x="1480" y="1200" name="R"/>
+ <anchor x="732" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="1015" y="1460" type="line"/>
+ <point x="1015" y="560" type="line" smooth="yes"/>
+ <point x="1015" y="344"/>
+ <point x="952" y="204"/>
+ <point x="735" y="204" type="curve" smooth="yes"/>
+ <point x="513" y="204"/>
+ <point x="450" y="344"/>
+ <point x="450" y="560" type="curve" smooth="yes"/>
+ <point x="450" y="1460" type="line"/>
+ <point x="150" y="1460" type="line"/>
+ <point x="164" y="1380"/>
+ <point x="165" y="1222"/>
+ <point x="165" y="1025" type="curve" smooth="yes"/>
+ <point x="165" y="515" type="line" smooth="yes"/>
+ <point x="165" y="190"/>
+ <point x="356" y="-25"/>
+ <point x="735" y="-25" type="curve" smooth="yes"/>
+ <point x="1110" y="-25"/>
+ <point x="1300" y="190"/>
+ <point x="1300" y="515" type="curve" smooth="yes"/>
+ <point x="1300" y="1025" type="line" smooth="yes"/>
+ <point x="1300" y="1232"/>
+ <point x="1302" y="1380"/>
+ <point x="1315" y="1460" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfglyphs2ufo/PsfTest-Bold.ufo/glyphs/L_tnC_apV_.glif b/tests/reference/ufo/psfglyphs2ufo/PsfTest-Bold.ufo/glyphs/L_tnC_apV_.glif
new file mode 100644
index 0000000..3468784
--- /dev/null
+++ b/tests/reference/ufo/psfglyphs2ufo/PsfTest-Bold.ufo/glyphs/L_tnC_apV_.glif
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnCapV" format="2">
+ <advance width="1465"/>
+ <unicode hex="0056"/>
+ <anchor x="730" y="0" name="H"/>
+ <anchor x="722" y="-100" name="L"/>
+ <anchor x="930" y="0" name="O"/>
+ <anchor x="722" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="1115" y="1460" type="line"/>
+ <point x="722" y="260" type="line"/>
+ <point x="330" y="1460" type="line"/>
+ <point x="25" y="1460" type="line"/>
+ <point x="58" y="1378"/>
+ <point x="96" y="1288"/>
+ <point x="165" y="1095" type="curve" smooth="yes"/>
+ <point x="555" y="0" type="line"/>
+ <point x="890" y="0" type="line"/>
+ <point x="1280" y="1095" type="line" smooth="yes"/>
+ <point x="1348" y="1289"/>
+ <point x="1384" y="1378"/>
+ <point x="1420" y="1460" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfglyphs2ufo/PsfTest-Bold.ufo/glyphs/L_tnC_apW_.glif b/tests/reference/ufo/psfglyphs2ufo/PsfTest-Bold.ufo/glyphs/L_tnC_apW_.glif
new file mode 100644
index 0000000..98329a0
--- /dev/null
+++ b/tests/reference/ufo/psfglyphs2ufo/PsfTest-Bold.ufo/glyphs/L_tnC_apW_.glif
@@ -0,0 +1,45 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnCapW" format="2">
+ <advance width="2135"/>
+ <unicode hex="0057"/>
+ <anchor x="1052" y="-100" name="L"/>
+ <anchor x="1052" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="1490" y="0" type="line"/>
+ <point x="1655" y="0" type="line"/>
+ <point x="1965" y="1095" type="line" smooth="yes"/>
+ <point x="2020" y="1289"/>
+ <point x="2048" y="1378"/>
+ <point x="2080" y="1460" type="curve"/>
+ <point x="1770" y="1460" type="line"/>
+ <point x="1470" y="130" type="line"/>
+ </contour>
+ <contour>
+ <point x="1180" y="1460" type="line"/>
+ <point x="920" y="1460" type="line"/>
+ <point x="995" y="1305" type="line"/>
+ <point x="1340" y="0" type="line"/>
+ <point x="1510" y="0" type="line"/>
+ <point x="1530" y="130" type="line"/>
+ </contour>
+ <contour>
+ <point x="600" y="0" type="line"/>
+ <point x="765" y="0" type="line"/>
+ <point x="1105" y="1305" type="line"/>
+ <point x="1180" y="1460" type="line"/>
+ <point x="920" y="1460" type="line"/>
+ <point x="580" y="130" type="line"/>
+ </contour>
+ <contour>
+ <point x="340" y="1460" type="line"/>
+ <point x="30" y="1460" type="line"/>
+ <point x="61" y="1381"/>
+ <point x="92" y="1286"/>
+ <point x="145" y="1095" type="curve" smooth="yes"/>
+ <point x="450" y="0" type="line"/>
+ <point x="620" y="0" type="line"/>
+ <point x="640" y="130" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfglyphs2ufo/PsfTest-Bold.ufo/glyphs/L_tnC_apX_.glif b/tests/reference/ufo/psfglyphs2ufo/PsfTest-Bold.ufo/glyphs/L_tnC_apX_.glif
new file mode 100644
index 0000000..17126dd
--- /dev/null
+++ b/tests/reference/ufo/psfglyphs2ufo/PsfTest-Bold.ufo/glyphs/L_tnC_apX_.glif
@@ -0,0 +1,39 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnCapX" format="2">
+ <advance width="1365"/>
+ <unicode hex="0058"/>
+ <anchor x="670" y="-100" name="L"/>
+ <anchor x="670" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="990" y="0" type="line"/>
+ <point x="1310" y="0" type="line"/>
+ <point x="1249" y="82"/>
+ <point x="1211" y="125"/>
+ <point x="1083" y="336" type="curve" smooth="yes"/>
+ <point x="400" y="1460" type="line"/>
+ <point x="75" y="1460" type="line"/>
+ <point x="139" y="1376"/>
+ <point x="189" y="1317"/>
+ <point x="315" y="1110" type="curve"/>
+ </contour>
+ <contour>
+ <point x="605" y="947" type="line"/>
+ <point x="255" y="340" type="line" smooth="yes"/>
+ <point x="133" y="128"/>
+ <point x="93" y="86"/>
+ <point x="30" y="0" type="curve"/>
+ <point x="350" y="0" type="line"/>
+ <point x="700" y="609" type="line"/>
+ </contour>
+ <contour>
+ <point x="750" y="609" type="line"/>
+ <point x="1040" y="1110" type="line" smooth="yes"/>
+ <point x="1153" y="1306"/>
+ <point x="1211" y="1383"/>
+ <point x="1275" y="1460" type="curve"/>
+ <point x="950" y="1460" type="line"/>
+ <point x="655" y="947" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfglyphs2ufo/PsfTest-Bold.ufo/glyphs/L_tnC_apY_.glif b/tests/reference/ufo/psfglyphs2ufo/PsfTest-Bold.ufo/glyphs/L_tnC_apY_.glif
new file mode 100644
index 0000000..a7a345d
--- /dev/null
+++ b/tests/reference/ufo/psfglyphs2ufo/PsfTest-Bold.ufo/glyphs/L_tnC_apY_.glif
@@ -0,0 +1,39 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnCapY" format="2">
+ <advance width="1364"/>
+ <unicode hex="0059"/>
+ <anchor x="672" y="-100" name="L"/>
+ <anchor x="672" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="575" y="560" type="line"/>
+ <point x="782" y="675" type="line"/>
+ <point x="357" y="1460" type="line"/>
+ <point x="25" y="1460" type="line"/>
+ <point x="137" y="1311"/>
+ <point x="203" y="1197"/>
+ <point x="280" y="1065" type="curve" smooth="yes"/>
+ </contour>
+ <contour>
+ <point x="770" y="560" type="line"/>
+ <point x="1069" y="1065" type="line" smooth="yes"/>
+ <point x="1145" y="1195"/>
+ <point x="1201" y="1291"/>
+ <point x="1319" y="1460" type="curve"/>
+ <point x="997" y="1460" type="line"/>
+ <point x="577" y="675" type="line"/>
+ </contour>
+ <contour>
+ <point x="530" y="695" type="line"/>
+ <point x="530" y="435" type="line" smooth="yes"/>
+ <point x="530" y="238"/>
+ <point x="530" y="80"/>
+ <point x="515" y="0" type="curve"/>
+ <point x="830" y="0" type="line"/>
+ <point x="815" y="80"/>
+ <point x="815" y="238"/>
+ <point x="815" y="435" type="curve" smooth="yes"/>
+ <point x="815" y="695" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfglyphs2ufo/PsfTest-Bold.ufo/glyphs/L_tnS_mA_.glif b/tests/reference/ufo/psfglyphs2ufo/PsfTest-Bold.ufo/glyphs/L_tnS_mA_.glif
new file mode 100644
index 0000000..f6ea8fb
--- /dev/null
+++ b/tests/reference/ufo/psfglyphs2ufo/PsfTest-Bold.ufo/glyphs/L_tnS_mA_.glif
@@ -0,0 +1,68 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmA" format="2">
+ <advance width="1205"/>
+ <unicode hex="0061"/>
+ <note>
+GlyphNote A
+</note>
+ <anchor x="985" y="0" name="H"/>
+ <anchor x="610" y="-100" name="L"/>
+ <anchor x="1185" y="0" name="O"/>
+ <anchor x="1145" y="1000" name="R"/>
+ <anchor x="610" y="1100" name="U"/>
+ <outline>
+ <contour>
+ <point x="1120" y="0" type="line"/>
+ <point x="1078" y="112"/>
+ <point x="1050" y="226"/>
+ <point x="1050" y="370" type="curve"/>
+ <point x="1050" y="760" type="line"/>
+ <point x="1050" y="919"/>
+ <point x="877" y="1040"/>
+ <point x="615" y="1040" type="curve" smooth="yes"/>
+ <point x="446" y="1040"/>
+ <point x="330" y="994"/>
+ <point x="216" y="950" type="curve"/>
+ <point x="210" y="868"/>
+ <point x="207" y="735"/>
+ <point x="206" y="691" type="curve"/>
+ <point x="323" y="773"/>
+ <point x="424" y="816"/>
+ <point x="530" y="816" type="curve" smooth="yes"/>
+ <point x="680" y="816"/>
+ <point x="770" y="785"/>
+ <point x="770" y="710" type="curve" smooth="yes"/>
+ <point x="770" y="660" type="line"/>
+ <point x="729" y="659"/>
+ <point x="569" y="649"/>
+ <point x="500" y="642" type="curve" smooth="yes"/>
+ <point x="191" y="612"/>
+ <point x="100" y="438"/>
+ <point x="100" y="285" type="curve" smooth="yes"/>
+ <point x="100" y="121"/>
+ <point x="245" y="-25"/>
+ <point x="445" y="-25" type="curve" smooth="yes"/>
+ <point x="562" y="-25"/>
+ <point x="688" y="23"/>
+ <point x="800" y="135" type="curve"/>
+ <point x="814" y="79"/>
+ <point x="838" y="28"/>
+ <point x="850" y="0" type="curve"/>
+ </contour>
+ <contour>
+ <point x="770" y="355" type="line"/>
+ <point x="674" y="225"/>
+ <point x="600" y="205"/>
+ <point x="518" y="205" type="curve" smooth="yes"/>
+ <point x="436" y="205"/>
+ <point x="380" y="256"/>
+ <point x="380" y="320" type="curve" smooth="yes"/>
+ <point x="380" y="386"/>
+ <point x="422" y="442"/>
+ <point x="560" y="457" type="curve" smooth="yes"/>
+ <point x="611" y="463"/>
+ <point x="730" y="474"/>
+ <point x="770" y="475" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfglyphs2ufo/PsfTest-Bold.ufo/glyphs/L_tnS_mA_A_cute.glif b/tests/reference/ufo/psfglyphs2ufo/PsfTest-Bold.ufo/glyphs/L_tnS_mA_A_cute.glif
new file mode 100644
index 0000000..f1c66a5
--- /dev/null
+++ b/tests/reference/ufo/psfglyphs2ufo/PsfTest-Bold.ufo/glyphs/L_tnS_mA_A_cute.glif
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmAAcute" format="2">
+ <advance width="1205"/>
+ <unicode hex="00E1"/>
+ <anchor x="985" y="0" name="H"/>
+ <anchor x="610" y="-100" name="L"/>
+ <anchor x="1185" y="0" name="O"/>
+ <anchor x="1145" y="1000" name="R"/>
+ <anchor x="550" y="1635" name="U"/>
+ <outline>
+ <component base="LtnSmA"/>
+ <component base="CombAcute" xOffset="1150"/>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfglyphs2ufo/PsfTest-Bold.ufo/glyphs/L_tnS_mA_C_ircum.glif b/tests/reference/ufo/psfglyphs2ufo/PsfTest-Bold.ufo/glyphs/L_tnS_mA_C_ircum.glif
new file mode 100644
index 0000000..218d694
--- /dev/null
+++ b/tests/reference/ufo/psfglyphs2ufo/PsfTest-Bold.ufo/glyphs/L_tnS_mA_C_ircum.glif
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmACircum" format="2">
+ <advance width="1205"/>
+ <unicode hex="00E2"/>
+ <anchor x="985" y="0" name="H"/>
+ <anchor x="610" y="-100" name="L"/>
+ <anchor x="1185" y="0" name="O"/>
+ <anchor x="1145" y="1000" name="R"/>
+ <anchor x="602" y="1635" name="U"/>
+ <outline>
+ <component base="LtnSmA"/>
+ <component base="CombCircum" xOffset="1190"/>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfglyphs2ufo/PsfTest-Bold.ufo/glyphs/L_tnS_mA_D_iaer.glif b/tests/reference/ufo/psfglyphs2ufo/PsfTest-Bold.ufo/glyphs/L_tnS_mA_D_iaer.glif
new file mode 100644
index 0000000..bb0ea2c
--- /dev/null
+++ b/tests/reference/ufo/psfglyphs2ufo/PsfTest-Bold.ufo/glyphs/L_tnS_mA_D_iaer.glif
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmADiaer" format="2">
+ <advance width="1205"/>
+ <unicode hex="00E4"/>
+ <anchor x="985" y="0" name="H"/>
+ <anchor x="610" y="-100" name="L"/>
+ <anchor x="1185" y="0" name="O"/>
+ <anchor x="1145" y="1000" name="R"/>
+ <anchor x="610" y="1585" name="U"/>
+ <outline>
+ <component base="LtnSmA"/>
+ <component base="CombDiaer" xOffset="1190"/>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfglyphs2ufo/PsfTest-Bold.ufo/glyphs/L_tnS_mA_G_rave.glif b/tests/reference/ufo/psfglyphs2ufo/PsfTest-Bold.ufo/glyphs/L_tnS_mA_G_rave.glif
new file mode 100644
index 0000000..3153364
--- /dev/null
+++ b/tests/reference/ufo/psfglyphs2ufo/PsfTest-Bold.ufo/glyphs/L_tnS_mA_G_rave.glif
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmAGrave" format="2">
+ <advance width="1205"/>
+ <unicode hex="00E0"/>
+ <anchor x="985" y="0" name="H"/>
+ <anchor x="610" y="-100" name="L"/>
+ <anchor x="1185" y="0" name="O"/>
+ <anchor x="1145" y="1000" name="R"/>
+ <anchor x="650" y="1635" name="U"/>
+ <outline>
+ <component base="LtnSmA"/>
+ <component base="CombGrave" xOffset="1240"/>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfglyphs2ufo/PsfTest-Bold.ufo/glyphs/L_tnS_mA_R_ingA_bv.glif b/tests/reference/ufo/psfglyphs2ufo/PsfTest-Bold.ufo/glyphs/L_tnS_mA_R_ingA_bv.glif
new file mode 100644
index 0000000..3b8da5a
--- /dev/null
+++ b/tests/reference/ufo/psfglyphs2ufo/PsfTest-Bold.ufo/glyphs/L_tnS_mA_R_ingA_bv.glif
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmARingAbv" format="2">
+ <advance width="1205"/>
+ <unicode hex="00E5"/>
+ <anchor x="985" y="0" name="H"/>
+ <anchor x="610" y="-100" name="L"/>
+ <anchor x="1185" y="0" name="O"/>
+ <anchor x="1145" y="1000" name="R"/>
+ <anchor x="612" y="1635" name="U"/>
+ <outline>
+ <component base="LtnSmA"/>
+ <component base="CombRingAbv" xOffset="1182"/>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfglyphs2ufo/PsfTest-Bold.ufo/glyphs/L_tnS_mA_T_ilde.glif b/tests/reference/ufo/psfglyphs2ufo/PsfTest-Bold.ufo/glyphs/L_tnS_mA_T_ilde.glif
new file mode 100644
index 0000000..b3a8515
--- /dev/null
+++ b/tests/reference/ufo/psfglyphs2ufo/PsfTest-Bold.ufo/glyphs/L_tnS_mA_T_ilde.glif
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmATilde" format="2">
+ <advance width="1205"/>
+ <unicode hex="00E3"/>
+ <anchor x="985" y="0" name="H"/>
+ <anchor x="610" y="-100" name="L"/>
+ <anchor x="1185" y="0" name="O"/>
+ <anchor x="1145" y="1000" name="R"/>
+ <anchor x="610" y="1490" name="U"/>
+ <outline>
+ <component base="LtnSmA"/>
+ <component base="CombTilde" xOffset="1190"/>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfglyphs2ufo/PsfTest-Bold.ufo/glyphs/L_tnS_mB_.glif b/tests/reference/ufo/psfglyphs2ufo/PsfTest-Bold.ufo/glyphs/L_tnS_mB_.glif
new file mode 100644
index 0000000..6cc6671
--- /dev/null
+++ b/tests/reference/ufo/psfglyphs2ufo/PsfTest-Bold.ufo/glyphs/L_tnS_mB_.glif
@@ -0,0 +1,50 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmB" format="2">
+ <advance width="1215"/>
+ <unicode hex="0062"/>
+ <anchor x="610" y="0" name="H"/>
+ <anchor x="610" y="-100" name="L"/>
+ <anchor x="1215" y="1000" name="R"/>
+ <anchor x="610" y="1635" name="U"/>
+ <outline>
+ <contour>
+ <point x="120" y="1600" type="line"/>
+ <point x="135" y="1488"/>
+ <point x="135" y="1273"/>
+ <point x="135" y="1130" type="curve" smooth="yes"/>
+ <point x="135" y="936"/>
+ <point x="135" y="228"/>
+ <point x="135" y="65" type="curve"/>
+ <point x="286" y="26"/>
+ <point x="457" y="-25"/>
+ <point x="650" y="-25" type="curve" smooth="yes"/>
+ <point x="939" y="-25"/>
+ <point x="1125" y="197"/>
+ <point x="1125" y="540" type="curve" smooth="yes"/>
+ <point x="1125" y="832"/>
+ <point x="986" y="1040"/>
+ <point x="789" y="1040" type="curve" smooth="yes"/>
+ <point x="626" y="1040"/>
+ <point x="505" y="956"/>
+ <point x="415" y="845" type="curve"/>
+ <point x="415" y="934"/>
+ <point x="415" y="1600"/>
+ <point x="415" y="1600" type="curve"/>
+ </contour>
+ <contour>
+ <point x="415" y="585" type="line"/>
+ <point x="471" y="709"/>
+ <point x="580" y="795"/>
+ <point x="683" y="795" type="curve" smooth="yes"/>
+ <point x="793" y="795"/>
+ <point x="855" y="684"/>
+ <point x="855" y="505" type="curve" smooth="yes"/>
+ <point x="855" y="317"/>
+ <point x="750" y="190"/>
+ <point x="605" y="190" type="curve" smooth="yes"/>
+ <point x="538" y="190"/>
+ <point x="492" y="204"/>
+ <point x="415" y="240" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfglyphs2ufo/PsfTest-Bold.ufo/glyphs/L_tnS_mC_.glif b/tests/reference/ufo/psfglyphs2ufo/PsfTest-Bold.ufo/glyphs/L_tnS_mC_.glif
new file mode 100644
index 0000000..19a8a6d
--- /dev/null
+++ b/tests/reference/ufo/psfglyphs2ufo/PsfTest-Bold.ufo/glyphs/L_tnS_mC_.glif
@@ -0,0 +1,39 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmC" format="2">
+ <advance width="1022"/>
+ <unicode hex="0063"/>
+ <anchor x="555" y="0" name="H"/>
+ <anchor x="575" y="-100" name="L"/>
+ <anchor x="1020" y="1000" name="R"/>
+ <anchor x="575" y="1100" name="U"/>
+ <outline>
+ <contour>
+ <point x="922" y="969" type="line"/>
+ <point x="849" y="1007"/>
+ <point x="744" y="1040"/>
+ <point x="612" y="1040" type="curve" smooth="yes"/>
+ <point x="295" y="1040"/>
+ <point x="90" y="802"/>
+ <point x="90" y="490" type="curve" smooth="yes"/>
+ <point x="90" y="161"/>
+ <point x="309" y="-25"/>
+ <point x="578" y="-25" type="curve" smooth="yes"/>
+ <point x="727" y="-25"/>
+ <point x="831" y="8"/>
+ <point x="932" y="70" type="curve"/>
+ <point x="902" y="314" type="line"/>
+ <point x="815" y="245"/>
+ <point x="737" y="205"/>
+ <point x="617" y="205" type="curve" smooth="yes"/>
+ <point x="467" y="205"/>
+ <point x="370" y="324"/>
+ <point x="370" y="500" type="curve" smooth="yes"/>
+ <point x="370" y="694"/>
+ <point x="478" y="810"/>
+ <point x="617" y="810" type="curve" smooth="yes"/>
+ <point x="720" y="810"/>
+ <point x="788" y="779"/>
+ <point x="878" y="717" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfglyphs2ufo/PsfTest-Bold.ufo/glyphs/L_tnS_mD_.glif b/tests/reference/ufo/psfglyphs2ufo/PsfTest-Bold.ufo/glyphs/L_tnS_mD_.glif
new file mode 100644
index 0000000..fc1cc76
--- /dev/null
+++ b/tests/reference/ufo/psfglyphs2ufo/PsfTest-Bold.ufo/glyphs/L_tnS_mD_.glif
@@ -0,0 +1,53 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmD" format="2">
+ <advance width="1265"/>
+ <unicode hex="0064"/>
+ <anchor x="595" y="0" name="H"/>
+ <anchor x="595" y="-100" name="L"/>
+ <anchor x="1285" y="1000" name="R"/>
+ <anchor x="610" y="1635" name="U"/>
+ <outline>
+ <contour>
+ <point x="1115" y="1600" type="line"/>
+ <point x="810" y="1600" type="line"/>
+ <point x="829" y="1516"/>
+ <point x="835" y="1395"/>
+ <point x="835" y="1235" type="curve" smooth="yes"/>
+ <point x="835" y="955" type="line"/>
+ <point x="763" y="999"/>
+ <point x="669" y="1040"/>
+ <point x="590" y="1040" type="curve" smooth="yes"/>
+ <point x="319" y="1040"/>
+ <point x="100" y="814"/>
+ <point x="100" y="460" type="curve" smooth="yes"/>
+ <point x="100" y="167"/>
+ <point x="268" y="-25"/>
+ <point x="515" y="-25" type="curve" smooth="yes"/>
+ <point x="654" y="-25"/>
+ <point x="770" y="47"/>
+ <point x="860" y="175" type="curve"/>
+ <point x="877" y="105"/>
+ <point x="900" y="32"/>
+ <point x="915" y="0" type="curve"/>
+ <point x="1190" y="0" type="line"/>
+ <point x="1147" y="112"/>
+ <point x="1115" y="278"/>
+ <point x="1115" y="530" type="curve" smooth="yes"/>
+ </contour>
+ <contour>
+ <point x="835" y="400" type="line"/>
+ <point x="787" y="300"/>
+ <point x="676" y="200"/>
+ <point x="570" y="200" type="curve" smooth="yes"/>
+ <point x="443" y="200"/>
+ <point x="380" y="300"/>
+ <point x="380" y="490" type="curve" smooth="yes"/>
+ <point x="380" y="685"/>
+ <point x="485" y="800"/>
+ <point x="590" y="800" type="curve" smooth="yes"/>
+ <point x="683" y="800"/>
+ <point x="743" y="783"/>
+ <point x="835" y="738" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfglyphs2ufo/PsfTest-Bold.ufo/glyphs/L_tnS_mE_.glif b/tests/reference/ufo/psfglyphs2ufo/PsfTest-Bold.ufo/glyphs/L_tnS_mE_.glif
new file mode 100644
index 0000000..5c67455
--- /dev/null
+++ b/tests/reference/ufo/psfglyphs2ufo/PsfTest-Bold.ufo/glyphs/L_tnS_mE_.glif
@@ -0,0 +1,45 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmE" format="2">
+ <advance width="1110"/>
+ <unicode hex="0065"/>
+ <anchor x="569" y="0" name="H"/>
+ <anchor x="589" y="-100" name="L"/>
+ <anchor x="900" y="0" name="O"/>
+ <anchor x="1130" y="1000" name="R"/>
+ <anchor x="537" y="1100" name="U"/>
+ <outline>
+ <contour>
+ <point x="1010" y="450" type="line"/>
+ <point x="1010" y="469"/>
+ <point x="1009" y="513"/>
+ <point x="1009" y="532" type="curve" smooth="yes"/>
+ <point x="1009" y="782"/>
+ <point x="924" y="1040"/>
+ <point x="589" y="1040" type="curve" smooth="yes"/>
+ <point x="281" y="1040"/>
+ <point x="90" y="826"/>
+ <point x="90" y="495" type="curve" smooth="yes"/>
+ <point x="90" y="155"/>
+ <point x="324" y="-25"/>
+ <point x="589" y="-25" type="curve" smooth="yes"/>
+ <point x="745" y="-25"/>
+ <point x="871" y="2"/>
+ <point x="1015" y="75" type="curve"/>
+ <point x="994" y="306" type="line"/>
+ <point x="870" y="232"/>
+ <point x="745" y="205"/>
+ <point x="614" y="205" type="curve" smooth="yes"/>
+ <point x="448" y="205"/>
+ <point x="362" y="293"/>
+ <point x="362" y="505" type="curve" smooth="yes"/>
+ <point x="362" y="739"/>
+ <point x="431" y="830"/>
+ <point x="575" y="830" type="curve" smooth="yes"/>
+ <point x="693" y="830"/>
+ <point x="755" y="770"/>
+ <point x="755" y="630" type="curve"/>
+ <point x="242" y="630" type="line"/>
+ <point x="242" y="450" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfglyphs2ufo/PsfTest-Bold.ufo/glyphs/L_tnS_mF_.glif b/tests/reference/ufo/psfglyphs2ufo/PsfTest-Bold.ufo/glyphs/L_tnS_mF_.glif
new file mode 100644
index 0000000..8a5996d
--- /dev/null
+++ b/tests/reference/ufo/psfglyphs2ufo/PsfTest-Bold.ufo/glyphs/L_tnS_mF_.glif
@@ -0,0 +1,39 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmF" format="2">
+ <advance width="800"/>
+ <unicode hex="0066"/>
+ <anchor x="380" y="0" name="H"/>
+ <anchor x="400" y="-100" name="L"/>
+ <anchor x="600" y="1635" name="U"/>
+ <outline>
+ <contour>
+ <point x="30" y="805" type="line"/>
+ <point x="230" y="805" type="line"/>
+ <point x="230" y="0" type="line"/>
+ <point x="540" y="0" type="line"/>
+ <point x="518" y="105"/>
+ <point x="510" y="300"/>
+ <point x="510" y="494" type="curve" smooth="yes"/>
+ <point x="510" y="805" type="line"/>
+ <point x="765" y="805" type="line"/>
+ <point x="765" y="1005" type="line"/>
+ <point x="510" y="1005" type="line"/>
+ <point x="510" y="1159" type="line" smooth="yes"/>
+ <point x="510" y="1322"/>
+ <point x="552" y="1387"/>
+ <point x="648" y="1387" type="curve" smooth="yes"/>
+ <point x="697" y="1387"/>
+ <point x="765" y="1362"/>
+ <point x="808" y="1322" type="curve"/>
+ <point x="865" y="1550" type="line"/>
+ <point x="806" y="1588"/>
+ <point x="699" y="1620"/>
+ <point x="625" y="1620" type="curve" smooth="yes"/>
+ <point x="378" y="1620"/>
+ <point x="230" y="1470"/>
+ <point x="230" y="1170" type="curve" smooth="yes"/>
+ <point x="230" y="1005" type="line"/>
+ <point x="30" y="1005" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfglyphs2ufo/PsfTest-Bold.ufo/glyphs/L_tnS_mG_.glif b/tests/reference/ufo/psfglyphs2ufo/PsfTest-Bold.ufo/glyphs/L_tnS_mG_.glif
new file mode 100644
index 0000000..871e4e9
--- /dev/null
+++ b/tests/reference/ufo/psfglyphs2ufo/PsfTest-Bold.ufo/glyphs/L_tnS_mG_.glif
@@ -0,0 +1,91 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmG" format="2">
+ <advance width="1170"/>
+ <unicode hex="0067"/>
+ <anchor x="597" y="-465" name="H"/>
+ <anchor x="597" y="-535" name="L"/>
+ <anchor x="1187" y="1000" name="R"/>
+ <anchor x="567" y="1100" name="U"/>
+ <outline>
+ <contour>
+ <point x="352" y="395" type="line"/>
+ <point x="256" y="357"/>
+ <point x="202" y="275"/>
+ <point x="202" y="215" type="curve" smooth="yes"/>
+ <point x="202" y="113"/>
+ <point x="280" y="12"/>
+ <point x="547" y="-23" type="curve" smooth="yes"/>
+ <point x="797" y="-50"/>
+ <point x="870" y="-99"/>
+ <point x="870" y="-170" type="curve" smooth="yes"/>
+ <point x="870" y="-229"/>
+ <point x="748" y="-302"/>
+ <point x="602" y="-302" type="curve" smooth="yes"/>
+ <point x="418" y="-302"/>
+ <point x="330" y="-235"/>
+ <point x="330" y="-180" type="curve" smooth="yes"/>
+ <point x="330" y="-121"/>
+ <point x="357" y="-56"/>
+ <point x="562" y="20" type="curve"/>
+ <point x="554" y="49"/>
+ <point x="322" y="75"/>
+ <point x="322" y="75" type="curve"/>
+ <point x="138" y="2"/>
+ <point x="50" y="-89"/>
+ <point x="50" y="-200" type="curve" smooth="yes"/>
+ <point x="50" y="-409"/>
+ <point x="341" y="-505"/>
+ <point x="587" y="-505" type="curve" smooth="yes"/>
+ <point x="843" y="-505"/>
+ <point x="1150" y="-375"/>
+ <point x="1150" y="-160" type="curve" smooth="yes"/>
+ <point x="1150" y="13"/>
+ <point x="1049" y="125"/>
+ <point x="752" y="165" type="curve" smooth="yes"/>
+ <point x="497" y="191"/>
+ <point x="433" y="216"/>
+ <point x="433" y="255" type="curve" smooth="yes"/>
+ <point x="433" y="285"/>
+ <point x="472" y="322"/>
+ <point x="588" y="350" type="curve"/>
+ </contour>
+ <contour>
+ <point x="1102" y="1040" type="line"/>
+ <point x="1003" y="1033"/>
+ <point x="871" y="997"/>
+ <point x="782" y="940" type="curve"/>
+ <point x="847" y="770" type="line"/>
+ <point x="939" y="808"/>
+ <point x="1019" y="823"/>
+ <point x="1092" y="825" type="curve"/>
+ </contour>
+ <contour>
+ <point x="122" y="670" type="curve" smooth="yes"/>
+ <point x="122" y="455"/>
+ <point x="316" y="305"/>
+ <point x="567" y="305" type="curve" smooth="yes"/>
+ <point x="820" y="305"/>
+ <point x="1012" y="465"/>
+ <point x="1012" y="680" type="curve" smooth="yes"/>
+ <point x="1012" y="884"/>
+ <point x="820" y="1040"/>
+ <point x="567" y="1040" type="curve" smooth="yes"/>
+ <point x="316" y="1040"/>
+ <point x="122" y="874"/>
+ </contour>
+ <contour>
+ <point x="377" y="680" type="curve" smooth="yes"/>
+ <point x="377" y="770"/>
+ <point x="457" y="847"/>
+ <point x="567" y="847" type="curve" smooth="yes"/>
+ <point x="678" y="847"/>
+ <point x="757" y="770"/>
+ <point x="757" y="680" type="curve" smooth="yes"/>
+ <point x="757" y="578"/>
+ <point x="678" y="501"/>
+ <point x="567" y="501" type="curve" smooth="yes"/>
+ <point x="457" y="501"/>
+ <point x="377" y="578"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfglyphs2ufo/PsfTest-Bold.ufo/glyphs/L_tnS_mH_.glif b/tests/reference/ufo/psfglyphs2ufo/PsfTest-Bold.ufo/glyphs/L_tnS_mH_.glif
new file mode 100644
index 0000000..15fc451
--- /dev/null
+++ b/tests/reference/ufo/psfglyphs2ufo/PsfTest-Bold.ufo/glyphs/L_tnS_mH_.glif
@@ -0,0 +1,43 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmH" format="2">
+ <advance width="1235"/>
+ <unicode hex="0068"/>
+ <anchor x="280" y="0" name="H"/>
+ <anchor x="620" y="-100" name="L"/>
+ <anchor x="620" y="1635" name="U"/>
+ <outline>
+ <contour>
+ <point x="415" y="580" type="line"/>
+ <point x="450" y="683"/>
+ <point x="560" y="795"/>
+ <point x="675" y="795" type="curve" smooth="yes"/>
+ <point x="782" y="795"/>
+ <point x="830" y="744"/>
+ <point x="830" y="550" type="curve" smooth="yes"/>
+ <point x="830" y="413"/>
+ <point x="830" y="0"/>
+ <point x="830" y="0" type="curve"/>
+ <point x="1110" y="0" type="line"/>
+ <point x="1110" y="0"/>
+ <point x="1110" y="459"/>
+ <point x="1110" y="625" type="curve" smooth="yes"/>
+ <point x="1110" y="900"/>
+ <point x="1008" y="1040"/>
+ <point x="805" y="1040" type="curve" smooth="yes"/>
+ <point x="662" y="1040"/>
+ <point x="513" y="976"/>
+ <point x="415" y="850" type="curve"/>
+ <point x="415" y="894"/>
+ <point x="415" y="1600"/>
+ <point x="415" y="1600" type="curve"/>
+ <point x="120" y="1600" type="line"/>
+ <point x="135" y="1514"/>
+ <point x="135" y="1345"/>
+ <point x="135" y="1130" type="curve" smooth="yes"/>
+ <point x="135" y="935"/>
+ <point x="135" y="0"/>
+ <point x="135" y="0" type="curve"/>
+ <point x="415" y="0" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfglyphs2ufo/PsfTest-Bold.ufo/glyphs/L_tnS_mI_.glif b/tests/reference/ufo/psfglyphs2ufo/PsfTest-Bold.ufo/glyphs/L_tnS_mI_.glif
new file mode 100644
index 0000000..05022d4
--- /dev/null
+++ b/tests/reference/ufo/psfglyphs2ufo/PsfTest-Bold.ufo/glyphs/L_tnS_mI_.glif
@@ -0,0 +1,42 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmI" format="2">
+ <advance width="640"/>
+ <unicode hex="0069"/>
+ <anchor x="320" y="0" name="H"/>
+ <anchor x="320" y="-100" name="L"/>
+ <anchor x="580" y="0" name="O"/>
+ <anchor x="640" y="1000" name="R"/>
+ <anchor x="320" y="1100" name="U"/>
+ <outline>
+ <contour>
+ <point x="165" y="1020" type="line"/>
+ <point x="178" y="915"/>
+ <point x="180" y="725"/>
+ <point x="180" y="530" type="curve" smooth="yes"/>
+ <point x="180" y="336"/>
+ <point x="180" y="0"/>
+ <point x="180" y="0" type="curve"/>
+ <point x="480" y="0" type="line"/>
+ <point x="467" y="107"/>
+ <point x="460" y="346"/>
+ <point x="460" y="475" type="curve" smooth="yes"/>
+ <point x="460" y="558"/>
+ <point x="460" y="1020"/>
+ <point x="460" y="1020" type="curve"/>
+ </contour>
+ <contour>
+ <point x="145" y="1385" type="curve" smooth="yes"/>
+ <point x="145" y="1281"/>
+ <point x="219" y="1210"/>
+ <point x="320" y="1210" type="curve" smooth="yes"/>
+ <point x="422" y="1210"/>
+ <point x="495" y="1281"/>
+ <point x="495" y="1385" type="curve" smooth="yes"/>
+ <point x="495" y="1487"/>
+ <point x="422" y="1560"/>
+ <point x="320" y="1560" type="curve" smooth="yes"/>
+ <point x="219" y="1560"/>
+ <point x="145" y="1487"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfglyphs2ufo/PsfTest-Bold.ufo/glyphs/L_tnS_mJ_.glif b/tests/reference/ufo/psfglyphs2ufo/PsfTest-Bold.ufo/glyphs/L_tnS_mJ_.glif
new file mode 100644
index 0000000..6e044af
--- /dev/null
+++ b/tests/reference/ufo/psfglyphs2ufo/PsfTest-Bold.ufo/glyphs/L_tnS_mJ_.glif
@@ -0,0 +1,44 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmJ" format="2">
+ <advance width="670"/>
+ <unicode hex="006A"/>
+ <anchor x="140" y="-500" name="L"/>
+ <anchor x="355" y="1100" name="U"/>
+ <outline>
+ <contour>
+ <point x="185" y="1385" type="curve" smooth="yes"/>
+ <point x="185" y="1281"/>
+ <point x="259" y="1210"/>
+ <point x="360" y="1210" type="curve" smooth="yes"/>
+ <point x="462" y="1210"/>
+ <point x="535" y="1281"/>
+ <point x="535" y="1385" type="curve" smooth="yes"/>
+ <point x="535" y="1487"/>
+ <point x="462" y="1560"/>
+ <point x="360" y="1560" type="curve" smooth="yes"/>
+ <point x="259" y="1560"/>
+ <point x="185" y="1487"/>
+ </contour>
+ <contour>
+ <point x="500" y="1020" type="line"/>
+ <point x="205" y="1020" type="line"/>
+ <point x="218" y="915"/>
+ <point x="220" y="725"/>
+ <point x="220" y="530" type="curve"/>
+ <point x="220" y="20" type="line"/>
+ <point x="220" y="-150"/>
+ <point x="165" y="-232"/>
+ <point x="48" y="-232" type="curve" smooth="yes"/>
+ <point x="-20" y="-232"/>
+ <point x="-101" y="-195"/>
+ <point x="-145" y="-152" type="curve"/>
+ <point x="-190" y="-389" type="line"/>
+ <point x="-148" y="-421"/>
+ <point x="-37" y="-470"/>
+ <point x="56" y="-470" type="curve" smooth="yes"/>
+ <point x="306" y="-470"/>
+ <point x="500" y="-348"/>
+ <point x="500" y="25" type="curve" smooth="yes"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfglyphs2ufo/PsfTest-Bold.ufo/glyphs/L_tnS_mK_.glif b/tests/reference/ufo/psfglyphs2ufo/PsfTest-Bold.ufo/glyphs/L_tnS_mK_.glif
new file mode 100644
index 0000000..529f7dd
--- /dev/null
+++ b/tests/reference/ufo/psfglyphs2ufo/PsfTest-Bold.ufo/glyphs/L_tnS_mK_.glif
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmK" format="2">
+ <advance width="1138"/>
+ <unicode hex="006B"/>
+ <anchor x="940" y="0" name="H"/>
+ <anchor x="585" y="-100" name="L"/>
+ <anchor x="1140" y="1000" name="R"/>
+ <anchor x="595" y="1635" name="U"/>
+ <outline>
+ <contour>
+ <point x="415" y="0" type="line"/>
+ <point x="415" y="1600" type="line"/>
+ <point x="120" y="1600" type="line"/>
+ <point x="135" y="1514"/>
+ <point x="135" y="1345"/>
+ <point x="135" y="1130" type="curve" smooth="yes"/>
+ <point x="135" y="934"/>
+ <point x="135" y="0"/>
+ <point x="135" y="0" type="curve"/>
+ </contour>
+ <contour>
+ <point x="723" y="1020" type="line"/>
+ <point x="353" y="570" type="line"/>
+ <point x="572" y="528" type="line"/>
+ <point x="1098" y="1020" type="line"/>
+ </contour>
+ <contour>
+ <point x="350" y="570" type="line"/>
+ <point x="761" y="0" type="line"/>
+ <point x="1128" y="0" type="line"/>
+ <point x="540" y="664" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfglyphs2ufo/PsfTest-Bold.ufo/glyphs/L_tnS_mL_.glif b/tests/reference/ufo/psfglyphs2ufo/PsfTest-Bold.ufo/glyphs/L_tnS_mL_.glif
new file mode 100644
index 0000000..0b21294
--- /dev/null
+++ b/tests/reference/ufo/psfglyphs2ufo/PsfTest-Bold.ufo/glyphs/L_tnS_mL_.glif
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmL" format="2">
+ <advance width="640"/>
+ <unicode hex="006C"/>
+ <anchor x="335" y="0" name="H"/>
+ <anchor x="335" y="-100" name="L"/>
+ <anchor x="660" y="1000" name="R"/>
+ <anchor x="320" y="1635" name="U"/>
+ <outline>
+ <contour>
+ <point x="460" y="1600" type="line"/>
+ <point x="160" y="1600" type="line"/>
+ <point x="173" y="1485"/>
+ <point x="180" y="1324"/>
+ <point x="180" y="1130" type="curve" smooth="yes"/>
+ <point x="180" y="0" type="line"/>
+ <point x="480" y="0" type="line"/>
+ <point x="467" y="109"/>
+ <point x="460" y="346"/>
+ <point x="460" y="475" type="curve" smooth="yes"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfglyphs2ufo/PsfTest-Bold.ufo/glyphs/L_tnS_mM_.glif b/tests/reference/ufo/psfglyphs2ufo/PsfTest-Bold.ufo/glyphs/L_tnS_mM_.glif
new file mode 100644
index 0000000..eace489
--- /dev/null
+++ b/tests/reference/ufo/psfglyphs2ufo/PsfTest-Bold.ufo/glyphs/L_tnS_mM_.glif
@@ -0,0 +1,52 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmM" format="2">
+ <advance width="1760"/>
+ <unicode hex="006D"/>
+ <anchor x="890" y="0" name="H"/>
+ <anchor x="890" y="-100" name="L"/>
+ <anchor x="890" y="1100" name="U"/>
+ <outline>
+ <contour>
+ <point x="115" y="1020" type="line"/>
+ <point x="136" y="951"/>
+ <point x="165" y="811"/>
+ <point x="165" y="615" type="curve" smooth="yes"/>
+ <point x="165" y="0" type="line"/>
+ <point x="445" y="0" type="line"/>
+ <point x="445" y="640" type="line"/>
+ <point x="484" y="731"/>
+ <point x="560" y="795"/>
+ <point x="635" y="795" type="curve" smooth="yes"/>
+ <point x="723" y="795"/>
+ <point x="750" y="759"/>
+ <point x="750" y="570" type="curve" smooth="yes"/>
+ <point x="750" y="0" type="line"/>
+ <point x="1030" y="0" type="line"/>
+ <point x="1030" y="660" type="line"/>
+ <point x="1073" y="742"/>
+ <point x="1147" y="795"/>
+ <point x="1220" y="795" type="curve" smooth="yes"/>
+ <point x="1310" y="795"/>
+ <point x="1335" y="751"/>
+ <point x="1335" y="550" type="curve" smooth="yes"/>
+ <point x="1335" y="0" type="line"/>
+ <point x="1615" y="0" type="line"/>
+ <point x="1615" y="660" type="line" smooth="yes"/>
+ <point x="1615" y="907"/>
+ <point x="1548" y="1040"/>
+ <point x="1345" y="1040" type="curve" smooth="yes"/>
+ <point x="1240" y="1040"/>
+ <point x="1131" y="1007"/>
+ <point x="1006" y="872" type="curve"/>
+ <point x="973" y="960"/>
+ <point x="891" y="1040"/>
+ <point x="760" y="1040" type="curve" smooth="yes"/>
+ <point x="644" y="1040"/>
+ <point x="544" y="1008"/>
+ <point x="422" y="875" type="curve"/>
+ <point x="412" y="920"/>
+ <point x="397" y="981"/>
+ <point x="375" y="1020" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfglyphs2ufo/PsfTest-Bold.ufo/glyphs/L_tnS_mN_.glif b/tests/reference/ufo/psfglyphs2ufo/PsfTest-Bold.ufo/glyphs/L_tnS_mN_.glif
new file mode 100644
index 0000000..f7abb6f
--- /dev/null
+++ b/tests/reference/ufo/psfglyphs2ufo/PsfTest-Bold.ufo/glyphs/L_tnS_mN_.glif
@@ -0,0 +1,43 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmN" format="2">
+ <advance width="1245"/>
+ <unicode hex="006E"/>
+ <anchor x="620" y="0" name="H"/>
+ <anchor x="620" y="-100" name="L"/>
+ <anchor x="620" y="1100" name="U"/>
+ <outline>
+ <contour>
+ <point x="1120" y="0" type="line"/>
+ <point x="1120" y="0"/>
+ <point x="1120" y="459"/>
+ <point x="1120" y="625" type="curve" smooth="yes"/>
+ <point x="1120" y="900"/>
+ <point x="998" y="1040"/>
+ <point x="795" y="1040" type="curve" smooth="yes"/>
+ <point x="654" y="1040"/>
+ <point x="537" y="980"/>
+ <point x="410" y="835" type="curve"/>
+ <point x="403" y="881"/>
+ <point x="385" y="980"/>
+ <point x="370" y="1020" type="curve"/>
+ <point x="95" y="1020" type="line"/>
+ <point x="117" y="951"/>
+ <point x="145" y="811"/>
+ <point x="145" y="615" type="curve" smooth="yes"/>
+ <point x="145" y="420"/>
+ <point x="145" y="0"/>
+ <point x="145" y="0" type="curve"/>
+ <point x="425" y="0" type="line"/>
+ <point x="425" y="580" type="line"/>
+ <point x="460" y="683"/>
+ <point x="570" y="795"/>
+ <point x="685" y="795" type="curve" smooth="yes"/>
+ <point x="792" y="795"/>
+ <point x="840" y="734"/>
+ <point x="840" y="550" type="curve" smooth="yes"/>
+ <point x="840" y="413"/>
+ <point x="840" y="0"/>
+ <point x="840" y="0" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfglyphs2ufo/PsfTest-Bold.ufo/glyphs/L_tnS_mO_.glif b/tests/reference/ufo/psfglyphs2ufo/PsfTest-Bold.ufo/glyphs/L_tnS_mO_.glif
new file mode 100644
index 0000000..063c297
--- /dev/null
+++ b/tests/reference/ufo/psfglyphs2ufo/PsfTest-Bold.ufo/glyphs/L_tnS_mO_.glif
@@ -0,0 +1,40 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmO" format="2">
+ <advance width="1160"/>
+ <unicode hex="006F"/>
+ <anchor x="578" y="0" name="H"/>
+ <anchor x="580" y="-100" name="L"/>
+ <anchor x="790" y="0" name="O"/>
+ <anchor x="1160" y="1000" name="R"/>
+ <anchor x="580" y="1100" name="U"/>
+ <outline>
+ <contour>
+ <point x="90" y="507" type="curve" smooth="yes"/>
+ <point x="90" y="163"/>
+ <point x="288" y="-25"/>
+ <point x="570" y="-25" type="curve" smooth="yes"/>
+ <point x="840" y="-25"/>
+ <point x="1070" y="163"/>
+ <point x="1070" y="507" type="curve" smooth="yes"/>
+ <point x="1070" y="851"/>
+ <point x="873" y="1040"/>
+ <point x="590" y="1040" type="curve" smooth="yes"/>
+ <point x="320" y="1040"/>
+ <point x="90" y="851"/>
+ </contour>
+ <contour>
+ <point x="370" y="507" type="curve" smooth="yes"/>
+ <point x="370" y="699"/>
+ <point x="451" y="815"/>
+ <point x="580" y="815" type="curve" smooth="yes"/>
+ <point x="717" y="815"/>
+ <point x="790" y="699"/>
+ <point x="790" y="507" type="curve" smooth="yes"/>
+ <point x="790" y="316"/>
+ <point x="709" y="200"/>
+ <point x="580" y="200" type="curve" smooth="yes"/>
+ <point x="443" y="200"/>
+ <point x="370" y="316"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfglyphs2ufo/PsfTest-Bold.ufo/glyphs/L_tnS_mP_.glif b/tests/reference/ufo/psfglyphs2ufo/PsfTest-Bold.ufo/glyphs/L_tnS_mP_.glif
new file mode 100644
index 0000000..4fe224b
--- /dev/null
+++ b/tests/reference/ufo/psfglyphs2ufo/PsfTest-Bold.ufo/glyphs/L_tnS_mP_.glif
@@ -0,0 +1,59 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmP" format="2">
+ <advance width="1235"/>
+ <unicode hex="0070"/>
+ <anchor x="290" y="-435" name="H"/>
+ <anchor x="640" y="-500" name="L"/>
+ <anchor x="1235" y="1000" name="R"/>
+ <anchor x="640" y="1100" name="U"/>
+ <outline>
+ <contour>
+ <point x="450" y="-490" type="line"/>
+ <point x="433" y="-405"/>
+ <point x="425" y="-310"/>
+ <point x="425" y="-150" type="curve" smooth="yes"/>
+ <point x="425" y="-71"/>
+ <point x="425" y="-41"/>
+ <point x="425" y="65" type="curve"/>
+ <point x="518" y="10"/>
+ <point x="594" y="-25"/>
+ <point x="699" y="-25" type="curve" smooth="yes"/>
+ <point x="945" y="-25"/>
+ <point x="1145" y="193"/>
+ <point x="1145" y="535" type="curve" smooth="yes"/>
+ <point x="1145" y="828"/>
+ <point x="996" y="1040"/>
+ <point x="773" y="1040" type="curve" smooth="yes"/>
+ <point x="628" y="1040"/>
+ <point x="502" y="962"/>
+ <point x="410" y="850" type="curve"/>
+ <point x="401" y="932"/>
+ <point x="385" y="990"/>
+ <point x="370" y="1020" type="curve"/>
+ <point x="95" y="1020" type="line"/>
+ <point x="140" y="907"/>
+ <point x="145" y="734"/>
+ <point x="145" y="485" type="curve" smooth="yes"/>
+ <point x="145" y="291"/>
+ <point x="145" y="-345"/>
+ <point x="145" y="-490" type="curve"/>
+ </contour>
+ <contour>
+ <point x="633" y="206" type="curve" smooth="yes"/>
+ <point x="564" y="206"/>
+ <point x="527" y="225"/>
+ <point x="425" y="300" type="curve"/>
+ <point x="425" y="390"/>
+ <point x="425" y="507"/>
+ <point x="425" y="585" type="curve"/>
+ <point x="482" y="726"/>
+ <point x="583" y="802"/>
+ <point x="672" y="802" type="curve" smooth="yes"/>
+ <point x="793" y="802"/>
+ <point x="865" y="686"/>
+ <point x="865" y="505" type="curve" smooth="yes"/>
+ <point x="865" y="320"/>
+ <point x="755" y="206"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfglyphs2ufo/PsfTest-Bold.ufo/glyphs/L_tnS_mQ_.glif b/tests/reference/ufo/psfglyphs2ufo/PsfTest-Bold.ufo/glyphs/L_tnS_mQ_.glif
new file mode 100644
index 0000000..9727ad7
--- /dev/null
+++ b/tests/reference/ufo/psfglyphs2ufo/PsfTest-Bold.ufo/glyphs/L_tnS_mQ_.glif
@@ -0,0 +1,47 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmQ" format="2">
+ <advance width="1210"/>
+ <unicode hex="0071"/>
+ <anchor x="600" y="-500" name="L"/>
+ <anchor x="1210" y="1000" name="R"/>
+ <anchor x="600" y="1100" name="U"/>
+ <outline>
+ <contour>
+ <point x="790" y="-490" type="line"/>
+ <point x="1095" y="-490" type="line"/>
+ <point x="1078" y="-405"/>
+ <point x="1070" y="-310"/>
+ <point x="1070" y="-150" type="curve" smooth="yes"/>
+ <point x="1070" y="-26"/>
+ <point x="1070" y="965"/>
+ <point x="1070" y="965" type="curve"/>
+ <point x="934" y="1001"/>
+ <point x="773" y="1040"/>
+ <point x="620" y="1040" type="curve" smooth="yes"/>
+ <point x="255" y="1040"/>
+ <point x="100" y="742"/>
+ <point x="100" y="435" type="curve" smooth="yes"/>
+ <point x="100" y="117"/>
+ <point x="316" y="-25"/>
+ <point x="500" y="-25" type="curve" smooth="yes"/>
+ <point x="593" y="-25"/>
+ <point x="686" y="14"/>
+ <point x="790" y="120" type="curve"/>
+ </contour>
+ <contour>
+ <point x="790" y="368" type="line"/>
+ <point x="727" y="258"/>
+ <point x="650" y="203"/>
+ <point x="580" y="203" type="curve" smooth="yes"/>
+ <point x="475" y="203"/>
+ <point x="380" y="287"/>
+ <point x="380" y="485" type="curve" smooth="yes"/>
+ <point x="380" y="641"/>
+ <point x="456" y="802"/>
+ <point x="655" y="802" type="curve" smooth="yes"/>
+ <point x="696" y="802"/>
+ <point x="749" y="789"/>
+ <point x="790" y="770" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfglyphs2ufo/PsfTest-Bold.ufo/glyphs/L_tnS_mR_.glif b/tests/reference/ufo/psfglyphs2ufo/PsfTest-Bold.ufo/glyphs/L_tnS_mR_.glif
new file mode 100644
index 0000000..8a81116
--- /dev/null
+++ b/tests/reference/ufo/psfglyphs2ufo/PsfTest-Bold.ufo/glyphs/L_tnS_mR_.glif
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmR" format="2">
+ <advance width="995"/>
+ <unicode hex="0072"/>
+ <anchor x="285" y="0" name="H"/>
+ <anchor x="275" y="-100" name="L"/>
+ <anchor x="550" y="1100" name="U"/>
+ <outline>
+ <contour>
+ <point x="425" y="0" type="line"/>
+ <point x="425" y="530" type="line"/>
+ <point x="460" y="654"/>
+ <point x="570" y="781"/>
+ <point x="637" y="781" type="curve" smooth="yes"/>
+ <point x="722" y="781"/>
+ <point x="755" y="721"/>
+ <point x="762" y="630" type="curve"/>
+ <point x="985" y="665" type="line"/>
+ <point x="985" y="868"/>
+ <point x="913" y="1040"/>
+ <point x="725" y="1040" type="curve" smooth="yes"/>
+ <point x="634" y="1040"/>
+ <point x="507" y="964"/>
+ <point x="410" y="825" type="curve"/>
+ <point x="403" y="873"/>
+ <point x="385" y="978"/>
+ <point x="370" y="1020" type="curve"/>
+ <point x="95" y="1020" type="line"/>
+ <point x="117" y="951"/>
+ <point x="145" y="811"/>
+ <point x="145" y="615" type="curve" smooth="yes"/>
+ <point x="145" y="0" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfglyphs2ufo/PsfTest-Bold.ufo/glyphs/L_tnS_mS_.glif b/tests/reference/ufo/psfglyphs2ufo/PsfTest-Bold.ufo/glyphs/L_tnS_mS_.glif
new file mode 100644
index 0000000..06b1a9a
--- /dev/null
+++ b/tests/reference/ufo/psfglyphs2ufo/PsfTest-Bold.ufo/glyphs/L_tnS_mS_.glif
@@ -0,0 +1,50 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmS" format="2">
+ <advance width="1035"/>
+ <unicode hex="0073"/>
+ <anchor x="515" y="0" name="H"/>
+ <anchor x="515" y="-100" name="L"/>
+ <anchor x="530" y="1100" name="U"/>
+ <outline>
+ <contour>
+ <point x="905" y="960" type="line"/>
+ <point x="827" y="998"/>
+ <point x="708" y="1040"/>
+ <point x="545" y="1040" type="curve" smooth="yes"/>
+ <point x="202" y="1040"/>
+ <point x="110" y="818"/>
+ <point x="110" y="720" type="curve" smooth="yes"/>
+ <point x="110" y="594"/>
+ <point x="171" y="491"/>
+ <point x="455" y="432" type="curve" smooth="yes"/>
+ <point x="646" y="390"/>
+ <point x="690" y="348"/>
+ <point x="690" y="290" type="curve" smooth="yes"/>
+ <point x="690" y="243"/>
+ <point x="624" y="199"/>
+ <point x="530" y="199" type="curve" smooth="yes"/>
+ <point x="413" y="199"/>
+ <point x="254" y="253"/>
+ <point x="155" y="334" type="curve"/>
+ <point x="100" y="90" type="line"/>
+ <point x="187" y="28"/>
+ <point x="346" y="-25"/>
+ <point x="525" y="-25" type="curve" smooth="yes"/>
+ <point x="768" y="-25"/>
+ <point x="960" y="123"/>
+ <point x="960" y="315" type="curve" smooth="yes"/>
+ <point x="960" y="504"/>
+ <point x="788" y="583"/>
+ <point x="580" y="625" type="curve" smooth="yes"/>
+ <point x="405" y="659"/>
+ <point x="380" y="681"/>
+ <point x="380" y="730" type="curve" smooth="yes"/>
+ <point x="380" y="770"/>
+ <point x="418" y="816"/>
+ <point x="535" y="816" type="curve" smooth="yes"/>
+ <point x="674" y="816"/>
+ <point x="791" y="760"/>
+ <point x="866" y="721" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfglyphs2ufo/PsfTest-Bold.ufo/glyphs/L_tnS_mT_.glif b/tests/reference/ufo/psfglyphs2ufo/PsfTest-Bold.ufo/glyphs/L_tnS_mT_.glif
new file mode 100644
index 0000000..d4123c7
--- /dev/null
+++ b/tests/reference/ufo/psfglyphs2ufo/PsfTest-Bold.ufo/glyphs/L_tnS_mT_.glif
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmT" format="2">
+ <advance width="885"/>
+ <unicode hex="0074"/>
+ <anchor x="530" y="0" name="H"/>
+ <anchor x="530" y="-100" name="L"/>
+ <anchor x="885" y="1000" name="R"/>
+ <anchor x="360" y="1360" name="U"/>
+ <outline>
+ <contour>
+ <point x="220" y="270" type="line"/>
+ <point x="220" y="39"/>
+ <point x="374" y="-25"/>
+ <point x="563" y="-25" type="curve" smooth="yes"/>
+ <point x="635" y="-25"/>
+ <point x="725" y="-3"/>
+ <point x="820" y="57" type="curve"/>
+ <point x="820" y="281" type="line"/>
+ <point x="741" y="232"/>
+ <point x="678" y="206"/>
+ <point x="627" y="206" type="curve" smooth="yes"/>
+ <point x="537" y="206"/>
+ <point x="500" y="235"/>
+ <point x="500" y="462" type="curve" smooth="yes"/>
+ <point x="500" y="1320" type="line"/>
+ <point x="220" y="1320" type="line"/>
+ </contour>
+ <contour>
+ <point x="805" y="805" type="line"/>
+ <point x="805" y="1005" type="line"/>
+ <point x="30" y="1005" type="line"/>
+ <point x="30" y="805" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfglyphs2ufo/PsfTest-Bold.ufo/glyphs/L_tnS_mU_.glif b/tests/reference/ufo/psfglyphs2ufo/PsfTest-Bold.ufo/glyphs/L_tnS_mU_.glif
new file mode 100644
index 0000000..5b8d434
--- /dev/null
+++ b/tests/reference/ufo/psfglyphs2ufo/PsfTest-Bold.ufo/glyphs/L_tnS_mU_.glif
@@ -0,0 +1,51 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmU" format="2">
+ <advance width="1245"/>
+ <unicode hex="0075"/>
+ <anchor x="515" y="0" name="H"/>
+ <anchor x="615" y="-100" name="L"/>
+ <anchor x="690" y="0" name="O"/>
+ <anchor x="1258" y="1000" name="R"/>
+ <anchor x="615" y="1100" name="U"/>
+ <outline>
+ <contour>
+ <point x="1160" y="0" type="line"/>
+ <point x="1118" y="112"/>
+ <point x="1095" y="256"/>
+ <point x="1095" y="450" type="curve" smooth="yes"/>
+ <point x="1095" y="646"/>
+ <point x="1095" y="1020"/>
+ <point x="1095" y="1020" type="curve"/>
+ <point x="795" y="1020" type="line"/>
+ <point x="813" y="898"/>
+ <point x="815" y="832"/>
+ <point x="815" y="700" type="curve" smooth="yes"/>
+ <point x="815" y="418" type="line"/>
+ <point x="774" y="326"/>
+ <point x="651" y="206"/>
+ <point x="560" y="206" type="curve" smooth="yes"/>
+ <point x="458" y="206"/>
+ <point x="425" y="284"/>
+ <point x="425" y="465" type="curve" smooth="yes"/>
+ <point x="425" y="603"/>
+ <point x="425" y="1020"/>
+ <point x="425" y="1020" type="curve"/>
+ <point x="125" y="1020" type="line"/>
+ <point x="143" y="900"/>
+ <point x="145" y="827"/>
+ <point x="145" y="700" type="curve" smooth="yes"/>
+ <point x="145" y="681"/>
+ <point x="145" y="424"/>
+ <point x="145" y="405" type="curve" smooth="yes"/>
+ <point x="145" y="120"/>
+ <point x="250" y="-25"/>
+ <point x="458" y="-25" type="curve" smooth="yes"/>
+ <point x="595" y="-25"/>
+ <point x="722" y="48"/>
+ <point x="840" y="185" type="curve"/>
+ <point x="850" y="116"/>
+ <point x="876" y="43"/>
+ <point x="895" y="0" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfglyphs2ufo/PsfTest-Bold.ufo/glyphs/L_tnS_mV_.glif b/tests/reference/ufo/psfglyphs2ufo/PsfTest-Bold.ufo/glyphs/L_tnS_mV_.glif
new file mode 100644
index 0000000..daf1468
--- /dev/null
+++ b/tests/reference/ufo/psfglyphs2ufo/PsfTest-Bold.ufo/glyphs/L_tnS_mV_.glif
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmV" format="2">
+ <advance width="1104"/>
+ <unicode hex="0076"/>
+ <anchor x="565" y="0" name="H"/>
+ <anchor x="565" y="-100" name="L"/>
+ <anchor x="750" y="0" name="O"/>
+ <anchor x="565" y="1100" name="U"/>
+ <outline>
+ <contour>
+ <point x="786" y="1020" type="line"/>
+ <point x="556" y="290" type="line"/>
+ <point x="322" y="1020" type="line"/>
+ <point x="10" y="1020" type="line"/>
+ <point x="65" y="905"/>
+ <point x="133" y="746"/>
+ <point x="165" y="665" type="curve" smooth="yes"/>
+ <point x="227" y="510"/>
+ <point x="430" y="0"/>
+ <point x="430" y="0" type="curve"/>
+ <point x="674" y="0" type="line"/>
+ <point x="674" y="0"/>
+ <point x="886" y="536"/>
+ <point x="939" y="665" type="curve" smooth="yes"/>
+ <point x="972" y="744"/>
+ <point x="1037" y="905"/>
+ <point x="1094" y="1020" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfglyphs2ufo/PsfTest-Bold.ufo/glyphs/L_tnS_mW_.glif b/tests/reference/ufo/psfglyphs2ufo/PsfTest-Bold.ufo/glyphs/L_tnS_mW_.glif
new file mode 100644
index 0000000..1ca1ec4
--- /dev/null
+++ b/tests/reference/ufo/psfglyphs2ufo/PsfTest-Bold.ufo/glyphs/L_tnS_mW_.glif
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmW" format="2">
+ <advance width="1570"/>
+ <unicode hex="0077"/>
+ <anchor x="785" y="-100" name="L"/>
+ <anchor x="785" y="1100" name="U"/>
+ <outline>
+ <contour>
+ <point x="665" y="1020" type="line"/>
+ <point x="480" y="285" type="line"/>
+ <point x="323" y="1020" type="line"/>
+ <point x="35" y="1020" type="line"/>
+ <point x="82" y="867"/>
+ <point x="110" y="771"/>
+ <point x="140" y="665" type="curve" smooth="yes"/>
+ <point x="325" y="0" type="line"/>
+ <point x="615" y="0" type="line"/>
+ <point x="785" y="695" type="line"/>
+ <point x="955" y="0" type="line"/>
+ <point x="1245" y="0" type="line"/>
+ <point x="1430" y="665" type="line" smooth="yes"/>
+ <point x="1464" y="785"/>
+ <point x="1488" y="868"/>
+ <point x="1535" y="1020" type="curve"/>
+ <point x="1247" y="1020" type="line"/>
+ <point x="1090" y="285" type="line"/>
+ <point x="905" y="1020" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfglyphs2ufo/PsfTest-Bold.ufo/glyphs/L_tnS_mX_.glif b/tests/reference/ufo/psfglyphs2ufo/PsfTest-Bold.ufo/glyphs/L_tnS_mX_.glif
new file mode 100644
index 0000000..971c129
--- /dev/null
+++ b/tests/reference/ufo/psfglyphs2ufo/PsfTest-Bold.ufo/glyphs/L_tnS_mX_.glif
@@ -0,0 +1,40 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmX" format="2">
+ <advance width="1185"/>
+ <unicode hex="0078"/>
+ <anchor x="960" y="0" name="H"/>
+ <anchor x="590" y="-100" name="L"/>
+ <anchor x="615" y="1100" name="U"/>
+ <outline>
+ <contour>
+ <point x="815" y="0" type="line"/>
+ <point x="1145" y="0" type="line"/>
+ <point x="1037" y="129"/>
+ <point x="989" y="190"/>
+ <point x="930" y="270" type="curve" smooth="yes"/>
+ <point x="380" y="1020" type="line"/>
+ <point x="50" y="1020" type="line"/>
+ <point x="158" y="887"/>
+ <point x="192" y="842"/>
+ <point x="260" y="750" type="curve" smooth="yes"/>
+ </contour>
+ <contour>
+ <point x="499" y="616" type="line"/>
+ <point x="245" y="270" type="line" smooth="yes"/>
+ <point x="195" y="201"/>
+ <point x="150" y="143"/>
+ <point x="40" y="0" type="curve"/>
+ <point x="345" y="0" type="line"/>
+ <point x="584" y="359" type="line"/>
+ </contour>
+ <contour>
+ <point x="675" y="405" type="line"/>
+ <point x="925" y="750" type="line" smooth="yes"/>
+ <point x="980" y="826"/>
+ <point x="1027" y="886"/>
+ <point x="1130" y="1020" type="curve"/>
+ <point x="825" y="1020" type="line"/>
+ <point x="595" y="668" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfglyphs2ufo/PsfTest-Bold.ufo/glyphs/L_tnS_mY_.glif b/tests/reference/ufo/psfglyphs2ufo/PsfTest-Bold.ufo/glyphs/L_tnS_mY_.glif
new file mode 100644
index 0000000..ea8d25e
--- /dev/null
+++ b/tests/reference/ufo/psfglyphs2ufo/PsfTest-Bold.ufo/glyphs/L_tnS_mY_.glif
@@ -0,0 +1,39 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmY" format="2">
+ <advance width="1100"/>
+ <unicode hex="0079"/>
+ <anchor x="845" y="-100" name="L"/>
+ <anchor x="1155" y="1000" name="R"/>
+ <anchor x="565" y="1100" name="U"/>
+ <outline>
+ <contour>
+ <point x="945" y="665" type="line" smooth="yes"/>
+ <point x="978" y="758"/>
+ <point x="1021" y="865"/>
+ <point x="1090" y="1020" type="curve"/>
+ <point x="777" y="1020" type="line"/>
+ <point x="777" y="1020"/>
+ <point x="646" y="549"/>
+ <point x="573" y="293" type="curve"/>
+ <point x="333" y="1020" type="line"/>
+ <point x="20" y="1020" type="line"/>
+ <point x="97" y="864"/>
+ <point x="144" y="757"/>
+ <point x="180" y="665" type="curve" smooth="yes"/>
+ <point x="445" y="-18" type="line"/>
+ <point x="366" y="-209"/>
+ <point x="304" y="-242"/>
+ <point x="245" y="-242" type="curve" smooth="yes"/>
+ <point x="179" y="-242"/>
+ <point x="102" y="-202"/>
+ <point x="60" y="-167" type="curve"/>
+ <point x="-10" y="-385" type="line"/>
+ <point x="63" y="-439"/>
+ <point x="154" y="-470"/>
+ <point x="245" y="-470" type="curve" smooth="yes"/>
+ <point x="427" y="-470"/>
+ <point x="565" y="-387"/>
+ <point x="705" y="0" type="curve" smooth="yes"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfglyphs2ufo/PsfTest-Bold.ufo/glyphs/N_onB_reakingH_yphen.glif b/tests/reference/ufo/psfglyphs2ufo/PsfTest-Bold.ufo/glyphs/N_onB_reakingH_yphen.glif
new file mode 100644
index 0000000..7dc67c0
--- /dev/null
+++ b/tests/reference/ufo/psfglyphs2ufo/PsfTest-Bold.ufo/glyphs/N_onB_reakingH_yphen.glif
@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="NonBreakingHyphen" format="2">
+ <advance width="895"/>
+ <unicode hex="2011"/>
+ <anchor x="450" y="1100" name="U"/>
+ <outline>
+ <component base="HyphenMinus"/>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfglyphs2ufo/PsfTest-Bold.ufo/glyphs/N_umS_gn.glif b/tests/reference/ufo/psfglyphs2ufo/PsfTest-Bold.ufo/glyphs/N_umS_gn.glif
new file mode 100644
index 0000000..54b82cb
--- /dev/null
+++ b/tests/reference/ufo/psfglyphs2ufo/PsfTest-Bold.ufo/glyphs/N_umS_gn.glif
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="NumSgn" format="2">
+ <advance width="1200"/>
+ <unicode hex="0023"/>
+ <outline>
+ <contour>
+ <point x="412" y="1360" type="line"/>
+ <point x="52" y="100" type="line"/>
+ <point x="272" y="100" type="line"/>
+ <point x="632" y="1360" type="line"/>
+ </contour>
+ <contour>
+ <point x="10" y="425" type="line"/>
+ <point x="1101" y="425" type="line"/>
+ <point x="1101" y="635" type="line"/>
+ <point x="10" y="635" type="line"/>
+ </contour>
+ <contour>
+ <point x="69" y="850" type="line"/>
+ <point x="1160" y="850" type="line"/>
+ <point x="1160" y="1060" type="line"/>
+ <point x="69" y="1060" type="line"/>
+ </contour>
+ <contour>
+ <point x="887" y="1360" type="line"/>
+ <point x="527" y="100" type="line"/>
+ <point x="747" y="100" type="line"/>
+ <point x="1107" y="1360" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfglyphs2ufo/PsfTest-Bold.ufo/glyphs/P_ercentS_gn.glif b/tests/reference/ufo/psfglyphs2ufo/PsfTest-Bold.ufo/glyphs/P_ercentS_gn.glif
new file mode 100644
index 0000000..5017543
--- /dev/null
+++ b/tests/reference/ufo/psfglyphs2ufo/PsfTest-Bold.ufo/glyphs/P_ercentS_gn.glif
@@ -0,0 +1,69 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="PercentSgn" format="2">
+ <advance width="1565"/>
+ <unicode hex="0025"/>
+ <outline>
+ <contour>
+ <point x="1073" y="1480" type="line"/>
+ <point x="291" y="-25" type="line"/>
+ <point x="499" y="-25" type="line"/>
+ <point x="1279" y="1480" type="line"/>
+ </contour>
+ <contour>
+ <point x="511" y="1076" type="curve" smooth="yes"/>
+ <point x="511" y="892"/>
+ <point x="470" y="815"/>
+ <point x="394" y="815" type="curve" smooth="yes"/>
+ <point x="315" y="815"/>
+ <point x="279" y="891"/>
+ <point x="279" y="1091" type="curve" smooth="yes"/>
+ <point x="279" y="1275"/>
+ <point x="317" y="1350"/>
+ <point x="394" y="1350" type="curve" smooth="yes"/>
+ <point x="475" y="1350"/>
+ <point x="511" y="1276"/>
+ </contour>
+ <contour>
+ <point x="721" y="1089" type="curve" smooth="yes"/>
+ <point x="721" y="1362"/>
+ <point x="584" y="1480"/>
+ <point x="399" y="1480" type="curve" smooth="yes"/>
+ <point x="215" y="1480"/>
+ <point x="69" y="1360"/>
+ <point x="69" y="1078" type="curve" smooth="yes"/>
+ <point x="69" y="796"/>
+ <point x="205" y="685"/>
+ <point x="390" y="685" type="curve" smooth="yes"/>
+ <point x="575" y="685"/>
+ <point x="721" y="794"/>
+ </contour>
+ <contour>
+ <point x="1286" y="366" type="curve" smooth="yes"/>
+ <point x="1286" y="182"/>
+ <point x="1245" y="105"/>
+ <point x="1169" y="105" type="curve" smooth="yes"/>
+ <point x="1090" y="105"/>
+ <point x="1054" y="181"/>
+ <point x="1054" y="381" type="curve" smooth="yes"/>
+ <point x="1054" y="565"/>
+ <point x="1092" y="640"/>
+ <point x="1169" y="640" type="curve" smooth="yes"/>
+ <point x="1250" y="640"/>
+ <point x="1286" y="566"/>
+ </contour>
+ <contour>
+ <point x="1496" y="379" type="curve" smooth="yes"/>
+ <point x="1496" y="652"/>
+ <point x="1359" y="770"/>
+ <point x="1174" y="770" type="curve" smooth="yes"/>
+ <point x="990" y="770"/>
+ <point x="844" y="650"/>
+ <point x="844" y="368" type="curve" smooth="yes"/>
+ <point x="844" y="86"/>
+ <point x="980" y="-25"/>
+ <point x="1165" y="-25" type="curve" smooth="yes"/>
+ <point x="1350" y="-25"/>
+ <point x="1496" y="84"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfglyphs2ufo/PsfTest-Bold.ufo/glyphs/P_lusS_gn.glif b/tests/reference/ufo/psfglyphs2ufo/PsfTest-Bold.ufo/glyphs/P_lusS_gn.glif
new file mode 100644
index 0000000..a1a4c93
--- /dev/null
+++ b/tests/reference/ufo/psfglyphs2ufo/PsfTest-Bold.ufo/glyphs/P_lusS_gn.glif
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="PlusSgn" format="2">
+ <advance width="1200"/>
+ <unicode hex="002B"/>
+ <outline>
+ <contour>
+ <point x="495" y="1180" type="line"/>
+ <point x="495" y="285" type="line"/>
+ <point x="705" y="285" type="line"/>
+ <point x="705" y="1180" type="line"/>
+ </contour>
+ <contour>
+ <point x="155" y="630" type="line"/>
+ <point x="1045" y="630" type="line"/>
+ <point x="1045" y="840" type="line"/>
+ <point x="155" y="840" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfglyphs2ufo/PsfTest-Bold.ufo/glyphs/Q_stnM_rk.glif b/tests/reference/ufo/psfglyphs2ufo/PsfTest-Bold.ufo/glyphs/Q_stnM_rk.glif
new file mode 100644
index 0000000..c9bbb28
--- /dev/null
+++ b/tests/reference/ufo/psfglyphs2ufo/PsfTest-Bold.ufo/glyphs/Q_stnM_rk.glif
@@ -0,0 +1,49 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="QstnMrk" format="2">
+ <advance width="1090"/>
+ <unicode hex="003F"/>
+ <outline>
+ <contour>
+ <point x="640" y="500" type="line"/>
+ <point x="640" y="671"/>
+ <point x="668" y="805"/>
+ <point x="767" y="956" type="curve" smooth="yes"/>
+ <point x="837" y="1063"/>
+ <point x="900" y="1117"/>
+ <point x="900" y="1220" type="curve" smooth="yes"/>
+ <point x="900" y="1402"/>
+ <point x="757" y="1540"/>
+ <point x="500" y="1540" type="curve" smooth="yes"/>
+ <point x="355" y="1540"/>
+ <point x="206" y="1470"/>
+ <point x="140" y="1407" type="curve"/>
+ <point x="185" y="1168" type="line"/>
+ <point x="261" y="1247"/>
+ <point x="372" y="1295"/>
+ <point x="472" y="1295" type="curve" smooth="yes"/>
+ <point x="569" y="1295"/>
+ <point x="615" y="1249"/>
+ <point x="615" y="1190" type="curve" smooth="yes"/>
+ <point x="615" y="1139"/>
+ <point x="565" y="1096"/>
+ <point x="495" y="980" type="curve" smooth="yes"/>
+ <point x="434" y="879"/>
+ <point x="375" y="710"/>
+ <point x="375" y="500" type="curve"/>
+ </contour>
+ <contour>
+ <point x="335" y="150" type="curve" smooth="yes"/>
+ <point x="335" y="46"/>
+ <point x="409" y="-25"/>
+ <point x="510" y="-25" type="curve" smooth="yes"/>
+ <point x="612" y="-25"/>
+ <point x="685" y="46"/>
+ <point x="685" y="150" type="curve" smooth="yes"/>
+ <point x="685" y="252"/>
+ <point x="612" y="325"/>
+ <point x="510" y="325" type="curve" smooth="yes"/>
+ <point x="409" y="325"/>
+ <point x="335" y="252"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfglyphs2ufo/PsfTest-Bold.ufo/glyphs/Q_uotM_rk.glif b/tests/reference/ufo/psfglyphs2ufo/PsfTest-Bold.ufo/glyphs/Q_uotM_rk.glif
new file mode 100644
index 0000000..794a655
--- /dev/null
+++ b/tests/reference/ufo/psfglyphs2ufo/PsfTest-Bold.ufo/glyphs/Q_uotM_rk.glif
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="QuotMrk" format="2">
+ <advance width="1085"/>
+ <unicode hex="0022"/>
+ <outline>
+ <contour>
+ <point x="450" y="1045" type="line"/>
+ <point x="455" y="1186"/>
+ <point x="456" y="1339"/>
+ <point x="485" y="1585" type="curve"/>
+ <point x="240" y="1585" type="line"/>
+ <point x="271" y="1339"/>
+ <point x="271" y="1186"/>
+ <point x="275" y="1045" type="curve"/>
+ </contour>
+ <contour>
+ <point x="810" y="1045" type="line"/>
+ <point x="815" y="1186"/>
+ <point x="816" y="1339"/>
+ <point x="845" y="1585" type="curve"/>
+ <point x="600" y="1585" type="line"/>
+ <point x="631" y="1339"/>
+ <point x="631" y="1186"/>
+ <point x="635" y="1045" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfglyphs2ufo/PsfTest-Bold.ufo/glyphs/R_everseS_olidus.glif b/tests/reference/ufo/psfglyphs2ufo/PsfTest-Bold.ufo/glyphs/R_everseS_olidus.glif
new file mode 100644
index 0000000..799c999
--- /dev/null
+++ b/tests/reference/ufo/psfglyphs2ufo/PsfTest-Bold.ufo/glyphs/R_everseS_olidus.glif
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="ReverseSolidus" format="2">
+ <advance width="1080"/>
+ <unicode hex="005C"/>
+ <outline>
+ <contour>
+ <point x="10" y="1600" type="line"/>
+ <point x="840" y="-245" type="line"/>
+ <point x="1070" y="-245" type="line"/>
+ <point x="240" y="1600" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfglyphs2ufo/PsfTest-Bold.ufo/glyphs/R_tC_urlyB_rac.glif b/tests/reference/ufo/psfglyphs2ufo/PsfTest-Bold.ufo/glyphs/R_tC_urlyB_rac.glif
new file mode 100644
index 0000000..48383fb
--- /dev/null
+++ b/tests/reference/ufo/psfglyphs2ufo/PsfTest-Bold.ufo/glyphs/R_tC_urlyB_rac.glif
@@ -0,0 +1,47 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="RtCurlyBrac" format="2">
+ <advance width="1040"/>
+ <unicode hex="007D"/>
+ <outline>
+ <contour>
+ <point x="180" y="-410" type="line"/>
+ <point x="316" y="-383"/>
+ <point x="520" y="-333"/>
+ <point x="570" y="-285" type="curve" smooth="yes"/>
+ <point x="645" y="-213"/>
+ <point x="633" y="378"/>
+ <point x="655" y="410" type="curve" smooth="yes"/>
+ <point x="685" y="453"/>
+ <point x="855" y="560"/>
+ <point x="855" y="615" type="curve" smooth="yes"/>
+ <point x="855" y="670"/>
+ <point x="685" y="777"/>
+ <point x="655" y="820" type="curve" smooth="yes"/>
+ <point x="633" y="852"/>
+ <point x="644" y="1442"/>
+ <point x="570" y="1515" type="curve" smooth="yes"/>
+ <point x="523" y="1562"/>
+ <point x="333" y="1613"/>
+ <point x="205" y="1640" type="curve"/>
+ <point x="155" y="1409" type="line"/>
+ <point x="218" y="1390"/>
+ <point x="323" y="1351"/>
+ <point x="340" y="1330" type="curve" smooth="yes"/>
+ <point x="375" y="1289"/>
+ <point x="364" y="820"/>
+ <point x="382" y="785" type="curve" smooth="yes"/>
+ <point x="405" y="740"/>
+ <point x="542" y="650"/>
+ <point x="542" y="615" type="curve" smooth="yes"/>
+ <point x="542" y="580"/>
+ <point x="404" y="491"/>
+ <point x="380" y="445" type="curve" smooth="yes"/>
+ <point x="362" y="411"/>
+ <point x="375" y="-60"/>
+ <point x="340" y="-100" type="curve" smooth="yes"/>
+ <point x="321" y="-122"/>
+ <point x="197" y="-160"/>
+ <point x="130" y="-179" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfglyphs2ufo/PsfTest-Bold.ufo/glyphs/R_tP_aren.glif b/tests/reference/ufo/psfglyphs2ufo/PsfTest-Bold.ufo/glyphs/R_tP_aren.glif
new file mode 100644
index 0000000..ae49fca
--- /dev/null
+++ b/tests/reference/ufo/psfglyphs2ufo/PsfTest-Bold.ufo/glyphs/R_tP_aren.glif
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="RtParen" format="2">
+ <advance width="860"/>
+ <unicode hex="0029"/>
+ <outline>
+ <contour>
+ <point x="185" y="1455" type="line"/>
+ <point x="395" y="1261"/>
+ <point x="485" y="938"/>
+ <point x="485" y="635" type="curve" smooth="yes"/>
+ <point x="485" y="335"/>
+ <point x="399" y="11"/>
+ <point x="175" y="-240" type="curve"/>
+ <point x="326" y="-410" type="line"/>
+ <point x="601" y="-125"/>
+ <point x="746" y="218"/>
+ <point x="746" y="625" type="curve" smooth="yes"/>
+ <point x="746" y="1062"/>
+ <point x="571" y="1444"/>
+ <point x="306" y="1640" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfglyphs2ufo/PsfTest-Bold.ufo/glyphs/R_tS_qrB_rac.glif b/tests/reference/ufo/psfglyphs2ufo/PsfTest-Bold.ufo/glyphs/R_tS_qrB_rac.glif
new file mode 100644
index 0000000..325e575
--- /dev/null
+++ b/tests/reference/ufo/psfglyphs2ufo/PsfTest-Bold.ufo/glyphs/R_tS_qrB_rac.glif
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="RtSqrBrac" format="2">
+ <advance width="850"/>
+ <unicode hex="005D"/>
+ <outline>
+ <contour>
+ <point x="660" y="-410" type="line"/>
+ <point x="660" y="1600" type="line"/>
+ <point x="140" y="1600" type="line"/>
+ <point x="140" y="1390" type="line"/>
+ <point x="380" y="1390" type="line"/>
+ <point x="380" y="-200" type="line"/>
+ <point x="140" y="-200" type="line"/>
+ <point x="140" y="-410" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfglyphs2ufo/PsfTest-Bold.ufo/glyphs/S_emicolon.glif b/tests/reference/ufo/psfglyphs2ufo/PsfTest-Bold.ufo/glyphs/S_emicolon.glif
new file mode 100644
index 0000000..ae95657
--- /dev/null
+++ b/tests/reference/ufo/psfglyphs2ufo/PsfTest-Bold.ufo/glyphs/S_emicolon.glif
@@ -0,0 +1,38 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="Semicolon" format="2">
+ <advance width="710"/>
+ <unicode hex="003B"/>
+ <outline>
+ <contour>
+ <point x="200" y="750" type="curve" smooth="yes"/>
+ <point x="200" y="646"/>
+ <point x="274" y="575"/>
+ <point x="375" y="575" type="curve" smooth="yes"/>
+ <point x="477" y="575"/>
+ <point x="550" y="646"/>
+ <point x="550" y="750" type="curve" smooth="yes"/>
+ <point x="550" y="852"/>
+ <point x="477" y="925"/>
+ <point x="375" y="925" type="curve" smooth="yes"/>
+ <point x="274" y="925"/>
+ <point x="200" y="852"/>
+ </contour>
+ <contour>
+ <point x="185" y="50" type="line"/>
+ <point x="345" y="50" type="line"/>
+ <point x="345" y="-34"/>
+ <point x="290" y="-153"/>
+ <point x="185" y="-265" type="curve"/>
+ <point x="330" y="-335" type="line"/>
+ <point x="454" y="-228"/>
+ <point x="560" y="-49"/>
+ <point x="560" y="130" type="curve" smooth="yes"/>
+ <point x="560" y="254"/>
+ <point x="489" y="340"/>
+ <point x="375" y="340" type="curve" smooth="yes"/>
+ <point x="262" y="340"/>
+ <point x="185" y="255"/>
+ <point x="185" y="180" type="curve" smooth="yes"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfglyphs2ufo/PsfTest-Bold.ufo/glyphs/S_olidus.glif b/tests/reference/ufo/psfglyphs2ufo/PsfTest-Bold.ufo/glyphs/S_olidus.glif
new file mode 100644
index 0000000..1e33c05
--- /dev/null
+++ b/tests/reference/ufo/psfglyphs2ufo/PsfTest-Bold.ufo/glyphs/S_olidus.glif
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="Solidus" format="2">
+ <advance width="1080"/>
+ <unicode hex="002F"/>
+ <outline>
+ <contour>
+ <point x="840" y="1600" type="line"/>
+ <point x="10" y="-245" type="line"/>
+ <point x="240" y="-245" type="line"/>
+ <point x="1070" y="1600" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfglyphs2ufo/PsfTest-Bold.ufo/glyphs/S_pace.glif b/tests/reference/ufo/psfglyphs2ufo/PsfTest-Bold.ufo/glyphs/S_pace.glif
new file mode 100644
index 0000000..ef0bed7
--- /dev/null
+++ b/tests/reference/ufo/psfglyphs2ufo/PsfTest-Bold.ufo/glyphs/S_pace.glif
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="Space" format="2">
+ <advance width="550"/>
+ <unicode hex="0020"/>
+ <outline/>
+</glyph>
diff --git a/tests/reference/ufo/psfglyphs2ufo/PsfTest-Bold.ufo/glyphs/T_ilde.glif b/tests/reference/ufo/psfglyphs2ufo/PsfTest-Bold.ufo/glyphs/T_ilde.glif
new file mode 100644
index 0000000..ec9fc73
--- /dev/null
+++ b/tests/reference/ufo/psfglyphs2ufo/PsfTest-Bold.ufo/glyphs/T_ilde.glif
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="Tilde" format="2">
+ <advance width="1115"/>
+ <unicode hex="007E"/>
+ <outline>
+ <contour>
+ <point x="165" y="345" type="line"/>
+ <point x="170" y="394"/>
+ <point x="202" y="435"/>
+ <point x="280" y="435" type="curve" smooth="yes"/>
+ <point x="435" y="435"/>
+ <point x="615" y="330"/>
+ <point x="825" y="330" type="curve" smooth="yes"/>
+ <point x="984" y="330"/>
+ <point x="1080" y="512"/>
+ <point x="1080" y="640" type="curve"/>
+ <point x="935" y="640" type="line"/>
+ <point x="928" y="594"/>
+ <point x="898" y="540"/>
+ <point x="815" y="540" type="curve" smooth="yes"/>
+ <point x="599" y="540"/>
+ <point x="461" y="645"/>
+ <point x="260" y="645" type="curve" smooth="yes"/>
+ <point x="104" y="645"/>
+ <point x="20" y="467"/>
+ <point x="20" y="345" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfglyphs2ufo/PsfTest-Bold.ufo/glyphs/V_ertL_ine.glif b/tests/reference/ufo/psfglyphs2ufo/PsfTest-Bold.ufo/glyphs/V_ertL_ine.glif
new file mode 100644
index 0000000..d7caa84
--- /dev/null
+++ b/tests/reference/ufo/psfglyphs2ufo/PsfTest-Bold.ufo/glyphs/V_ertL_ine.glif
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="VertLine" format="2">
+ <advance width="690"/>
+ <unicode hex="007C"/>
+ <outline>
+ <contour>
+ <point x="240" y="1600" type="line"/>
+ <point x="240" y="-390" type="line"/>
+ <point x="450" y="-390" type="line"/>
+ <point x="450" y="1600" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfglyphs2ufo/PsfTest-Bold.ufo/glyphs/_notdef.glif b/tests/reference/ufo/psfglyphs2ufo/PsfTest-Bold.ufo/glyphs/_notdef.glif
new file mode 100644
index 0000000..a3e9354
--- /dev/null
+++ b/tests/reference/ufo/psfglyphs2ufo/PsfTest-Bold.ufo/glyphs/_notdef.glif
@@ -0,0 +1,18 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name=".notdef" format="2">
+ <advance width="1400"/>
+ <outline>
+ <contour>
+ <point x="100" y="0" type="line"/>
+ <point x="1300" y="0" type="line"/>
+ <point x="1300" y="1800" type="line"/>
+ <point x="100" y="1800" type="line"/>
+ </contour>
+ <contour>
+ <point x="150" y="1750" type="line"/>
+ <point x="1250" y="1750" type="line"/>
+ <point x="1250" y="50" type="line"/>
+ <point x="150" y="50" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfglyphs2ufo/PsfTest-Bold.ufo/glyphs/_null.glif b/tests/reference/ufo/psfglyphs2ufo/PsfTest-Bold.ufo/glyphs/_null.glif
new file mode 100644
index 0000000..0b9caa6
--- /dev/null
+++ b/tests/reference/ufo/psfglyphs2ufo/PsfTest-Bold.ufo/glyphs/_null.glif
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name=".null" format="2">
+ <outline/>
+</glyph>
diff --git a/tests/reference/ufo/psfglyphs2ufo/PsfTest-Bold.ufo/glyphs/contents.plist b/tests/reference/ufo/psfglyphs2ufo/PsfTest-Bold.ufo/glyphs/contents.plist
new file mode 100644
index 0000000..de3c0b3
--- /dev/null
+++ b/tests/reference/ufo/psfglyphs2ufo/PsfTest-Bold.ufo/glyphs/contents.plist
@@ -0,0 +1,234 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+ <key>.notdef</key>
+ <string>_notdef.glif</string>
+ <key>.null</key>
+ <string>_null.glif</string>
+ <key>Ampersand</key>
+ <string>A_mpersand.glif</string>
+ <key>Apos</key>
+ <string>A_pos.glif</string>
+ <key>Asterisk</key>
+ <string>A_sterisk.glif</string>
+ <key>AtSgn</key>
+ <string>A_tS_gn.glif</string>
+ <key>CircumAccent</key>
+ <string>C_ircumA_ccent.glif</string>
+ <key>Colon</key>
+ <string>C_olon.glif</string>
+ <key>CombAcute</key>
+ <string>C_ombA_cute.glif</string>
+ <key>CombCircum</key>
+ <string>C_ombC_ircum.glif</string>
+ <key>CombDiaer</key>
+ <string>C_ombD_iaer.glif</string>
+ <key>CombGrave</key>
+ <string>C_ombG_rave.glif</string>
+ <key>CombRingAbv</key>
+ <string>C_ombR_ingA_bv.glif</string>
+ <key>CombTilde</key>
+ <string>C_ombT_ilde.glif</string>
+ <key>Comma</key>
+ <string>C_omma.glif</string>
+ <key>DigitEight</key>
+ <string>D_igitE_ight.glif</string>
+ <key>DigitFive</key>
+ <string>D_igitF_ive.glif</string>
+ <key>DigitFour</key>
+ <string>D_igitF_our.glif</string>
+ <key>DigitNine</key>
+ <string>D_igitN_ine.glif</string>
+ <key>DigitOne</key>
+ <string>D_igitO_ne.glif</string>
+ <key>DigitSeven</key>
+ <string>D_igitS_even.glif</string>
+ <key>DigitSix</key>
+ <string>D_igitS_ix.glif</string>
+ <key>DigitThree</key>
+ <string>D_igitT_hree.glif</string>
+ <key>DigitTwo</key>
+ <string>D_igitT_wo.glif</string>
+ <key>DigitZero</key>
+ <string>D_igitZ_ero.glif</string>
+ <key>DollarSgn</key>
+ <string>D_ollarS_gn.glif</string>
+ <key>DottedCirc</key>
+ <string>D_ottedC_irc.glif</string>
+ <key>EqSgn</key>
+ <string>E_qS_gn.glif</string>
+ <key>ExclamationMrk</key>
+ <string>E_xclamationM_rk.glif</string>
+ <key>FullStop</key>
+ <string>F_ullS_top.glif</string>
+ <key>GTSgn</key>
+ <string>G_T_S_gn.glif</string>
+ <key>GraveAccent</key>
+ <string>G_raveA_ccent.glif</string>
+ <key>Hyphen</key>
+ <string>H_yphen.glif</string>
+ <key>HyphenMinus</key>
+ <string>H_yphenM_inus.glif</string>
+ <key>Hyphen_Soft</key>
+ <string>H_yphen_S_oft.glif</string>
+ <key>LTSgn</key>
+ <string>L_T_S_gn.glif</string>
+ <key>LftCurlyBrac</key>
+ <string>L_ftC_urlyB_rac.glif</string>
+ <key>LftParen</key>
+ <string>L_ftP_aren.glif</string>
+ <key>LftSqrBrac</key>
+ <string>L_ftS_qrB_rac.glif</string>
+ <key>LowLine</key>
+ <string>L_owL_ine.glif</string>
+ <key>LtnCapA</key>
+ <string>L_tnC_apA_.glif</string>
+ <key>LtnCapA.alt</key>
+ <string>L_tnC_apA_.alt.glif</string>
+ <key>LtnCapADiaer</key>
+ <string>L_tnC_apA_D_iaer.glif</string>
+ <key>LtnCapB</key>
+ <string>L_tnC_apB_.glif</string>
+ <key>LtnCapC</key>
+ <string>L_tnC_apC_.glif</string>
+ <key>LtnCapD</key>
+ <string>L_tnC_apD_.glif</string>
+ <key>LtnCapE</key>
+ <string>L_tnC_apE_.glif</string>
+ <key>LtnCapF</key>
+ <string>L_tnC_apF_.glif</string>
+ <key>LtnCapG</key>
+ <string>L_tnC_apG_.glif</string>
+ <key>LtnCapH</key>
+ <string>L_tnC_apH_.glif</string>
+ <key>LtnCapI</key>
+ <string>L_tnC_apI_.glif</string>
+ <key>LtnCapJ</key>
+ <string>L_tnC_apJ_.glif</string>
+ <key>LtnCapK</key>
+ <string>L_tnC_apK_.glif</string>
+ <key>LtnCapL</key>
+ <string>L_tnC_apL_.glif</string>
+ <key>LtnCapM</key>
+ <string>L_tnC_apM_.glif</string>
+ <key>LtnCapN</key>
+ <string>L_tnC_apN_.glif</string>
+ <key>LtnCapO</key>
+ <string>L_tnC_apO_.glif</string>
+ <key>LtnCapP</key>
+ <string>L_tnC_apP_.glif</string>
+ <key>LtnCapQ</key>
+ <string>L_tnC_apQ_.glif</string>
+ <key>LtnCapR</key>
+ <string>L_tnC_apR_.glif</string>
+ <key>LtnCapS</key>
+ <string>L_tnC_apS_.glif</string>
+ <key>LtnCapT</key>
+ <string>L_tnC_apT_.glif</string>
+ <key>LtnCapU</key>
+ <string>L_tnC_apU_.glif</string>
+ <key>LtnCapV</key>
+ <string>L_tnC_apV_.glif</string>
+ <key>LtnCapW</key>
+ <string>L_tnC_apW_.glif</string>
+ <key>LtnCapX</key>
+ <string>L_tnC_apX_.glif</string>
+ <key>LtnCapY</key>
+ <string>L_tnC_apY_.glif</string>
+ <key>LtnSmA</key>
+ <string>L_tnS_mA_.glif</string>
+ <key>LtnSmAAcute</key>
+ <string>L_tnS_mA_A_cute.glif</string>
+ <key>LtnSmACircum</key>
+ <string>L_tnS_mA_C_ircum.glif</string>
+ <key>LtnSmADiaer</key>
+ <string>L_tnS_mA_D_iaer.glif</string>
+ <key>LtnSmAGrave</key>
+ <string>L_tnS_mA_G_rave.glif</string>
+ <key>LtnSmARingAbv</key>
+ <string>L_tnS_mA_R_ingA_bv.glif</string>
+ <key>LtnSmATilde</key>
+ <string>L_tnS_mA_T_ilde.glif</string>
+ <key>LtnSmB</key>
+ <string>L_tnS_mB_.glif</string>
+ <key>LtnSmC</key>
+ <string>L_tnS_mC_.glif</string>
+ <key>LtnSmD</key>
+ <string>L_tnS_mD_.glif</string>
+ <key>LtnSmE</key>
+ <string>L_tnS_mE_.glif</string>
+ <key>LtnSmF</key>
+ <string>L_tnS_mF_.glif</string>
+ <key>LtnSmG</key>
+ <string>L_tnS_mG_.glif</string>
+ <key>LtnSmH</key>
+ <string>L_tnS_mH_.glif</string>
+ <key>LtnSmI</key>
+ <string>L_tnS_mI_.glif</string>
+ <key>LtnSmJ</key>
+ <string>L_tnS_mJ_.glif</string>
+ <key>LtnSmK</key>
+ <string>L_tnS_mK_.glif</string>
+ <key>LtnSmL</key>
+ <string>L_tnS_mL_.glif</string>
+ <key>LtnSmM</key>
+ <string>L_tnS_mM_.glif</string>
+ <key>LtnSmN</key>
+ <string>L_tnS_mN_.glif</string>
+ <key>LtnSmO</key>
+ <string>L_tnS_mO_.glif</string>
+ <key>LtnSmP</key>
+ <string>L_tnS_mP_.glif</string>
+ <key>LtnSmQ</key>
+ <string>L_tnS_mQ_.glif</string>
+ <key>LtnSmR</key>
+ <string>L_tnS_mR_.glif</string>
+ <key>LtnSmS</key>
+ <string>L_tnS_mS_.glif</string>
+ <key>LtnSmT</key>
+ <string>L_tnS_mT_.glif</string>
+ <key>LtnSmU</key>
+ <string>L_tnS_mU_.glif</string>
+ <key>LtnSmV</key>
+ <string>L_tnS_mV_.glif</string>
+ <key>LtnSmW</key>
+ <string>L_tnS_mW_.glif</string>
+ <key>LtnSmX</key>
+ <string>L_tnS_mX_.glif</string>
+ <key>LtnSmY</key>
+ <string>L_tnS_mY_.glif</string>
+ <key>NonBreakingHyphen</key>
+ <string>N_onB_reakingH_yphen.glif</string>
+ <key>NumSgn</key>
+ <string>N_umS_gn.glif</string>
+ <key>PercentSgn</key>
+ <string>P_ercentS_gn.glif</string>
+ <key>PlusSgn</key>
+ <string>P_lusS_gn.glif</string>
+ <key>QstnMrk</key>
+ <string>Q_stnM_rk.glif</string>
+ <key>QuotMrk</key>
+ <string>Q_uotM_rk.glif</string>
+ <key>ReverseSolidus</key>
+ <string>R_everseS_olidus.glif</string>
+ <key>RtCurlyBrac</key>
+ <string>R_tC_urlyB_rac.glif</string>
+ <key>RtParen</key>
+ <string>R_tP_aren.glif</string>
+ <key>RtSqrBrac</key>
+ <string>R_tS_qrB_rac.glif</string>
+ <key>Semicolon</key>
+ <string>S_emicolon.glif</string>
+ <key>Solidus</key>
+ <string>S_olidus.glif</string>
+ <key>Space</key>
+ <string>S_pace.glif</string>
+ <key>Tilde</key>
+ <string>T_ilde.glif</string>
+ <key>VertLine</key>
+ <string>V_ertL_ine.glif</string>
+ <key>nonmarkingreturn</key>
+ <string>nonmarkingreturn.glif</string>
+</dict>
+</plist>
diff --git a/tests/reference/ufo/psfglyphs2ufo/PsfTest-Bold.ufo/glyphs/nonmarkingreturn.glif b/tests/reference/ufo/psfglyphs2ufo/PsfTest-Bold.ufo/glyphs/nonmarkingreturn.glif
new file mode 100644
index 0000000..ee41448
--- /dev/null
+++ b/tests/reference/ufo/psfglyphs2ufo/PsfTest-Bold.ufo/glyphs/nonmarkingreturn.glif
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="nonmarkingreturn" format="2">
+ <advance width="1024"/>
+ <outline/>
+</glyph>
diff --git a/tests/reference/ufo/psfglyphs2ufo/PsfTest-Bold.ufo/layercontents.plist b/tests/reference/ufo/psfglyphs2ufo/PsfTest-Bold.ufo/layercontents.plist
new file mode 100644
index 0000000..42b7482
--- /dev/null
+++ b/tests/reference/ufo/psfglyphs2ufo/PsfTest-Bold.ufo/layercontents.plist
@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<array>
+ <array>
+ <string>public.default</string>
+ <string>glyphs</string>
+ </array>
+</array>
+</plist>
diff --git a/tests/reference/ufo/psfglyphs2ufo/PsfTest-Bold.ufo/lib.plist b/tests/reference/ufo/psfglyphs2ufo/PsfTest-Bold.ufo/lib.plist
new file mode 100644
index 0000000..e2b5315
--- /dev/null
+++ b/tests/reference/ufo/psfglyphs2ufo/PsfTest-Bold.ufo/lib.plist
@@ -0,0 +1,417 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+ <key>com.schriftgestaltung.Glyphs.fontUserData</key>
+ <dict/>
+ <key>com.schriftgestaltung.appVersion</key>
+ <string>1165</string>
+ <key>com.schriftgestaltung.customParameter.GSFont.disablesAutomaticAlignment</key>
+ <true/>
+ <key>com.schriftgestaltung.customParameter.GSFont.disablesLastChange</key>
+ <true/>
+ <key>com.schriftgestaltung.customParameter.GSFont.useNiceNames</key>
+ <integer>0</integer>
+ <key>com.schriftgestaltung.customParameter.GSFontMaster.customValue</key>
+ <integer>0</integer>
+ <key>com.schriftgestaltung.customParameter.GSFontMaster.customValue1</key>
+ <integer>0</integer>
+ <key>com.schriftgestaltung.customParameter.GSFontMaster.customValue2</key>
+ <integer>0</integer>
+ <key>com.schriftgestaltung.customParameter.GSFontMaster.customValue3</key>
+ <integer>0</integer>
+ <key>com.schriftgestaltung.customParameter.GSFontMaster.iconName</key>
+ <string/>
+ <key>com.schriftgestaltung.customParameter.GSFontMaster.weightValue</key>
+ <integer>700</integer>
+ <key>com.schriftgestaltung.customParameter.GSFontMaster.widthValue</key>
+ <integer>100</integer>
+ <key>com.schriftgestaltung.disablesAutomaticAlignment</key>
+ <true/>
+ <key>com.schriftgestaltung.disablesLastChange</key>
+ <true/>
+ <key>com.schriftgestaltung.fontMasterOrder</key>
+ <integer>1</integer>
+ <key>com.schriftgestaltung.keyboardIncrement</key>
+ <integer>1</integer>
+ <key>com.schriftgestaltung.weight</key>
+ <string>Bold</string>
+ <key>com.schriftgestaltung.weightValue</key>
+ <integer>700</integer>
+ <key>com.schriftgestaltung.width</key>
+ <string>Regular</string>
+ <key>com.schriftgestaltung.widthValue</key>
+ <integer>100</integer>
+ <key>org.sil.lcg.toneLetters</key>
+ <dict>
+ <key>contourWidth</key>
+ <integer>540</integer>
+ <key>dotSize</key>
+ <integer>280</integer>
+ <key>dotSpacing</key>
+ <integer>200</integer>
+ <key>glyphDepth</key>
+ <integer>-25</integer>
+ <key>glyphHeight</key>
+ <integer>1600</integer>
+ <key>italicAngle</key>
+ <integer>0</integer>
+ <key>marginDotLeft</key>
+ <integer>100</integer>
+ <key>marginDotRight</key>
+ <integer>140</integer>
+ <key>marginFlatLeft</key>
+ <integer>100</integer>
+ <key>marginFlatRight</key>
+ <integer>140</integer>
+ <key>marginPointLeft</key>
+ <integer>80</integer>
+ <key>marginPointRight</key>
+ <integer>120</integer>
+ <key>strokeThickness</key>
+ <integer>200</integer>
+ </dict>
+ <key>public.glyphOrder</key>
+ <array>
+ <string>.notdef</string>
+ <string>.null</string>
+ <string>nonmarkingreturn</string>
+ <string>Space</string>
+ <string>ExclamationMrk</string>
+ <string>QuotMrk</string>
+ <string>NumSgn</string>
+ <string>DollarSgn</string>
+ <string>PercentSgn</string>
+ <string>Ampersand</string>
+ <string>Apos</string>
+ <string>LftParen</string>
+ <string>RtParen</string>
+ <string>Asterisk</string>
+ <string>PlusSgn</string>
+ <string>Comma</string>
+ <string>HyphenMinus</string>
+ <string>FullStop</string>
+ <string>Solidus</string>
+ <string>DigitZero</string>
+ <string>DigitOne</string>
+ <string>DigitTwo</string>
+ <string>DigitThree</string>
+ <string>DigitFour</string>
+ <string>DigitFive</string>
+ <string>DigitSix</string>
+ <string>DigitSeven</string>
+ <string>DigitEight</string>
+ <string>DigitNine</string>
+ <string>Colon</string>
+ <string>Semicolon</string>
+ <string>LTSgn</string>
+ <string>EqSgn</string>
+ <string>GTSgn</string>
+ <string>QstnMrk</string>
+ <string>AtSgn</string>
+ <string>LtnCapA</string>
+ <string>LtnCapA.alt</string>
+ <string>LtnCapB</string>
+ <string>LtnCapC</string>
+ <string>LtnCapD</string>
+ <string>LtnCapE</string>
+ <string>LtnCapF</string>
+ <string>LtnCapG</string>
+ <string>LtnCapH</string>
+ <string>LtnCapI</string>
+ <string>LtnCapJ</string>
+ <string>LtnCapK</string>
+ <string>LtnCapL</string>
+ <string>LtnCapM</string>
+ <string>LtnCapN</string>
+ <string>LtnCapO</string>
+ <string>LtnCapP</string>
+ <string>LtnCapQ</string>
+ <string>LtnCapR</string>
+ <string>LtnCapS</string>
+ <string>LtnCapT</string>
+ <string>LtnCapU</string>
+ <string>LtnCapV</string>
+ <string>LtnCapW</string>
+ <string>LtnCapX</string>
+ <string>LtnCapY</string>
+ <string>LftSqrBrac</string>
+ <string>ReverseSolidus</string>
+ <string>RtSqrBrac</string>
+ <string>CircumAccent</string>
+ <string>LowLine</string>
+ <string>GraveAccent</string>
+ <string>LtnSmA</string>
+ <string>LtnSmB</string>
+ <string>LtnSmC</string>
+ <string>LtnSmD</string>
+ <string>LtnSmE</string>
+ <string>LtnSmF</string>
+ <string>LtnSmG</string>
+ <string>LtnSmH</string>
+ <string>LtnSmI</string>
+ <string>LtnSmJ</string>
+ <string>LtnSmK</string>
+ <string>LtnSmL</string>
+ <string>LtnSmM</string>
+ <string>LtnSmN</string>
+ <string>LtnSmO</string>
+ <string>LtnSmP</string>
+ <string>LtnSmQ</string>
+ <string>LtnSmR</string>
+ <string>LtnSmS</string>
+ <string>LtnSmT</string>
+ <string>LtnSmU</string>
+ <string>LtnSmV</string>
+ <string>LtnSmW</string>
+ <string>LtnSmX</string>
+ <string>LtnSmY</string>
+ <string>LftCurlyBrac</string>
+ <string>VertLine</string>
+ <string>RtCurlyBrac</string>
+ <string>Tilde</string>
+ <string>LtnCapADiaer</string>
+ <string>LtnSmAAcute</string>
+ <string>LtnSmAGrave</string>
+ <string>LtnSmACircum</string>
+ <string>LtnSmADiaer</string>
+ <string>LtnSmATilde</string>
+ <string>LtnSmARingAbv</string>
+ <string>DottedCirc</string>
+ <string>Hyphen</string>
+ <string>NonBreakingHyphen</string>
+ <string>Hyphen_Soft</string>
+ <string>CombAcute</string>
+ <string>CombGrave</string>
+ <string>CombCircum</string>
+ <string>CombTilde</string>
+ <string>CombDiaer</string>
+ <string>CombRingAbv</string>
+ </array>
+ <key>public.postscriptNames</key>
+ <dict>
+ <key>Ampersand</key>
+ <string>ampersand</string>
+ <key>Apos</key>
+ <string>quotesingle</string>
+ <key>Asterisk</key>
+ <string>asterisk</string>
+ <key>AtSgn</key>
+ <string>at</string>
+ <key>CircumAccent</key>
+ <string>asciicircum</string>
+ <key>Colon</key>
+ <string>colon</string>
+ <key>CombAcute</key>
+ <string>acutecomb</string>
+ <key>CombCircum</key>
+ <string>uni0302</string>
+ <key>CombDiaer</key>
+ <string>uni0308</string>
+ <key>CombGrave</key>
+ <string>gravecomb</string>
+ <key>CombRingAbv</key>
+ <string>uni030A</string>
+ <key>CombTilde</key>
+ <string>tildecomb</string>
+ <key>Comma</key>
+ <string>comma</string>
+ <key>DigitEight</key>
+ <string>eight</string>
+ <key>DigitFive</key>
+ <string>five</string>
+ <key>DigitFour</key>
+ <string>four</string>
+ <key>DigitNine</key>
+ <string>nine</string>
+ <key>DigitOne</key>
+ <string>one</string>
+ <key>DigitSeven</key>
+ <string>seven</string>
+ <key>DigitSix</key>
+ <string>six</string>
+ <key>DigitThree</key>
+ <string>three</string>
+ <key>DigitTwo</key>
+ <string>two</string>
+ <key>DigitZero</key>
+ <string>zero</string>
+ <key>DollarSgn</key>
+ <string>dollar</string>
+ <key>DottedCirc</key>
+ <string>uni25CC</string>
+ <key>EqSgn</key>
+ <string>equal</string>
+ <key>ExclamationMrk</key>
+ <string>exclam</string>
+ <key>FullStop</key>
+ <string>period</string>
+ <key>GTSgn</key>
+ <string>greater</string>
+ <key>GraveAccent</key>
+ <string>grave</string>
+ <key>Hyphen</key>
+ <string>uni2010</string>
+ <key>HyphenMinus</key>
+ <string>hyphen</string>
+ <key>Hyphen_Soft</key>
+ <string>uni00AD</string>
+ <key>LTSgn</key>
+ <string>less</string>
+ <key>LftCurlyBrac</key>
+ <string>braceleft</string>
+ <key>LftParen</key>
+ <string>parenleft</string>
+ <key>LftSqrBrac</key>
+ <string>bracketleft</string>
+ <key>LowLine</key>
+ <string>underscore</string>
+ <key>LtnCapA</key>
+ <string>A</string>
+ <key>LtnCapA.alt</key>
+ <string>A</string>
+ <key>LtnCapADiaer</key>
+ <string>Adieresis</string>
+ <key>LtnCapB</key>
+ <string>B</string>
+ <key>LtnCapC</key>
+ <string>C</string>
+ <key>LtnCapD</key>
+ <string>D</string>
+ <key>LtnCapE</key>
+ <string>E</string>
+ <key>LtnCapF</key>
+ <string>F</string>
+ <key>LtnCapG</key>
+ <string>G</string>
+ <key>LtnCapH</key>
+ <string>H</string>
+ <key>LtnCapI</key>
+ <string>I</string>
+ <key>LtnCapJ</key>
+ <string>J</string>
+ <key>LtnCapK</key>
+ <string>K</string>
+ <key>LtnCapL</key>
+ <string>L</string>
+ <key>LtnCapM</key>
+ <string>M</string>
+ <key>LtnCapN</key>
+ <string>N</string>
+ <key>LtnCapO</key>
+ <string>O</string>
+ <key>LtnCapP</key>
+ <string>P</string>
+ <key>LtnCapQ</key>
+ <string>Q</string>
+ <key>LtnCapR</key>
+ <string>R</string>
+ <key>LtnCapS</key>
+ <string>S</string>
+ <key>LtnCapT</key>
+ <string>T</string>
+ <key>LtnCapU</key>
+ <string>U</string>
+ <key>LtnCapV</key>
+ <string>V</string>
+ <key>LtnCapW</key>
+ <string>W</string>
+ <key>LtnCapX</key>
+ <string>X</string>
+ <key>LtnCapY</key>
+ <string>Y</string>
+ <key>LtnSmA</key>
+ <string>a</string>
+ <key>LtnSmAAcute</key>
+ <string>aacute</string>
+ <key>LtnSmACircum</key>
+ <string>acircumflex</string>
+ <key>LtnSmADiaer</key>
+ <string>adieresis</string>
+ <key>LtnSmAGrave</key>
+ <string>agrave</string>
+ <key>LtnSmARingAbv</key>
+ <string>aring</string>
+ <key>LtnSmATilde</key>
+ <string>atilde</string>
+ <key>LtnSmB</key>
+ <string>b</string>
+ <key>LtnSmC</key>
+ <string>c</string>
+ <key>LtnSmD</key>
+ <string>d</string>
+ <key>LtnSmE</key>
+ <string>e</string>
+ <key>LtnSmF</key>
+ <string>f</string>
+ <key>LtnSmG</key>
+ <string>g</string>
+ <key>LtnSmH</key>
+ <string>h</string>
+ <key>LtnSmI</key>
+ <string>i</string>
+ <key>LtnSmJ</key>
+ <string>j</string>
+ <key>LtnSmK</key>
+ <string>k</string>
+ <key>LtnSmL</key>
+ <string>l</string>
+ <key>LtnSmM</key>
+ <string>m</string>
+ <key>LtnSmN</key>
+ <string>n</string>
+ <key>LtnSmO</key>
+ <string>o</string>
+ <key>LtnSmP</key>
+ <string>p</string>
+ <key>LtnSmQ</key>
+ <string>q</string>
+ <key>LtnSmR</key>
+ <string>r</string>
+ <key>LtnSmS</key>
+ <string>s</string>
+ <key>LtnSmT</key>
+ <string>t</string>
+ <key>LtnSmU</key>
+ <string>u</string>
+ <key>LtnSmV</key>
+ <string>v</string>
+ <key>LtnSmW</key>
+ <string>w</string>
+ <key>LtnSmX</key>
+ <string>x</string>
+ <key>LtnSmY</key>
+ <string>y</string>
+ <key>NonBreakingHyphen</key>
+ <string>uni2011</string>
+ <key>NumSgn</key>
+ <string>numbersign</string>
+ <key>PercentSgn</key>
+ <string>percent</string>
+ <key>PlusSgn</key>
+ <string>plus</string>
+ <key>QstnMrk</key>
+ <string>question</string>
+ <key>QuotMrk</key>
+ <string>quotedbl</string>
+ <key>ReverseSolidus</key>
+ <string>backslash</string>
+ <key>RtCurlyBrac</key>
+ <string>braceright</string>
+ <key>RtParen</key>
+ <string>parenright</string>
+ <key>RtSqrBrac</key>
+ <string>bracketright</string>
+ <key>Semicolon</key>
+ <string>semicolon</string>
+ <key>Solidus</key>
+ <string>slash</string>
+ <key>Space</key>
+ <string>space</string>
+ <key>Tilde</key>
+ <string>asciitilde</string>
+ <key>VertLine</key>
+ <string>bar</string>
+ </dict>
+</dict>
+</plist>
diff --git a/tests/reference/ufo/psfglyphs2ufo/PsfTest-Bold.ufo/metainfo.plist b/tests/reference/ufo/psfglyphs2ufo/PsfTest-Bold.ufo/metainfo.plist
new file mode 100644
index 0000000..aa10c5c
--- /dev/null
+++ b/tests/reference/ufo/psfglyphs2ufo/PsfTest-Bold.ufo/metainfo.plist
@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+ <key>creator</key>
+ <string>org.sil.scripts.pysilfont</string>
+ <key>formatVersion</key>
+ <integer>3</integer>
+</dict>
+</plist>
diff --git a/tests/reference/ufo/psfglyphs2ufo/PsfTest-Regular.ufo/fontinfo.plist b/tests/reference/ufo/psfglyphs2ufo/PsfTest-Regular.ufo/fontinfo.plist
new file mode 100644
index 0000000..ca97ce8
--- /dev/null
+++ b/tests/reference/ufo/psfglyphs2ufo/PsfTest-Regular.ufo/fontinfo.plist
@@ -0,0 +1,260 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+ <key>ascender</key>
+ <integer>2100</integer>
+ <key>capHeight</key>
+ <integer>1485</integer>
+ <key>copyright</key>
+ <string>Copyright (c) 2004-2021 SIL International</string>
+ <key>descender</key>
+ <integer>-550</integer>
+ <key>familyName</key>
+ <string>Psf Test</string>
+ <key>guidelines</key>
+ <array>
+ <dict>
+ <key>angle</key>
+ <integer>0</integer>
+ <key>x</key>
+ <integer>1084</integer>
+ <key>y</key>
+ <integer>1040</integer>
+ </dict>
+ <dict>
+ <key>y</key>
+ <integer>1250</integer>
+ </dict>
+ </array>
+ <key>note</key>
+ <string>Test note
+Second line
+
+Third line
+</string>
+ <key>openTypeHeadCreated</key>
+ <string>2021/10/22 11:32:25</string>
+ <key>openTypeHheaAscender</key>
+ <integer>2100</integer>
+ <key>openTypeHheaDescender</key>
+ <integer>-550</integer>
+ <key>openTypeHheaLineGap</key>
+ <integer>0</integer>
+ <key>openTypeNameDescription</key>
+ <string>Copyright (c) 2004-2021 SIL International</string>
+ <key>openTypeNameDesigner</key>
+ <string>Victor Gaultney, Annie Olsen, Julie Remington, Don Collingsworth, Eric Hays, Becca Hirsbrunner</string>
+ <key>openTypeNameDesignerURL</key>
+ <string>http://scripts.sil.org/</string>
+ <key>openTypeNameLicense</key>
+ <string>Copyright (c) 2004-2021 SIL International (http://www.sil.org/) with Reserved Font Names "Andika" and "SIL".
+
+This Font Software is licensed under the SIL Open Font License, Version 1.1. This license is copied below, and is also available with a FAQ at: http://scripts.sil.org/OFL
+
+
+-----------------------------------------------------------
+SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007
+-----------------------------------------------------------
+
+PREAMBLE
+The goals of the Open Font License (OFL) are to stimulate worldwide development of collaborative font projects, to support the font creation efforts of academic and linguistic communities, and to provide a free and open framework in which fonts may be shared and improved in partnership with others.
+
+The OFL allows the licensed fonts to be used, studied, modified and redistributed freely as long as they are not sold by themselves. The fonts, including any derivative works, can be bundled, embedded, redistributed and/or sold with any software provided that any reserved names are not used by derivative works. The fonts and derivatives, however, cannot be released under any other type of license. The requirement for fonts to remain under this license does not apply to any document created using the fonts or their derivatives.
+
+DEFINITIONS
+"Font Software" refers to the set of files released by the Copyright Holder(s) under this license and clearly marked as such. This may include source files, build scripts and documentation.
+
+"Reserved Font Name" refers to any names specified as such after the copyright statement(s).
+
+"Original Version" refers to the collection of Font Software components as distributed by the Copyright Holder(s).
+
+"Modified Version" refers to any derivative made by adding to, deleting, or substituting -- in part or in whole -- any of the components of the Original Version, by changing formats or by porting the Font Software to a new environment.
+
+"Author" refers to any designer, engineer, programmer, technical writer or other person who contributed to the Font Software.
+
+PERMISSION &amp; CONDITIONS
+Permission is hereby granted, free of charge, to any person obtaining a copy of the Font Software, to use, study, copy, merge, embed, modify, redistribute, and sell modified and unmodified copies of the Font Software, subject to the following conditions:
+
+1) Neither the Font Software nor any of its individual components, in Original or Modified Versions, may be sold by itself.
+
+2) Original or Modified Versions of the Font Software may be bundled, redistributed and/or sold with any software, provided that each copy contains the above copyright notice and this license. These can be included either as stand-alone text files, human-readable headers or in the appropriate machine-readable metadata fields within text or binary files as long as those fields can be easily viewed by the user.
+
+3) No Modified Version of the Font Software may use the Reserved Font Name(s) unless explicit written permission is granted by the corresponding Copyright Holder. This restriction only applies to the primary font name as presented to the users.
+
+4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font Software shall not be used to promote, endorse or advertise any Modified Version, except to acknowledge the contribution(s) of the Copyright Holder(s) and the Author(s) or with their explicit written permission.
+
+5) The Font Software, modified or unmodified, in part or in whole, must be distributed entirely under this license, and must not be distributed under any other license. The requirement for fonts to remain under this license does not apply to any document created using the Font Software.
+
+TERMINATION
+This license becomes null and void if any of the above conditions are not met.
+
+DISCLAIMER
+THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM OTHER DEALINGS IN THE FONT SOFTWARE.</string>
+ <key>openTypeNameLicenseURL</key>
+ <string>http://scripts.sil.org/OFL</string>
+ <key>openTypeNameManufacturer</key>
+ <string>SIL International</string>
+ <key>openTypeNameManufacturerURL</key>
+ <string>http://scripts.sil.org</string>
+ <key>openTypeNamePreferredFamilyName</key>
+ <string>Psf Test</string>
+ <key>openTypeNamePreferredSubfamilyName</key>
+ <string>Regular</string>
+ <key>openTypeNameUniqueID</key>
+ <string>SIL International: Psf Test Regular: 2022</string>
+ <key>openTypeNameVersion</key>
+ <string>Version 5.550</string>
+ <key>openTypeOS2CodePageRanges</key>
+ <array>
+ <integer>0</integer>
+ <integer>1</integer>
+ <integer>2</integer>
+ <integer>4</integer>
+ <integer>7</integer>
+ <integer>8</integer>
+ </array>
+ <key>openTypeOS2FamilyClass</key>
+ <array>
+ <integer>0</integer>
+ <integer>0</integer>
+ </array>
+ <key>openTypeOS2Panose</key>
+ <array>
+ <integer>2</integer>
+ <integer>0</integer>
+ <integer>0</integer>
+ <integer>0</integer>
+ <integer>0</integer>
+ <integer>0</integer>
+ <integer>0</integer>
+ <integer>0</integer>
+ <integer>0</integer>
+ <integer>0</integer>
+ </array>
+ <key>openTypeOS2StrikeoutPosition</key>
+ <integer>700</integer>
+ <key>openTypeOS2StrikeoutSize</key>
+ <integer>100</integer>
+ <key>openTypeOS2SubscriptXOffset</key>
+ <integer>0</integer>
+ <key>openTypeOS2SubscriptXSize</key>
+ <integer>1433</integer>
+ <key>openTypeOS2SubscriptYOffset</key>
+ <integer>286</integer>
+ <key>openTypeOS2SubscriptYSize</key>
+ <integer>1331</integer>
+ <key>openTypeOS2SuperscriptXOffset</key>
+ <integer>0</integer>
+ <key>openTypeOS2SuperscriptXSize</key>
+ <integer>1433</integer>
+ <key>openTypeOS2SuperscriptYOffset</key>
+ <integer>976</integer>
+ <key>openTypeOS2SuperscriptYSize</key>
+ <integer>1331</integer>
+ <key>openTypeOS2Type</key>
+ <array/>
+ <key>openTypeOS2TypoAscender</key>
+ <integer>2100</integer>
+ <key>openTypeOS2TypoDescender</key>
+ <integer>-550</integer>
+ <key>openTypeOS2TypoLineGap</key>
+ <integer>0</integer>
+ <key>openTypeOS2UnicodeRanges</key>
+ <array>
+ <integer>0</integer>
+ <integer>1</integer>
+ <integer>6</integer>
+ <integer>7</integer>
+ <integer>31</integer>
+ <integer>33</integer>
+ <integer>35</integer>
+ <integer>36</integer>
+ <integer>37</integer>
+ <integer>38</integer>
+ <integer>39</integer>
+ <integer>40</integer>
+ <integer>45</integer>
+ <integer>46</integer>
+ <integer>47</integer>
+ <integer>57</integer>
+ <integer>60</integer>
+ <integer>62</integer>
+ <integer>64</integer>
+ <integer>67</integer>
+ <integer>69</integer>
+ <integer>89</integer>
+ </array>
+ <key>openTypeOS2VendorID</key>
+ <string>SIL</string>
+ <key>openTypeOS2WeightClass</key>
+ <integer>400</integer>
+ <key>openTypeOS2WidthClass</key>
+ <integer>5</integer>
+ <key>openTypeOS2WinAscent</key>
+ <integer>2100</integer>
+ <key>openTypeOS2WinDescent</key>
+ <integer>550</integer>
+ <key>postscriptBlueValues</key>
+ <array>
+ <integer>-490</integer>
+ <integer>-490</integer>
+ <integer>-25</integer>
+ <integer>0</integer>
+ <integer>1020</integer>
+ <integer>1040</integer>
+ <integer>1455</integer>
+ <integer>1485</integer>
+ <integer>1600</integer>
+ <integer>1620</integer>
+ </array>
+ <key>postscriptFontName</key>
+ <string>PsfTest-Regular</string>
+ <key>postscriptFullName</key>
+ <string>Psf Test Regular</string>
+ <key>postscriptStemSnapH</key>
+ <array>
+ <integer>140</integer>
+ <integer>145</integer>
+ <integer>150</integer>
+ <integer>155</integer>
+ <integer>160</integer>
+ <integer>165</integer>
+ <integer>170</integer>
+ <integer>175</integer>
+ <integer>185</integer>
+ <integer>270</integer>
+ </array>
+ <key>postscriptStemSnapV</key>
+ <array>
+ <integer>165</integer>
+ <integer>180</integer>
+ <integer>185</integer>
+ <integer>190</integer>
+ <integer>195</integer>
+ <integer>200</integer>
+ <integer>205</integer>
+ <integer>270</integer>
+ </array>
+ <key>postscriptUnderlinePosition</key>
+ <integer>-110</integer>
+ <key>postscriptUnderlineThickness</key>
+ <integer>80</integer>
+ <key>styleMapFamilyName</key>
+ <string>Psf Test</string>
+ <key>styleMapStyleName</key>
+ <string>regular</string>
+ <key>styleName</key>
+ <string>Regular</string>
+ <key>trademark</key>
+ <string>Andika is a trademark of SIL International.</string>
+ <key>unitsPerEm</key>
+ <integer>2048</integer>
+ <key>versionMajor</key>
+ <integer>5</integer>
+ <key>versionMinor</key>
+ <integer>550</integer>
+ <key>xHeight</key>
+ <integer>1040</integer>
+</dict>
+</plist>
diff --git a/tests/reference/ufo/psfglyphs2ufo/PsfTest-Regular.ufo/glyphs/A_mpersand.glif b/tests/reference/ufo/psfglyphs2ufo/PsfTest-Regular.ufo/glyphs/A_mpersand.glif
new file mode 100644
index 0000000..c2cef04
--- /dev/null
+++ b/tests/reference/ufo/psfglyphs2ufo/PsfTest-Regular.ufo/glyphs/A_mpersand.glif
@@ -0,0 +1,61 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="Ampersand" format="2">
+ <advance width="1222"/>
+ <unicode hex="0026"/>
+ <outline>
+ <contour>
+ <point x="490" y="1485" type="curve" smooth="yes"/>
+ <point x="331" y="1485"/>
+ <point x="155" y="1412"/>
+ <point x="155" y="1190" type="curve" smooth="yes"/>
+ <point x="155" y="1010"/>
+ <point x="362" y="815"/>
+ <point x="535" y="570" type="curve" smooth="yes"/>
+ <point x="794" y="202"/>
+ <point x="973" y="-25"/>
+ <point x="1025" y="-25" type="curve" smooth="yes"/>
+ <point x="1060" y="-25"/>
+ <point x="1138" y="38"/>
+ <point x="1175" y="70" type="curve"/>
+ <point x="1080" y="110"/>
+ <point x="914" y="297"/>
+ <point x="650" y="680" type="curve" smooth="yes"/>
+ <point x="494" y="906"/>
+ <point x="315" y="1075"/>
+ <point x="315" y="1200" type="curve" smooth="yes"/>
+ <point x="315" y="1291"/>
+ <point x="398" y="1350"/>
+ <point x="475" y="1350" type="curve" smooth="yes"/>
+ <point x="555" y="1350"/>
+ <point x="630" y="1294"/>
+ <point x="630" y="1205" type="curve" smooth="yes"/>
+ <point x="630" y="1116"/>
+ <point x="523" y="1001"/>
+ <point x="350" y="840" type="curve" smooth="yes"/>
+ <point x="146" y="651"/>
+ <point x="55" y="527"/>
+ <point x="55" y="375" type="curve" smooth="yes"/>
+ <point x="55" y="151"/>
+ <point x="217" y="-25"/>
+ <point x="440" y="-25" type="curve" smooth="yes"/>
+ <point x="713" y="-25"/>
+ <point x="1002" y="274"/>
+ <point x="1080" y="435" type="curve"/>
+ <point x="975" y="570" type="line"/>
+ <point x="911" y="403"/>
+ <point x="630" y="150"/>
+ <point x="455" y="150" type="curve" smooth="yes"/>
+ <point x="310" y="150"/>
+ <point x="230" y="267"/>
+ <point x="230" y="380" type="curve" smooth="yes"/>
+ <point x="230" y="490"/>
+ <point x="296" y="587"/>
+ <point x="470" y="740" type="curve" smooth="yes"/>
+ <point x="651" y="899"/>
+ <point x="790" y="1068"/>
+ <point x="790" y="1200" type="curve" smooth="yes"/>
+ <point x="790" y="1382"/>
+ <point x="642" y="1485"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfglyphs2ufo/PsfTest-Regular.ufo/glyphs/A_pos.glif b/tests/reference/ufo/psfglyphs2ufo/PsfTest-Regular.ufo/glyphs/A_pos.glif
new file mode 100644
index 0000000..5042901
--- /dev/null
+++ b/tests/reference/ufo/psfglyphs2ufo/PsfTest-Regular.ufo/glyphs/A_pos.glif
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="Apos" format="2">
+ <advance width="605"/>
+ <unicode hex="0027"/>
+ <outline>
+ <contour>
+ <point x="365" y="1045" type="line"/>
+ <point x="370" y="1186"/>
+ <point x="376" y="1339"/>
+ <point x="405" y="1585" type="curve"/>
+ <point x="200" y="1585" type="line"/>
+ <point x="231" y="1339"/>
+ <point x="236" y="1186"/>
+ <point x="240" y="1045" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfglyphs2ufo/PsfTest-Regular.ufo/glyphs/A_sterisk.glif b/tests/reference/ufo/psfglyphs2ufo/PsfTest-Regular.ufo/glyphs/A_sterisk.glif
new file mode 100644
index 0000000..850d344
--- /dev/null
+++ b/tests/reference/ufo/psfglyphs2ufo/PsfTest-Regular.ufo/glyphs/A_sterisk.glif
@@ -0,0 +1,51 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="Asterisk" format="2">
+ <advance width="1028"/>
+ <unicode hex="002A"/>
+ <outline>
+ <contour>
+ <point x="560" y="1600" type="curve"/>
+ <point x="415" y="1600" type="line"/>
+ <point x="434" y="1467"/>
+ <point x="447" y="1387"/>
+ <point x="450" y="1300" type="curve"/>
+ <point x="376" y="1344"/>
+ <point x="309" y="1387"/>
+ <point x="200" y="1465" type="curve"/>
+ <point x="125" y="1340" type="line"/>
+ <point x="250" y="1290"/>
+ <point x="327" y="1261"/>
+ <point x="405" y="1220" type="curve"/>
+ <point x="329" y="1177"/>
+ <point x="256" y="1140"/>
+ <point x="135" y="1085" type="curve"/>
+ <point x="205" y="960" type="line"/>
+ <point x="310" y="1042"/>
+ <point x="377" y="1094"/>
+ <point x="450" y="1140" type="curve"/>
+ <point x="448" y="1055"/>
+ <point x="442" y="973"/>
+ <point x="430" y="840" type="curve"/>
+ <point x="570" y="840" type="line"/>
+ <point x="550" y="973"/>
+ <point x="544" y="1052"/>
+ <point x="540" y="1140" type="curve"/>
+ <point x="614" y="1095"/>
+ <point x="681" y="1053"/>
+ <point x="790" y="975" type="curve"/>
+ <point x="865" y="1100" type="line"/>
+ <point x="739" y="1149"/>
+ <point x="663" y="1179"/>
+ <point x="585" y="1220" type="curve"/>
+ <point x="661" y="1261"/>
+ <point x="733" y="1299"/>
+ <point x="855" y="1355" type="curve"/>
+ <point x="785" y="1480" type="line"/>
+ <point x="680" y="1396"/>
+ <point x="614" y="1348"/>
+ <point x="540" y="1300" type="curve"/>
+ <point x="541" y="1387"/>
+ <point x="547" y="1467"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfglyphs2ufo/PsfTest-Regular.ufo/glyphs/A_tS_gn.glif b/tests/reference/ufo/psfglyphs2ufo/PsfTest-Regular.ufo/glyphs/A_tS_gn.glif
new file mode 100644
index 0000000..681014d
--- /dev/null
+++ b/tests/reference/ufo/psfglyphs2ufo/PsfTest-Regular.ufo/glyphs/A_tS_gn.glif
@@ -0,0 +1,80 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="AtSgn" format="2">
+ <advance width="1702"/>
+ <unicode hex="0040"/>
+ <outline>
+ <contour>
+ <point x="1605" y="700" type="curve" smooth="yes"/>
+ <point x="1605" y="1127"/>
+ <point x="1307" y="1405"/>
+ <point x="880" y="1405" type="curve" smooth="yes"/>
+ <point x="465" y="1405"/>
+ <point x="95" y="1126"/>
+ <point x="95" y="575" type="curve" smooth="yes"/>
+ <point x="95" y="48"/>
+ <point x="464" y="-235"/>
+ <point x="855" y="-235" type="curve" smooth="yes"/>
+ <point x="990" y="-235"/>
+ <point x="1150" y="-188"/>
+ <point x="1250" y="-118" type="curve"/>
+ <point x="1145" y="-10" type="line"/>
+ <point x="1058" y="-70"/>
+ <point x="963" y="-95"/>
+ <point x="870" y="-95" type="curve" smooth="yes"/>
+ <point x="523" y="-95"/>
+ <point x="240" y="174"/>
+ <point x="240" y="605" type="curve" smooth="yes"/>
+ <point x="240" y="1003"/>
+ <point x="542" y="1270"/>
+ <point x="870" y="1270" type="curve" smooth="yes"/>
+ <point x="1263" y="1270"/>
+ <point x="1465" y="1002"/>
+ <point x="1465" y="670" type="curve" smooth="yes"/>
+ <point x="1465" y="432"/>
+ <point x="1348" y="315"/>
+ <point x="1280" y="315" type="curve" smooth="yes"/>
+ <point x="1221" y="315"/>
+ <point x="1175" y="410"/>
+ <point x="1175" y="630" type="curve" smooth="yes"/>
+ <point x="1175" y="980" type="line"/>
+ <point x="1088" y="1015"/>
+ <point x="961" y="1040"/>
+ <point x="880" y="1040" type="curve" smooth="yes"/>
+ <point x="716" y="1040"/>
+ <point x="613" y="971"/>
+ <point x="530" y="835" type="curve" smooth="yes"/>
+ <point x="483" y="756"/>
+ <point x="455" y="653"/>
+ <point x="455" y="530" type="curve" smooth="yes"/>
+ <point x="455" y="294"/>
+ <point x="601" y="183"/>
+ <point x="735" y="183" type="curve" smooth="yes"/>
+ <point x="852" y="183"/>
+ <point x="988" y="366"/>
+ <point x="1040" y="490" type="curve"/>
+ <point x="1050" y="322"/>
+ <point x="1128" y="180"/>
+ <point x="1250" y="180" type="curve" smooth="yes"/>
+ <point x="1425" y="180"/>
+ <point x="1605" y="368"/>
+ </contour>
+ <contour>
+ <point x="850" y="905" type="curve" smooth="yes"/>
+ <point x="924" y="905"/>
+ <point x="992" y="886"/>
+ <point x="1025" y="870" type="curve"/>
+ <point x="1025" y="720" type="line"/>
+ <point x="993" y="582"/>
+ <point x="838" y="320"/>
+ <point x="748" y="320" type="curve" smooth="yes"/>
+ <point x="676" y="320"/>
+ <point x="605" y="398"/>
+ <point x="605" y="575" type="curve" smooth="yes"/>
+ <point x="605" y="652"/>
+ <point x="621" y="731"/>
+ <point x="650" y="780" type="curve" smooth="yes"/>
+ <point x="706" y="876"/>
+ <point x="782" y="905"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfglyphs2ufo/PsfTest-Regular.ufo/glyphs/C_ircumA_ccent.glif b/tests/reference/ufo/psfglyphs2ufo/PsfTest-Regular.ufo/glyphs/C_ircumA_ccent.glif
new file mode 100644
index 0000000..60bd1cf
--- /dev/null
+++ b/tests/reference/ufo/psfglyphs2ufo/PsfTest-Regular.ufo/glyphs/C_ircumA_ccent.glif
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="CircumAccent" format="2">
+ <advance width="850"/>
+ <unicode hex="005E"/>
+ <outline>
+ <component base="CombCircum" xOffset="995"/>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfglyphs2ufo/PsfTest-Regular.ufo/glyphs/C_olon.glif b/tests/reference/ufo/psfglyphs2ufo/PsfTest-Regular.ufo/glyphs/C_olon.glif
new file mode 100644
index 0000000..3cfbbc1
--- /dev/null
+++ b/tests/reference/ufo/psfglyphs2ufo/PsfTest-Regular.ufo/glyphs/C_olon.glif
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="Colon" format="2">
+ <advance width="640"/>
+ <unicode hex="003A"/>
+ <outline>
+ <contour>
+ <point x="185" y="790" type="curve" smooth="yes"/>
+ <point x="185" y="716"/>
+ <point x="246" y="655"/>
+ <point x="320" y="655" type="curve" smooth="yes"/>
+ <point x="394" y="655"/>
+ <point x="455" y="716"/>
+ <point x="455" y="790" type="curve" smooth="yes"/>
+ <point x="455" y="864"/>
+ <point x="394" y="925"/>
+ <point x="320" y="925" type="curve" smooth="yes"/>
+ <point x="246" y="925"/>
+ <point x="185" y="864"/>
+ </contour>
+ <contour>
+ <point x="185" y="110" type="curve" smooth="yes"/>
+ <point x="185" y="36"/>
+ <point x="246" y="-25"/>
+ <point x="320" y="-25" type="curve" smooth="yes"/>
+ <point x="394" y="-25"/>
+ <point x="455" y="36"/>
+ <point x="455" y="110" type="curve" smooth="yes"/>
+ <point x="455" y="184"/>
+ <point x="394" y="245"/>
+ <point x="320" y="245" type="curve" smooth="yes"/>
+ <point x="246" y="245"/>
+ <point x="185" y="184"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfglyphs2ufo/PsfTest-Regular.ufo/glyphs/C_ombA_cute.glif b/tests/reference/ufo/psfglyphs2ufo/PsfTest-Regular.ufo/glyphs/C_ombA_cute.glif
new file mode 100644
index 0000000..bb13221
--- /dev/null
+++ b/tests/reference/ufo/psfglyphs2ufo/PsfTest-Regular.ufo/glyphs/C_ombA_cute.glif
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="CombAcute" format="2">
+ <unicode hex="0301"/>
+ <anchor x="-570" y="1635" name="U"/>
+ <anchor x="-570" y="1100" name="_U"/>
+ <outline>
+ <contour>
+ <point x="-400" y="1600" type="line"/>
+ <point x="-750" y="1170" type="line"/>
+ <point x="-590" y="1170" type="line"/>
+ <point x="-170" y="1600" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfglyphs2ufo/PsfTest-Regular.ufo/glyphs/C_ombC_ircum.glif b/tests/reference/ufo/psfglyphs2ufo/PsfTest-Regular.ufo/glyphs/C_ombC_ircum.glif
new file mode 100644
index 0000000..fa444ec
--- /dev/null
+++ b/tests/reference/ufo/psfglyphs2ufo/PsfTest-Regular.ufo/glyphs/C_ombC_ircum.glif
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="CombCircum" format="2">
+ <unicode hex="0302"/>
+ <anchor x="-570" y="1635" name="U"/>
+ <anchor x="-570" y="1100" name="_U"/>
+ <outline>
+ <contour>
+ <point x="-845" y="1170" type="line"/>
+ <point x="-570" y="1450" type="line"/>
+ <point x="-295" y="1170" type="line"/>
+ <point x="-145" y="1170" type="line"/>
+ <point x="-485" y="1600" type="line"/>
+ <point x="-655" y="1600" type="line"/>
+ <point x="-995" y="1170" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfglyphs2ufo/PsfTest-Regular.ufo/glyphs/C_ombD_iaer.glif b/tests/reference/ufo/psfglyphs2ufo/PsfTest-Regular.ufo/glyphs/C_ombD_iaer.glif
new file mode 100644
index 0000000..f7540ef
--- /dev/null
+++ b/tests/reference/ufo/psfglyphs2ufo/PsfTest-Regular.ufo/glyphs/C_ombD_iaer.glif
@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="CombDiaer" format="2">
+ <unicode hex="0308"/>
+ <anchor x="-570" y="1505" name="U"/>
+ <anchor x="-570" y="1100" name="_U"/>
+ <outline>
+ <contour>
+ <point x="-490" y="1345" type="curve" smooth="yes"/>
+ <point x="-490" y="1271"/>
+ <point x="-434" y="1210"/>
+ <point x="-360" y="1210" type="curve" smooth="yes"/>
+ <point x="-285" y="1210"/>
+ <point x="-230" y="1271"/>
+ <point x="-230" y="1345" type="curve" smooth="yes"/>
+ <point x="-230" y="1419"/>
+ <point x="-285" y="1480"/>
+ <point x="-360" y="1480" type="curve" smooth="yes"/>
+ <point x="-434" y="1480"/>
+ <point x="-490" y="1419"/>
+ </contour>
+ <contour>
+ <point x="-910" y="1345" type="curve" smooth="yes"/>
+ <point x="-910" y="1271"/>
+ <point x="-854" y="1210"/>
+ <point x="-780" y="1210" type="curve" smooth="yes"/>
+ <point x="-705" y="1210"/>
+ <point x="-650" y="1271"/>
+ <point x="-650" y="1345" type="curve" smooth="yes"/>
+ <point x="-650" y="1419"/>
+ <point x="-705" y="1480"/>
+ <point x="-780" y="1480" type="curve" smooth="yes"/>
+ <point x="-854" y="1480"/>
+ <point x="-910" y="1419"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfglyphs2ufo/PsfTest-Regular.ufo/glyphs/C_ombG_rave.glif b/tests/reference/ufo/psfglyphs2ufo/PsfTest-Regular.ufo/glyphs/C_ombG_rave.glif
new file mode 100644
index 0000000..c33b56a
--- /dev/null
+++ b/tests/reference/ufo/psfglyphs2ufo/PsfTest-Regular.ufo/glyphs/C_ombG_rave.glif
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="CombGrave" format="2">
+ <unicode hex="0300"/>
+ <anchor x="-550" y="1635" name="U"/>
+ <anchor x="-550" y="1100" name="_U"/>
+ <outline>
+ <contour>
+ <point x="-940" y="1600" type="line"/>
+ <point x="-520" y="1170" type="line"/>
+ <point x="-360" y="1170" type="line"/>
+ <point x="-710" y="1600" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfglyphs2ufo/PsfTest-Regular.ufo/glyphs/C_ombR_ingA_bv.glif b/tests/reference/ufo/psfglyphs2ufo/PsfTest-Regular.ufo/glyphs/C_ombR_ingA_bv.glif
new file mode 100644
index 0000000..b019e05
--- /dev/null
+++ b/tests/reference/ufo/psfglyphs2ufo/PsfTest-Regular.ufo/glyphs/C_ombR_ingA_bv.glif
@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="CombRingAbv" format="2">
+ <unicode hex="030A"/>
+ <anchor x="-570" y="1635" name="U"/>
+ <anchor x="-572" y="1100" name="_U"/>
+ <outline>
+ <contour>
+ <point x="-470" y="1385" type="curve" smooth="yes"/>
+ <point x="-470" y="1325"/>
+ <point x="-510" y="1285"/>
+ <point x="-570" y="1285" type="curve" smooth="yes"/>
+ <point x="-630" y="1285"/>
+ <point x="-670" y="1325"/>
+ <point x="-670" y="1385" type="curve" smooth="yes"/>
+ <point x="-670" y="1445"/>
+ <point x="-630" y="1485"/>
+ <point x="-570" y="1485" type="curve" smooth="yes"/>
+ <point x="-510" y="1485"/>
+ <point x="-470" y="1445"/>
+ </contour>
+ <contour>
+ <point x="-785" y="1385" type="curve" smooth="yes"/>
+ <point x="-785" y="1265"/>
+ <point x="-690" y="1170"/>
+ <point x="-570" y="1170" type="curve" smooth="yes"/>
+ <point x="-450" y="1170"/>
+ <point x="-355" y="1265"/>
+ <point x="-355" y="1385" type="curve" smooth="yes"/>
+ <point x="-355" y="1505"/>
+ <point x="-450" y="1600"/>
+ <point x="-570" y="1600" type="curve" smooth="yes"/>
+ <point x="-690" y="1600"/>
+ <point x="-785" y="1505"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfglyphs2ufo/PsfTest-Regular.ufo/glyphs/C_ombT_ilde.glif b/tests/reference/ufo/psfglyphs2ufo/PsfTest-Regular.ufo/glyphs/C_ombT_ilde.glif
new file mode 100644
index 0000000..88d5ca7
--- /dev/null
+++ b/tests/reference/ufo/psfglyphs2ufo/PsfTest-Regular.ufo/glyphs/C_ombT_ilde.glif
@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="CombTilde" format="2">
+ <unicode hex="0303"/>
+ <anchor x="-575" y="1475" name="U"/>
+ <anchor x="-575" y="1100" name="_U"/>
+ <outline>
+ <contour>
+ <point x="-820" y="1205" type="line"/>
+ <point x="-815" y="1254"/>
+ <point x="-784" y="1290"/>
+ <point x="-735" y="1290" type="curve" smooth="yes"/>
+ <point x="-698" y="1290"/>
+ <point x="-657" y="1274"/>
+ <point x="-580" y="1238" type="curve" smooth="yes"/>
+ <point x="-519" y="1210"/>
+ <point x="-466" y="1190"/>
+ <point x="-413" y="1190" type="curve" smooth="yes"/>
+ <point x="-290" y="1190"/>
+ <point x="-215" y="1312"/>
+ <point x="-215" y="1440" type="curve"/>
+ <point x="-320" y="1440" type="line"/>
+ <point x="-327" y="1394"/>
+ <point x="-358" y="1355"/>
+ <point x="-405" y="1355" type="curve" smooth="yes"/>
+ <point x="-447" y="1355"/>
+ <point x="-488" y="1374"/>
+ <point x="-560" y="1403" type="curve" smooth="yes"/>
+ <point x="-630" y="1431"/>
+ <point x="-677" y="1455"/>
+ <point x="-733" y="1455" type="curve" smooth="yes"/>
+ <point x="-852" y="1455"/>
+ <point x="-925" y="1327"/>
+ <point x="-925" y="1205" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfglyphs2ufo/PsfTest-Regular.ufo/glyphs/C_omma.glif b/tests/reference/ufo/psfglyphs2ufo/PsfTest-Regular.ufo/glyphs/C_omma.glif
new file mode 100644
index 0000000..6e8f5a3
--- /dev/null
+++ b/tests/reference/ufo/psfglyphs2ufo/PsfTest-Regular.ufo/glyphs/C_omma.glif
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="Comma" format="2">
+ <advance width="650"/>
+ <unicode hex="002C"/>
+ <outline>
+ <contour>
+ <point x="185" y="50" type="line"/>
+ <point x="325" y="50" type="line"/>
+ <point x="325" y="-51"/>
+ <point x="248" y="-172"/>
+ <point x="190" y="-230" type="curve"/>
+ <point x="290" y="-270" type="line"/>
+ <point x="407" y="-160"/>
+ <point x="465" y="-37"/>
+ <point x="465" y="85" type="curve" smooth="yes"/>
+ <point x="465" y="186"/>
+ <point x="400" y="250"/>
+ <point x="320" y="250" type="curve" smooth="yes"/>
+ <point x="263" y="250"/>
+ <point x="198" y="213"/>
+ <point x="185" y="150" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfglyphs2ufo/PsfTest-Regular.ufo/glyphs/D_igitE_ight.glif b/tests/reference/ufo/psfglyphs2ufo/PsfTest-Regular.ufo/glyphs/D_igitE_ight.glif
new file mode 100644
index 0000000..b7e540a
--- /dev/null
+++ b/tests/reference/ufo/psfglyphs2ufo/PsfTest-Regular.ufo/glyphs/D_igitE_ight.glif
@@ -0,0 +1,63 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="DigitEight" format="2">
+ <advance width="1200"/>
+ <unicode hex="0038"/>
+ <anchor x="600" y="-100" name="L"/>
+ <anchor x="600" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="600" y="-25" type="curve" smooth="yes"/>
+ <point x="857" y="-25"/>
+ <point x="1110" y="134"/>
+ <point x="1110" y="405" type="curve" smooth="yes"/>
+ <point x="1110" y="611"/>
+ <point x="965" y="739"/>
+ <point x="855" y="795" type="curve"/>
+ <point x="933" y="844"/>
+ <point x="1050" y="923"/>
+ <point x="1050" y="1105" type="curve" smooth="yes"/>
+ <point x="1050" y="1350"/>
+ <point x="840" y="1485"/>
+ <point x="610" y="1485" type="curve" smooth="yes"/>
+ <point x="381" y="1485"/>
+ <point x="150" y="1350"/>
+ <point x="150" y="1105" type="curve" smooth="yes"/>
+ <point x="150" y="923"/>
+ <point x="272" y="838"/>
+ <point x="350" y="795" type="curve"/>
+ <point x="221" y="725"/>
+ <point x="90" y="611"/>
+ <point x="90" y="405" type="curve" smooth="yes"/>
+ <point x="90" y="134"/>
+ <point x="344" y="-25"/>
+ </contour>
+ <contour>
+ <point x="860" y="1105" type="curve" smooth="yes"/>
+ <point x="860" y="949"/>
+ <point x="743" y="865"/>
+ <point x="600" y="865" type="curve" smooth="yes"/>
+ <point x="457" y="865"/>
+ <point x="340" y="949"/>
+ <point x="340" y="1105" type="curve" smooth="yes"/>
+ <point x="340" y="1252"/>
+ <point x="457" y="1325"/>
+ <point x="600" y="1325" type="curve" smooth="yes"/>
+ <point x="743" y="1325"/>
+ <point x="860" y="1252"/>
+ </contour>
+ <contour>
+ <point x="910" y="425" type="curve" smooth="yes"/>
+ <point x="910" y="250"/>
+ <point x="778" y="145"/>
+ <point x="600" y="145" type="curve" smooth="yes"/>
+ <point x="420" y="145"/>
+ <point x="290" y="250"/>
+ <point x="290" y="425" type="curve" smooth="yes"/>
+ <point x="290" y="592"/>
+ <point x="420" y="710"/>
+ <point x="600" y="710" type="curve" smooth="yes"/>
+ <point x="778" y="710"/>
+ <point x="910" y="592"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfglyphs2ufo/PsfTest-Regular.ufo/glyphs/D_igitF_ive.glif b/tests/reference/ufo/psfglyphs2ufo/PsfTest-Regular.ufo/glyphs/D_igitF_ive.glif
new file mode 100644
index 0000000..cb2dd85
--- /dev/null
+++ b/tests/reference/ufo/psfglyphs2ufo/PsfTest-Regular.ufo/glyphs/D_igitF_ive.glif
@@ -0,0 +1,44 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="DigitFive" format="2">
+ <advance width="1200"/>
+ <unicode hex="0035"/>
+ <anchor x="600" y="-100" name="L"/>
+ <anchor x="600" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="195" y="685" type="line"/>
+ <point x="319" y="733"/>
+ <point x="404" y="750"/>
+ <point x="510" y="750" type="curve" smooth="yes"/>
+ <point x="670" y="750"/>
+ <point x="870" y="672"/>
+ <point x="870" y="470" type="curve" smooth="yes"/>
+ <point x="870" y="268"/>
+ <point x="730" y="155"/>
+ <point x="530" y="155" type="curve" smooth="yes"/>
+ <point x="390" y="155"/>
+ <point x="294" y="182"/>
+ <point x="160" y="290" type="curve"/>
+ <point x="130" y="80" type="line"/>
+ <point x="255" y="2"/>
+ <point x="363" y="-25"/>
+ <point x="518" y="-25" type="curve" smooth="yes"/>
+ <point x="831" y="-25"/>
+ <point x="1060" y="163"/>
+ <point x="1060" y="475" type="curve" smooth="yes"/>
+ <point x="1060" y="742"/>
+ <point x="832" y="930"/>
+ <point x="545" y="930" type="curve" smooth="yes"/>
+ <point x="472" y="930"/>
+ <point x="411" y="924"/>
+ <point x="380" y="920" type="curve"/>
+ <point x="380" y="1290" type="line"/>
+ <point x="765" y="1290" type="line"/>
+ <point x="849" y="1290"/>
+ <point x="925" y="1286"/>
+ <point x="1000" y="1270" type="curve"/>
+ <point x="1000" y="1460" type="line"/>
+ <point x="195" y="1460" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfglyphs2ufo/PsfTest-Regular.ufo/glyphs/D_igitF_our.glif b/tests/reference/ufo/psfglyphs2ufo/PsfTest-Regular.ufo/glyphs/D_igitF_our.glif
new file mode 100644
index 0000000..d9a5610
--- /dev/null
+++ b/tests/reference/ufo/psfglyphs2ufo/PsfTest-Regular.ufo/glyphs/D_igitF_our.glif
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="DigitFour" format="2">
+ <advance width="1200"/>
+ <unicode hex="0034"/>
+ <anchor x="607" y="-100" name="L"/>
+ <anchor x="607" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="1125" y="395" type="line"/>
+ <point x="1125" y="550" type="line"/>
+ <point x="935" y="550" type="line"/>
+ <point x="935" y="1480" type="line"/>
+ <point x="745" y="1480" type="line"/>
+ <point x="90" y="550" type="line"/>
+ <point x="90" y="395" type="line"/>
+ <point x="745" y="395" type="line"/>
+ <point x="745" y="0" type="line"/>
+ <point x="935" y="0" type="line"/>
+ <point x="935" y="395" type="line"/>
+ </contour>
+ <contour>
+ <point x="745" y="1230" type="line"/>
+ <point x="745" y="550" type="line"/>
+ <point x="263" y="550" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfglyphs2ufo/PsfTest-Regular.ufo/glyphs/D_igitN_ine.glif b/tests/reference/ufo/psfglyphs2ufo/PsfTest-Regular.ufo/glyphs/D_igitN_ine.glif
new file mode 100644
index 0000000..0ce656a
--- /dev/null
+++ b/tests/reference/ufo/psfglyphs2ufo/PsfTest-Regular.ufo/glyphs/D_igitN_ine.glif
@@ -0,0 +1,49 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="DigitNine" format="2">
+ <advance width="1200"/>
+ <unicode hex="0039"/>
+ <anchor x="600" y="-100" name="L"/>
+ <anchor x="600" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="193" y="65" type="line"/>
+ <point x="297" y="-5"/>
+ <point x="383" y="-25"/>
+ <point x="501" y="-25" type="curve" smooth="yes"/>
+ <point x="976" y="-25"/>
+ <point x="1114" y="411"/>
+ <point x="1114" y="780" type="curve" smooth="yes"/>
+ <point x="1114" y="1198"/>
+ <point x="926" y="1485"/>
+ <point x="616" y="1485" type="curve" smooth="yes"/>
+ <point x="349" y="1485"/>
+ <point x="112" y="1306"/>
+ <point x="112" y="1002" type="curve" smooth="yes"/>
+ <point x="112" y="773"/>
+ <point x="281" y="586"/>
+ <point x="559" y="586" type="curve" smooth="yes"/>
+ <point x="750" y="586"/>
+ <point x="922" y="717"/>
+ <point x="1019" y="878" type="curve"/>
+ <point x="948" y="961" type="line"/>
+ <point x="874" y="847"/>
+ <point x="738" y="760"/>
+ <point x="583" y="760" type="curve" smooth="yes"/>
+ <point x="424" y="760"/>
+ <point x="306" y="860"/>
+ <point x="306" y="1036" type="curve" smooth="yes"/>
+ <point x="306" y="1196"/>
+ <point x="420" y="1310"/>
+ <point x="596" y="1310" type="curve" smooth="yes"/>
+ <point x="837" y="1310"/>
+ <point x="919" y="1065"/>
+ <point x="919" y="813" type="curve" smooth="yes"/>
+ <point x="919" y="326"/>
+ <point x="748" y="150"/>
+ <point x="511" y="150" type="curve" smooth="yes"/>
+ <point x="415" y="150"/>
+ <point x="323" y="174"/>
+ <point x="237" y="260" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfglyphs2ufo/PsfTest-Regular.ufo/glyphs/D_igitO_ne.glif b/tests/reference/ufo/psfglyphs2ufo/PsfTest-Regular.ufo/glyphs/D_igitO_ne.glif
new file mode 100644
index 0000000..42c7708
--- /dev/null
+++ b/tests/reference/ufo/psfglyphs2ufo/PsfTest-Regular.ufo/glyphs/D_igitO_ne.glif
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="DigitOne" format="2">
+ <advance width="1200"/>
+ <unicode hex="0031"/>
+ <anchor x="600" y="-100" name="L"/>
+ <anchor x="600" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="535" y="170" type="line"/>
+ <point x="220" y="170" type="line"/>
+ <point x="220" y="0" type="line"/>
+ <point x="1040" y="0" type="line"/>
+ <point x="1040" y="170" type="line"/>
+ <point x="725" y="170" type="line"/>
+ <point x="725" y="1480" type="line"/>
+ <point x="555" y="1480" type="line"/>
+ <point x="210" y="1268" type="line"/>
+ <point x="235" y="1088" type="line"/>
+ <point x="535" y="1260" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfglyphs2ufo/PsfTest-Regular.ufo/glyphs/D_igitS_even.glif b/tests/reference/ufo/psfglyphs2ufo/PsfTest-Regular.ufo/glyphs/D_igitS_even.glif
new file mode 100644
index 0000000..c9ca97e
--- /dev/null
+++ b/tests/reference/ufo/psfglyphs2ufo/PsfTest-Regular.ufo/glyphs/D_igitS_even.glif
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="DigitSeven" format="2">
+ <advance width="1200"/>
+ <unicode hex="0037"/>
+ <anchor x="600" y="-100" name="L"/>
+ <anchor x="600" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="460" y="0" type="line"/>
+ <point x="589" y="459"/>
+ <point x="794" y="895"/>
+ <point x="1090" y="1300" type="curve"/>
+ <point x="1090" y="1460" type="line"/>
+ <point x="100" y="1460" type="line"/>
+ <point x="100" y="1275" type="line"/>
+ <point x="176" y="1291"/>
+ <point x="292" y="1295"/>
+ <point x="480" y="1295" type="curve" smooth="yes"/>
+ <point x="870" y="1295" type="line"/>
+ <point x="612" y="912"/>
+ <point x="439" y="566"/>
+ <point x="275" y="0" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfglyphs2ufo/PsfTest-Regular.ufo/glyphs/D_igitS_ix.glif b/tests/reference/ufo/psfglyphs2ufo/PsfTest-Regular.ufo/glyphs/D_igitS_ix.glif
new file mode 100644
index 0000000..ec0acdb
--- /dev/null
+++ b/tests/reference/ufo/psfglyphs2ufo/PsfTest-Regular.ufo/glyphs/D_igitS_ix.glif
@@ -0,0 +1,49 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="DigitSix" format="2">
+ <advance width="1200"/>
+ <unicode hex="0036"/>
+ <anchor x="600" y="-100" name="L"/>
+ <anchor x="600" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="1033" y="1395" type="line"/>
+ <point x="929" y="1465"/>
+ <point x="843" y="1485"/>
+ <point x="725" y="1485" type="curve" smooth="yes"/>
+ <point x="250" y="1485"/>
+ <point x="110" y="1049"/>
+ <point x="110" y="680" type="curve" smooth="yes"/>
+ <point x="110" y="242"/>
+ <point x="290" y="-25"/>
+ <point x="600" y="-25" type="curve" smooth="yes"/>
+ <point x="907" y="-25"/>
+ <point x="1115" y="166"/>
+ <point x="1115" y="470" type="curve" smooth="yes"/>
+ <point x="1115" y="719"/>
+ <point x="943" y="895"/>
+ <point x="665" y="895" type="curve" smooth="yes"/>
+ <point x="474" y="895"/>
+ <point x="328" y="780"/>
+ <point x="215" y="625" type="curve"/>
+ <point x="280" y="550" type="line"/>
+ <point x="362" y="653"/>
+ <point x="490" y="720"/>
+ <point x="645" y="720" type="curve" smooth="yes"/>
+ <point x="824" y="720"/>
+ <point x="920" y="611"/>
+ <point x="920" y="435" type="curve" smooth="yes"/>
+ <point x="920" y="275"/>
+ <point x="806" y="150"/>
+ <point x="630" y="150" type="curve" smooth="yes"/>
+ <point x="409" y="150"/>
+ <point x="305" y="393"/>
+ <point x="305" y="645" type="curve" smooth="yes"/>
+ <point x="305" y="1132"/>
+ <point x="478" y="1310"/>
+ <point x="715" y="1310" type="curve" smooth="yes"/>
+ <point x="811" y="1310"/>
+ <point x="903" y="1286"/>
+ <point x="989" y="1200" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfglyphs2ufo/PsfTest-Regular.ufo/glyphs/D_igitT_hree.glif b/tests/reference/ufo/psfglyphs2ufo/PsfTest-Regular.ufo/glyphs/D_igitT_hree.glif
new file mode 100644
index 0000000..3242c12
--- /dev/null
+++ b/tests/reference/ufo/psfglyphs2ufo/PsfTest-Regular.ufo/glyphs/D_igitT_hree.glif
@@ -0,0 +1,52 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="DigitThree" format="2">
+ <advance width="1200"/>
+ <unicode hex="0033"/>
+ <anchor x="600" y="-100" name="L"/>
+ <anchor x="600" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="410" y="870" type="line"/>
+ <point x="410" y="700" type="line"/>
+ <point x="480" y="700" type="line"/>
+ <point x="716" y="700"/>
+ <point x="895" y="588"/>
+ <point x="895" y="425" type="curve" smooth="yes"/>
+ <point x="895" y="241"/>
+ <point x="718" y="150"/>
+ <point x="565" y="150" type="curve" smooth="yes"/>
+ <point x="385" y="150"/>
+ <point x="244" y="232"/>
+ <point x="135" y="355" type="curve"/>
+ <point x="110" y="140" type="line"/>
+ <point x="215" y="42"/>
+ <point x="368" y="-25"/>
+ <point x="545" y="-25" type="curve" smooth="yes"/>
+ <point x="834" y="-25"/>
+ <point x="1090" y="170"/>
+ <point x="1090" y="405" type="curve" smooth="yes"/>
+ <point x="1090" y="672"/>
+ <point x="862" y="776"/>
+ <point x="720" y="800" type="curve"/>
+ <point x="862" y="829"/>
+ <point x="1040" y="957"/>
+ <point x="1040" y="1140" type="curve" smooth="yes"/>
+ <point x="1040" y="1354"/>
+ <point x="828" y="1485"/>
+ <point x="580" y="1485" type="curve"/>
+ <point x="413" y="1485"/>
+ <point x="260" y="1416"/>
+ <point x="180" y="1325" type="curve"/>
+ <point x="215" y="1155" type="line"/>
+ <point x="328" y="1271"/>
+ <point x="436" y="1310"/>
+ <point x="590" y="1310" type="curve" smooth="yes"/>
+ <point x="711" y="1310"/>
+ <point x="850" y="1250"/>
+ <point x="850" y="1115" type="curve" smooth="yes"/>
+ <point x="850" y="991"/>
+ <point x="679" y="870"/>
+ <point x="480" y="870" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfglyphs2ufo/PsfTest-Regular.ufo/glyphs/D_igitT_wo.glif b/tests/reference/ufo/psfglyphs2ufo/PsfTest-Regular.ufo/glyphs/D_igitT_wo.glif
new file mode 100644
index 0000000..c179477
--- /dev/null
+++ b/tests/reference/ufo/psfglyphs2ufo/PsfTest-Regular.ufo/glyphs/D_igitT_wo.glif
@@ -0,0 +1,37 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="DigitTwo" format="2">
+ <advance width="1200"/>
+ <unicode hex="0032"/>
+ <anchor x="600" y="-100" name="L"/>
+ <anchor x="560" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="1080" y="180" type="line"/>
+ <point x="1000" y="166"/>
+ <point x="842" y="165"/>
+ <point x="645" y="165" type="curve" smooth="yes"/>
+ <point x="390" y="165" type="line"/>
+ <point x="609" y="352"/>
+ <point x="1010" y="729"/>
+ <point x="1010" y="1065" type="curve" smooth="yes"/>
+ <point x="1010" y="1323"/>
+ <point x="800" y="1485"/>
+ <point x="560" y="1485" type="curve" smooth="yes"/>
+ <point x="391" y="1485"/>
+ <point x="206" y="1402"/>
+ <point x="125" y="1290" type="curve"/>
+ <point x="170" y="1120" type="line"/>
+ <point x="259" y="1228"/>
+ <point x="402" y="1305"/>
+ <point x="525" y="1305" type="curve" smooth="yes"/>
+ <point x="668" y="1305"/>
+ <point x="810" y="1233"/>
+ <point x="810" y="1045" type="curve" smooth="yes"/>
+ <point x="810" y="768"/>
+ <point x="391" y="365"/>
+ <point x="120" y="170" type="curve"/>
+ <point x="120" y="0" type="line"/>
+ <point x="1080" y="0" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfglyphs2ufo/PsfTest-Regular.ufo/glyphs/D_igitZ_ero.glif b/tests/reference/ufo/psfglyphs2ufo/PsfTest-Regular.ufo/glyphs/D_igitZ_ero.glif
new file mode 100644
index 0000000..d976d0f
--- /dev/null
+++ b/tests/reference/ufo/psfglyphs2ufo/PsfTest-Regular.ufo/glyphs/D_igitZ_ero.glif
@@ -0,0 +1,37 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="DigitZero" format="2">
+ <advance width="1200"/>
+ <unicode hex="0030"/>
+ <anchor x="605" y="-100" name="L"/>
+ <anchor x="605" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="910" y="715" type="curve" smooth="yes"/>
+ <point x="910" y="308"/>
+ <point x="792" y="145"/>
+ <point x="600" y="145" type="curve" smooth="yes"/>
+ <point x="402" y="145"/>
+ <point x="290" y="305"/>
+ <point x="290" y="745" type="curve" smooth="yes"/>
+ <point x="290" y="1153"/>
+ <point x="407" y="1315"/>
+ <point x="600" y="1315" type="curve" smooth="yes"/>
+ <point x="802" y="1315"/>
+ <point x="910" y="1156"/>
+ </contour>
+ <contour>
+ <point x="1110" y="740" type="curve" smooth="yes"/>
+ <point x="1110" y="1286"/>
+ <point x="900" y="1485"/>
+ <point x="610" y="1485" type="curve" smooth="yes"/>
+ <point x="321" y="1485"/>
+ <point x="90" y="1283"/>
+ <point x="90" y="720" type="curve" smooth="yes"/>
+ <point x="90" y="155"/>
+ <point x="301" y="-25"/>
+ <point x="590" y="-25" type="curve" smooth="yes"/>
+ <point x="881" y="-25"/>
+ <point x="1110" y="151"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfglyphs2ufo/PsfTest-Regular.ufo/glyphs/D_ollarS_gn.glif b/tests/reference/ufo/psfglyphs2ufo/PsfTest-Regular.ufo/glyphs/D_ollarS_gn.glif
new file mode 100644
index 0000000..52136d8
--- /dev/null
+++ b/tests/reference/ufo/psfglyphs2ufo/PsfTest-Regular.ufo/glyphs/D_ollarS_gn.glif
@@ -0,0 +1,53 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="DollarSgn" format="2">
+ <advance width="1200"/>
+ <unicode hex="0024"/>
+ <outline>
+ <contour>
+ <point x="553" y="1600" type="line"/>
+ <point x="553" y="-220" type="line"/>
+ <point x="683" y="-220" type="line"/>
+ <point x="683" y="1600" type="line"/>
+ </contour>
+ <contour>
+ <point x="986" y="1306" type="line"/>
+ <point x="866" y="1364"/>
+ <point x="764" y="1389"/>
+ <point x="623" y="1389" type="curve" smooth="yes"/>
+ <point x="317" y="1389"/>
+ <point x="190" y="1173"/>
+ <point x="190" y="1017" type="curve" smooth="yes"/>
+ <point x="190" y="860"/>
+ <point x="253" y="739"/>
+ <point x="540" y="653" type="curve" smooth="yes"/>
+ <point x="827" y="567"/>
+ <point x="871" y="492"/>
+ <point x="871" y="396" type="curve" smooth="yes"/>
+ <point x="871" y="247"/>
+ <point x="734" y="161"/>
+ <point x="586" y="161" type="curve" smooth="yes"/>
+ <point x="450" y="161"/>
+ <point x="316" y="207"/>
+ <point x="195" y="313" type="curve"/>
+ <point x="153" y="124" type="line"/>
+ <point x="247" y="52"/>
+ <point x="408" y="0"/>
+ <point x="586" y="0" type="curve" smooth="yes"/>
+ <point x="837" y="0"/>
+ <point x="1046" y="167"/>
+ <point x="1046" y="414" type="curve" smooth="yes"/>
+ <point x="1046" y="613"/>
+ <point x="912" y="725"/>
+ <point x="669" y="796" type="curve" smooth="yes"/>
+ <point x="406" y="873"/>
+ <point x="365" y="929"/>
+ <point x="365" y="1030" type="curve" smooth="yes"/>
+ <point x="365" y="1132"/>
+ <point x="466" y="1228"/>
+ <point x="613" y="1228" type="curve" smooth="yes"/>
+ <point x="731" y="1228"/>
+ <point x="818" y="1200"/>
+ <point x="949" y="1127" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfglyphs2ufo/PsfTest-Regular.ufo/glyphs/D_ottedC_irc.glif b/tests/reference/ufo/psfglyphs2ufo/PsfTest-Regular.ufo/glyphs/D_ottedC_irc.glif
new file mode 100644
index 0000000..4cf5cb4
--- /dev/null
+++ b/tests/reference/ufo/psfglyphs2ufo/PsfTest-Regular.ufo/glyphs/D_ottedC_irc.glif
@@ -0,0 +1,235 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="DottedCirc" format="2">
+ <advance width="1106"/>
+ <unicode hex="25CC"/>
+ <anchor x="553" y="0" name="H"/>
+ <anchor x="553" y="-100" name="L"/>
+ <anchor x="810" y="0" name="O"/>
+ <anchor x="553" y="1000" name="U"/>
+ <outline>
+ <contour>
+ <point x="443" y="837" type="curve" smooth="yes"/>
+ <point x="443" y="864"/>
+ <point x="423" y="885"/>
+ <point x="398" y="885" type="curve" smooth="yes"/>
+ <point x="371" y="885"/>
+ <point x="348" y="861"/>
+ <point x="348" y="837" type="curve" smooth="yes"/>
+ <point x="348" y="809"/>
+ <point x="372" y="789"/>
+ <point x="398" y="789" type="curve" smooth="yes"/>
+ <point x="425" y="789"/>
+ <point x="443" y="812"/>
+ </contour>
+ <contour>
+ <point x="758" y="79" type="curve" smooth="yes"/>
+ <point x="758" y="106"/>
+ <point x="736" y="127"/>
+ <point x="710" y="127" type="curve" smooth="yes"/>
+ <point x="685" y="127"/>
+ <point x="662" y="103"/>
+ <point x="662" y="80" type="curve" smooth="yes"/>
+ <point x="662" y="52"/>
+ <point x="686" y="31"/>
+ <point x="710" y="31" type="curve" smooth="yes"/>
+ <point x="737" y="31"/>
+ <point x="758" y="55"/>
+ </contour>
+ <contour>
+ <point x="310" y="749" type="curve" smooth="yes"/>
+ <point x="310" y="775"/>
+ <point x="288" y="796"/>
+ <point x="263" y="796" type="curve" smooth="yes"/>
+ <point x="238" y="796"/>
+ <point x="215" y="774"/>
+ <point x="215" y="747" type="curve" smooth="yes"/>
+ <point x="215" y="722"/>
+ <point x="236" y="701"/>
+ <point x="263" y="701" type="curve" smooth="yes"/>
+ <point x="291" y="701"/>
+ <point x="310" y="720"/>
+ </contour>
+ <contour>
+ <point x="891" y="168" type="curve" smooth="yes"/>
+ <point x="891" y="197"/>
+ <point x="870" y="215"/>
+ <point x="843" y="215" type="curve" smooth="yes"/>
+ <point x="817" y="215"/>
+ <point x="795" y="194"/>
+ <point x="795" y="168" type="curve" smooth="yes"/>
+ <point x="795" y="143"/>
+ <point x="816" y="121"/>
+ <point x="843" y="121" type="curve" smooth="yes"/>
+ <point x="871" y="121"/>
+ <point x="891" y="143"/>
+ </contour>
+ <contour>
+ <point x="222" y="613" type="curve" smooth="yes"/>
+ <point x="222" y="640"/>
+ <point x="199" y="663"/>
+ <point x="173" y="663" type="curve" smooth="yes"/>
+ <point x="149" y="663"/>
+ <point x="126" y="642"/>
+ <point x="126" y="615" type="curve" smooth="yes"/>
+ <point x="126" y="591"/>
+ <point x="145" y="567"/>
+ <point x="173" y="567" type="curve" smooth="yes"/>
+ <point x="197" y="567"/>
+ <point x="222" y="587"/>
+ </contour>
+ <contour>
+ <point x="980" y="301" type="curve" smooth="yes"/>
+ <point x="980" y="327"/>
+ <point x="957" y="348"/>
+ <point x="932" y="348" type="curve" smooth="yes"/>
+ <point x="908" y="348"/>
+ <point x="884" y="332"/>
+ <point x="884" y="301" type="curve" smooth="yes"/>
+ <point x="884" y="277"/>
+ <point x="902" y="254"/>
+ <point x="932" y="254" type="curve" smooth="yes"/>
+ <point x="957" y="254"/>
+ <point x="980" y="274"/>
+ </contour>
+ <contour>
+ <point x="191" y="459" type="curve" smooth="yes"/>
+ <point x="191" y="484"/>
+ <point x="168" y="505"/>
+ <point x="143" y="505" type="curve" smooth="yes"/>
+ <point x="116" y="505"/>
+ <point x="95" y="484"/>
+ <point x="95" y="458" type="curve" smooth="yes"/>
+ <point x="95" y="433"/>
+ <point x="115" y="410"/>
+ <point x="143" y="410" type="curve" smooth="yes"/>
+ <point x="167" y="410"/>
+ <point x="191" y="432"/>
+ </contour>
+ <contour>
+ <point x="1011" y="458" type="curve" smooth="yes"/>
+ <point x="1011" y="484"/>
+ <point x="990" y="506"/>
+ <point x="964" y="506" type="curve" smooth="yes"/>
+ <point x="940" y="506"/>
+ <point x="915" y="484"/>
+ <point x="915" y="457" type="curve" smooth="yes"/>
+ <point x="915" y="433"/>
+ <point x="936" y="411"/>
+ <point x="964" y="411" type="curve" smooth="yes"/>
+ <point x="990" y="411"/>
+ <point x="1011" y="433"/>
+ </contour>
+ <contour>
+ <point x="222" y="302" type="curve" smooth="yes"/>
+ <point x="222" y="328"/>
+ <point x="200" y="348"/>
+ <point x="174" y="348" type="curve" smooth="yes"/>
+ <point x="147" y="348"/>
+ <point x="126" y="326"/>
+ <point x="126" y="302" type="curve" smooth="yes"/>
+ <point x="126" y="275"/>
+ <point x="149" y="253"/>
+ <point x="174" y="253" type="curve" smooth="yes"/>
+ <point x="201" y="253"/>
+ <point x="222" y="277"/>
+ </contour>
+ <contour>
+ <point x="980" y="615" type="curve" smooth="yes"/>
+ <point x="980" y="642"/>
+ <point x="955" y="663"/>
+ <point x="931" y="663" type="curve" smooth="yes"/>
+ <point x="904" y="663"/>
+ <point x="885" y="638"/>
+ <point x="885" y="614" type="curve" smooth="yes"/>
+ <point x="885" y="588"/>
+ <point x="907" y="567"/>
+ <point x="931" y="567" type="curve" smooth="yes"/>
+ <point x="959" y="567"/>
+ <point x="980" y="591"/>
+ </contour>
+ <contour>
+ <point x="310" y="168" type="curve" smooth="yes"/>
+ <point x="310" y="195"/>
+ <point x="291" y="215"/>
+ <point x="263" y="215" type="curve" smooth="yes"/>
+ <point x="238" y="215"/>
+ <point x="215" y="190"/>
+ <point x="215" y="168" type="curve" smooth="yes"/>
+ <point x="215" y="143"/>
+ <point x="238" y="120"/>
+ <point x="263" y="120" type="curve" smooth="yes"/>
+ <point x="289" y="120"/>
+ <point x="310" y="143"/>
+ </contour>
+ <contour>
+ <point x="890" y="748" type="curve" smooth="yes"/>
+ <point x="890" y="774"/>
+ <point x="870" y="796"/>
+ <point x="843" y="796" type="curve" smooth="yes"/>
+ <point x="815" y="796"/>
+ <point x="796" y="773"/>
+ <point x="796" y="748" type="curve" smooth="yes"/>
+ <point x="796" y="724"/>
+ <point x="817" y="700"/>
+ <point x="843" y="700" type="curve" smooth="yes"/>
+ <point x="869" y="700"/>
+ <point x="890" y="722"/>
+ </contour>
+ <contour>
+ <point x="444" y="78" type="curve" smooth="yes"/>
+ <point x="444" y="102"/>
+ <point x="423" y="126"/>
+ <point x="396" y="126" type="curve" smooth="yes"/>
+ <point x="370" y="126"/>
+ <point x="348" y="102"/>
+ <point x="348" y="78" type="curve" smooth="yes"/>
+ <point x="348" y="55"/>
+ <point x="370" y="31"/>
+ <point x="396" y="31" type="curve" smooth="yes"/>
+ <point x="420" y="31"/>
+ <point x="444" y="51"/>
+ </contour>
+ <contour>
+ <point x="758" y="836" type="curve" smooth="yes"/>
+ <point x="758" y="861"/>
+ <point x="737" y="885"/>
+ <point x="710" y="885" type="curve" smooth="yes"/>
+ <point x="684" y="885"/>
+ <point x="663" y="862"/>
+ <point x="663" y="838" type="curve" smooth="yes"/>
+ <point x="663" y="814"/>
+ <point x="683" y="789"/>
+ <point x="710" y="789" type="curve" smooth="yes"/>
+ <point x="734" y="789"/>
+ <point x="758" y="809"/>
+ </contour>
+ <contour>
+ <point x="601" y="47" type="curve" smooth="yes"/>
+ <point x="601" y="73"/>
+ <point x="579" y="95"/>
+ <point x="553" y="95" type="curve" smooth="yes"/>
+ <point x="527" y="95"/>
+ <point x="506" y="73"/>
+ <point x="506" y="47" type="curve" smooth="yes"/>
+ <point x="506" y="21"/>
+ <point x="527" y="0"/>
+ <point x="553" y="0" type="curve" smooth="yes"/>
+ <point x="579" y="0"/>
+ <point x="601" y="21"/>
+ </contour>
+ <contour>
+ <point x="601" y="868" type="curve" smooth="yes"/>
+ <point x="601" y="894"/>
+ <point x="579" y="916"/>
+ <point x="553" y="916" type="curve" smooth="yes"/>
+ <point x="527" y="916"/>
+ <point x="506" y="894"/>
+ <point x="506" y="868" type="curve" smooth="yes"/>
+ <point x="506" y="842"/>
+ <point x="527" y="821"/>
+ <point x="553" y="821" type="curve" smooth="yes"/>
+ <point x="579" y="821"/>
+ <point x="601" y="842"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfglyphs2ufo/PsfTest-Regular.ufo/glyphs/E_qS_gn.glif b/tests/reference/ufo/psfglyphs2ufo/PsfTest-Regular.ufo/glyphs/E_qS_gn.glif
new file mode 100644
index 0000000..1315ffa
--- /dev/null
+++ b/tests/reference/ufo/psfglyphs2ufo/PsfTest-Regular.ufo/glyphs/E_qS_gn.glif
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="EqSgn" format="2">
+ <advance width="1200"/>
+ <unicode hex="003D"/>
+ <outline>
+ <contour>
+ <point x="120" y="480" type="line"/>
+ <point x="1080" y="480" type="line"/>
+ <point x="1080" y="630" type="line"/>
+ <point x="120" y="630" type="line"/>
+ </contour>
+ <contour>
+ <point x="120" y="830" type="line"/>
+ <point x="1080" y="830" type="line"/>
+ <point x="1080" y="980" type="line"/>
+ <point x="120" y="980" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfglyphs2ufo/PsfTest-Regular.ufo/glyphs/E_xclamationM_rk.glif b/tests/reference/ufo/psfglyphs2ufo/PsfTest-Regular.ufo/glyphs/E_xclamationM_rk.glif
new file mode 100644
index 0000000..e683644
--- /dev/null
+++ b/tests/reference/ufo/psfglyphs2ufo/PsfTest-Regular.ufo/glyphs/E_xclamationM_rk.glif
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="ExclamationMrk" format="2">
+ <advance width="764"/>
+ <unicode hex="0021"/>
+ <outline>
+ <contour>
+ <point x="450" y="440" type="line"/>
+ <point x="456" y="730"/>
+ <point x="451" y="1076"/>
+ <point x="490" y="1510" type="curve"/>
+ <point x="235" y="1510" type="line"/>
+ <point x="273" y="1076"/>
+ <point x="268" y="730"/>
+ <point x="275" y="440" type="curve"/>
+ </contour>
+ <contour>
+ <point x="225" y="110" type="curve" smooth="yes"/>
+ <point x="225" y="36"/>
+ <point x="286" y="-25"/>
+ <point x="360" y="-25" type="curve" smooth="yes"/>
+ <point x="434" y="-25"/>
+ <point x="495" y="36"/>
+ <point x="495" y="110" type="curve" smooth="yes"/>
+ <point x="495" y="184"/>
+ <point x="434" y="245"/>
+ <point x="360" y="245" type="curve" smooth="yes"/>
+ <point x="286" y="245"/>
+ <point x="225" y="184"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfglyphs2ufo/PsfTest-Regular.ufo/glyphs/F_ullS_top.glif b/tests/reference/ufo/psfglyphs2ufo/PsfTest-Regular.ufo/glyphs/F_ullS_top.glif
new file mode 100644
index 0000000..9f3a3f0
--- /dev/null
+++ b/tests/reference/ufo/psfglyphs2ufo/PsfTest-Regular.ufo/glyphs/F_ullS_top.glif
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="FullStop" format="2">
+ <advance width="640"/>
+ <unicode hex="002E"/>
+ <outline>
+ <contour>
+ <point x="185" y="110" type="curve" smooth="yes"/>
+ <point x="185" y="36"/>
+ <point x="246" y="-25"/>
+ <point x="320" y="-25" type="curve" smooth="yes"/>
+ <point x="394" y="-25"/>
+ <point x="455" y="36"/>
+ <point x="455" y="110" type="curve" smooth="yes"/>
+ <point x="455" y="184"/>
+ <point x="394" y="245"/>
+ <point x="320" y="245" type="curve" smooth="yes"/>
+ <point x="246" y="245"/>
+ <point x="185" y="184"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfglyphs2ufo/PsfTest-Regular.ufo/glyphs/G_T_S_gn.glif b/tests/reference/ufo/psfglyphs2ufo/PsfTest-Regular.ufo/glyphs/G_T_S_gn.glif
new file mode 100644
index 0000000..c591997
--- /dev/null
+++ b/tests/reference/ufo/psfglyphs2ufo/PsfTest-Regular.ufo/glyphs/G_T_S_gn.glif
@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="GTSgn" format="2">
+ <advance width="1200"/>
+ <unicode hex="003E"/>
+ <outline>
+ <contour>
+ <point x="120" y="1035" type="line"/>
+ <point x="910" y="730" type="line"/>
+ <point x="120" y="425" type="line"/>
+ <point x="120" y="245" type="line"/>
+ <point x="1100" y="645" type="line"/>
+ <point x="1100" y="815" type="line"/>
+ <point x="120" y="1215" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfglyphs2ufo/PsfTest-Regular.ufo/glyphs/G_raveA_ccent.glif b/tests/reference/ufo/psfglyphs2ufo/PsfTest-Regular.ufo/glyphs/G_raveA_ccent.glif
new file mode 100644
index 0000000..a0a0004
--- /dev/null
+++ b/tests/reference/ufo/psfglyphs2ufo/PsfTest-Regular.ufo/glyphs/G_raveA_ccent.glif
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="GraveAccent" format="2">
+ <advance width="580"/>
+ <unicode hex="0060"/>
+ <outline>
+ <component base="CombGrave" xOffset="940"/>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfglyphs2ufo/PsfTest-Regular.ufo/glyphs/H_yphen.glif b/tests/reference/ufo/psfglyphs2ufo/PsfTest-Regular.ufo/glyphs/H_yphen.glif
new file mode 100644
index 0000000..fabf6ce
--- /dev/null
+++ b/tests/reference/ufo/psfglyphs2ufo/PsfTest-Regular.ufo/glyphs/H_yphen.glif
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="Hyphen" format="2">
+ <advance width="860"/>
+ <unicode hex="2010"/>
+ <anchor x="430" y="1100" name="U"/>
+ <outline>
+ <contour>
+ <point x="80" y="555" type="line"/>
+ <point x="780" y="555" type="line"/>
+ <point x="780" y="705" type="line"/>
+ <point x="80" y="705" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfglyphs2ufo/PsfTest-Regular.ufo/glyphs/H_yphenM_inus.glif b/tests/reference/ufo/psfglyphs2ufo/PsfTest-Regular.ufo/glyphs/H_yphenM_inus.glif
new file mode 100644
index 0000000..bc3f4eb
--- /dev/null
+++ b/tests/reference/ufo/psfglyphs2ufo/PsfTest-Regular.ufo/glyphs/H_yphenM_inus.glif
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="HyphenMinus" format="2">
+ <advance width="860"/>
+ <unicode hex="002D"/>
+ <anchor x="430" y="1100" name="U"/>
+ <outline>
+ <contour>
+ <point x="80" y="555" type="line"/>
+ <point x="780" y="555" type="line"/>
+ <point x="780" y="705" type="line"/>
+ <point x="80" y="705" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfglyphs2ufo/PsfTest-Regular.ufo/glyphs/H_yphen_S_oft.glif b/tests/reference/ufo/psfglyphs2ufo/PsfTest-Regular.ufo/glyphs/H_yphen_S_oft.glif
new file mode 100644
index 0000000..293b653
--- /dev/null
+++ b/tests/reference/ufo/psfglyphs2ufo/PsfTest-Regular.ufo/glyphs/H_yphen_S_oft.glif
@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="Hyphen_Soft" format="2">
+ <advance width="860"/>
+ <unicode hex="00AD"/>
+ <anchor x="430" y="1100" name="U"/>
+ <outline>
+ <component base="HyphenMinus"/>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfglyphs2ufo/PsfTest-Regular.ufo/glyphs/L_T_S_gn.glif b/tests/reference/ufo/psfglyphs2ufo/PsfTest-Regular.ufo/glyphs/L_T_S_gn.glif
new file mode 100644
index 0000000..db9ae78
--- /dev/null
+++ b/tests/reference/ufo/psfglyphs2ufo/PsfTest-Regular.ufo/glyphs/L_T_S_gn.glif
@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LTSgn" format="2">
+ <advance width="1200"/>
+ <unicode hex="003C"/>
+ <outline>
+ <contour>
+ <point x="1080" y="425" type="line"/>
+ <point x="290" y="730" type="line"/>
+ <point x="1080" y="1035" type="line"/>
+ <point x="1080" y="1215" type="line"/>
+ <point x="100" y="815" type="line"/>
+ <point x="100" y="645" type="line"/>
+ <point x="1080" y="245" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfglyphs2ufo/PsfTest-Regular.ufo/glyphs/L_ftC_urlyB_rac.glif b/tests/reference/ufo/psfglyphs2ufo/PsfTest-Regular.ufo/glyphs/L_ftC_urlyB_rac.glif
new file mode 100644
index 0000000..bc7ef03
--- /dev/null
+++ b/tests/reference/ufo/psfglyphs2ufo/PsfTest-Regular.ufo/glyphs/L_ftC_urlyB_rac.glif
@@ -0,0 +1,47 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LftCurlyBrac" format="2">
+ <advance width="1000"/>
+ <unicode hex="007B"/>
+ <outline>
+ <contour>
+ <point x="210" y="615" type="curve" smooth="yes"/>
+ <point x="210" y="583"/>
+ <point x="383" y="486"/>
+ <point x="410" y="450" type="curve" smooth="yes"/>
+ <point x="434" y="418"/>
+ <point x="424" y="-205"/>
+ <point x="495" y="-285" type="curve" smooth="yes"/>
+ <point x="535" y="-330"/>
+ <point x="696" y="-383"/>
+ <point x="800" y="-410" type="curve"/>
+ <point x="840" y="-270" type="line"/>
+ <point x="773" y="-247"/>
+ <point x="650" y="-198"/>
+ <point x="630" y="-170" type="curve" smooth="yes"/>
+ <point x="597" y="-123"/>
+ <point x="610" y="447"/>
+ <point x="590" y="485" type="curve" smooth="yes"/>
+ <point x="571" y="521"/>
+ <point x="434" y="593"/>
+ <point x="430" y="615" type="curve"/>
+ <point x="434" y="637"/>
+ <point x="571" y="709"/>
+ <point x="590" y="745" type="curve" smooth="yes"/>
+ <point x="610" y="783"/>
+ <point x="597" y="1353"/>
+ <point x="630" y="1400" type="curve" smooth="yes"/>
+ <point x="650" y="1428"/>
+ <point x="773" y="1477"/>
+ <point x="840" y="1500" type="curve"/>
+ <point x="800" y="1640" type="line"/>
+ <point x="696" y="1613"/>
+ <point x="535" y="1560"/>
+ <point x="495" y="1515" type="curve" smooth="yes"/>
+ <point x="424" y="1435"/>
+ <point x="434" y="812"/>
+ <point x="410" y="780" type="curve" smooth="yes"/>
+ <point x="383" y="744"/>
+ <point x="210" y="647"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfglyphs2ufo/PsfTest-Regular.ufo/glyphs/L_ftP_aren.glif b/tests/reference/ufo/psfglyphs2ufo/PsfTest-Regular.ufo/glyphs/L_ftP_aren.glif
new file mode 100644
index 0000000..a4b9814
--- /dev/null
+++ b/tests/reference/ufo/psfglyphs2ufo/PsfTest-Regular.ufo/glyphs/L_ftP_aren.glif
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LftParen" format="2">
+ <advance width="795"/>
+ <unicode hex="0028"/>
+ <outline>
+ <contour>
+ <point x="115" y="625" type="curve" smooth="yes"/>
+ <point x="115" y="218"/>
+ <point x="260" y="-125"/>
+ <point x="535" y="-410" type="curve"/>
+ <point x="630" y="-265" type="line"/>
+ <point x="395" y="-8"/>
+ <point x="305" y="278"/>
+ <point x="305" y="625" type="curve" smooth="yes"/>
+ <point x="305" y="982"/>
+ <point x="395" y="1280"/>
+ <point x="630" y="1485" type="curve"/>
+ <point x="555" y="1640" type="line"/>
+ <point x="290" y="1444"/>
+ <point x="115" y="1062"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfglyphs2ufo/PsfTest-Regular.ufo/glyphs/L_ftS_qrB_rac.glif b/tests/reference/ufo/psfglyphs2ufo/PsfTest-Regular.ufo/glyphs/L_ftS_qrB_rac.glif
new file mode 100644
index 0000000..e97ed98
--- /dev/null
+++ b/tests/reference/ufo/psfglyphs2ufo/PsfTest-Regular.ufo/glyphs/L_ftS_qrB_rac.glif
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LftSqrBrac" format="2">
+ <advance width="790"/>
+ <unicode hex="005B"/>
+ <outline>
+ <contour>
+ <point x="640" y="-410" type="line"/>
+ <point x="640" y="-260" type="line"/>
+ <point x="385" y="-260" type="line"/>
+ <point x="385" y="1450" type="line"/>
+ <point x="640" y="1450" type="line"/>
+ <point x="640" y="1600" type="line"/>
+ <point x="200" y="1600" type="line"/>
+ <point x="200" y="-410" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfglyphs2ufo/PsfTest-Regular.ufo/glyphs/L_owL_ine.glif b/tests/reference/ufo/psfglyphs2ufo/PsfTest-Regular.ufo/glyphs/L_owL_ine.glif
new file mode 100644
index 0000000..2fc71eb
--- /dev/null
+++ b/tests/reference/ufo/psfglyphs2ufo/PsfTest-Regular.ufo/glyphs/L_owL_ine.glif
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LowLine" format="2">
+ <advance width="1274"/>
+ <unicode hex="005F"/>
+ <outline>
+ <contour>
+ <point x="0" y="-320" type="line"/>
+ <point x="1274" y="-320" type="line"/>
+ <point x="1274" y="-170" type="line"/>
+ <point x="0" y="-170" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfglyphs2ufo/PsfTest-Regular.ufo/glyphs/L_tnC_apA_.alt.glif b/tests/reference/ufo/psfglyphs2ufo/PsfTest-Regular.ufo/glyphs/L_tnC_apA_.alt.glif
new file mode 100644
index 0000000..fbdfff2
--- /dev/null
+++ b/tests/reference/ufo/psfglyphs2ufo/PsfTest-Regular.ufo/glyphs/L_tnC_apA_.alt.glif
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnCapA.alt" format="2">
+ <advance width="1395"/>
+ <anchor x="668" y="1460" name="H"/>
+ <anchor x="688" y="1560" name="L"/>
+ <anchor x="-75" y="1460" name="O"/>
+ <anchor x="688" y="-70" name="U"/>
+ <outline>
+ <contour>
+ <point x="1130" y="1460" type="line"/>
+ <point x="996" y="1075" type="line"/>
+ <point x="381" y="1075" type="line"/>
+ <point x="245" y="1460" type="line"/>
+ <point x="40" y="1460" type="line"/>
+ <point x="75" y="1380"/>
+ <point x="113" y="1291"/>
+ <point x="180" y="1105" type="curve" smooth="yes"/>
+ <point x="580" y="0" type="line"/>
+ <point x="795" y="0" type="line"/>
+ <point x="1195" y="1105" type="line" smooth="yes"/>
+ <point x="1263" y="1292"/>
+ <point x="1299" y="1379"/>
+ <point x="1335" y="1460" type="curve"/>
+ </contour>
+ <contour>
+ <point x="435" y="920" type="line"/>
+ <point x="942" y="920" type="line"/>
+ <point x="690" y="195" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfglyphs2ufo/PsfTest-Regular.ufo/glyphs/L_tnC_apA_.glif b/tests/reference/ufo/psfglyphs2ufo/PsfTest-Regular.ufo/glyphs/L_tnC_apA_.glif
new file mode 100644
index 0000000..3c64e18
--- /dev/null
+++ b/tests/reference/ufo/psfglyphs2ufo/PsfTest-Regular.ufo/glyphs/L_tnC_apA_.glif
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnCapA" format="2">
+ <advance width="1395"/>
+ <unicode hex="0041"/>
+ <anchor x="707" y="0" name="H"/>
+ <anchor x="687" y="-100" name="L"/>
+ <anchor x="1450" y="0" name="O"/>
+ <anchor x="687" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="245" y="0" type="line"/>
+ <point x="379" y="385" type="line"/>
+ <point x="994" y="385" type="line"/>
+ <point x="1130" y="0" type="line"/>
+ <point x="1335" y="0" type="line"/>
+ <point x="1300" y="80"/>
+ <point x="1262" y="169"/>
+ <point x="1195" y="355" type="curve" smooth="yes"/>
+ <point x="795" y="1460" type="line"/>
+ <point x="580" y="1460" type="line"/>
+ <point x="180" y="355" type="line" smooth="yes"/>
+ <point x="112" y="168"/>
+ <point x="76" y="81"/>
+ <point x="40" y="0" type="curve"/>
+ </contour>
+ <contour>
+ <point x="940" y="540" type="line"/>
+ <point x="433" y="540" type="line"/>
+ <point x="685" y="1265" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfglyphs2ufo/PsfTest-Regular.ufo/glyphs/L_tnC_apA_D_iaer.glif b/tests/reference/ufo/psfglyphs2ufo/PsfTest-Regular.ufo/glyphs/L_tnC_apA_D_iaer.glif
new file mode 100644
index 0000000..b74cc60
--- /dev/null
+++ b/tests/reference/ufo/psfglyphs2ufo/PsfTest-Regular.ufo/glyphs/L_tnC_apA_D_iaer.glif
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnCapADiaer" format="2">
+ <advance width="1395"/>
+ <unicode hex="00C4"/>
+ <anchor x="707" y="0" name="H"/>
+ <anchor x="687" y="-100" name="L"/>
+ <anchor x="1450" y="0" name="O"/>
+ <anchor x="687" y="1935" name="U"/>
+ <outline>
+ <component base="LtnCapA"/>
+ <component base="CombDiaer" xOffset="1257" yOffset="430"/>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfglyphs2ufo/PsfTest-Regular.ufo/glyphs/L_tnC_apB_.glif b/tests/reference/ufo/psfglyphs2ufo/PsfTest-Regular.ufo/glyphs/L_tnC_apB_.glif
new file mode 100644
index 0000000..415122e
--- /dev/null
+++ b/tests/reference/ufo/psfglyphs2ufo/PsfTest-Regular.ufo/glyphs/L_tnC_apB_.glif
@@ -0,0 +1,62 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnCapB" format="2">
+ <advance width="1285"/>
+ <unicode hex="0042"/>
+ <anchor x="615" y="-100" name="L"/>
+ <anchor x="615" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="365" y="1310" type="line"/>
+ <point x="407" y="1312"/>
+ <point x="512" y="1315"/>
+ <point x="590" y="1315" type="curve" smooth="yes"/>
+ <point x="791" y="1315"/>
+ <point x="870" y="1239"/>
+ <point x="870" y="1090" type="curve" smooth="yes"/>
+ <point x="870" y="951"/>
+ <point x="774" y="855"/>
+ <point x="560" y="855" type="curve" smooth="yes"/>
+ <point x="365" y="855" type="line"/>
+ </contour>
+ <contour>
+ <point x="175" y="455" type="line"/>
+ <point x="175" y="257"/>
+ <point x="175" y="80"/>
+ <point x="160" y="0" type="curve"/>
+ <point x="213" y="-5"/>
+ <point x="402" y="-10"/>
+ <point x="605" y="-10" type="curve" smooth="yes"/>
+ <point x="988" y="-10"/>
+ <point x="1140" y="177"/>
+ <point x="1140" y="420" type="curve" smooth="yes"/>
+ <point x="1140" y="669"/>
+ <point x="974" y="759"/>
+ <point x="820" y="800" type="curve"/>
+ <point x="956" y="852"/>
+ <point x="1065" y="952"/>
+ <point x="1065" y="1120" type="curve" smooth="yes"/>
+ <point x="1065" y="1381"/>
+ <point x="897" y="1470"/>
+ <point x="600" y="1470" type="curve" smooth="yes"/>
+ <point x="431" y="1470"/>
+ <point x="248" y="1466"/>
+ <point x="160" y="1460" type="curve"/>
+ <point x="175" y="1380"/>
+ <point x="175" y="1196"/>
+ <point x="175" y="1000" type="curve" smooth="yes"/>
+ </contour>
+ <contour>
+ <point x="365" y="700" type="line"/>
+ <point x="600" y="700" type="line" smooth="yes"/>
+ <point x="833" y="700"/>
+ <point x="945" y="604"/>
+ <point x="945" y="420" type="curve" smooth="yes"/>
+ <point x="945" y="212"/>
+ <point x="781" y="150"/>
+ <point x="610" y="150" type="curve" smooth="yes"/>
+ <point x="498" y="150"/>
+ <point x="402" y="153"/>
+ <point x="365" y="155" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfglyphs2ufo/PsfTest-Regular.ufo/glyphs/L_tnC_apC_.glif b/tests/reference/ufo/psfglyphs2ufo/PsfTest-Regular.ufo/glyphs/L_tnC_apC_.glif
new file mode 100644
index 0000000..daf4f2d
--- /dev/null
+++ b/tests/reference/ufo/psfglyphs2ufo/PsfTest-Regular.ufo/glyphs/L_tnC_apC_.glif
@@ -0,0 +1,38 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnCapC" format="2">
+ <advance width="1355"/>
+ <unicode hex="0043"/>
+ <anchor x="750" y="0" name="H"/>
+ <anchor x="750" y="-100" name="L"/>
+ <anchor x="750" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="1190" y="335" type="line"/>
+ <point x="1078" y="223"/>
+ <point x="912" y="150"/>
+ <point x="760" y="150" type="curve" smooth="yes"/>
+ <point x="489" y="150"/>
+ <point x="290" y="376"/>
+ <point x="290" y="735" type="curve" smooth="yes"/>
+ <point x="290" y="1119"/>
+ <point x="491" y="1315"/>
+ <point x="770" y="1315" type="curve" smooth="yes"/>
+ <point x="891" y="1315"/>
+ <point x="1030" y="1278"/>
+ <point x="1155" y="1165" type="curve"/>
+ <point x="1215" y="1345" type="line"/>
+ <point x="1072" y="1452"/>
+ <point x="913" y="1485"/>
+ <point x="770" y="1485" type="curve" smooth="yes"/>
+ <point x="418" y="1485"/>
+ <point x="95" y="1225"/>
+ <point x="95" y="710" type="curve" smooth="yes"/>
+ <point x="95" y="260"/>
+ <point x="346" y="-25"/>
+ <point x="750" y="-25" type="curve" smooth="yes"/>
+ <point x="902" y="-25"/>
+ <point x="1114" y="32"/>
+ <point x="1230" y="140" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfglyphs2ufo/PsfTest-Regular.ufo/glyphs/L_tnC_apD_.glif b/tests/reference/ufo/psfglyphs2ufo/PsfTest-Regular.ufo/glyphs/L_tnC_apD_.glif
new file mode 100644
index 0000000..9154a06
--- /dev/null
+++ b/tests/reference/ufo/psfglyphs2ufo/PsfTest-Regular.ufo/glyphs/L_tnC_apD_.glif
@@ -0,0 +1,45 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnCapD" format="2">
+ <advance width="1435"/>
+ <unicode hex="0044"/>
+ <anchor x="715" y="-100" name="L"/>
+ <anchor x="715" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="175" y="455" type="line"/>
+ <point x="174" y="257"/>
+ <point x="175" y="80"/>
+ <point x="160" y="0" type="curve"/>
+ <point x="160" y="0"/>
+ <point x="467" y="-10"/>
+ <point x="595" y="-10" type="curve" smooth="yes"/>
+ <point x="888" y="-10"/>
+ <point x="1315" y="145"/>
+ <point x="1315" y="740" type="curve" smooth="yes"/>
+ <point x="1315" y="1394"/>
+ <point x="829" y="1470"/>
+ <point x="615" y="1470" type="curve" smooth="yes"/>
+ <point x="480" y="1470"/>
+ <point x="245" y="1466"/>
+ <point x="160" y="1460" type="curve"/>
+ <point x="175" y="1380"/>
+ <point x="175" y="1196"/>
+ <point x="175" y="1000" type="curve" smooth="yes"/>
+ </contour>
+ <contour>
+ <point x="365" y="1305" type="line"/>
+ <point x="415" y="1307"/>
+ <point x="524" y="1310"/>
+ <point x="590" y="1310" type="curve" smooth="yes"/>
+ <point x="878" y="1310"/>
+ <point x="1120" y="1167"/>
+ <point x="1120" y="720" type="curve" smooth="yes"/>
+ <point x="1120" y="308"/>
+ <point x="853" y="155"/>
+ <point x="585" y="155" type="curve" smooth="yes"/>
+ <point x="490" y="155"/>
+ <point x="412" y="161"/>
+ <point x="365" y="165" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfglyphs2ufo/PsfTest-Regular.ufo/glyphs/L_tnC_apE_.glif b/tests/reference/ufo/psfglyphs2ufo/PsfTest-Regular.ufo/glyphs/L_tnC_apE_.glif
new file mode 100644
index 0000000..e5d0043
--- /dev/null
+++ b/tests/reference/ufo/psfglyphs2ufo/PsfTest-Regular.ufo/glyphs/L_tnC_apE_.glif
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnCapE" format="2">
+ <advance width="1160"/>
+ <unicode hex="0045"/>
+ <anchor x="600" y="0" name="H"/>
+ <anchor x="600" y="-100" name="L"/>
+ <anchor x="917" y="0" name="O"/>
+ <anchor x="1160" y="1200" name="R"/>
+ <anchor x="600" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="365" y="845" type="line"/>
+ <point x="365" y="1295" type="line"/>
+ <point x="1010" y="1295" type="line"/>
+ <point x="1010" y="1460" type="line"/>
+ <point x="160" y="1460" type="line"/>
+ <point x="175" y="1380"/>
+ <point x="175" y="1222"/>
+ <point x="175" y="1025" type="curve" smooth="yes"/>
+ <point x="175" y="435" type="line" smooth="yes"/>
+ <point x="175" y="238"/>
+ <point x="175" y="80"/>
+ <point x="160" y="0" type="curve"/>
+ <point x="1040" y="0" type="line"/>
+ <point x="1040" y="180" type="line"/>
+ <point x="960" y="166"/>
+ <point x="826" y="165"/>
+ <point x="629" y="165" type="curve" smooth="yes"/>
+ <point x="365" y="165" type="line"/>
+ <point x="365" y="685" type="line"/>
+ <point x="935" y="685" type="line"/>
+ <point x="935" y="845" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfglyphs2ufo/PsfTest-Regular.ufo/glyphs/L_tnC_apF_.glif b/tests/reference/ufo/psfglyphs2ufo/PsfTest-Regular.ufo/glyphs/L_tnC_apF_.glif
new file mode 100644
index 0000000..deb38fb
--- /dev/null
+++ b/tests/reference/ufo/psfglyphs2ufo/PsfTest-Regular.ufo/glyphs/L_tnC_apF_.glif
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnCapF" format="2">
+ <advance width="1150"/>
+ <unicode hex="0046"/>
+ <anchor x="595" y="-100" name="L"/>
+ <anchor x="595" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="365" y="835" type="line"/>
+ <point x="365" y="1295" type="line"/>
+ <point x="1030" y="1295" type="line"/>
+ <point x="1030" y="1460" type="line"/>
+ <point x="160" y="1460" type="line"/>
+ <point x="175" y="1380"/>
+ <point x="175" y="1217"/>
+ <point x="175" y="1020" type="curve" smooth="yes"/>
+ <point x="175" y="435" type="line" smooth="yes"/>
+ <point x="175" y="238"/>
+ <point x="175" y="80"/>
+ <point x="160" y="0" type="curve"/>
+ <point x="380" y="0" type="line"/>
+ <point x="365" y="78"/>
+ <point x="365" y="237"/>
+ <point x="365" y="435" type="curve" smooth="yes"/>
+ <point x="365" y="675" type="line"/>
+ <point x="945" y="675" type="line"/>
+ <point x="945" y="835" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfglyphs2ufo/PsfTest-Regular.ufo/glyphs/L_tnC_apG_.glif b/tests/reference/ufo/psfglyphs2ufo/PsfTest-Regular.ufo/glyphs/L_tnC_apG_.glif
new file mode 100644
index 0000000..477d223
--- /dev/null
+++ b/tests/reference/ufo/psfglyphs2ufo/PsfTest-Regular.ufo/glyphs/L_tnC_apG_.glif
@@ -0,0 +1,42 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnCapG" format="2">
+ <advance width="1420"/>
+ <unicode hex="0047"/>
+ <anchor x="745" y="0" name="H"/>
+ <anchor x="745" y="-100" name="L"/>
+ <anchor x="745" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="1275" y="745" type="line"/>
+ <point x="735" y="745" type="line"/>
+ <point x="735" y="580" type="line"/>
+ <point x="1085" y="580" type="line"/>
+ <point x="1085" y="245" type="line"/>
+ <point x="963" y="171"/>
+ <point x="876" y="150"/>
+ <point x="757" y="150" type="curve" smooth="yes"/>
+ <point x="471" y="150"/>
+ <point x="290" y="377"/>
+ <point x="290" y="745" type="curve" smooth="yes"/>
+ <point x="290" y="1094"/>
+ <point x="480" y="1315"/>
+ <point x="785" y="1315" type="curve" smooth="yes"/>
+ <point x="918" y="1315"/>
+ <point x="1046" y="1286"/>
+ <point x="1195" y="1165" type="curve"/>
+ <point x="1260" y="1345" type="line"/>
+ <point x="1085" y="1462"/>
+ <point x="947" y="1485"/>
+ <point x="785" y="1485" type="curve" smooth="yes"/>
+ <point x="402" y="1485"/>
+ <point x="95" y="1199"/>
+ <point x="95" y="720" type="curve" smooth="yes"/>
+ <point x="95" y="241"/>
+ <point x="367" y="-25"/>
+ <point x="745" y="-25" type="curve" smooth="yes"/>
+ <point x="918" y="-25"/>
+ <point x="1070" y="11"/>
+ <point x="1275" y="155" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfglyphs2ufo/PsfTest-Regular.ufo/glyphs/L_tnC_apH_.glif b/tests/reference/ufo/psfglyphs2ufo/PsfTest-Regular.ufo/glyphs/L_tnC_apH_.glif
new file mode 100644
index 0000000..5924270
--- /dev/null
+++ b/tests/reference/ufo/psfglyphs2ufo/PsfTest-Regular.ufo/glyphs/L_tnC_apH_.glif
@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnCapH" format="2">
+ <advance width="1475"/>
+ <unicode hex="0048"/>
+ <anchor x="285" y="0" name="H"/>
+ <anchor x="725" y="-100" name="L"/>
+ <anchor x="725" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="1290" y="0" type="line"/>
+ <point x="1275" y="80"/>
+ <point x="1275" y="238"/>
+ <point x="1275" y="435" type="curve" smooth="yes"/>
+ <point x="1275" y="1025" type="line" smooth="yes"/>
+ <point x="1275" y="1222"/>
+ <point x="1275" y="1380"/>
+ <point x="1290" y="1460" type="curve"/>
+ <point x="1085" y="1460" type="line"/>
+ <point x="1085" y="835" type="line"/>
+ <point x="365" y="835" type="line"/>
+ <point x="365" y="1460" type="line"/>
+ <point x="160" y="1460" type="line"/>
+ <point x="175" y="1380"/>
+ <point x="175" y="1222"/>
+ <point x="175" y="1025" type="curve" smooth="yes"/>
+ <point x="175" y="435" type="line" smooth="yes"/>
+ <point x="175" y="238"/>
+ <point x="175" y="80"/>
+ <point x="160" y="0" type="curve"/>
+ <point x="365" y="0" type="line"/>
+ <point x="365" y="675" type="line"/>
+ <point x="1085" y="675" type="line"/>
+ <point x="1085" y="0" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfglyphs2ufo/PsfTest-Regular.ufo/glyphs/L_tnC_apI_.glif b/tests/reference/ufo/psfglyphs2ufo/PsfTest-Regular.ufo/glyphs/L_tnC_apI_.glif
new file mode 100644
index 0000000..c6001c3
--- /dev/null
+++ b/tests/reference/ufo/psfglyphs2ufo/PsfTest-Regular.ufo/glyphs/L_tnC_apI_.glif
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnCapI" format="2">
+ <advance width="975"/>
+ <unicode hex="0049"/>
+ <anchor x="477" y="0" name="H"/>
+ <anchor x="477" y="-100" name="L"/>
+ <anchor x="673" y="0" name="O"/>
+ <anchor x="975" y="1200" name="R"/>
+ <anchor x="477" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="140" y="1460" type="line"/>
+ <point x="140" y="1315" type="line"/>
+ <point x="380" y="1315" type="line"/>
+ <point x="380" y="145" type="line"/>
+ <point x="140" y="145" type="line"/>
+ <point x="140" y="0" type="line"/>
+ <point x="815" y="0" type="line"/>
+ <point x="815" y="145" type="line"/>
+ <point x="570" y="145" type="line"/>
+ <point x="570" y="1315" type="line"/>
+ <point x="815" y="1315" type="line"/>
+ <point x="815" y="1460" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfglyphs2ufo/PsfTest-Regular.ufo/glyphs/L_tnC_apJ_.glif b/tests/reference/ufo/psfglyphs2ufo/PsfTest-Regular.ufo/glyphs/L_tnC_apJ_.glif
new file mode 100644
index 0000000..457e39d
--- /dev/null
+++ b/tests/reference/ufo/psfglyphs2ufo/PsfTest-Regular.ufo/glyphs/L_tnC_apJ_.glif
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnCapJ" format="2">
+ <advance width="965"/>
+ <unicode hex="004A"/>
+ <anchor x="410" y="-100" name="L"/>
+ <anchor x="675" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="575" y="1460" type="line"/>
+ <point x="588" y="1354"/>
+ <point x="590" y="1175"/>
+ <point x="590" y="980" type="curve"/>
+ <point x="590" y="485" type="line" smooth="yes"/>
+ <point x="590" y="256"/>
+ <point x="487" y="155"/>
+ <point x="340" y="155" type="curve" smooth="yes"/>
+ <point x="248" y="155"/>
+ <point x="147" y="198"/>
+ <point x="80" y="275" type="curve"/>
+ <point x="35" y="90" type="line"/>
+ <point x="106" y="9"/>
+ <point x="250" y="-25"/>
+ <point x="345" y="-25" type="curve" smooth="yes"/>
+ <point x="602" y="-25"/>
+ <point x="780" y="119"/>
+ <point x="780" y="535" type="curve" smooth="yes"/>
+ <point x="780" y="1460" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfglyphs2ufo/PsfTest-Regular.ufo/glyphs/L_tnC_apK_.glif b/tests/reference/ufo/psfglyphs2ufo/PsfTest-Regular.ufo/glyphs/L_tnC_apK_.glif
new file mode 100644
index 0000000..b3f4cdd
--- /dev/null
+++ b/tests/reference/ufo/psfglyphs2ufo/PsfTest-Regular.ufo/glyphs/L_tnC_apK_.glif
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnCapK" format="2">
+ <advance width="1310"/>
+ <unicode hex="004B"/>
+ <anchor x="270" y="0" name="H"/>
+ <anchor x="695" y="-100" name="L"/>
+ <anchor x="650" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="925" y="1460" type="line"/>
+ <point x="295" y="703" type="line"/>
+ <point x="425" y="745" type="line"/>
+ <point x="530" y="740" type="line"/>
+ <point x="1165" y="1460" type="line"/>
+ </contour>
+ <contour>
+ <point x="350" y="735" type="line"/>
+ <point x="985" y="0" type="line"/>
+ <point x="1230" y="0" type="line"/>
+ <point x="485" y="860" type="line"/>
+ </contour>
+ <contour>
+ <point x="365" y="1460" type="line"/>
+ <point x="160" y="1460" type="line"/>
+ <point x="175" y="1380"/>
+ <point x="175" y="1222"/>
+ <point x="175" y="1025" type="curve" smooth="yes"/>
+ <point x="175" y="435" type="line" smooth="yes"/>
+ <point x="175" y="238"/>
+ <point x="175" y="80"/>
+ <point x="160" y="0" type="curve"/>
+ <point x="365" y="0" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfglyphs2ufo/PsfTest-Regular.ufo/glyphs/L_tnC_apL_.glif b/tests/reference/ufo/psfglyphs2ufo/PsfTest-Regular.ufo/glyphs/L_tnC_apL_.glif
new file mode 100644
index 0000000..3d5883a
--- /dev/null
+++ b/tests/reference/ufo/psfglyphs2ufo/PsfTest-Regular.ufo/glyphs/L_tnC_apL_.glif
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnCapL" format="2">
+ <advance width="1080"/>
+ <unicode hex="004C"/>
+ <anchor x="592" y="0" name="H"/>
+ <anchor x="592" y="-100" name="L"/>
+ <anchor x="540" y="1200" name="R"/>
+ <anchor x="592" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="365" y="165" type="line"/>
+ <point x="365" y="1460" type="line"/>
+ <point x="160" y="1460" type="line"/>
+ <point x="175" y="1380"/>
+ <point x="175" y="1222"/>
+ <point x="175" y="1025" type="curve" smooth="yes"/>
+ <point x="175" y="435" type="line" smooth="yes"/>
+ <point x="175" y="238"/>
+ <point x="175" y="80"/>
+ <point x="160" y="0" type="curve"/>
+ <point x="1025" y="0" type="line"/>
+ <point x="1025" y="180" type="line"/>
+ <point x="945" y="166"/>
+ <point x="786" y="165"/>
+ <point x="589" y="165" type="curve" smooth="yes"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfglyphs2ufo/PsfTest-Regular.ufo/glyphs/L_tnC_apM_.glif b/tests/reference/ufo/psfglyphs2ufo/PsfTest-Regular.ufo/glyphs/L_tnC_apM_.glif
new file mode 100644
index 0000000..fbdf3b1
--- /dev/null
+++ b/tests/reference/ufo/psfglyphs2ufo/PsfTest-Regular.ufo/glyphs/L_tnC_apM_.glif
@@ -0,0 +1,37 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnCapM" format="2">
+ <advance width="1795"/>
+ <unicode hex="004D"/>
+ <anchor x="1521" y="0" name="H"/>
+ <anchor x="885" y="-100" name="L"/>
+ <anchor x="885" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="885" y="205" type="line"/>
+ <point x="455" y="1460" type="line"/>
+ <point x="285" y="1460" type="line"/>
+ <point x="790" y="0" type="line"/>
+ <point x="985" y="0" type="line"/>
+ <point x="1487" y="1460" type="line"/>
+ <point x="1320" y="1460" type="line"/>
+ </contour>
+ <contour>
+ <point x="230" y="1460" type="line"/>
+ <point x="230" y="1460"/>
+ <point x="186" y="198"/>
+ <point x="160" y="0" type="curve"/>
+ <point x="345" y="0" type="line"/>
+ <point x="377" y="1205" type="line"/>
+ <point x="405" y="1460" type="line"/>
+ </contour>
+ <contour>
+ <point x="1610" y="0" type="line"/>
+ <point x="1581" y="198"/>
+ <point x="1540" y="1460"/>
+ <point x="1540" y="1460" type="curve"/>
+ <point x="1365" y="1460" type="line"/>
+ <point x="1397" y="1205" type="line"/>
+ <point x="1425" y="0" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfglyphs2ufo/PsfTest-Regular.ufo/glyphs/L_tnC_apN_.glif b/tests/reference/ufo/psfglyphs2ufo/PsfTest-Regular.ufo/glyphs/L_tnC_apN_.glif
new file mode 100644
index 0000000..360e6e6
--- /dev/null
+++ b/tests/reference/ufo/psfglyphs2ufo/PsfTest-Regular.ufo/glyphs/L_tnC_apN_.glif
@@ -0,0 +1,37 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnCapN" format="2">
+ <advance width="1500"/>
+ <unicode hex="004E"/>
+ <anchor x="1230" y="0" name="H"/>
+ <anchor x="737" y="-100" name="L"/>
+ <anchor x="737" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="200" y="1355" type="line"/>
+ <point x="1135" y="0" type="line"/>
+ <point x="1275" y="100" type="line"/>
+ <point x="340" y="1460" type="line"/>
+ </contour>
+ <contour>
+ <point x="1135" y="0" type="line"/>
+ <point x="1300" y="0" type="line"/>
+ <point x="1300" y="1025" type="line" smooth="yes"/>
+ <point x="1300" y="1222"/>
+ <point x="1301" y="1380"/>
+ <point x="1315" y="1460" type="curve"/>
+ <point x="1135" y="1460" type="line"/>
+ </contour>
+ <contour>
+ <point x="340" y="1460" type="line"/>
+ <point x="160" y="1460" type="line"/>
+ <point x="175" y="1380"/>
+ <point x="175" y="1222"/>
+ <point x="175" y="1025" type="curve" smooth="yes"/>
+ <point x="175" y="435" type="line" smooth="yes"/>
+ <point x="175" y="238"/>
+ <point x="175" y="80"/>
+ <point x="160" y="0" type="curve"/>
+ <point x="340" y="0" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfglyphs2ufo/PsfTest-Regular.ufo/glyphs/L_tnC_apO_.glif b/tests/reference/ufo/psfglyphs2ufo/PsfTest-Regular.ufo/glyphs/L_tnC_apO_.glif
new file mode 100644
index 0000000..e351c3d
--- /dev/null
+++ b/tests/reference/ufo/psfglyphs2ufo/PsfTest-Regular.ufo/glyphs/L_tnC_apO_.glif
@@ -0,0 +1,40 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnCapO" format="2">
+ <advance width="1460"/>
+ <unicode hex="004F"/>
+ <anchor x="717" y="0" name="H"/>
+ <anchor x="717" y="-100" name="L"/>
+ <anchor x="994" y="0" name="O"/>
+ <anchor x="1460" y="1200" name="R"/>
+ <anchor x="717" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="1145" y="715" type="curve" smooth="yes"/>
+ <point x="1145" y="360"/>
+ <point x="965" y="150"/>
+ <point x="720" y="150" type="curve" smooth="yes"/>
+ <point x="460" y="150"/>
+ <point x="290" y="380"/>
+ <point x="290" y="745" type="curve" smooth="yes"/>
+ <point x="290" y="1091"/>
+ <point x="467" y="1310"/>
+ <point x="720" y="1310" type="curve" smooth="yes"/>
+ <point x="974" y="1310"/>
+ <point x="1145" y="1084"/>
+ </contour>
+ <contour>
+ <point x="1340" y="740" type="curve" smooth="yes"/>
+ <point x="1340" y="1219"/>
+ <point x="1048" y="1485"/>
+ <point x="730" y="1485" type="curve" smooth="yes"/>
+ <point x="407" y="1485"/>
+ <point x="95" y="1199"/>
+ <point x="95" y="720" type="curve" smooth="yes"/>
+ <point x="95" y="241"/>
+ <point x="388" y="-25"/>
+ <point x="710" y="-25" type="curve" smooth="yes"/>
+ <point x="1029" y="-25"/>
+ <point x="1340" y="260"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfglyphs2ufo/PsfTest-Regular.ufo/glyphs/L_tnC_apP_.glif b/tests/reference/ufo/psfglyphs2ufo/PsfTest-Regular.ufo/glyphs/L_tnC_apP_.glif
new file mode 100644
index 0000000..9f29954
--- /dev/null
+++ b/tests/reference/ufo/psfglyphs2ufo/PsfTest-Regular.ufo/glyphs/L_tnC_apP_.glif
@@ -0,0 +1,50 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnCapP" format="2">
+ <advance width="1195"/>
+ <unicode hex="0050"/>
+ <anchor x="637" y="-100" name="L"/>
+ <anchor x="637" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="365" y="565" type="line"/>
+ <point x="430" y="558"/>
+ <point x="512" y="555"/>
+ <point x="585" y="555" type="curve" smooth="yes"/>
+ <point x="914" y="555"/>
+ <point x="1115" y="736"/>
+ <point x="1115" y="1030" type="curve" smooth="yes"/>
+ <point x="1115" y="1322"/>
+ <point x="908" y="1470"/>
+ <point x="585" y="1470" type="curve" smooth="yes"/>
+ <point x="372" y="1470"/>
+ <point x="160" y="1460"/>
+ <point x="160" y="1460" type="curve"/>
+ <point x="175" y="1380"/>
+ <point x="175" y="1196"/>
+ <point x="175" y="1000" type="curve"/>
+ <point x="175" y="435" type="line" smooth="yes"/>
+ <point x="175" y="238"/>
+ <point x="175" y="80"/>
+ <point x="160" y="0" type="curve"/>
+ <point x="380" y="0" type="line"/>
+ <point x="366" y="78"/>
+ <point x="365" y="237"/>
+ <point x="365" y="435" type="curve" smooth="yes"/>
+ </contour>
+ <contour>
+ <point x="365" y="1305" type="line"/>
+ <point x="433" y="1308"/>
+ <point x="481" y="1310"/>
+ <point x="575" y="1310" type="curve" smooth="yes"/>
+ <point x="841" y="1310"/>
+ <point x="925" y="1170"/>
+ <point x="925" y="1010" type="curve" smooth="yes"/>
+ <point x="925" y="849"/>
+ <point x="850" y="710"/>
+ <point x="570" y="710" type="curve" smooth="yes"/>
+ <point x="495" y="710"/>
+ <point x="428" y="712"/>
+ <point x="365" y="720" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfglyphs2ufo/PsfTest-Regular.ufo/glyphs/L_tnC_apQ_.glif b/tests/reference/ufo/psfglyphs2ufo/PsfTest-Regular.ufo/glyphs/L_tnC_apQ_.glif
new file mode 100644
index 0000000..ddd0351
--- /dev/null
+++ b/tests/reference/ufo/psfglyphs2ufo/PsfTest-Regular.ufo/glyphs/L_tnC_apQ_.glif
@@ -0,0 +1,49 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnCapQ" format="2">
+ <advance width="1475"/>
+ <unicode hex="0051"/>
+ <anchor x="717" y="-270" name="L"/>
+ <anchor x="717" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="1340" y="740" type="curve" smooth="yes"/>
+ <point x="1340" y="1219"/>
+ <point x="1053" y="1485"/>
+ <point x="730" y="1485" type="curve" smooth="yes"/>
+ <point x="407" y="1485"/>
+ <point x="95" y="1199"/>
+ <point x="95" y="720" type="curve" smooth="yes"/>
+ <point x="95" y="241"/>
+ <point x="383" y="-25"/>
+ <point x="705" y="-25" type="curve" smooth="yes"/>
+ <point x="767" y="-25"/>
+ <point x="818" y="-18"/>
+ <point x="875" y="0" type="curve"/>
+ <point x="944" y="0"/>
+ <point x="1236" y="-190"/>
+ <point x="1320" y="-190" type="curve" smooth="yes"/>
+ <point x="1374" y="-190"/>
+ <point x="1431" y="-81"/>
+ <point x="1455" y="-45" type="curve"/>
+ <point x="1321" y="-28"/>
+ <point x="1205" y="28"/>
+ <point x="1080" y="105" type="curve"/>
+ <point x="1256" y="236"/>
+ <point x="1340" y="479"/>
+ </contour>
+ <contour>
+ <point x="1145" y="715" type="curve" smooth="yes"/>
+ <point x="1145" y="360"/>
+ <point x="965" y="150"/>
+ <point x="720" y="150" type="curve" smooth="yes"/>
+ <point x="460" y="150"/>
+ <point x="290" y="380"/>
+ <point x="290" y="745" type="curve" smooth="yes"/>
+ <point x="290" y="1091"/>
+ <point x="467" y="1310"/>
+ <point x="720" y="1310" type="curve" smooth="yes"/>
+ <point x="974" y="1310"/>
+ <point x="1145" y="1084"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfglyphs2ufo/PsfTest-Regular.ufo/glyphs/L_tnC_apR_.glif b/tests/reference/ufo/psfglyphs2ufo/PsfTest-Regular.ufo/glyphs/L_tnC_apR_.glif
new file mode 100644
index 0000000..cd9e037
--- /dev/null
+++ b/tests/reference/ufo/psfglyphs2ufo/PsfTest-Regular.ufo/glyphs/L_tnC_apR_.glif
@@ -0,0 +1,55 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnCapR" format="2">
+ <advance width="1305"/>
+ <unicode hex="0052"/>
+ <anchor x="285" y="0" name="H"/>
+ <anchor x="610" y="-100" name="L"/>
+ <anchor x="610" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="365" y="625" type="line"/>
+ <point x="620" y="625" type="line"/>
+ <point x="805" y="625"/>
+ <point x="1090" y="743"/>
+ <point x="1090" y="1060" type="curve" smooth="yes"/>
+ <point x="1090" y="1349"/>
+ <point x="876" y="1470"/>
+ <point x="565" y="1470" type="curve" smooth="yes"/>
+ <point x="331" y="1470"/>
+ <point x="160" y="1460"/>
+ <point x="160" y="1460" type="curve"/>
+ <point x="175" y="1380"/>
+ <point x="175" y="1196"/>
+ <point x="175" y="1000" type="curve" smooth="yes"/>
+ <point x="175" y="435" type="line"/>
+ <point x="175" y="238"/>
+ <point x="175" y="80"/>
+ <point x="160" y="0" type="curve"/>
+ <point x="380" y="0" type="line"/>
+ <point x="366" y="78"/>
+ <point x="365" y="238"/>
+ <point x="365" y="435" type="curve"/>
+ </contour>
+ <contour>
+ <point x="365" y="1305" type="line"/>
+ <point x="418" y="1307"/>
+ <point x="485" y="1310"/>
+ <point x="555" y="1310" type="curve" smooth="yes"/>
+ <point x="800" y="1310"/>
+ <point x="900" y="1216"/>
+ <point x="900" y="1045" type="curve" smooth="yes"/>
+ <point x="900" y="879"/>
+ <point x="780" y="780"/>
+ <point x="555" y="780" type="curve"/>
+ <point x="365" y="780" type="line"/>
+ </contour>
+ <contour>
+ <point x="561" y="635" type="line"/>
+ <point x="990" y="0" type="line"/>
+ <point x="1245" y="0" type="line"/>
+ <point x="1178" y="73"/>
+ <point x="715" y="710"/>
+ <point x="715" y="710" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfglyphs2ufo/PsfTest-Regular.ufo/glyphs/L_tnC_apS_.glif b/tests/reference/ufo/psfglyphs2ufo/PsfTest-Regular.ufo/glyphs/L_tnC_apS_.glif
new file mode 100644
index 0000000..92da6b0
--- /dev/null
+++ b/tests/reference/ufo/psfglyphs2ufo/PsfTest-Regular.ufo/glyphs/L_tnC_apS_.glif
@@ -0,0 +1,50 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnCapS" format="2">
+ <advance width="1175"/>
+ <unicode hex="0053"/>
+ <anchor x="580" y="0" name="H"/>
+ <anchor x="580" y="-100" name="L"/>
+ <anchor x="580" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="1000" y="1395" type="line"/>
+ <point x="870" y="1458"/>
+ <point x="759" y="1485"/>
+ <point x="605" y="1485" type="curve" smooth="yes"/>
+ <point x="273" y="1485"/>
+ <point x="135" y="1250"/>
+ <point x="135" y="1080" type="curve" smooth="yes"/>
+ <point x="135" y="910"/>
+ <point x="203" y="778"/>
+ <point x="515" y="685" type="curve" smooth="yes"/>
+ <point x="827" y="591"/>
+ <point x="875" y="510"/>
+ <point x="875" y="405" type="curve" smooth="yes"/>
+ <point x="875" y="243"/>
+ <point x="726" y="150"/>
+ <point x="565" y="150" type="curve" smooth="yes"/>
+ <point x="417" y="150"/>
+ <point x="272" y="200"/>
+ <point x="140" y="315" type="curve"/>
+ <point x="95" y="110" type="line"/>
+ <point x="197" y="31"/>
+ <point x="372" y="-25"/>
+ <point x="565" y="-25" type="curve" smooth="yes"/>
+ <point x="838" y="-25"/>
+ <point x="1065" y="157"/>
+ <point x="1065" y="425" type="curve" smooth="yes"/>
+ <point x="1065" y="641"/>
+ <point x="920" y="762"/>
+ <point x="655" y="840" type="curve" smooth="yes"/>
+ <point x="370" y="923"/>
+ <point x="325" y="985"/>
+ <point x="325" y="1095" type="curve" smooth="yes"/>
+ <point x="325" y="1205"/>
+ <point x="435" y="1310"/>
+ <point x="595" y="1310" type="curve" smooth="yes"/>
+ <point x="723" y="1310"/>
+ <point x="817" y="1279"/>
+ <point x="960" y="1200" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfglyphs2ufo/PsfTest-Regular.ufo/glyphs/L_tnC_apT_.glif b/tests/reference/ufo/psfglyphs2ufo/PsfTest-Regular.ufo/glyphs/L_tnC_apT_.glif
new file mode 100644
index 0000000..124138f
--- /dev/null
+++ b/tests/reference/ufo/psfglyphs2ufo/PsfTest-Regular.ufo/glyphs/L_tnC_apT_.glif
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnCapT" format="2">
+ <advance width="1265"/>
+ <unicode hex="0054"/>
+ <anchor x="622" y="0" name="H"/>
+ <anchor x="622" y="-100" name="L"/>
+ <anchor x="622" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="45" y="1460" type="line"/>
+ <point x="45" y="1275" type="line"/>
+ <point x="125" y="1292"/>
+ <point x="201" y="1295"/>
+ <point x="290" y="1295" type="curve" smooth="yes"/>
+ <point x="525" y="1295" type="line"/>
+ <point x="525" y="435" type="line" smooth="yes"/>
+ <point x="525" y="238"/>
+ <point x="522" y="80"/>
+ <point x="505" y="0" type="curve"/>
+ <point x="735" y="0" type="line"/>
+ <point x="718" y="80"/>
+ <point x="715" y="238"/>
+ <point x="715" y="435" type="curve" smooth="yes"/>
+ <point x="715" y="1295" type="line"/>
+ <point x="955" y="1295" type="line" smooth="yes"/>
+ <point x="1045" y="1295"/>
+ <point x="1120" y="1292"/>
+ <point x="1200" y="1275" type="curve"/>
+ <point x="1200" y="1460" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfglyphs2ufo/PsfTest-Regular.ufo/glyphs/L_tnC_apU_.glif b/tests/reference/ufo/psfglyphs2ufo/PsfTest-Regular.ufo/glyphs/L_tnC_apU_.glif
new file mode 100644
index 0000000..7afa08d
--- /dev/null
+++ b/tests/reference/ufo/psfglyphs2ufo/PsfTest-Regular.ufo/glyphs/L_tnC_apU_.glif
@@ -0,0 +1,38 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnCapU" format="2">
+ <advance width="1440"/>
+ <unicode hex="0055"/>
+ <anchor x="707" y="0" name="H"/>
+ <anchor x="707" y="-100" name="L"/>
+ <anchor x="1026" y="0" name="O"/>
+ <anchor x="1400" y="1200" name="R"/>
+ <anchor x="707" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="1050" y="1460" type="line"/>
+ <point x="1050" y="560" type="line" smooth="yes"/>
+ <point x="1050" y="299"/>
+ <point x="968" y="135"/>
+ <point x="710" y="135" type="curve" smooth="yes"/>
+ <point x="447" y="135"/>
+ <point x="365" y="299"/>
+ <point x="365" y="560" type="curve" smooth="yes"/>
+ <point x="365" y="1460" type="line"/>
+ <point x="160" y="1460" type="line"/>
+ <point x="174" y="1380"/>
+ <point x="175" y="1222"/>
+ <point x="175" y="1025" type="curve" smooth="yes"/>
+ <point x="175" y="515" type="line"/>
+ <point x="175" y="190"/>
+ <point x="345" y="-25"/>
+ <point x="710" y="-25" type="curve" smooth="yes"/>
+ <point x="1071" y="-25"/>
+ <point x="1240" y="190"/>
+ <point x="1240" y="515" type="curve"/>
+ <point x="1240" y="1025" type="line" smooth="yes"/>
+ <point x="1240" y="1232"/>
+ <point x="1242" y="1380"/>
+ <point x="1255" y="1460" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfglyphs2ufo/PsfTest-Regular.ufo/glyphs/L_tnC_apV_.glif b/tests/reference/ufo/psfglyphs2ufo/PsfTest-Regular.ufo/glyphs/L_tnC_apV_.glif
new file mode 100644
index 0000000..86c76b5
--- /dev/null
+++ b/tests/reference/ufo/psfglyphs2ufo/PsfTest-Regular.ufo/glyphs/L_tnC_apV_.glif
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnCapV" format="2">
+ <advance width="1365"/>
+ <unicode hex="0056"/>
+ <anchor x="680" y="0" name="H"/>
+ <anchor x="672" y="-100" name="L"/>
+ <anchor x="880" y="0" name="O"/>
+ <anchor x="672" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="1095" y="1460" type="line"/>
+ <point x="672" y="195" type="line"/>
+ <point x="250" y="1460" type="line"/>
+ <point x="35" y="1460" type="line"/>
+ <point x="68" y="1378"/>
+ <point x="101" y="1288"/>
+ <point x="170" y="1095" type="curve" smooth="yes"/>
+ <point x="560" y="0" type="line"/>
+ <point x="785" y="0" type="line"/>
+ <point x="1170" y="1095" type="line" smooth="yes"/>
+ <point x="1238" y="1289"/>
+ <point x="1274" y="1378"/>
+ <point x="1310" y="1460" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfglyphs2ufo/PsfTest-Regular.ufo/glyphs/L_tnC_apW_.glif b/tests/reference/ufo/psfglyphs2ufo/PsfTest-Regular.ufo/glyphs/L_tnC_apW_.glif
new file mode 100644
index 0000000..b1f4961
--- /dev/null
+++ b/tests/reference/ufo/psfglyphs2ufo/PsfTest-Regular.ufo/glyphs/L_tnC_apW_.glif
@@ -0,0 +1,45 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnCapW" format="2">
+ <advance width="2080"/>
+ <unicode hex="0057"/>
+ <anchor x="1027" y="-100" name="L"/>
+ <anchor x="1027" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="1480" y="0" type="line"/>
+ <point x="1595" y="0" type="line"/>
+ <point x="1900" y="1095" type="line" smooth="yes"/>
+ <point x="1954" y="1289"/>
+ <point x="1983" y="1378"/>
+ <point x="2015" y="1460" type="curve"/>
+ <point x="1795" y="1460" type="line"/>
+ <point x="1470" y="130" type="line"/>
+ </contour>
+ <contour>
+ <point x="1120" y="1460" type="line"/>
+ <point x="935" y="1460" type="line"/>
+ <point x="990" y="1305" type="line"/>
+ <point x="1370" y="0" type="line"/>
+ <point x="1480" y="0" type="line"/>
+ <point x="1500" y="130" type="line"/>
+ </contour>
+ <contour>
+ <point x="580" y="0" type="line"/>
+ <point x="685" y="0" type="line"/>
+ <point x="1065" y="1305" type="line"/>
+ <point x="1120" y="1460" type="line"/>
+ <point x="935" y="1460" type="line"/>
+ <point x="560" y="130" type="line"/>
+ </contour>
+ <contour>
+ <point x="260" y="1460" type="line"/>
+ <point x="40" y="1460" type="line"/>
+ <point x="71" y="1381"/>
+ <point x="102" y="1286"/>
+ <point x="155" y="1095" type="curve" smooth="yes"/>
+ <point x="460" y="0" type="line"/>
+ <point x="580" y="0" type="line"/>
+ <point x="590" y="130" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfglyphs2ufo/PsfTest-Regular.ufo/glyphs/L_tnC_apX_.glif b/tests/reference/ufo/psfglyphs2ufo/PsfTest-Regular.ufo/glyphs/L_tnC_apX_.glif
new file mode 100644
index 0000000..7472407
--- /dev/null
+++ b/tests/reference/ufo/psfglyphs2ufo/PsfTest-Regular.ufo/glyphs/L_tnC_apX_.glif
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnCapX" format="2">
+ <advance width="1325"/>
+ <unicode hex="0058"/>
+ <anchor x="650" y="-100" name="L"/>
+ <anchor x="650" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="537" y="781" type="line"/>
+ <point x="265" y="340" type="line" smooth="yes"/>
+ <point x="136" y="132"/>
+ <point x="103" y="86"/>
+ <point x="40" y="0" type="curve"/>
+ <point x="270" y="0" type="line"/>
+ <point x="642" y="614" type="line"/>
+ <point x="1030" y="0" type="line"/>
+ <point x="1260" y="0" type="line"/>
+ <point x="1199" y="82"/>
+ <point x="1165" y="127"/>
+ <point x="1033" y="336" type="curve" smooth="yes"/>
+ <point x="761" y="767" type="line"/>
+ <point x="972" y="1110" type="line" smooth="yes"/>
+ <point x="1097" y="1313"/>
+ <point x="1148" y="1383"/>
+ <point x="1210" y="1460" type="curve"/>
+ <point x="975" y="1460" type="line"/>
+ <point x="656" y="934" type="line"/>
+ <point x="325" y="1460" type="line"/>
+ <point x="90" y="1460" type="line"/>
+ <point x="154" y="1376"/>
+ <point x="201" y="1315"/>
+ <point x="330" y="1110" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfglyphs2ufo/PsfTest-Regular.ufo/glyphs/L_tnC_apY_.glif b/tests/reference/ufo/psfglyphs2ufo/PsfTest-Regular.ufo/glyphs/L_tnC_apY_.glif
new file mode 100644
index 0000000..c2c5f54
--- /dev/null
+++ b/tests/reference/ufo/psfglyphs2ufo/PsfTest-Regular.ufo/glyphs/L_tnC_apY_.glif
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnCapY" format="2">
+ <advance width="1320"/>
+ <unicode hex="0059"/>
+ <anchor x="650" y="-100" name="L"/>
+ <anchor x="650" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="35" y="1460" type="line"/>
+ <point x="147" y="1311"/>
+ <point x="213" y="1197"/>
+ <point x="290" y="1065" type="curve" smooth="yes"/>
+ <point x="555" y="611" type="line"/>
+ <point x="555" y="435" type="line" smooth="yes"/>
+ <point x="555" y="238"/>
+ <point x="555" y="80"/>
+ <point x="540" y="0" type="curve"/>
+ <point x="760" y="0" type="line"/>
+ <point x="745" y="80"/>
+ <point x="745" y="238"/>
+ <point x="745" y="435" type="curve" smooth="yes"/>
+ <point x="745" y="603" type="line"/>
+ <point x="1015" y="1065" type="line" smooth="yes"/>
+ <point x="1091" y="1195"/>
+ <point x="1147" y="1291"/>
+ <point x="1265" y="1460" type="curve"/>
+ <point x="1035" y="1460" type="line"/>
+ <point x="660" y="799" type="line"/>
+ <point x="265" y="1460" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfglyphs2ufo/PsfTest-Regular.ufo/glyphs/L_tnS_mA_.glif b/tests/reference/ufo/psfglyphs2ufo/PsfTest-Regular.ufo/glyphs/L_tnS_mA_.glif
new file mode 100644
index 0000000..4f0d667
--- /dev/null
+++ b/tests/reference/ufo/psfglyphs2ufo/PsfTest-Regular.ufo/glyphs/L_tnS_mA_.glif
@@ -0,0 +1,68 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmA" format="2">
+ <advance width="1120"/>
+ <unicode hex="0061"/>
+ <note>
+GlyphNote A
+</note>
+ <anchor x="540" y="0" name="H"/>
+ <anchor x="540" y="-100" name="L"/>
+ <anchor x="1125" y="0" name="O"/>
+ <anchor x="1120" y="1000" name="R"/>
+ <anchor x="540" y="1100" name="U"/>
+ <outline>
+ <contour>
+ <point x="950" y="760" type="line"/>
+ <point x="950" y="919"/>
+ <point x="800" y="1040"/>
+ <point x="570" y="1040" type="curve" smooth="yes"/>
+ <point x="418" y="1040"/>
+ <point x="312" y="994"/>
+ <point x="209" y="950" type="curve"/>
+ <point x="203" y="907"/>
+ <point x="200" y="799"/>
+ <point x="199" y="755" type="curve"/>
+ <point x="316" y="837"/>
+ <point x="419" y="880"/>
+ <point x="525" y="880" type="curve" smooth="yes"/>
+ <point x="675" y="880"/>
+ <point x="765" y="831"/>
+ <point x="765" y="710" type="curve" smooth="yes"/>
+ <point x="765" y="635" type="line"/>
+ <point x="724" y="632"/>
+ <point x="564" y="617"/>
+ <point x="495" y="610" type="curve" smooth="yes"/>
+ <point x="186" y="580"/>
+ <point x="95" y="407"/>
+ <point x="95" y="255" type="curve" smooth="yes"/>
+ <point x="95" y="107"/>
+ <point x="232" y="-25"/>
+ <point x="420" y="-25" type="curve" smooth="yes"/>
+ <point x="544" y="-25"/>
+ <point x="677" y="29"/>
+ <point x="795" y="155" type="curve"/>
+ <point x="809" y="91"/>
+ <point x="833" y="32"/>
+ <point x="845" y="0" type="curve"/>
+ <point x="1025" y="0" type="line"/>
+ <point x="981" y="112"/>
+ <point x="950" y="226"/>
+ <point x="950" y="370" type="curve"/>
+ </contour>
+ <contour>
+ <point x="765" y="325" type="line"/>
+ <point x="644" y="164"/>
+ <point x="552" y="140"/>
+ <point x="450" y="140" type="curve" smooth="yes"/>
+ <point x="340" y="140"/>
+ <point x="275" y="191"/>
+ <point x="275" y="280" type="curve" smooth="yes"/>
+ <point x="275" y="372"/>
+ <point x="335" y="450"/>
+ <point x="505" y="470" type="curve" smooth="yes"/>
+ <point x="568" y="478"/>
+ <point x="715" y="493"/>
+ <point x="765" y="495" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfglyphs2ufo/PsfTest-Regular.ufo/glyphs/L_tnS_mA_A_cute.glif b/tests/reference/ufo/psfglyphs2ufo/PsfTest-Regular.ufo/glyphs/L_tnS_mA_A_cute.glif
new file mode 100644
index 0000000..2ab1b23
--- /dev/null
+++ b/tests/reference/ufo/psfglyphs2ufo/PsfTest-Regular.ufo/glyphs/L_tnS_mA_A_cute.glif
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmAAcute" format="2">
+ <advance width="1120"/>
+ <unicode hex="00E1"/>
+ <anchor x="540" y="0" name="H"/>
+ <anchor x="540" y="-100" name="L"/>
+ <anchor x="1125" y="0" name="O"/>
+ <anchor x="1120" y="1000" name="R"/>
+ <anchor x="540" y="1635" name="U"/>
+ <outline>
+ <component base="LtnSmA"/>
+ <component base="CombAcute" xOffset="1110"/>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfglyphs2ufo/PsfTest-Regular.ufo/glyphs/L_tnS_mA_C_ircum.glif b/tests/reference/ufo/psfglyphs2ufo/PsfTest-Regular.ufo/glyphs/L_tnS_mA_C_ircum.glif
new file mode 100644
index 0000000..6551c45
--- /dev/null
+++ b/tests/reference/ufo/psfglyphs2ufo/PsfTest-Regular.ufo/glyphs/L_tnS_mA_C_ircum.glif
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmACircum" format="2">
+ <advance width="1120"/>
+ <unicode hex="00E2"/>
+ <anchor x="540" y="0" name="H"/>
+ <anchor x="540" y="-100" name="L"/>
+ <anchor x="1125" y="0" name="O"/>
+ <anchor x="1120" y="1000" name="R"/>
+ <anchor x="540" y="1635" name="U"/>
+ <outline>
+ <component base="LtnSmA"/>
+ <component base="CombCircum" xOffset="1110"/>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfglyphs2ufo/PsfTest-Regular.ufo/glyphs/L_tnS_mA_D_iaer.glif b/tests/reference/ufo/psfglyphs2ufo/PsfTest-Regular.ufo/glyphs/L_tnS_mA_D_iaer.glif
new file mode 100644
index 0000000..61c5d3f
--- /dev/null
+++ b/tests/reference/ufo/psfglyphs2ufo/PsfTest-Regular.ufo/glyphs/L_tnS_mA_D_iaer.glif
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmADiaer" format="2">
+ <advance width="1120"/>
+ <unicode hex="00E4"/>
+ <anchor x="540" y="0" name="H"/>
+ <anchor x="540" y="-100" name="L"/>
+ <anchor x="1125" y="0" name="O"/>
+ <anchor x="1120" y="1000" name="R"/>
+ <anchor x="540" y="1505" name="U"/>
+ <outline>
+ <component base="LtnSmA"/>
+ <component base="CombDiaer" xOffset="1110"/>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfglyphs2ufo/PsfTest-Regular.ufo/glyphs/L_tnS_mA_G_rave.glif b/tests/reference/ufo/psfglyphs2ufo/PsfTest-Regular.ufo/glyphs/L_tnS_mA_G_rave.glif
new file mode 100644
index 0000000..9879252
--- /dev/null
+++ b/tests/reference/ufo/psfglyphs2ufo/PsfTest-Regular.ufo/glyphs/L_tnS_mA_G_rave.glif
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmAGrave" format="2">
+ <advance width="1120"/>
+ <unicode hex="00E0"/>
+ <anchor x="540" y="0" name="H"/>
+ <anchor x="540" y="-100" name="L"/>
+ <anchor x="1125" y="0" name="O"/>
+ <anchor x="1120" y="1000" name="R"/>
+ <anchor x="540" y="1635" name="U"/>
+ <outline>
+ <component base="LtnSmA"/>
+ <component base="CombGrave" xOffset="1090"/>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfglyphs2ufo/PsfTest-Regular.ufo/glyphs/L_tnS_mA_R_ingA_bv.glif b/tests/reference/ufo/psfglyphs2ufo/PsfTest-Regular.ufo/glyphs/L_tnS_mA_R_ingA_bv.glif
new file mode 100644
index 0000000..ae3b838
--- /dev/null
+++ b/tests/reference/ufo/psfglyphs2ufo/PsfTest-Regular.ufo/glyphs/L_tnS_mA_R_ingA_bv.glif
@@ -0,0 +1,41 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmARingAbv" format="2">
+ <advance width="1120"/>
+ <unicode hex="00E5"/>
+ <anchor x="540" y="0" name="H"/>
+ <anchor x="540" y="-100" name="L"/>
+ <anchor x="1125" y="0" name="O"/>
+ <anchor x="1120" y="1000" name="R"/>
+ <anchor x="542" y="1635" name="U"/>
+ <outline>
+ <component base="LtnSmA"/>
+ <contour>
+ <point x="642" y="1385" type="curve" smooth="yes"/>
+ <point x="642" y="1325"/>
+ <point x="602" y="1285"/>
+ <point x="542" y="1285" type="curve" smooth="yes"/>
+ <point x="482" y="1285"/>
+ <point x="442" y="1325"/>
+ <point x="442" y="1385" type="curve" smooth="yes"/>
+ <point x="442" y="1445"/>
+ <point x="482" y="1485"/>
+ <point x="542" y="1485" type="curve" smooth="yes"/>
+ <point x="602" y="1485"/>
+ <point x="642" y="1445"/>
+ </contour>
+ <contour>
+ <point x="327" y="1385" type="curve" smooth="yes"/>
+ <point x="327" y="1265"/>
+ <point x="422" y="1170"/>
+ <point x="542" y="1170" type="curve" smooth="yes"/>
+ <point x="662" y="1170"/>
+ <point x="757" y="1265"/>
+ <point x="757" y="1385" type="curve" smooth="yes"/>
+ <point x="757" y="1505"/>
+ <point x="662" y="1600"/>
+ <point x="542" y="1600" type="curve" smooth="yes"/>
+ <point x="422" y="1600"/>
+ <point x="327" y="1505"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfglyphs2ufo/PsfTest-Regular.ufo/glyphs/L_tnS_mA_T_ilde.glif b/tests/reference/ufo/psfglyphs2ufo/PsfTest-Regular.ufo/glyphs/L_tnS_mA_T_ilde.glif
new file mode 100644
index 0000000..cf21919
--- /dev/null
+++ b/tests/reference/ufo/psfglyphs2ufo/PsfTest-Regular.ufo/glyphs/L_tnS_mA_T_ilde.glif
@@ -0,0 +1,41 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmATilde" format="2">
+ <advance width="1120"/>
+ <unicode hex="00E3"/>
+ <anchor x="540" y="0" name="H"/>
+ <anchor x="540" y="-100" name="L"/>
+ <anchor x="1125" y="0" name="O"/>
+ <anchor x="1120" y="1000" name="R"/>
+ <anchor x="540" y="1475" name="U"/>
+ <outline>
+ <component base="LtnSmA"/>
+ <contour>
+ <point x="295" y="1205" type="line"/>
+ <point x="300" y="1254"/>
+ <point x="331" y="1290"/>
+ <point x="380" y="1290" type="curve" smooth="yes"/>
+ <point x="417" y="1290"/>
+ <point x="458" y="1274"/>
+ <point x="535" y="1238" type="curve" smooth="yes"/>
+ <point x="596" y="1210"/>
+ <point x="649" y="1190"/>
+ <point x="702" y="1190" type="curve" smooth="yes"/>
+ <point x="825" y="1190"/>
+ <point x="900" y="1312"/>
+ <point x="900" y="1440" type="curve"/>
+ <point x="795" y="1440" type="line"/>
+ <point x="788" y="1394"/>
+ <point x="757" y="1355"/>
+ <point x="710" y="1355" type="curve" smooth="yes"/>
+ <point x="668" y="1355"/>
+ <point x="627" y="1374"/>
+ <point x="555" y="1403" type="curve" smooth="yes"/>
+ <point x="485" y="1431"/>
+ <point x="438" y="1455"/>
+ <point x="382" y="1455" type="curve" smooth="yes"/>
+ <point x="263" y="1455"/>
+ <point x="190" y="1327"/>
+ <point x="190" y="1205" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfglyphs2ufo/PsfTest-Regular.ufo/glyphs/L_tnS_mB_.glif b/tests/reference/ufo/psfglyphs2ufo/PsfTest-Regular.ufo/glyphs/L_tnS_mB_.glif
new file mode 100644
index 0000000..67ff8ac
--- /dev/null
+++ b/tests/reference/ufo/psfglyphs2ufo/PsfTest-Regular.ufo/glyphs/L_tnS_mB_.glif
@@ -0,0 +1,50 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmB" format="2">
+ <advance width="1155"/>
+ <unicode hex="0062"/>
+ <anchor x="590" y="0" name="H"/>
+ <anchor x="590" y="-100" name="L"/>
+ <anchor x="1155" y="1000" name="R"/>
+ <anchor x="590" y="1635" name="U"/>
+ <outline>
+ <contour>
+ <point x="130" y="1600" type="line"/>
+ <point x="145" y="1488"/>
+ <point x="145" y="1273"/>
+ <point x="145" y="1130" type="curve" smooth="yes"/>
+ <point x="145" y="936"/>
+ <point x="145" y="228"/>
+ <point x="145" y="65" type="curve"/>
+ <point x="272" y="26"/>
+ <point x="413" y="-25"/>
+ <point x="575" y="-25" type="curve" smooth="yes"/>
+ <point x="870" y="-25"/>
+ <point x="1060" y="197"/>
+ <point x="1060" y="540" type="curve" smooth="yes"/>
+ <point x="1060" y="832"/>
+ <point x="917" y="1040"/>
+ <point x="715" y="1040" type="curve" smooth="yes"/>
+ <point x="547" y="1040"/>
+ <point x="423" y="947"/>
+ <point x="330" y="825" type="curve"/>
+ <point x="330" y="916"/>
+ <point x="330" y="1600"/>
+ <point x="330" y="1600" type="curve"/>
+ </contour>
+ <contour>
+ <point x="330" y="585" type="line"/>
+ <point x="398" y="751"/>
+ <point x="531" y="865"/>
+ <point x="655" y="865" type="curve" smooth="yes"/>
+ <point x="799" y="865"/>
+ <point x="880" y="727"/>
+ <point x="880" y="505" type="curve" smooth="yes"/>
+ <point x="880" y="280"/>
+ <point x="752" y="130"/>
+ <point x="575" y="130" type="curve" smooth="yes"/>
+ <point x="489" y="130"/>
+ <point x="428" y="144"/>
+ <point x="330" y="185" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfglyphs2ufo/PsfTest-Regular.ufo/glyphs/L_tnS_mC_.glif b/tests/reference/ufo/psfglyphs2ufo/PsfTest-Regular.ufo/glyphs/L_tnS_mC_.glif
new file mode 100644
index 0000000..7c403fb
--- /dev/null
+++ b/tests/reference/ufo/psfglyphs2ufo/PsfTest-Regular.ufo/glyphs/L_tnS_mC_.glif
@@ -0,0 +1,39 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmC" format="2">
+ <advance width="1020"/>
+ <unicode hex="0063"/>
+ <anchor x="580" y="0" name="H"/>
+ <anchor x="580" y="-100" name="L"/>
+ <anchor x="1020" y="1000" name="R"/>
+ <anchor x="570" y="1100" name="U"/>
+ <outline>
+ <contour>
+ <point x="905" y="260" type="line"/>
+ <point x="818" y="183"/>
+ <point x="720" y="140"/>
+ <point x="600" y="140" type="curve" smooth="yes"/>
+ <point x="406" y="140"/>
+ <point x="285" y="285"/>
+ <point x="285" y="500" type="curve" smooth="yes"/>
+ <point x="285" y="736"/>
+ <point x="422" y="875"/>
+ <point x="600" y="875" type="curve" smooth="yes"/>
+ <point x="703" y="875"/>
+ <point x="790" y="841"/>
+ <point x="880" y="775" type="curve"/>
+ <point x="915" y="955" type="line"/>
+ <point x="842" y="1005"/>
+ <point x="748" y="1040"/>
+ <point x="615" y="1040" type="curve" smooth="yes"/>
+ <point x="297" y="1040"/>
+ <point x="95" y="792"/>
+ <point x="95" y="490" type="curve" smooth="yes"/>
+ <point x="95" y="171"/>
+ <point x="312" y="-25"/>
+ <point x="580" y="-25" type="curve" smooth="yes"/>
+ <point x="730" y="-25"/>
+ <point x="824" y="9"/>
+ <point x="925" y="85" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfglyphs2ufo/PsfTest-Regular.ufo/glyphs/L_tnS_mD_.glif b/tests/reference/ufo/psfglyphs2ufo/PsfTest-Regular.ufo/glyphs/L_tnS_mD_.glif
new file mode 100644
index 0000000..13547d4
--- /dev/null
+++ b/tests/reference/ufo/psfglyphs2ufo/PsfTest-Regular.ufo/glyphs/L_tnS_mD_.glif
@@ -0,0 +1,53 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmD" format="2">
+ <advance width="1190"/>
+ <unicode hex="0064"/>
+ <anchor x="605" y="0" name="H"/>
+ <anchor x="605" y="-100" name="L"/>
+ <anchor x="1190" y="1000" name="R"/>
+ <anchor x="605" y="1635" name="U"/>
+ <outline>
+ <contour>
+ <point x="1030" y="1600" type="line"/>
+ <point x="820" y="1600" type="line"/>
+ <point x="839" y="1516"/>
+ <point x="845" y="1395"/>
+ <point x="845" y="1235" type="curve"/>
+ <point x="845" y="955" type="line"/>
+ <point x="767" y="999"/>
+ <point x="665" y="1040"/>
+ <point x="580" y="1040" type="curve" smooth="yes"/>
+ <point x="312" y="1040"/>
+ <point x="105" y="814"/>
+ <point x="105" y="460" type="curve" smooth="yes"/>
+ <point x="105" y="167"/>
+ <point x="261" y="-25"/>
+ <point x="505" y="-25" type="curve" smooth="yes"/>
+ <point x="652" y="-25"/>
+ <point x="775" y="50"/>
+ <point x="870" y="185" type="curve"/>
+ <point x="887" y="111"/>
+ <point x="910" y="34"/>
+ <point x="925" y="0" type="curve"/>
+ <point x="1105" y="0" type="line"/>
+ <point x="1062" y="112"/>
+ <point x="1030" y="278"/>
+ <point x="1030" y="530" type="curve"/>
+ </contour>
+ <contour>
+ <point x="845" y="400" type="line"/>
+ <point x="790" y="268"/>
+ <point x="662" y="135"/>
+ <point x="540" y="135" type="curve" smooth="yes"/>
+ <point x="366" y="135"/>
+ <point x="290" y="258"/>
+ <point x="290" y="490" type="curve" smooth="yes"/>
+ <point x="290" y="727"/>
+ <point x="429" y="870"/>
+ <point x="580" y="870" type="curve" smooth="yes"/>
+ <point x="681" y="870"/>
+ <point x="746" y="848"/>
+ <point x="845" y="795" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfglyphs2ufo/PsfTest-Regular.ufo/glyphs/L_tnS_mE_.glif b/tests/reference/ufo/psfglyphs2ufo/PsfTest-Regular.ufo/glyphs/L_tnS_mE_.glif
new file mode 100644
index 0000000..f231440
--- /dev/null
+++ b/tests/reference/ufo/psfglyphs2ufo/PsfTest-Regular.ufo/glyphs/L_tnS_mE_.glif
@@ -0,0 +1,45 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmE" format="2">
+ <advance width="1095"/>
+ <unicode hex="0065"/>
+ <anchor x="545" y="0" name="H"/>
+ <anchor x="569" y="-100" name="L"/>
+ <anchor x="925" y="0" name="O"/>
+ <anchor x="1095" y="1000" name="R"/>
+ <anchor x="569" y="1100" name="U"/>
+ <outline>
+ <contour>
+ <point x="989" y="485" type="line"/>
+ <point x="990" y="503"/>
+ <point x="990" y="545"/>
+ <point x="990" y="563" type="curve" smooth="yes"/>
+ <point x="990" y="788"/>
+ <point x="905" y="1040"/>
+ <point x="575" y="1040" type="curve" smooth="yes"/>
+ <point x="279" y="1040"/>
+ <point x="95" y="826"/>
+ <point x="95" y="495" type="curve" smooth="yes"/>
+ <point x="95" y="155"/>
+ <point x="320" y="-25"/>
+ <point x="575" y="-25" type="curve" smooth="yes"/>
+ <point x="729" y="-25"/>
+ <point x="853" y="2"/>
+ <point x="995" y="75" type="curve"/>
+ <point x="975" y="240" type="line"/>
+ <point x="853" y="166"/>
+ <point x="729" y="140"/>
+ <point x="600" y="140" type="curve" smooth="yes"/>
+ <point x="414" y="140"/>
+ <point x="280" y="258"/>
+ <point x="280" y="505" type="curve" smooth="yes"/>
+ <point x="280" y="770"/>
+ <point x="385" y="890"/>
+ <point x="560" y="890" type="curve" smooth="yes"/>
+ <point x="705" y="890"/>
+ <point x="810" y="797"/>
+ <point x="810" y="625" type="curve"/>
+ <point x="245" y="625" type="line"/>
+ <point x="245" y="485" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfglyphs2ufo/PsfTest-Regular.ufo/glyphs/L_tnS_mF_.glif b/tests/reference/ufo/psfglyphs2ufo/PsfTest-Regular.ufo/glyphs/L_tnS_mF_.glif
new file mode 100644
index 0000000..56c0b15
--- /dev/null
+++ b/tests/reference/ufo/psfglyphs2ufo/PsfTest-Regular.ufo/glyphs/L_tnS_mF_.glif
@@ -0,0 +1,39 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmF" format="2">
+ <advance width="750"/>
+ <unicode hex="0066"/>
+ <anchor x="370" y="0" name="H"/>
+ <anchor x="335" y="-100" name="L"/>
+ <anchor x="560" y="1635" name="U"/>
+ <outline>
+ <contour>
+ <point x="40" y="850" type="line"/>
+ <point x="240" y="850" type="line"/>
+ <point x="240" y="0" type="line"/>
+ <point x="455" y="0" type="line"/>
+ <point x="433" y="105"/>
+ <point x="425" y="300"/>
+ <point x="425" y="494" type="curve" smooth="yes"/>
+ <point x="425" y="850" type="line"/>
+ <point x="695" y="850" type="line"/>
+ <point x="695" y="995" type="line"/>
+ <point x="425" y="995" type="line"/>
+ <point x="425" y="1210" type="line" smooth="yes"/>
+ <point x="425" y="1381"/>
+ <point x="481" y="1450"/>
+ <point x="585" y="1450" type="curve" smooth="yes"/>
+ <point x="643" y="1450"/>
+ <point x="710" y="1427"/>
+ <point x="760" y="1390" type="curve"/>
+ <point x="805" y="1550" type="line"/>
+ <point x="743" y="1594"/>
+ <point x="663" y="1620"/>
+ <point x="585" y="1620" type="curve" smooth="yes"/>
+ <point x="369" y="1620"/>
+ <point x="240" y="1470"/>
+ <point x="240" y="1170" type="curve" smooth="yes"/>
+ <point x="240" y="995" type="line"/>
+ <point x="40" y="995" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfglyphs2ufo/PsfTest-Regular.ufo/glyphs/L_tnS_mG_.glif b/tests/reference/ufo/psfglyphs2ufo/PsfTest-Regular.ufo/glyphs/L_tnS_mG_.glif
new file mode 100644
index 0000000..236da64
--- /dev/null
+++ b/tests/reference/ufo/psfglyphs2ufo/PsfTest-Regular.ufo/glyphs/L_tnS_mG_.glif
@@ -0,0 +1,91 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmG" format="2">
+ <advance width="1095"/>
+ <unicode hex="0067"/>
+ <anchor x="545" y="-432" name="H"/>
+ <anchor x="545" y="-535" name="L"/>
+ <anchor x="1095" y="1000" name="R"/>
+ <anchor x="515" y="1100" name="U"/>
+ <outline>
+ <contour>
+ <point x="330" y="395" type="line"/>
+ <point x="234" y="357"/>
+ <point x="180" y="275"/>
+ <point x="180" y="215" type="curve" smooth="yes"/>
+ <point x="180" y="121"/>
+ <point x="263" y="27"/>
+ <point x="545" y="-5" type="curve" smooth="yes"/>
+ <point x="805" y="-35"/>
+ <point x="880" y="-90"/>
+ <point x="880" y="-170" type="curve" smooth="yes"/>
+ <point x="880" y="-255"/>
+ <point x="731" y="-360"/>
+ <point x="550" y="-360" type="curve" smooth="yes"/>
+ <point x="323" y="-360"/>
+ <point x="215" y="-261"/>
+ <point x="215" y="-180" type="curve" smooth="yes"/>
+ <point x="215" y="-121"/>
+ <point x="244" y="-56"/>
+ <point x="465" y="20" type="curve"/>
+ <point x="459" y="49"/>
+ <point x="290" y="75"/>
+ <point x="290" y="75" type="curve"/>
+ <point x="113" y="2"/>
+ <point x="30" y="-89"/>
+ <point x="30" y="-200" type="curve" smooth="yes"/>
+ <point x="30" y="-409"/>
+ <point x="303" y="-505"/>
+ <point x="535" y="-505" type="curve" smooth="yes"/>
+ <point x="777" y="-505"/>
+ <point x="1065" y="-375"/>
+ <point x="1065" y="-160" type="curve" smooth="yes"/>
+ <point x="1065" y="-8"/>
+ <point x="967" y="90"/>
+ <point x="670" y="125" type="curve" smooth="yes"/>
+ <point x="410" y="156"/>
+ <point x="345" y="198"/>
+ <point x="345" y="235" type="curve" smooth="yes"/>
+ <point x="345" y="271"/>
+ <point x="384" y="316"/>
+ <point x="500" y="350" type="curve"/>
+ </contour>
+ <contour>
+ <point x="1050" y="1040" type="line"/>
+ <point x="951" y="1033"/>
+ <point x="819" y="997"/>
+ <point x="730" y="940" type="curve"/>
+ <point x="795" y="825" type="line"/>
+ <point x="887" y="863"/>
+ <point x="967" y="878"/>
+ <point x="1040" y="880" type="curve"/>
+ </contour>
+ <contour>
+ <point x="115" y="680" type="curve" smooth="yes"/>
+ <point x="115" y="476"/>
+ <point x="289" y="325"/>
+ <point x="515" y="325" type="curve" smooth="yes"/>
+ <point x="742" y="325"/>
+ <point x="915" y="476"/>
+ <point x="915" y="680" type="curve" smooth="yes"/>
+ <point x="915" y="884"/>
+ <point x="742" y="1040"/>
+ <point x="515" y="1040" type="curve" smooth="yes"/>
+ <point x="289" y="1040"/>
+ <point x="115" y="884"/>
+ </contour>
+ <contour>
+ <point x="285" y="680" type="curve" smooth="yes"/>
+ <point x="285" y="803"/>
+ <point x="382" y="895"/>
+ <point x="515" y="895" type="curve" smooth="yes"/>
+ <point x="649" y="895"/>
+ <point x="745" y="803"/>
+ <point x="745" y="680" type="curve" smooth="yes"/>
+ <point x="745" y="557"/>
+ <point x="649" y="465"/>
+ <point x="515" y="465" type="curve" smooth="yes"/>
+ <point x="382" y="465"/>
+ <point x="285" y="557"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfglyphs2ufo/PsfTest-Regular.ufo/glyphs/L_tnS_mH_.glif b/tests/reference/ufo/psfglyphs2ufo/PsfTest-Regular.ufo/glyphs/L_tnS_mH_.glif
new file mode 100644
index 0000000..bad060c
--- /dev/null
+++ b/tests/reference/ufo/psfglyphs2ufo/PsfTest-Regular.ufo/glyphs/L_tnS_mH_.glif
@@ -0,0 +1,43 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmH" format="2">
+ <advance width="1175"/>
+ <unicode hex="0068"/>
+ <anchor x="250" y="0" name="H"/>
+ <anchor x="585" y="-100" name="L"/>
+ <anchor x="585" y="1635" name="U"/>
+ <outline>
+ <contour>
+ <point x="1040" y="0" type="line"/>
+ <point x="1040" y="0"/>
+ <point x="1040" y="459"/>
+ <point x="1040" y="625" type="curve" smooth="yes"/>
+ <point x="1040" y="900"/>
+ <point x="923" y="1040"/>
+ <point x="710" y="1040" type="curve" smooth="yes"/>
+ <point x="570" y="1040"/>
+ <point x="428" y="969"/>
+ <point x="330" y="830" type="curve"/>
+ <point x="330" y="877"/>
+ <point x="330" y="1600"/>
+ <point x="330" y="1600" type="curve"/>
+ <point x="130" y="1600" type="line"/>
+ <point x="145" y="1514"/>
+ <point x="145" y="1345"/>
+ <point x="145" y="1130" type="curve" smooth="yes"/>
+ <point x="145" y="935"/>
+ <point x="145" y="0"/>
+ <point x="145" y="0" type="curve"/>
+ <point x="330" y="0" type="line"/>
+ <point x="330" y="580" type="line"/>
+ <point x="374" y="716"/>
+ <point x="511" y="865"/>
+ <point x="655" y="865" type="curve" smooth="yes"/>
+ <point x="789" y="865"/>
+ <point x="855" y="800"/>
+ <point x="855" y="550" type="curve" smooth="yes"/>
+ <point x="855" y="413"/>
+ <point x="855" y="0"/>
+ <point x="855" y="0" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfglyphs2ufo/PsfTest-Regular.ufo/glyphs/L_tnS_mI_.glif b/tests/reference/ufo/psfglyphs2ufo/PsfTest-Regular.ufo/glyphs/L_tnS_mI_.glif
new file mode 100644
index 0000000..369347b
--- /dev/null
+++ b/tests/reference/ufo/psfglyphs2ufo/PsfTest-Regular.ufo/glyphs/L_tnS_mI_.glif
@@ -0,0 +1,40 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmI" format="2">
+ <advance width="565"/>
+ <unicode hex="0069"/>
+ <anchor x="282" y="0" name="H"/>
+ <anchor x="285" y="-100" name="L"/>
+ <anchor x="500" y="0" name="O"/>
+ <anchor x="555" y="1000" name="R"/>
+ <anchor x="282" y="1100" name="U"/>
+ <outline>
+ <contour>
+ <point x="375" y="1020" type="line"/>
+ <point x="175" y="1020" type="line"/>
+ <point x="188" y="915"/>
+ <point x="190" y="725"/>
+ <point x="190" y="530" type="curve" smooth="yes"/>
+ <point x="190" y="336"/>
+ <point x="190" y="0"/>
+ <point x="190" y="0" type="curve"/>
+ <point x="395" y="0" type="line"/>
+ <point x="382" y="107"/>
+ <point x="375" y="346"/>
+ <point x="375" y="475" type="curve" smooth="yes"/>
+ </contour>
+ <contour>
+ <point x="155" y="1345" type="curve" smooth="yes"/>
+ <point x="155" y="1271"/>
+ <point x="206" y="1210"/>
+ <point x="280" y="1210" type="curve" smooth="yes"/>
+ <point x="355" y="1210"/>
+ <point x="410" y="1271"/>
+ <point x="410" y="1345" type="curve" smooth="yes"/>
+ <point x="410" y="1419"/>
+ <point x="355" y="1480"/>
+ <point x="280" y="1480" type="curve" smooth="yes"/>
+ <point x="206" y="1480"/>
+ <point x="155" y="1419"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfglyphs2ufo/PsfTest-Regular.ufo/glyphs/L_tnS_mJ_.glif b/tests/reference/ufo/psfglyphs2ufo/PsfTest-Regular.ufo/glyphs/L_tnS_mJ_.glif
new file mode 100644
index 0000000..87f74c6
--- /dev/null
+++ b/tests/reference/ufo/psfglyphs2ufo/PsfTest-Regular.ufo/glyphs/L_tnS_mJ_.glif
@@ -0,0 +1,44 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmJ" format="2">
+ <advance width="595"/>
+ <unicode hex="006A"/>
+ <anchor x="125" y="-500" name="L"/>
+ <anchor x="313" y="1100" name="U"/>
+ <outline>
+ <contour>
+ <point x="405" y="1020" type="line"/>
+ <point x="205" y="1020" type="line"/>
+ <point x="218" y="915"/>
+ <point x="220" y="725"/>
+ <point x="220" y="530" type="curve"/>
+ <point x="220" y="-25" type="line"/>
+ <point x="220" y="-222"/>
+ <point x="147" y="-300"/>
+ <point x="40" y="-300" type="curve" smooth="yes"/>
+ <point x="-16" y="-300"/>
+ <point x="-111" y="-273"/>
+ <point x="-155" y="-240" type="curve"/>
+ <point x="-190" y="-405" type="line"/>
+ <point x="-130" y="-446"/>
+ <point x="-26" y="-470"/>
+ <point x="30" y="-470" type="curve" smooth="yes"/>
+ <point x="258" y="-470"/>
+ <point x="405" y="-348"/>
+ <point x="405" y="25" type="curve" smooth="yes"/>
+ </contour>
+ <contour>
+ <point x="185" y="1345" type="curve" smooth="yes"/>
+ <point x="185" y="1271"/>
+ <point x="236" y="1210"/>
+ <point x="310" y="1210" type="curve" smooth="yes"/>
+ <point x="385" y="1210"/>
+ <point x="440" y="1271"/>
+ <point x="440" y="1345" type="curve" smooth="yes"/>
+ <point x="440" y="1419"/>
+ <point x="385" y="1480"/>
+ <point x="310" y="1480" type="curve" smooth="yes"/>
+ <point x="236" y="1480"/>
+ <point x="185" y="1419"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfglyphs2ufo/PsfTest-Regular.ufo/glyphs/L_tnS_mK_.glif b/tests/reference/ufo/psfglyphs2ufo/PsfTest-Regular.ufo/glyphs/L_tnS_mK_.glif
new file mode 100644
index 0000000..d1b00cb
--- /dev/null
+++ b/tests/reference/ufo/psfglyphs2ufo/PsfTest-Regular.ufo/glyphs/L_tnS_mK_.glif
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmK" format="2">
+ <advance width="1035"/>
+ <unicode hex="006B"/>
+ <guideline x="500" y="774" angle="314"/>
+ <anchor x="243" y="0" name="H"/>
+ <anchor x="572" y="-100" name="L"/>
+ <anchor x="1035" y="1000" name="R"/>
+ <anchor x="572" y="1635" name="U"/>
+ <outline>
+ <contour>
+ <point x="330" y="0" type="line"/>
+ <point x="330" y="1600" type="line"/>
+ <point x="130" y="1600" type="line"/>
+ <point x="145" y="1514"/>
+ <point x="145" y="1345"/>
+ <point x="145" y="1130" type="curve" smooth="yes"/>
+ <point x="145" y="934"/>
+ <point x="145" y="0"/>
+ <point x="145" y="0" type="curve"/>
+ </contour>
+ <contour>
+ <point x="735" y="1020" type="line"/>
+ <point x="280" y="550" type="line"/>
+ <point x="436" y="524" type="line"/>
+ <point x="985" y="1020" type="line"/>
+ </contour>
+ <contour>
+ <point x="305" y="550" type="line"/>
+ <point x="770" y="0" type="line"/>
+ <point x="1015" y="0" type="line"/>
+ <point x="410" y="660" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfglyphs2ufo/PsfTest-Regular.ufo/glyphs/L_tnS_mL_.glif b/tests/reference/ufo/psfglyphs2ufo/PsfTest-Regular.ufo/glyphs/L_tnS_mL_.glif
new file mode 100644
index 0000000..4378793
--- /dev/null
+++ b/tests/reference/ufo/psfglyphs2ufo/PsfTest-Regular.ufo/glyphs/L_tnS_mL_.glif
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmL" format="2">
+ <advance width="565"/>
+ <unicode hex="006C"/>
+ <guideline x="500" y="874" angle="340"/>
+ <anchor x="290" y="0" name="H"/>
+ <anchor x="290" y="-100" name="L"/>
+ <anchor x="550" y="1000" name="R"/>
+ <anchor x="282" y="1635" name="U"/>
+ <outline>
+ <contour>
+ <point x="375" y="1600" type="line"/>
+ <point x="170" y="1600" type="line"/>
+ <point x="183" y="1485"/>
+ <point x="190" y="1324"/>
+ <point x="190" y="1130" type="curve"/>
+ <point x="190" y="0" type="line"/>
+ <point x="395" y="0" type="line"/>
+ <point x="382" y="109"/>
+ <point x="375" y="346"/>
+ <point x="375" y="475" type="curve" smooth="yes"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfglyphs2ufo/PsfTest-Regular.ufo/glyphs/L_tnS_mM_.glif b/tests/reference/ufo/psfglyphs2ufo/PsfTest-Regular.ufo/glyphs/L_tnS_mM_.glif
new file mode 100644
index 0000000..4498bb1
--- /dev/null
+++ b/tests/reference/ufo/psfglyphs2ufo/PsfTest-Regular.ufo/glyphs/L_tnS_mM_.glif
@@ -0,0 +1,52 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmM" format="2">
+ <advance width="1685"/>
+ <unicode hex="006D"/>
+ <anchor x="1450" y="0" name="H"/>
+ <anchor x="865" y="-100" name="L"/>
+ <anchor x="865" y="1100" name="U"/>
+ <outline>
+ <contour>
+ <point x="945" y="660" type="line"/>
+ <point x="1003" y="785"/>
+ <point x="1102" y="865"/>
+ <point x="1200" y="865" type="curve" smooth="yes"/>
+ <point x="1312" y="865"/>
+ <point x="1345" y="808"/>
+ <point x="1345" y="550" type="curve" smooth="yes"/>
+ <point x="1345" y="0" type="line"/>
+ <point x="1530" y="0" type="line"/>
+ <point x="1530" y="660" type="line" smooth="yes"/>
+ <point x="1530" y="907"/>
+ <point x="1463" y="1040"/>
+ <point x="1260" y="1040" type="curve" smooth="yes"/>
+ <point x="1155" y="1040"/>
+ <point x="1046" y="1007"/>
+ <point x="921" y="872" type="curve"/>
+ <point x="888" y="960"/>
+ <point x="806" y="1040"/>
+ <point x="675" y="1040" type="curve" smooth="yes"/>
+ <point x="560" y="1040"/>
+ <point x="459" y="1006"/>
+ <point x="337" y="865" type="curve"/>
+ <point x="330" y="913"/>
+ <point x="320" y="978"/>
+ <point x="305" y="1020" type="curve"/>
+ <point x="125" y="1020" type="line"/>
+ <point x="146" y="951"/>
+ <point x="175" y="811"/>
+ <point x="175" y="615" type="curve" smooth="yes"/>
+ <point x="175" y="0" type="line"/>
+ <point x="360" y="0" type="line"/>
+ <point x="360" y="660" type="line"/>
+ <point x="413" y="780"/>
+ <point x="517" y="865"/>
+ <point x="615" y="865" type="curve" smooth="yes"/>
+ <point x="727" y="865"/>
+ <point x="760" y="818"/>
+ <point x="760" y="570" type="curve" smooth="yes"/>
+ <point x="760" y="0" type="line"/>
+ <point x="945" y="0" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfglyphs2ufo/PsfTest-Regular.ufo/glyphs/L_tnS_mN_.glif b/tests/reference/ufo/psfglyphs2ufo/PsfTest-Regular.ufo/glyphs/L_tnS_mN_.glif
new file mode 100644
index 0000000..5534dd8
--- /dev/null
+++ b/tests/reference/ufo/psfglyphs2ufo/PsfTest-Regular.ufo/glyphs/L_tnS_mN_.glif
@@ -0,0 +1,43 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmN" format="2">
+ <advance width="1185"/>
+ <unicode hex="006E"/>
+ <anchor x="970" y="0" name="H"/>
+ <anchor x="600" y="-100" name="L"/>
+ <anchor x="600" y="1100" name="U"/>
+ <outline>
+ <contour>
+ <point x="1050" y="0" type="line"/>
+ <point x="1050" y="0"/>
+ <point x="1050" y="459"/>
+ <point x="1050" y="625" type="curve" smooth="yes"/>
+ <point x="1050" y="900"/>
+ <point x="933" y="1040"/>
+ <point x="720" y="1040" type="curve" smooth="yes"/>
+ <point x="579" y="1040"/>
+ <point x="452" y="977"/>
+ <point x="325" y="825" type="curve"/>
+ <point x="318" y="873"/>
+ <point x="300" y="978"/>
+ <point x="285" y="1020" type="curve"/>
+ <point x="105" y="1020" type="line"/>
+ <point x="127" y="951"/>
+ <point x="155" y="811"/>
+ <point x="155" y="615" type="curve" smooth="yes"/>
+ <point x="155" y="420"/>
+ <point x="155" y="0"/>
+ <point x="155" y="0" type="curve"/>
+ <point x="340" y="0" type="line"/>
+ <point x="340" y="580" type="line"/>
+ <point x="384" y="716"/>
+ <point x="521" y="865"/>
+ <point x="665" y="865" type="curve" smooth="yes"/>
+ <point x="800" y="865"/>
+ <point x="865" y="800"/>
+ <point x="865" y="550" type="curve" smooth="yes"/>
+ <point x="865" y="413"/>
+ <point x="865" y="0"/>
+ <point x="865" y="0" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfglyphs2ufo/PsfTest-Regular.ufo/glyphs/L_tnS_mO_.glif b/tests/reference/ufo/psfglyphs2ufo/PsfTest-Regular.ufo/glyphs/L_tnS_mO_.glif
new file mode 100644
index 0000000..ee9b6c6
--- /dev/null
+++ b/tests/reference/ufo/psfglyphs2ufo/PsfTest-Regular.ufo/glyphs/L_tnS_mO_.glif
@@ -0,0 +1,40 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmO" format="2">
+ <advance width="1140"/>
+ <unicode hex="006F"/>
+ <anchor x="570" y="0" name="H"/>
+ <anchor x="570" y="-100" name="L"/>
+ <anchor x="835" y="0" name="O"/>
+ <anchor x="1140" y="1000" name="R"/>
+ <anchor x="570" y="1100" name="U"/>
+ <outline>
+ <contour>
+ <point x="95" y="505" type="curve" smooth="yes"/>
+ <point x="95" y="161"/>
+ <point x="286" y="-25"/>
+ <point x="560" y="-25" type="curve" smooth="yes"/>
+ <point x="823" y="-25"/>
+ <point x="1045" y="161"/>
+ <point x="1045" y="505" type="curve" smooth="yes"/>
+ <point x="1045" y="849"/>
+ <point x="855" y="1040"/>
+ <point x="580" y="1040" type="curve" smooth="yes"/>
+ <point x="317" y="1040"/>
+ <point x="95" y="849"/>
+ </contour>
+ <contour>
+ <point x="280" y="505" type="curve" smooth="yes"/>
+ <point x="280" y="739"/>
+ <point x="408" y="880"/>
+ <point x="570" y="880" type="curve" smooth="yes"/>
+ <point x="742" y="880"/>
+ <point x="860" y="739"/>
+ <point x="860" y="505" type="curve" smooth="yes"/>
+ <point x="860" y="272"/>
+ <point x="731" y="135"/>
+ <point x="570" y="135" type="curve" smooth="yes"/>
+ <point x="398" y="135"/>
+ <point x="280" y="272"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfglyphs2ufo/PsfTest-Regular.ufo/glyphs/L_tnS_mP_.glif b/tests/reference/ufo/psfglyphs2ufo/PsfTest-Regular.ufo/glyphs/L_tnS_mP_.glif
new file mode 100644
index 0000000..e960bc9
--- /dev/null
+++ b/tests/reference/ufo/psfglyphs2ufo/PsfTest-Regular.ufo/glyphs/L_tnS_mP_.glif
@@ -0,0 +1,56 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmP" format="2">
+ <advance width="1170"/>
+ <unicode hex="0070"/>
+ <guideline x="214" y="-490" angle="0"/>
+ <anchor x="265" y="-435" name="H"/>
+ <anchor x="590" y="-500" name="L"/>
+ <anchor x="1170" y="1000" name="R"/>
+ <anchor x="590" y="1100" name="U"/>
+ <outline>
+ <contour>
+ <point x="105" y="1020" type="line"/>
+ <point x="150" y="907"/>
+ <point x="155" y="734"/>
+ <point x="155" y="485" type="curve" smooth="yes"/>
+ <point x="155" y="291"/>
+ <point x="155" y="-490"/>
+ <point x="155" y="-490" type="curve"/>
+ <point x="365" y="-490" type="line"/>
+ <point x="348" y="-405"/>
+ <point x="340" y="-310"/>
+ <point x="340" y="-150" type="curve"/>
+ <point x="340" y="85" type="line"/>
+ <point x="435" y="18"/>
+ <point x="513" y="-25"/>
+ <point x="620" y="-25" type="curve" smooth="yes"/>
+ <point x="871" y="-25"/>
+ <point x="1075" y="193"/>
+ <point x="1075" y="535" type="curve" smooth="yes"/>
+ <point x="1075" y="828"/>
+ <point x="923" y="1040"/>
+ <point x="695" y="1040" type="curve" smooth="yes"/>
+ <point x="547" y="1040"/>
+ <point x="419" y="954"/>
+ <point x="325" y="830" type="curve"/>
+ <point x="316" y="922"/>
+ <point x="300" y="986"/>
+ <point x="285" y="1020" type="curve"/>
+ </contour>
+ <contour>
+ <point x="340" y="575" type="line"/>
+ <point x="414" y="768"/>
+ <point x="545" y="870"/>
+ <point x="660" y="870" type="curve" smooth="yes"/>
+ <point x="804" y="870"/>
+ <point x="890" y="727"/>
+ <point x="890" y="505" type="curve" smooth="yes"/>
+ <point x="890" y="279"/>
+ <point x="761" y="140"/>
+ <point x="620" y="140" type="curve" smooth="yes"/>
+ <point x="528" y="140"/>
+ <point x="477" y="164"/>
+ <point x="340" y="260" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfglyphs2ufo/PsfTest-Regular.ufo/glyphs/L_tnS_mQ_.glif b/tests/reference/ufo/psfglyphs2ufo/PsfTest-Regular.ufo/glyphs/L_tnS_mQ_.glif
new file mode 100644
index 0000000..1da1d6a
--- /dev/null
+++ b/tests/reference/ufo/psfglyphs2ufo/PsfTest-Regular.ufo/glyphs/L_tnS_mQ_.glif
@@ -0,0 +1,47 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmQ" format="2">
+ <advance width="1130"/>
+ <unicode hex="0071"/>
+ <anchor x="555" y="-500" name="L"/>
+ <anchor x="1130" y="1000" name="R"/>
+ <anchor x="555" y="1100" name="U"/>
+ <outline>
+ <contour>
+ <point x="795" y="-490" type="line"/>
+ <point x="1005" y="-490" type="line"/>
+ <point x="988" y="-405"/>
+ <point x="980" y="-310"/>
+ <point x="980" y="-150" type="curve" smooth="yes"/>
+ <point x="980" y="-26"/>
+ <point x="980" y="965"/>
+ <point x="980" y="965" type="curve"/>
+ <point x="872" y="1001"/>
+ <point x="746" y="1040"/>
+ <point x="625" y="1040" type="curve" smooth="yes"/>
+ <point x="260" y="1040"/>
+ <point x="105" y="742"/>
+ <point x="105" y="435" type="curve" smooth="yes"/>
+ <point x="105" y="117"/>
+ <point x="321" y="-25"/>
+ <point x="505" y="-25" type="curve" smooth="yes"/>
+ <point x="598" y="-25"/>
+ <point x="691" y="19"/>
+ <point x="795" y="140" type="curve"/>
+ </contour>
+ <contour>
+ <point x="795" y="365" type="line"/>
+ <point x="713" y="219"/>
+ <point x="612" y="145"/>
+ <point x="520" y="145" type="curve" smooth="yes"/>
+ <point x="412" y="145"/>
+ <point x="290" y="237"/>
+ <point x="290" y="485" type="curve" smooth="yes"/>
+ <point x="290" y="674"/>
+ <point x="376" y="870"/>
+ <point x="595" y="870" type="curve" smooth="yes"/>
+ <point x="656" y="870"/>
+ <point x="735" y="853"/>
+ <point x="795" y="830" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfglyphs2ufo/PsfTest-Regular.ufo/glyphs/L_tnS_mR_.glif b/tests/reference/ufo/psfglyphs2ufo/PsfTest-Regular.ufo/glyphs/L_tnS_mR_.glif
new file mode 100644
index 0000000..0f090a4
--- /dev/null
+++ b/tests/reference/ufo/psfglyphs2ufo/PsfTest-Regular.ufo/glyphs/L_tnS_mR_.glif
@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmR" format="2">
+ <advance width="890"/>
+ <unicode hex="0072"/>
+ <guideline x="214" y="500" angle="0"/>
+ <anchor x="270" y="0" name="H"/>
+ <anchor x="255" y="-100" name="L"/>
+ <anchor x="455" y="1100" name="U"/>
+ <outline>
+ <contour>
+ <point x="340" y="0" type="line"/>
+ <point x="340" y="580" type="line"/>
+ <point x="384" y="716"/>
+ <point x="521" y="860"/>
+ <point x="605" y="860" type="curve" smooth="yes"/>
+ <point x="684" y="860"/>
+ <point x="720" y="770"/>
+ <point x="720" y="670" type="curve"/>
+ <point x="880" y="705" type="line"/>
+ <point x="880" y="880"/>
+ <point x="817" y="1040"/>
+ <point x="650" y="1040" type="curve" smooth="yes"/>
+ <point x="559" y="1040"/>
+ <point x="422" y="964"/>
+ <point x="325" y="825" type="curve"/>
+ <point x="318" y="873"/>
+ <point x="300" y="978"/>
+ <point x="285" y="1020" type="curve"/>
+ <point x="105" y="1020" type="line"/>
+ <point x="127" y="951"/>
+ <point x="155" y="811"/>
+ <point x="155" y="615" type="curve" smooth="yes"/>
+ <point x="155" y="0" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfglyphs2ufo/PsfTest-Regular.ufo/glyphs/L_tnS_mS_.glif b/tests/reference/ufo/psfglyphs2ufo/PsfTest-Regular.ufo/glyphs/L_tnS_mS_.glif
new file mode 100644
index 0000000..ea1e7ba
--- /dev/null
+++ b/tests/reference/ufo/psfglyphs2ufo/PsfTest-Regular.ufo/glyphs/L_tnS_mS_.glif
@@ -0,0 +1,50 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmS" format="2">
+ <advance width="965"/>
+ <unicode hex="0073"/>
+ <anchor x="495" y="0" name="H"/>
+ <anchor x="495" y="-100" name="L"/>
+ <anchor x="495" y="1100" name="U"/>
+ <outline>
+ <contour>
+ <point x="835" y="960" type="line"/>
+ <point x="766" y="998"/>
+ <point x="660" y="1040"/>
+ <point x="515" y="1040" type="curve" smooth="yes"/>
+ <point x="211" y="1040"/>
+ <point x="130" y="832"/>
+ <point x="130" y="740" type="curve" smooth="yes"/>
+ <point x="130" y="616"/>
+ <point x="182" y="514"/>
+ <point x="425" y="455" type="curve" smooth="yes"/>
+ <point x="649" y="400"/>
+ <point x="700" y="345"/>
+ <point x="700" y="270" type="curve" smooth="yes"/>
+ <point x="700" y="201"/>
+ <point x="617" y="135"/>
+ <point x="500" y="135" type="curve" smooth="yes"/>
+ <point x="394" y="135"/>
+ <point x="250" y="189"/>
+ <point x="160" y="270" type="curve"/>
+ <point x="110" y="90" type="line"/>
+ <point x="189" y="28"/>
+ <point x="333" y="-25"/>
+ <point x="495" y="-25" type="curve" smooth="yes"/>
+ <point x="710" y="-25"/>
+ <point x="880" y="115"/>
+ <point x="880" y="295" type="curve" smooth="yes"/>
+ <point x="880" y="481"/>
+ <point x="731" y="559"/>
+ <point x="550" y="600" type="curve" smooth="yes"/>
+ <point x="340" y="648"/>
+ <point x="310" y="680"/>
+ <point x="310" y="750" type="curve" smooth="yes"/>
+ <point x="310" y="810"/>
+ <point x="358" y="880"/>
+ <point x="505" y="880" type="curve" smooth="yes"/>
+ <point x="629" y="880"/>
+ <point x="733" y="824"/>
+ <point x="800" y="785" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfglyphs2ufo/PsfTest-Regular.ufo/glyphs/L_tnS_mT_.glif b/tests/reference/ufo/psfglyphs2ufo/PsfTest-Regular.ufo/glyphs/L_tnS_mT_.glif
new file mode 100644
index 0000000..45d6b50
--- /dev/null
+++ b/tests/reference/ufo/psfglyphs2ufo/PsfTest-Regular.ufo/glyphs/L_tnS_mT_.glif
@@ -0,0 +1,39 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmT" format="2">
+ <advance width="835"/>
+ <unicode hex="0074"/>
+ <anchor x="475" y="0" name="H"/>
+ <anchor x="475" y="-100" name="L"/>
+ <anchor x="835" y="1000" name="R"/>
+ <anchor x="325" y="1360" name="U"/>
+ <outline>
+ <contour>
+ <point x="760" y="215" type="line"/>
+ <point x="672" y="166"/>
+ <point x="600" y="140"/>
+ <point x="543" y="140" type="curve" smooth="yes"/>
+ <point x="453" y="140"/>
+ <point x="415" y="184"/>
+ <point x="415" y="390" type="curve" smooth="yes"/>
+ <point x="415" y="528"/>
+ <point x="415" y="1320"/>
+ <point x="415" y="1320" type="curve"/>
+ <point x="230" y="1320" type="line"/>
+ <point x="230" y="1320"/>
+ <point x="230" y="435"/>
+ <point x="230" y="270" type="curve" smooth="yes"/>
+ <point x="230" y="39"/>
+ <point x="356" y="-25"/>
+ <point x="512" y="-25" type="curve" smooth="yes"/>
+ <point x="582" y="-25"/>
+ <point x="668" y="-4"/>
+ <point x="760" y="55" type="curve"/>
+ </contour>
+ <contour>
+ <point x="30" y="850" type="line"/>
+ <point x="740" y="850" type="line"/>
+ <point x="740" y="995" type="line"/>
+ <point x="30" y="995" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfglyphs2ufo/PsfTest-Regular.ufo/glyphs/L_tnS_mU_.glif b/tests/reference/ufo/psfglyphs2ufo/PsfTest-Regular.ufo/glyphs/L_tnS_mU_.glif
new file mode 100644
index 0000000..39609ad
--- /dev/null
+++ b/tests/reference/ufo/psfglyphs2ufo/PsfTest-Regular.ufo/glyphs/L_tnS_mU_.glif
@@ -0,0 +1,51 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmU" format="2">
+ <advance width="1185"/>
+ <unicode hex="0075"/>
+ <anchor x="589" y="0" name="H"/>
+ <anchor x="589" y="-100" name="L"/>
+ <anchor x="1192" y="0" name="O"/>
+ <anchor x="1185" y="1000" name="R"/>
+ <anchor x="589" y="1100" name="U"/>
+ <outline>
+ <contour>
+ <point x="1090" y="0" type="line"/>
+ <point x="1048" y="112"/>
+ <point x="1025" y="256"/>
+ <point x="1025" y="450" type="curve" smooth="yes"/>
+ <point x="1025" y="646"/>
+ <point x="1025" y="1020"/>
+ <point x="1025" y="1020" type="curve"/>
+ <point x="820" y="1020" type="line"/>
+ <point x="838" y="898"/>
+ <point x="840" y="832"/>
+ <point x="840" y="700" type="curve" smooth="yes"/>
+ <point x="840" y="420" type="line"/>
+ <point x="787" y="298"/>
+ <point x="628" y="140"/>
+ <point x="510" y="140" type="curve" smooth="yes"/>
+ <point x="383" y="140"/>
+ <point x="340" y="238"/>
+ <point x="340" y="465" type="curve" smooth="yes"/>
+ <point x="340" y="603"/>
+ <point x="340" y="1020"/>
+ <point x="340" y="1020" type="curve"/>
+ <point x="135" y="1020" type="line"/>
+ <point x="153" y="900"/>
+ <point x="155" y="827"/>
+ <point x="155" y="700" type="curve" smooth="yes"/>
+ <point x="155" y="681"/>
+ <point x="155" y="424"/>
+ <point x="155" y="405" type="curve" smooth="yes"/>
+ <point x="155" y="120"/>
+ <point x="262" y="-25"/>
+ <point x="475" y="-25" type="curve" smooth="yes"/>
+ <point x="615" y="-25"/>
+ <point x="744" y="53"/>
+ <point x="865" y="200" type="curve"/>
+ <point x="875" y="125"/>
+ <point x="901" y="46"/>
+ <point x="920" y="0" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfglyphs2ufo/PsfTest-Regular.ufo/glyphs/L_tnS_mV_.glif b/tests/reference/ufo/psfglyphs2ufo/PsfTest-Regular.ufo/glyphs/L_tnS_mV_.glif
new file mode 100644
index 0000000..3097f4b
--- /dev/null
+++ b/tests/reference/ufo/psfglyphs2ufo/PsfTest-Regular.ufo/glyphs/L_tnS_mV_.glif
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmV" format="2">
+ <advance width="1070"/>
+ <unicode hex="0076"/>
+ <anchor x="549" y="0" name="H"/>
+ <anchor x="535" y="-100" name="L"/>
+ <anchor x="725" y="0" name="O"/>
+ <anchor x="535" y="1100" name="U"/>
+ <outline>
+ <contour>
+ <point x="840" y="1020" type="line"/>
+ <point x="535" y="200" type="line"/>
+ <point x="230" y="1020" type="line"/>
+ <point x="20" y="1020" type="line"/>
+ <point x="75" y="905"/>
+ <point x="143" y="746"/>
+ <point x="175" y="665" type="curve" smooth="yes"/>
+ <point x="237" y="510"/>
+ <point x="440" y="0"/>
+ <point x="440" y="0" type="curve"/>
+ <point x="630" y="0" type="line"/>
+ <point x="630" y="0"/>
+ <point x="842" y="536"/>
+ <point x="895" y="665" type="curve" smooth="yes"/>
+ <point x="928" y="744"/>
+ <point x="993" y="905"/>
+ <point x="1050" y="1020" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfglyphs2ufo/PsfTest-Regular.ufo/glyphs/L_tnS_mW_.glif b/tests/reference/ufo/psfglyphs2ufo/PsfTest-Regular.ufo/glyphs/L_tnS_mW_.glif
new file mode 100644
index 0000000..3557415
--- /dev/null
+++ b/tests/reference/ufo/psfglyphs2ufo/PsfTest-Regular.ufo/glyphs/L_tnS_mW_.glif
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmW" format="2">
+ <advance width="1550"/>
+ <unicode hex="0077"/>
+ <anchor x="775" y="-100" name="L"/>
+ <anchor x="775" y="1100" name="U"/>
+ <outline>
+ <contour>
+ <point x="700" y="1020" type="line"/>
+ <point x="440" y="215" type="line"/>
+ <point x="230" y="1020" type="line"/>
+ <point x="45" y="1020" type="line"/>
+ <point x="92" y="867"/>
+ <point x="120" y="771"/>
+ <point x="150" y="665" type="curve" smooth="yes"/>
+ <point x="335" y="0" type="line"/>
+ <point x="525" y="0" type="line"/>
+ <point x="775" y="785" type="line"/>
+ <point x="1025" y="0" type="line"/>
+ <point x="1215" y="0" type="line"/>
+ <point x="1400" y="665" type="line" smooth="yes"/>
+ <point x="1434" y="785"/>
+ <point x="1458" y="868"/>
+ <point x="1505" y="1020" type="curve"/>
+ <point x="1320" y="1020" type="line"/>
+ <point x="1110" y="215" type="line"/>
+ <point x="850" y="1020" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfglyphs2ufo/PsfTest-Regular.ufo/glyphs/L_tnS_mX_.glif b/tests/reference/ufo/psfglyphs2ufo/PsfTest-Regular.ufo/glyphs/L_tnS_mX_.glif
new file mode 100644
index 0000000..883cba4
--- /dev/null
+++ b/tests/reference/ufo/psfglyphs2ufo/PsfTest-Regular.ufo/glyphs/L_tnS_mX_.glif
@@ -0,0 +1,40 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmX" format="2">
+ <advance width="1085"/>
+ <unicode hex="0078"/>
+ <anchor x="900" y="0" name="H"/>
+ <anchor x="542" y="-100" name="L"/>
+ <anchor x="542" y="1100" name="U"/>
+ <outline>
+ <contour>
+ <point x="805" y="0" type="line"/>
+ <point x="1035" y="0" type="line"/>
+ <point x="927" y="142"/>
+ <point x="902" y="170"/>
+ <point x="830" y="270" type="curve" smooth="yes"/>
+ <point x="290" y="1020" type="line"/>
+ <point x="60" y="1020" type="line"/>
+ <point x="168" y="887"/>
+ <point x="203" y="843"/>
+ <point x="270" y="750" type="curve"/>
+ </contour>
+ <contour>
+ <point x="489" y="616" type="line"/>
+ <point x="250" y="270" type="line" smooth="yes"/>
+ <point x="189" y="182"/>
+ <point x="160" y="143"/>
+ <point x="50" y="0" type="curve"/>
+ <point x="275" y="0" type="line"/>
+ <point x="556" y="404" type="line"/>
+ </contour>
+ <contour>
+ <point x="585" y="405" type="line"/>
+ <point x="820" y="750" type="line" smooth="yes"/>
+ <point x="883" y="842"/>
+ <point x="917" y="886"/>
+ <point x="1020" y="1020" type="curve"/>
+ <point x="795" y="1020" type="line"/>
+ <point x="520" y="615" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfglyphs2ufo/PsfTest-Regular.ufo/glyphs/L_tnS_mY_.glif b/tests/reference/ufo/psfglyphs2ufo/PsfTest-Regular.ufo/glyphs/L_tnS_mY_.glif
new file mode 100644
index 0000000..cbe0f68
--- /dev/null
+++ b/tests/reference/ufo/psfglyphs2ufo/PsfTest-Regular.ufo/glyphs/L_tnS_mY_.glif
@@ -0,0 +1,42 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmY" format="2">
+ <advance width="1060"/>
+ <unicode hex="0079"/>
+ <anchor x="795" y="-100" name="L"/>
+ <anchor x="1120" y="1000" name="R"/>
+ <anchor x="535" y="1100" name="U"/>
+ <outline>
+ <contour>
+ <point x="610" y="60" type="line"/>
+ <point x="230" y="1020" type="line"/>
+ <point x="30" y="1020" type="line"/>
+ <point x="107" y="864"/>
+ <point x="153" y="756"/>
+ <point x="190" y="665" type="curve" smooth="yes"/>
+ <point x="525" y="-165" type="line"/>
+ </contour>
+ <contour>
+ <point x="895" y="665" type="line"/>
+ <point x="928" y="758"/>
+ <point x="971" y="865"/>
+ <point x="1040" y="1020" type="curve"/>
+ <point x="840" y="1020" type="line"/>
+ <point x="840" y="1020"/>
+ <point x="564" y="230"/>
+ <point x="500" y="55" type="curve" smooth="yes"/>
+ <point x="391" y="-248"/>
+ <point x="315" y="-300"/>
+ <point x="225" y="-300" type="curve" smooth="yes"/>
+ <point x="159" y="-300"/>
+ <point x="82" y="-260"/>
+ <point x="40" y="-225" type="curve"/>
+ <point x="-20" y="-385" type="line"/>
+ <point x="53" y="-439"/>
+ <point x="134" y="-470"/>
+ <point x="225" y="-470" type="curve" smooth="yes"/>
+ <point x="395" y="-470"/>
+ <point x="516" y="-383"/>
+ <point x="655" y="0" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfglyphs2ufo/PsfTest-Regular.ufo/glyphs/N_onB_reakingH_yphen.glif b/tests/reference/ufo/psfglyphs2ufo/PsfTest-Regular.ufo/glyphs/N_onB_reakingH_yphen.glif
new file mode 100644
index 0000000..14aff81
--- /dev/null
+++ b/tests/reference/ufo/psfglyphs2ufo/PsfTest-Regular.ufo/glyphs/N_onB_reakingH_yphen.glif
@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="NonBreakingHyphen" format="2">
+ <advance width="860"/>
+ <unicode hex="2011"/>
+ <anchor x="430" y="1100" name="U"/>
+ <outline>
+ <component base="HyphenMinus"/>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfglyphs2ufo/PsfTest-Regular.ufo/glyphs/N_umS_gn.glif b/tests/reference/ufo/psfglyphs2ufo/PsfTest-Regular.ufo/glyphs/N_umS_gn.glif
new file mode 100644
index 0000000..f4625db
--- /dev/null
+++ b/tests/reference/ufo/psfglyphs2ufo/PsfTest-Regular.ufo/glyphs/N_umS_gn.glif
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="NumSgn" format="2">
+ <advance width="1200"/>
+ <unicode hex="0023"/>
+ <outline>
+ <contour>
+ <point x="487" y="1460" type="line"/>
+ <point x="127" y="200" type="line"/>
+ <point x="277" y="200" type="line"/>
+ <point x="637" y="1460" type="line"/>
+ </contour>
+ <contour>
+ <point x="25" y="575" type="line"/>
+ <point x="1116" y="575" type="line"/>
+ <point x="1116" y="725" type="line"/>
+ <point x="25" y="725" type="line"/>
+ </contour>
+ <contour>
+ <point x="84" y="960" type="line"/>
+ <point x="1175" y="960" type="line"/>
+ <point x="1175" y="1110" type="line"/>
+ <point x="84" y="1110" type="line"/>
+ </contour>
+ <contour>
+ <point x="912" y="1460" type="line"/>
+ <point x="552" y="200" type="line"/>
+ <point x="702" y="200" type="line"/>
+ <point x="1062" y="1460" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfglyphs2ufo/PsfTest-Regular.ufo/glyphs/P_ercentS_gn.glif b/tests/reference/ufo/psfglyphs2ufo/PsfTest-Regular.ufo/glyphs/P_ercentS_gn.glif
new file mode 100644
index 0000000..e81f237
--- /dev/null
+++ b/tests/reference/ufo/psfglyphs2ufo/PsfTest-Regular.ufo/glyphs/P_ercentS_gn.glif
@@ -0,0 +1,69 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="PercentSgn" format="2">
+ <advance width="1526"/>
+ <unicode hex="0025"/>
+ <outline>
+ <contour>
+ <point x="1261" y="366" type="curve" smooth="yes"/>
+ <point x="1261" y="182"/>
+ <point x="1216" y="115"/>
+ <point x="1130" y="115" type="curve" smooth="yes"/>
+ <point x="1041" y="115"/>
+ <point x="1001" y="181"/>
+ <point x="1001" y="381" type="curve" smooth="yes"/>
+ <point x="1001" y="565"/>
+ <point x="1043" y="630"/>
+ <point x="1130" y="630" type="curve" smooth="yes"/>
+ <point x="1221" y="630"/>
+ <point x="1261" y="566"/>
+ </contour>
+ <contour>
+ <point x="1426" y="379" type="curve" smooth="yes"/>
+ <point x="1426" y="652"/>
+ <point x="1310" y="770"/>
+ <point x="1135" y="770" type="curve" smooth="yes"/>
+ <point x="961" y="770"/>
+ <point x="836" y="650"/>
+ <point x="836" y="368" type="curve" smooth="yes"/>
+ <point x="836" y="86"/>
+ <point x="951" y="-25"/>
+ <point x="1126" y="-25" type="curve" smooth="yes"/>
+ <point x="1301" y="-25"/>
+ <point x="1426" y="84"/>
+ </contour>
+ <contour>
+ <point x="1073" y="1480" type="line"/>
+ <point x="291" y="-25" type="line"/>
+ <point x="459" y="-25" type="line"/>
+ <point x="1239" y="1480" type="line"/>
+ </contour>
+ <contour>
+ <point x="525" y="1076" type="curve" smooth="yes"/>
+ <point x="525" y="892"/>
+ <point x="480" y="825"/>
+ <point x="394" y="825" type="curve" smooth="yes"/>
+ <point x="305" y="825"/>
+ <point x="265" y="891"/>
+ <point x="265" y="1091" type="curve" smooth="yes"/>
+ <point x="265" y="1275"/>
+ <point x="307" y="1340"/>
+ <point x="394" y="1340" type="curve" smooth="yes"/>
+ <point x="485" y="1340"/>
+ <point x="525" y="1276"/>
+ </contour>
+ <contour>
+ <point x="690" y="1089" type="curve" smooth="yes"/>
+ <point x="690" y="1362"/>
+ <point x="574" y="1480"/>
+ <point x="399" y="1480" type="curve" smooth="yes"/>
+ <point x="225" y="1480"/>
+ <point x="100" y="1360"/>
+ <point x="100" y="1078" type="curve" smooth="yes"/>
+ <point x="100" y="796"/>
+ <point x="215" y="685"/>
+ <point x="390" y="685" type="curve" smooth="yes"/>
+ <point x="565" y="685"/>
+ <point x="690" y="794"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfglyphs2ufo/PsfTest-Regular.ufo/glyphs/P_lusS_gn.glif b/tests/reference/ufo/psfglyphs2ufo/PsfTest-Regular.ufo/glyphs/P_lusS_gn.glif
new file mode 100644
index 0000000..de1f259
--- /dev/null
+++ b/tests/reference/ufo/psfglyphs2ufo/PsfTest-Regular.ufo/glyphs/P_lusS_gn.glif
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="PlusSgn" format="2">
+ <advance width="1200"/>
+ <unicode hex="002B"/>
+ <outline>
+ <contour>
+ <point x="525" y="1180" type="line"/>
+ <point x="525" y="285" type="line"/>
+ <point x="675" y="285" type="line"/>
+ <point x="675" y="1180" type="line"/>
+ </contour>
+ <contour>
+ <point x="155" y="660" type="line"/>
+ <point x="1045" y="660" type="line"/>
+ <point x="1045" y="810" type="line"/>
+ <point x="155" y="810" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfglyphs2ufo/PsfTest-Regular.ufo/glyphs/Q_stnM_rk.glif b/tests/reference/ufo/psfglyphs2ufo/PsfTest-Regular.ufo/glyphs/Q_stnM_rk.glif
new file mode 100644
index 0000000..5526aec
--- /dev/null
+++ b/tests/reference/ufo/psfglyphs2ufo/PsfTest-Regular.ufo/glyphs/Q_stnM_rk.glif
@@ -0,0 +1,49 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="QstnMrk" format="2">
+ <advance width="1050"/>
+ <unicode hex="003F"/>
+ <outline>
+ <contour>
+ <point x="460" y="1540" type="curve" smooth="yes"/>
+ <point x="335" y="1540"/>
+ <point x="206" y="1493"/>
+ <point x="140" y="1430" type="curve"/>
+ <point x="185" y="1251" type="line"/>
+ <point x="261" y="1330"/>
+ <point x="352" y="1365"/>
+ <point x="432" y="1365" type="curve" smooth="yes"/>
+ <point x="579" y="1365"/>
+ <point x="625" y="1289"/>
+ <point x="625" y="1230" type="curve" smooth="yes"/>
+ <point x="625" y="1159"/>
+ <point x="572" y="1092"/>
+ <point x="485" y="980" type="curve" smooth="yes"/>
+ <point x="397" y="867"/>
+ <point x="355" y="730"/>
+ <point x="355" y="440" type="curve"/>
+ <point x="540" y="440" type="line"/>
+ <point x="540" y="721"/>
+ <point x="561" y="806"/>
+ <point x="665" y="927" type="curve" smooth="yes"/>
+ <point x="753" y="1028"/>
+ <point x="830" y="1117"/>
+ <point x="830" y="1240" type="curve" smooth="yes"/>
+ <point x="830" y="1422"/>
+ <point x="697" y="1540"/>
+ </contour>
+ <contour>
+ <point x="315" y="110" type="curve" smooth="yes"/>
+ <point x="315" y="36"/>
+ <point x="376" y="-25"/>
+ <point x="450" y="-25" type="curve" smooth="yes"/>
+ <point x="524" y="-25"/>
+ <point x="585" y="36"/>
+ <point x="585" y="110" type="curve" smooth="yes"/>
+ <point x="585" y="184"/>
+ <point x="524" y="245"/>
+ <point x="450" y="245" type="curve" smooth="yes"/>
+ <point x="376" y="245"/>
+ <point x="315" y="184"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfglyphs2ufo/PsfTest-Regular.ufo/glyphs/Q_uotM_rk.glif b/tests/reference/ufo/psfglyphs2ufo/PsfTest-Regular.ufo/glyphs/Q_uotM_rk.glif
new file mode 100644
index 0000000..c9f06c6
--- /dev/null
+++ b/tests/reference/ufo/psfglyphs2ufo/PsfTest-Regular.ufo/glyphs/Q_uotM_rk.glif
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="QuotMrk" format="2">
+ <advance width="1025"/>
+ <unicode hex="0022"/>
+ <outline>
+ <contour>
+ <point x="405" y="1045" type="line"/>
+ <point x="410" y="1186"/>
+ <point x="416" y="1339"/>
+ <point x="445" y="1585" type="curve"/>
+ <point x="240" y="1585" type="line"/>
+ <point x="271" y="1339"/>
+ <point x="276" y="1186"/>
+ <point x="280" y="1045" type="curve"/>
+ </contour>
+ <contour>
+ <point x="745" y="1045" type="line"/>
+ <point x="750" y="1186"/>
+ <point x="756" y="1339"/>
+ <point x="785" y="1585" type="curve"/>
+ <point x="580" y="1585" type="line"/>
+ <point x="611" y="1339"/>
+ <point x="616" y="1186"/>
+ <point x="620" y="1045" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfglyphs2ufo/PsfTest-Regular.ufo/glyphs/R_everseS_olidus.glif b/tests/reference/ufo/psfglyphs2ufo/PsfTest-Regular.ufo/glyphs/R_everseS_olidus.glif
new file mode 100644
index 0000000..d145f26
--- /dev/null
+++ b/tests/reference/ufo/psfglyphs2ufo/PsfTest-Regular.ufo/glyphs/R_everseS_olidus.glif
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="ReverseSolidus" format="2">
+ <advance width="1000"/>
+ <unicode hex="005C"/>
+ <outline>
+ <contour>
+ <point x="990" y="-245" type="line"/>
+ <point x="160" y="1600" type="line"/>
+ <point x="10" y="1600" type="line"/>
+ <point x="840" y="-245" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfglyphs2ufo/PsfTest-Regular.ufo/glyphs/R_tC_urlyB_rac.glif b/tests/reference/ufo/psfglyphs2ufo/PsfTest-Regular.ufo/glyphs/R_tC_urlyB_rac.glif
new file mode 100644
index 0000000..288a75a
--- /dev/null
+++ b/tests/reference/ufo/psfglyphs2ufo/PsfTest-Regular.ufo/glyphs/R_tC_urlyB_rac.glif
@@ -0,0 +1,47 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="RtCurlyBrac" format="2">
+ <advance width="1000"/>
+ <unicode hex="007D"/>
+ <outline>
+ <contour>
+ <point x="790" y="615" type="curve" smooth="yes"/>
+ <point x="790" y="647"/>
+ <point x="617" y="744"/>
+ <point x="590" y="780" type="curve" smooth="yes"/>
+ <point x="566" y="812"/>
+ <point x="576" y="1435"/>
+ <point x="505" y="1515" type="curve" smooth="yes"/>
+ <point x="465" y="1560"/>
+ <point x="304" y="1613"/>
+ <point x="200" y="1640" type="curve"/>
+ <point x="160" y="1500" type="line"/>
+ <point x="227" y="1477"/>
+ <point x="350" y="1428"/>
+ <point x="370" y="1400" type="curve" smooth="yes"/>
+ <point x="403" y="1353"/>
+ <point x="390" y="783"/>
+ <point x="410" y="745" type="curve" smooth="yes"/>
+ <point x="429" y="709"/>
+ <point x="566" y="637"/>
+ <point x="570" y="615" type="curve"/>
+ <point x="566" y="593"/>
+ <point x="429" y="521"/>
+ <point x="410" y="485" type="curve" smooth="yes"/>
+ <point x="390" y="447"/>
+ <point x="403" y="-123"/>
+ <point x="370" y="-170" type="curve" smooth="yes"/>
+ <point x="350" y="-198"/>
+ <point x="227" y="-247"/>
+ <point x="160" y="-270" type="curve"/>
+ <point x="200" y="-410" type="line"/>
+ <point x="304" y="-383"/>
+ <point x="465" y="-330"/>
+ <point x="505" y="-285" type="curve" smooth="yes"/>
+ <point x="576" y="-205"/>
+ <point x="566" y="418"/>
+ <point x="590" y="450" type="curve" smooth="yes"/>
+ <point x="617" y="486"/>
+ <point x="790" y="583"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfglyphs2ufo/PsfTest-Regular.ufo/glyphs/R_tP_aren.glif b/tests/reference/ufo/psfglyphs2ufo/PsfTest-Regular.ufo/glyphs/R_tP_aren.glif
new file mode 100644
index 0000000..3983f6b
--- /dev/null
+++ b/tests/reference/ufo/psfglyphs2ufo/PsfTest-Regular.ufo/glyphs/R_tP_aren.glif
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="RtParen" format="2">
+ <advance width="795"/>
+ <unicode hex="0029"/>
+ <outline>
+ <contour>
+ <point x="680" y="625" type="curve" smooth="yes"/>
+ <point x="680" y="1062"/>
+ <point x="505" y="1444"/>
+ <point x="240" y="1640" type="curve"/>
+ <point x="165" y="1485" type="line"/>
+ <point x="390" y="1280"/>
+ <point x="490" y="962"/>
+ <point x="490" y="625" type="curve" smooth="yes"/>
+ <point x="490" y="278"/>
+ <point x="390" y="-8"/>
+ <point x="165" y="-265" type="curve"/>
+ <point x="260" y="-410" type="line"/>
+ <point x="535" y="-125"/>
+ <point x="680" y="218"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfglyphs2ufo/PsfTest-Regular.ufo/glyphs/R_tS_qrB_rac.glif b/tests/reference/ufo/psfglyphs2ufo/PsfTest-Regular.ufo/glyphs/R_tS_qrB_rac.glif
new file mode 100644
index 0000000..702689b
--- /dev/null
+++ b/tests/reference/ufo/psfglyphs2ufo/PsfTest-Regular.ufo/glyphs/R_tS_qrB_rac.glif
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="RtSqrBrac" format="2">
+ <advance width="790"/>
+ <unicode hex="005D"/>
+ <outline>
+ <contour>
+ <point x="590" y="-410" type="line"/>
+ <point x="590" y="1600" type="line"/>
+ <point x="150" y="1600" type="line"/>
+ <point x="150" y="1450" type="line"/>
+ <point x="405" y="1450" type="line"/>
+ <point x="405" y="-260" type="line"/>
+ <point x="150" y="-260" type="line"/>
+ <point x="150" y="-410" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfglyphs2ufo/PsfTest-Regular.ufo/glyphs/S_emicolon.glif b/tests/reference/ufo/psfglyphs2ufo/PsfTest-Regular.ufo/glyphs/S_emicolon.glif
new file mode 100644
index 0000000..247bed0
--- /dev/null
+++ b/tests/reference/ufo/psfglyphs2ufo/PsfTest-Regular.ufo/glyphs/S_emicolon.glif
@@ -0,0 +1,38 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="Semicolon" format="2">
+ <advance width="650"/>
+ <unicode hex="003B"/>
+ <outline>
+ <contour>
+ <point x="185" y="790" type="curve" smooth="yes"/>
+ <point x="185" y="716"/>
+ <point x="246" y="655"/>
+ <point x="320" y="655" type="curve" smooth="yes"/>
+ <point x="394" y="655"/>
+ <point x="455" y="716"/>
+ <point x="455" y="790" type="curve" smooth="yes"/>
+ <point x="455" y="864"/>
+ <point x="394" y="925"/>
+ <point x="320" y="925" type="curve" smooth="yes"/>
+ <point x="246" y="925"/>
+ <point x="185" y="864"/>
+ </contour>
+ <contour>
+ <point x="185" y="50" type="line"/>
+ <point x="325" y="50" type="line"/>
+ <point x="325" y="-51"/>
+ <point x="248" y="-172"/>
+ <point x="190" y="-230" type="curve"/>
+ <point x="290" y="-270" type="line"/>
+ <point x="407" y="-160"/>
+ <point x="465" y="-37"/>
+ <point x="465" y="85" type="curve" smooth="yes"/>
+ <point x="465" y="186"/>
+ <point x="400" y="250"/>
+ <point x="320" y="250" type="curve" smooth="yes"/>
+ <point x="263" y="250"/>
+ <point x="198" y="213"/>
+ <point x="185" y="150" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfglyphs2ufo/PsfTest-Regular.ufo/glyphs/S_olidus.glif b/tests/reference/ufo/psfglyphs2ufo/PsfTest-Regular.ufo/glyphs/S_olidus.glif
new file mode 100644
index 0000000..3edff5d
--- /dev/null
+++ b/tests/reference/ufo/psfglyphs2ufo/PsfTest-Regular.ufo/glyphs/S_olidus.glif
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="Solidus" format="2">
+ <advance width="1000"/>
+ <unicode hex="002F"/>
+ <outline>
+ <contour>
+ <point x="840" y="1600" type="line"/>
+ <point x="10" y="-245" type="line"/>
+ <point x="160" y="-245" type="line"/>
+ <point x="990" y="1600" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfglyphs2ufo/PsfTest-Regular.ufo/glyphs/S_pace.glif b/tests/reference/ufo/psfglyphs2ufo/PsfTest-Regular.ufo/glyphs/S_pace.glif
new file mode 100644
index 0000000..ef0bed7
--- /dev/null
+++ b/tests/reference/ufo/psfglyphs2ufo/PsfTest-Regular.ufo/glyphs/S_pace.glif
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="Space" format="2">
+ <advance width="550"/>
+ <unicode hex="0020"/>
+ <outline/>
+</glyph>
diff --git a/tests/reference/ufo/psfglyphs2ufo/PsfTest-Regular.ufo/glyphs/T_ilde.glif b/tests/reference/ufo/psfglyphs2ufo/PsfTest-Regular.ufo/glyphs/T_ilde.glif
new file mode 100644
index 0000000..60ddaa7
--- /dev/null
+++ b/tests/reference/ufo/psfglyphs2ufo/PsfTest-Regular.ufo/glyphs/T_ilde.glif
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="Tilde" format="2">
+ <advance width="1115"/>
+ <unicode hex="007E"/>
+ <outline>
+ <contour>
+ <point x="125" y="375" type="line"/>
+ <point x="130" y="424"/>
+ <point x="162" y="465"/>
+ <point x="240" y="465" type="curve" smooth="yes"/>
+ <point x="415" y="465"/>
+ <point x="615" y="360"/>
+ <point x="845" y="360" type="curve" smooth="yes"/>
+ <point x="1004" y="360"/>
+ <point x="1080" y="482"/>
+ <point x="1080" y="610" type="curve"/>
+ <point x="975" y="610" type="line"/>
+ <point x="968" y="564"/>
+ <point x="938" y="510"/>
+ <point x="855" y="510" type="curve" smooth="yes"/>
+ <point x="619" y="510"/>
+ <point x="461" y="615"/>
+ <point x="240" y="615" type="curve" smooth="yes"/>
+ <point x="94" y="615"/>
+ <point x="20" y="497"/>
+ <point x="20" y="375" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfglyphs2ufo/PsfTest-Regular.ufo/glyphs/V_ertL_ine.glif b/tests/reference/ufo/psfglyphs2ufo/PsfTest-Regular.ufo/glyphs/V_ertL_ine.glif
new file mode 100644
index 0000000..c73e040
--- /dev/null
+++ b/tests/reference/ufo/psfglyphs2ufo/PsfTest-Regular.ufo/glyphs/V_ertL_ine.glif
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="VertLine" format="2">
+ <advance width="690"/>
+ <unicode hex="007C"/>
+ <outline>
+ <contour>
+ <point x="270" y="1600" type="line"/>
+ <point x="270" y="-390" type="line"/>
+ <point x="420" y="-390" type="line"/>
+ <point x="420" y="1600" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfglyphs2ufo/PsfTest-Regular.ufo/glyphs/_notdef.glif b/tests/reference/ufo/psfglyphs2ufo/PsfTest-Regular.ufo/glyphs/_notdef.glif
new file mode 100644
index 0000000..a3e9354
--- /dev/null
+++ b/tests/reference/ufo/psfglyphs2ufo/PsfTest-Regular.ufo/glyphs/_notdef.glif
@@ -0,0 +1,18 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name=".notdef" format="2">
+ <advance width="1400"/>
+ <outline>
+ <contour>
+ <point x="100" y="0" type="line"/>
+ <point x="1300" y="0" type="line"/>
+ <point x="1300" y="1800" type="line"/>
+ <point x="100" y="1800" type="line"/>
+ </contour>
+ <contour>
+ <point x="150" y="1750" type="line"/>
+ <point x="1250" y="1750" type="line"/>
+ <point x="1250" y="50" type="line"/>
+ <point x="150" y="50" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfglyphs2ufo/PsfTest-Regular.ufo/glyphs/_null.glif b/tests/reference/ufo/psfglyphs2ufo/PsfTest-Regular.ufo/glyphs/_null.glif
new file mode 100644
index 0000000..0b9caa6
--- /dev/null
+++ b/tests/reference/ufo/psfglyphs2ufo/PsfTest-Regular.ufo/glyphs/_null.glif
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name=".null" format="2">
+ <outline/>
+</glyph>
diff --git a/tests/reference/ufo/psfglyphs2ufo/PsfTest-Regular.ufo/glyphs/contents.plist b/tests/reference/ufo/psfglyphs2ufo/PsfTest-Regular.ufo/glyphs/contents.plist
new file mode 100644
index 0000000..de3c0b3
--- /dev/null
+++ b/tests/reference/ufo/psfglyphs2ufo/PsfTest-Regular.ufo/glyphs/contents.plist
@@ -0,0 +1,234 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+ <key>.notdef</key>
+ <string>_notdef.glif</string>
+ <key>.null</key>
+ <string>_null.glif</string>
+ <key>Ampersand</key>
+ <string>A_mpersand.glif</string>
+ <key>Apos</key>
+ <string>A_pos.glif</string>
+ <key>Asterisk</key>
+ <string>A_sterisk.glif</string>
+ <key>AtSgn</key>
+ <string>A_tS_gn.glif</string>
+ <key>CircumAccent</key>
+ <string>C_ircumA_ccent.glif</string>
+ <key>Colon</key>
+ <string>C_olon.glif</string>
+ <key>CombAcute</key>
+ <string>C_ombA_cute.glif</string>
+ <key>CombCircum</key>
+ <string>C_ombC_ircum.glif</string>
+ <key>CombDiaer</key>
+ <string>C_ombD_iaer.glif</string>
+ <key>CombGrave</key>
+ <string>C_ombG_rave.glif</string>
+ <key>CombRingAbv</key>
+ <string>C_ombR_ingA_bv.glif</string>
+ <key>CombTilde</key>
+ <string>C_ombT_ilde.glif</string>
+ <key>Comma</key>
+ <string>C_omma.glif</string>
+ <key>DigitEight</key>
+ <string>D_igitE_ight.glif</string>
+ <key>DigitFive</key>
+ <string>D_igitF_ive.glif</string>
+ <key>DigitFour</key>
+ <string>D_igitF_our.glif</string>
+ <key>DigitNine</key>
+ <string>D_igitN_ine.glif</string>
+ <key>DigitOne</key>
+ <string>D_igitO_ne.glif</string>
+ <key>DigitSeven</key>
+ <string>D_igitS_even.glif</string>
+ <key>DigitSix</key>
+ <string>D_igitS_ix.glif</string>
+ <key>DigitThree</key>
+ <string>D_igitT_hree.glif</string>
+ <key>DigitTwo</key>
+ <string>D_igitT_wo.glif</string>
+ <key>DigitZero</key>
+ <string>D_igitZ_ero.glif</string>
+ <key>DollarSgn</key>
+ <string>D_ollarS_gn.glif</string>
+ <key>DottedCirc</key>
+ <string>D_ottedC_irc.glif</string>
+ <key>EqSgn</key>
+ <string>E_qS_gn.glif</string>
+ <key>ExclamationMrk</key>
+ <string>E_xclamationM_rk.glif</string>
+ <key>FullStop</key>
+ <string>F_ullS_top.glif</string>
+ <key>GTSgn</key>
+ <string>G_T_S_gn.glif</string>
+ <key>GraveAccent</key>
+ <string>G_raveA_ccent.glif</string>
+ <key>Hyphen</key>
+ <string>H_yphen.glif</string>
+ <key>HyphenMinus</key>
+ <string>H_yphenM_inus.glif</string>
+ <key>Hyphen_Soft</key>
+ <string>H_yphen_S_oft.glif</string>
+ <key>LTSgn</key>
+ <string>L_T_S_gn.glif</string>
+ <key>LftCurlyBrac</key>
+ <string>L_ftC_urlyB_rac.glif</string>
+ <key>LftParen</key>
+ <string>L_ftP_aren.glif</string>
+ <key>LftSqrBrac</key>
+ <string>L_ftS_qrB_rac.glif</string>
+ <key>LowLine</key>
+ <string>L_owL_ine.glif</string>
+ <key>LtnCapA</key>
+ <string>L_tnC_apA_.glif</string>
+ <key>LtnCapA.alt</key>
+ <string>L_tnC_apA_.alt.glif</string>
+ <key>LtnCapADiaer</key>
+ <string>L_tnC_apA_D_iaer.glif</string>
+ <key>LtnCapB</key>
+ <string>L_tnC_apB_.glif</string>
+ <key>LtnCapC</key>
+ <string>L_tnC_apC_.glif</string>
+ <key>LtnCapD</key>
+ <string>L_tnC_apD_.glif</string>
+ <key>LtnCapE</key>
+ <string>L_tnC_apE_.glif</string>
+ <key>LtnCapF</key>
+ <string>L_tnC_apF_.glif</string>
+ <key>LtnCapG</key>
+ <string>L_tnC_apG_.glif</string>
+ <key>LtnCapH</key>
+ <string>L_tnC_apH_.glif</string>
+ <key>LtnCapI</key>
+ <string>L_tnC_apI_.glif</string>
+ <key>LtnCapJ</key>
+ <string>L_tnC_apJ_.glif</string>
+ <key>LtnCapK</key>
+ <string>L_tnC_apK_.glif</string>
+ <key>LtnCapL</key>
+ <string>L_tnC_apL_.glif</string>
+ <key>LtnCapM</key>
+ <string>L_tnC_apM_.glif</string>
+ <key>LtnCapN</key>
+ <string>L_tnC_apN_.glif</string>
+ <key>LtnCapO</key>
+ <string>L_tnC_apO_.glif</string>
+ <key>LtnCapP</key>
+ <string>L_tnC_apP_.glif</string>
+ <key>LtnCapQ</key>
+ <string>L_tnC_apQ_.glif</string>
+ <key>LtnCapR</key>
+ <string>L_tnC_apR_.glif</string>
+ <key>LtnCapS</key>
+ <string>L_tnC_apS_.glif</string>
+ <key>LtnCapT</key>
+ <string>L_tnC_apT_.glif</string>
+ <key>LtnCapU</key>
+ <string>L_tnC_apU_.glif</string>
+ <key>LtnCapV</key>
+ <string>L_tnC_apV_.glif</string>
+ <key>LtnCapW</key>
+ <string>L_tnC_apW_.glif</string>
+ <key>LtnCapX</key>
+ <string>L_tnC_apX_.glif</string>
+ <key>LtnCapY</key>
+ <string>L_tnC_apY_.glif</string>
+ <key>LtnSmA</key>
+ <string>L_tnS_mA_.glif</string>
+ <key>LtnSmAAcute</key>
+ <string>L_tnS_mA_A_cute.glif</string>
+ <key>LtnSmACircum</key>
+ <string>L_tnS_mA_C_ircum.glif</string>
+ <key>LtnSmADiaer</key>
+ <string>L_tnS_mA_D_iaer.glif</string>
+ <key>LtnSmAGrave</key>
+ <string>L_tnS_mA_G_rave.glif</string>
+ <key>LtnSmARingAbv</key>
+ <string>L_tnS_mA_R_ingA_bv.glif</string>
+ <key>LtnSmATilde</key>
+ <string>L_tnS_mA_T_ilde.glif</string>
+ <key>LtnSmB</key>
+ <string>L_tnS_mB_.glif</string>
+ <key>LtnSmC</key>
+ <string>L_tnS_mC_.glif</string>
+ <key>LtnSmD</key>
+ <string>L_tnS_mD_.glif</string>
+ <key>LtnSmE</key>
+ <string>L_tnS_mE_.glif</string>
+ <key>LtnSmF</key>
+ <string>L_tnS_mF_.glif</string>
+ <key>LtnSmG</key>
+ <string>L_tnS_mG_.glif</string>
+ <key>LtnSmH</key>
+ <string>L_tnS_mH_.glif</string>
+ <key>LtnSmI</key>
+ <string>L_tnS_mI_.glif</string>
+ <key>LtnSmJ</key>
+ <string>L_tnS_mJ_.glif</string>
+ <key>LtnSmK</key>
+ <string>L_tnS_mK_.glif</string>
+ <key>LtnSmL</key>
+ <string>L_tnS_mL_.glif</string>
+ <key>LtnSmM</key>
+ <string>L_tnS_mM_.glif</string>
+ <key>LtnSmN</key>
+ <string>L_tnS_mN_.glif</string>
+ <key>LtnSmO</key>
+ <string>L_tnS_mO_.glif</string>
+ <key>LtnSmP</key>
+ <string>L_tnS_mP_.glif</string>
+ <key>LtnSmQ</key>
+ <string>L_tnS_mQ_.glif</string>
+ <key>LtnSmR</key>
+ <string>L_tnS_mR_.glif</string>
+ <key>LtnSmS</key>
+ <string>L_tnS_mS_.glif</string>
+ <key>LtnSmT</key>
+ <string>L_tnS_mT_.glif</string>
+ <key>LtnSmU</key>
+ <string>L_tnS_mU_.glif</string>
+ <key>LtnSmV</key>
+ <string>L_tnS_mV_.glif</string>
+ <key>LtnSmW</key>
+ <string>L_tnS_mW_.glif</string>
+ <key>LtnSmX</key>
+ <string>L_tnS_mX_.glif</string>
+ <key>LtnSmY</key>
+ <string>L_tnS_mY_.glif</string>
+ <key>NonBreakingHyphen</key>
+ <string>N_onB_reakingH_yphen.glif</string>
+ <key>NumSgn</key>
+ <string>N_umS_gn.glif</string>
+ <key>PercentSgn</key>
+ <string>P_ercentS_gn.glif</string>
+ <key>PlusSgn</key>
+ <string>P_lusS_gn.glif</string>
+ <key>QstnMrk</key>
+ <string>Q_stnM_rk.glif</string>
+ <key>QuotMrk</key>
+ <string>Q_uotM_rk.glif</string>
+ <key>ReverseSolidus</key>
+ <string>R_everseS_olidus.glif</string>
+ <key>RtCurlyBrac</key>
+ <string>R_tC_urlyB_rac.glif</string>
+ <key>RtParen</key>
+ <string>R_tP_aren.glif</string>
+ <key>RtSqrBrac</key>
+ <string>R_tS_qrB_rac.glif</string>
+ <key>Semicolon</key>
+ <string>S_emicolon.glif</string>
+ <key>Solidus</key>
+ <string>S_olidus.glif</string>
+ <key>Space</key>
+ <string>S_pace.glif</string>
+ <key>Tilde</key>
+ <string>T_ilde.glif</string>
+ <key>VertLine</key>
+ <string>V_ertL_ine.glif</string>
+ <key>nonmarkingreturn</key>
+ <string>nonmarkingreturn.glif</string>
+</dict>
+</plist>
diff --git a/tests/reference/ufo/psfglyphs2ufo/PsfTest-Regular.ufo/glyphs/nonmarkingreturn.glif b/tests/reference/ufo/psfglyphs2ufo/PsfTest-Regular.ufo/glyphs/nonmarkingreturn.glif
new file mode 100644
index 0000000..ee41448
--- /dev/null
+++ b/tests/reference/ufo/psfglyphs2ufo/PsfTest-Regular.ufo/glyphs/nonmarkingreturn.glif
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="nonmarkingreturn" format="2">
+ <advance width="1024"/>
+ <outline/>
+</glyph>
diff --git a/tests/reference/ufo/psfglyphs2ufo/PsfTest-Regular.ufo/layercontents.plist b/tests/reference/ufo/psfglyphs2ufo/PsfTest-Regular.ufo/layercontents.plist
new file mode 100644
index 0000000..42b7482
--- /dev/null
+++ b/tests/reference/ufo/psfglyphs2ufo/PsfTest-Regular.ufo/layercontents.plist
@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<array>
+ <array>
+ <string>public.default</string>
+ <string>glyphs</string>
+ </array>
+</array>
+</plist>
diff --git a/tests/reference/ufo/psfglyphs2ufo/PsfTest-Regular.ufo/lib.plist b/tests/reference/ufo/psfglyphs2ufo/PsfTest-Regular.ufo/lib.plist
new file mode 100644
index 0000000..db1ec1b
--- /dev/null
+++ b/tests/reference/ufo/psfglyphs2ufo/PsfTest-Regular.ufo/lib.plist
@@ -0,0 +1,417 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+ <key>com.schriftgestaltung.Glyphs.fontUserData</key>
+ <dict/>
+ <key>com.schriftgestaltung.appVersion</key>
+ <string>1165</string>
+ <key>com.schriftgestaltung.customParameter.GSFont.disablesAutomaticAlignment</key>
+ <true/>
+ <key>com.schriftgestaltung.customParameter.GSFont.disablesLastChange</key>
+ <true/>
+ <key>com.schriftgestaltung.customParameter.GSFont.useNiceNames</key>
+ <integer>0</integer>
+ <key>com.schriftgestaltung.customParameter.GSFontMaster.customValue</key>
+ <integer>0</integer>
+ <key>com.schriftgestaltung.customParameter.GSFontMaster.customValue1</key>
+ <integer>0</integer>
+ <key>com.schriftgestaltung.customParameter.GSFontMaster.customValue2</key>
+ <integer>0</integer>
+ <key>com.schriftgestaltung.customParameter.GSFontMaster.customValue3</key>
+ <integer>0</integer>
+ <key>com.schriftgestaltung.customParameter.GSFontMaster.iconName</key>
+ <string/>
+ <key>com.schriftgestaltung.customParameter.GSFontMaster.weightValue</key>
+ <integer>400</integer>
+ <key>com.schriftgestaltung.customParameter.GSFontMaster.widthValue</key>
+ <integer>100</integer>
+ <key>com.schriftgestaltung.disablesAutomaticAlignment</key>
+ <true/>
+ <key>com.schriftgestaltung.disablesLastChange</key>
+ <true/>
+ <key>com.schriftgestaltung.fontMasterOrder</key>
+ <integer>0</integer>
+ <key>com.schriftgestaltung.keyboardIncrement</key>
+ <integer>1</integer>
+ <key>com.schriftgestaltung.weight</key>
+ <string>Regular</string>
+ <key>com.schriftgestaltung.weightValue</key>
+ <integer>400</integer>
+ <key>com.schriftgestaltung.width</key>
+ <string>Regular</string>
+ <key>com.schriftgestaltung.widthValue</key>
+ <integer>100</integer>
+ <key>org.sil.lcg.toneLetters</key>
+ <dict>
+ <key>contourWidth</key>
+ <integer>480</integer>
+ <key>dotSize</key>
+ <integer>180</integer>
+ <key>dotSpacing</key>
+ <integer>200</integer>
+ <key>glyphDepth</key>
+ <integer>-25</integer>
+ <key>glyphHeight</key>
+ <integer>1600</integer>
+ <key>italicAngle</key>
+ <integer>0</integer>
+ <key>marginDotLeft</key>
+ <integer>120</integer>
+ <key>marginDotRight</key>
+ <integer>160</integer>
+ <key>marginFlatLeft</key>
+ <integer>120</integer>
+ <key>marginFlatRight</key>
+ <integer>160</integer>
+ <key>marginPointLeft</key>
+ <integer>100</integer>
+ <key>marginPointRight</key>
+ <integer>140</integer>
+ <key>strokeThickness</key>
+ <integer>120</integer>
+ </dict>
+ <key>public.glyphOrder</key>
+ <array>
+ <string>.notdef</string>
+ <string>.null</string>
+ <string>nonmarkingreturn</string>
+ <string>Space</string>
+ <string>ExclamationMrk</string>
+ <string>QuotMrk</string>
+ <string>NumSgn</string>
+ <string>DollarSgn</string>
+ <string>PercentSgn</string>
+ <string>Ampersand</string>
+ <string>Apos</string>
+ <string>LftParen</string>
+ <string>RtParen</string>
+ <string>Asterisk</string>
+ <string>PlusSgn</string>
+ <string>Comma</string>
+ <string>HyphenMinus</string>
+ <string>FullStop</string>
+ <string>Solidus</string>
+ <string>DigitZero</string>
+ <string>DigitOne</string>
+ <string>DigitTwo</string>
+ <string>DigitThree</string>
+ <string>DigitFour</string>
+ <string>DigitFive</string>
+ <string>DigitSix</string>
+ <string>DigitSeven</string>
+ <string>DigitEight</string>
+ <string>DigitNine</string>
+ <string>Colon</string>
+ <string>Semicolon</string>
+ <string>LTSgn</string>
+ <string>EqSgn</string>
+ <string>GTSgn</string>
+ <string>QstnMrk</string>
+ <string>AtSgn</string>
+ <string>LtnCapA</string>
+ <string>LtnCapA.alt</string>
+ <string>LtnCapB</string>
+ <string>LtnCapC</string>
+ <string>LtnCapD</string>
+ <string>LtnCapE</string>
+ <string>LtnCapF</string>
+ <string>LtnCapG</string>
+ <string>LtnCapH</string>
+ <string>LtnCapI</string>
+ <string>LtnCapJ</string>
+ <string>LtnCapK</string>
+ <string>LtnCapL</string>
+ <string>LtnCapM</string>
+ <string>LtnCapN</string>
+ <string>LtnCapO</string>
+ <string>LtnCapP</string>
+ <string>LtnCapQ</string>
+ <string>LtnCapR</string>
+ <string>LtnCapS</string>
+ <string>LtnCapT</string>
+ <string>LtnCapU</string>
+ <string>LtnCapV</string>
+ <string>LtnCapW</string>
+ <string>LtnCapX</string>
+ <string>LtnCapY</string>
+ <string>LftSqrBrac</string>
+ <string>ReverseSolidus</string>
+ <string>RtSqrBrac</string>
+ <string>CircumAccent</string>
+ <string>LowLine</string>
+ <string>GraveAccent</string>
+ <string>LtnSmA</string>
+ <string>LtnSmB</string>
+ <string>LtnSmC</string>
+ <string>LtnSmD</string>
+ <string>LtnSmE</string>
+ <string>LtnSmF</string>
+ <string>LtnSmG</string>
+ <string>LtnSmH</string>
+ <string>LtnSmI</string>
+ <string>LtnSmJ</string>
+ <string>LtnSmK</string>
+ <string>LtnSmL</string>
+ <string>LtnSmM</string>
+ <string>LtnSmN</string>
+ <string>LtnSmO</string>
+ <string>LtnSmP</string>
+ <string>LtnSmQ</string>
+ <string>LtnSmR</string>
+ <string>LtnSmS</string>
+ <string>LtnSmT</string>
+ <string>LtnSmU</string>
+ <string>LtnSmV</string>
+ <string>LtnSmW</string>
+ <string>LtnSmX</string>
+ <string>LtnSmY</string>
+ <string>LftCurlyBrac</string>
+ <string>VertLine</string>
+ <string>RtCurlyBrac</string>
+ <string>Tilde</string>
+ <string>LtnCapADiaer</string>
+ <string>LtnSmAAcute</string>
+ <string>LtnSmAGrave</string>
+ <string>LtnSmACircum</string>
+ <string>LtnSmADiaer</string>
+ <string>LtnSmATilde</string>
+ <string>LtnSmARingAbv</string>
+ <string>DottedCirc</string>
+ <string>Hyphen</string>
+ <string>NonBreakingHyphen</string>
+ <string>Hyphen_Soft</string>
+ <string>CombAcute</string>
+ <string>CombGrave</string>
+ <string>CombCircum</string>
+ <string>CombTilde</string>
+ <string>CombDiaer</string>
+ <string>CombRingAbv</string>
+ </array>
+ <key>public.postscriptNames</key>
+ <dict>
+ <key>Ampersand</key>
+ <string>ampersand</string>
+ <key>Apos</key>
+ <string>quotesingle</string>
+ <key>Asterisk</key>
+ <string>asterisk</string>
+ <key>AtSgn</key>
+ <string>at</string>
+ <key>CircumAccent</key>
+ <string>asciicircum</string>
+ <key>Colon</key>
+ <string>colon</string>
+ <key>CombAcute</key>
+ <string>acutecomb</string>
+ <key>CombCircum</key>
+ <string>uni0302</string>
+ <key>CombDiaer</key>
+ <string>uni0308</string>
+ <key>CombGrave</key>
+ <string>gravecomb</string>
+ <key>CombRingAbv</key>
+ <string>uni030A</string>
+ <key>CombTilde</key>
+ <string>tildecomb</string>
+ <key>Comma</key>
+ <string>comma</string>
+ <key>DigitEight</key>
+ <string>eight</string>
+ <key>DigitFive</key>
+ <string>five</string>
+ <key>DigitFour</key>
+ <string>four</string>
+ <key>DigitNine</key>
+ <string>nine</string>
+ <key>DigitOne</key>
+ <string>one</string>
+ <key>DigitSeven</key>
+ <string>seven</string>
+ <key>DigitSix</key>
+ <string>six</string>
+ <key>DigitThree</key>
+ <string>three</string>
+ <key>DigitTwo</key>
+ <string>two</string>
+ <key>DigitZero</key>
+ <string>zero</string>
+ <key>DollarSgn</key>
+ <string>dollar</string>
+ <key>DottedCirc</key>
+ <string>uni25CC</string>
+ <key>EqSgn</key>
+ <string>equal</string>
+ <key>ExclamationMrk</key>
+ <string>exclam</string>
+ <key>FullStop</key>
+ <string>period</string>
+ <key>GTSgn</key>
+ <string>greater</string>
+ <key>GraveAccent</key>
+ <string>grave</string>
+ <key>Hyphen</key>
+ <string>uni2010</string>
+ <key>HyphenMinus</key>
+ <string>hyphen</string>
+ <key>Hyphen_Soft</key>
+ <string>uni00AD</string>
+ <key>LTSgn</key>
+ <string>less</string>
+ <key>LftCurlyBrac</key>
+ <string>braceleft</string>
+ <key>LftParen</key>
+ <string>parenleft</string>
+ <key>LftSqrBrac</key>
+ <string>bracketleft</string>
+ <key>LowLine</key>
+ <string>underscore</string>
+ <key>LtnCapA</key>
+ <string>A</string>
+ <key>LtnCapA.alt</key>
+ <string>A</string>
+ <key>LtnCapADiaer</key>
+ <string>Adieresis</string>
+ <key>LtnCapB</key>
+ <string>B</string>
+ <key>LtnCapC</key>
+ <string>C</string>
+ <key>LtnCapD</key>
+ <string>D</string>
+ <key>LtnCapE</key>
+ <string>E</string>
+ <key>LtnCapF</key>
+ <string>F</string>
+ <key>LtnCapG</key>
+ <string>G</string>
+ <key>LtnCapH</key>
+ <string>H</string>
+ <key>LtnCapI</key>
+ <string>I</string>
+ <key>LtnCapJ</key>
+ <string>J</string>
+ <key>LtnCapK</key>
+ <string>K</string>
+ <key>LtnCapL</key>
+ <string>L</string>
+ <key>LtnCapM</key>
+ <string>M</string>
+ <key>LtnCapN</key>
+ <string>N</string>
+ <key>LtnCapO</key>
+ <string>O</string>
+ <key>LtnCapP</key>
+ <string>P</string>
+ <key>LtnCapQ</key>
+ <string>Q</string>
+ <key>LtnCapR</key>
+ <string>R</string>
+ <key>LtnCapS</key>
+ <string>S</string>
+ <key>LtnCapT</key>
+ <string>T</string>
+ <key>LtnCapU</key>
+ <string>U</string>
+ <key>LtnCapV</key>
+ <string>V</string>
+ <key>LtnCapW</key>
+ <string>W</string>
+ <key>LtnCapX</key>
+ <string>X</string>
+ <key>LtnCapY</key>
+ <string>Y</string>
+ <key>LtnSmA</key>
+ <string>a</string>
+ <key>LtnSmAAcute</key>
+ <string>aacute</string>
+ <key>LtnSmACircum</key>
+ <string>acircumflex</string>
+ <key>LtnSmADiaer</key>
+ <string>adieresis</string>
+ <key>LtnSmAGrave</key>
+ <string>agrave</string>
+ <key>LtnSmARingAbv</key>
+ <string>aring</string>
+ <key>LtnSmATilde</key>
+ <string>atilde</string>
+ <key>LtnSmB</key>
+ <string>b</string>
+ <key>LtnSmC</key>
+ <string>c</string>
+ <key>LtnSmD</key>
+ <string>d</string>
+ <key>LtnSmE</key>
+ <string>e</string>
+ <key>LtnSmF</key>
+ <string>f</string>
+ <key>LtnSmG</key>
+ <string>g</string>
+ <key>LtnSmH</key>
+ <string>h</string>
+ <key>LtnSmI</key>
+ <string>i</string>
+ <key>LtnSmJ</key>
+ <string>j</string>
+ <key>LtnSmK</key>
+ <string>k</string>
+ <key>LtnSmL</key>
+ <string>l</string>
+ <key>LtnSmM</key>
+ <string>m</string>
+ <key>LtnSmN</key>
+ <string>n</string>
+ <key>LtnSmO</key>
+ <string>o</string>
+ <key>LtnSmP</key>
+ <string>p</string>
+ <key>LtnSmQ</key>
+ <string>q</string>
+ <key>LtnSmR</key>
+ <string>r</string>
+ <key>LtnSmS</key>
+ <string>s</string>
+ <key>LtnSmT</key>
+ <string>t</string>
+ <key>LtnSmU</key>
+ <string>u</string>
+ <key>LtnSmV</key>
+ <string>v</string>
+ <key>LtnSmW</key>
+ <string>w</string>
+ <key>LtnSmX</key>
+ <string>x</string>
+ <key>LtnSmY</key>
+ <string>y</string>
+ <key>NonBreakingHyphen</key>
+ <string>uni2011</string>
+ <key>NumSgn</key>
+ <string>numbersign</string>
+ <key>PercentSgn</key>
+ <string>percent</string>
+ <key>PlusSgn</key>
+ <string>plus</string>
+ <key>QstnMrk</key>
+ <string>question</string>
+ <key>QuotMrk</key>
+ <string>quotedbl</string>
+ <key>ReverseSolidus</key>
+ <string>backslash</string>
+ <key>RtCurlyBrac</key>
+ <string>braceright</string>
+ <key>RtParen</key>
+ <string>parenright</string>
+ <key>RtSqrBrac</key>
+ <string>bracketright</string>
+ <key>Semicolon</key>
+ <string>semicolon</string>
+ <key>Solidus</key>
+ <string>slash</string>
+ <key>Space</key>
+ <string>space</string>
+ <key>Tilde</key>
+ <string>asciitilde</string>
+ <key>VertLine</key>
+ <string>bar</string>
+ </dict>
+</dict>
+</plist>
diff --git a/tests/reference/ufo/psfglyphs2ufo/PsfTest-Regular.ufo/metainfo.plist b/tests/reference/ufo/psfglyphs2ufo/PsfTest-Regular.ufo/metainfo.plist
new file mode 100644
index 0000000..aa10c5c
--- /dev/null
+++ b/tests/reference/ufo/psfglyphs2ufo/PsfTest-Regular.ufo/metainfo.plist
@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+ <key>creator</key>
+ <string>org.sil.scripts.pysilfont</string>
+ <key>formatVersion</key>
+ <integer>3</integer>
+</dict>
+</plist>
diff --git a/tests/reference/ufo/psfmakefea.fea b/tests/reference/ufo/psfmakefea.fea
new file mode 100644
index 0000000..1ce54da
--- /dev/null
+++ b/tests/reference/ufo/psfmakefea.fea
@@ -0,0 +1,214 @@
+
+# Main Classes
+@GDEF_bases = [.notdef .null Ampersand Apos Asterisk AtSgn CircumAccent Colon Comma DigitEight DigitFive DigitFour DigitNine DigitOne DigitSeven DigitSix DigitThree DigitTwo DigitZero DollarSgn DottedCirc EqSgn ExclamationMrk FullStop GTSgn GraveAccent Hyphen HyphenMinus Hyphen_Soft LTSgn LftCurlyBrac LftParen LftSqrBrac LowLine LtnCapA LtnCapA.alt LtnCapADiaer LtnCapB LtnCapC LtnCapD LtnCapE LtnCapF LtnCapG LtnCapH LtnCapI LtnCapJ LtnCapK LtnCapL LtnCapM LtnCapN LtnCapO LtnCapP LtnCapQ LtnCapR LtnCapS LtnCapT LtnCapU LtnCapV LtnCapW LtnCapX LtnCapY LtnSmA LtnSmAAcute LtnSmACircum LtnSmADiaer LtnSmAGrave LtnSmARingAbv LtnSmATilde LtnSmB LtnSmC LtnSmD LtnSmE LtnSmF LtnSmG LtnSmH LtnSmI LtnSmJ LtnSmK LtnSmL LtnSmM LtnSmN LtnSmO LtnSmP LtnSmQ LtnSmR LtnSmS LtnSmT LtnSmU LtnSmV LtnSmW LtnSmX LtnSmY NonBreakingHyphen NumSgn PercentSgn PlusSgn QstnMrk QuotMrk ReverseSolidus RtCurlyBrac RtParen RtSqrBrac Semicolon Solidus Space Tilde VertLine nonmarkingreturn];
+@GDEF_marks = [CombAcute CombCircum CombDiaer CombGrave CombRingAbv CombTilde];
+@c_alt = [LtnCapA.alt];
+@cno_alt = [LtnCapA];
+
+# Positioning classes and statements
+
+# AP: U
+@U = [DigitEight DigitFive DigitNine DigitOne DigitSeven DigitSix DigitThree LtnCapE DigitFour DigitTwo DigitZero DottedCirc Hyphen HyphenMinus Hyphen_Soft NonBreakingHyphen LtnCapA LtnCapA.alt LtnCapADiaer LtnCapB LtnCapC LtnCapD LtnCapF LtnCapG LtnCapH LtnCapI LtnCapJ LtnCapK LtnCapX LtnCapY LtnCapL LtnCapM LtnCapN LtnCapO LtnCapQ LtnCapP LtnCapR LtnCapS LtnCapT LtnCapU LtnCapV LtnCapW LtnSmA LtnSmAAcute LtnSmACircum LtnSmAGrave LtnSmADiaer LtnSmARingAbv LtnSmATilde LtnSmB LtnSmC LtnSmO LtnSmD LtnSmE LtnSmF LtnSmG LtnSmH LtnSmI LtnSmJ LtnSmK LtnSmL LtnSmM LtnSmN LtnSmP LtnSmQ LtnSmR LtnSmS LtnSmT LtnSmU LtnSmV LtnSmY LtnSmW LtnSmX];
+@U_MarkBase = [CombAcute CombCircum CombRingAbv CombDiaer CombGrave CombTilde];
+# baseClass [DigitEight DigitFive DigitNine DigitOne DigitSeven DigitSix DigitThree LtnCapE] <anchor 600 1530> @U;
+# baseClass DigitFour <anchor 607 1530> @U;
+# baseClass DigitTwo <anchor 560 1530> @U;
+# baseClass DigitZero <anchor 605 1530> @U;
+# baseClass DottedCirc <anchor 553 1000> @U;
+# baseClass [Hyphen HyphenMinus Hyphen_Soft NonBreakingHyphen] <anchor 430 1100> @U;
+# baseClass LtnCapA <anchor 687 1530> @U;
+# baseClass LtnCapA.alt <anchor 688 -70> @U;
+# baseClass LtnCapADiaer <anchor 687 1935> @U;
+# baseClass LtnCapB <anchor 615 1530> @U;
+# baseClass LtnCapC <anchor 750 1530> @U;
+# baseClass LtnCapD <anchor 715 1530> @U;
+# baseClass LtnCapF <anchor 595 1530> @U;
+# baseClass LtnCapG <anchor 745 1530> @U;
+# baseClass LtnCapH <anchor 725 1530> @U;
+# baseClass LtnCapI <anchor 477 1530> @U;
+# baseClass LtnCapJ <anchor 675 1530> @U;
+# baseClass [LtnCapK LtnCapX LtnCapY] <anchor 650 1530> @U;
+# baseClass LtnCapL <anchor 592 1530> @U;
+# baseClass LtnCapM <anchor 885 1530> @U;
+# baseClass LtnCapN <anchor 737 1530> @U;
+# baseClass [LtnCapO LtnCapQ] <anchor 717 1530> @U;
+# baseClass LtnCapP <anchor 637 1530> @U;
+# baseClass LtnCapR <anchor 610 1530> @U;
+# baseClass LtnCapS <anchor 580 1530> @U;
+# baseClass LtnCapT <anchor 622 1530> @U;
+# baseClass LtnCapU <anchor 707 1530> @U;
+# baseClass LtnCapV <anchor 672 1530> @U;
+# baseClass LtnCapW <anchor 1027 1530> @U;
+# baseClass LtnSmA <anchor 540 1100> @U;
+# baseClass [LtnSmAAcute LtnSmACircum LtnSmAGrave] <anchor 540 1635> @U;
+# baseClass LtnSmADiaer <anchor 540 1505> @U;
+# baseClass LtnSmARingAbv <anchor 542 1635> @U;
+# baseClass LtnSmATilde <anchor 540 1475> @U;
+# baseClass LtnSmB <anchor 590 1635> @U;
+# baseClass [LtnSmC LtnSmO] <anchor 570 1100> @U;
+# baseClass LtnSmD <anchor 605 1635> @U;
+# baseClass LtnSmE <anchor 569 1100> @U;
+# baseClass LtnSmF <anchor 560 1635> @U;
+# baseClass LtnSmG <anchor 515 1100> @U;
+# baseClass LtnSmH <anchor 585 1635> @U;
+# baseClass LtnSmI <anchor 282 1100> @U;
+# baseClass LtnSmJ <anchor 313 1100> @U;
+# baseClass LtnSmK <anchor 572 1635> @U;
+# baseClass LtnSmL <anchor 282 1635> @U;
+# baseClass LtnSmM <anchor 865 1100> @U;
+# baseClass LtnSmN <anchor 600 1100> @U;
+# baseClass LtnSmP <anchor 590 1100> @U;
+# baseClass LtnSmQ <anchor 555 1100> @U;
+# baseClass LtnSmR <anchor 455 1100> @U;
+# baseClass LtnSmS <anchor 495 1100> @U;
+# baseClass LtnSmT <anchor 325 1360> @U;
+# baseClass LtnSmU <anchor 589 1100> @U;
+# baseClass [LtnSmV LtnSmY] <anchor 535 1100> @U;
+# baseClass LtnSmW <anchor 775 1100> @U;
+# baseClass LtnSmX <anchor 542 1100> @U;
+# baseClass [CombAcute CombCircum CombRingAbv] <anchor -570 1635> @U_MarkBase;
+# baseClass CombDiaer <anchor -570 1505> @U_MarkBase;
+# baseClass CombGrave <anchor -550 1635> @U_MarkBase;
+# baseClass CombTilde <anchor -575 1475> @U_MarkBase;
+
+# AP: _U
+markClass [CombAcute CombCircum CombDiaer] <anchor -570 1100> @_U;
+markClass CombGrave <anchor -550 1100> @_U;
+markClass CombRingAbv <anchor -572 1100> @_U;
+markClass CombTilde <anchor -575 1100> @_U;
+
+# AP: L
+@L = [DigitEight DigitFive DigitNine DigitOne DigitSeven DigitSix DigitThree DigitTwo LtnCapE LtnSmN DigitFour DigitZero LtnSmD DottedCirc LtnCapA LtnCapADiaer LtnCapA.alt LtnCapB LtnCapC LtnCapD LtnCapF LtnCapG LtnCapH LtnCapI LtnCapJ LtnCapK LtnCapL LtnCapM LtnCapN LtnCapO LtnCapP LtnCapQ LtnCapR LtnCapS LtnSmC LtnCapT LtnCapU LtnCapV LtnCapW LtnCapX LtnCapY LtnSmA LtnSmAAcute LtnSmACircum LtnSmADiaer LtnSmAGrave LtnSmARingAbv LtnSmATilde LtnSmB LtnSmE LtnSmF LtnSmG LtnSmH LtnSmI LtnSmJ LtnSmK LtnSmL LtnSmM LtnSmO LtnSmP LtnSmQ LtnSmR LtnSmS LtnSmT LtnSmU LtnSmV LtnSmW LtnSmX LtnSmY];
+# baseClass [DigitEight DigitFive DigitNine DigitOne DigitSeven DigitSix DigitThree DigitTwo LtnCapE LtnSmN] <anchor 600 -100> @L;
+# baseClass DigitFour <anchor 607 -100> @L;
+# baseClass [DigitZero LtnSmD] <anchor 605 -100> @L;
+# baseClass DottedCirc <anchor 553 -100> @L;
+# baseClass [LtnCapA LtnCapADiaer] <anchor 687 -100> @L;
+# baseClass LtnCapA.alt <anchor 688 1560> @L;
+# baseClass LtnCapB <anchor 615 -100> @L;
+# baseClass LtnCapC <anchor 750 -100> @L;
+# baseClass LtnCapD <anchor 715 -100> @L;
+# baseClass LtnCapF <anchor 595 -100> @L;
+# baseClass LtnCapG <anchor 745 -100> @L;
+# baseClass LtnCapH <anchor 725 -100> @L;
+# baseClass LtnCapI <anchor 477 -100> @L;
+# baseClass LtnCapJ <anchor 410 -100> @L;
+# baseClass LtnCapK <anchor 695 -100> @L;
+# baseClass LtnCapL <anchor 592 -100> @L;
+# baseClass LtnCapM <anchor 885 -100> @L;
+# baseClass LtnCapN <anchor 737 -100> @L;
+# baseClass LtnCapO <anchor 717 -100> @L;
+# baseClass LtnCapP <anchor 637 -100> @L;
+# baseClass LtnCapQ <anchor 717 -270> @L;
+# baseClass LtnCapR <anchor 610 -100> @L;
+# baseClass [LtnCapS LtnSmC] <anchor 580 -100> @L;
+# baseClass LtnCapT <anchor 622 -100> @L;
+# baseClass LtnCapU <anchor 707 -100> @L;
+# baseClass LtnCapV <anchor 672 -100> @L;
+# baseClass LtnCapW <anchor 1027 -100> @L;
+# baseClass [LtnCapX LtnCapY] <anchor 650 -100> @L;
+# baseClass [LtnSmA LtnSmAAcute LtnSmACircum LtnSmADiaer LtnSmAGrave LtnSmARingAbv LtnSmATilde] <anchor 540 -100> @L;
+# baseClass LtnSmB <anchor 590 -100> @L;
+# baseClass LtnSmE <anchor 569 -100> @L;
+# baseClass LtnSmF <anchor 335 -100> @L;
+# baseClass LtnSmG <anchor 545 -535> @L;
+# baseClass LtnSmH <anchor 585 -100> @L;
+# baseClass LtnSmI <anchor 285 -100> @L;
+# baseClass LtnSmJ <anchor 125 -500> @L;
+# baseClass LtnSmK <anchor 572 -100> @L;
+# baseClass LtnSmL <anchor 290 -100> @L;
+# baseClass LtnSmM <anchor 865 -100> @L;
+# baseClass LtnSmO <anchor 570 -100> @L;
+# baseClass LtnSmP <anchor 590 -500> @L;
+# baseClass LtnSmQ <anchor 555 -500> @L;
+# baseClass LtnSmR <anchor 255 -100> @L;
+# baseClass LtnSmS <anchor 495 -100> @L;
+# baseClass LtnSmT <anchor 475 -100> @L;
+# baseClass LtnSmU <anchor 589 -100> @L;
+# baseClass LtnSmV <anchor 535 -100> @L;
+# baseClass LtnSmW <anchor 775 -100> @L;
+# baseClass LtnSmX <anchor 542 -100> @L;
+# baseClass LtnSmY <anchor 795 -100> @L;
+
+# AP: H
+@H = [DottedCirc LtnCapA LtnCapADiaer LtnCapU LtnCapA.alt LtnCapC LtnCapE LtnCapG LtnCapH LtnCapR LtnCapI LtnCapK LtnSmR LtnCapL LtnCapM LtnCapN LtnCapO LtnCapS LtnSmC LtnCapT LtnCapV LtnSmA LtnSmAAcute LtnSmACircum LtnSmADiaer LtnSmAGrave LtnSmARingAbv LtnSmATilde LtnSmB LtnSmD LtnSmE LtnSmF LtnSmG LtnSmH LtnSmI LtnSmK LtnSmL LtnSmM LtnSmN LtnSmO LtnSmP LtnSmS LtnSmT LtnSmU LtnSmV LtnSmX];
+# baseClass DottedCirc <anchor 553 0> @H;
+# baseClass [LtnCapA LtnCapADiaer LtnCapU] <anchor 707 0> @H;
+# baseClass LtnCapA.alt <anchor 668 1460> @H;
+# baseClass LtnCapC <anchor 750 0> @H;
+# baseClass LtnCapE <anchor 600 0> @H;
+# baseClass LtnCapG <anchor 745 0> @H;
+# baseClass [LtnCapH LtnCapR] <anchor 285 0> @H;
+# baseClass LtnCapI <anchor 477 0> @H;
+# baseClass [LtnCapK LtnSmR] <anchor 270 0> @H;
+# baseClass LtnCapL <anchor 592 0> @H;
+# baseClass LtnCapM <anchor 1521 0> @H;
+# baseClass LtnCapN <anchor 1230 0> @H;
+# baseClass LtnCapO <anchor 717 0> @H;
+# baseClass [LtnCapS LtnSmC] <anchor 580 0> @H;
+# baseClass LtnCapT <anchor 622 0> @H;
+# baseClass LtnCapV <anchor 680 0> @H;
+# baseClass [LtnSmA LtnSmAAcute LtnSmACircum LtnSmADiaer LtnSmAGrave LtnSmARingAbv LtnSmATilde] <anchor 540 0> @H;
+# baseClass LtnSmB <anchor 590 0> @H;
+# baseClass LtnSmD <anchor 605 0> @H;
+# baseClass LtnSmE <anchor 545 0> @H;
+# baseClass LtnSmF <anchor 370 0> @H;
+# baseClass LtnSmG <anchor 545 -432> @H;
+# baseClass LtnSmH <anchor 250 0> @H;
+# baseClass LtnSmI <anchor 282 0> @H;
+# baseClass LtnSmK <anchor 243 0> @H;
+# baseClass LtnSmL <anchor 290 0> @H;
+# baseClass LtnSmM <anchor 1450 0> @H;
+# baseClass LtnSmN <anchor 970 0> @H;
+# baseClass LtnSmO <anchor 570 0> @H;
+# baseClass LtnSmP <anchor 265 -435> @H;
+# baseClass LtnSmS <anchor 495 0> @H;
+# baseClass LtnSmT <anchor 475 0> @H;
+# baseClass LtnSmU <anchor 589 0> @H;
+# baseClass LtnSmV <anchor 549 0> @H;
+# baseClass LtnSmX <anchor 900 0> @H;
+
+# AP: O
+@O = [DottedCirc LtnCapA LtnCapADiaer LtnCapA.alt LtnCapE LtnCapI LtnCapO LtnCapU LtnCapV LtnSmA LtnSmAAcute LtnSmACircum LtnSmADiaer LtnSmAGrave LtnSmARingAbv LtnSmATilde LtnSmE LtnSmI LtnSmO LtnSmU LtnSmV];
+# baseClass DottedCirc <anchor 810 0> @O;
+# baseClass [LtnCapA LtnCapADiaer] <anchor 1450 0> @O;
+# baseClass LtnCapA.alt <anchor -75 1460> @O;
+# baseClass LtnCapE <anchor 917 0> @O;
+# baseClass LtnCapI <anchor 673 0> @O;
+# baseClass LtnCapO <anchor 994 0> @O;
+# baseClass LtnCapU <anchor 1026 0> @O;
+# baseClass LtnCapV <anchor 880 0> @O;
+# baseClass [LtnSmA LtnSmAAcute LtnSmACircum LtnSmADiaer LtnSmAGrave LtnSmARingAbv LtnSmATilde] <anchor 1125 0> @O;
+# baseClass LtnSmE <anchor 925 0> @O;
+# baseClass LtnSmI <anchor 500 0> @O;
+# baseClass LtnSmO <anchor 835 0> @O;
+# baseClass LtnSmU <anchor 1192 0> @O;
+# baseClass LtnSmV <anchor 725 0> @O;
+
+# AP: R
+@R = [LtnCapE LtnCapI LtnCapL LtnCapO LtnCapU LtnSmA LtnSmAAcute LtnSmACircum LtnSmADiaer LtnSmAGrave LtnSmARingAbv LtnSmATilde LtnSmY LtnSmB LtnSmC LtnSmD LtnSmE LtnSmG LtnSmI LtnSmK LtnSmL LtnSmO LtnSmP LtnSmQ LtnSmT LtnSmU];
+# baseClass LtnCapE <anchor 1160 1200> @R;
+# baseClass LtnCapI <anchor 975 1200> @R;
+# baseClass LtnCapL <anchor 540 1200> @R;
+# baseClass LtnCapO <anchor 1460 1200> @R;
+# baseClass LtnCapU <anchor 1400 1200> @R;
+# baseClass [LtnSmA LtnSmAAcute LtnSmACircum LtnSmADiaer LtnSmAGrave LtnSmARingAbv LtnSmATilde LtnSmY] <anchor 1120 1000> @R;
+# baseClass LtnSmB <anchor 1155 1000> @R;
+# baseClass LtnSmC <anchor 1020 1000> @R;
+# baseClass LtnSmD <anchor 1190 1000> @R;
+# baseClass [LtnSmE LtnSmG] <anchor 1095 1000> @R;
+# baseClass LtnSmI <anchor 555 1000> @R;
+# baseClass LtnSmK <anchor 1035 1000> @R;
+# baseClass LtnSmL <anchor 550 1000> @R;
+# baseClass LtnSmO <anchor 1140 1000> @R;
+# baseClass LtnSmP <anchor 1170 1000> @R;
+# baseClass LtnSmQ <anchor 1130 1000> @R;
+# baseClass LtnSmT <anchor 835 1000> @R;
+# baseClass LtnSmU <anchor 1185 1000> @R;
+@base = [A a];
+@basex = [A.x a.x];
+@basey = [A.y a.y];
+feature alt {
+ sub A from [A.x A.y];
+ sub a from [a.x a.y];
+} alt;
diff --git a/tests/reference/ufo/psfmakefea.lg b/tests/reference/ufo/psfmakefea.lg
new file mode 100644
index 0000000..98ea8d4
--- /dev/null
+++ b/tests/reference/ufo/psfmakefea.lg
@@ -0,0 +1,2 @@
+2020-07-28 14:36:08 Progress: Running: psfmakefea -i tests/input/psfmakefea.feax -o local/testresults/ufo/psfmakefea.fea -l local/testresults/ufo/psfmakefea.log tests/input/font-psf-test/source/PsfTest-Regular.ufo
+2020-07-28 14:36:08 Progress: Reading UFO: tests/input/font-psf-test/source/PsfTest-Regular.ufo
diff --git a/tests/reference/ufo/psfmakewoffmetadata.lg b/tests/reference/ufo/psfmakewoffmetadata.lg
new file mode 100644
index 0000000..f866b62
--- /dev/null
+++ b/tests/reference/ufo/psfmakewoffmetadata.lg
@@ -0,0 +1,13 @@
+2022-03-07 14:44:21 Progress: Running: psfmakewoffmetadata tests/input/font-psf-test/source/PsfTest-Regular.ufo -n Test -i SIL -f tests/input/psfmakewoffmetadata.txt -o local/testresults/ufo/psfmakewoffmetadata.xml -l local/testresults/ufo/psfmakewoffmetadata.log
+2022-03-07 14:44:21 Progress: Reading UFO: tests/input/font-psf-test/source/PsfTest-Regular.ufo
+2022-03-07 14:44:21 Progress: Checking fontinfo.plist metadata
+2022-03-07 14:44:21 Warning: note is present - it's use is discouraged
+2022-03-07 14:44:21 Warning: openTypeOS2FamilyClass would be removed from fontinfo Old value: [0, 0]
+2022-03-07 14:44:21 Warning: openTypeOS2Selection would be added New value: [7]
+2022-03-07 14:44:21 Progress: Checking lib.plist metadata
+2022-03-07 14:44:21 Warning: com.schriftgestaltung.disablesAutomaticAlignment would be deleted - obsolete key Old value: True
+2022-03-07 14:44:21 Warning: com.schriftgestaltung.disablesLastChange would be deleted - obsolete key Old value: True
+2022-03-07 14:44:21 Progress: Check & fix results:- Errors: 0, Changes to make: 4, Other warnings: 1
+2022-03-07 14:44:21 Progress: See log file for details
+2022-03-07 14:44:21 Warning: WOFF field(s) missing from fontinfo.plist will be generated from FONTLOG.txt: woffMetadataCredits, woffMetadataDescription
+2022-03-07 14:44:21 Progress: Writing to : local/testresults/ufo/psfmakewoffmetadata.xml
diff --git a/tests/reference/ufo/psfmakewoffmetadata.xml b/tests/reference/ufo/psfmakewoffmetadata.xml
new file mode 100644
index 0000000..06a4ac1
--- /dev/null
+++ b/tests/reference/ufo/psfmakewoffmetadata.xml
@@ -0,0 +1,82 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<metadata version="1.0">
+ <uniqueid id="SIL.Test.5.550" />
+ <vendor name="SIL International" url="http://scripts.sil.org" />
+ <credits>
+ <credit
+ name="Victor Gaultney"
+ url="http://www.sil.org/~gaultney/"
+ role="Original Designer"
+ />
+ <credit
+ name="SIL font engineers"
+ url="http://scripts.sil.org/"
+ role="Graphite, OpenType, and TypeTuner code, and build support"
+ />
+ </credits>
+ <description>
+ <text lang="en">
+ There are intentional problems with the UFO!
+
+ Features
+ --------
+
+ What features?
+ </text>
+ </description>
+ <license url="http://scripts.sil.org/OFL" id="org.sil.ofl.1.1">
+ <text lang="en">
+ Copyright (c) 2004-2021 SIL International (http://www.sil.org/) with Reserved Font Names "Andika" and "SIL".
+
+ This Font Software is licensed under the SIL Open Font License, Version 1.1. This license is copied below, and is also available with a FAQ at: http://scripts.sil.org/OFL
+
+
+ -----------------------------------------------------------
+ SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007
+ -----------------------------------------------------------
+
+ PREAMBLE
+ The goals of the Open Font License (OFL) are to stimulate worldwide development of collaborative font projects, to support the font creation efforts of academic and linguistic communities, and to provide a free and open framework in which fonts may be shared and improved in partnership with others.
+
+ The OFL allows the licensed fonts to be used, studied, modified and redistributed freely as long as they are not sold by themselves. The fonts, including any derivative works, can be bundled, embedded, redistributed and/or sold with any software provided that any reserved names are not used by derivative works. The fonts and derivatives, however, cannot be released under any other type of license. The requirement for fonts to remain under this license does not apply to any document created using the fonts or their derivatives.
+
+ DEFINITIONS
+ "Font Software" refers to the set of files released by the Copyright Holder(s) under this license and clearly marked as such. This may include source files, build scripts and documentation.
+
+ "Reserved Font Name" refers to any names specified as such after the copyright statement(s).
+
+ "Original Version" refers to the collection of Font Software components as distributed by the Copyright Holder(s).
+
+ "Modified Version" refers to any derivative made by adding to, deleting, or substituting -- in part or in whole -- any of the components of the Original Version, by changing formats or by porting the Font Software to a new environment.
+
+ "Author" refers to any designer, engineer, programmer, technical writer or other person who contributed to the Font Software.
+
+ PERMISSION &amp; CONDITIONS
+ Permission is hereby granted, free of charge, to any person obtaining a copy of the Font Software, to use, study, copy, merge, embed, modify, redistribute, and sell modified and unmodified copies of the Font Software, subject to the following conditions:
+
+ 1) Neither the Font Software nor any of its individual components, in Original or Modified Versions, may be sold by itself.
+
+ 2) Original or Modified Versions of the Font Software may be bundled, redistributed and/or sold with any software, provided that each copy contains the above copyright notice and this license. These can be included either as stand-alone text files, human-readable headers or in the appropriate machine-readable metadata fields within text or binary files as long as those fields can be easily viewed by the user.
+
+ 3) No Modified Version of the Font Software may use the Reserved Font Name(s) unless explicit written permission is granted by the corresponding Copyright Holder. This restriction only applies to the primary font name as presented to the users.
+
+ 4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font Software shall not be used to promote, endorse or advertise any Modified Version, except to acknowledge the contribution(s) of the Copyright Holder(s) and the Author(s) or with their explicit written permission.
+
+ 5) The Font Software, modified or unmodified, in part or in whole, must be distributed entirely under this license, and must not be distributed under any other license. The requirement for fonts to remain under this license does not apply to any document created using the Font Software.
+
+ TERMINATION
+ This license becomes null and void if any of the above conditions are not met.
+
+ DISCLAIMER
+ THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM OTHER DEALINGS IN THE FONT SOFTWARE.
+ </text>
+ </license>
+ <copyright>
+ <text lang="en">
+ Copyright (c) 2004-2021 SIL International
+ </text>
+ </copyright>
+ <trademark>
+ <text lang="en">Andika is a trademark of SIL International.</text>
+ </trademark>
+</metadata> \ No newline at end of file
diff --git a/tests/reference/ufo/psfnormalize.lg b/tests/reference/ufo/psfnormalize.lg
new file mode 100644
index 0000000..313c267
--- /dev/null
+++ b/tests/reference/ufo/psfnormalize.lg
@@ -0,0 +1,18 @@
+2021-06-29 14:42:23 Progress: Running: psfnormalize tests/input/font-psf-test/source/PsfTest-Italic.ufo -l local/testresults/ufo/psfnormalize.log -p checkfix=fix
+2021-06-29 14:42:23 Progress: Reading UFO: tests/input/font-psf-test/source/PsfTest-Italic.ufo
+2021-06-29 14:42:23 Progress: Checking fontinfo.plist metadata
+2021-06-29 14:42:23 Warning: openTypeOS2FamilyClass removed from fontinfo. Old value: [0, 0]
+2021-06-29 14:42:23 Warning: year removed from fontinfo. Old value: 2021
+2021-06-29 14:42:23 Warning: capHeight updated Old value: 1485.3, new value: 1485
+2021-06-29 14:42:23 Warning: styleMapFamilyName uppdated Old value: Psf test, new value: Psf Test
+2021-06-29 14:42:23 Warning: openTypeOS2TypoLineGap updated Old value: 1, new value: 0
+2021-06-29 14:42:23 Warning: openTypeOS2Selection added New value: [7]
+2021-06-29 14:42:23 Warning: openTypeNamePreferredFamilyName updated Old value: Psf Testing, new value: Psf Test
+2021-06-29 14:42:23 Progress: Checking lib.plist metadata
+2021-06-29 14:42:23 Warning: com.schriftgestaltung.disablesAutomaticAlignment deleted - obsolete key Old value: True
+2021-06-29 14:42:23 Warning: com.schriftgestaltung.disablesLastChange deleted - obsolete key Old value: True
+2021-06-29 14:42:23 Progress: Check & fix results:- Errors: 0, Changes made: 9, Other warnings: 0
+2021-06-29 14:42:23 Progress: See log file for details
+2021-06-29 14:42:23 Progress: Processing font for output
+2021-06-29 14:42:23 Progress: Output UFO already exists - reading for comparison
+2021-06-29 14:42:23 Progress: Writing font to local/testresults/ufo/psfnormalize.ufo
diff --git a/tests/reference/ufo/psfnormalize.ufo/fontinfo.plist b/tests/reference/ufo/psfnormalize.ufo/fontinfo.plist
new file mode 100644
index 0000000..d5f4bef
--- /dev/null
+++ b/tests/reference/ufo/psfnormalize.ufo/fontinfo.plist
@@ -0,0 +1,240 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+ <key>ascender</key>
+ <integer>2100</integer>
+ <key>capHeight</key>
+ <integer>1485</integer>
+ <key>copyright</key>
+ <string>Copyright (c) 2004-2021 SIL International</string>
+ <key>descender</key>
+ <integer>-550</integer>
+ <key>familyName</key>
+ <string>Psf Test</string>
+ <key>italicAngle</key>
+ <integer>-14</integer>
+ <key>openTypeHeadCreated</key>
+ <string>2021/06/29 14:43:53</string>
+ <key>openTypeHheaAscender</key>
+ <integer>2100</integer>
+ <key>openTypeHheaDescender</key>
+ <integer>-550</integer>
+ <key>openTypeHheaLineGap</key>
+ <integer>0</integer>
+ <key>openTypeNameDescription</key>
+ <string>Copyright (c) 2004-2021 SIL International</string>
+ <key>openTypeNameDesigner</key>
+ <string>Victor Gaultney, Annie Olsen, Julie Remington, Don Collingsworth, Eric Hays, Becca Hirsbrunner</string>
+ <key>openTypeNameDesignerURL</key>
+ <string>http://scripts.sil.org/</string>
+ <key>openTypeNameLicense</key>
+ <string>Copyright (c) 2004-2021 SIL International (http://www.sil.org/) with Reserved Font Names "Andika" and "SIL".
+
+This Font Software is licensed under the SIL Open Font License, Version 1.1. This license is copied below, and is also available with a FAQ at: http://scripts.sil.org/OFL
+
+
+-----------------------------------------------------------
+SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007
+-----------------------------------------------------------
+
+PREAMBLE
+The goals of the Open Font License (OFL) are to stimulate worldwide development of collaborative font projects, to support the font creation efforts of academic and linguistic communities, and to provide a free and open framework in which fonts may be shared and improved in partnership with others.
+
+The OFL allows the licensed fonts to be used, studied, modified and redistributed freely as long as they are not sold by themselves. The fonts, including any derivative works, can be bundled, embedded, redistributed and/or sold with any software provided that any reserved names are not used by derivative works. The fonts and derivatives, however, cannot be released under any other type of license. The requirement for fonts to remain under this license does not apply to any document created using the fonts or their derivatives.
+
+DEFINITIONS
+"Font Software" refers to the set of files released by the Copyright Holder(s) under this license and clearly marked as such. This may include source files, build scripts and documentation.
+
+"Reserved Font Name" refers to any names specified as such after the copyright statement(s).
+
+"Original Version" refers to the collection of Font Software components as distributed by the Copyright Holder(s).
+
+"Modified Version" refers to any derivative made by adding to, deleting, or substituting -- in part or in whole -- any of the components of the Original Version, by changing formats or by porting the Font Software to a new environment.
+
+"Author" refers to any designer, engineer, programmer, technical writer or other person who contributed to the Font Software.
+
+PERMISSION &amp; CONDITIONS
+Permission is hereby granted, free of charge, to any person obtaining a copy of the Font Software, to use, study, copy, merge, embed, modify, redistribute, and sell modified and unmodified copies of the Font Software, subject to the following conditions:
+
+1) Neither the Font Software nor any of its individual components, in Original or Modified Versions, may be sold by itself.
+
+2) Original or Modified Versions of the Font Software may be bundled, redistributed and/or sold with any software, provided that each copy contains the above copyright notice and this license. These can be included either as stand-alone text files, human-readable headers or in the appropriate machine-readable metadata fields within text or binary files as long as those fields can be easily viewed by the user.
+
+3) No Modified Version of the Font Software may use the Reserved Font Name(s) unless explicit written permission is granted by the corresponding Copyright Holder. This restriction only applies to the primary font name as presented to the users.
+
+4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font Software shall not be used to promote, endorse or advertise any Modified Version, except to acknowledge the contribution(s) of the Copyright Holder(s) and the Author(s) or with their explicit written permission.
+
+5) The Font Software, modified or unmodified, in part or in whole, must be distributed entirely under this license, and must not be distributed under any other license. The requirement for fonts to remain under this license does not apply to any document created using the Font Software.
+
+TERMINATION
+This license becomes null and void if any of the above conditions are not met.
+
+DISCLAIMER
+THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM OTHER DEALINGS IN THE FONT SOFTWARE.</string>
+ <key>openTypeNameLicenseURL</key>
+ <string>http://scripts.sil.org/OFL</string>
+ <key>openTypeNameManufacturer</key>
+ <string>SIL International</string>
+ <key>openTypeNameManufacturerURL</key>
+ <string>http://scripts.sil.org</string>
+ <key>openTypeNamePreferredFamilyName</key>
+ <string>Psf Test</string>
+ <key>openTypeNamePreferredSubfamilyName</key>
+ <string>Italic</string>
+ <key>openTypeNameUniqueID</key>
+ <string>SIL International: Psf Test Italic: 2022</string>
+ <key>openTypeNameVersion</key>
+ <string>Version 5.550</string>
+ <key>openTypeOS2CodePageRanges</key>
+ <array>
+ <integer>0</integer>
+ <integer>1</integer>
+ <integer>2</integer>
+ <integer>4</integer>
+ <integer>7</integer>
+ <integer>8</integer>
+ </array>
+ <key>openTypeOS2Panose</key>
+ <array>
+ <integer>2</integer>
+ <integer>0</integer>
+ <integer>0</integer>
+ <integer>0</integer>
+ <integer>0</integer>
+ <integer>0</integer>
+ <integer>0</integer>
+ <integer>0</integer>
+ <integer>0</integer>
+ <integer>0</integer>
+ </array>
+ <key>openTypeOS2Selection</key>
+ <array>
+ <integer>7</integer>
+ </array>
+ <key>openTypeOS2StrikeoutPosition</key>
+ <integer>700</integer>
+ <key>openTypeOS2StrikeoutSize</key>
+ <integer>100</integer>
+ <key>openTypeOS2SubscriptXOffset</key>
+ <integer>0</integer>
+ <key>openTypeOS2SubscriptXSize</key>
+ <integer>1433</integer>
+ <key>openTypeOS2SubscriptYOffset</key>
+ <integer>286</integer>
+ <key>openTypeOS2SubscriptYSize</key>
+ <integer>1331</integer>
+ <key>openTypeOS2SuperscriptXOffset</key>
+ <integer>0</integer>
+ <key>openTypeOS2SuperscriptXSize</key>
+ <integer>1433</integer>
+ <key>openTypeOS2SuperscriptYOffset</key>
+ <integer>976</integer>
+ <key>openTypeOS2SuperscriptYSize</key>
+ <integer>1331</integer>
+ <key>openTypeOS2Type</key>
+ <array/>
+ <key>openTypeOS2TypoAscender</key>
+ <integer>2100</integer>
+ <key>openTypeOS2TypoDescender</key>
+ <integer>-550</integer>
+ <key>openTypeOS2TypoLineGap</key>
+ <integer>0</integer>
+ <key>openTypeOS2UnicodeRanges</key>
+ <array>
+ <integer>0</integer>
+ <integer>1</integer>
+ <integer>6</integer>
+ <integer>7</integer>
+ <integer>31</integer>
+ <integer>33</integer>
+ <integer>35</integer>
+ <integer>36</integer>
+ <integer>37</integer>
+ <integer>38</integer>
+ <integer>39</integer>
+ <integer>40</integer>
+ <integer>45</integer>
+ <integer>46</integer>
+ <integer>47</integer>
+ <integer>57</integer>
+ <integer>60</integer>
+ <integer>62</integer>
+ <integer>64</integer>
+ <integer>67</integer>
+ <integer>69</integer>
+ <integer>89</integer>
+ </array>
+ <key>openTypeOS2VendorID</key>
+ <string>SIL</string>
+ <key>openTypeOS2WeightClass</key>
+ <integer>400</integer>
+ <key>openTypeOS2WidthClass</key>
+ <integer>5</integer>
+ <key>openTypeOS2WinAscent</key>
+ <integer>2100</integer>
+ <key>openTypeOS2WinDescent</key>
+ <integer>550</integer>
+ <key>postscriptBlueValues</key>
+ <array>
+ <integer>-490</integer>
+ <integer>-490</integer>
+ <integer>-25</integer>
+ <integer>0</integer>
+ <integer>1020</integer>
+ <integer>1040</integer>
+ <integer>1455</integer>
+ <integer>1485</integer>
+ <integer>1600</integer>
+ <integer>1620</integer>
+ </array>
+ <key>postscriptFontName</key>
+ <string>PsfTest-Italic</string>
+ <key>postscriptFullName</key>
+ <string>Psf Test Italic</string>
+ <key>postscriptStemSnapH</key>
+ <array>
+ <integer>140</integer>
+ <integer>145</integer>
+ <integer>150</integer>
+ <integer>155</integer>
+ <integer>160</integer>
+ <integer>165</integer>
+ <integer>170</integer>
+ <integer>175</integer>
+ <integer>185</integer>
+ <integer>270</integer>
+ </array>
+ <key>postscriptStemSnapV</key>
+ <array>
+ <integer>165</integer>
+ <integer>180</integer>
+ <integer>185</integer>
+ <integer>190</integer>
+ <integer>195</integer>
+ <integer>200</integer>
+ <integer>205</integer>
+ <integer>270</integer>
+ </array>
+ <key>postscriptUnderlinePosition</key>
+ <integer>-110</integer>
+ <key>postscriptUnderlineThickness</key>
+ <integer>80</integer>
+ <key>styleMapFamilyName</key>
+ <string>Psf Test</string>
+ <key>styleMapStyleName</key>
+ <string>italic</string>
+ <key>styleName</key>
+ <string>Italic</string>
+ <key>trademark</key>
+ <string>Andika is a trademark of SIL International.</string>
+ <key>unitsPerEm</key>
+ <integer>2048</integer>
+ <key>versionMajor</key>
+ <integer>5</integer>
+ <key>versionMinor</key>
+ <integer>550</integer>
+ <key>xHeight</key>
+ <integer>1040</integer>
+</dict>
+</plist>
diff --git a/tests/reference/ufo/psfnormalize.ufo/glyphs/A_mpersand.glif b/tests/reference/ufo/psfnormalize.ufo/glyphs/A_mpersand.glif
new file mode 100644
index 0000000..689cb3e
--- /dev/null
+++ b/tests/reference/ufo/psfnormalize.ufo/glyphs/A_mpersand.glif
@@ -0,0 +1,61 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="Ampersand" format="2">
+ <advance width="1202"/>
+ <unicode hex="0026"/>
+ <outline>
+ <contour>
+ <point x="1054" y="559" type="line"/>
+ <point x="949" y="395"/>
+ <point x="616" y="147"/>
+ <point x="441" y="147" type="curve" smooth="yes"/>
+ <point x="318" y="147"/>
+ <point x="256" y="224"/>
+ <point x="256" y="314" type="curve" smooth="yes"/>
+ <point x="256" y="453"/>
+ <point x="369" y="575"/>
+ <point x="590" y="725" type="curve" smooth="yes"/>
+ <point x="836" y="892"/>
+ <point x="1022" y="1067"/>
+ <point x="1022" y="1223" type="curve" smooth="yes"/>
+ <point x="1022" y="1363"/>
+ <point x="894" y="1455"/>
+ <point x="762" y="1455" type="curve" smooth="yes"/>
+ <point x="504" y="1455"/>
+ <point x="378" y="1328"/>
+ <point x="378" y="1114" type="curve" smooth="yes"/>
+ <point x="378" y="953"/>
+ <point x="514" y="771"/>
+ <point x="614" y="559" type="curve" smooth="yes"/>
+ <point x="783" y="198"/>
+ <point x="906" y="-25"/>
+ <point x="958" y="-25" type="curve" smooth="yes"/>
+ <point x="993" y="-25"/>
+ <point x="1087" y="37"/>
+ <point x="1132" y="69" type="curve"/>
+ <point x="1046" y="108"/>
+ <point x="926" y="291"/>
+ <point x="756" y="666" type="curve" smooth="yes"/>
+ <point x="665" y="866"/>
+ <point x="544" y="1029"/>
+ <point x="544" y="1149" type="curve" smooth="yes"/>
+ <point x="544" y="1252"/>
+ <point x="632" y="1323"/>
+ <point x="724" y="1323" type="curve" smooth="yes"/>
+ <point x="794" y="1323"/>
+ <point x="858" y="1266"/>
+ <point x="858" y="1193" type="curve" smooth="yes"/>
+ <point x="858" y="1107"/>
+ <point x="743" y="1004"/>
+ <point x="492" y="826" type="curve" smooth="yes"/>
+ <point x="182" y="606"/>
+ <point x="73" y="439"/>
+ <point x="73" y="288" type="curve" smooth="yes"/>
+ <point x="73" y="113"/>
+ <point x="195" y="-25"/>
+ <point x="383" y="-25" type="curve" smooth="yes"/>
+ <point x="656" y="-25"/>
+ <point x="1009" y="269"/>
+ <point x="1126" y="426" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfnormalize.ufo/glyphs/A_pos.glif b/tests/reference/ufo/psfnormalize.ufo/glyphs/A_pos.glif
new file mode 100644
index 0000000..deb1650
--- /dev/null
+++ b/tests/reference/ufo/psfnormalize.ufo/glyphs/A_pos.glif
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="Apos" format="2">
+ <advance width="585"/>
+ <unicode hex="0027"/>
+ <outline>
+ <contour>
+ <point x="560" y="1024" type="line"/>
+ <point x="599" y="1162"/>
+ <point x="643" y="1312"/>
+ <point x="732" y="1553" type="curve"/>
+ <point x="527" y="1553" type="line"/>
+ <point x="498" y="1312"/>
+ <point x="465" y="1162"/>
+ <point x="435" y="1024" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfnormalize.ufo/glyphs/A_sterisk.glif b/tests/reference/ufo/psfnormalize.ufo/glyphs/A_sterisk.glif
new file mode 100644
index 0000000..3027a5d
--- /dev/null
+++ b/tests/reference/ufo/psfnormalize.ufo/glyphs/A_sterisk.glif
@@ -0,0 +1,51 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="Asterisk" format="2">
+ <advance width="1008"/>
+ <unicode hex="002A"/>
+ <outline>
+ <contour>
+ <point x="745" y="1568" type="line"/>
+ <point x="733" y="1438"/>
+ <point x="725" y="1359"/>
+ <point x="707" y="1274" type="curve"/>
+ <point x="644" y="1317"/>
+ <point x="587" y="1359"/>
+ <point x="498" y="1436" type="curve"/>
+ <point x="392" y="1313" type="line"/>
+ <point x="505" y="1264"/>
+ <point x="575" y="1236"/>
+ <point x="643" y="1196" type="curve"/>
+ <point x="556" y="1153"/>
+ <point x="474" y="1117"/>
+ <point x="340" y="1063" type="curve"/>
+ <point x="379" y="941" type="line"/>
+ <point x="504" y="1021"/>
+ <point x="584" y="1072"/>
+ <point x="668" y="1117" type="curve"/>
+ <point x="645" y="1034"/>
+ <point x="619" y="954"/>
+ <point x="575" y="823" type="curve"/>
+ <point x="715" y="823" type="line"/>
+ <point x="727" y="954"/>
+ <point x="741" y="1031"/>
+ <point x="758" y="1117" type="curve"/>
+ <point x="821" y="1073"/>
+ <point x="878" y="1032"/>
+ <point x="968" y="956" type="curve"/>
+ <point x="1073" y="1078" type="line"/>
+ <point x="959" y="1126"/>
+ <point x="890" y="1155"/>
+ <point x="823" y="1196" type="curve"/>
+ <point x="909" y="1236"/>
+ <point x="990" y="1273"/>
+ <point x="1126" y="1328" type="curve"/>
+ <point x="1086" y="1450" type="line"/>
+ <point x="961" y="1368"/>
+ <point x="883" y="1321"/>
+ <point x="797" y="1274" type="curve"/>
+ <point x="819" y="1359"/>
+ <point x="845" y="1438"/>
+ <point x="890" y="1568" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfnormalize.ufo/glyphs/A_tS_gn.glif b/tests/reference/ufo/psfnormalize.ufo/glyphs/A_tS_gn.glif
new file mode 100644
index 0000000..2cd2542
--- /dev/null
+++ b/tests/reference/ufo/psfnormalize.ufo/glyphs/A_tS_gn.glif
@@ -0,0 +1,104 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="AtSgn" format="2">
+ <advance width="1682"/>
+ <unicode hex="0040"/>
+ <outline>
+ <contour>
+ <point x="1082" y="-10" type="line"/>
+ <point x="980" y="-69"/>
+ <point x="889" y="-93"/>
+ <point x="796" y="-93" type="curve" smooth="yes"/>
+ <point x="507" y="-93"/>
+ <point x="301" y="104"/>
+ <point x="301" y="414" type="curve" smooth="yes"/>
+ <point x="301" y="476"/>
+ <point x="309" y="543"/>
+ <point x="327" y="613" type="curve" smooth="yes"/>
+ <point x="425" y="1003"/>
+ <point x="782" y="1245"/>
+ <point x="1110" y="1245" type="curve" smooth="yes"/>
+ <point x="1433" y="1245"/>
+ <point x="1590" y="1060"/>
+ <point x="1590" y="813" type="curve" smooth="yes"/>
+ <point x="1590" y="760"/>
+ <point x="1582" y="705"/>
+ <point x="1568" y="647" type="curve" smooth="yes"/>
+ <point x="1510" y="413"/>
+ <point x="1365" y="309"/>
+ <point x="1297" y="309" type="curve" smooth="yes"/>
+ <point x="1261" y="309"/>
+ <point x="1238" y="344"/>
+ <point x="1238" y="420" type="curve" smooth="yes"/>
+ <point x="1238" y="468"/>
+ <point x="1247" y="533"/>
+ <point x="1268" y="617" type="curve" smooth="yes"/>
+ <point x="1354" y="960" type="line"/>
+ <point x="1276" y="995"/>
+ <point x="1155" y="1019"/>
+ <point x="1074" y="1019" type="curve" smooth="yes"/>
+ <point x="910" y="1019"/>
+ <point x="790" y="962"/>
+ <point x="673" y="828" type="curve" smooth="yes"/>
+ <point x="607" y="751"/>
+ <point x="554" y="650"/>
+ <point x="524" y="529" type="curve" smooth="yes"/>
+ <point x="514" y="488"/>
+ <point x="509" y="450"/>
+ <point x="509" y="416" type="curve" smooth="yes"/>
+ <point x="509" y="259"/>
+ <point x="609" y="179"/>
+ <point x="719" y="179" type="curve" smooth="yes"/>
+ <point x="836" y="179"/>
+ <point x="1017" y="359"/>
+ <point x="1099" y="480" type="curve"/>
+ <point x="1093" y="446"/>
+ <point x="1089" y="413"/>
+ <point x="1089" y="382" type="curve" smooth="yes"/>
+ <point x="1089" y="264"/>
+ <point x="1136" y="176"/>
+ <point x="1233" y="176" type="curve" smooth="yes"/>
+ <point x="1408" y="176"/>
+ <point x="1635" y="331"/>
+ <point x="1716" y="656" type="curve" smooth="yes"/>
+ <point x="1732" y="722"/>
+ <point x="1740" y="784"/>
+ <point x="1740" y="843" type="curve" smooth="yes"/>
+ <point x="1740" y="1161"/>
+ <point x="1513" y="1377"/>
+ <point x="1153" y="1377" type="curve" smooth="yes"/>
+ <point x="738" y="1377"/>
+ <point x="310" y="1143"/>
+ <point x="175" y="603" type="curve" smooth="yes"/>
+ <point x="155" y="522"/>
+ <point x="145" y="446"/>
+ <point x="145" y="375" type="curve" smooth="yes"/>
+ <point x="145" y="-5"/>
+ <point x="417" y="-230"/>
+ <point x="747" y="-230" type="curve" smooth="yes"/>
+ <point x="882" y="-230"/>
+ <point x="1044" y="-184"/>
+ <point x="1161" y="-116" type="curve"/>
+ </contour>
+ <contour>
+ <point x="1141" y="706" type="line"/>
+ <point x="1075" y="570"/>
+ <point x="856" y="314"/>
+ <point x="766" y="314" type="curve" smooth="yes"/>
+ <point x="712" y="314"/>
+ <point x="669" y="362"/>
+ <point x="669" y="459" type="curve" smooth="yes"/>
+ <point x="669" y="491"/>
+ <point x="674" y="530"/>
+ <point x="685" y="573" type="curve" smooth="yes"/>
+ <point x="704" y="649"/>
+ <point x="739" y="726"/>
+ <point x="780" y="774" type="curve" smooth="yes"/>
+ <point x="859" y="868"/>
+ <point x="943" y="887"/>
+ <point x="1011" y="887" type="curve" smooth="yes"/>
+ <point x="1085" y="887"/>
+ <point x="1148" y="868"/>
+ <point x="1177" y="853" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfnormalize.ufo/glyphs/C_ircumA_ccent.glif b/tests/reference/ufo/psfnormalize.ufo/glyphs/C_ircumA_ccent.glif
new file mode 100644
index 0000000..91ab811
--- /dev/null
+++ b/tests/reference/ufo/psfnormalize.ufo/glyphs/C_ircumA_ccent.glif
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="CircumAccent" format="2">
+ <advance width="830"/>
+ <unicode hex="005E"/>
+ <anchor x="705" y="1635" name="U"/>
+ <outline>
+ <contour>
+ <point x="316" y="1147" type="line"/>
+ <point x="660" y="1421" type="line"/>
+ <point x="866" y="1147" type="line"/>
+ <point x="1015" y="1147" type="line"/>
+ <point x="761" y="1568" type="line"/>
+ <point x="591" y="1568" type="line"/>
+ <point x="166" y="1147" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfnormalize.ufo/glyphs/C_olon.glif b/tests/reference/ufo/psfnormalize.ufo/glyphs/C_olon.glif
new file mode 100644
index 0000000..bcccfc2
--- /dev/null
+++ b/tests/reference/ufo/psfnormalize.ufo/glyphs/C_olon.glif
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="Colon" format="2">
+ <advance width="620"/>
+ <unicode hex="003A"/>
+ <outline>
+ <contour>
+ <point x="314" y="758" type="curve" smooth="yes"/>
+ <point x="314" y="696"/>
+ <point x="365" y="642"/>
+ <point x="430" y="642" type="curve" smooth="yes"/>
+ <point x="514" y="642"/>
+ <point x="590" y="712"/>
+ <point x="590" y="792" type="curve" smooth="yes"/>
+ <point x="590" y="854"/>
+ <point x="540" y="907"/>
+ <point x="476" y="907" type="curve" smooth="yes"/>
+ <point x="393" y="907"/>
+ <point x="314" y="837"/>
+ </contour>
+ <contour>
+ <point x="148" y="90" type="curve" smooth="yes"/>
+ <point x="148" y="28"/>
+ <point x="198" y="-25"/>
+ <point x="263" y="-25" type="curve" smooth="yes"/>
+ <point x="347" y="-25"/>
+ <point x="424" y="45"/>
+ <point x="424" y="125" type="curve" smooth="yes"/>
+ <point x="424" y="186"/>
+ <point x="374" y="240"/>
+ <point x="309" y="240" type="curve" smooth="yes"/>
+ <point x="225" y="240"/>
+ <point x="148" y="170"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfnormalize.ufo/glyphs/C_ombA_cute.glif b/tests/reference/ufo/psfnormalize.ufo/glyphs/C_ombA_cute.glif
new file mode 100644
index 0000000..a7607fe
--- /dev/null
+++ b/tests/reference/ufo/psfnormalize.ufo/glyphs/C_ombA_cute.glif
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="CombAcute" format="2">
+ <unicode hex="0301"/>
+ <anchor x="-221" y="1635" name="U"/>
+ <anchor x="-355" y="1100" name="_U"/>
+ <outline>
+ <contour>
+ <point x="-99" y="1568" type="line"/>
+ <point x="-524" y="1147" type="line"/>
+ <point x="-354" y="1147" type="line"/>
+ <point x="150" y="1568" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfnormalize.ufo/glyphs/C_ombC_ircum.glif b/tests/reference/ufo/psfnormalize.ufo/glyphs/C_ombC_ircum.glif
new file mode 100644
index 0000000..6614f85
--- /dev/null
+++ b/tests/reference/ufo/psfnormalize.ufo/glyphs/C_ombC_ircum.glif
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="CombCircum" format="2">
+ <unicode hex="0302"/>
+ <anchor x="-221" y="1635" name="U"/>
+ <anchor x="-320" y="1100" name="_U"/>
+ <outline>
+ <contour>
+ <point x="-619" y="1147" type="line"/>
+ <point x="-275" y="1421" type="line"/>
+ <point x="-69" y="1147" type="line"/>
+ <point x="80" y="1147" type="line"/>
+ <point x="-174" y="1568" type="line"/>
+ <point x="-344" y="1568" type="line"/>
+ <point x="-769" y="1147" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfnormalize.ufo/glyphs/C_ombD_iaer.glif b/tests/reference/ufo/psfnormalize.ufo/glyphs/C_ombD_iaer.glif
new file mode 100644
index 0000000..d6b35b7
--- /dev/null
+++ b/tests/reference/ufo/psfnormalize.ufo/glyphs/C_ombD_iaer.glif
@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="CombDiaer" format="2">
+ <unicode hex="0308"/>
+ <anchor x="-253" y="1505" name="U"/>
+ <anchor x="-350" y="1100" name="_U"/>
+ <outline>
+ <contour>
+ <point x="39" y="1338" type="curve" smooth="yes"/>
+ <point x="39" y="1399"/>
+ <point x="-7" y="1450"/>
+ <point x="-72" y="1450" type="curve" smooth="yes"/>
+ <point x="-167" y="1450"/>
+ <point x="-229" y="1372"/>
+ <point x="-229" y="1299" type="curve" smooth="yes"/>
+ <point x="-229" y="1238"/>
+ <point x="-182" y="1186"/>
+ <point x="-118" y="1186" type="curve" smooth="yes"/>
+ <point x="-33" y="1186"/>
+ <point x="39" y="1259"/>
+ </contour>
+ <contour>
+ <point x="-381" y="1338" type="curve" smooth="yes"/>
+ <point x="-381" y="1399"/>
+ <point x="-427" y="1450"/>
+ <point x="-492" y="1450" type="curve" smooth="yes"/>
+ <point x="-587" y="1450"/>
+ <point x="-649" y="1372"/>
+ <point x="-649" y="1299" type="curve" smooth="yes"/>
+ <point x="-649" y="1238"/>
+ <point x="-602" y="1186"/>
+ <point x="-538" y="1186" type="curve" smooth="yes"/>
+ <point x="-453" y="1186"/>
+ <point x="-381" y="1259"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfnormalize.ufo/glyphs/C_ombG_rave.glif b/tests/reference/ufo/psfnormalize.ufo/glyphs/C_ombG_rave.glif
new file mode 100644
index 0000000..8869bb9
--- /dev/null
+++ b/tests/reference/ufo/psfnormalize.ufo/glyphs/C_ombG_rave.glif
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="CombGrave" format="2">
+ <unicode hex="0300"/>
+ <anchor x="-201" y="1635" name="U"/>
+ <anchor x="-335" y="1100" name="_U"/>
+ <outline>
+ <contour>
+ <point x="-619" y="1568" type="line"/>
+ <point x="-284" y="1147" type="line"/>
+ <point x="-134" y="1147" type="line"/>
+ <point x="-409" y="1568" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfnormalize.ufo/glyphs/C_ombR_ingA_bv.glif b/tests/reference/ufo/psfnormalize.ufo/glyphs/C_ombR_ingA_bv.glif
new file mode 100644
index 0000000..38232a0
--- /dev/null
+++ b/tests/reference/ufo/psfnormalize.ufo/glyphs/C_ombR_ingA_bv.glif
@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="CombRingAbv" format="2">
+ <unicode hex="030A"/>
+ <anchor x="-221" y="1635" name="U"/>
+ <anchor x="-385" y="1100" name="_U"/>
+ <outline>
+ <contour>
+ <point x="-377" y="1259" type="curve" smooth="yes"/>
+ <point x="-427" y="1259"/>
+ <point x="-456" y="1287"/>
+ <point x="-456" y="1329" type="curve" smooth="yes"/>
+ <point x="-456" y="1400"/>
+ <point x="-393" y="1455"/>
+ <point x="-328" y="1455" type="curve" smooth="yes"/>
+ <point x="-278" y="1455"/>
+ <point x="-248" y="1428"/>
+ <point x="-248" y="1385" type="curve" smooth="yes"/>
+ <point x="-248" y="1314"/>
+ <point x="-312" y="1259"/>
+ </contour>
+ <contour>
+ <point x="-573" y="1320" type="curve" smooth="yes"/>
+ <point x="-573" y="1224"/>
+ <point x="-498" y="1147"/>
+ <point x="-395" y="1147" type="curve" smooth="yes"/>
+ <point x="-257" y="1147"/>
+ <point x="-131" y="1263"/>
+ <point x="-131" y="1394" type="curve" smooth="yes"/>
+ <point x="-131" y="1491"/>
+ <point x="-206" y="1568"/>
+ <point x="-310" y="1568" type="curve" smooth="yes"/>
+ <point x="-448" y="1568"/>
+ <point x="-573" y="1451"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfnormalize.ufo/glyphs/C_ombT_ilde.glif b/tests/reference/ufo/psfnormalize.ufo/glyphs/C_ombT_ilde.glif
new file mode 100644
index 0000000..f79322e
--- /dev/null
+++ b/tests/reference/ufo/psfnormalize.ufo/glyphs/C_ombT_ilde.glif
@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="CombTilde" format="2">
+ <unicode hex="0303"/>
+ <anchor x="-290" y="1475" name="U"/>
+ <anchor x="-385" y="1100" name="_U"/>
+ <outline>
+ <contour>
+ <point x="-646" y="1181" type="line"/>
+ <point x="-629" y="1229"/>
+ <point x="-589" y="1269"/>
+ <point x="-540" y="1269" type="curve" smooth="yes"/>
+ <point x="-503" y="1269"/>
+ <point x="-466" y="1253"/>
+ <point x="-398" y="1218" type="curve" smooth="yes"/>
+ <point x="-344" y="1190"/>
+ <point x="-296" y="1171"/>
+ <point x="-243" y="1171" type="curve" smooth="yes"/>
+ <point x="-120" y="1171"/>
+ <point x="-15" y="1286"/>
+ <point x="16" y="1411" type="curve"/>
+ <point x="-89" y="1411" type="line"/>
+ <point x="-107" y="1366"/>
+ <point x="-147" y="1323"/>
+ <point x="-194" y="1323" type="curve" smooth="yes"/>
+ <point x="-236" y="1323"/>
+ <point x="-273" y="1342"/>
+ <point x="-338" y="1370" type="curve" smooth="yes"/>
+ <point x="-401" y="1397"/>
+ <point x="-442" y="1421"/>
+ <point x="-498" y="1421" type="curve" smooth="yes"/>
+ <point x="-617" y="1421"/>
+ <point x="-721" y="1300"/>
+ <point x="-751" y="1181" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfnormalize.ufo/glyphs/C_omma.glif b/tests/reference/ufo/psfnormalize.ufo/glyphs/C_omma.glif
new file mode 100644
index 0000000..eaff517
--- /dev/null
+++ b/tests/reference/ufo/psfnormalize.ufo/glyphs/C_omma.glif
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="Comma" format="2">
+ <advance width="630"/>
+ <unicode hex="002C"/>
+ <outline>
+ <contour>
+ <point x="137" y="49" type="line"/>
+ <point x="277" y="49" type="line"/>
+ <point x="252" y="-50"/>
+ <point x="145" y="-169"/>
+ <point x="73" y="-225" type="curve"/>
+ <point x="163" y="-265" type="line"/>
+ <point x="280" y="-175"/>
+ <point x="431" y="-28"/>
+ <point x="431" y="118" type="curve" smooth="yes"/>
+ <point x="431" y="193"/>
+ <point x="378" y="245"/>
+ <point x="311" y="245" type="curve" smooth="yes"/>
+ <point x="254" y="245"/>
+ <point x="190" y="209"/>
+ <point x="161" y="147" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfnormalize.ufo/glyphs/D_igitE_ight.glif b/tests/reference/ufo/psfnormalize.ufo/glyphs/D_igitE_ight.glif
new file mode 100644
index 0000000..262f860
--- /dev/null
+++ b/tests/reference/ufo/psfnormalize.ufo/glyphs/D_igitE_ight.glif
@@ -0,0 +1,63 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="DigitEight" format="2">
+ <advance width="1180"/>
+ <unicode hex="0038"/>
+ <anchor x="515" y="-100" name="L"/>
+ <anchor x="922" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="542" y="-25" type="curve" smooth="yes"/>
+ <point x="839" y="-25"/>
+ <point x="1160" y="170"/>
+ <point x="1160" y="475" type="curve" smooth="yes"/>
+ <point x="1160" y="626"/>
+ <point x="1068" y="733"/>
+ <point x="988" y="779" type="curve"/>
+ <point x="1155" y="860"/>
+ <point x="1270" y="970"/>
+ <point x="1270" y="1151" type="curve" smooth="yes"/>
+ <point x="1270" y="1340"/>
+ <point x="1102" y="1455"/>
+ <point x="901" y="1455" type="curve" smooth="yes"/>
+ <point x="620" y="1455"/>
+ <point x="348" y="1292"/>
+ <point x="348" y="1018" type="curve" smooth="yes"/>
+ <point x="348" y="891"/>
+ <point x="427" y="814"/>
+ <point x="483" y="779" type="curve"/>
+ <point x="297" y="706"/>
+ <point x="115" y="549"/>
+ <point x="115" y="325" type="curve" smooth="yes"/>
+ <point x="115" y="111"/>
+ <point x="317" y="-25"/>
+ </contour>
+ <contour>
+ <point x="750" y="848" type="curve" smooth="yes"/>
+ <point x="628" y="848"/>
+ <point x="541" y="917"/>
+ <point x="541" y="1029" type="curve" smooth="yes"/>
+ <point x="541" y="1205"/>
+ <point x="704" y="1299"/>
+ <point x="862" y="1299" type="curve" smooth="yes"/>
+ <point x="985" y="1299"/>
+ <point x="1076" y="1235"/>
+ <point x="1076" y="1128" type="curve" smooth="yes"/>
+ <point x="1076" y="955"/>
+ <point x="907" y="848"/>
+ </contour>
+ <contour>
+ <point x="564" y="142" type="curve" smooth="yes"/>
+ <point x="413" y="142"/>
+ <point x="322" y="225"/>
+ <point x="322" y="350" type="curve" smooth="yes"/>
+ <point x="322" y="557"/>
+ <point x="520" y="696"/>
+ <point x="712" y="696" type="curve" smooth="yes"/>
+ <point x="864" y="696"/>
+ <point x="961" y="602"/>
+ <point x="961" y="476" type="curve" smooth="yes"/>
+ <point x="961" y="266"/>
+ <point x="753" y="142"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfnormalize.ufo/glyphs/D_igitF_ive.glif b/tests/reference/ufo/psfnormalize.ufo/glyphs/D_igitF_ive.glif
new file mode 100644
index 0000000..a224838
--- /dev/null
+++ b/tests/reference/ufo/psfnormalize.ufo/glyphs/D_igitF_ive.glif
@@ -0,0 +1,44 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="DigitFive" format="2">
+ <advance width="1180"/>
+ <unicode hex="0035"/>
+ <anchor x="515" y="-100" name="L"/>
+ <anchor x="922" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="1296" y="1431" type="line"/>
+ <point x="491" y="1431" type="line"/>
+ <point x="302" y="671" type="line"/>
+ <point x="438" y="718"/>
+ <point x="537" y="735"/>
+ <point x="643" y="735" type="curve" smooth="yes"/>
+ <point x="784" y="735"/>
+ <point x="933" y="660"/>
+ <point x="933" y="508" type="curve" smooth="yes"/>
+ <point x="933" y="273"/>
+ <point x="710" y="152"/>
+ <point x="497" y="152" type="curve" smooth="yes"/>
+ <point x="357" y="152"/>
+ <point x="263" y="195"/>
+ <point x="170" y="284" type="curve"/>
+ <point x="89" y="78" type="line"/>
+ <point x="195" y="2"/>
+ <point x="326" y="-25"/>
+ <point x="481" y="-25" type="curve" smooth="yes"/>
+ <point x="807" y="-25"/>
+ <point x="1129" y="190"/>
+ <point x="1129" y="546" type="curve" smooth="yes"/>
+ <point x="1129" y="757"/>
+ <point x="951" y="911"/>
+ <point x="702" y="911" type="curve" smooth="yes"/>
+ <point x="629" y="911"/>
+ <point x="576" y="906"/>
+ <point x="544" y="902" type="curve"/>
+ <point x="635" y="1264" type="line"/>
+ <point x="1020" y="1264" type="line" smooth="yes"/>
+ <point x="1104" y="1264"/>
+ <point x="1179" y="1260"/>
+ <point x="1250" y="1245" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfnormalize.ufo/glyphs/D_igitF_our.glif b/tests/reference/ufo/psfnormalize.ufo/glyphs/D_igitF_our.glif
new file mode 100644
index 0000000..eeccb48
--- /dev/null
+++ b/tests/reference/ufo/psfnormalize.ufo/glyphs/D_igitF_our.glif
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="DigitFour" format="2">
+ <advance width="1180"/>
+ <unicode hex="0034"/>
+ <anchor x="522" y="-100" name="L"/>
+ <anchor x="929" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="1161" y="387" type="line"/>
+ <point x="1199" y="539" type="line"/>
+ <point x="1009" y="539" type="line"/>
+ <point x="1236" y="1450" type="line"/>
+ <point x="1026" y="1450" type="line"/>
+ <point x="144" y="539" type="line"/>
+ <point x="106" y="387" type="line"/>
+ <point x="781" y="387" type="line"/>
+ <point x="685" y="0" type="line"/>
+ <point x="875" y="0" type="line"/>
+ <point x="971" y="387" type="line"/>
+ </contour>
+ <contour>
+ <point x="985" y="1205" type="line"/>
+ <point x="819" y="539" type="line"/>
+ <point x="337" y="539" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfnormalize.ufo/glyphs/D_igitN_ine.glif b/tests/reference/ufo/psfnormalize.ufo/glyphs/D_igitN_ine.glif
new file mode 100644
index 0000000..191cd79
--- /dev/null
+++ b/tests/reference/ufo/psfnormalize.ufo/glyphs/D_igitN_ine.glif
@@ -0,0 +1,49 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="DigitNine" format="2">
+ <advance width="1180"/>
+ <unicode hex="0039"/>
+ <anchor x="515" y="-100" name="L"/>
+ <anchor x="922" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="157" y="94" type="line"/>
+ <point x="208" y="29"/>
+ <point x="355" y="-25"/>
+ <point x="473" y="-25" type="curve" smooth="yes"/>
+ <point x="999" y="-25"/>
+ <point x="1267" y="520"/>
+ <point x="1267" y="982" type="curve" smooth="yes"/>
+ <point x="1267" y="1248"/>
+ <point x="1127" y="1455"/>
+ <point x="866" y="1455" type="curve" smooth="yes"/>
+ <point x="596" y="1455"/>
+ <point x="303" y="1269"/>
+ <point x="303" y="932" type="curve" smooth="yes"/>
+ <point x="303" y="761"/>
+ <point x="425" y="574"/>
+ <point x="661" y="574" type="curve" smooth="yes"/>
+ <point x="852" y="574"/>
+ <point x="1036" y="683"/>
+ <point x="1172" y="840" type="curve"/>
+ <point x="1121" y="922" type="line"/>
+ <point x="1019" y="810"/>
+ <point x="872" y="745"/>
+ <point x="717" y="745" type="curve" smooth="yes"/>
+ <point x="584" y="745"/>
+ <point x="498" y="833"/>
+ <point x="498" y="956" type="curve" smooth="yes"/>
+ <point x="498" y="1146"/>
+ <point x="638" y="1284"/>
+ <point x="821" y="1284" type="curve" smooth="yes"/>
+ <point x="998" y="1284"/>
+ <point x="1073" y="1119"/>
+ <point x="1073" y="956" type="curve" smooth="yes"/>
+ <point x="1073" y="455"/>
+ <point x="760" y="147"/>
+ <point x="496" y="147" type="curve" smooth="yes"/>
+ <point x="410" y="147"/>
+ <point x="298" y="209"/>
+ <point x="249" y="285" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfnormalize.ufo/glyphs/D_igitO_ne.glif b/tests/reference/ufo/psfnormalize.ufo/glyphs/D_igitO_ne.glif
new file mode 100644
index 0000000..a639774
--- /dev/null
+++ b/tests/reference/ufo/psfnormalize.ufo/glyphs/D_igitO_ne.glif
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="DigitOne" format="2">
+ <advance width="1180"/>
+ <unicode hex="0031"/>
+ <anchor x="515" y="-100" name="L"/>
+ <anchor x="922" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="1021" y="167" type="line"/>
+ <point x="706" y="167" type="line"/>
+ <point x="1026" y="1450" type="line"/>
+ <point x="856" y="1450" type="line"/>
+ <point x="459" y="1243" type="line"/>
+ <point x="440" y="1066" type="line"/>
+ <point x="782" y="1235" type="line"/>
+ <point x="516" y="167" type="line"/>
+ <point x="201" y="167" type="line"/>
+ <point x="160" y="0" type="line"/>
+ <point x="980" y="0" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfnormalize.ufo/glyphs/D_igitS_even.glif b/tests/reference/ufo/psfnormalize.ufo/glyphs/D_igitS_even.glif
new file mode 100644
index 0000000..68c6ef6
--- /dev/null
+++ b/tests/reference/ufo/psfnormalize.ufo/glyphs/D_igitS_even.glif
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="DigitSeven" format="2">
+ <advance width="1180"/>
+ <unicode hex="0037"/>
+ <anchor x="515" y="-100" name="L"/>
+ <anchor x="922" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="420" y="0" type="line"/>
+ <point x="661" y="450"/>
+ <point x="972" y="877"/>
+ <point x="1367" y="1274" type="curve"/>
+ <point x="1406" y="1431" type="line"/>
+ <point x="386" y="1431" type="line"/>
+ <point x="341" y="1245" type="line"/>
+ <point x="421" y="1260"/>
+ <point x="538" y="1264"/>
+ <point x="726" y="1264" type="curve" smooth="yes"/>
+ <point x="1126" y="1264" type="line"/>
+ <point x="774" y="889"/>
+ <point x="517" y="555"/>
+ <point x="215" y="0" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfnormalize.ufo/glyphs/D_igitS_ix.glif b/tests/reference/ufo/psfnormalize.ufo/glyphs/D_igitS_ix.glif
new file mode 100644
index 0000000..b6be793
--- /dev/null
+++ b/tests/reference/ufo/psfnormalize.ufo/glyphs/D_igitS_ix.glif
@@ -0,0 +1,49 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="DigitSix" format="2">
+ <advance width="1180"/>
+ <unicode hex="0036"/>
+ <anchor x="515" y="-100" name="L"/>
+ <anchor x="922" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="1313" y="1347" type="line"/>
+ <point x="1248" y="1418"/>
+ <point x="1135" y="1455"/>
+ <point x="1017" y="1455" type="curve" smooth="yes"/>
+ <point x="481" y="1454"/>
+ <point x="208" y="915"/>
+ <point x="208" y="475" type="curve" smooth="yes"/>
+ <point x="208" y="167"/>
+ <point x="392" y="-25"/>
+ <point x="623" y="-25" type="curve" smooth="yes"/>
+ <point x="947" y="-25"/>
+ <point x="1183" y="169"/>
+ <point x="1183" y="517" type="curve" smooth="yes"/>
+ <point x="1183" y="709"/>
+ <point x="1029" y="887"/>
+ <point x="793" y="887" type="curve" smooth="yes"/>
+ <point x="636" y="887"/>
+ <point x="432" y="784"/>
+ <point x="317" y="633" type="curve"/>
+ <point x="364" y="559" type="line"/>
+ <point x="471" y="660"/>
+ <point x="596" y="716"/>
+ <point x="751" y="716" type="curve" smooth="yes"/>
+ <point x="898" y="716"/>
+ <point x="987" y="614"/>
+ <point x="987" y="454" type="curve" smooth="yes"/>
+ <point x="987" y="263"/>
+ <point x="816" y="147"/>
+ <point x="656" y="147" type="curve" smooth="yes"/>
+ <point x="491" y="147"/>
+ <point x="403" y="284"/>
+ <point x="403" y="472" type="curve" smooth="yes"/>
+ <point x="403" y="962"/>
+ <point x="664" y="1284"/>
+ <point x="985" y="1284" type="curve" smooth="yes"/>
+ <point x="1081" y="1284"/>
+ <point x="1174" y="1235"/>
+ <point x="1222" y="1156" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfnormalize.ufo/glyphs/D_igitT_hree.glif b/tests/reference/ufo/psfnormalize.ufo/glyphs/D_igitT_hree.glif
new file mode 100644
index 0000000..e01df2c
--- /dev/null
+++ b/tests/reference/ufo/psfnormalize.ufo/glyphs/D_igitT_hree.glif
@@ -0,0 +1,52 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="DigitThree" format="2">
+ <advance width="1180"/>
+ <unicode hex="0033"/>
+ <anchor x="515" y="-100" name="L"/>
+ <anchor x="922" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="562" y="853" type="line"/>
+ <point x="521" y="686" type="line"/>
+ <point x="591" y="686" type="line" smooth="yes"/>
+ <point x="802" y="686"/>
+ <point x="944" y="606"/>
+ <point x="944" y="476" type="curve" smooth="yes"/>
+ <point x="944" y="268"/>
+ <point x="738" y="147"/>
+ <point x="551" y="147" type="curve" smooth="yes"/>
+ <point x="371" y="147"/>
+ <point x="260" y="227"/>
+ <point x="181" y="348" type="curve"/>
+ <point x="104" y="137" type="line"/>
+ <point x="185" y="41"/>
+ <point x="341" y="-25"/>
+ <point x="518" y="-25" type="curve" smooth="yes"/>
+ <point x="815" y="-25"/>
+ <point x="1141" y="168"/>
+ <point x="1141" y="475" type="curve" smooth="yes"/>
+ <point x="1141" y="670"/>
+ <point x="973" y="763"/>
+ <point x="855" y="784" type="curve"/>
+ <point x="1046" y="827"/>
+ <point x="1266" y="955"/>
+ <point x="1266" y="1163" type="curve" smooth="yes"/>
+ <point x="1266" y="1338"/>
+ <point x="1073" y="1455"/>
+ <point x="852" y="1455" type="curve" smooth="yes"/>
+ <point x="685" y="1455"/>
+ <point x="536" y="1388"/>
+ <point x="433" y="1299" type="curve"/>
+ <point x="427" y="1132" type="line"/>
+ <point x="568" y="1246"/>
+ <point x="696" y="1284"/>
+ <point x="850" y="1284" type="curve" smooth="yes"/>
+ <point x="957" y="1284"/>
+ <point x="1068" y="1236"/>
+ <point x="1068" y="1137" type="curve" smooth="yes"/>
+ <point x="1068" y="949"/>
+ <point x="781" y="853"/>
+ <point x="632" y="853" type="curve" smooth="yes"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfnormalize.ufo/glyphs/D_igitT_wo.glif b/tests/reference/ufo/psfnormalize.ufo/glyphs/D_igitT_wo.glif
new file mode 100644
index 0000000..d1bbb54
--- /dev/null
+++ b/tests/reference/ufo/psfnormalize.ufo/glyphs/D_igitT_wo.glif
@@ -0,0 +1,37 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="DigitTwo" format="2">
+ <advance width="1180"/>
+ <unicode hex="0032"/>
+ <anchor x="515" y="-100" name="L"/>
+ <anchor x="882" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="1063" y="176" type="line"/>
+ <point x="980" y="163"/>
+ <point x="822" y="162"/>
+ <point x="625" y="162" type="curve" smooth="yes"/>
+ <point x="370" y="162" type="line"/>
+ <point x="783" y="393"/>
+ <point x="1210" y="830"/>
+ <point x="1210" y="1098" type="curve" smooth="yes"/>
+ <point x="1210" y="1296"/>
+ <point x="1075" y="1455"/>
+ <point x="842" y="1455" type="curve" smooth="yes"/>
+ <point x="673" y="1455"/>
+ <point x="488" y="1374"/>
+ <point x="380" y="1264" type="curve"/>
+ <point x="388" y="1098" type="line"/>
+ <point x="503" y="1203"/>
+ <point x="660" y="1279"/>
+ <point x="783" y="1279" type="curve" smooth="yes"/>
+ <point x="915" y="1279"/>
+ <point x="1003" y="1199"/>
+ <point x="1003" y="1063" type="curve" smooth="yes"/>
+ <point x="1003" y="848"/>
+ <point x="506" y="386"/>
+ <point x="101" y="167" type="curve"/>
+ <point x="60" y="0" type="line"/>
+ <point x="1020" y="0" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfnormalize.ufo/glyphs/D_igitZ_ero.glif b/tests/reference/ufo/psfnormalize.ufo/glyphs/D_igitZ_ero.glif
new file mode 100644
index 0000000..5d1bf0e
--- /dev/null
+++ b/tests/reference/ufo/psfnormalize.ufo/glyphs/D_igitZ_ero.glif
@@ -0,0 +1,49 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="DigitZero" format="2">
+ <advance width="1180"/>
+ <unicode hex="0030"/>
+ <anchor x="520" y="-100" name="L"/>
+ <anchor x="927" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="1024" y="711" type="curve" smooth="yes"/>
+ <point x="925" y="312"/>
+ <point x="747" y="142"/>
+ <point x="565" y="142" type="curve" smooth="yes"/>
+ <point x="432" y="142"/>
+ <point x="360" y="218"/>
+ <point x="360" y="383" type="curve" smooth="yes"/>
+ <point x="360" y="468"/>
+ <point x="377" y="579"/>
+ <point x="412" y="720" type="curve" smooth="yes"/>
+ <point x="512" y="1120"/>
+ <point x="678" y="1289"/>
+ <point x="871" y="1289" type="curve" smooth="yes"/>
+ <point x="1006" y="1289"/>
+ <point x="1077" y="1223"/>
+ <point x="1077" y="1051" type="curve" smooth="yes"/>
+ <point x="1077" y="966"/>
+ <point x="1060" y="854"/>
+ </contour>
+ <contour>
+ <point x="1230" y="715" type="curve" smooth="yes"/>
+ <point x="1262" y="841"/>
+ <point x="1276" y="949"/>
+ <point x="1276" y="1040" type="curve" smooth="yes"/>
+ <point x="1276" y="1335"/>
+ <point x="1124" y="1455"/>
+ <point x="902" y="1455" type="curve" smooth="yes"/>
+ <point x="613" y="1455"/>
+ <point x="344" y="1267"/>
+ <point x="206" y="716" type="curve" smooth="yes"/>
+ <point x="173" y="584"/>
+ <point x="158" y="474"/>
+ <point x="158" y="381" type="curve" smooth="yes"/>
+ <point x="158" y="104"/>
+ <point x="313" y="-25"/>
+ <point x="533" y="-25" type="curve" smooth="yes"/>
+ <point x="804" y="-25"/>
+ <point x="1086" y="138"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfnormalize.ufo/glyphs/D_ollarS_gn.glif b/tests/reference/ufo/psfnormalize.ufo/glyphs/D_ollarS_gn.glif
new file mode 100644
index 0000000..5c2db20
--- /dev/null
+++ b/tests/reference/ufo/psfnormalize.ufo/glyphs/D_ollarS_gn.glif
@@ -0,0 +1,53 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="DollarSgn" format="2">
+ <advance width="1180"/>
+ <unicode hex="0024"/>
+ <outline>
+ <contour>
+ <point x="1225" y="1280" type="line"/>
+ <point x="1119" y="1337"/>
+ <point x="1023" y="1361"/>
+ <point x="882" y="1361" type="curve" smooth="yes"/>
+ <point x="513" y="1361"/>
+ <point x="354" y="1182"/>
+ <point x="354" y="992" type="curve" smooth="yes"/>
+ <point x="354" y="837"/>
+ <point x="446" y="771"/>
+ <point x="639" y="650" type="curve" smooth="yes"/>
+ <point x="844" y="521"/>
+ <point x="919" y="439"/>
+ <point x="919" y="357" type="curve" smooth="yes"/>
+ <point x="919" y="244"/>
+ <point x="826" y="158"/>
+ <point x="635" y="158" type="curve" smooth="yes"/>
+ <point x="469" y="158"/>
+ <point x="314" y="266"/>
+ <point x="251" y="347" type="curve"/>
+ <point x="163" y="162" type="line"/>
+ <point x="304" y="58"/>
+ <point x="453" y="0"/>
+ <point x="606" y="0" type="curve" smooth="yes"/>
+ <point x="872" y="0"/>
+ <point x="1102" y="119"/>
+ <point x="1102" y="381" type="curve" smooth="yes"/>
+ <point x="1102" y="528"/>
+ <point x="981" y="657"/>
+ <point x="801" y="771" type="curve" smooth="yes"/>
+ <point x="610" y="892"/>
+ <point x="535" y="943"/>
+ <point x="535" y="1024" type="curve" smooth="yes"/>
+ <point x="535" y="1116"/>
+ <point x="657" y="1203"/>
+ <point x="832" y="1203" type="curve" smooth="yes"/>
+ <point x="950" y="1203"/>
+ <point x="1031" y="1176"/>
+ <point x="1144" y="1104" type="curve"/>
+ </contour>
+ <contour>
+ <point x="878" y="1568" type="line"/>
+ <point x="434" y="-216" type="line"/>
+ <point x="574" y="-216" type="line"/>
+ <point x="1018" y="1568" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfnormalize.ufo/glyphs/D_ottedC_irc.glif b/tests/reference/ufo/psfnormalize.ufo/glyphs/D_ottedC_irc.glif
new file mode 100644
index 0000000..2cdf8fd
--- /dev/null
+++ b/tests/reference/ufo/psfnormalize.ufo/glyphs/D_ottedC_irc.glif
@@ -0,0 +1,235 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="DottedCirc" format="2">
+ <advance width="1086"/>
+ <unicode hex="25CC"/>
+ <anchor x="493" y="0" name="H"/>
+ <anchor x="468" y="-100" name="L"/>
+ <anchor x="750" y="0" name="O"/>
+ <anchor x="743" y="1000" name="U"/>
+ <outline>
+ <contour>
+ <point x="588" y="834" type="curve" smooth="yes"/>
+ <point x="588" y="858"/>
+ <point x="571" y="867"/>
+ <point x="553" y="867" type="curve" smooth="yes"/>
+ <point x="521" y="867"/>
+ <point x="491" y="837"/>
+ <point x="491" y="809" type="curve" smooth="yes"/>
+ <point x="491" y="788"/>
+ <point x="508" y="773"/>
+ <point x="530" y="773" type="curve" smooth="yes"/>
+ <point x="564" y="773"/>
+ <point x="588" y="805"/>
+ </contour>
+ <contour>
+ <point x="677" y="124" type="curve" smooth="yes"/>
+ <point x="647" y="124"/>
+ <point x="620" y="93"/>
+ <point x="620" y="67" type="curve" smooth="yes"/>
+ <point x="620" y="46"/>
+ <point x="636" y="30"/>
+ <point x="657" y="30" type="curve" smooth="yes"/>
+ <point x="687" y="30"/>
+ <point x="718" y="60"/>
+ <point x="718" y="86" type="curve" smooth="yes"/>
+ <point x="718" y="109"/>
+ <point x="700" y="124"/>
+ </contour>
+ <contour>
+ <point x="396" y="780" type="curve" smooth="yes"/>
+ <point x="369" y="780"/>
+ <point x="336" y="753"/>
+ <point x="336" y="722" type="curve" smooth="yes"/>
+ <point x="336" y="702"/>
+ <point x="351" y="687"/>
+ <point x="374" y="687" type="curve" smooth="yes"/>
+ <point x="403" y="687"/>
+ <point x="434" y="711"/>
+ <point x="434" y="744" type="curve" smooth="yes"/>
+ <point x="434" y="764"/>
+ <point x="414" y="780"/>
+ </contour>
+ <contour>
+ <point x="873" y="175" type="curve" smooth="yes"/>
+ <point x="872" y="199"/>
+ <point x="854" y="211"/>
+ <point x="833" y="211" type="curve" smooth="yes"/>
+ <point x="803" y="211"/>
+ <point x="774" y="183"/>
+ <point x="774" y="153" type="curve" smooth="yes"/>
+ <point x="774" y="133"/>
+ <point x="789" y="119"/>
+ <point x="812" y="119" type="curve" smooth="yes"/>
+ <point x="843" y="119"/>
+ <point x="873" y="146"/>
+ </contour>
+ <contour>
+ <point x="313" y="612" type="curve" smooth="yes"/>
+ <point x="312" y="633"/>
+ <point x="296" y="650"/>
+ <point x="275" y="650" type="curve" smooth="yes"/>
+ <point x="247" y="650"/>
+ <point x="215" y="623"/>
+ <point x="215" y="592" type="curve" smooth="yes"/>
+ <point x="215" y="573"/>
+ <point x="227" y="556"/>
+ <point x="251" y="556" type="curve" smooth="yes"/>
+ <point x="278" y="556"/>
+ <point x="313" y="581"/>
+ </contour>
+ <contour>
+ <point x="994" y="306" type="curve" smooth="yes"/>
+ <point x="993" y="327"/>
+ <point x="978" y="341"/>
+ <point x="958" y="341" type="curve" smooth="yes"/>
+ <point x="933" y="341"/>
+ <point x="896" y="321"/>
+ <point x="896" y="284" type="curve" smooth="yes"/>
+ <point x="896" y="265"/>
+ <point x="909" y="249"/>
+ <point x="934" y="249" type="curve" smooth="yes"/>
+ <point x="963" y="249"/>
+ <point x="994" y="275"/>
+ </contour>
+ <contour>
+ <point x="205" y="495" type="curve" smooth="yes"/>
+ <point x="175" y="495"/>
+ <point x="145" y="468"/>
+ <point x="145" y="438" type="curve" smooth="yes"/>
+ <point x="145" y="418"/>
+ <point x="159" y="402"/>
+ <point x="183" y="402" type="curve" smooth="yes"/>
+ <point x="208" y="402"/>
+ <point x="244" y="428"/>
+ <point x="244" y="459" type="curve" smooth="yes"/>
+ <point x="244" y="479"/>
+ <point x="227" y="495"/>
+ </contour>
+ <contour>
+ <point x="1026" y="496" type="curve" smooth="yes"/>
+ <point x="999" y="496"/>
+ <point x="965" y="469"/>
+ <point x="965" y="438" type="curve" smooth="yes"/>
+ <point x="965" y="418"/>
+ <point x="979" y="403"/>
+ <point x="1004" y="403" type="curve" smooth="yes"/>
+ <point x="1033" y="403"/>
+ <point x="1064" y="431"/>
+ <point x="1064" y="460" type="curve" smooth="yes"/>
+ <point x="1064" y="480"/>
+ <point x="1048" y="496"/>
+ </contour>
+ <contour>
+ <point x="237" y="307" type="curve" smooth="yes"/>
+ <point x="237" y="327"/>
+ <point x="221" y="341"/>
+ <point x="199" y="341" type="curve" smooth="yes"/>
+ <point x="169" y="341"/>
+ <point x="138" y="314"/>
+ <point x="138" y="285" type="curve" smooth="yes"/>
+ <point x="138" y="263"/>
+ <point x="153" y="248"/>
+ <point x="175" y="248" type="curve" smooth="yes"/>
+ <point x="206" y="248"/>
+ <point x="237" y="278"/>
+ </contour>
+ <contour>
+ <point x="1071" y="613" type="curve" smooth="yes"/>
+ <point x="1071" y="634"/>
+ <point x="1055" y="650"/>
+ <point x="1034" y="650" type="curve" smooth="yes"/>
+ <point x="1003" y="650"/>
+ <point x="973" y="619"/>
+ <point x="973" y="590" type="curve" smooth="yes"/>
+ <point x="973" y="570"/>
+ <point x="989" y="556"/>
+ <point x="1009" y="556" type="curve" smooth="yes"/>
+ <point x="1041" y="556"/>
+ <point x="1071" y="585"/>
+ </contour>
+ <contour>
+ <point x="292" y="177" type="curve" smooth="yes"/>
+ <point x="292" y="197"/>
+ <point x="277" y="211"/>
+ <point x="253" y="211" type="curve" smooth="yes"/>
+ <point x="224" y="211"/>
+ <point x="194" y="181"/>
+ <point x="194" y="154" type="curve" smooth="yes"/>
+ <point x="194" y="134"/>
+ <point x="211" y="118"/>
+ <point x="232" y="118" type="curve" smooth="yes"/>
+ <point x="262" y="118"/>
+ <point x="292" y="148"/>
+ </contour>
+ <contour>
+ <point x="917" y="724" type="curve" smooth="yes"/>
+ <point x="917" y="704"/>
+ <point x="931" y="686"/>
+ <point x="954" y="686" type="curve" smooth="yes"/>
+ <point x="984" y="686"/>
+ <point x="1014" y="716"/>
+ <point x="1014" y="745" type="curve" smooth="yes"/>
+ <point x="1014" y="765"/>
+ <point x="1000" y="780"/>
+ <point x="977" y="780" type="curve" smooth="yes"/>
+ <point x="947" y="780"/>
+ <point x="917" y="753"/>
+ </contour>
+ <contour>
+ <point x="403" y="87" type="curve" smooth="yes"/>
+ <point x="403" y="107"/>
+ <point x="390" y="123"/>
+ <point x="367" y="123" type="curve" smooth="yes"/>
+ <point x="339" y="123"/>
+ <point x="305" y="96"/>
+ <point x="305" y="68" type="curve" smooth="yes"/>
+ <point x="305" y="49"/>
+ <point x="320" y="30"/>
+ <point x="343" y="30" type="curve" smooth="yes"/>
+ <point x="371" y="30"/>
+ <point x="403" y="56"/>
+ </contour>
+ <contour>
+ <point x="806" y="810" type="curve" smooth="yes"/>
+ <point x="806" y="791"/>
+ <point x="819" y="773"/>
+ <point x="842" y="773" type="curve" smooth="yes"/>
+ <point x="869" y="773"/>
+ <point x="903" y="799"/>
+ <point x="903" y="830" type="curve" smooth="yes"/>
+ <point x="903" y="850"/>
+ <point x="889" y="867"/>
+ <point x="866" y="867" type="curve" smooth="yes"/>
+ <point x="836" y="867"/>
+ <point x="806" y="839"/>
+ </contour>
+ <contour>
+ <point x="553" y="57" type="curve" smooth="yes"/>
+ <point x="553" y="78"/>
+ <point x="538" y="93"/>
+ <point x="516" y="93" type="curve" smooth="yes"/>
+ <point x="485" y="93"/>
+ <point x="456" y="65"/>
+ <point x="456" y="36" type="curve" smooth="yes"/>
+ <point x="456" y="16"/>
+ <point x="471" y="0"/>
+ <point x="493" y="0" type="curve" smooth="yes"/>
+ <point x="523" y="0"/>
+ <point x="553" y="27"/>
+ </contour>
+ <contour>
+ <point x="656" y="839" type="curve" smooth="yes"/>
+ <point x="656" y="819"/>
+ <point x="671" y="805"/>
+ <point x="693" y="805" type="curve" smooth="yes"/>
+ <point x="721" y="805"/>
+ <point x="754" y="830"/>
+ <point x="754" y="861" type="curve" smooth="yes"/>
+ <point x="754" y="882"/>
+ <point x="738" y="898"/>
+ <point x="716" y="898" type="curve" smooth="yes"/>
+ <point x="685" y="898"/>
+ <point x="656" y="868"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfnormalize.ufo/glyphs/E_qS_gn.glif b/tests/reference/ufo/psfnormalize.ufo/glyphs/E_qS_gn.glif
new file mode 100644
index 0000000..3d756e8
--- /dev/null
+++ b/tests/reference/ufo/psfnormalize.ufo/glyphs/E_qS_gn.glif
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="EqSgn" format="2">
+ <advance width="1180"/>
+ <unicode hex="003D"/>
+ <outline>
+ <contour>
+ <point x="177" y="470" type="line"/>
+ <point x="1137" y="470" type="line"/>
+ <point x="1173" y="617" type="line"/>
+ <point x="213" y="617" type="line"/>
+ </contour>
+ <contour>
+ <point x="262" y="813" type="line"/>
+ <point x="1222" y="813" type="line"/>
+ <point x="1259" y="960" type="line"/>
+ <point x="299" y="960" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfnormalize.ufo/glyphs/E_xclamationM_rk.glif b/tests/reference/ufo/psfnormalize.ufo/glyphs/E_xclamationM_rk.glif
new file mode 100644
index 0000000..a1c14d9
--- /dev/null
+++ b/tests/reference/ufo/psfnormalize.ufo/glyphs/E_xclamationM_rk.glif
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="ExclamationMrk" format="2">
+ <advance width="744"/>
+ <unicode hex="0021"/>
+ <outline>
+ <contour>
+ <point x="497" y="431" type="line"/>
+ <point x="574" y="715"/>
+ <point x="653" y="1054"/>
+ <point x="799" y="1480" type="curve"/>
+ <point x="544" y="1480" type="line"/>
+ <point x="475" y="1054"/>
+ <point x="386" y="715"/>
+ <point x="322" y="431" type="curve"/>
+ </contour>
+ <contour>
+ <point x="188" y="90" type="curve" smooth="yes"/>
+ <point x="188" y="28"/>
+ <point x="238" y="-25"/>
+ <point x="303" y="-25" type="curve" smooth="yes"/>
+ <point x="387" y="-25"/>
+ <point x="464" y="45"/>
+ <point x="464" y="125" type="curve" smooth="yes"/>
+ <point x="464" y="186"/>
+ <point x="414" y="240"/>
+ <point x="349" y="240" type="curve" smooth="yes"/>
+ <point x="265" y="240"/>
+ <point x="188" y="170"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfnormalize.ufo/glyphs/F_ullS_top.glif b/tests/reference/ufo/psfnormalize.ufo/glyphs/F_ullS_top.glif
new file mode 100644
index 0000000..a6c4d08
--- /dev/null
+++ b/tests/reference/ufo/psfnormalize.ufo/glyphs/F_ullS_top.glif
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="FullStop" format="2">
+ <advance width="620"/>
+ <unicode hex="002E"/>
+ <outline>
+ <contour>
+ <point x="148" y="90" type="curve" smooth="yes"/>
+ <point x="148" y="28"/>
+ <point x="198" y="-25"/>
+ <point x="263" y="-25" type="curve" smooth="yes"/>
+ <point x="347" y="-25"/>
+ <point x="424" y="45"/>
+ <point x="424" y="125" type="curve" smooth="yes"/>
+ <point x="424" y="186"/>
+ <point x="374" y="240"/>
+ <point x="309" y="240" type="curve" smooth="yes"/>
+ <point x="225" y="240"/>
+ <point x="148" y="170"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfnormalize.ufo/glyphs/G_T_S_gn.glif b/tests/reference/ufo/psfnormalize.ufo/glyphs/G_T_S_gn.glif
new file mode 100644
index 0000000..12da8b3
--- /dev/null
+++ b/tests/reference/ufo/psfnormalize.ufo/glyphs/G_T_S_gn.glif
@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="GTSgn" format="2">
+ <advance width="1180"/>
+ <unicode hex="003E"/>
+ <outline>
+ <contour>
+ <point x="312" y="1014" type="line"/>
+ <point x="1028" y="725" type="line"/>
+ <point x="163" y="417" type="line"/>
+ <point x="119" y="240" type="line"/>
+ <point x="1197" y="632" type="line"/>
+ <point x="1239" y="799" type="line"/>
+ <point x="356" y="1191" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfnormalize.ufo/glyphs/G_raveA_ccent.glif b/tests/reference/ufo/psfnormalize.ufo/glyphs/G_raveA_ccent.glif
new file mode 100644
index 0000000..48adfc4
--- /dev/null
+++ b/tests/reference/ufo/psfnormalize.ufo/glyphs/G_raveA_ccent.glif
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="GraveAccent" format="2">
+ <advance width="560"/>
+ <unicode hex="0060"/>
+ <anchor x="738" y="1635" name="U"/>
+ <outline>
+ <contour>
+ <point x="261" y="1568" type="line"/>
+ <point x="596" y="1147" type="line"/>
+ <point x="746" y="1147" type="line"/>
+ <point x="471" y="1568" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfnormalize.ufo/glyphs/H_yphen.glif b/tests/reference/ufo/psfnormalize.ufo/glyphs/H_yphen.glif
new file mode 100644
index 0000000..ae8cad5
--- /dev/null
+++ b/tests/reference/ufo/psfnormalize.ufo/glyphs/H_yphen.glif
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="Hyphen" format="2">
+ <advance width="840"/>
+ <unicode hex="2010"/>
+ <anchor x="645" y="1100" name="U"/>
+ <outline>
+ <contour>
+ <point x="155" y="544" type="line"/>
+ <point x="855" y="544" type="line"/>
+ <point x="892" y="691" type="line"/>
+ <point x="192" y="691" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfnormalize.ufo/glyphs/H_yphenM_inus.glif b/tests/reference/ufo/psfnormalize.ufo/glyphs/H_yphenM_inus.glif
new file mode 100644
index 0000000..155b460
--- /dev/null
+++ b/tests/reference/ufo/psfnormalize.ufo/glyphs/H_yphenM_inus.glif
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="HyphenMinus" format="2">
+ <advance width="840"/>
+ <unicode hex="002D"/>
+ <anchor x="645" y="1100" name="U"/>
+ <outline>
+ <contour>
+ <point x="155" y="544" type="line"/>
+ <point x="855" y="544" type="line"/>
+ <point x="892" y="691" type="line"/>
+ <point x="192" y="691" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfnormalize.ufo/glyphs/H_yphen_S_oft.glif b/tests/reference/ufo/psfnormalize.ufo/glyphs/H_yphen_S_oft.glif
new file mode 100644
index 0000000..0c7b834
--- /dev/null
+++ b/tests/reference/ufo/psfnormalize.ufo/glyphs/H_yphen_S_oft.glif
@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="Hyphen_Soft" format="2">
+ <advance width="840"/>
+ <unicode hex="00AD"/>
+ <anchor x="645" y="1100" name="U"/>
+ <outline>
+ <component base="HyphenMinus"/>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfnormalize.ufo/glyphs/L_T_S_gn.glif b/tests/reference/ufo/psfnormalize.ufo/glyphs/L_T_S_gn.glif
new file mode 100644
index 0000000..3c857a5
--- /dev/null
+++ b/tests/reference/ufo/psfnormalize.ufo/glyphs/L_T_S_gn.glif
@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LTSgn" format="2">
+ <advance width="1180"/>
+ <unicode hex="003C"/>
+ <outline>
+ <contour>
+ <point x="1123" y="417" type="line"/>
+ <point x="408" y="705" type="line"/>
+ <point x="1272" y="1014" type="line"/>
+ <point x="1316" y="1191" type="line"/>
+ <point x="239" y="799" type="line"/>
+ <point x="197" y="632" type="line"/>
+ <point x="1079" y="240" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfnormalize.ufo/glyphs/L_ftC_urlyB_rac.glif b/tests/reference/ufo/psfnormalize.ufo/glyphs/L_ftC_urlyB_rac.glif
new file mode 100644
index 0000000..4f8c90c
--- /dev/null
+++ b/tests/reference/ufo/psfnormalize.ufo/glyphs/L_ftC_urlyB_rac.glif
@@ -0,0 +1,50 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LftCurlyBrac" format="2">
+ <advance width="980"/>
+ <unicode hex="007B"/>
+ <outline>
+ <contour>
+ <point x="713" y="-265" type="line"/>
+ <point x="660" y="-250"/>
+ <point x="526" y="-188"/>
+ <point x="526" y="-158" type="curve" smooth="yes"/>
+ <point x="526" y="-59"/>
+ <point x="649" y="404"/>
+ <point x="649" y="469" type="curve" smooth="yes"/>
+ <point x="649" y="509"/>
+ <point x="520" y="577"/>
+ <point x="520" y="602" type="curve" smooth="yes"/>
+ <point x="520" y="620"/>
+ <point x="688" y="700"/>
+ <point x="712" y="730" type="curve" smooth="yes"/>
+ <point x="741" y="767"/>
+ <point x="867" y="1326"/>
+ <point x="912" y="1372" type="curve" smooth="yes"/>
+ <point x="938" y="1399"/>
+ <point x="1073" y="1447"/>
+ <point x="1146" y="1470" type="curve"/>
+ <point x="1140" y="1607" type="line"/>
+ <point x="1030" y="1581"/>
+ <point x="856" y="1529"/>
+ <point x="805" y="1485" type="curve" smooth="yes"/>
+ <point x="714" y="1406"/>
+ <point x="572" y="796"/>
+ <point x="540" y="764" type="curve" smooth="yes"/>
+ <point x="504" y="729"/>
+ <point x="300" y="633"/>
+ <point x="300" y="601" type="curve" smooth="yes"/>
+ <point x="300" y="560"/>
+ <point x="460" y="468"/>
+ <point x="460" y="432" type="curve" smooth="yes"/>
+ <point x="460" y="362"/>
+ <point x="355" y="-53"/>
+ <point x="355" y="-219" type="curve" smooth="yes"/>
+ <point x="355" y="-247"/>
+ <point x="358" y="-268"/>
+ <point x="365" y="-279" type="curve" smooth="yes"/>
+ <point x="394" y="-323"/>
+ <point x="542" y="-375"/>
+ <point x="639" y="-402" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfnormalize.ufo/glyphs/L_ftP_aren.glif b/tests/reference/ufo/psfnormalize.ufo/glyphs/L_ftP_aren.glif
new file mode 100644
index 0000000..bc65fc1
--- /dev/null
+++ b/tests/reference/ufo/psfnormalize.ufo/glyphs/L_ftP_aren.glif
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LftParen" format="2">
+ <advance width="775"/>
+ <unicode hex="0028"/>
+ <outline>
+ <contour>
+ <point x="895" y="1607" type="line"/>
+ <point x="582" y="1415"/>
+ <point x="314" y="1061"/>
+ <point x="207" y="633" type="curve" smooth="yes"/>
+ <point x="176" y="508"/>
+ <point x="161" y="386"/>
+ <point x="161" y="270" type="curve" smooth="yes"/>
+ <point x="161" y="17"/>
+ <point x="233" y="-211"/>
+ <point x="374" y="-402" type="curve"/>
+ <point x="505" y="-260" type="line"/>
+ <point x="397" y="-102"/>
+ <point x="348" y="75"/>
+ <point x="348" y="270" type="curve" smooth="yes"/>
+ <point x="348" y="385"/>
+ <point x="365" y="506"/>
+ <point x="397" y="633" type="curve" smooth="yes"/>
+ <point x="484" y="982"/>
+ <point x="647" y="1254"/>
+ <point x="932" y="1455" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfnormalize.ufo/glyphs/L_ftS_qrB_rac.glif b/tests/reference/ufo/psfnormalize.ufo/glyphs/L_ftS_qrB_rac.glif
new file mode 100644
index 0000000..6d064d1
--- /dev/null
+++ b/tests/reference/ufo/psfnormalize.ufo/glyphs/L_ftS_qrB_rac.glif
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LftSqrBrac" format="2">
+ <advance width="770"/>
+ <unicode hex="005B"/>
+ <outline>
+ <contour>
+ <point x="484" y="-402" type="line"/>
+ <point x="521" y="-255" type="line"/>
+ <point x="266" y="-255" type="line"/>
+ <point x="679" y="1421" type="line"/>
+ <point x="934" y="1421" type="line"/>
+ <point x="970" y="1568" type="line"/>
+ <point x="530" y="1568" type="line"/>
+ <point x="44" y="-402" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfnormalize.ufo/glyphs/L_owL_ine.glif b/tests/reference/ufo/psfnormalize.ufo/glyphs/L_owL_ine.glif
new file mode 100644
index 0000000..879d36b
--- /dev/null
+++ b/tests/reference/ufo/psfnormalize.ufo/glyphs/L_owL_ine.glif
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LowLine" format="2">
+ <advance width="1254"/>
+ <unicode hex="005F"/>
+ <outline>
+ <contour>
+ <point x="-138" y="-314" type="line"/>
+ <point x="1135" y="-314" type="line"/>
+ <point x="1172" y="-167" type="line"/>
+ <point x="-101" y="-167" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfnormalize.ufo/glyphs/L_tnC_apA_.glif b/tests/reference/ufo/psfnormalize.ufo/glyphs/L_tnC_apA_.glif
new file mode 100644
index 0000000..3a14b0e
--- /dev/null
+++ b/tests/reference/ufo/psfnormalize.ufo/glyphs/L_tnC_apA_.glif
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnCapA" format="2">
+ <advance width="1395"/>
+ <unicode hex="0041"/>
+ <anchor x="1170" y="0" name="H"/>
+ <anchor x="602" y="-100" name="L"/>
+ <anchor x="1390" y="0" name="O"/>
+ <anchor x="1009" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="1080" y="0" type="line"/>
+ <point x="1275" y="0" type="line"/>
+ <point x="1259" y="78"/>
+ <point x="1243" y="166"/>
+ <point x="1221" y="348" type="curve" smooth="yes"/>
+ <point x="1091" y="1431" type="line"/>
+ <point x="876" y="1431" type="line"/>
+ <point x="206" y="348" type="line" smooth="yes"/>
+ <point x="93" y="165"/>
+ <point x="35" y="79"/>
+ <point x="-20" y="0" type="curve"/>
+ <point x="195" y="0" type="line"/>
+ <point x="422" y="377" type="line"/>
+ <point x="1038" y="377" type="line"/>
+ </contour>
+ <contour>
+ <point x="944" y="1240" type="line"/>
+ <point x="1022" y="529" type="line"/>
+ <point x="514" y="529" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfnormalize.ufo/glyphs/L_tnC_apA_D_iaer.glif b/tests/reference/ufo/psfnormalize.ufo/glyphs/L_tnC_apA_D_iaer.glif
new file mode 100644
index 0000000..6c3502c
--- /dev/null
+++ b/tests/reference/ufo/psfnormalize.ufo/glyphs/L_tnC_apA_D_iaer.glif
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnCapADiaer" format="2">
+ <advance width="1395"/>
+ <unicode hex="00C4"/>
+ <anchor x="1170" y="0" name="H"/>
+ <anchor x="602" y="-100" name="L"/>
+ <anchor x="1390" y="0" name="O"/>
+ <anchor x="1106" y="1935" name="U"/>
+ <outline>
+ <component base="LtnCapA"/>
+ <component base="CombDiaer" xOffset="1359" yOffset="430"/>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfnormalize.ufo/glyphs/L_tnC_apB_.glif b/tests/reference/ufo/psfnormalize.ufo/glyphs/L_tnC_apB_.glif
new file mode 100644
index 0000000..5445f93
--- /dev/null
+++ b/tests/reference/ufo/psfnormalize.ufo/glyphs/L_tnC_apB_.glif
@@ -0,0 +1,62 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnCapB" format="2">
+ <advance width="1271"/>
+ <unicode hex="0042"/>
+ <anchor x="530" y="-100" name="L"/>
+ <anchor x="937" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="625" y="1284" type="line"/>
+ <point x="667" y="1286"/>
+ <point x="733" y="1289"/>
+ <point x="811" y="1289" type="curve" smooth="yes"/>
+ <point x="993" y="1289"/>
+ <point x="1080" y="1230"/>
+ <point x="1080" y="1105" type="curve" smooth="yes"/>
+ <point x="1080" y="932"/>
+ <point x="931" y="838"/>
+ <point x="698" y="838" type="curve" smooth="yes"/>
+ <point x="513" y="838" type="line"/>
+ </contour>
+ <contour>
+ <point x="226" y="446" type="line"/>
+ <point x="178" y="252"/>
+ <point x="134" y="78"/>
+ <point x="100" y="0" type="curve"/>
+ <point x="151" y="-5"/>
+ <point x="359" y="-10"/>
+ <point x="562" y="-10" type="curve" smooth="yes"/>
+ <point x="960" y="-10"/>
+ <point x="1201" y="149"/>
+ <point x="1201" y="453" type="curve" smooth="yes"/>
+ <point x="1201" y="644"/>
+ <point x="1067" y="736"/>
+ <point x="955" y="764" type="curve"/>
+ <point x="1155" y="819"/>
+ <point x="1283" y="941"/>
+ <point x="1283" y="1140" type="curve" smooth="yes"/>
+ <point x="1283" y="1310"/>
+ <point x="1136" y="1441"/>
+ <point x="869" y="1441" type="curve" smooth="yes"/>
+ <point x="700" y="1441"/>
+ <point x="546" y="1437"/>
+ <point x="456" y="1431" type="curve"/>
+ <point x="452" y="1352"/>
+ <point x="407" y="1172"/>
+ <point x="359" y="980" type="curve" smooth="yes"/>
+ </contour>
+ <contour>
+ <point x="476" y="686" type="line"/>
+ <point x="721" y="686" type="line" smooth="yes"/>
+ <point x="892" y="686"/>
+ <point x="1011" y="598"/>
+ <point x="1011" y="450" type="curve" smooth="yes"/>
+ <point x="1011" y="218"/>
+ <point x="806" y="147"/>
+ <point x="586" y="147" type="curve" smooth="yes"/>
+ <point x="474" y="147"/>
+ <point x="379" y="150"/>
+ <point x="342" y="152" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfnormalize.ufo/glyphs/L_tnC_apC_.glif b/tests/reference/ufo/psfnormalize.ufo/glyphs/L_tnC_apC_.glif
new file mode 100644
index 0000000..c2e4948
--- /dev/null
+++ b/tests/reference/ufo/psfnormalize.ufo/glyphs/L_tnC_apC_.glif
@@ -0,0 +1,38 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnCapC" format="2">
+ <advance width="1341"/>
+ <unicode hex="0043"/>
+ <anchor x="690" y="0" name="H"/>
+ <anchor x="665" y="-100" name="L"/>
+ <anchor x="1072" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="1237" y="318" type="line"/>
+ <point x="1115" y="222"/>
+ <point x="934" y="147"/>
+ <point x="752" y="147" type="curve" smooth="yes"/>
+ <point x="537" y="147"/>
+ <point x="385" y="304"/>
+ <point x="385" y="532" type="curve" smooth="yes"/>
+ <point x="385" y="964"/>
+ <point x="704" y="1289"/>
+ <point x="1037" y="1289" type="curve" smooth="yes"/>
+ <point x="1168" y="1289"/>
+ <point x="1310" y="1235"/>
+ <point x="1385" y="1132" type="curve"/>
+ <point x="1489" y="1308" type="line"/>
+ <point x="1388" y="1408"/>
+ <point x="1201" y="1455"/>
+ <point x="1058" y="1455" type="curve" smooth="yes"/>
+ <point x="645" y="1455"/>
+ <point x="185" y="1093"/>
+ <point x="185" y="513" type="curve" smooth="yes"/>
+ <point x="185" y="202"/>
+ <point x="381" y="-25"/>
+ <point x="709" y="-25" type="curve" smooth="yes"/>
+ <point x="896" y="-25"/>
+ <point x="1087" y="21"/>
+ <point x="1230" y="127" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfnormalize.ufo/glyphs/L_tnC_apD_.glif b/tests/reference/ufo/psfnormalize.ufo/glyphs/L_tnC_apD_.glif
new file mode 100644
index 0000000..3b93811
--- /dev/null
+++ b/tests/reference/ufo/psfnormalize.ufo/glyphs/L_tnC_apD_.glif
@@ -0,0 +1,51 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnCapD" format="2">
+ <advance width="1421"/>
+ <unicode hex="0044"/>
+ <anchor x="630" y="-100" name="L"/>
+ <anchor x="1037" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="226" y="446" type="line"/>
+ <point x="176" y="252"/>
+ <point x="134" y="78"/>
+ <point x="100" y="0" type="curve"/>
+ <point x="100" y="0"/>
+ <point x="414" y="-10"/>
+ <point x="542" y="-10" type="curve" smooth="yes"/>
+ <point x="985" y="-10"/>
+ <point x="1299" y="181"/>
+ <point x="1415" y="648" type="curve" smooth="yes"/>
+ <point x="1437" y="738"/>
+ <point x="1447" y="819"/>
+ <point x="1447" y="891" type="curve" smooth="yes"/>
+ <point x="1447" y="1279"/>
+ <point x="1188" y="1441"/>
+ <point x="894" y="1441" type="curve" smooth="yes"/>
+ <point x="759" y="1441"/>
+ <point x="543" y="1437"/>
+ <point x="456" y="1431" type="curve"/>
+ <point x="452" y="1352"/>
+ <point x="407" y="1172"/>
+ <point x="359" y="980" type="curve" smooth="yes"/>
+ </contour>
+ <contour>
+ <point x="623" y="1279" type="line"/>
+ <point x="674" y="1281"/>
+ <point x="764" y="1284"/>
+ <point x="830" y="1284" type="curve" smooth="yes"/>
+ <point x="1105" y="1284"/>
+ <point x="1246" y="1140"/>
+ <point x="1246" y="850" type="curve" smooth="yes"/>
+ <point x="1246" y="784"/>
+ <point x="1236" y="710"/>
+ <point x="1216" y="629" type="curve" smooth="yes"/>
+ <point x="1134" y="300"/>
+ <point x="925" y="152"/>
+ <point x="572" y="152" type="curve" smooth="yes"/>
+ <point x="477" y="152"/>
+ <point x="391" y="158"/>
+ <point x="345" y="162" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfnormalize.ufo/glyphs/L_tnC_apE_.glif b/tests/reference/ufo/psfnormalize.ufo/glyphs/L_tnC_apE_.glif
new file mode 100644
index 0000000..8b5f8b9
--- /dev/null
+++ b/tests/reference/ufo/psfnormalize.ufo/glyphs/L_tnC_apE_.glif
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnCapE" format="2">
+ <advance width="1140"/>
+ <unicode hex="0045"/>
+ <anchor x="540" y="0" name="H"/>
+ <anchor x="515" y="-100" name="L"/>
+ <anchor x="857" y="0" name="O"/>
+ <anchor x="1400" y="1200" name="R"/>
+ <anchor x="922" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="511" y="828" type="line"/>
+ <point x="621" y="1269" type="line"/>
+ <point x="1266" y="1269" type="line"/>
+ <point x="1306" y="1431" type="line"/>
+ <point x="456" y="1431" type="line"/>
+ <point x="452" y="1352"/>
+ <point x="413" y="1197"/>
+ <point x="365" y="1005" type="curve" smooth="yes"/>
+ <point x="221" y="426" type="line" smooth="yes"/>
+ <point x="173" y="233"/>
+ <point x="134" y="78"/>
+ <point x="100" y="0" type="curve"/>
+ <point x="980" y="0" type="line"/>
+ <point x="1023" y="176" type="line"/>
+ <point x="940" y="163"/>
+ <point x="806" y="162"/>
+ <point x="609" y="162" type="curve" smooth="yes"/>
+ <point x="345" y="162" type="line"/>
+ <point x="472" y="671" type="line"/>
+ <point x="1042" y="671" type="line"/>
+ <point x="1081" y="828" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfnormalize.ufo/glyphs/L_tnC_apF_.glif b/tests/reference/ufo/psfnormalize.ufo/glyphs/L_tnC_apF_.glif
new file mode 100644
index 0000000..cbc1726
--- /dev/null
+++ b/tests/reference/ufo/psfnormalize.ufo/glyphs/L_tnC_apF_.glif
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnCapF" format="2">
+ <advance width="1130"/>
+ <unicode hex="0046"/>
+ <anchor x="510" y="-100" name="L"/>
+ <anchor x="917" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="508" y="818" type="line"/>
+ <point x="621" y="1269" type="line"/>
+ <point x="1286" y="1269" type="line"/>
+ <point x="1326" y="1431" type="line"/>
+ <point x="456" y="1431" type="line"/>
+ <point x="452" y="1352"/>
+ <point x="412" y="1193"/>
+ <point x="364" y="1000" type="curve" smooth="yes"/>
+ <point x="221" y="426" type="line" smooth="yes"/>
+ <point x="173" y="233"/>
+ <point x="134" y="78"/>
+ <point x="100" y="0" type="curve"/>
+ <point x="320" y="0" type="line"/>
+ <point x="323" y="76"/>
+ <point x="362" y="232"/>
+ <point x="411" y="426" type="curve" smooth="yes"/>
+ <point x="470" y="662" type="line"/>
+ <point x="1050" y="662" type="line"/>
+ <point x="1088" y="818" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfnormalize.ufo/glyphs/L_tnC_apG_.glif b/tests/reference/ufo/psfnormalize.ufo/glyphs/L_tnC_apG_.glif
new file mode 100644
index 0000000..c39b75a
--- /dev/null
+++ b/tests/reference/ufo/psfnormalize.ufo/glyphs/L_tnC_apG_.glif
@@ -0,0 +1,48 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnCapG" format="2">
+ <advance width="1406"/>
+ <unicode hex="0047"/>
+ <anchor x="685" y="0" name="H"/>
+ <anchor x="660" y="-100" name="L"/>
+ <anchor x="1067" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="1403" y="710" type="line"/>
+ <point x="863" y="710" type="line"/>
+ <point x="822" y="548" type="line"/>
+ <point x="1172" y="548" type="line"/>
+ <point x="1090" y="220" type="line"/>
+ <point x="1012" y="176"/>
+ <point x="858" y="147"/>
+ <point x="739" y="147" type="curve" smooth="yes"/>
+ <point x="520" y="147"/>
+ <point x="384" y="272"/>
+ <point x="384" y="493" type="curve" smooth="yes"/>
+ <point x="384" y="560"/>
+ <point x="394" y="636"/>
+ <point x="415" y="720" type="curve" smooth="yes"/>
+ <point x="500" y="1062"/>
+ <point x="747" y="1289"/>
+ <point x="1052" y="1289" type="curve" smooth="yes"/>
+ <point x="1195" y="1289"/>
+ <point x="1335" y="1233"/>
+ <point x="1425" y="1122" type="curve"/>
+ <point x="1534" y="1298" type="line"/>
+ <point x="1409" y="1405"/>
+ <point x="1235" y="1455"/>
+ <point x="1063" y="1455" type="curve" smooth="yes"/>
+ <point x="680" y="1455"/>
+ <point x="334" y="1195"/>
+ <point x="217" y="726" type="curve" smooth="yes"/>
+ <point x="195" y="639"/>
+ <point x="185" y="559"/>
+ <point x="185" y="486" type="curve" smooth="yes"/>
+ <point x="185" y="162"/>
+ <point x="406" y="-25"/>
+ <point x="714" y="-25" type="curve" smooth="yes"/>
+ <point x="907" y="-25"/>
+ <point x="1149" y="50"/>
+ <point x="1258" y="132" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfnormalize.ufo/glyphs/L_tnC_apH_.glif b/tests/reference/ufo/psfnormalize.ufo/glyphs/L_tnC_apH_.glif
new file mode 100644
index 0000000..f454288
--- /dev/null
+++ b/tests/reference/ufo/psfnormalize.ufo/glyphs/L_tnC_apH_.glif
@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnCapH" format="2">
+ <advance width="1455"/>
+ <unicode hex="0048"/>
+ <anchor x="225" y="0" name="H"/>
+ <anchor x="640" y="-100" name="L"/>
+ <anchor x="1047" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="1230" y="0" type="line"/>
+ <point x="1234" y="78"/>
+ <point x="1273" y="233"/>
+ <point x="1321" y="426" type="curve" smooth="yes"/>
+ <point x="1465" y="1005" type="line" smooth="yes"/>
+ <point x="1513" y="1198"/>
+ <point x="1552" y="1352"/>
+ <point x="1586" y="1431" type="curve"/>
+ <point x="1381" y="1431" type="line"/>
+ <point x="1228" y="818" type="line"/>
+ <point x="508" y="818" type="line"/>
+ <point x="661" y="1431" type="line"/>
+ <point x="456" y="1431" type="line"/>
+ <point x="452" y="1352"/>
+ <point x="413" y="1197"/>
+ <point x="365" y="1005" type="curve" smooth="yes"/>
+ <point x="221" y="426" type="line" smooth="yes"/>
+ <point x="173" y="233"/>
+ <point x="134" y="78"/>
+ <point x="100" y="0" type="curve"/>
+ <point x="305" y="0" type="line"/>
+ <point x="470" y="662" type="line"/>
+ <point x="1190" y="662" type="line"/>
+ <point x="1025" y="0" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfnormalize.ufo/glyphs/L_tnC_apI_.glif b/tests/reference/ufo/psfnormalize.ufo/glyphs/L_tnC_apI_.glif
new file mode 100644
index 0000000..78b151c
--- /dev/null
+++ b/tests/reference/ufo/psfnormalize.ufo/glyphs/L_tnC_apI_.glif
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnCapI" format="2">
+ <advance width="955"/>
+ <unicode hex="0049"/>
+ <anchor x="417" y="0" name="H"/>
+ <anchor x="392" y="-100" name="L"/>
+ <anchor x="613" y="0" name="O"/>
+ <anchor x="1215" y="1200" name="R"/>
+ <anchor x="799" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="436" y="1431" type="line"/>
+ <point x="401" y="1289" type="line"/>
+ <point x="641" y="1289" type="line"/>
+ <point x="355" y="142" type="line"/>
+ <point x="115" y="142" type="line"/>
+ <point x="80" y="0" type="line"/>
+ <point x="755" y="0" type="line"/>
+ <point x="790" y="142" type="line"/>
+ <point x="545" y="142" type="line"/>
+ <point x="831" y="1289" type="line"/>
+ <point x="1076" y="1289" type="line"/>
+ <point x="1111" y="1431" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfnormalize.ufo/glyphs/L_tnC_apJ_.glif b/tests/reference/ufo/psfnormalize.ufo/glyphs/L_tnC_apJ_.glif
new file mode 100644
index 0000000..417d1f8
--- /dev/null
+++ b/tests/reference/ufo/psfnormalize.ufo/glyphs/L_tnC_apJ_.glif
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnCapJ" format="2">
+ <advance width="996"/>
+ <unicode hex="004A"/>
+ <anchor x="325" y="-100" name="L"/>
+ <anchor x="997" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="871" y="1431" type="line"/>
+ <point x="858" y="1327"/>
+ <point x="817" y="1151"/>
+ <point x="769" y="960" type="curve" smooth="yes"/>
+ <point x="648" y="475" type="line" smooth="yes"/>
+ <point x="592" y="251"/>
+ <point x="484" y="152"/>
+ <point x="337" y="152" type="curve" smooth="yes"/>
+ <point x="245" y="152"/>
+ <point x="145" y="224"/>
+ <point x="97" y="299" type="curve"/>
+ <point x="6" y="118" type="line"/>
+ <point x="58" y="39"/>
+ <point x="193" y="-25"/>
+ <point x="298" y="-25" type="curve" smooth="yes"/>
+ <point x="555" y="-25"/>
+ <point x="749" y="117"/>
+ <point x="850" y="524" type="curve" smooth="yes"/>
+ <point x="1076" y="1431" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfnormalize.ufo/glyphs/L_tnC_apK_.glif b/tests/reference/ufo/psfnormalize.ufo/glyphs/L_tnC_apK_.glif
new file mode 100644
index 0000000..8e54a6d
--- /dev/null
+++ b/tests/reference/ufo/psfnormalize.ufo/glyphs/L_tnC_apK_.glif
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnCapK" format="2">
+ <advance width="1261"/>
+ <unicode hex="004B"/>
+ <anchor x="210" y="0" name="H"/>
+ <anchor x="610" y="-100" name="L"/>
+ <anchor x="972" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="1221" y="1431" type="line"/>
+ <point x="406" y="689" type="line"/>
+ <point x="547" y="730" type="line"/>
+ <point x="660" y="725" type="line"/>
+ <point x="1461" y="1431" type="line"/>
+ </contour>
+ <contour>
+ <point x="1170" y="0" type="line"/>
+ <point x="615" y="823" type="line"/>
+ <point x="469" y="720" type="line"/>
+ <point x="925" y="0" type="line"/>
+ </contour>
+ <contour>
+ <point x="661" y="1431" type="line"/>
+ <point x="456" y="1431" type="line"/>
+ <point x="452" y="1352"/>
+ <point x="413" y="1197"/>
+ <point x="365" y="1005" type="curve" smooth="yes"/>
+ <point x="221" y="426" type="line" smooth="yes"/>
+ <point x="173" y="233"/>
+ <point x="134" y="78"/>
+ <point x="100" y="0" type="curve"/>
+ <point x="305" y="0" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfnormalize.ufo/glyphs/L_tnC_apL_.glif b/tests/reference/ufo/psfnormalize.ufo/glyphs/L_tnC_apL_.glif
new file mode 100644
index 0000000..d2eb932
--- /dev/null
+++ b/tests/reference/ufo/psfnormalize.ufo/glyphs/L_tnC_apL_.glif
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnCapL" format="2">
+ <advance width="1060"/>
+ <unicode hex="004C"/>
+ <anchor x="532" y="0" name="H"/>
+ <anchor x="507" y="-100" name="L"/>
+ <anchor x="780" y="1200" name="R"/>
+ <anchor x="914" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="345" y="162" type="line"/>
+ <point x="661" y="1431" type="line"/>
+ <point x="456" y="1431" type="line"/>
+ <point x="452" y="1352"/>
+ <point x="413" y="1197"/>
+ <point x="365" y="1005" type="curve" smooth="yes"/>
+ <point x="221" y="426" type="line" smooth="yes"/>
+ <point x="173" y="233"/>
+ <point x="134" y="78"/>
+ <point x="100" y="0" type="curve"/>
+ <point x="965" y="0" type="line"/>
+ <point x="1008" y="176" type="line"/>
+ <point x="925" y="163"/>
+ <point x="766" y="162"/>
+ <point x="569" y="162" type="curve" smooth="yes"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfnormalize.ufo/glyphs/L_tnC_apM_.glif b/tests/reference/ufo/psfnormalize.ufo/glyphs/L_tnC_apM_.glif
new file mode 100644
index 0000000..7c3c824
--- /dev/null
+++ b/tests/reference/ufo/psfnormalize.ufo/glyphs/L_tnC_apM_.glif
@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnCapM" format="2">
+ <advance width="1785"/>
+ <unicode hex="004D"/>
+ <anchor x="800" y="-100" name="L"/>
+ <anchor x="1207" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="880" y="201" type="line"/>
+ <point x="751" y="1431" type="line"/>
+ <point x="591" y="1431" type="line"/>
+ <point x="740" y="0" type="line"/>
+ <point x="935" y="0" type="line"/>
+ <point x="1793" y="1431" type="line"/>
+ <point x="1616" y="1431" type="line"/>
+ </contour>
+ <contour>
+ <point x="536" y="1431" type="line"/>
+ <point x="536" y="1431"/>
+ <point x="184" y="194"/>
+ <point x="110" y="0" type="curve"/>
+ <point x="295" y="0" type="line"/>
+ <point x="621" y="1181" type="line"/>
+ <point x="711" y="1431" type="line"/>
+ </contour>
+ <contour>
+ <point x="1560" y="0" type="line"/>
+ <point x="1579" y="194"/>
+ <point x="1846" y="1431"/>
+ <point x="1846" y="1431" type="curve"/>
+ <point x="1671" y="1431" type="line"/>
+ <point x="1641" y="1181" type="line"/>
+ <point x="1375" y="0" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfnormalize.ufo/glyphs/L_tnC_apN_.glif b/tests/reference/ufo/psfnormalize.ufo/glyphs/L_tnC_apN_.glif
new file mode 100644
index 0000000..7306669
--- /dev/null
+++ b/tests/reference/ufo/psfnormalize.ufo/glyphs/L_tnC_apN_.glif
@@ -0,0 +1,37 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnCapN" format="2">
+ <advance width="1480"/>
+ <unicode hex="004E"/>
+ <anchor x="1170" y="0" name="H"/>
+ <anchor x="652" y="-100" name="L"/>
+ <anchor x="1059" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="491" y="1328" type="line"/>
+ <point x="1075" y="0" type="line"/>
+ <point x="1219" y="98" type="line"/>
+ <point x="636" y="1431" type="line"/>
+ </contour>
+ <contour>
+ <point x="1075" y="0" type="line"/>
+ <point x="1250" y="0" type="line"/>
+ <point x="1500" y="1005" type="line" smooth="yes"/>
+ <point x="1548" y="1198"/>
+ <point x="1588" y="1352"/>
+ <point x="1621" y="1431" type="curve"/>
+ <point x="1431" y="1431" type="line"/>
+ </contour>
+ <contour>
+ <point x="636" y="1431" type="line"/>
+ <point x="446" y="1431" type="line"/>
+ <point x="442" y="1352"/>
+ <point x="403" y="1197"/>
+ <point x="355" y="1005" type="curve" smooth="yes"/>
+ <point x="211" y="426" type="line" smooth="yes"/>
+ <point x="163" y="233"/>
+ <point x="124" y="78"/>
+ <point x="90" y="0" type="curve"/>
+ <point x="280" y="0" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfnormalize.ufo/glyphs/L_tnC_apO_.glif b/tests/reference/ufo/psfnormalize.ufo/glyphs/L_tnC_apO_.glif
new file mode 100644
index 0000000..19c4886
--- /dev/null
+++ b/tests/reference/ufo/psfnormalize.ufo/glyphs/L_tnC_apO_.glif
@@ -0,0 +1,40 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnCapO" format="2">
+ <advance width="1447"/>
+ <unicode hex="004F"/>
+ <anchor x="657" y="0" name="H"/>
+ <anchor x="632" y="-100" name="L"/>
+ <anchor x="896" y="0" name="O"/>
+ <anchor x="1700" y="1200" name="R"/>
+ <anchor x="1039" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="719" y="147" type="curve" smooth="yes"/>
+ <point x="514" y="147"/>
+ <point x="386" y="300"/>
+ <point x="386" y="541" type="curve" smooth="yes"/>
+ <point x="386" y="871"/>
+ <point x="606" y="1284"/>
+ <point x="963" y="1284" type="curve" smooth="yes"/>
+ <point x="1164" y="1284"/>
+ <point x="1291" y="1133"/>
+ <point x="1291" y="892" type="curve" smooth="yes"/>
+ <point x="1291" y="563"/>
+ <point x="1077" y="147"/>
+ </contour>
+ <contour>
+ <point x="1492" y="931" type="curve" smooth="yes"/>
+ <point x="1492" y="1263"/>
+ <point x="1278" y="1455"/>
+ <point x="1015" y="1455" type="curve" smooth="yes"/>
+ <point x="599" y="1455"/>
+ <point x="185" y="1036"/>
+ <point x="185" y="500" type="curve" smooth="yes"/>
+ <point x="185" y="167"/>
+ <point x="400" y="-25"/>
+ <point x="666" y="-25" type="curve" smooth="yes"/>
+ <point x="1078" y="-25"/>
+ <point x="1492" y="395"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfnormalize.ufo/glyphs/L_tnC_apP_.glif b/tests/reference/ufo/psfnormalize.ufo/glyphs/L_tnC_apP_.glif
new file mode 100644
index 0000000..5b51a57
--- /dev/null
+++ b/tests/reference/ufo/psfnormalize.ufo/glyphs/L_tnC_apP_.glif
@@ -0,0 +1,50 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnCapP" format="2">
+ <advance width="1190"/>
+ <unicode hex="0050"/>
+ <anchor x="552" y="-100" name="L"/>
+ <anchor x="959" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="443" y="554" type="line"/>
+ <point x="506" y="547"/>
+ <point x="597" y="544"/>
+ <point x="670" y="544" type="curve" smooth="yes"/>
+ <point x="1058" y="544"/>
+ <point x="1321" y="733"/>
+ <point x="1321" y="1084" type="curve" smooth="yes"/>
+ <point x="1321" y="1302"/>
+ <point x="1141" y="1441"/>
+ <point x="864" y="1441" type="curve" smooth="yes"/>
+ <point x="651" y="1441"/>
+ <point x="456" y="1431"/>
+ <point x="456" y="1431" type="curve"/>
+ <point x="452" y="1352"/>
+ <point x="407" y="1172"/>
+ <point x="359" y="980" type="curve"/>
+ <point x="221" y="426" type="line" smooth="yes"/>
+ <point x="173" y="233"/>
+ <point x="134" y="78"/>
+ <point x="100" y="0" type="curve"/>
+ <point x="320" y="0" type="line"/>
+ <point x="324" y="76"/>
+ <point x="362" y="232"/>
+ <point x="411" y="426" type="curve" smooth="yes"/>
+ </contour>
+ <contour>
+ <point x="623" y="1279" type="line"/>
+ <point x="692" y="1282"/>
+ <point x="721" y="1284"/>
+ <point x="815" y="1284" type="curve" smooth="yes"/>
+ <point x="1036" y="1284"/>
+ <point x="1121" y="1172"/>
+ <point x="1121" y="1048" type="curve" smooth="yes"/>
+ <point x="1121" y="845"/>
+ <point x="968" y="696"/>
+ <point x="693" y="696" type="curve" smooth="yes"/>
+ <point x="618" y="696"/>
+ <point x="542" y="698"/>
+ <point x="481" y="706" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfnormalize.ufo/glyphs/L_tnC_apQ_.glif b/tests/reference/ufo/psfnormalize.ufo/glyphs/L_tnC_apQ_.glif
new file mode 100644
index 0000000..3dcbc8d
--- /dev/null
+++ b/tests/reference/ufo/psfnormalize.ufo/glyphs/L_tnC_apQ_.glif
@@ -0,0 +1,52 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnCapQ" format="2">
+ <advance width="1459"/>
+ <unicode hex="0051"/>
+ <anchor x="589" y="-270" name="L"/>
+ <anchor x="1039" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="1495" y="939" type="curve" smooth="yes"/>
+ <point x="1495" y="1266"/>
+ <point x="1306" y="1455"/>
+ <point x="1026" y="1455" type="curve" smooth="yes"/>
+ <point x="703" y="1455"/>
+ <point x="332" y="1195"/>
+ <point x="215" y="726" type="curve" smooth="yes"/>
+ <point x="194" y="642"/>
+ <point x="185" y="564"/>
+ <point x="185" y="492" type="curve" smooth="yes"/>
+ <point x="185" y="165"/>
+ <point x="388" y="-25"/>
+ <point x="652" y="-25" type="curve" smooth="yes"/>
+ <point x="714" y="-25"/>
+ <point x="781" y="-17"/>
+ <point x="829" y="0" type="curve"/>
+ <point x="898" y="0"/>
+ <point x="1133" y="-186"/>
+ <point x="1217" y="-186" type="curve" smooth="yes"/>
+ <point x="1271" y="-186"/>
+ <point x="1355" y="-79"/>
+ <point x="1388" y="-44" type="curve"/>
+ <point x="1258" y="-27"/>
+ <point x="1155" y="27"/>
+ <point x="1049" y="103" type="curve"/>
+ <point x="1253" y="217"/>
+ <point x="1495" y="528"/>
+ </contour>
+ <contour>
+ <point x="690" y="147" type="curve" smooth="yes"/>
+ <point x="492" y="147"/>
+ <point x="384" y="284"/>
+ <point x="384" y="508" type="curve" smooth="yes"/>
+ <point x="384" y="856"/>
+ <point x="609" y="1284"/>
+ <point x="994" y="1284" type="curve" smooth="yes"/>
+ <point x="1188" y="1284"/>
+ <point x="1295" y="1149"/>
+ <point x="1295" y="925" type="curve" smooth="yes"/>
+ <point x="1295" y="490"/>
+ <point x="985" y="147"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfnormalize.ufo/glyphs/L_tnC_apR_.glif b/tests/reference/ufo/psfnormalize.ufo/glyphs/L_tnC_apR_.glif
new file mode 100644
index 0000000..c8f8186
--- /dev/null
+++ b/tests/reference/ufo/psfnormalize.ufo/glyphs/L_tnC_apR_.glif
@@ -0,0 +1,55 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnCapR" format="2">
+ <advance width="1295"/>
+ <unicode hex="0052"/>
+ <anchor x="590" y="0" name="H"/>
+ <anchor x="525" y="-100" name="L"/>
+ <anchor x="932" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="457" y="613" type="line"/>
+ <point x="712" y="613" type="line" smooth="yes"/>
+ <point x="1010" y="613"/>
+ <point x="1303" y="784"/>
+ <point x="1303" y="1114" type="curve" smooth="yes"/>
+ <point x="1303" y="1326"/>
+ <point x="1114" y="1441"/>
+ <point x="844" y="1441" type="curve" smooth="yes"/>
+ <point x="610" y="1441"/>
+ <point x="456" y="1431"/>
+ <point x="456" y="1431" type="curve"/>
+ <point x="452" y="1352"/>
+ <point x="407" y="1172"/>
+ <point x="359" y="980" type="curve" smooth="yes"/>
+ <point x="221" y="426" type="line"/>
+ <point x="173" y="233"/>
+ <point x="134" y="78"/>
+ <point x="100" y="0" type="curve"/>
+ <point x="320" y="0" type="line"/>
+ <point x="324" y="76"/>
+ <point x="363" y="233"/>
+ <point x="411" y="426" type="curve"/>
+ </contour>
+ <contour>
+ <point x="623" y="1279" type="line"/>
+ <point x="677" y="1281"/>
+ <point x="725" y="1284"/>
+ <point x="795" y="1284" type="curve" smooth="yes"/>
+ <point x="1003" y="1284"/>
+ <point x="1104" y="1203"/>
+ <point x="1104" y="1076" type="curve" smooth="yes"/>
+ <point x="1104" y="856"/>
+ <point x="921" y="764"/>
+ <point x="685" y="764" type="curve" smooth="yes"/>
+ <point x="495" y="764" type="line"/>
+ </contour>
+ <contour>
+ <point x="656" y="622" type="line"/>
+ <point x="930" y="0" type="line"/>
+ <point x="1185" y="0" type="line"/>
+ <point x="1122" y="89"/>
+ <point x="864" y="602"/>
+ <point x="828" y="676" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfnormalize.ufo/glyphs/L_tnC_apS_.glif b/tests/reference/ufo/psfnormalize.ufo/glyphs/L_tnC_apS_.glif
new file mode 100644
index 0000000..01e9f47
--- /dev/null
+++ b/tests/reference/ufo/psfnormalize.ufo/glyphs/L_tnC_apS_.glif
@@ -0,0 +1,50 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnCapS" format="2">
+ <advance width="1155"/>
+ <unicode hex="0053"/>
+ <anchor x="520" y="0" name="H"/>
+ <anchor x="495" y="-100" name="L"/>
+ <anchor x="902" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="1260" y="1347" type="line"/>
+ <point x="1146" y="1419"/>
+ <point x="1021" y="1455"/>
+ <point x="867" y="1455" type="curve" smooth="yes"/>
+ <point x="549" y="1455"/>
+ <point x="320" y="1303"/>
+ <point x="320" y="1040" type="curve" smooth="yes"/>
+ <point x="320" y="901"/>
+ <point x="438" y="794"/>
+ <point x="622" y="691" type="curve" smooth="yes"/>
+ <point x="877" y="549"/>
+ <point x="914" y="461"/>
+ <point x="914" y="378" type="curve" smooth="yes"/>
+ <point x="914" y="256"/>
+ <point x="792" y="147"/>
+ <point x="621" y="147" type="curve" smooth="yes"/>
+ <point x="473" y="147"/>
+ <point x="278" y="235"/>
+ <point x="161" y="378" type="curve"/>
+ <point x="65" y="187" type="line"/>
+ <point x="178" y="73"/>
+ <point x="365" y="-25"/>
+ <point x="558" y="-25" type="curve" smooth="yes"/>
+ <point x="852" y="-25"/>
+ <point x="1114" y="115"/>
+ <point x="1114" y="414" type="curve" smooth="yes"/>
+ <point x="1114" y="526"/>
+ <point x="1057" y="679"/>
+ <point x="800" y="828" type="curve" smooth="yes"/>
+ <point x="597" y="946"/>
+ <point x="510" y="1005"/>
+ <point x="510" y="1079" type="curve" smooth="yes"/>
+ <point x="510" y="1210"/>
+ <point x="659" y="1284"/>
+ <point x="845" y="1284" type="curve" smooth="yes"/>
+ <point x="959" y="1284"/>
+ <point x="1075" y="1240"/>
+ <point x="1173" y="1156" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfnormalize.ufo/glyphs/L_tnC_apT_.glif b/tests/reference/ufo/psfnormalize.ufo/glyphs/L_tnC_apT_.glif
new file mode 100644
index 0000000..0eeece4
--- /dev/null
+++ b/tests/reference/ufo/psfnormalize.ufo/glyphs/L_tnC_apT_.glif
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnCapT" format="2">
+ <advance width="1245"/>
+ <unicode hex="0054"/>
+ <anchor x="562" y="0" name="H"/>
+ <anchor x="562" y="-100" name="L"/>
+ <anchor x="944" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="341" y="1431" type="line"/>
+ <point x="296" y="1250" type="line"/>
+ <point x="380" y="1266"/>
+ <point x="457" y="1269"/>
+ <point x="546" y="1269" type="curve" smooth="yes"/>
+ <point x="781" y="1269" type="line"/>
+ <point x="571" y="426" type="line" smooth="yes"/>
+ <point x="523" y="233"/>
+ <point x="481" y="78"/>
+ <point x="445" y="0" type="curve"/>
+ <point x="675" y="0" type="line"/>
+ <point x="677" y="78"/>
+ <point x="713" y="233"/>
+ <point x="761" y="426" type="curve" smooth="yes"/>
+ <point x="971" y="1269" type="line"/>
+ <point x="1211" y="1269" type="line" smooth="yes"/>
+ <point x="1301" y="1269"/>
+ <point x="1375" y="1266"/>
+ <point x="1451" y="1250" type="curve"/>
+ <point x="1496" y="1431" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfnormalize.ufo/glyphs/L_tnC_apU_.glif b/tests/reference/ufo/psfnormalize.ufo/glyphs/L_tnC_apU_.glif
new file mode 100644
index 0000000..9576e20
--- /dev/null
+++ b/tests/reference/ufo/psfnormalize.ufo/glyphs/L_tnC_apU_.glif
@@ -0,0 +1,44 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnCapU" format="2">
+ <advance width="1420"/>
+ <unicode hex="0055"/>
+ <anchor x="647" y="0" name="H"/>
+ <anchor x="622" y="-100" name="L"/>
+ <anchor x="865" y="0" name="O"/>
+ <anchor x="1640" y="1200" name="R"/>
+ <anchor x="1029" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="1346" y="1431" type="line"/>
+ <point x="1126" y="549" type="line" smooth="yes"/>
+ <point x="1055" y="264"/>
+ <point x="916" y="132"/>
+ <point x="682" y="132" type="curve" smooth="yes"/>
+ <point x="485" y="132"/>
+ <point x="421" y="244"/>
+ <point x="421" y="391" type="curve" smooth="yes"/>
+ <point x="421" y="451"/>
+ <point x="431" y="516"/>
+ <point x="448" y="582" type="curve" smooth="yes"/>
+ <point x="661" y="1431" type="line"/>
+ <point x="456" y="1431" type="line"/>
+ <point x="451" y="1352"/>
+ <point x="414" y="1198"/>
+ <point x="365" y="1005" type="curve" smooth="yes"/>
+ <point x="251" y="552" type="line" smooth="yes"/>
+ <point x="236" y="493"/>
+ <point x="228" y="435"/>
+ <point x="228" y="379" type="curve" smooth="yes"/>
+ <point x="228" y="157"/>
+ <point x="351" y="-25"/>
+ <point x="643" y="-25" type="curve" smooth="yes"/>
+ <point x="1020" y="-25"/>
+ <point x="1223" y="177"/>
+ <point x="1299" y="480" type="curve" smooth="yes"/>
+ <point x="1430" y="1005" type="line" smooth="yes"/>
+ <point x="1480" y="1207"/>
+ <point x="1519" y="1352"/>
+ <point x="1551" y="1431" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfnormalize.ufo/glyphs/L_tnC_apV_.glif b/tests/reference/ufo/psfnormalize.ufo/glyphs/L_tnC_apV_.glif
new file mode 100644
index 0000000..2bf8b96
--- /dev/null
+++ b/tests/reference/ufo/psfnormalize.ufo/glyphs/L_tnC_apV_.glif
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnCapV" format="2">
+ <advance width="1345"/>
+ <unicode hex="0056"/>
+ <anchor x="620" y="0" name="H"/>
+ <anchor x="587" y="-100" name="L"/>
+ <anchor x="820" y="0" name="O"/>
+ <anchor x="994" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="1381" y="1431" type="line"/>
+ <point x="654" y="191" type="line"/>
+ <point x="536" y="1431" type="line"/>
+ <point x="331" y="1431" type="line"/>
+ <point x="344" y="1350"/>
+ <point x="355" y="1262"/>
+ <point x="377" y="1073" type="curve" smooth="yes"/>
+ <point x="500" y="0" type="line"/>
+ <point x="725" y="0" type="line"/>
+ <point x="1377" y="1073" type="line" smooth="yes"/>
+ <point x="1492" y="1263"/>
+ <point x="1550" y="1350"/>
+ <point x="1606" y="1431" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfnormalize.ufo/glyphs/L_tnC_apW_.glif b/tests/reference/ufo/psfnormalize.ufo/glyphs/L_tnC_apW_.glif
new file mode 100644
index 0000000..553ea17
--- /dev/null
+++ b/tests/reference/ufo/psfnormalize.ufo/glyphs/L_tnC_apW_.glif
@@ -0,0 +1,44 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnCapW" format="2">
+ <advance width="2060"/>
+ <unicode hex="0057"/>
+ <anchor x="942" y="-100" name="L"/>
+ <anchor x="1349" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="1535" y="0" type="line"/>
+ <point x="2107" y="1073" type="line" smooth="yes"/>
+ <point x="2208" y="1263"/>
+ <point x="2259" y="1350"/>
+ <point x="2311" y="1431" type="curve"/>
+ <point x="2081" y="1431" type="line"/>
+ <point x="1431" y="127" type="line"/>
+ <point x="1420" y="0" type="line"/>
+ </contour>
+ <contour>
+ <point x="1310" y="0" type="line"/>
+ <point x="1420" y="0" type="line"/>
+ <point x="1461" y="127" type="line"/>
+ <point x="1406" y="1431" type="line"/>
+ <point x="1231" y="1431" type="line"/>
+ <point x="1248" y="1279" type="line"/>
+ </contour>
+ <contour>
+ <point x="625" y="0" type="line"/>
+ <point x="1406" y="1431" type="line"/>
+ <point x="1221" y="1431" type="line"/>
+ <point x="521" y="127" type="line"/>
+ <point x="521" y="0" type="line"/>
+ </contour>
+ <contour>
+ <point x="546" y="1431" type="line"/>
+ <point x="336" y="1431" type="line"/>
+ <point x="348" y="1353"/>
+ <point x="355" y="1260"/>
+ <point x="362" y="1073" type="curve" smooth="yes"/>
+ <point x="400" y="0" type="line"/>
+ <point x="521" y="0" type="line"/>
+ <point x="551" y="127" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfnormalize.ufo/glyphs/L_tnC_apX_.glif b/tests/reference/ufo/psfnormalize.ufo/glyphs/L_tnC_apX_.glif
new file mode 100644
index 0000000..2da5787
--- /dev/null
+++ b/tests/reference/ufo/psfnormalize.ufo/glyphs/L_tnC_apX_.glif
@@ -0,0 +1,39 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnCapX" format="2">
+ <advance width="1305"/>
+ <unicode hex="0058"/>
+ <anchor x="565" y="-100" name="L"/>
+ <anchor x="972" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="970" y="0" type="line"/>
+ <point x="1190" y="0" type="line"/>
+ <point x="1148" y="80"/>
+ <point x="1125" y="124"/>
+ <point x="1045" y="329" type="curve" smooth="yes"/>
+ <point x="611" y="1431" type="line"/>
+ <point x="386" y="1431" type="line"/>
+ <point x="430" y="1348"/>
+ <point x="462" y="1289"/>
+ <point x="541" y="1088" type="curve" smooth="yes"/>
+ </contour>
+ <contour>
+ <point x="752" y="872" type="line"/>
+ <point x="278" y="333" type="line" smooth="yes"/>
+ <point x="98" y="129"/>
+ <point x="53" y="84"/>
+ <point x="-30" y="0" type="curve"/>
+ <point x="210" y="0" type="line"/>
+ <point x="750" y="622" type="line"/>
+ </contour>
+ <contour>
+ <point x="765" y="622" type="line"/>
+ <point x="1183" y="1088" type="line" smooth="yes"/>
+ <point x="1360" y="1285"/>
+ <point x="1425" y="1355"/>
+ <point x="1506" y="1431" type="curve"/>
+ <point x="1261" y="1431" type="line"/>
+ <point x="767" y="872" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfnormalize.ufo/glyphs/L_tnC_apY_.glif b/tests/reference/ufo/psfnormalize.ufo/glyphs/L_tnC_apY_.glif
new file mode 100644
index 0000000..9ec65ef
--- /dev/null
+++ b/tests/reference/ufo/psfnormalize.ufo/glyphs/L_tnC_apY_.glif
@@ -0,0 +1,39 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnCapY" format="2">
+ <advance width="1300"/>
+ <unicode hex="0059"/>
+ <anchor x="565" y="-100" name="L"/>
+ <anchor x="972" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="331" y="1431" type="line"/>
+ <point x="407" y="1285"/>
+ <point x="446" y="1173"/>
+ <point x="490" y="1044" type="curve"/>
+ <point x="661" y="549" type="line"/>
+ <point x="829" y="661" type="line"/>
+ <point x="551" y="1431" type="line"/>
+ </contour>
+ <contour>
+ <point x="1321" y="1431" type="line"/>
+ <point x="684" y="661" type="line"/>
+ <point x="796" y="549" type="line"/>
+ <point x="1215" y="1044" type="line" smooth="yes"/>
+ <point x="1322" y="1171"/>
+ <point x="1402" y="1265"/>
+ <point x="1561" y="1431" type="curve"/>
+ </contour>
+ <contour>
+ <point x="700" y="0" type="line"/>
+ <point x="704" y="78"/>
+ <point x="743" y="233"/>
+ <point x="791" y="426" type="curve" smooth="yes"/>
+ <point x="854" y="681" type="line"/>
+ <point x="664" y="681" type="line"/>
+ <point x="601" y="426" type="line" smooth="yes"/>
+ <point x="553" y="233"/>
+ <point x="514" y="78"/>
+ <point x="480" y="0" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfnormalize.ufo/glyphs/L_tnS_mA_.glif b/tests/reference/ufo/psfnormalize.ufo/glyphs/L_tnS_mA_.glif
new file mode 100644
index 0000000..586e494
--- /dev/null
+++ b/tests/reference/ufo/psfnormalize.ufo/glyphs/L_tnS_mA_.glif
@@ -0,0 +1,77 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmA" format="2">
+ <advance width="1107"/>
+ <unicode hex="0061"/>
+ <anchor x="860" y="0" name="H"/>
+ <anchor x="455" y="-100" name="L"/>
+ <anchor x="1065" y="0" name="O"/>
+ <anchor x="1310" y="1000" name="R"/>
+ <anchor x="755" y="1100" name="U"/>
+ <outline>
+ <contour>
+ <point x="972" y="0" type="line"/>
+ <point x="965" y="48"/>
+ <point x="960" y="98"/>
+ <point x="960" y="149" type="curve" smooth="yes"/>
+ <point x="960" y="214"/>
+ <point x="967" y="284"/>
+ <point x="987" y="363" type="curve"/>
+ <point x="1077" y="726" type="line"/>
+ <point x="1081" y="744"/>
+ <point x="1084" y="762"/>
+ <point x="1084" y="779" type="curve" smooth="yes"/>
+ <point x="1084" y="912"/>
+ <point x="955" y="1019"/>
+ <point x="751" y="1019" type="curve" smooth="yes"/>
+ <point x="599" y="1019"/>
+ <point x="502" y="974"/>
+ <point x="389" y="931" type="curve"/>
+ <point x="373" y="889"/>
+ <point x="343" y="783"/>
+ <point x="331" y="740" type="curve"/>
+ <point x="468" y="820"/>
+ <point x="560" y="862"/>
+ <point x="666" y="862" type="curve" smooth="yes"/>
+ <point x="798" y="862"/>
+ <point x="885" y="810"/>
+ <point x="885" y="718" type="curve" smooth="yes"/>
+ <point x="885" y="705"/>
+ <point x="884" y="691"/>
+ <point x="880" y="677" type="curve" smooth="yes"/>
+ <point x="867" y="622" type="line"/>
+ <point x="825" y="619"/>
+ <point x="661" y="605"/>
+ <point x="591" y="598" type="curve" smooth="yes"/>
+ <point x="282" y="568"/>
+ <point x="102" y="415"/>
+ <point x="102" y="233" type="curve" smooth="yes"/>
+ <point x="102" y="103"/>
+ <point x="223" y="-25"/>
+ <point x="390" y="-25" type="curve" smooth="yes"/>
+ <point x="514" y="-25"/>
+ <point x="674" y="47"/>
+ <point x="779" y="152" type="curve"/>
+ <point x="779" y="89"/>
+ <point x="787" y="31"/>
+ <point x="792" y="0" type="curve"/>
+ </contour>
+ <contour>
+ <point x="791" y="319" type="line"/>
+ <point x="674" y="191"/>
+ <point x="553" y="137"/>
+ <point x="451" y="137" type="curve" smooth="yes"/>
+ <point x="355" y="137"/>
+ <point x="290" y="192"/>
+ <point x="290" y="264" type="curve" smooth="yes"/>
+ <point x="290" y="274"/>
+ <point x="291" y="285"/>
+ <point x="294" y="296" type="curve" smooth="yes"/>
+ <point x="315" y="380"/>
+ <point x="432" y="450"/>
+ <point x="566" y="461" type="curve" smooth="yes"/>
+ <point x="631" y="466"/>
+ <point x="782" y="483"/>
+ <point x="832" y="485" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfnormalize.ufo/glyphs/L_tnS_mA_A_cute.glif b/tests/reference/ufo/psfnormalize.ufo/glyphs/L_tnS_mA_A_cute.glif
new file mode 100644
index 0000000..198d6db
--- /dev/null
+++ b/tests/reference/ufo/psfnormalize.ufo/glyphs/L_tnS_mA_A_cute.glif
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmAAcute" format="2">
+ <advance width="1107"/>
+ <unicode hex="00E1"/>
+ <anchor x="860" y="0" name="H"/>
+ <anchor x="455" y="-100" name="L"/>
+ <anchor x="1065" y="0" name="O"/>
+ <anchor x="1310" y="1000" name="R"/>
+ <anchor x="889" y="1635" name="U"/>
+ <outline>
+ <component base="LtnSmA"/>
+ <component base="CombAcute" xOffset="1110"/>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfnormalize.ufo/glyphs/L_tnS_mA_C_ircum.glif b/tests/reference/ufo/psfnormalize.ufo/glyphs/L_tnS_mA_C_ircum.glif
new file mode 100644
index 0000000..f5cfb16
--- /dev/null
+++ b/tests/reference/ufo/psfnormalize.ufo/glyphs/L_tnS_mA_C_ircum.glif
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmACircum" format="2">
+ <advance width="1107"/>
+ <unicode hex="00E2"/>
+ <anchor x="860" y="0" name="H"/>
+ <anchor x="455" y="-100" name="L"/>
+ <anchor x="1065" y="0" name="O"/>
+ <anchor x="1310" y="1000" name="R"/>
+ <anchor x="854" y="1635" name="U"/>
+ <outline>
+ <component base="LtnSmA"/>
+ <component base="CombCircum" xOffset="1075"/>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfnormalize.ufo/glyphs/L_tnS_mA_D_iaer.glif b/tests/reference/ufo/psfnormalize.ufo/glyphs/L_tnS_mA_D_iaer.glif
new file mode 100644
index 0000000..6f05301
--- /dev/null
+++ b/tests/reference/ufo/psfnormalize.ufo/glyphs/L_tnS_mA_D_iaer.glif
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmADiaer" format="2">
+ <advance width="1107"/>
+ <unicode hex="00E4"/>
+ <anchor x="860" y="0" name="H"/>
+ <anchor x="455" y="-100" name="L"/>
+ <anchor x="1065" y="0" name="O"/>
+ <anchor x="1310" y="1000" name="R"/>
+ <anchor x="852" y="1505" name="U"/>
+ <outline>
+ <component base="LtnSmA"/>
+ <component base="CombDiaer" xOffset="1105"/>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfnormalize.ufo/glyphs/L_tnS_mA_G_rave.glif b/tests/reference/ufo/psfnormalize.ufo/glyphs/L_tnS_mA_G_rave.glif
new file mode 100644
index 0000000..9048920
--- /dev/null
+++ b/tests/reference/ufo/psfnormalize.ufo/glyphs/L_tnS_mA_G_rave.glif
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmAGrave" format="2">
+ <advance width="1107"/>
+ <unicode hex="00E0"/>
+ <anchor x="860" y="0" name="H"/>
+ <anchor x="455" y="-100" name="L"/>
+ <anchor x="1065" y="0" name="O"/>
+ <anchor x="1310" y="1000" name="R"/>
+ <anchor x="889" y="1635" name="U"/>
+ <outline>
+ <component base="LtnSmA"/>
+ <component base="CombGrave" xOffset="1090"/>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfnormalize.ufo/glyphs/L_tnS_mA_R_ingA_bv.glif b/tests/reference/ufo/psfnormalize.ufo/glyphs/L_tnS_mA_R_ingA_bv.glif
new file mode 100644
index 0000000..8ada58f
--- /dev/null
+++ b/tests/reference/ufo/psfnormalize.ufo/glyphs/L_tnS_mA_R_ingA_bv.glif
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmARingAbv" format="2">
+ <advance width="1107"/>
+ <unicode hex="00E5"/>
+ <anchor x="860" y="0" name="H"/>
+ <anchor x="455" y="-100" name="L"/>
+ <anchor x="1065" y="0" name="O"/>
+ <anchor x="1310" y="1000" name="R"/>
+ <anchor x="919" y="1635" name="U"/>
+ <outline>
+ <component base="LtnSmA"/>
+ <component base="CombRingAbv" xOffset="1140"/>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfnormalize.ufo/glyphs/L_tnS_mA_T_ilde.glif b/tests/reference/ufo/psfnormalize.ufo/glyphs/L_tnS_mA_T_ilde.glif
new file mode 100644
index 0000000..c29348b
--- /dev/null
+++ b/tests/reference/ufo/psfnormalize.ufo/glyphs/L_tnS_mA_T_ilde.glif
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmATilde" format="2">
+ <advance width="1107"/>
+ <unicode hex="00E3"/>
+ <anchor x="860" y="0" name="H"/>
+ <anchor x="455" y="-100" name="L"/>
+ <anchor x="1065" y="0" name="O"/>
+ <anchor x="1310" y="1000" name="R"/>
+ <anchor x="850" y="1475" name="U"/>
+ <outline>
+ <component base="LtnSmA"/>
+ <component base="CombTilde" xOffset="1140"/>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfnormalize.ufo/glyphs/L_tnS_mB_.glif b/tests/reference/ufo/psfnormalize.ufo/glyphs/L_tnS_mB_.glif
new file mode 100644
index 0000000..b3a3696
--- /dev/null
+++ b/tests/reference/ufo/psfnormalize.ufo/glyphs/L_tnS_mB_.glif
@@ -0,0 +1,55 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmB" format="2">
+ <advance width="1144"/>
+ <unicode hex="0062"/>
+ <anchor x="530" y="0" name="H"/>
+ <anchor x="505" y="-100" name="L"/>
+ <anchor x="1345" y="1000" name="R"/>
+ <anchor x="938" y="1635" name="U"/>
+ <outline>
+ <contour>
+ <point x="437" y="1570" type="line"/>
+ <point x="437" y="1456"/>
+ <point x="402" y="1246"/>
+ <point x="367" y="1105" type="curve" smooth="yes"/>
+ <point x="110" y="85" type="line"/>
+ <point x="198" y="44"/>
+ <point x="355" y="-25"/>
+ <point x="517" y="-25" type="curve" smooth="yes"/>
+ <point x="675" y="-25"/>
+ <point x="795" y="24"/>
+ <point x="907" y="125" type="curve" smooth="yes"/>
+ <point x="1050" y="255"/>
+ <point x="1162" y="466"/>
+ <point x="1162" y="695" type="curve" smooth="yes"/>
+ <point x="1162" y="930"/>
+ <point x="1046" y="1020"/>
+ <point x="907" y="1020" type="curve" smooth="yes"/>
+ <point x="754" y="1020"/>
+ <point x="584" y="878"/>
+ <point x="456" y="719" type="curve"/>
+ <point x="552" y="1105" type="line" smooth="yes"/>
+ <point x="600" y="1296"/>
+ <point x="627" y="1508"/>
+ <point x="627" y="1570" type="curve"/>
+ </contour>
+ <contour>
+ <point x="382" y="429" type="line"/>
+ <point x="485" y="617"/>
+ <point x="708" y="850"/>
+ <point x="822" y="850" type="curve" smooth="yes"/>
+ <point x="913" y="850"/>
+ <point x="972" y="784"/>
+ <point x="972" y="635" type="curve" smooth="yes"/>
+ <point x="972" y="469"/>
+ <point x="909" y="336"/>
+ <point x="822" y="250" type="curve" smooth="yes"/>
+ <point x="741" y="169"/>
+ <point x="638" y="125"/>
+ <point x="552" y="125" type="curve" smooth="yes"/>
+ <point x="466" y="125"/>
+ <point x="376" y="167"/>
+ <point x="325" y="200" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfnormalize.ufo/glyphs/L_tnS_mC_.glif b/tests/reference/ufo/psfnormalize.ufo/glyphs/L_tnS_mC_.glif
new file mode 100644
index 0000000..f54fbe9
--- /dev/null
+++ b/tests/reference/ufo/psfnormalize.ufo/glyphs/L_tnS_mC_.glif
@@ -0,0 +1,39 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmC" format="2">
+ <advance width="989"/>
+ <unicode hex="0063"/>
+ <anchor x="520" y="0" name="H"/>
+ <anchor x="495" y="-100" name="L"/>
+ <anchor x="1210" y="1000" name="R"/>
+ <anchor x="785" y="1100" name="U"/>
+ <outline>
+ <contour>
+ <point x="917" y="255" type="line"/>
+ <point x="811" y="179"/>
+ <point x="703" y="137"/>
+ <point x="583" y="137" type="curve" smooth="yes"/>
+ <point x="427" y="137"/>
+ <point x="331" y="239"/>
+ <point x="331" y="406" type="curve" smooth="yes"/>
+ <point x="331" y="619"/>
+ <point x="499" y="858"/>
+ <point x="742" y="858" type="curve" smooth="yes"/>
+ <point x="845" y="858"/>
+ <point x="924" y="824"/>
+ <point x="998" y="760" type="curve"/>
+ <point x="1077" y="936" type="line"/>
+ <point x="1016" y="985"/>
+ <point x="902" y="1020"/>
+ <point x="789" y="1020" type="curve" smooth="yes"/>
+ <point x="420" y="1020"/>
+ <point x="139" y="737"/>
+ <point x="139" y="381" type="curve" smooth="yes"/>
+ <point x="139" y="130"/>
+ <point x="309" y="-25"/>
+ <point x="532" y="-25" type="curve" smooth="yes"/>
+ <point x="682" y="-25"/>
+ <point x="785" y="9"/>
+ <point x="904" y="83" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfnormalize.ufo/glyphs/L_tnS_mD_.glif b/tests/reference/ufo/psfnormalize.ufo/glyphs/L_tnS_mD_.glif
new file mode 100644
index 0000000..4ea9ea1
--- /dev/null
+++ b/tests/reference/ufo/psfnormalize.ufo/glyphs/L_tnS_mD_.glif
@@ -0,0 +1,65 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmD" format="2">
+ <advance width="1197"/>
+ <unicode hex="0064"/>
+ <anchor x="545" y="0" name="H"/>
+ <anchor x="520" y="-100" name="L"/>
+ <anchor x="1380" y="1000" name="R"/>
+ <anchor x="953" y="1635" name="U"/>
+ <outline>
+ <contour>
+ <point x="1144" y="1570" type="line"/>
+ <point x="1144" y="1456"/>
+ <point x="1114" y="1327"/>
+ <point x="1079" y="1175" type="curve" smooth="yes"/>
+ <point x="1024" y="935" type="line"/>
+ <point x="957" y="978"/>
+ <point x="854" y="1020"/>
+ <point x="759" y="1020" type="curve" smooth="yes"/>
+ <point x="650" y="1020"/>
+ <point x="534" y="979"/>
+ <point x="429" y="895" type="curve" smooth="yes"/>
+ <point x="262" y="761"/>
+ <point x="139" y="532"/>
+ <point x="139" y="288" type="curve" smooth="yes"/>
+ <point x="139" y="94"/>
+ <point x="250" y="-25"/>
+ <point x="424" y="-25" type="curve" smooth="yes"/>
+ <point x="563" y="-25"/>
+ <point x="791" y="141"/>
+ <point x="899" y="305" type="curve"/>
+ <point x="875" y="196"/>
+ <point x="869" y="93"/>
+ <point x="869" y="0" type="curve"/>
+ <point x="1052" y="0" type="line"/>
+ <point x="1048" y="23"/>
+ <point x="1047" y="53"/>
+ <point x="1047" y="90" type="curve" smooth="yes"/>
+ <point x="1047" y="190"/>
+ <point x="1063" y="340"/>
+ <point x="1107" y="520" type="curve" smooth="yes"/>
+ <point x="1267" y="1175" type="line" smooth="yes"/>
+ <point x="1310" y="1351"/>
+ <point x="1337" y="1475"/>
+ <point x="1337" y="1570" type="curve"/>
+ </contour>
+ <contour>
+ <point x="930" y="545" type="line"/>
+ <point x="846" y="370"/>
+ <point x="592" y="130"/>
+ <point x="479" y="130" type="curve" smooth="yes"/>
+ <point x="374" y="130"/>
+ <point x="330" y="195"/>
+ <point x="330" y="316" type="curve" smooth="yes"/>
+ <point x="330" y="460"/>
+ <point x="397" y="649"/>
+ <point x="509" y="760" type="curve" smooth="yes"/>
+ <point x="572" y="822"/>
+ <point x="643" y="855"/>
+ <point x="734" y="855" type="curve" smooth="yes"/>
+ <point x="835" y="855"/>
+ <point x="898" y="832"/>
+ <point x="984" y="780" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfnormalize.ufo/glyphs/L_tnS_mE_.glif b/tests/reference/ufo/psfnormalize.ufo/glyphs/L_tnS_mE_.glif
new file mode 100644
index 0000000..a3a6490
--- /dev/null
+++ b/tests/reference/ufo/psfnormalize.ufo/glyphs/L_tnS_mE_.glif
@@ -0,0 +1,52 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmE" format="2">
+ <advance width="1042"/>
+ <unicode hex="0065"/>
+ <anchor x="485" y="0" name="H"/>
+ <anchor x="484" y="-100" name="L"/>
+ <anchor x="840" y="0" name="O"/>
+ <anchor x="1285" y="1000" name="R"/>
+ <anchor x="784" y="1100" name="U"/>
+ <outline>
+ <contour>
+ <point x="967" y="270" type="line"/>
+ <point x="854" y="189"/>
+ <point x="700" y="135"/>
+ <point x="567" y="135" type="curve" smooth="yes"/>
+ <point x="386" y="135"/>
+ <point x="317" y="263"/>
+ <point x="317" y="420" type="curve" smooth="yes"/>
+ <point x="317" y="686"/>
+ <point x="522" y="872"/>
+ <point x="720" y="872" type="curve" smooth="yes"/>
+ <point x="813" y="872"/>
+ <point x="883" y="823"/>
+ <point x="883" y="753" type="curve" smooth="yes"/>
+ <point x="883" y="660"/>
+ <point x="766" y="590"/>
+ <point x="539" y="590" type="curve" smooth="yes"/>
+ <point x="468" y="590"/>
+ <point x="382" y="596"/>
+ <point x="279" y="610" type="curve"/>
+ <point x="279" y="477" type="line"/>
+ <point x="391" y="461"/>
+ <point x="487" y="453"/>
+ <point x="569" y="453" type="curve" smooth="yes"/>
+ <point x="931" y="453"/>
+ <point x="1077" y="609"/>
+ <point x="1077" y="791" type="curve" smooth="yes"/>
+ <point x="1077" y="899"/>
+ <point x="986" y="1020"/>
+ <point x="772" y="1020" type="curve" smooth="yes"/>
+ <point x="399" y="1020"/>
+ <point x="137" y="710"/>
+ <point x="137" y="380" type="curve" smooth="yes"/>
+ <point x="137" y="147"/>
+ <point x="258" y="-25"/>
+ <point x="523" y="-25" type="curve" smooth="yes"/>
+ <point x="689" y="-25"/>
+ <point x="849" y="26"/>
+ <point x="955" y="83" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfnormalize.ufo/glyphs/L_tnS_mF_.glif b/tests/reference/ufo/psfnormalize.ufo/glyphs/L_tnS_mF_.glif
new file mode 100644
index 0000000..ede52a9
--- /dev/null
+++ b/tests/reference/ufo/psfnormalize.ufo/glyphs/L_tnS_mF_.glif
@@ -0,0 +1,44 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmF" format="2">
+ <advance width="756"/>
+ <unicode hex="0066"/>
+ <anchor x="290" y="0" name="H"/>
+ <anchor x="315" y="-100" name="L"/>
+ <anchor x="908" y="1635" name="U"/>
+ <outline>
+ <contour>
+ <point x="180" y="833" type="line"/>
+ <point x="835" y="833" type="line"/>
+ <point x="871" y="975" type="line"/>
+ <point x="216" y="975" type="line"/>
+ </contour>
+ <contour>
+ <point x="1106" y="1519" type="line"/>
+ <point x="1062" y="1555"/>
+ <point x="981" y="1588"/>
+ <point x="903" y="1588" type="curve" smooth="yes"/>
+ <point x="687" y="1588"/>
+ <point x="533" y="1478"/>
+ <point x="448" y="1147" type="curve" smooth="yes"/>
+ <point x="403" y="972"/>
+ <point x="244" y="334"/>
+ <point x="223" y="0" type="curve"/>
+ <point x="436" y="0" type="line"/>
+ <point x="430" y="28"/>
+ <point x="427" y="66"/>
+ <point x="427" y="110" type="curve" smooth="yes"/>
+ <point x="427" y="213"/>
+ <point x="447" y="351"/>
+ <point x="476" y="484" type="curve" smooth="yes"/>
+ <point x="510" y="641"/>
+ <point x="558" y="846"/>
+ <point x="641" y="1186" type="curve" smooth="yes"/>
+ <point x="682" y="1353"/>
+ <point x="758" y="1421"/>
+ <point x="862" y="1421" type="curve" smooth="yes"/>
+ <point x="920" y="1421"/>
+ <point x="988" y="1392"/>
+ <point x="1022" y="1362" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfnormalize.ufo/glyphs/L_tnS_mG_.glif b/tests/reference/ufo/psfnormalize.ufo/glyphs/L_tnS_mG_.glif
new file mode 100644
index 0000000..8931f8d
--- /dev/null
+++ b/tests/reference/ufo/psfnormalize.ufo/glyphs/L_tnS_mG_.glif
@@ -0,0 +1,100 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmG" format="2">
+ <advance width="1075"/>
+ <unicode hex="0067"/>
+ <anchor x="368" y="-465" name="H"/>
+ <anchor x="351" y="-535" name="L"/>
+ <anchor x="1285" y="1000" name="R"/>
+ <anchor x="730" y="1100" name="U"/>
+ <outline>
+ <contour>
+ <point x="360" y="389" type="line"/>
+ <point x="277" y="352"/>
+ <point x="168" y="266"/>
+ <point x="168" y="176" type="curve" smooth="yes"/>
+ <point x="168" y="96"/>
+ <point x="246" y="33"/>
+ <point x="483" y="-5" type="curve" smooth="yes"/>
+ <point x="707" y="-41"/>
+ <point x="781" y="-94"/>
+ <point x="781" y="-151" type="curve" smooth="yes"/>
+ <point x="781" y="-256"/>
+ <point x="580" y="-353"/>
+ <point x="411" y="-353" type="curve" smooth="yes"/>
+ <point x="202" y="-353"/>
+ <point x="104" y="-271"/>
+ <point x="104" y="-196" type="curve" smooth="yes"/>
+ <point x="104" y="-189"/>
+ <point x="104" y="-183"/>
+ <point x="106" y="-176" type="curve" smooth="yes"/>
+ <point x="120" y="-119"/>
+ <point x="170" y="-55"/>
+ <point x="409" y="20" type="curve"/>
+ <point x="410" y="48"/>
+ <point x="248" y="73"/>
+ <point x="248" y="73" type="curve"/>
+ <point x="53" y="12"/>
+ <point x="-51" y="-77"/>
+ <point x="-78" y="-186" type="curve" smooth="yes"/>
+ <point x="-82" y="-201"/>
+ <point x="-84" y="-217"/>
+ <point x="-84" y="-231" type="curve" smooth="yes"/>
+ <point x="-84" y="-396"/>
+ <point x="158" y="-495"/>
+ <point x="371" y="-495" type="curve" smooth="yes"/>
+ <point x="632" y="-495"/>
+ <point x="972" y="-360"/>
+ <point x="972" y="-125" type="curve" smooth="yes"/>
+ <point x="972" y="0"/>
+ <point x="849" y="90"/>
+ <point x="619" y="127" type="curve" smooth="yes"/>
+ <point x="403" y="162"/>
+ <point x="341" y="184"/>
+ <point x="341" y="218" type="curve" smooth="yes"/>
+ <point x="341" y="263"/>
+ <point x="447" y="325"/>
+ <point x="522" y="342" type="curve"/>
+ </contour>
+ <contour>
+ <point x="1244" y="1019" type="line"/>
+ <point x="1143" y="1012"/>
+ <point x="1002" y="977"/>
+ <point x="899" y="921" type="curve"/>
+ <point x="936" y="809" type="line"/>
+ <point x="1037" y="846"/>
+ <point x="1121" y="860"/>
+ <point x="1194" y="862" type="curve"/>
+ </contour>
+ <contour>
+ <point x="212" y="613" type="curve" smooth="yes"/>
+ <point x="212" y="449"/>
+ <point x="356" y="319"/>
+ <point x="554" y="319" type="curve" smooth="yes"/>
+ <point x="791" y="319"/>
+ <point x="1030" y="495"/>
+ <point x="1030" y="729" type="curve" smooth="yes"/>
+ <point x="1030" y="894"/>
+ <point x="887" y="1019"/>
+ <point x="689" y="1019" type="curve" smooth="yes"/>
+ <point x="441" y="1019"/>
+ <point x="212" y="847"/>
+ </contour>
+ <contour>
+ <point x="857" y="704" type="curve" smooth="yes"/>
+ <point x="857" y="555"/>
+ <point x="712" y="456"/>
+ <point x="578" y="456" type="curve" smooth="yes"/>
+ <point x="463" y="456"/>
+ <point x="385" y="530"/>
+ <point x="385" y="628" type="curve" smooth="yes"/>
+ <point x="385" y="643"/>
+ <point x="387" y="660"/>
+ <point x="391" y="676" type="curve" smooth="yes"/>
+ <point x="421" y="797"/>
+ <point x="530" y="877"/>
+ <point x="663" y="877" type="curve" smooth="yes"/>
+ <point x="779" y="877"/>
+ <point x="857" y="802"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfnormalize.ufo/glyphs/L_tnS_mH_.glif b/tests/reference/ufo/psfnormalize.ufo/glyphs/L_tnS_mH_.glif
new file mode 100644
index 0000000..08afbac
--- /dev/null
+++ b/tests/reference/ufo/psfnormalize.ufo/glyphs/L_tnS_mH_.glif
@@ -0,0 +1,54 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmH" format="2">
+ <advance width="1185"/>
+ <unicode hex="0068"/>
+ <anchor x="190" y="0" name="H"/>
+ <anchor x="550" y="-100" name="L"/>
+ <anchor x="933" y="1635" name="U"/>
+ <outline>
+ <contour>
+ <point x="1055" y="0" type="line"/>
+ <point x="1047" y="30"/>
+ <point x="1043" y="65"/>
+ <point x="1043" y="102" type="curve" smooth="yes"/>
+ <point x="1043" y="143"/>
+ <point x="1048" y="188"/>
+ <point x="1055" y="238" type="curve" smooth="yes"/>
+ <point x="1069" y="327"/>
+ <point x="1170" y="636"/>
+ <point x="1170" y="745" type="curve" smooth="yes"/>
+ <point x="1170" y="917"/>
+ <point x="1095" y="1020"/>
+ <point x="930" y="1020" type="curve" smooth="yes"/>
+ <point x="760" y="1020"/>
+ <point x="591" y="877"/>
+ <point x="475" y="723" type="curve"/>
+ <point x="571" y="1105" type="line" smooth="yes"/>
+ <point x="609" y="1259"/>
+ <point x="645" y="1482"/>
+ <point x="645" y="1570" type="curve"/>
+ <point x="455" y="1570" type="line"/>
+ <point x="455" y="1456"/>
+ <point x="423" y="1257"/>
+ <point x="385" y="1105" type="curve" smooth="yes"/>
+ <point x="110" y="0" type="line"/>
+ <point x="295" y="0" type="line"/>
+ <point x="397" y="408" type="line"/>
+ <point x="492" y="612"/>
+ <point x="717" y="850"/>
+ <point x="840" y="850" type="curve" smooth="yes"/>
+ <point x="937" y="850"/>
+ <point x="970" y="798"/>
+ <point x="970" y="680" type="curve" smooth="yes"/>
+ <point x="970" y="592"/>
+ <point x="886" y="319"/>
+ <point x="872" y="203" type="curve" smooth="yes"/>
+ <point x="867" y="158"/>
+ <point x="864" y="115"/>
+ <point x="864" y="77" type="curve" smooth="yes"/>
+ <point x="864" y="48"/>
+ <point x="866" y="21"/>
+ <point x="870" y="0" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfnormalize.ufo/glyphs/L_tnS_mI_.glif b/tests/reference/ufo/psfnormalize.ufo/glyphs/L_tnS_mI_.glif
new file mode 100644
index 0000000..65ed550
--- /dev/null
+++ b/tests/reference/ufo/psfnormalize.ufo/glyphs/L_tnS_mI_.glif
@@ -0,0 +1,50 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmI" format="2">
+ <advance width="554"/>
+ <unicode hex="0069"/>
+ <anchor x="235" y="0" name="H"/>
+ <anchor x="250" y="-100" name="L"/>
+ <anchor x="455" y="0" name="O"/>
+ <anchor x="745" y="1000" name="R"/>
+ <anchor x="472" y="1100" name="U"/>
+ <outline>
+ <contour>
+ <point x="361" y="1297" type="curve" smooth="yes"/>
+ <point x="361" y="1237"/>
+ <point x="404" y="1186"/>
+ <point x="467" y="1186" type="curve" smooth="yes"/>
+ <point x="552" y="1186"/>
+ <point x="624" y="1259"/>
+ <point x="624" y="1338" type="curve" smooth="yes"/>
+ <point x="624" y="1399"/>
+ <point x="578" y="1450"/>
+ <point x="513" y="1450" type="curve" smooth="yes"/>
+ <point x="428" y="1450"/>
+ <point x="361" y="1375"/>
+ </contour>
+ <contour>
+ <point x="335" y="1000" type="line"/>
+ <point x="335" y="886"/>
+ <point x="286" y="688"/>
+ <point x="246" y="537" type="curve" smooth="yes"/>
+ <point x="207" y="388" type="line" smooth="yes"/>
+ <point x="180" y="284"/>
+ <point x="165" y="172"/>
+ <point x="165" y="87" type="curve" smooth="yes"/>
+ <point x="165" y="53"/>
+ <point x="167" y="24"/>
+ <point x="172" y="0" type="curve"/>
+ <point x="372" y="0" type="line"/>
+ <point x="365" y="37"/>
+ <point x="360" y="85"/>
+ <point x="360" y="136" type="curve" smooth="yes"/>
+ <point x="360" y="208"/>
+ <point x="368" y="287"/>
+ <point x="386" y="357" type="curve" smooth="yes"/>
+ <point x="431" y="536" type="line" smooth="yes"/>
+ <point x="476" y="712"/>
+ <point x="525" y="912"/>
+ <point x="525" y="1000" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfnormalize.ufo/glyphs/L_tnS_mJ_.glif b/tests/reference/ufo/psfnormalize.ufo/glyphs/L_tnS_mJ_.glif
new file mode 100644
index 0000000..e9e18b8
--- /dev/null
+++ b/tests/reference/ufo/psfnormalize.ufo/glyphs/L_tnS_mJ_.glif
@@ -0,0 +1,45 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmJ" format="2">
+ <advance width="602"/>
+ <unicode hex="006A"/>
+ <anchor x="-60" y="-500" name="L"/>
+ <anchor x="510" y="1100" name="U"/>
+ <outline>
+ <contour>
+ <point x="370" y="1000" type="line"/>
+ <point x="370" y="856"/>
+ <point x="288" y="374"/>
+ <point x="214" y="77" type="curve" smooth="yes"/>
+ <point x="152" y="-173"/>
+ <point x="29" y="-295"/>
+ <point x="-77" y="-295" type="curve" smooth="yes"/>
+ <point x="-133" y="-295"/>
+ <point x="-217" y="-264"/>
+ <point x="-253" y="-229" type="curve"/>
+ <point x="-328" y="-397" type="line"/>
+ <point x="-278" y="-437"/>
+ <point x="-170" y="-465"/>
+ <point x="-114" y="-465" type="curve" smooth="yes"/>
+ <point x="103" y="-465"/>
+ <point x="303" y="-314"/>
+ <point x="396" y="66" type="curve" smooth="yes"/>
+ <point x="455" y="307"/>
+ <point x="560" y="872"/>
+ <point x="560" y="1000" type="curve"/>
+ </contour>
+ <contour>
+ <point x="397" y="1297" type="curve" smooth="yes"/>
+ <point x="397" y="1237"/>
+ <point x="440" y="1186"/>
+ <point x="503" y="1186" type="curve" smooth="yes"/>
+ <point x="588" y="1186"/>
+ <point x="660" y="1259"/>
+ <point x="660" y="1338" type="curve" smooth="yes"/>
+ <point x="660" y="1399"/>
+ <point x="614" y="1450"/>
+ <point x="549" y="1450" type="curve" smooth="yes"/>
+ <point x="464" y="1450"/>
+ <point x="397" y="1375"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfnormalize.ufo/glyphs/L_tnS_mK_.glif b/tests/reference/ufo/psfnormalize.ufo/glyphs/L_tnS_mK_.glif
new file mode 100644
index 0000000..28fbc71
--- /dev/null
+++ b/tests/reference/ufo/psfnormalize.ufo/glyphs/L_tnS_mK_.glif
@@ -0,0 +1,50 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmK" format="2">
+ <advance width="1059"/>
+ <unicode hex="006B"/>
+ <anchor x="840" y="0" name="H"/>
+ <anchor x="537" y="-100" name="L"/>
+ <anchor x="1225" y="1000" name="R"/>
+ <anchor x="920" y="1635" name="U"/>
+ <outline>
+ <contour>
+ <point x="295" y="0" type="line"/>
+ <point x="570" y="1105" type="line" smooth="yes"/>
+ <point x="614" y="1280"/>
+ <point x="645" y="1482"/>
+ <point x="645" y="1570" type="curve"/>
+ <point x="455" y="1570" type="line"/>
+ <point x="455" y="1456"/>
+ <point x="424" y="1259"/>
+ <point x="386" y="1107" type="curve" smooth="yes"/>
+ <point x="338" y="915"/>
+ <point x="110" y="0"/>
+ <point x="110" y="0" type="curve"/>
+ </contour>
+ <contour>
+ <point x="909" y="1000" type="line"/>
+ <point x="885" y="863"/>
+ <point x="654" y="700"/>
+ <point x="379" y="539" type="curve"/>
+ <point x="386" y="540"/>
+ <point x="393" y="540"/>
+ <point x="400" y="540" type="curve" smooth="yes"/>
+ <point x="467" y="540"/>
+ <point x="559" y="514"/>
+ <point x="559" y="514" type="curve"/>
+ <point x="902" y="702"/>
+ <point x="1134" y="884"/>
+ <point x="1134" y="1000" type="curve"/>
+ </contour>
+ <contour>
+ <point x="1010" y="0" type="line"/>
+ <point x="863" y="238"/>
+ <point x="718" y="600"/>
+ <point x="527" y="600" type="curve"/>
+ <point x="385" y="529" type="line"/>
+ <point x="540" y="529"/>
+ <point x="667" y="246"/>
+ <point x="775" y="0" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfnormalize.ufo/glyphs/L_tnS_mL_.glif b/tests/reference/ufo/psfnormalize.ufo/glyphs/L_tnS_mL_.glif
new file mode 100644
index 0000000..06d68fd
--- /dev/null
+++ b/tests/reference/ufo/psfnormalize.ufo/glyphs/L_tnS_mL_.glif
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmL" format="2">
+ <advance width="575"/>
+ <unicode hex="006C"/>
+ <anchor x="230" y="0" name="H"/>
+ <anchor x="255" y="-100" name="L"/>
+ <anchor x="740" y="1000" name="R"/>
+ <anchor x="630" y="1635" name="U"/>
+ <outline>
+ <contour>
+ <point x="465" y="1570" type="line"/>
+ <point x="465" y="1456"/>
+ <point x="434" y="1259"/>
+ <point x="396" y="1107" type="curve" smooth="yes"/>
+ <point x="241" y="489" type="line" smooth="yes"/>
+ <point x="204" y="343"/>
+ <point x="186" y="220"/>
+ <point x="186" y="104" type="curve" smooth="yes"/>
+ <point x="186" y="69"/>
+ <point x="188" y="34"/>
+ <point x="191" y="0" type="curve"/>
+ <point x="391" y="0" type="line"/>
+ <point x="386" y="32"/>
+ <point x="384" y="70"/>
+ <point x="384" y="112" type="curve" smooth="yes"/>
+ <point x="384" y="230"/>
+ <point x="402" y="380"/>
+ <point x="436" y="517" type="curve" smooth="yes"/>
+ <point x="580" y="1105" type="line" smooth="yes"/>
+ <point x="623" y="1280"/>
+ <point x="655" y="1482"/>
+ <point x="655" y="1570" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfnormalize.ufo/glyphs/L_tnS_mM_.glif b/tests/reference/ufo/psfnormalize.ufo/glyphs/L_tnS_mM_.glif
new file mode 100644
index 0000000..a6b80db
--- /dev/null
+++ b/tests/reference/ufo/psfnormalize.ufo/glyphs/L_tnS_mM_.glif
@@ -0,0 +1,80 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmM" format="2">
+ <advance width="1680"/>
+ <unicode hex="006D"/>
+ <anchor x="805" y="0" name="H"/>
+ <anchor x="780" y="-100" name="L"/>
+ <anchor x="1080" y="1100" name="U"/>
+ <outline>
+ <contour>
+ <point x="1520" y="0" type="line"/>
+ <point x="1512" y="30"/>
+ <point x="1510" y="65"/>
+ <point x="1510" y="102" type="curve" smooth="yes"/>
+ <point x="1510" y="143"/>
+ <point x="1515" y="188"/>
+ <point x="1522" y="238" type="curve" smooth="yes"/>
+ <point x="1536" y="327"/>
+ <point x="1655" y="691"/>
+ <point x="1655" y="800" type="curve" smooth="yes"/>
+ <point x="1655" y="930"/>
+ <point x="1594" y="1020"/>
+ <point x="1445" y="1020" type="curve" smooth="yes"/>
+ <point x="1292" y="1020"/>
+ <point x="1124" y="867"/>
+ <point x="1026" y="680" type="curve"/>
+ <point x="1030" y="704"/>
+ <point x="1045" y="778"/>
+ <point x="1045" y="800" type="curve" smooth="yes"/>
+ <point x="1045" y="932"/>
+ <point x="982" y="1020"/>
+ <point x="860" y="1020" type="curve" smooth="yes"/>
+ <point x="717" y="1020"/>
+ <point x="563" y="879"/>
+ <point x="446" y="680" type="curve"/>
+ <point x="466" y="753"/>
+ <point x="476" y="880"/>
+ <point x="476" y="961" type="curve" smooth="yes"/>
+ <point x="476" y="976"/>
+ <point x="476" y="989"/>
+ <point x="475" y="1000" type="curve"/>
+ <point x="295" y="1000" type="line"/>
+ <point x="296" y="983"/>
+ <point x="296" y="964"/>
+ <point x="296" y="945" type="curve" smooth="yes"/>
+ <point x="296" y="825"/>
+ <point x="283" y="680"/>
+ <point x="262" y="595" type="curve" smooth="yes"/>
+ <point x="115" y="0" type="line"/>
+ <point x="300" y="0" type="line"/>
+ <point x="389" y="359" type="line"/>
+ <point x="475" y="573"/>
+ <point x="685" y="850"/>
+ <point x="775" y="850" type="curve" smooth="yes"/>
+ <point x="833" y="850"/>
+ <point x="865" y="813"/>
+ <point x="865" y="720" type="curve" smooth="yes"/>
+ <point x="865" y="679"/>
+ <point x="846" y="583"/>
+ <point x="822" y="486" type="curve" smooth="yes"/>
+ <point x="700" y="0" type="line"/>
+ <point x="885" y="0" type="line"/>
+ <point x="974" y="359" type="line"/>
+ <point x="1032" y="531"/>
+ <point x="1242" y="850"/>
+ <point x="1357" y="850" type="curve" smooth="yes"/>
+ <point x="1425" y="850"/>
+ <point x="1457" y="813"/>
+ <point x="1457" y="720" type="curve" smooth="yes"/>
+ <point x="1457" y="632"/>
+ <point x="1349" y="319"/>
+ <point x="1335" y="203" type="curve" smooth="yes"/>
+ <point x="1330" y="158"/>
+ <point x="1327" y="115"/>
+ <point x="1327" y="77" type="curve" smooth="yes"/>
+ <point x="1327" y="48"/>
+ <point x="1331" y="21"/>
+ <point x="1335" y="0" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfnormalize.ufo/glyphs/L_tnS_mN_.glif b/tests/reference/ufo/psfnormalize.ufo/glyphs/L_tnS_mN_.glif
new file mode 100644
index 0000000..1f38f20
--- /dev/null
+++ b/tests/reference/ufo/psfnormalize.ufo/glyphs/L_tnS_mN_.glif
@@ -0,0 +1,57 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmN" format="2">
+ <advance width="1195"/>
+ <unicode hex="006E"/>
+ <anchor x="540" y="0" name="H"/>
+ <anchor x="565" y="-100" name="L"/>
+ <anchor x="815" y="1100" name="U"/>
+ <outline>
+ <contour>
+ <point x="1060" y="0" type="line"/>
+ <point x="1052" y="30"/>
+ <point x="1050" y="65"/>
+ <point x="1050" y="102" type="curve" smooth="yes"/>
+ <point x="1050" y="143"/>
+ <point x="1055" y="188"/>
+ <point x="1062" y="238" type="curve" smooth="yes"/>
+ <point x="1075" y="327"/>
+ <point x="1175" y="636"/>
+ <point x="1175" y="745" type="curve" smooth="yes"/>
+ <point x="1175" y="917"/>
+ <point x="1100" y="1020"/>
+ <point x="935" y="1020" type="curve" smooth="yes"/>
+ <point x="755" y="1020"/>
+ <point x="581" y="870"/>
+ <point x="445" y="672" type="curve"/>
+ <point x="463" y="740"/>
+ <point x="477" y="873"/>
+ <point x="477" y="957" type="curve" smooth="yes"/>
+ <point x="477" y="973"/>
+ <point x="476" y="988"/>
+ <point x="475" y="1000" type="curve"/>
+ <point x="295" y="1000" type="line"/>
+ <point x="295" y="961" type="line" smooth="yes"/>
+ <point x="295" y="833"/>
+ <point x="283" y="679"/>
+ <point x="262" y="595" type="curve" smooth="yes"/>
+ <point x="115" y="0" type="line"/>
+ <point x="300" y="0" type="line"/>
+ <point x="392" y="370" type="line"/>
+ <point x="478" y="573"/>
+ <point x="708" y="850"/>
+ <point x="835" y="850" type="curve" smooth="yes"/>
+ <point x="927" y="850"/>
+ <point x="975" y="798"/>
+ <point x="975" y="680" type="curve" smooth="yes"/>
+ <point x="975" y="592"/>
+ <point x="888" y="319"/>
+ <point x="875" y="203" type="curve" smooth="yes"/>
+ <point x="870" y="158"/>
+ <point x="867" y="115"/>
+ <point x="867" y="77" type="curve" smooth="yes"/>
+ <point x="867" y="48"/>
+ <point x="871" y="21"/>
+ <point x="875" y="0" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfnormalize.ufo/glyphs/L_tnS_mO_.glif b/tests/reference/ufo/psfnormalize.ufo/glyphs/L_tnS_mO_.glif
new file mode 100644
index 0000000..bec7b9e
--- /dev/null
+++ b/tests/reference/ufo/psfnormalize.ufo/glyphs/L_tnS_mO_.glif
@@ -0,0 +1,40 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmO" format="2">
+ <advance width="1133"/>
+ <unicode hex="006F"/>
+ <anchor x="510" y="0" name="H"/>
+ <anchor x="505" y="-100" name="L"/>
+ <anchor x="800" y="0" name="O"/>
+ <anchor x="1330" y="1000" name="R"/>
+ <anchor x="785" y="1100" name="U"/>
+ <outline>
+ <contour>
+ <point x="142" y="344" type="curve" smooth="yes"/>
+ <point x="142" y="114"/>
+ <point x="306" y="-25"/>
+ <point x="530" y="-25" type="curve" smooth="yes"/>
+ <point x="896" y="-25"/>
+ <point x="1138" y="314"/>
+ <point x="1138" y="648" type="curve" smooth="yes"/>
+ <point x="1138" y="879"/>
+ <point x="985" y="1020"/>
+ <point x="761" y="1020" type="curve" smooth="yes"/>
+ <point x="387" y="1020"/>
+ <point x="142" y="677"/>
+ </contour>
+ <contour>
+ <point x="721" y="862" type="curve" smooth="yes"/>
+ <point x="859" y="862"/>
+ <point x="947" y="767"/>
+ <point x="947" y="611" type="curve" smooth="yes"/>
+ <point x="947" y="391"/>
+ <point x="795" y="132"/>
+ <point x="559" y="132" type="curve" smooth="yes"/>
+ <point x="421" y="132"/>
+ <point x="333" y="226"/>
+ <point x="333" y="380" type="curve" smooth="yes"/>
+ <point x="333" y="599"/>
+ <point x="486" y="862"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfnormalize.ufo/glyphs/L_tnS_mP_.glif b/tests/reference/ufo/psfnormalize.ufo/glyphs/L_tnS_mP_.glif
new file mode 100644
index 0000000..f9e06b1
--- /dev/null
+++ b/tests/reference/ufo/psfnormalize.ufo/glyphs/L_tnS_mP_.glif
@@ -0,0 +1,66 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmP" format="2">
+ <advance width="1185"/>
+ <unicode hex="0070"/>
+ <anchor x="105" y="-435" name="H"/>
+ <anchor x="405" y="-500" name="L"/>
+ <anchor x="1360" y="1000" name="R"/>
+ <anchor x="805" y="1100" name="U"/>
+ <outline>
+ <contour>
+ <point x="215" y="-480" type="line"/>
+ <point x="215" y="-388"/>
+ <point x="229" y="-282"/>
+ <point x="255" y="-175" type="curve" smooth="yes"/>
+ <point x="320" y="85" type="line"/>
+ <point x="399" y="20"/>
+ <point x="468" y="-25"/>
+ <point x="575" y="-25" type="curve" smooth="yes"/>
+ <point x="685" y="-25"/>
+ <point x="797" y="9"/>
+ <point x="895" y="85" type="curve" smooth="yes"/>
+ <point x="1063" y="215"/>
+ <point x="1185" y="438"/>
+ <point x="1185" y="680" type="curve" smooth="yes"/>
+ <point x="1185" y="878"/>
+ <point x="1101" y="1020"/>
+ <point x="920" y="1020" type="curve" smooth="yes"/>
+ <point x="757" y="1020"/>
+ <point x="559" y="842"/>
+ <point x="452" y="680" type="curve"/>
+ <point x="468" y="760"/>
+ <point x="477" y="860"/>
+ <point x="477" y="940" type="curve" smooth="yes"/>
+ <point x="477" y="962"/>
+ <point x="477" y="982"/>
+ <point x="475" y="1000" type="curve"/>
+ <point x="295" y="1000" type="line"/>
+ <point x="295" y="971" type="line" smooth="yes"/>
+ <point x="295" y="819"/>
+ <point x="273" y="625"/>
+ <point x="235" y="475" type="curve" smooth="yes"/>
+ <point x="70" y="-175" type="line" smooth="yes"/>
+ <point x="43" y="-281"/>
+ <point x="20" y="-398"/>
+ <point x="20" y="-480" type="curve"/>
+ </contour>
+ <contour>
+ <point x="407" y="432" type="line"/>
+ <point x="544" y="656"/>
+ <point x="732" y="850"/>
+ <point x="840" y="850" type="curve" smooth="yes"/>
+ <point x="939" y="850"/>
+ <point x="990" y="763"/>
+ <point x="990" y="630" type="curve" smooth="yes"/>
+ <point x="990" y="491"/>
+ <point x="926" y="322"/>
+ <point x="815" y="220" type="curve" smooth="yes"/>
+ <point x="759" y="168"/>
+ <point x="693" y="135"/>
+ <point x="615" y="135" type="curve" smooth="yes"/>
+ <point x="523" y="135"/>
+ <point x="479" y="161"/>
+ <point x="365" y="255" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfnormalize.ufo/glyphs/L_tnS_mQ_.glif b/tests/reference/ufo/psfnormalize.ufo/glyphs/L_tnS_mQ_.glif
new file mode 100644
index 0000000..58d9f87
--- /dev/null
+++ b/tests/reference/ufo/psfnormalize.ufo/glyphs/L_tnS_mQ_.glif
@@ -0,0 +1,54 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmQ" format="2">
+ <advance width="1115"/>
+ <unicode hex="0071"/>
+ <anchor x="370" y="-500" name="L"/>
+ <anchor x="1320" y="1000" name="R"/>
+ <anchor x="770" y="1100" name="U"/>
+ <outline>
+ <contour>
+ <point x="843" y="-480" type="line"/>
+ <point x="843" y="-391"/>
+ <point x="858" y="-294"/>
+ <point x="885" y="-185" type="curve" smooth="yes"/>
+ <point x="1165" y="945" type="line"/>
+ <point x="1066" y="980"/>
+ <point x="946" y="1020"/>
+ <point x="825" y="1020" type="curve" smooth="yes"/>
+ <point x="675" y="1020"/>
+ <point x="550" y="977"/>
+ <point x="440" y="890" type="curve" smooth="yes"/>
+ <point x="260" y="747"/>
+ <point x="135" y="505"/>
+ <point x="135" y="285" type="curve" smooth="yes"/>
+ <point x="135" y="73"/>
+ <point x="261" y="-25"/>
+ <point x="380" y="-25" type="curve" smooth="yes"/>
+ <point x="524" y="-25"/>
+ <point x="751" y="172"/>
+ <point x="825" y="300" type="curve"/>
+ <point x="693" y="-180" type="line" smooth="yes"/>
+ <point x="662" y="-294"/>
+ <point x="648" y="-414"/>
+ <point x="648" y="-480" type="curve"/>
+ </contour>
+ <contour>
+ <point x="885" y="565" type="line"/>
+ <point x="807" y="413"/>
+ <point x="550" y="140"/>
+ <point x="455" y="140" type="curve" smooth="yes"/>
+ <point x="376" y="140"/>
+ <point x="330" y="199"/>
+ <point x="330" y="330" type="curve" smooth="yes"/>
+ <point x="330" y="481"/>
+ <point x="400" y="658"/>
+ <point x="515" y="760" type="curve" smooth="yes"/>
+ <point x="580" y="817"/>
+ <point x="658" y="855"/>
+ <point x="750" y="855" type="curve" smooth="yes"/>
+ <point x="811" y="855"/>
+ <point x="893" y="840"/>
+ <point x="947" y="817" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfnormalize.ufo/glyphs/L_tnS_mR_.glif b/tests/reference/ufo/psfnormalize.ufo/glyphs/L_tnS_mR_.glif
new file mode 100644
index 0000000..8037612
--- /dev/null
+++ b/tests/reference/ufo/psfnormalize.ufo/glyphs/L_tnS_mR_.glif
@@ -0,0 +1,42 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmR" format="2">
+ <advance width="910"/>
+ <unicode hex="0072"/>
+ <anchor x="210" y="0" name="H"/>
+ <anchor x="220" y="-100" name="L"/>
+ <anchor x="670" y="1100" name="U"/>
+ <outline>
+ <contour>
+ <point x="300" y="0" type="line"/>
+ <point x="402" y="415" type="line"/>
+ <point x="502" y="602"/>
+ <point x="703" y="850"/>
+ <point x="785" y="850" type="curve" smooth="yes"/>
+ <point x="831" y="850"/>
+ <point x="855" y="801"/>
+ <point x="855" y="740" type="curve" smooth="yes"/>
+ <point x="855" y="715"/>
+ <point x="852" y="689"/>
+ <point x="845" y="660" type="curve"/>
+ <point x="1010" y="690" type="line"/>
+ <point x="1022" y="737"/>
+ <point x="1030" y="783"/>
+ <point x="1030" y="825" type="curve" smooth="yes"/>
+ <point x="1030" y="935"/>
+ <point x="986" y="1020"/>
+ <point x="865" y="1020" type="curve" smooth="yes"/>
+ <point x="735" y="1020"/>
+ <point x="575" y="867"/>
+ <point x="445" y="675" type="curve"/>
+ <point x="467" y="773"/>
+ <point x="475" y="929"/>
+ <point x="475" y="1000" type="curve"/>
+ <point x="295" y="1000" type="line"/>
+ <point x="295" y="961" type="line" smooth="yes"/>
+ <point x="295" y="833"/>
+ <point x="283" y="679"/>
+ <point x="262" y="595" type="curve" smooth="yes"/>
+ <point x="115" y="0" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfnormalize.ufo/glyphs/L_tnS_mS_.glif b/tests/reference/ufo/psfnormalize.ufo/glyphs/L_tnS_mS_.glif
new file mode 100644
index 0000000..848ddda
--- /dev/null
+++ b/tests/reference/ufo/psfnormalize.ufo/glyphs/L_tnS_mS_.glif
@@ -0,0 +1,50 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmS" format="2">
+ <advance width="945"/>
+ <unicode hex="0073"/>
+ <anchor x="435" y="0" name="H"/>
+ <anchor x="440" y="-100" name="L"/>
+ <anchor x="710" y="1100" name="U"/>
+ <outline>
+ <contour>
+ <point x="990" y="941" type="line"/>
+ <point x="930" y="978"/>
+ <point x="815" y="1020"/>
+ <point x="640" y="1020" type="curve" smooth="yes"/>
+ <point x="384" y="1020"/>
+ <point x="230" y="881"/>
+ <point x="230" y="716" type="curve" smooth="yes"/>
+ <point x="230" y="614"/>
+ <point x="320" y="533"/>
+ <point x="466" y="461" type="curve" smooth="yes"/>
+ <point x="638" y="376"/>
+ <point x="700" y="333"/>
+ <point x="700" y="265" type="curve" smooth="yes"/>
+ <point x="700" y="188"/>
+ <point x="621" y="132"/>
+ <point x="532" y="132" type="curve" smooth="yes"/>
+ <point x="376" y="132"/>
+ <point x="244" y="216"/>
+ <point x="159" y="325" type="curve"/>
+ <point x="71" y="158" type="line"/>
+ <point x="160" y="60"/>
+ <point x="296" y="-25"/>
+ <point x="488" y="-25" type="curve" smooth="yes"/>
+ <point x="713" y="-25"/>
+ <point x="891" y="106"/>
+ <point x="891" y="306" type="curve" smooth="yes"/>
+ <point x="891" y="432"/>
+ <point x="774" y="515"/>
+ <point x="626" y="593" type="curve" smooth="yes"/>
+ <point x="476" y="672"/>
+ <point x="418" y="695"/>
+ <point x="418" y="753" type="curve" smooth="yes"/>
+ <point x="418" y="822"/>
+ <point x="494" y="862"/>
+ <point x="619" y="862" type="curve" smooth="yes"/>
+ <point x="743" y="862"/>
+ <point x="854" y="808"/>
+ <point x="911" y="769" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfnormalize.ufo/glyphs/L_tnS_mT_.glif b/tests/reference/ufo/psfnormalize.ufo/glyphs/L_tnS_mT_.glif
new file mode 100644
index 0000000..0eddfe9
--- /dev/null
+++ b/tests/reference/ufo/psfnormalize.ufo/glyphs/L_tnS_mT_.glif
@@ -0,0 +1,45 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmT" format="2">
+ <advance width="815"/>
+ <unicode hex="0074"/>
+ <anchor x="455" y="0" name="H"/>
+ <anchor x="390" y="-100" name="L"/>
+ <anchor x="1025" y="1000" name="R"/>
+ <anchor x="605" y="1360" name="U"/>
+ <outline>
+ <contour>
+ <point x="752" y="211" type="line"/>
+ <point x="665" y="169"/>
+ <point x="593" y="134"/>
+ <point x="527" y="134" type="curve" smooth="yes"/>
+ <point x="448" y="134"/>
+ <point x="425" y="188"/>
+ <point x="425" y="247" type="curve" smooth="yes"/>
+ <point x="425" y="274"/>
+ <point x="429" y="301"/>
+ <point x="434" y="326" type="curve" smooth="yes"/>
+ <point x="470" y="519"/>
+ <point x="564" y="843"/>
+ <point x="677" y="1294" type="curve"/>
+ <point x="492" y="1294" type="line"/>
+ <point x="377" y="841"/>
+ <point x="263" y="429"/>
+ <point x="243" y="301" type="curve" smooth="yes"/>
+ <point x="238" y="269"/>
+ <point x="236" y="240"/>
+ <point x="236" y="213" type="curve" smooth="yes"/>
+ <point x="236" y="41"/>
+ <point x="330" y="-25"/>
+ <point x="465" y="-25" type="curve" smooth="yes"/>
+ <point x="535" y="-25"/>
+ <point x="634" y="-6"/>
+ <point x="740" y="52" type="curve"/>
+ </contour>
+ <contour>
+ <point x="177" y="833" type="line"/>
+ <point x="887" y="833" type="line"/>
+ <point x="923" y="975" type="line"/>
+ <point x="213" y="975" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfnormalize.ufo/glyphs/L_tnS_mU_.glif b/tests/reference/ufo/psfnormalize.ufo/glyphs/L_tnS_mU_.glif
new file mode 100644
index 0000000..0eda3d2
--- /dev/null
+++ b/tests/reference/ufo/psfnormalize.ufo/glyphs/L_tnS_mU_.glif
@@ -0,0 +1,57 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmU" format="2">
+ <advance width="1175"/>
+ <unicode hex="0075"/>
+ <anchor x="465" y="0" name="H"/>
+ <anchor x="504" y="-100" name="L"/>
+ <anchor x="640" y="0" name="O"/>
+ <anchor x="1375" y="1000" name="R"/>
+ <anchor x="804" y="1100" name="U"/>
+ <outline>
+ <contour>
+ <point x="1040" y="0" type="line"/>
+ <point x="1036" y="29"/>
+ <point x="1035" y="62"/>
+ <point x="1035" y="100" type="curve" smooth="yes"/>
+ <point x="1035" y="206"/>
+ <point x="1054" y="341"/>
+ <point x="1080" y="455" type="curve" smooth="yes"/>
+ <point x="1135" y="689"/>
+ <point x="1197" y="895"/>
+ <point x="1205" y="1000" type="curve"/>
+ <point x="1010" y="1000" type="line"/>
+ <point x="1003" y="882"/>
+ <point x="971" y="769"/>
+ <point x="920" y="565" type="curve"/>
+ <point x="827" y="376"/>
+ <point x="573" y="135"/>
+ <point x="475" y="135" type="curve" smooth="yes"/>
+ <point x="409" y="135"/>
+ <point x="365" y="181"/>
+ <point x="365" y="280" type="curve" smooth="yes"/>
+ <point x="365" y="347"/>
+ <point x="407" y="500"/>
+ <point x="459" y="702" type="curve" smooth="yes"/>
+ <point x="494" y="837"/>
+ <point x="515" y="925"/>
+ <point x="520" y="1000" type="curve"/>
+ <point x="325" y="1000" type="line"/>
+ <point x="313" y="882"/>
+ <point x="295" y="809"/>
+ <point x="265" y="685" type="curve" smooth="yes"/>
+ <point x="195" y="395" type="line" smooth="yes"/>
+ <point x="179" y="330"/>
+ <point x="170" y="275"/>
+ <point x="170" y="225" type="curve" smooth="yes"/>
+ <point x="170" y="60"/>
+ <point x="257" y="-25"/>
+ <point x="410" y="-25" type="curve" smooth="yes"/>
+ <point x="551" y="-25"/>
+ <point x="745" y="118"/>
+ <point x="880" y="305" type="curve"/>
+ <point x="861" y="196"/>
+ <point x="860" y="98"/>
+ <point x="860" y="0" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfnormalize.ufo/glyphs/L_tnS_mV_.glif b/tests/reference/ufo/psfnormalize.ufo/glyphs/L_tnS_mV_.glif
new file mode 100644
index 0000000..33e91d6
--- /dev/null
+++ b/tests/reference/ufo/psfnormalize.ufo/glyphs/L_tnS_mV_.glif
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmV" format="2">
+ <advance width="941"/>
+ <unicode hex="0076"/>
+ <anchor x="359" y="0" name="H"/>
+ <anchor x="350" y="-100" name="L"/>
+ <anchor x="565" y="0" name="O"/>
+ <anchor x="650" y="1100" name="U"/>
+ <outline>
+ <contour>
+ <point x="180" y="1000" type="line"/>
+ <point x="232" y="825"/>
+ <point x="256" y="602"/>
+ <point x="256" y="354" type="curve" smooth="yes"/>
+ <point x="256" y="241"/>
+ <point x="251" y="122"/>
+ <point x="241" y="0" type="curve"/>
+ <point x="441" y="0" type="line"/>
+ <point x="744" y="336"/>
+ <point x="1056" y="765"/>
+ <point x="1056" y="1000" type="curve"/>
+ <point x="856" y="1000" type="line"/>
+ <point x="856" y="769"/>
+ <point x="606" y="394"/>
+ <point x="404" y="176" type="curve"/>
+ <point x="421" y="277"/>
+ <point x="429" y="402"/>
+ <point x="429" y="526" type="curve" smooth="yes"/>
+ <point x="429" y="707"/>
+ <point x="412" y="887"/>
+ <point x="380" y="1000" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfnormalize.ufo/glyphs/L_tnS_mW_.glif b/tests/reference/ufo/psfnormalize.ufo/glyphs/L_tnS_mW_.glif
new file mode 100644
index 0000000..1daea7c
--- /dev/null
+++ b/tests/reference/ufo/psfnormalize.ufo/glyphs/L_tnS_mW_.glif
@@ -0,0 +1,50 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmW" format="2">
+ <advance width="1555"/>
+ <unicode hex="0077"/>
+ <anchor x="690" y="-100" name="L"/>
+ <anchor x="990" y="1100" name="U"/>
+ <outline>
+ <contour>
+ <point x="858" y="1000" type="line"/>
+ <point x="743" y="739"/>
+ <point x="588" y="466"/>
+ <point x="388" y="181" type="curve"/>
+ <point x="417" y="339"/>
+ <point x="430" y="500"/>
+ <point x="430" y="644" type="curve" smooth="yes"/>
+ <point x="430" y="784"/>
+ <point x="418" y="908"/>
+ <point x="395" y="1000" type="curve"/>
+ <point x="195" y="1000" type="line"/>
+ <point x="234" y="873"/>
+ <point x="256" y="688"/>
+ <point x="256" y="472" type="curve" smooth="yes"/>
+ <point x="256" y="326"/>
+ <point x="246" y="166"/>
+ <point x="225" y="0" type="curve"/>
+ <point x="425" y="0" type="line"/>
+ <point x="632" y="298"/>
+ <point x="825" y="583"/>
+ <point x="896" y="765" type="curve"/>
+ <point x="920" y="478"/>
+ <point x="912" y="233"/>
+ <point x="915" y="0" type="curve"/>
+ <point x="1115" y="0" type="line"/>
+ <point x="1362" y="330"/>
+ <point x="1642" y="777"/>
+ <point x="1645" y="1000" type="curve"/>
+ <point x="1445" y="1000" type="line"/>
+ <point x="1445" y="990" type="line"/>
+ <point x="1445" y="797"/>
+ <point x="1242" y="417"/>
+ <point x="1063" y="181" type="curve"/>
+ <point x="1064" y="221"/>
+ <point x="1064" y="260"/>
+ <point x="1064" y="298" type="curve" smooth="yes"/>
+ <point x="1064" y="577"/>
+ <point x="1046" y="811"/>
+ <point x="1020" y="1000" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfnormalize.ufo/glyphs/L_tnS_mX_.glif b/tests/reference/ufo/psfnormalize.ufo/glyphs/L_tnS_mX_.glif
new file mode 100644
index 0000000..5508ff9
--- /dev/null
+++ b/tests/reference/ufo/psfnormalize.ufo/glyphs/L_tnS_mX_.glif
@@ -0,0 +1,40 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmX" format="2">
+ <advance width="1009"/>
+ <unicode hex="0078"/>
+ <anchor x="840" y="0" name="H"/>
+ <anchor x="457" y="-100" name="L"/>
+ <anchor x="657" y="1100" name="U"/>
+ <outline>
+ <contour>
+ <point x="945" y="0" type="line"/>
+ <point x="765" y="133"/>
+ <point x="558" y="867"/>
+ <point x="439" y="1000" type="curve"/>
+ <point x="181" y="1000" type="line"/>
+ <point x="410" y="832"/>
+ <point x="578" y="141"/>
+ <point x="698" y="0" type="curve"/>
+ </contour>
+ <contour>
+ <point x="504" y="572" type="line"/>
+ <point x="286" y="463"/>
+ <point x="57" y="230"/>
+ <point x="30" y="0" type="curve"/>
+ <point x="230" y="0" type="line"/>
+ <point x="231" y="156"/>
+ <point x="375" y="380"/>
+ <point x="563" y="467" type="curve"/>
+ </contour>
+ <contour>
+ <point x="659" y="471" type="line"/>
+ <point x="838" y="591"/>
+ <point x="1092" y="798"/>
+ <point x="1099" y="1000" type="curve"/>
+ <point x="889" y="1000" type="line"/>
+ <point x="883" y="842"/>
+ <point x="758" y="675"/>
+ <point x="601" y="581" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfnormalize.ufo/glyphs/L_tnS_mY_.glif b/tests/reference/ufo/psfnormalize.ufo/glyphs/L_tnS_mY_.glif
new file mode 100644
index 0000000..b9000c5
--- /dev/null
+++ b/tests/reference/ufo/psfnormalize.ufo/glyphs/L_tnS_mY_.glif
@@ -0,0 +1,45 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmY" format="2">
+ <advance width="976"/>
+ <unicode hex="0079"/>
+ <anchor x="710" y="-100" name="L"/>
+ <anchor x="1270" y="1000" name="R"/>
+ <anchor x="630" y="1100" name="U"/>
+ <outline>
+ <contour>
+ <point x="132" y="1000" type="line"/>
+ <point x="270" y="825"/>
+ <point x="398" y="406"/>
+ <point x="403" y="-16" type="curve"/>
+ <point x="263" y="-232"/>
+ <point x="145" y="-295"/>
+ <point x="64" y="-295" type="curve" smooth="yes"/>
+ <point x="-2" y="-295"/>
+ <point x="-69" y="-254"/>
+ <point x="-102" y="-220" type="curve"/>
+ <point x="-200" y="-377" type="line"/>
+ <point x="-141" y="-430"/>
+ <point x="-68" y="-465"/>
+ <point x="23" y="-465" type="curve" smooth="yes"/>
+ <point x="193" y="-465"/>
+ <point x="369" y="-371"/>
+ <point x="609" y="0" type="curve" smooth="yes"/>
+ <point x="877" y="414"/>
+ <point x="1056" y="808"/>
+ <point x="1056" y="964" type="curve" smooth="yes"/>
+ <point x="1056" y="978"/>
+ <point x="1055" y="990"/>
+ <point x="1052" y="1000" type="curve"/>
+ <point x="852" y="1000" type="line"/>
+ <point x="856" y="984"/>
+ <point x="858" y="967"/>
+ <point x="858" y="946" type="curve" smooth="yes"/>
+ <point x="858" y="783"/>
+ <point x="722" y="472"/>
+ <point x="548" y="189" type="curve"/>
+ <point x="548" y="484"/>
+ <point x="447" y="866"/>
+ <point x="347" y="1000" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfnormalize.ufo/glyphs/N_onB_reakingH_yphen.glif b/tests/reference/ufo/psfnormalize.ufo/glyphs/N_onB_reakingH_yphen.glif
new file mode 100644
index 0000000..e7d9c06
--- /dev/null
+++ b/tests/reference/ufo/psfnormalize.ufo/glyphs/N_onB_reakingH_yphen.glif
@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="NonBreakingHyphen" format="2">
+ <advance width="840"/>
+ <unicode hex="2011"/>
+ <anchor x="645" y="1100" name="U"/>
+ <outline>
+ <component base="HyphenMinus"/>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfnormalize.ufo/glyphs/N_umS_gn.glif b/tests/reference/ufo/psfnormalize.ufo/glyphs/N_umS_gn.glif
new file mode 100644
index 0000000..b7506f7
--- /dev/null
+++ b/tests/reference/ufo/psfnormalize.ufo/glyphs/N_umS_gn.glif
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="NumSgn" format="2">
+ <advance width="1180"/>
+ <unicode hex="0023"/>
+ <outline>
+ <contour>
+ <point x="739" y="1333" type="line"/>
+ <point x="91" y="98" type="line"/>
+ <point x="261" y="98" type="line"/>
+ <point x="909" y="1333" type="line"/>
+ </contour>
+ <contour>
+ <point x="80" y="465" type="line"/>
+ <point x="1171" y="465" type="line"/>
+ <point x="1208" y="612" type="line"/>
+ <point x="117" y="612" type="line"/>
+ </contour>
+ <contour>
+ <point x="234" y="843" type="line"/>
+ <point x="1325" y="843" type="line"/>
+ <point x="1361" y="990" type="line"/>
+ <point x="270" y="990" type="line"/>
+ </contour>
+ <contour>
+ <point x="1164" y="1333" type="line"/>
+ <point x="516" y="98" type="line"/>
+ <point x="686" y="98" type="line"/>
+ <point x="1334" y="1333" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfnormalize.ufo/glyphs/P_ercentS_gn.glif b/tests/reference/ufo/psfnormalize.ufo/glyphs/P_ercentS_gn.glif
new file mode 100644
index 0000000..84241ea
--- /dev/null
+++ b/tests/reference/ufo/psfnormalize.ufo/glyphs/P_ercentS_gn.glif
@@ -0,0 +1,93 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="PercentSgn" format="2">
+ <advance width="1506"/>
+ <unicode hex="0025"/>
+ <outline>
+ <contour>
+ <point x="1300" y="349" type="curve" smooth="yes"/>
+ <point x="1255" y="168"/>
+ <point x="1204" y="113"/>
+ <point x="1118" y="113" type="curve" smooth="yes"/>
+ <point x="1056" y="113"/>
+ <point x="1021" y="148"/>
+ <point x="1021" y="235" type="curve" smooth="yes"/>
+ <point x="1021" y="274"/>
+ <point x="1028" y="322"/>
+ <point x="1043" y="383" type="curve" smooth="yes"/>
+ <point x="1088" y="564"/>
+ <point x="1136" y="617"/>
+ <point x="1223" y="617" type="curve" smooth="yes"/>
+ <point x="1286" y="617"/>
+ <point x="1322" y="582"/>
+ <point x="1322" y="496" type="curve" smooth="yes"/>
+ <point x="1322" y="458"/>
+ <point x="1315" y="409"/>
+ </contour>
+ <contour>
+ <point x="1468" y="361" type="curve" smooth="yes"/>
+ <point x="1483" y="419"/>
+ <point x="1489" y="470"/>
+ <point x="1489" y="515" type="curve" smooth="yes"/>
+ <point x="1489" y="677"/>
+ <point x="1400" y="755"/>
+ <point x="1263" y="755" type="curve" smooth="yes"/>
+ <point x="1089" y="755"/>
+ <point x="945" y="647"/>
+ <point x="876" y="371" type="curve" smooth="yes"/>
+ <point x="861" y="310"/>
+ <point x="854" y="256"/>
+ <point x="854" y="210" type="curve" smooth="yes"/>
+ <point x="854" y="47"/>
+ <point x="943" y="-25"/>
+ <point x="1079" y="-25" type="curve" smooth="yes"/>
+ <point x="1254" y="-25"/>
+ <point x="1396" y="72"/>
+ </contour>
+ <contour>
+ <point x="1369" y="1450" type="line"/>
+ <point x="219" y="-25" type="line"/>
+ <point x="397" y="-25" type="line"/>
+ <point x="1545" y="1450" type="line"/>
+ </contour>
+ <contour>
+ <point x="717" y="1044" type="curve" smooth="yes"/>
+ <point x="672" y="864"/>
+ <point x="621" y="809"/>
+ <point x="535" y="809" type="curve" smooth="yes"/>
+ <point x="474" y="809"/>
+ <point x="439" y="844"/>
+ <point x="439" y="930" type="curve" smooth="yes"/>
+ <point x="439" y="969"/>
+ <point x="446" y="1018"/>
+ <point x="461" y="1079" type="curve" smooth="yes"/>
+ <point x="506" y="1260"/>
+ <point x="554" y="1313"/>
+ <point x="641" y="1313" type="curve" smooth="yes"/>
+ <point x="704" y="1313"/>
+ <point x="739" y="1278"/>
+ <point x="739" y="1192" type="curve" smooth="yes"/>
+ <point x="739" y="1153"/>
+ <point x="732" y="1105"/>
+ </contour>
+ <contour>
+ <point x="886" y="1057" type="curve" smooth="yes"/>
+ <point x="900" y="1114"/>
+ <point x="907" y="1166"/>
+ <point x="907" y="1210" type="curve" smooth="yes"/>
+ <point x="907" y="1373"/>
+ <point x="817" y="1450"/>
+ <point x="680" y="1450" type="curve" smooth="yes"/>
+ <point x="506" y="1450"/>
+ <point x="362" y="1343"/>
+ <point x="293" y="1066" type="curve" smooth="yes"/>
+ <point x="278" y="1005"/>
+ <point x="271" y="952"/>
+ <point x="271" y="906" type="curve" smooth="yes"/>
+ <point x="271" y="743"/>
+ <point x="360" y="671"/>
+ <point x="497" y="671" type="curve" smooth="yes"/>
+ <point x="672" y="671"/>
+ <point x="813" y="768"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfnormalize.ufo/glyphs/P_lusS_gn.glif b/tests/reference/ufo/psfnormalize.ufo/glyphs/P_lusS_gn.glif
new file mode 100644
index 0000000..8c4577e
--- /dev/null
+++ b/tests/reference/ufo/psfnormalize.ufo/glyphs/P_lusS_gn.glif
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="PlusSgn" format="2">
+ <advance width="1180"/>
+ <unicode hex="002B"/>
+ <outline>
+ <contour>
+ <point x="748" y="1156" type="line"/>
+ <point x="529" y="279" type="line"/>
+ <point x="684" y="279" type="line"/>
+ <point x="903" y="1156" type="line"/>
+ </contour>
+ <contour>
+ <point x="256" y="647" type="line"/>
+ <point x="1146" y="647" type="line"/>
+ <point x="1182" y="794" type="line"/>
+ <point x="292" y="794" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfnormalize.ufo/glyphs/Q_stnM_rk.glif b/tests/reference/ufo/psfnormalize.ufo/glyphs/Q_stnM_rk.glif
new file mode 100644
index 0000000..8b14a6c
--- /dev/null
+++ b/tests/reference/ufo/psfnormalize.ufo/glyphs/Q_stnM_rk.glif
@@ -0,0 +1,49 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="QstnMrk" format="2">
+ <advance width="1030"/>
+ <unicode hex="003F"/>
+ <outline>
+ <contour>
+ <point x="419" y="1226" type="line"/>
+ <point x="514" y="1303"/>
+ <point x="615" y="1338"/>
+ <point x="685" y="1338" type="curve" smooth="yes"/>
+ <point x="800" y="1338"/>
+ <point x="858" y="1294"/>
+ <point x="858" y="1222" type="curve" smooth="yes"/>
+ <point x="858" y="1122"/>
+ <point x="713" y="1017"/>
+ <point x="654" y="960" type="curve" smooth="yes"/>
+ <point x="538" y="850"/>
+ <point x="473" y="715"/>
+ <point x="402" y="431" type="curve"/>
+ <point x="587" y="431" type="line"/>
+ <point x="656" y="707"/>
+ <point x="697" y="778"/>
+ <point x="831" y="901" type="curve" smooth="yes"/>
+ <point x="949" y="1010"/>
+ <point x="1072" y="1146"/>
+ <point x="1072" y="1272" type="curve" smooth="yes"/>
+ <point x="1072" y="1409"/>
+ <point x="947" y="1509"/>
+ <point x="746" y="1509" type="curve" smooth="yes"/>
+ <point x="631" y="1509"/>
+ <point x="500" y="1463"/>
+ <point x="419" y="1401" type="curve"/>
+ </contour>
+ <contour>
+ <point x="278" y="90" type="curve" smooth="yes"/>
+ <point x="278" y="28"/>
+ <point x="328" y="-25"/>
+ <point x="393" y="-25" type="curve" smooth="yes"/>
+ <point x="477" y="-25"/>
+ <point x="554" y="45"/>
+ <point x="554" y="125" type="curve" smooth="yes"/>
+ <point x="554" y="186"/>
+ <point x="504" y="240"/>
+ <point x="439" y="240" type="curve" smooth="yes"/>
+ <point x="355" y="240"/>
+ <point x="278" y="170"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfnormalize.ufo/glyphs/Q_uotM_rk.glif b/tests/reference/ufo/psfnormalize.ufo/glyphs/Q_uotM_rk.glif
new file mode 100644
index 0000000..4a8357b
--- /dev/null
+++ b/tests/reference/ufo/psfnormalize.ufo/glyphs/Q_uotM_rk.glif
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="QuotMrk" format="2">
+ <advance width="1005"/>
+ <unicode hex="0022"/>
+ <outline>
+ <contour>
+ <point x="600" y="1024" type="line"/>
+ <point x="639" y="1162"/>
+ <point x="683" y="1312"/>
+ <point x="772" y="1553" type="curve"/>
+ <point x="567" y="1553" type="line"/>
+ <point x="538" y="1312"/>
+ <point x="505" y="1162"/>
+ <point x="475" y="1024" type="curve"/>
+ </contour>
+ <contour>
+ <point x="940" y="1024" type="line"/>
+ <point x="979" y="1162"/>
+ <point x="1023" y="1312"/>
+ <point x="1112" y="1553" type="curve"/>
+ <point x="907" y="1553" type="line"/>
+ <point x="878" y="1312"/>
+ <point x="845" y="1162"/>
+ <point x="815" y="1024" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfnormalize.ufo/glyphs/R_everseS_olidus.glif b/tests/reference/ufo/psfnormalize.ufo/glyphs/R_everseS_olidus.glif
new file mode 100644
index 0000000..f146267
--- /dev/null
+++ b/tests/reference/ufo/psfnormalize.ufo/glyphs/R_everseS_olidus.glif
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="ReverseSolidus" format="2">
+ <advance width="1005"/>
+ <unicode hex="005C"/>
+ <outline>
+ <contour>
+ <point x="473" y="1538" type="line"/>
+ <point x="656" y="-123" type="line"/>
+ <point x="799" y="-93" type="line"/>
+ <point x="620" y="1568" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfnormalize.ufo/glyphs/R_tC_urlyB_rac.glif b/tests/reference/ufo/psfnormalize.ufo/glyphs/R_tC_urlyB_rac.glif
new file mode 100644
index 0000000..82df531
--- /dev/null
+++ b/tests/reference/ufo/psfnormalize.ufo/glyphs/R_tC_urlyB_rac.glif
@@ -0,0 +1,50 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="RtCurlyBrac" format="2">
+ <advance width="980"/>
+ <unicode hex="007D"/>
+ <outline>
+ <contour>
+ <point x="466" y="1470" type="line"/>
+ <point x="513" y="1452"/>
+ <point x="653" y="1397"/>
+ <point x="653" y="1366" type="curve" smooth="yes"/>
+ <point x="653" y="1238"/>
+ <point x="531" y="801"/>
+ <point x="531" y="737" type="curve" smooth="yes"/>
+ <point x="531" y="701"/>
+ <point x="660" y="627"/>
+ <point x="660" y="603" type="curve" smooth="yes"/>
+ <point x="660" y="585"/>
+ <point x="496" y="511"/>
+ <point x="468" y="475" type="curve" smooth="yes"/>
+ <point x="439" y="438"/>
+ <point x="312" y="-121"/>
+ <point x="268" y="-167" type="curve" smooth="yes"/>
+ <point x="241" y="-194"/>
+ <point x="106" y="-242"/>
+ <point x="33" y="-265" type="curve"/>
+ <point x="39" y="-402" type="line"/>
+ <point x="150" y="-375"/>
+ <point x="324" y="-323"/>
+ <point x="375" y="-279" type="curve" smooth="yes"/>
+ <point x="465" y="-201"/>
+ <point x="608" y="410"/>
+ <point x="639" y="441" type="curve" smooth="yes"/>
+ <point x="675" y="476"/>
+ <point x="880" y="571"/>
+ <point x="880" y="607" type="curve" smooth="yes"/>
+ <point x="880" y="639"/>
+ <point x="719" y="740"/>
+ <point x="719" y="771" type="curve" smooth="yes"/>
+ <point x="719" y="839"/>
+ <point x="825" y="1259"/>
+ <point x="825" y="1425" type="curve" smooth="yes"/>
+ <point x="825" y="1453"/>
+ <point x="822" y="1474"/>
+ <point x="815" y="1485" type="curve" smooth="yes"/>
+ <point x="786" y="1529"/>
+ <point x="638" y="1581"/>
+ <point x="540" y="1607" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfnormalize.ufo/glyphs/R_tP_aren.glif b/tests/reference/ufo/psfnormalize.ufo/glyphs/R_tP_aren.glif
new file mode 100644
index 0000000..3950e09
--- /dev/null
+++ b/tests/reference/ufo/psfnormalize.ufo/glyphs/R_tP_aren.glif
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="RtParen" format="2">
+ <advance width="775"/>
+ <unicode hex="0029"/>
+ <outline>
+ <contour>
+ <point x="467" y="1455" type="line"/>
+ <point x="578" y="1327"/>
+ <point x="628" y="1146"/>
+ <point x="628" y="946" type="curve" smooth="yes"/>
+ <point x="628" y="832"/>
+ <point x="612" y="713"/>
+ <point x="582" y="593" type="curve" smooth="yes"/>
+ <point x="497" y="252"/>
+ <point x="328" y="-8"/>
+ <point x="40" y="-260" type="curve"/>
+ <point x="99" y="-402" type="line"/>
+ <point x="444" y="-123"/>
+ <point x="673" y="194"/>
+ <point x="772" y="593" type="curve" smooth="yes"/>
+ <point x="804" y="719"/>
+ <point x="819" y="843"/>
+ <point x="819" y="959" type="curve" smooth="yes"/>
+ <point x="819" y="1236"/>
+ <point x="733" y="1472"/>
+ <point x="580" y="1607" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfnormalize.ufo/glyphs/R_tS_qrB_rac.glif b/tests/reference/ufo/psfnormalize.ufo/glyphs/R_tS_qrB_rac.glif
new file mode 100644
index 0000000..4c13a82
--- /dev/null
+++ b/tests/reference/ufo/psfnormalize.ufo/glyphs/R_tS_qrB_rac.glif
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="RtSqrBrac" format="2">
+ <advance width="770"/>
+ <unicode hex="005D"/>
+ <outline>
+ <contour>
+ <point x="434" y="-402" type="line"/>
+ <point x="920" y="1568" type="line"/>
+ <point x="480" y="1568" type="line"/>
+ <point x="444" y="1421" type="line"/>
+ <point x="699" y="1421" type="line"/>
+ <point x="286" y="-255" type="line"/>
+ <point x="31" y="-255" type="line"/>
+ <point x="-6" y="-402" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfnormalize.ufo/glyphs/S_emicolon.glif b/tests/reference/ufo/psfnormalize.ufo/glyphs/S_emicolon.glif
new file mode 100644
index 0000000..be971ac
--- /dev/null
+++ b/tests/reference/ufo/psfnormalize.ufo/glyphs/S_emicolon.glif
@@ -0,0 +1,38 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="Semicolon" format="2">
+ <advance width="630"/>
+ <unicode hex="003B"/>
+ <outline>
+ <contour>
+ <point x="314" y="758" type="curve" smooth="yes"/>
+ <point x="314" y="696"/>
+ <point x="365" y="642"/>
+ <point x="430" y="642" type="curve" smooth="yes"/>
+ <point x="514" y="642"/>
+ <point x="590" y="712"/>
+ <point x="590" y="792" type="curve" smooth="yes"/>
+ <point x="590" y="854"/>
+ <point x="540" y="907"/>
+ <point x="476" y="907" type="curve" smooth="yes"/>
+ <point x="393" y="907"/>
+ <point x="314" y="837"/>
+ </contour>
+ <contour>
+ <point x="137" y="49" type="line"/>
+ <point x="277" y="49" type="line"/>
+ <point x="252" y="-50"/>
+ <point x="145" y="-169"/>
+ <point x="73" y="-225" type="curve"/>
+ <point x="163" y="-265" type="line"/>
+ <point x="280" y="-175"/>
+ <point x="431" y="-28"/>
+ <point x="431" y="118" type="curve" smooth="yes"/>
+ <point x="431" y="193"/>
+ <point x="378" y="245"/>
+ <point x="311" y="245" type="curve" smooth="yes"/>
+ <point x="254" y="245"/>
+ <point x="190" y="209"/>
+ <point x="161" y="147" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfnormalize.ufo/glyphs/S_olidus.glif b/tests/reference/ufo/psfnormalize.ufo/glyphs/S_olidus.glif
new file mode 100644
index 0000000..589697b
--- /dev/null
+++ b/tests/reference/ufo/psfnormalize.ufo/glyphs/S_olidus.glif
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="Solidus" format="2">
+ <advance width="980"/>
+ <unicode hex="002F"/>
+ <outline>
+ <contour>
+ <point x="1160" y="1568" type="line"/>
+ <point x="-119" y="-240" type="line"/>
+ <point x="50" y="-240" type="line"/>
+ <point x="1330" y="1568" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfnormalize.ufo/glyphs/S_pace.glif b/tests/reference/ufo/psfnormalize.ufo/glyphs/S_pace.glif
new file mode 100644
index 0000000..c49f0f2
--- /dev/null
+++ b/tests/reference/ufo/psfnormalize.ufo/glyphs/S_pace.glif
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="Space" format="2">
+ <advance width="530"/>
+ <unicode hex="0020"/>
+ <outline/>
+</glyph>
diff --git a/tests/reference/ufo/psfnormalize.ufo/glyphs/T_ilde.glif b/tests/reference/ufo/psfnormalize.ufo/glyphs/T_ilde.glif
new file mode 100644
index 0000000..bf260b8
--- /dev/null
+++ b/tests/reference/ufo/psfnormalize.ufo/glyphs/T_ilde.glif
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="Tilde" format="2">
+ <advance width="1095"/>
+ <unicode hex="007E"/>
+ <outline>
+ <contour>
+ <point x="156" y="368" type="line"/>
+ <point x="173" y="416"/>
+ <point x="215" y="456"/>
+ <point x="293" y="456" type="curve" smooth="yes"/>
+ <point x="468" y="456"/>
+ <point x="643" y="353"/>
+ <point x="873" y="353" type="curve" smooth="yes"/>
+ <point x="1032" y="353"/>
+ <point x="1137" y="472"/>
+ <point x="1169" y="598" type="curve"/>
+ <point x="1064" y="598" type="line"/>
+ <point x="1045" y="553"/>
+ <point x="1002" y="500"/>
+ <point x="919" y="500" type="curve" smooth="yes"/>
+ <point x="683" y="500"/>
+ <point x="551" y="603"/>
+ <point x="330" y="603" type="curve" smooth="yes"/>
+ <point x="184" y="603"/>
+ <point x="81" y="487"/>
+ <point x="51" y="368" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfnormalize.ufo/glyphs/V_ertL_ine.glif b/tests/reference/ufo/psfnormalize.ufo/glyphs/V_ertL_ine.glif
new file mode 100644
index 0000000..445d622
--- /dev/null
+++ b/tests/reference/ufo/psfnormalize.ufo/glyphs/V_ertL_ine.glif
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="VertLine" format="2">
+ <advance width="670"/>
+ <unicode hex="007C"/>
+ <outline>
+ <contour>
+ <point x="602" y="1578" type="line"/>
+ <point x="112" y="-392" type="line"/>
+ <point x="262" y="-392" type="line"/>
+ <point x="752" y="1578" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfnormalize.ufo/glyphs/_notdef.glif b/tests/reference/ufo/psfnormalize.ufo/glyphs/_notdef.glif
new file mode 100644
index 0000000..a3e9354
--- /dev/null
+++ b/tests/reference/ufo/psfnormalize.ufo/glyphs/_notdef.glif
@@ -0,0 +1,18 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name=".notdef" format="2">
+ <advance width="1400"/>
+ <outline>
+ <contour>
+ <point x="100" y="0" type="line"/>
+ <point x="1300" y="0" type="line"/>
+ <point x="1300" y="1800" type="line"/>
+ <point x="100" y="1800" type="line"/>
+ </contour>
+ <contour>
+ <point x="150" y="1750" type="line"/>
+ <point x="1250" y="1750" type="line"/>
+ <point x="1250" y="50" type="line"/>
+ <point x="150" y="50" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfnormalize.ufo/glyphs/_null.glif b/tests/reference/ufo/psfnormalize.ufo/glyphs/_null.glif
new file mode 100644
index 0000000..0b9caa6
--- /dev/null
+++ b/tests/reference/ufo/psfnormalize.ufo/glyphs/_null.glif
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name=".null" format="2">
+ <outline/>
+</glyph>
diff --git a/tests/reference/ufo/psfnormalize.ufo/glyphs/contents.plist b/tests/reference/ufo/psfnormalize.ufo/glyphs/contents.plist
new file mode 100644
index 0000000..ad2aa41
--- /dev/null
+++ b/tests/reference/ufo/psfnormalize.ufo/glyphs/contents.plist
@@ -0,0 +1,232 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+ <key>.notdef</key>
+ <string>_notdef.glif</string>
+ <key>.null</key>
+ <string>_null.glif</string>
+ <key>Ampersand</key>
+ <string>A_mpersand.glif</string>
+ <key>Apos</key>
+ <string>A_pos.glif</string>
+ <key>Asterisk</key>
+ <string>A_sterisk.glif</string>
+ <key>AtSgn</key>
+ <string>A_tS_gn.glif</string>
+ <key>CircumAccent</key>
+ <string>C_ircumA_ccent.glif</string>
+ <key>Colon</key>
+ <string>C_olon.glif</string>
+ <key>CombAcute</key>
+ <string>C_ombA_cute.glif</string>
+ <key>CombCircum</key>
+ <string>C_ombC_ircum.glif</string>
+ <key>CombDiaer</key>
+ <string>C_ombD_iaer.glif</string>
+ <key>CombGrave</key>
+ <string>C_ombG_rave.glif</string>
+ <key>CombRingAbv</key>
+ <string>C_ombR_ingA_bv.glif</string>
+ <key>CombTilde</key>
+ <string>C_ombT_ilde.glif</string>
+ <key>Comma</key>
+ <string>C_omma.glif</string>
+ <key>DigitEight</key>
+ <string>D_igitE_ight.glif</string>
+ <key>DigitFive</key>
+ <string>D_igitF_ive.glif</string>
+ <key>DigitFour</key>
+ <string>D_igitF_our.glif</string>
+ <key>DigitNine</key>
+ <string>D_igitN_ine.glif</string>
+ <key>DigitOne</key>
+ <string>D_igitO_ne.glif</string>
+ <key>DigitSeven</key>
+ <string>D_igitS_even.glif</string>
+ <key>DigitSix</key>
+ <string>D_igitS_ix.glif</string>
+ <key>DigitThree</key>
+ <string>D_igitT_hree.glif</string>
+ <key>DigitTwo</key>
+ <string>D_igitT_wo.glif</string>
+ <key>DigitZero</key>
+ <string>D_igitZ_ero.glif</string>
+ <key>DollarSgn</key>
+ <string>D_ollarS_gn.glif</string>
+ <key>DottedCirc</key>
+ <string>D_ottedC_irc.glif</string>
+ <key>EqSgn</key>
+ <string>E_qS_gn.glif</string>
+ <key>ExclamationMrk</key>
+ <string>E_xclamationM_rk.glif</string>
+ <key>FullStop</key>
+ <string>F_ullS_top.glif</string>
+ <key>GTSgn</key>
+ <string>G_T_S_gn.glif</string>
+ <key>GraveAccent</key>
+ <string>G_raveA_ccent.glif</string>
+ <key>Hyphen</key>
+ <string>H_yphen.glif</string>
+ <key>HyphenMinus</key>
+ <string>H_yphenM_inus.glif</string>
+ <key>Hyphen_Soft</key>
+ <string>H_yphen_S_oft.glif</string>
+ <key>LTSgn</key>
+ <string>L_T_S_gn.glif</string>
+ <key>LftCurlyBrac</key>
+ <string>L_ftC_urlyB_rac.glif</string>
+ <key>LftParen</key>
+ <string>L_ftP_aren.glif</string>
+ <key>LftSqrBrac</key>
+ <string>L_ftS_qrB_rac.glif</string>
+ <key>LowLine</key>
+ <string>L_owL_ine.glif</string>
+ <key>LtnCapA</key>
+ <string>L_tnC_apA_.glif</string>
+ <key>LtnCapADiaer</key>
+ <string>L_tnC_apA_D_iaer.glif</string>
+ <key>LtnCapB</key>
+ <string>L_tnC_apB_.glif</string>
+ <key>LtnCapC</key>
+ <string>L_tnC_apC_.glif</string>
+ <key>LtnCapD</key>
+ <string>L_tnC_apD_.glif</string>
+ <key>LtnCapE</key>
+ <string>L_tnC_apE_.glif</string>
+ <key>LtnCapF</key>
+ <string>L_tnC_apF_.glif</string>
+ <key>LtnCapG</key>
+ <string>L_tnC_apG_.glif</string>
+ <key>LtnCapH</key>
+ <string>L_tnC_apH_.glif</string>
+ <key>LtnCapI</key>
+ <string>L_tnC_apI_.glif</string>
+ <key>LtnCapJ</key>
+ <string>L_tnC_apJ_.glif</string>
+ <key>LtnCapK</key>
+ <string>L_tnC_apK_.glif</string>
+ <key>LtnCapL</key>
+ <string>L_tnC_apL_.glif</string>
+ <key>LtnCapM</key>
+ <string>L_tnC_apM_.glif</string>
+ <key>LtnCapN</key>
+ <string>L_tnC_apN_.glif</string>
+ <key>LtnCapO</key>
+ <string>L_tnC_apO_.glif</string>
+ <key>LtnCapP</key>
+ <string>L_tnC_apP_.glif</string>
+ <key>LtnCapQ</key>
+ <string>L_tnC_apQ_.glif</string>
+ <key>LtnCapR</key>
+ <string>L_tnC_apR_.glif</string>
+ <key>LtnCapS</key>
+ <string>L_tnC_apS_.glif</string>
+ <key>LtnCapT</key>
+ <string>L_tnC_apT_.glif</string>
+ <key>LtnCapU</key>
+ <string>L_tnC_apU_.glif</string>
+ <key>LtnCapV</key>
+ <string>L_tnC_apV_.glif</string>
+ <key>LtnCapW</key>
+ <string>L_tnC_apW_.glif</string>
+ <key>LtnCapX</key>
+ <string>L_tnC_apX_.glif</string>
+ <key>LtnCapY</key>
+ <string>L_tnC_apY_.glif</string>
+ <key>LtnSmA</key>
+ <string>L_tnS_mA_.glif</string>
+ <key>LtnSmAAcute</key>
+ <string>L_tnS_mA_A_cute.glif</string>
+ <key>LtnSmACircum</key>
+ <string>L_tnS_mA_C_ircum.glif</string>
+ <key>LtnSmADiaer</key>
+ <string>L_tnS_mA_D_iaer.glif</string>
+ <key>LtnSmAGrave</key>
+ <string>L_tnS_mA_G_rave.glif</string>
+ <key>LtnSmARingAbv</key>
+ <string>L_tnS_mA_R_ingA_bv.glif</string>
+ <key>LtnSmATilde</key>
+ <string>L_tnS_mA_T_ilde.glif</string>
+ <key>LtnSmB</key>
+ <string>L_tnS_mB_.glif</string>
+ <key>LtnSmC</key>
+ <string>L_tnS_mC_.glif</string>
+ <key>LtnSmD</key>
+ <string>L_tnS_mD_.glif</string>
+ <key>LtnSmE</key>
+ <string>L_tnS_mE_.glif</string>
+ <key>LtnSmF</key>
+ <string>L_tnS_mF_.glif</string>
+ <key>LtnSmG</key>
+ <string>L_tnS_mG_.glif</string>
+ <key>LtnSmH</key>
+ <string>L_tnS_mH_.glif</string>
+ <key>LtnSmI</key>
+ <string>L_tnS_mI_.glif</string>
+ <key>LtnSmJ</key>
+ <string>L_tnS_mJ_.glif</string>
+ <key>LtnSmK</key>
+ <string>L_tnS_mK_.glif</string>
+ <key>LtnSmL</key>
+ <string>L_tnS_mL_.glif</string>
+ <key>LtnSmM</key>
+ <string>L_tnS_mM_.glif</string>
+ <key>LtnSmN</key>
+ <string>L_tnS_mN_.glif</string>
+ <key>LtnSmO</key>
+ <string>L_tnS_mO_.glif</string>
+ <key>LtnSmP</key>
+ <string>L_tnS_mP_.glif</string>
+ <key>LtnSmQ</key>
+ <string>L_tnS_mQ_.glif</string>
+ <key>LtnSmR</key>
+ <string>L_tnS_mR_.glif</string>
+ <key>LtnSmS</key>
+ <string>L_tnS_mS_.glif</string>
+ <key>LtnSmT</key>
+ <string>L_tnS_mT_.glif</string>
+ <key>LtnSmU</key>
+ <string>L_tnS_mU_.glif</string>
+ <key>LtnSmV</key>
+ <string>L_tnS_mV_.glif</string>
+ <key>LtnSmW</key>
+ <string>L_tnS_mW_.glif</string>
+ <key>LtnSmX</key>
+ <string>L_tnS_mX_.glif</string>
+ <key>LtnSmY</key>
+ <string>L_tnS_mY_.glif</string>
+ <key>NonBreakingHyphen</key>
+ <string>N_onB_reakingH_yphen.glif</string>
+ <key>NumSgn</key>
+ <string>N_umS_gn.glif</string>
+ <key>PercentSgn</key>
+ <string>P_ercentS_gn.glif</string>
+ <key>PlusSgn</key>
+ <string>P_lusS_gn.glif</string>
+ <key>QstnMrk</key>
+ <string>Q_stnM_rk.glif</string>
+ <key>QuotMrk</key>
+ <string>Q_uotM_rk.glif</string>
+ <key>ReverseSolidus</key>
+ <string>R_everseS_olidus.glif</string>
+ <key>RtCurlyBrac</key>
+ <string>R_tC_urlyB_rac.glif</string>
+ <key>RtParen</key>
+ <string>R_tP_aren.glif</string>
+ <key>RtSqrBrac</key>
+ <string>R_tS_qrB_rac.glif</string>
+ <key>Semicolon</key>
+ <string>S_emicolon.glif</string>
+ <key>Solidus</key>
+ <string>S_olidus.glif</string>
+ <key>Space</key>
+ <string>S_pace.glif</string>
+ <key>Tilde</key>
+ <string>T_ilde.glif</string>
+ <key>VertLine</key>
+ <string>V_ertL_ine.glif</string>
+ <key>nonmarkingreturn</key>
+ <string>nonmarkingreturn.glif</string>
+</dict>
+</plist>
diff --git a/tests/reference/ufo/psfnormalize.ufo/glyphs/nonmarkingreturn.glif b/tests/reference/ufo/psfnormalize.ufo/glyphs/nonmarkingreturn.glif
new file mode 100644
index 0000000..9a63f06
--- /dev/null
+++ b/tests/reference/ufo/psfnormalize.ufo/glyphs/nonmarkingreturn.glif
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="nonmarkingreturn" format="2">
+ <advance width="1004"/>
+ <outline/>
+</glyph>
diff --git a/tests/reference/ufo/psfnormalize.ufo/layercontents.plist b/tests/reference/ufo/psfnormalize.ufo/layercontents.plist
new file mode 100644
index 0000000..42b7482
--- /dev/null
+++ b/tests/reference/ufo/psfnormalize.ufo/layercontents.plist
@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<array>
+ <array>
+ <string>public.default</string>
+ <string>glyphs</string>
+ </array>
+</array>
+</plist>
diff --git a/tests/reference/ufo/psfnormalize.ufo/lib.plist b/tests/reference/ufo/psfnormalize.ufo/lib.plist
new file mode 100644
index 0000000..fa77038
--- /dev/null
+++ b/tests/reference/ufo/psfnormalize.ufo/lib.plist
@@ -0,0 +1,534 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+ <key>com.schriftgestaltung.Glyphs.fontUserData</key>
+ <dict/>
+ <key>com.schriftgestaltung.appVersion</key>
+ <string>1161</string>
+ <key>com.schriftgestaltung.customName</key>
+ <string>Italic</string>
+ <key>com.schriftgestaltung.customParameter.GSFont.DisplayStrings</key>
+ <string/>
+ <key>com.schriftgestaltung.customParameter.GSFont.disablesAutomaticAlignment</key>
+ <true/>
+ <key>com.schriftgestaltung.customParameter.GSFont.disablesLastChange</key>
+ <true/>
+ <key>com.schriftgestaltung.customParameter.GSFont.useNiceNames</key>
+ <integer>0</integer>
+ <key>com.schriftgestaltung.customParameter.GSFontMaster.customValue</key>
+ <integer>0</integer>
+ <key>com.schriftgestaltung.customParameter.GSFontMaster.customValue1</key>
+ <integer>0</integer>
+ <key>com.schriftgestaltung.customParameter.GSFontMaster.customValue2</key>
+ <integer>0</integer>
+ <key>com.schriftgestaltung.customParameter.GSFontMaster.customValue3</key>
+ <integer>0</integer>
+ <key>com.schriftgestaltung.customParameter.GSFontMaster.iconName</key>
+ <string/>
+ <key>com.schriftgestaltung.customParameter.GSFontMaster.weightValue</key>
+ <integer>400</integer>
+ <key>com.schriftgestaltung.customParameter.GSFontMaster.widthValue</key>
+ <integer>100</integer>
+ <key>com.schriftgestaltung.fontMasterOrder</key>
+ <integer>0</integer>
+ <key>com.schriftgestaltung.glyphOrder</key>
+ <array>
+ <string>.notdef</string>
+ <string>.null</string>
+ <string>nonmarkingreturn</string>
+ <string>Space</string>
+ <string>ExclamationMrk</string>
+ <string>QuotMrk</string>
+ <string>NumSgn</string>
+ <string>DollarSgn</string>
+ <string>PercentSgn</string>
+ <string>Ampersand</string>
+ <string>Apos</string>
+ <string>LftParen</string>
+ <string>RtParen</string>
+ <string>Asterisk</string>
+ <string>PlusSgn</string>
+ <string>Comma</string>
+ <string>HyphenMinus</string>
+ <string>FullStop</string>
+ <string>Solidus</string>
+ <string>DigitZero</string>
+ <string>DigitOne</string>
+ <string>DigitTwo</string>
+ <string>DigitThree</string>
+ <string>DigitFour</string>
+ <string>DigitFive</string>
+ <string>DigitSix</string>
+ <string>DigitSeven</string>
+ <string>DigitEight</string>
+ <string>DigitNine</string>
+ <string>Colon</string>
+ <string>Semicolon</string>
+ <string>LTSgn</string>
+ <string>EqSgn</string>
+ <string>GTSgn</string>
+ <string>QstnMrk</string>
+ <string>AtSgn</string>
+ <string>LtnCapA</string>
+ <string>LtnCapA.alt</string>
+ <string>LtnCapB</string>
+ <string>LtnCapC</string>
+ <string>LtnCapD</string>
+ <string>LtnCapE</string>
+ <string>LtnCapF</string>
+ <string>LtnCapG</string>
+ <string>LtnCapH</string>
+ <string>LtnCapI</string>
+ <string>LtnCapJ</string>
+ <string>LtnCapK</string>
+ <string>LtnCapL</string>
+ <string>LtnCapM</string>
+ <string>LtnCapN</string>
+ <string>LtnCapO</string>
+ <string>LtnCapP</string>
+ <string>LtnCapQ</string>
+ <string>LtnCapR</string>
+ <string>LtnCapS</string>
+ <string>LtnCapT</string>
+ <string>LtnCapU</string>
+ <string>LtnCapV</string>
+ <string>LtnCapW</string>
+ <string>LtnCapX</string>
+ <string>LtnCapY</string>
+ <string>LftSqrBrac</string>
+ <string>ReverseSolidus</string>
+ <string>RtSqrBrac</string>
+ <string>CircumAccent</string>
+ <string>LowLine</string>
+ <string>GraveAccent</string>
+ <string>LtnSmA</string>
+ <string>LtnSmB</string>
+ <string>LtnSmC</string>
+ <string>LtnSmD</string>
+ <string>LtnSmE</string>
+ <string>LtnSmF</string>
+ <string>LtnSmG</string>
+ <string>LtnSmH</string>
+ <string>LtnSmI</string>
+ <string>LtnSmJ</string>
+ <string>LtnSmK</string>
+ <string>LtnSmL</string>
+ <string>LtnSmM</string>
+ <string>LtnSmN</string>
+ <string>LtnSmO</string>
+ <string>LtnSmP</string>
+ <string>LtnSmQ</string>
+ <string>LtnSmR</string>
+ <string>LtnSmS</string>
+ <string>LtnSmT</string>
+ <string>LtnSmU</string>
+ <string>LtnSmV</string>
+ <string>LtnSmW</string>
+ <string>LtnSmX</string>
+ <string>LtnSmY</string>
+ <string>LftCurlyBrac</string>
+ <string>VertLine</string>
+ <string>RtCurlyBrac</string>
+ <string>Tilde</string>
+ <string>LtnCapADiaer</string>
+ <string>LtnSmAAcute</string>
+ <string>LtnSmAGrave</string>
+ <string>LtnSmACircum</string>
+ <string>LtnSmADiaer</string>
+ <string>LtnSmATilde</string>
+ <string>LtnSmARingAbv</string>
+ <string>DottedCirc</string>
+ <string>Hyphen</string>
+ <string>NonBreakingHyphen</string>
+ <string>Hyphen_Soft</string>
+ <string>CombAcute</string>
+ <string>CombGrave</string>
+ <string>CombCircum</string>
+ <string>CombTilde</string>
+ <string>CombDiaer</string>
+ <string>CombRingAbv</string>
+ </array>
+ <key>com.schriftgestaltung.keyboardIncrement</key>
+ <integer>1</integer>
+ <key>com.schriftgestaltung.weight</key>
+ <string>Regular</string>
+ <key>com.schriftgestaltung.weightValue</key>
+ <integer>400</integer>
+ <key>com.schriftgestaltung.width</key>
+ <string>Regular</string>
+ <key>com.schriftgestaltung.widthValue</key>
+ <integer>100</integer>
+ <key>org.sil.lcg.toneLetters</key>
+ <dict>
+ <key>contourWidth</key>
+ <integer>480</integer>
+ <key>dotSize</key>
+ <integer>180</integer>
+ <key>dotSpacing</key>
+ <integer>200</integer>
+ <key>glyphDepth</key>
+ <integer>-25</integer>
+ <key>glyphHeight</key>
+ <integer>1600</integer>
+ <key>italicAngle</key>
+ <integer>14</integer>
+ <key>marginDotLeft</key>
+ <integer>120</integer>
+ <key>marginDotRight</key>
+ <integer>160</integer>
+ <key>marginFlatLeft</key>
+ <integer>120</integer>
+ <key>marginFlatRight</key>
+ <integer>160</integer>
+ <key>marginPointLeft</key>
+ <integer>100</integer>
+ <key>marginPointRight</key>
+ <integer>140</integer>
+ <key>strokeThickness</key>
+ <integer>120</integer>
+ </dict>
+ <key>public.glyphOrder</key>
+ <array>
+ <string>.notdef</string>
+ <string>.null</string>
+ <string>nonmarkingreturn</string>
+ <string>Space</string>
+ <string>ExclamationMrk</string>
+ <string>QuotMrk</string>
+ <string>NumSgn</string>
+ <string>DollarSgn</string>
+ <string>PercentSgn</string>
+ <string>Ampersand</string>
+ <string>Apos</string>
+ <string>LftParen</string>
+ <string>RtParen</string>
+ <string>Asterisk</string>
+ <string>PlusSgn</string>
+ <string>Comma</string>
+ <string>HyphenMinus</string>
+ <string>FullStop</string>
+ <string>Solidus</string>
+ <string>DigitZero</string>
+ <string>DigitOne</string>
+ <string>DigitTwo</string>
+ <string>DigitThree</string>
+ <string>DigitFour</string>
+ <string>DigitFive</string>
+ <string>DigitSix</string>
+ <string>DigitSeven</string>
+ <string>DigitEight</string>
+ <string>DigitNine</string>
+ <string>Colon</string>
+ <string>Semicolon</string>
+ <string>LTSgn</string>
+ <string>EqSgn</string>
+ <string>GTSgn</string>
+ <string>QstnMrk</string>
+ <string>AtSgn</string>
+ <string>LtnCapA</string>
+ <string>LtnCapA.alt</string>
+ <string>LtnCapB</string>
+ <string>LtnCapC</string>
+ <string>LtnCapD</string>
+ <string>LtnCapE</string>
+ <string>LtnCapF</string>
+ <string>LtnCapG</string>
+ <string>LtnCapH</string>
+ <string>LtnCapI</string>
+ <string>LtnCapJ</string>
+ <string>LtnCapK</string>
+ <string>LtnCapL</string>
+ <string>LtnCapM</string>
+ <string>LtnCapN</string>
+ <string>LtnCapO</string>
+ <string>LtnCapP</string>
+ <string>LtnCapQ</string>
+ <string>LtnCapR</string>
+ <string>LtnCapS</string>
+ <string>LtnCapT</string>
+ <string>LtnCapU</string>
+ <string>LtnCapV</string>
+ <string>LtnCapW</string>
+ <string>LtnCapX</string>
+ <string>LtnCapY</string>
+ <string>LftSqrBrac</string>
+ <string>ReverseSolidus</string>
+ <string>RtSqrBrac</string>
+ <string>CircumAccent</string>
+ <string>LowLine</string>
+ <string>GraveAccent</string>
+ <string>LtnSmA</string>
+ <string>LtnSmB</string>
+ <string>LtnSmC</string>
+ <string>LtnSmD</string>
+ <string>LtnSmE</string>
+ <string>LtnSmF</string>
+ <string>LtnSmG</string>
+ <string>LtnSmH</string>
+ <string>LtnSmI</string>
+ <string>LtnSmJ</string>
+ <string>LtnSmK</string>
+ <string>LtnSmL</string>
+ <string>LtnSmM</string>
+ <string>LtnSmN</string>
+ <string>LtnSmO</string>
+ <string>LtnSmP</string>
+ <string>LtnSmQ</string>
+ <string>LtnSmR</string>
+ <string>LtnSmS</string>
+ <string>LtnSmT</string>
+ <string>LtnSmU</string>
+ <string>LtnSmV</string>
+ <string>LtnSmW</string>
+ <string>LtnSmX</string>
+ <string>LtnSmY</string>
+ <string>LftCurlyBrac</string>
+ <string>VertLine</string>
+ <string>RtCurlyBrac</string>
+ <string>Tilde</string>
+ <string>LtnCapADiaer</string>
+ <string>LtnSmAAcute</string>
+ <string>LtnSmAGrave</string>
+ <string>LtnSmACircum</string>
+ <string>LtnSmADiaer</string>
+ <string>LtnSmATilde</string>
+ <string>LtnSmARingAbv</string>
+ <string>DottedCirc</string>
+ <string>Hyphen</string>
+ <string>NonBreakingHyphen</string>
+ <string>Hyphen_Soft</string>
+ <string>CombAcute</string>
+ <string>CombGrave</string>
+ <string>CombCircum</string>
+ <string>CombTilde</string>
+ <string>CombDiaer</string>
+ <string>CombRingAbv</string>
+ </array>
+ <key>public.postscriptNames</key>
+ <dict>
+ <key>Ampersand</key>
+ <string>ampersand</string>
+ <key>Apos</key>
+ <string>quotesingle</string>
+ <key>Asterisk</key>
+ <string>asterisk</string>
+ <key>AtSgn</key>
+ <string>at</string>
+ <key>CircumAccent</key>
+ <string>asciicircum</string>
+ <key>Colon</key>
+ <string>colon</string>
+ <key>CombAcute</key>
+ <string>acutecomb</string>
+ <key>CombCircum</key>
+ <string>uni0302</string>
+ <key>CombDiaer</key>
+ <string>uni0308</string>
+ <key>CombGrave</key>
+ <string>gravecomb</string>
+ <key>CombRingAbv</key>
+ <string>uni030A</string>
+ <key>CombTilde</key>
+ <string>tildecomb</string>
+ <key>Comma</key>
+ <string>comma</string>
+ <key>DigitEight</key>
+ <string>eight</string>
+ <key>DigitFive</key>
+ <string>five</string>
+ <key>DigitFour</key>
+ <string>four</string>
+ <key>DigitNine</key>
+ <string>nine</string>
+ <key>DigitOne</key>
+ <string>one</string>
+ <key>DigitSeven</key>
+ <string>seven</string>
+ <key>DigitSix</key>
+ <string>six</string>
+ <key>DigitThree</key>
+ <string>three</string>
+ <key>DigitTwo</key>
+ <string>two</string>
+ <key>DigitZero</key>
+ <string>zero</string>
+ <key>DollarSgn</key>
+ <string>dollar</string>
+ <key>DottedCirc</key>
+ <string>uni25CC</string>
+ <key>EqSgn</key>
+ <string>equal</string>
+ <key>ExclamationMrk</key>
+ <string>exclam</string>
+ <key>FullStop</key>
+ <string>period</string>
+ <key>GTSgn</key>
+ <string>greater</string>
+ <key>GraveAccent</key>
+ <string>grave</string>
+ <key>Hyphen</key>
+ <string>uni2010</string>
+ <key>HyphenMinus</key>
+ <string>hyphen</string>
+ <key>Hyphen_Soft</key>
+ <string>uni00AD</string>
+ <key>LTSgn</key>
+ <string>less</string>
+ <key>LftCurlyBrac</key>
+ <string>braceleft</string>
+ <key>LftParen</key>
+ <string>parenleft</string>
+ <key>LftSqrBrac</key>
+ <string>bracketleft</string>
+ <key>LowLine</key>
+ <string>underscore</string>
+ <key>LtnCapA</key>
+ <string>A</string>
+ <key>LtnCapA.alt</key>
+ <string>A</string>
+ <key>LtnCapADiaer</key>
+ <string>Adieresis</string>
+ <key>LtnCapB</key>
+ <string>B</string>
+ <key>LtnCapC</key>
+ <string>C</string>
+ <key>LtnCapD</key>
+ <string>D</string>
+ <key>LtnCapE</key>
+ <string>E</string>
+ <key>LtnCapF</key>
+ <string>F</string>
+ <key>LtnCapG</key>
+ <string>G</string>
+ <key>LtnCapH</key>
+ <string>H</string>
+ <key>LtnCapI</key>
+ <string>I</string>
+ <key>LtnCapJ</key>
+ <string>J</string>
+ <key>LtnCapK</key>
+ <string>K</string>
+ <key>LtnCapL</key>
+ <string>L</string>
+ <key>LtnCapM</key>
+ <string>M</string>
+ <key>LtnCapN</key>
+ <string>N</string>
+ <key>LtnCapO</key>
+ <string>O</string>
+ <key>LtnCapP</key>
+ <string>P</string>
+ <key>LtnCapQ</key>
+ <string>Q</string>
+ <key>LtnCapR</key>
+ <string>R</string>
+ <key>LtnCapS</key>
+ <string>S</string>
+ <key>LtnCapT</key>
+ <string>T</string>
+ <key>LtnCapU</key>
+ <string>U</string>
+ <key>LtnCapV</key>
+ <string>V</string>
+ <key>LtnCapW</key>
+ <string>W</string>
+ <key>LtnCapX</key>
+ <string>X</string>
+ <key>LtnCapY</key>
+ <string>Y</string>
+ <key>LtnSmA</key>
+ <string>a</string>
+ <key>LtnSmAAcute</key>
+ <string>aacute</string>
+ <key>LtnSmACircum</key>
+ <string>acircumflex</string>
+ <key>LtnSmADiaer</key>
+ <string>adieresis</string>
+ <key>LtnSmAGrave</key>
+ <string>agrave</string>
+ <key>LtnSmARingAbv</key>
+ <string>aring</string>
+ <key>LtnSmATilde</key>
+ <string>atilde</string>
+ <key>LtnSmB</key>
+ <string>b</string>
+ <key>LtnSmC</key>
+ <string>c</string>
+ <key>LtnSmD</key>
+ <string>d</string>
+ <key>LtnSmE</key>
+ <string>e</string>
+ <key>LtnSmF</key>
+ <string>f</string>
+ <key>LtnSmG</key>
+ <string>g</string>
+ <key>LtnSmH</key>
+ <string>h</string>
+ <key>LtnSmI</key>
+ <string>i</string>
+ <key>LtnSmJ</key>
+ <string>j</string>
+ <key>LtnSmK</key>
+ <string>k</string>
+ <key>LtnSmL</key>
+ <string>l</string>
+ <key>LtnSmM</key>
+ <string>m</string>
+ <key>LtnSmN</key>
+ <string>n</string>
+ <key>LtnSmO</key>
+ <string>o</string>
+ <key>LtnSmP</key>
+ <string>p</string>
+ <key>LtnSmQ</key>
+ <string>q</string>
+ <key>LtnSmR</key>
+ <string>r</string>
+ <key>LtnSmS</key>
+ <string>s</string>
+ <key>LtnSmT</key>
+ <string>t</string>
+ <key>LtnSmU</key>
+ <string>u</string>
+ <key>LtnSmV</key>
+ <string>v</string>
+ <key>LtnSmW</key>
+ <string>w</string>
+ <key>LtnSmX</key>
+ <string>x</string>
+ <key>LtnSmY</key>
+ <string>y</string>
+ <key>NonBreakingHyphen</key>
+ <string>uni2011</string>
+ <key>NumSgn</key>
+ <string>numbersign</string>
+ <key>PercentSgn</key>
+ <string>percent</string>
+ <key>PlusSgn</key>
+ <string>plus</string>
+ <key>QstnMrk</key>
+ <string>question</string>
+ <key>QuotMrk</key>
+ <string>quotedbl</string>
+ <key>ReverseSolidus</key>
+ <string>backslash</string>
+ <key>RtCurlyBrac</key>
+ <string>braceright</string>
+ <key>RtParen</key>
+ <string>parenright</string>
+ <key>RtSqrBrac</key>
+ <string>bracketright</string>
+ <key>Semicolon</key>
+ <string>semicolon</string>
+ <key>Solidus</key>
+ <string>slash</string>
+ <key>Space</key>
+ <string>space</string>
+ <key>Tilde</key>
+ <string>asciitilde</string>
+ <key>VertLine</key>
+ <string>bar</string>
+ </dict>
+</dict>
+</plist>
diff --git a/tests/reference/ufo/psfnormalize.ufo/metainfo.plist b/tests/reference/ufo/psfnormalize.ufo/metainfo.plist
new file mode 100644
index 0000000..aa10c5c
--- /dev/null
+++ b/tests/reference/ufo/psfnormalize.ufo/metainfo.plist
@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+ <key>creator</key>
+ <string>org.sil.scripts.pysilfont</string>
+ <key>formatVersion</key>
+ <integer>3</integer>
+</dict>
+</plist>
diff --git a/tests/reference/ufo/psfrenameglyphs.lg b/tests/reference/ufo/psfrenameglyphs.lg
new file mode 100644
index 0000000..557bc2f
--- /dev/null
+++ b/tests/reference/ufo/psfrenameglyphs.lg
@@ -0,0 +1,34 @@
+2021-06-29 14:42:22 Progress: Running: psfrenameglyphs tests/input/font-psf-test/source/PsfTest-Bold.ufo -i tests/input/psfrenameglyphs.csv -l local/testresults/ufo/psfrenameglyphs.log -p loglevel=i -p checkfix=fix
+2021-06-29 14:42:22 Progress: Opening file for input: tests/input/psfrenameglyphs.csv
+2021-06-29 14:42:22 Progress: Reading UFO: tests/input/font-psf-test/source/PsfTest-Bold.ufo
+2021-06-29 14:42:22 Info: Processing Glyph Layer 0: public.defaultglyphs
+2021-06-29 14:42:22 Progress: Checking fontinfo.plist metadata
+2021-06-29 14:42:22 Warning: note is present - it's use is discouraged
+2021-06-29 14:42:22 Warning: openTypeOS2FamilyClass removed from fontinfo. Old value: [0, 0]
+2021-06-29 14:42:22 Info: Types: Old - list, New - NoneType
+2021-06-29 14:42:22 Warning: openTypeOS2Selection added New value: [7]
+2021-06-29 14:42:22 Info: Types: Old - NoneType, New - list
+2021-06-29 14:42:22 Progress: Checking lib.plist metadata
+2021-06-29 14:42:22 Warning: com.schriftgestaltung.disablesAutomaticAlignment deleted - obsolete key Old value: True
+2021-06-29 14:42:22 Info: Types: Old - bool, New - NoneType
+2021-06-29 14:42:22 Warning: com.schriftgestaltung.disablesLastChange deleted - obsolete key Old value: True
+2021-06-29 14:42:22 Info: Types: Old - bool, New - NoneType
+2021-06-29 14:42:22 Progress: Check & fix results:- Errors: 0, Changes made: 4, Other warnings: 1
+2021-06-29 14:42:22 Progress: See log file for details
+2021-06-29 14:42:22 Info: Pass 1 (Font): Renamed Apos to Bpos
+2021-06-29 14:42:22 Info: Pass 1 (PGO): Renamed Apos to Bpos
+2021-06-29 14:42:22 Info: Pass 1 (csGO): Renamed Apos to Bpos
+2021-06-29 14:42:22 Info: Pass 1 (psn): Renamed Apos to Bpos
+2021-06-29 14:42:22 Info: Pass 1 (Font): Renamed Asterisk to Star
+2021-06-29 14:42:22 Info: Pass 1 (PGO): Renamed Asterisk to Star
+2021-06-29 14:42:22 Info: Pass 1 (csGO): Renamed Asterisk to Star
+2021-06-29 14:42:22 Info: Pass 1 (psn): Renamed Asterisk to Star
+2021-06-29 14:42:22 Info: glyph name not in font: Commer
+2021-06-29 14:42:22 Info: glyph name not in publicGlyphorder: Commer
+2021-06-29 14:42:22 Info: glyph name not in csGlyphorder: Commer
+2021-06-29 14:42:22 Info: glyph name not in psnames: Commer
+2021-06-29 14:42:22 Progress: 2 glyphs renamed in UFO
+2021-06-29 14:42:22 Progress: Processing font for output
+2021-06-29 14:42:22 Progress: Output UFO already exists - reading for comparison
+2021-06-29 14:42:22 Progress: Writing font to local/testresults/ufo/psfrenameglyphs.ufo
+2021-06-29 14:42:22 Info: Processing glyphs directory
diff --git a/tests/reference/ufo/psfrenameglyphs.ufo/fontinfo.plist b/tests/reference/ufo/psfrenameglyphs.ufo/fontinfo.plist
new file mode 100644
index 0000000..c60d899
--- /dev/null
+++ b/tests/reference/ufo/psfrenameglyphs.ufo/fontinfo.plist
@@ -0,0 +1,244 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+ <key>ascender</key>
+ <integer>2100</integer>
+ <key>capHeight</key>
+ <integer>1485</integer>
+ <key>copyright</key>
+ <string>Copyright (c) 2004-2021 SIL International</string>
+ <key>descender</key>
+ <integer>-550</integer>
+ <key>familyName</key>
+ <string>Psf Test</string>
+ <key>note</key>
+ <string>Test note
+Second line
+
+Third line
+</string>
+ <key>openTypeHeadCreated</key>
+ <string>2021/06/29 14:43:52</string>
+ <key>openTypeHheaAscender</key>
+ <integer>2100</integer>
+ <key>openTypeHheaDescender</key>
+ <integer>-550</integer>
+ <key>openTypeHheaLineGap</key>
+ <integer>0</integer>
+ <key>openTypeNameDescription</key>
+ <string>Copyright (c) 2004-2021 SIL International</string>
+ <key>openTypeNameDesigner</key>
+ <string>Victor Gaultney, Annie Olsen, Julie Remington, Don Collingsworth, Eric Hays, Becca Hirsbrunner</string>
+ <key>openTypeNameDesignerURL</key>
+ <string>http://scripts.sil.org/</string>
+ <key>openTypeNameLicense</key>
+ <string>Copyright (c) 2004-2021 SIL International (http://www.sil.org/) with Reserved Font Names "Andika" and "SIL".
+
+This Font Software is licensed under the SIL Open Font License, Version 1.1. This license is copied below, and is also available with a FAQ at: http://scripts.sil.org/OFL
+
+
+-----------------------------------------------------------
+SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007
+-----------------------------------------------------------
+
+PREAMBLE
+The goals of the Open Font License (OFL) are to stimulate worldwide development of collaborative font projects, to support the font creation efforts of academic and linguistic communities, and to provide a free and open framework in which fonts may be shared and improved in partnership with others.
+
+The OFL allows the licensed fonts to be used, studied, modified and redistributed freely as long as they are not sold by themselves. The fonts, including any derivative works, can be bundled, embedded, redistributed and/or sold with any software provided that any reserved names are not used by derivative works. The fonts and derivatives, however, cannot be released under any other type of license. The requirement for fonts to remain under this license does not apply to any document created using the fonts or their derivatives.
+
+DEFINITIONS
+"Font Software" refers to the set of files released by the Copyright Holder(s) under this license and clearly marked as such. This may include source files, build scripts and documentation.
+
+"Reserved Font Name" refers to any names specified as such after the copyright statement(s).
+
+"Original Version" refers to the collection of Font Software components as distributed by the Copyright Holder(s).
+
+"Modified Version" refers to any derivative made by adding to, deleting, or substituting -- in part or in whole -- any of the components of the Original Version, by changing formats or by porting the Font Software to a new environment.
+
+"Author" refers to any designer, engineer, programmer, technical writer or other person who contributed to the Font Software.
+
+PERMISSION &amp; CONDITIONS
+Permission is hereby granted, free of charge, to any person obtaining a copy of the Font Software, to use, study, copy, merge, embed, modify, redistribute, and sell modified and unmodified copies of the Font Software, subject to the following conditions:
+
+1) Neither the Font Software nor any of its individual components, in Original or Modified Versions, may be sold by itself.
+
+2) Original or Modified Versions of the Font Software may be bundled, redistributed and/or sold with any software, provided that each copy contains the above copyright notice and this license. These can be included either as stand-alone text files, human-readable headers or in the appropriate machine-readable metadata fields within text or binary files as long as those fields can be easily viewed by the user.
+
+3) No Modified Version of the Font Software may use the Reserved Font Name(s) unless explicit written permission is granted by the corresponding Copyright Holder. This restriction only applies to the primary font name as presented to the users.
+
+4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font Software shall not be used to promote, endorse or advertise any Modified Version, except to acknowledge the contribution(s) of the Copyright Holder(s) and the Author(s) or with their explicit written permission.
+
+5) The Font Software, modified or unmodified, in part or in whole, must be distributed entirely under this license, and must not be distributed under any other license. The requirement for fonts to remain under this license does not apply to any document created using the Font Software.
+
+TERMINATION
+This license becomes null and void if any of the above conditions are not met.
+
+DISCLAIMER
+THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM OTHER DEALINGS IN THE FONT SOFTWARE.</string>
+ <key>openTypeNameLicenseURL</key>
+ <string>http://scripts.sil.org/OFL</string>
+ <key>openTypeNameManufacturer</key>
+ <string>SIL International</string>
+ <key>openTypeNameManufacturerURL</key>
+ <string>http://scripts.sil.org</string>
+ <key>openTypeNamePreferredFamilyName</key>
+ <string>Psf Test</string>
+ <key>openTypeNamePreferredSubfamilyName</key>
+ <string>Bold</string>
+ <key>openTypeNameUniqueID</key>
+ <string>SIL International: Psf Test Bold: 2022</string>
+ <key>openTypeNameVersion</key>
+ <string>Version 5.550</string>
+ <key>openTypeOS2CodePageRanges</key>
+ <array>
+ <integer>0</integer>
+ <integer>1</integer>
+ <integer>2</integer>
+ <integer>4</integer>
+ <integer>7</integer>
+ <integer>8</integer>
+ </array>
+ <key>openTypeOS2Panose</key>
+ <array>
+ <integer>2</integer>
+ <integer>0</integer>
+ <integer>0</integer>
+ <integer>0</integer>
+ <integer>0</integer>
+ <integer>0</integer>
+ <integer>0</integer>
+ <integer>0</integer>
+ <integer>0</integer>
+ <integer>0</integer>
+ </array>
+ <key>openTypeOS2Selection</key>
+ <array>
+ <integer>7</integer>
+ </array>
+ <key>openTypeOS2StrikeoutPosition</key>
+ <integer>700</integer>
+ <key>openTypeOS2StrikeoutSize</key>
+ <integer>100</integer>
+ <key>openTypeOS2SubscriptXOffset</key>
+ <integer>0</integer>
+ <key>openTypeOS2SubscriptXSize</key>
+ <integer>1433</integer>
+ <key>openTypeOS2SubscriptYOffset</key>
+ <integer>286</integer>
+ <key>openTypeOS2SubscriptYSize</key>
+ <integer>1331</integer>
+ <key>openTypeOS2SuperscriptXOffset</key>
+ <integer>0</integer>
+ <key>openTypeOS2SuperscriptXSize</key>
+ <integer>1433</integer>
+ <key>openTypeOS2SuperscriptYOffset</key>
+ <integer>976</integer>
+ <key>openTypeOS2SuperscriptYSize</key>
+ <integer>1331</integer>
+ <key>openTypeOS2Type</key>
+ <array/>
+ <key>openTypeOS2TypoAscender</key>
+ <integer>2100</integer>
+ <key>openTypeOS2TypoDescender</key>
+ <integer>-550</integer>
+ <key>openTypeOS2TypoLineGap</key>
+ <integer>0</integer>
+ <key>openTypeOS2UnicodeRanges</key>
+ <array>
+ <integer>0</integer>
+ <integer>1</integer>
+ <integer>6</integer>
+ <integer>7</integer>
+ <integer>31</integer>
+ <integer>33</integer>
+ <integer>35</integer>
+ <integer>36</integer>
+ <integer>37</integer>
+ <integer>38</integer>
+ <integer>39</integer>
+ <integer>40</integer>
+ <integer>45</integer>
+ <integer>46</integer>
+ <integer>47</integer>
+ <integer>57</integer>
+ <integer>60</integer>
+ <integer>62</integer>
+ <integer>64</integer>
+ <integer>67</integer>
+ <integer>69</integer>
+ <integer>89</integer>
+ </array>
+ <key>openTypeOS2VendorID</key>
+ <string>SIL</string>
+ <key>openTypeOS2WeightClass</key>
+ <integer>700</integer>
+ <key>openTypeOS2WidthClass</key>
+ <integer>5</integer>
+ <key>openTypeOS2WinAscent</key>
+ <integer>2100</integer>
+ <key>openTypeOS2WinDescent</key>
+ <integer>550</integer>
+ <key>postscriptBlueValues</key>
+ <array>
+ <integer>-490</integer>
+ <integer>-490</integer>
+ <integer>-25</integer>
+ <integer>0</integer>
+ <integer>1020</integer>
+ <integer>1040</integer>
+ <integer>1455</integer>
+ <integer>1485</integer>
+ <integer>1600</integer>
+ <integer>1620</integer>
+ </array>
+ <key>postscriptFontName</key>
+ <string>PsfTest-Bold</string>
+ <key>postscriptFullName</key>
+ <string>Psf Test Bold</string>
+ <key>postscriptStemSnapH</key>
+ <array>
+ <integer>140</integer>
+ <integer>145</integer>
+ <integer>150</integer>
+ <integer>155</integer>
+ <integer>160</integer>
+ <integer>165</integer>
+ <integer>170</integer>
+ <integer>175</integer>
+ <integer>185</integer>
+ <integer>270</integer>
+ </array>
+ <key>postscriptStemSnapV</key>
+ <array>
+ <integer>165</integer>
+ <integer>180</integer>
+ <integer>185</integer>
+ <integer>190</integer>
+ <integer>195</integer>
+ <integer>200</integer>
+ <integer>205</integer>
+ <integer>270</integer>
+ </array>
+ <key>postscriptUnderlinePosition</key>
+ <integer>-110</integer>
+ <key>postscriptUnderlineThickness</key>
+ <integer>80</integer>
+ <key>styleMapFamilyName</key>
+ <string>Psf Test</string>
+ <key>styleMapStyleName</key>
+ <string>bold</string>
+ <key>styleName</key>
+ <string>Bold</string>
+ <key>trademark</key>
+ <string>Andika is a trademark of SIL International.</string>
+ <key>unitsPerEm</key>
+ <integer>2048</integer>
+ <key>versionMajor</key>
+ <integer>5</integer>
+ <key>versionMinor</key>
+ <integer>550</integer>
+ <key>xHeight</key>
+ <integer>1040</integer>
+</dict>
+</plist>
diff --git a/tests/reference/ufo/psfrenameglyphs.ufo/glyphs/A_mpersand.glif b/tests/reference/ufo/psfrenameglyphs.ufo/glyphs/A_mpersand.glif
new file mode 100644
index 0000000..f2749f2
--- /dev/null
+++ b/tests/reference/ufo/psfrenameglyphs.ufo/glyphs/A_mpersand.glif
@@ -0,0 +1,61 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="Ampersand" format="2">
+ <advance width="1355"/>
+ <unicode hex="0026"/>
+ <outline>
+ <contour>
+ <point x="1060" y="600" type="line"/>
+ <point x="996" y="433"/>
+ <point x="715" y="190"/>
+ <point x="540" y="190" type="curve" smooth="yes"/>
+ <point x="425" y="190"/>
+ <point x="335" y="257"/>
+ <point x="335" y="370" type="curve" smooth="yes"/>
+ <point x="335" y="480"/>
+ <point x="411" y="547"/>
+ <point x="585" y="700" type="curve" smooth="yes"/>
+ <point x="766" y="859"/>
+ <point x="925" y="1048"/>
+ <point x="925" y="1190" type="curve" smooth="yes"/>
+ <point x="925" y="1372"/>
+ <point x="777" y="1485"/>
+ <point x="575" y="1485" type="curve" smooth="yes"/>
+ <point x="366" y="1485"/>
+ <point x="190" y="1372"/>
+ <point x="190" y="1160" type="curve" smooth="yes"/>
+ <point x="190" y="1000"/>
+ <point x="407" y="785"/>
+ <point x="590" y="540" type="curve" smooth="yes"/>
+ <point x="859" y="179"/>
+ <point x="1038" y="-25"/>
+ <point x="1090" y="-25" type="curve" smooth="yes"/>
+ <point x="1125" y="-25"/>
+ <point x="1253" y="58"/>
+ <point x="1290" y="90" type="curve"/>
+ <point x="1195" y="130"/>
+ <point x="1060" y="305"/>
+ <point x="785" y="680" type="curve" smooth="yes"/>
+ <point x="619" y="906"/>
+ <point x="420" y="1085"/>
+ <point x="420" y="1170" type="curve" smooth="yes"/>
+ <point x="420" y="1241"/>
+ <point x="483" y="1310"/>
+ <point x="560" y="1310" type="curve" smooth="yes"/>
+ <point x="640" y="1310"/>
+ <point x="695" y="1254"/>
+ <point x="695" y="1175" type="curve" smooth="yes"/>
+ <point x="695" y="1106"/>
+ <point x="628" y="1001"/>
+ <point x="455" y="840" type="curve" smooth="yes"/>
+ <point x="251" y="651"/>
+ <point x="90" y="527"/>
+ <point x="90" y="344" type="curve" smooth="yes"/>
+ <point x="90" y="121"/>
+ <point x="242" y="-25"/>
+ <point x="525" y="-25" type="curve" smooth="yes"/>
+ <point x="808" y="-25"/>
+ <point x="1117" y="264"/>
+ <point x="1195" y="425" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfrenameglyphs.ufo/glyphs/A_tS_gn.glif b/tests/reference/ufo/psfrenameglyphs.ufo/glyphs/A_tS_gn.glif
new file mode 100644
index 0000000..47fee96
--- /dev/null
+++ b/tests/reference/ufo/psfrenameglyphs.ufo/glyphs/A_tS_gn.glif
@@ -0,0 +1,80 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="AtSgn" format="2">
+ <advance width="1742"/>
+ <unicode hex="0040"/>
+ <outline>
+ <contour>
+ <point x="1140" y="10" type="line"/>
+ <point x="1077" y="-34"/>
+ <point x="988" y="-60"/>
+ <point x="895" y="-60" type="curve" smooth="yes"/>
+ <point x="558" y="-60"/>
+ <point x="290" y="204"/>
+ <point x="290" y="605" type="curve" smooth="yes"/>
+ <point x="290" y="973"/>
+ <point x="557" y="1240"/>
+ <point x="895" y="1240" type="curve" smooth="yes"/>
+ <point x="1278" y="1240"/>
+ <point x="1460" y="992"/>
+ <point x="1460" y="670" type="curve" smooth="yes"/>
+ <point x="1460" y="452"/>
+ <point x="1363" y="335"/>
+ <point x="1305" y="335" type="curve" smooth="yes"/>
+ <point x="1256" y="335"/>
+ <point x="1220" y="430"/>
+ <point x="1220" y="650" type="curve" smooth="yes"/>
+ <point x="1220" y="980" type="line"/>
+ <point x="1133" y="1015"/>
+ <point x="986" y="1040"/>
+ <point x="905" y="1040" type="curve" smooth="yes"/>
+ <point x="741" y="1040"/>
+ <point x="618" y="961"/>
+ <point x="535" y="825" type="curve" smooth="yes"/>
+ <point x="488" y="746"/>
+ <point x="460" y="653"/>
+ <point x="460" y="530" type="curve" smooth="yes"/>
+ <point x="460" y="304"/>
+ <point x="606" y="163"/>
+ <point x="740" y="163" type="curve" smooth="yes"/>
+ <point x="867" y="163"/>
+ <point x="1013" y="331"/>
+ <point x="1065" y="455" type="curve"/>
+ <point x="1075" y="287"/>
+ <point x="1153" y="160"/>
+ <point x="1275" y="160" type="curve" smooth="yes"/>
+ <point x="1450" y="160"/>
+ <point x="1650" y="358"/>
+ <point x="1650" y="700" type="curve" smooth="yes"/>
+ <point x="1650" y="1137"/>
+ <point x="1342" y="1425"/>
+ <point x="905" y="1425" type="curve" smooth="yes"/>
+ <point x="480" y="1425"/>
+ <point x="90" y="1136"/>
+ <point x="90" y="575" type="curve" smooth="yes"/>
+ <point x="90" y="38"/>
+ <point x="479" y="-245"/>
+ <point x="880" y="-245" type="curve" smooth="yes"/>
+ <point x="1015" y="-245"/>
+ <point x="1175" y="-198"/>
+ <point x="1275" y="-128" type="curve"/>
+ </contour>
+ <contour>
+ <point x="1020" y="710" type="line"/>
+ <point x="988" y="572"/>
+ <point x="863" y="350"/>
+ <point x="773" y="350" type="curve" smooth="yes"/>
+ <point x="701" y="350"/>
+ <point x="660" y="428"/>
+ <point x="660" y="575" type="curve" smooth="yes"/>
+ <point x="660" y="652"/>
+ <point x="682" y="737"/>
+ <point x="720" y="786" type="curve" smooth="yes"/>
+ <point x="756" y="831"/>
+ <point x="807" y="855"/>
+ <point x="875" y="855" type="curve" smooth="yes"/>
+ <point x="949" y="855"/>
+ <point x="987" y="836"/>
+ <point x="1020" y="820" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfrenameglyphs.ufo/glyphs/B_pos.glif b/tests/reference/ufo/psfrenameglyphs.ufo/glyphs/B_pos.glif
new file mode 100644
index 0000000..e26faa2
--- /dev/null
+++ b/tests/reference/ufo/psfrenameglyphs.ufo/glyphs/B_pos.glif
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="Bpos" format="2">
+ <advance width="625"/>
+ <unicode hex="0027"/>
+ <outline>
+ <contour>
+ <point x="400" y="1045" type="line"/>
+ <point x="405" y="1186"/>
+ <point x="406" y="1339"/>
+ <point x="435" y="1585" type="curve"/>
+ <point x="190" y="1585" type="line"/>
+ <point x="221" y="1339"/>
+ <point x="221" y="1186"/>
+ <point x="225" y="1045" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfrenameglyphs.ufo/glyphs/C_ircumA_ccent.glif b/tests/reference/ufo/psfrenameglyphs.ufo/glyphs/C_ircumA_ccent.glif
new file mode 100644
index 0000000..7258b7d
--- /dev/null
+++ b/tests/reference/ufo/psfrenameglyphs.ufo/glyphs/C_ircumA_ccent.glif
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="CircumAccent" format="2">
+ <advance width="880"/>
+ <unicode hex="005E"/>
+ <anchor x="440" y="1635" name="U"/>
+ <outline>
+ <contour>
+ <point x="888" y="1200" type="line"/>
+ <point x="598" y="1600" type="line"/>
+ <point x="298" y="1600" type="line"/>
+ <point x="8" y="1200" type="line"/>
+ <point x="248" y="1200" type="line"/>
+ <point x="448" y="1430" type="line"/>
+ <point x="648" y="1200" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfrenameglyphs.ufo/glyphs/C_olon.glif b/tests/reference/ufo/psfrenameglyphs.ufo/glyphs/C_olon.glif
new file mode 100644
index 0000000..ae4801a
--- /dev/null
+++ b/tests/reference/ufo/psfrenameglyphs.ufo/glyphs/C_olon.glif
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="Colon" format="2">
+ <advance width="710"/>
+ <unicode hex="003A"/>
+ <outline>
+ <contour>
+ <point x="200" y="150" type="curve" smooth="yes"/>
+ <point x="200" y="46"/>
+ <point x="274" y="-25"/>
+ <point x="375" y="-25" type="curve" smooth="yes"/>
+ <point x="477" y="-25"/>
+ <point x="550" y="46"/>
+ <point x="550" y="150" type="curve" smooth="yes"/>
+ <point x="550" y="252"/>
+ <point x="477" y="325"/>
+ <point x="375" y="325" type="curve" smooth="yes"/>
+ <point x="274" y="325"/>
+ <point x="200" y="252"/>
+ </contour>
+ <contour>
+ <point x="200" y="750" type="curve" smooth="yes"/>
+ <point x="200" y="646"/>
+ <point x="274" y="575"/>
+ <point x="375" y="575" type="curve" smooth="yes"/>
+ <point x="477" y="575"/>
+ <point x="550" y="646"/>
+ <point x="550" y="750" type="curve" smooth="yes"/>
+ <point x="550" y="852"/>
+ <point x="477" y="925"/>
+ <point x="375" y="925" type="curve" smooth="yes"/>
+ <point x="274" y="925"/>
+ <point x="200" y="852"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfrenameglyphs.ufo/glyphs/C_ombA_cute.glif b/tests/reference/ufo/psfrenameglyphs.ufo/glyphs/C_ombA_cute.glif
new file mode 100644
index 0000000..5574223
--- /dev/null
+++ b/tests/reference/ufo/psfrenameglyphs.ufo/glyphs/C_ombA_cute.glif
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="CombAcute" format="2">
+ <unicode hex="0301"/>
+ <anchor x="-600" y="1635" name="U"/>
+ <anchor x="-540" y="1100" name="_U"/>
+ <outline>
+ <contour>
+ <point x="-470" y="1600" type="line"/>
+ <point x="-760" y="1200" type="line"/>
+ <point x="-520" y="1200" type="line"/>
+ <point x="-120" y="1600" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfrenameglyphs.ufo/glyphs/C_ombC_ircum.glif b/tests/reference/ufo/psfrenameglyphs.ufo/glyphs/C_ombC_ircum.glif
new file mode 100644
index 0000000..ca30491
--- /dev/null
+++ b/tests/reference/ufo/psfrenameglyphs.ufo/glyphs/C_ombC_ircum.glif
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="CombCircum" format="2">
+ <unicode hex="0302"/>
+ <anchor x="-588" y="1635" name="U"/>
+ <anchor x="-580" y="1100" name="_U"/>
+ <outline>
+ <contour>
+ <point x="-140" y="1200" type="line"/>
+ <point x="-430" y="1600" type="line"/>
+ <point x="-730" y="1600" type="line"/>
+ <point x="-1020" y="1200" type="line"/>
+ <point x="-780" y="1200" type="line"/>
+ <point x="-580" y="1430" type="line"/>
+ <point x="-380" y="1200" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfrenameglyphs.ufo/glyphs/C_ombD_iaer.glif b/tests/reference/ufo/psfrenameglyphs.ufo/glyphs/C_ombD_iaer.glif
new file mode 100644
index 0000000..5a15368
--- /dev/null
+++ b/tests/reference/ufo/psfrenameglyphs.ufo/glyphs/C_ombD_iaer.glif
@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="CombDiaer" format="2">
+ <unicode hex="0308"/>
+ <anchor x="-580" y="1585" name="U"/>
+ <anchor x="-580" y="1100" name="_U"/>
+ <outline>
+ <contour>
+ <point x="-510" y="1385" type="curve" smooth="yes"/>
+ <point x="-510" y="1281"/>
+ <point x="-436" y="1210"/>
+ <point x="-335" y="1210" type="curve" smooth="yes"/>
+ <point x="-233" y="1210"/>
+ <point x="-160" y="1281"/>
+ <point x="-160" y="1385" type="curve" smooth="yes"/>
+ <point x="-160" y="1487"/>
+ <point x="-233" y="1560"/>
+ <point x="-335" y="1560" type="curve" smooth="yes"/>
+ <point x="-436" y="1560"/>
+ <point x="-510" y="1487"/>
+ </contour>
+ <contour>
+ <point x="-1000" y="1385" type="curve" smooth="yes"/>
+ <point x="-1000" y="1281"/>
+ <point x="-926" y="1210"/>
+ <point x="-825" y="1210" type="curve" smooth="yes"/>
+ <point x="-723" y="1210"/>
+ <point x="-650" y="1281"/>
+ <point x="-650" y="1385" type="curve" smooth="yes"/>
+ <point x="-650" y="1487"/>
+ <point x="-723" y="1560"/>
+ <point x="-825" y="1560" type="curve" smooth="yes"/>
+ <point x="-926" y="1560"/>
+ <point x="-1000" y="1487"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfrenameglyphs.ufo/glyphs/C_ombG_rave.glif b/tests/reference/ufo/psfrenameglyphs.ufo/glyphs/C_ombG_rave.glif
new file mode 100644
index 0000000..33bed8f
--- /dev/null
+++ b/tests/reference/ufo/psfrenameglyphs.ufo/glyphs/C_ombG_rave.glif
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="CombGrave" format="2">
+ <unicode hex="0300"/>
+ <anchor x="-590" y="1635" name="U"/>
+ <anchor x="-630" y="1100" name="_U"/>
+ <outline>
+ <contour>
+ <point x="-1050" y="1600" type="line"/>
+ <point x="-650" y="1200" type="line"/>
+ <point x="-410" y="1200" type="line"/>
+ <point x="-700" y="1600" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfrenameglyphs.ufo/glyphs/C_ombR_ingA_bv.glif b/tests/reference/ufo/psfrenameglyphs.ufo/glyphs/C_ombR_ingA_bv.glif
new file mode 100644
index 0000000..7e03146
--- /dev/null
+++ b/tests/reference/ufo/psfrenameglyphs.ufo/glyphs/C_ombR_ingA_bv.glif
@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="CombRingAbv" format="2">
+ <unicode hex="030A"/>
+ <anchor x="-570" y="1635" name="U"/>
+ <anchor x="-572" y="1100" name="_U"/>
+ <outline>
+ <contour>
+ <point x="-475" y="1400" type="curve" smooth="yes"/>
+ <point x="-475" y="1345"/>
+ <point x="-515" y="1305"/>
+ <point x="-570" y="1305" type="curve" smooth="yes"/>
+ <point x="-625" y="1305"/>
+ <point x="-665" y="1345"/>
+ <point x="-665" y="1400" type="curve" smooth="yes"/>
+ <point x="-665" y="1455"/>
+ <point x="-625" y="1495"/>
+ <point x="-570" y="1495" type="curve" smooth="yes"/>
+ <point x="-515" y="1495"/>
+ <point x="-475" y="1455"/>
+ </contour>
+ <contour>
+ <point x="-815" y="1400" type="curve" smooth="yes"/>
+ <point x="-815" y="1260"/>
+ <point x="-710" y="1160"/>
+ <point x="-570" y="1160" type="curve" smooth="yes"/>
+ <point x="-430" y="1160"/>
+ <point x="-325" y="1260"/>
+ <point x="-325" y="1400" type="curve" smooth="yes"/>
+ <point x="-325" y="1540"/>
+ <point x="-430" y="1640"/>
+ <point x="-570" y="1640" type="curve" smooth="yes"/>
+ <point x="-710" y="1640"/>
+ <point x="-815" y="1540"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfrenameglyphs.ufo/glyphs/C_ombT_ilde.glif b/tests/reference/ufo/psfrenameglyphs.ufo/glyphs/C_ombT_ilde.glif
new file mode 100644
index 0000000..ee23af5
--- /dev/null
+++ b/tests/reference/ufo/psfrenameglyphs.ufo/glyphs/C_ombT_ilde.glif
@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="CombTilde" format="2">
+ <unicode hex="0303"/>
+ <anchor x="-580" y="1490" name="U"/>
+ <anchor x="-580" y="1100" name="_U"/>
+ <outline>
+ <contour>
+ <point x="-830" y="1190" type="line"/>
+ <point x="-824" y="1232"/>
+ <point x="-803" y="1280"/>
+ <point x="-753" y="1280" type="curve" smooth="yes"/>
+ <point x="-710" y="1280"/>
+ <point x="-653" y="1264"/>
+ <point x="-570" y="1229" type="curve" smooth="yes"/>
+ <point x="-500" y="1199"/>
+ <point x="-448" y="1180"/>
+ <point x="-386" y="1180" type="curve" smooth="yes"/>
+ <point x="-250" y="1180"/>
+ <point x="-155" y="1307"/>
+ <point x="-155" y="1480" type="curve"/>
+ <point x="-310" y="1480" type="line"/>
+ <point x="-318" y="1438"/>
+ <point x="-340" y="1390"/>
+ <point x="-387" y="1390" type="curve" smooth="yes"/>
+ <point x="-435" y="1390"/>
+ <point x="-472" y="1408"/>
+ <point x="-550" y="1437" type="curve" smooth="yes"/>
+ <point x="-629" y="1466"/>
+ <point x="-695" y="1490"/>
+ <point x="-760" y="1490" type="curve" smooth="yes"/>
+ <point x="-892" y="1490"/>
+ <point x="-985" y="1349"/>
+ <point x="-985" y="1190" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfrenameglyphs.ufo/glyphs/C_omma.glif b/tests/reference/ufo/psfrenameglyphs.ufo/glyphs/C_omma.glif
new file mode 100644
index 0000000..9d4845e
--- /dev/null
+++ b/tests/reference/ufo/psfrenameglyphs.ufo/glyphs/C_omma.glif
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="Comma" format="2">
+ <advance width="665"/>
+ <unicode hex="002C"/>
+ <outline>
+ <contour>
+ <point x="185" y="50" type="line"/>
+ <point x="345" y="50" type="line"/>
+ <point x="345" y="-34"/>
+ <point x="290" y="-153"/>
+ <point x="185" y="-265" type="curve"/>
+ <point x="330" y="-335" type="line"/>
+ <point x="454" y="-228"/>
+ <point x="560" y="-49"/>
+ <point x="560" y="130" type="curve" smooth="yes"/>
+ <point x="560" y="254"/>
+ <point x="489" y="340"/>
+ <point x="375" y="340" type="curve" smooth="yes"/>
+ <point x="262" y="340"/>
+ <point x="185" y="255"/>
+ <point x="185" y="180" type="curve" smooth="yes"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfrenameglyphs.ufo/glyphs/D_igitE_ight.glif b/tests/reference/ufo/psfrenameglyphs.ufo/glyphs/D_igitE_ight.glif
new file mode 100644
index 0000000..a59fff4
--- /dev/null
+++ b/tests/reference/ufo/psfrenameglyphs.ufo/glyphs/D_igitE_ight.glif
@@ -0,0 +1,63 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="DigitEight" format="2">
+ <advance width="1200"/>
+ <unicode hex="0038"/>
+ <anchor x="600" y="-100" name="L"/>
+ <anchor x="600" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="600" y="-25" type="curve" smooth="yes"/>
+ <point x="877" y="-25"/>
+ <point x="1130" y="144"/>
+ <point x="1130" y="415" type="curve" smooth="yes"/>
+ <point x="1130" y="641"/>
+ <point x="985" y="739"/>
+ <point x="875" y="795" type="curve"/>
+ <point x="953" y="841"/>
+ <point x="1060" y="923"/>
+ <point x="1060" y="1105" type="curve" smooth="yes"/>
+ <point x="1060" y="1350"/>
+ <point x="860" y="1485"/>
+ <point x="610" y="1485" type="curve" smooth="yes"/>
+ <point x="361" y="1485"/>
+ <point x="140" y="1350"/>
+ <point x="140" y="1105" type="curve" smooth="yes"/>
+ <point x="140" y="923"/>
+ <point x="252" y="838"/>
+ <point x="330" y="795" type="curve"/>
+ <point x="201" y="725"/>
+ <point x="70" y="631"/>
+ <point x="70" y="405" type="curve" smooth="yes"/>
+ <point x="70" y="134"/>
+ <point x="324" y="-25"/>
+ </contour>
+ <contour>
+ <point x="810" y="1100" type="curve" smooth="yes"/>
+ <point x="810" y="974"/>
+ <point x="733" y="895"/>
+ <point x="600" y="895" type="curve" smooth="yes"/>
+ <point x="467" y="895"/>
+ <point x="390" y="974"/>
+ <point x="390" y="1100" type="curve" smooth="yes"/>
+ <point x="390" y="1217"/>
+ <point x="477" y="1290"/>
+ <point x="600" y="1290" type="curve" smooth="yes"/>
+ <point x="743" y="1290"/>
+ <point x="810" y="1207"/>
+ </contour>
+ <contour>
+ <point x="865" y="435" type="curve" smooth="yes"/>
+ <point x="865" y="300"/>
+ <point x="768" y="185"/>
+ <point x="600" y="185" type="curve" smooth="yes"/>
+ <point x="440" y="185"/>
+ <point x="335" y="300"/>
+ <point x="335" y="435" type="curve" smooth="yes"/>
+ <point x="335" y="582"/>
+ <point x="450" y="680"/>
+ <point x="600" y="680" type="curve" smooth="yes"/>
+ <point x="748" y="680"/>
+ <point x="865" y="582"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfrenameglyphs.ufo/glyphs/D_igitF_ive.glif b/tests/reference/ufo/psfrenameglyphs.ufo/glyphs/D_igitF_ive.glif
new file mode 100644
index 0000000..102780d
--- /dev/null
+++ b/tests/reference/ufo/psfrenameglyphs.ufo/glyphs/D_igitF_ive.glif
@@ -0,0 +1,44 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="DigitFive" format="2">
+ <advance width="1200"/>
+ <unicode hex="0035"/>
+ <anchor x="600" y="-100" name="L"/>
+ <anchor x="600" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="175" y="645" type="line"/>
+ <point x="299" y="693"/>
+ <point x="404" y="710"/>
+ <point x="510" y="710" type="curve" smooth="yes"/>
+ <point x="670" y="710"/>
+ <point x="810" y="632"/>
+ <point x="810" y="470" type="curve" smooth="yes"/>
+ <point x="810" y="318"/>
+ <point x="690" y="215"/>
+ <point x="530" y="215" type="curve" smooth="yes"/>
+ <point x="390" y="215"/>
+ <point x="274" y="252"/>
+ <point x="140" y="360" type="curve"/>
+ <point x="100" y="80" type="line"/>
+ <point x="225" y="2"/>
+ <point x="365" y="-25"/>
+ <point x="520" y="-25" type="curve" smooth="yes"/>
+ <point x="833" y="-25"/>
+ <point x="1090" y="163"/>
+ <point x="1090" y="475" type="curve" smooth="yes"/>
+ <point x="1090" y="752"/>
+ <point x="882" y="930"/>
+ <point x="605" y="930" type="curve" smooth="yes"/>
+ <point x="543" y="930"/>
+ <point x="468" y="911"/>
+ <point x="435" y="895" type="curve"/>
+ <point x="435" y="1215" type="line"/>
+ <point x="765" y="1215" type="line" smooth="yes"/>
+ <point x="849" y="1215"/>
+ <point x="955" y="1211"/>
+ <point x="1030" y="1195" type="curve"/>
+ <point x="1030" y="1460" type="line"/>
+ <point x="175" y="1460" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfrenameglyphs.ufo/glyphs/D_igitF_our.glif b/tests/reference/ufo/psfrenameglyphs.ufo/glyphs/D_igitF_our.glif
new file mode 100644
index 0000000..7d2cbe6
--- /dev/null
+++ b/tests/reference/ufo/psfrenameglyphs.ufo/glyphs/D_igitF_our.glif
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="DigitFour" format="2">
+ <advance width="1200"/>
+ <unicode hex="0034"/>
+ <anchor x="607" y="-100" name="L"/>
+ <anchor x="607" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="1155" y="345" type="line"/>
+ <point x="1155" y="570" type="line"/>
+ <point x="995" y="570" type="line"/>
+ <point x="995" y="1460" type="line"/>
+ <point x="695" y="1460" type="line"/>
+ <point x="60" y="570" type="line"/>
+ <point x="60" y="345" type="line"/>
+ <point x="730" y="345" type="line"/>
+ <point x="730" y="0" type="line"/>
+ <point x="995" y="0" type="line"/>
+ <point x="995" y="345" type="line"/>
+ </contour>
+ <contour>
+ <point x="730" y="1145" type="line"/>
+ <point x="730" y="570" type="line"/>
+ <point x="305" y="570" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfrenameglyphs.ufo/glyphs/D_igitN_ine.glif b/tests/reference/ufo/psfrenameglyphs.ufo/glyphs/D_igitN_ine.glif
new file mode 100644
index 0000000..b1e153b
--- /dev/null
+++ b/tests/reference/ufo/psfrenameglyphs.ufo/glyphs/D_igitN_ine.glif
@@ -0,0 +1,49 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="DigitNine" format="2">
+ <advance width="1200"/>
+ <unicode hex="0039"/>
+ <anchor x="600" y="-100" name="L"/>
+ <anchor x="600" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="154" y="65" type="line"/>
+ <point x="248" y="5"/>
+ <point x="364" y="-25"/>
+ <point x="492" y="-25" type="curve" smooth="yes"/>
+ <point x="967" y="-25"/>
+ <point x="1135" y="411"/>
+ <point x="1135" y="780" type="curve" smooth="yes"/>
+ <point x="1135" y="1150"/>
+ <point x="977" y="1485"/>
+ <point x="589" y="1485" type="curve" smooth="yes"/>
+ <point x="310" y="1485"/>
+ <point x="70" y="1300"/>
+ <point x="70" y="1002" type="curve" smooth="yes"/>
+ <point x="70" y="763"/>
+ <point x="272" y="576"/>
+ <point x="550" y="576" type="curve" smooth="yes"/>
+ <point x="741" y="576"/>
+ <point x="913" y="707"/>
+ <point x="1010" y="868" type="curve"/>
+ <point x="939" y="991" type="line"/>
+ <point x="865" y="877"/>
+ <point x="729" y="790"/>
+ <point x="574" y="790" type="curve" smooth="yes"/>
+ <point x="425" y="790"/>
+ <point x="326" y="890"/>
+ <point x="326" y="1036" type="curve" smooth="yes"/>
+ <point x="326" y="1153"/>
+ <point x="425" y="1250"/>
+ <point x="573" y="1250" type="curve" smooth="yes"/>
+ <point x="773" y="1250"/>
+ <point x="870" y="1102"/>
+ <point x="870" y="813" type="curve" smooth="yes"/>
+ <point x="870" y="326"/>
+ <point x="699" y="210"/>
+ <point x="502" y="210" type="curve" smooth="yes"/>
+ <point x="406" y="210"/>
+ <point x="294" y="234"/>
+ <point x="208" y="320" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfrenameglyphs.ufo/glyphs/D_igitO_ne.glif b/tests/reference/ufo/psfrenameglyphs.ufo/glyphs/D_igitO_ne.glif
new file mode 100644
index 0000000..c744b9f
--- /dev/null
+++ b/tests/reference/ufo/psfrenameglyphs.ufo/glyphs/D_igitO_ne.glif
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="DigitOne" format="2">
+ <advance width="1200"/>
+ <unicode hex="0031"/>
+ <anchor x="600" y="-100" name="L"/>
+ <anchor x="600" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="1075" y="0" type="line"/>
+ <point x="1075" y="235" type="line"/>
+ <point x="767" y="235" type="line"/>
+ <point x="767" y="1460" type="line"/>
+ <point x="492" y="1460" type="line"/>
+ <point x="177" y="1278" type="line"/>
+ <point x="212" y="1018" type="line"/>
+ <point x="492" y="1170" type="line"/>
+ <point x="492" y="235" type="line"/>
+ <point x="185" y="235" type="line"/>
+ <point x="185" y="0" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfrenameglyphs.ufo/glyphs/D_igitS_even.glif b/tests/reference/ufo/psfrenameglyphs.ufo/glyphs/D_igitS_even.glif
new file mode 100644
index 0000000..63fb1c4
--- /dev/null
+++ b/tests/reference/ufo/psfrenameglyphs.ufo/glyphs/D_igitS_even.glif
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="DigitSeven" format="2">
+ <advance width="1200"/>
+ <unicode hex="0037"/>
+ <anchor x="600" y="-100" name="L"/>
+ <anchor x="600" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="520" y="0" type="line"/>
+ <point x="649" y="459"/>
+ <point x="834" y="855"/>
+ <point x="1130" y="1260" type="curve"/>
+ <point x="1130" y="1460" type="line"/>
+ <point x="100" y="1460" type="line"/>
+ <point x="100" y="1195" type="line"/>
+ <point x="176" y="1211"/>
+ <point x="292" y="1215"/>
+ <point x="480" y="1215" type="curve" smooth="yes"/>
+ <point x="800" y="1215" type="line"/>
+ <point x="542" y="842"/>
+ <point x="409" y="566"/>
+ <point x="235" y="0" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfrenameglyphs.ufo/glyphs/D_igitS_ix.glif b/tests/reference/ufo/psfrenameglyphs.ufo/glyphs/D_igitS_ix.glif
new file mode 100644
index 0000000..7526cc6
--- /dev/null
+++ b/tests/reference/ufo/psfrenameglyphs.ufo/glyphs/D_igitS_ix.glif
@@ -0,0 +1,49 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="DigitSix" format="2">
+ <advance width="1200"/>
+ <unicode hex="0036"/>
+ <anchor x="610" y="-100" name="L"/>
+ <anchor x="610" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="1073" y="1395" type="line"/>
+ <point x="969" y="1465"/>
+ <point x="873" y="1485"/>
+ <point x="735" y="1485" type="curve" smooth="yes"/>
+ <point x="260" y="1485"/>
+ <point x="90" y="1069"/>
+ <point x="90" y="680" type="curve" smooth="yes"/>
+ <point x="90" y="223"/>
+ <point x="297" y="-25"/>
+ <point x="652" y="-25" type="curve" smooth="yes"/>
+ <point x="955" y="-25"/>
+ <point x="1155" y="179"/>
+ <point x="1155" y="470" type="curve" smooth="yes"/>
+ <point x="1155" y="729"/>
+ <point x="963" y="925"/>
+ <point x="675" y="925" type="curve" smooth="yes"/>
+ <point x="484" y="925"/>
+ <point x="338" y="810"/>
+ <point x="225" y="655" type="curve"/>
+ <point x="290" y="540" type="line"/>
+ <point x="372" y="643"/>
+ <point x="500" y="710"/>
+ <point x="655" y="710" type="curve" smooth="yes"/>
+ <point x="814" y="710"/>
+ <point x="900" y="601"/>
+ <point x="900" y="455" type="curve" smooth="yes"/>
+ <point x="900" y="329"/>
+ <point x="803" y="210"/>
+ <point x="656" y="210" type="curve" smooth="yes"/>
+ <point x="474" y="210"/>
+ <point x="355" y="386"/>
+ <point x="355" y="645" type="curve" smooth="yes"/>
+ <point x="355" y="1132"/>
+ <point x="528" y="1250"/>
+ <point x="725" y="1250" type="curve" smooth="yes"/>
+ <point x="821" y="1250"/>
+ <point x="923" y="1226"/>
+ <point x="1009" y="1140" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfrenameglyphs.ufo/glyphs/D_igitT_hree.glif b/tests/reference/ufo/psfrenameglyphs.ufo/glyphs/D_igitT_hree.glif
new file mode 100644
index 0000000..883bd62
--- /dev/null
+++ b/tests/reference/ufo/psfrenameglyphs.ufo/glyphs/D_igitT_hree.glif
@@ -0,0 +1,52 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="DigitThree" format="2">
+ <advance width="1200"/>
+ <unicode hex="0033"/>
+ <anchor x="600" y="-100" name="L"/>
+ <anchor x="600" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="390" y="885" type="line"/>
+ <point x="390" y="645" type="line"/>
+ <point x="480" y="645" type="line" smooth="yes"/>
+ <point x="706" y="645"/>
+ <point x="835" y="548"/>
+ <point x="835" y="425" type="curve" smooth="yes"/>
+ <point x="835" y="291"/>
+ <point x="708" y="210"/>
+ <point x="565" y="210" type="curve" smooth="yes"/>
+ <point x="405" y="210"/>
+ <point x="244" y="282"/>
+ <point x="135" y="405" type="curve"/>
+ <point x="100" y="130" type="line"/>
+ <point x="205" y="32"/>
+ <point x="368" y="-25"/>
+ <point x="545" y="-25" type="curve" smooth="yes"/>
+ <point x="874" y="-25"/>
+ <point x="1120" y="170"/>
+ <point x="1120" y="405" type="curve" smooth="yes"/>
+ <point x="1120" y="672"/>
+ <point x="892" y="756"/>
+ <point x="750" y="780" type="curve"/>
+ <point x="892" y="809"/>
+ <point x="1070" y="957"/>
+ <point x="1070" y="1140" type="curve" smooth="yes"/>
+ <point x="1070" y="1354"/>
+ <point x="868" y="1485"/>
+ <point x="580" y="1485" type="curve" smooth="yes"/>
+ <point x="413" y="1485"/>
+ <point x="240" y="1416"/>
+ <point x="160" y="1325" type="curve"/>
+ <point x="195" y="1095" type="line"/>
+ <point x="308" y="1211"/>
+ <point x="436" y="1250"/>
+ <point x="590" y="1250" type="curve" smooth="yes"/>
+ <point x="689" y="1250"/>
+ <point x="791" y="1193"/>
+ <point x="791" y="1102" type="curve" smooth="yes"/>
+ <point x="791" y="994"/>
+ <point x="662" y="885"/>
+ <point x="480" y="885" type="curve" smooth="yes"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfrenameglyphs.ufo/glyphs/D_igitT_wo.glif b/tests/reference/ufo/psfrenameglyphs.ufo/glyphs/D_igitT_wo.glif
new file mode 100644
index 0000000..1d73732
--- /dev/null
+++ b/tests/reference/ufo/psfrenameglyphs.ufo/glyphs/D_igitT_wo.glif
@@ -0,0 +1,37 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="DigitTwo" format="2">
+ <advance width="1200"/>
+ <unicode hex="0032"/>
+ <anchor x="600" y="-100" name="L"/>
+ <anchor x="560" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="1090" y="260" type="line"/>
+ <point x="1010" y="246"/>
+ <point x="942" y="245"/>
+ <point x="745" y="245" type="curve" smooth="yes"/>
+ <point x="480" y="245" type="line"/>
+ <point x="699" y="422"/>
+ <point x="1046" y="739"/>
+ <point x="1046" y="1065" type="curve" smooth="yes"/>
+ <point x="1046" y="1323"/>
+ <point x="850" y="1485"/>
+ <point x="560" y="1485" type="curve" smooth="yes"/>
+ <point x="391" y="1485"/>
+ <point x="196" y="1402"/>
+ <point x="105" y="1290" type="curve"/>
+ <point x="170" y="1050" type="line"/>
+ <point x="259" y="1158"/>
+ <point x="412" y="1235"/>
+ <point x="535" y="1235" type="curve" smooth="yes"/>
+ <point x="688" y="1235"/>
+ <point x="758" y="1133"/>
+ <point x="758" y="1015" type="curve" smooth="yes"/>
+ <point x="758" y="758"/>
+ <point x="381" y="415"/>
+ <point x="110" y="220" type="curve"/>
+ <point x="110" y="0" type="line"/>
+ <point x="1090" y="0" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfrenameglyphs.ufo/glyphs/D_igitZ_ero.glif b/tests/reference/ufo/psfrenameglyphs.ufo/glyphs/D_igitZ_ero.glif
new file mode 100644
index 0000000..01f4532
--- /dev/null
+++ b/tests/reference/ufo/psfrenameglyphs.ufo/glyphs/D_igitZ_ero.glif
@@ -0,0 +1,37 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="DigitZero" format="2">
+ <advance width="1200"/>
+ <unicode hex="0030"/>
+ <anchor x="605" y="-100" name="L"/>
+ <anchor x="605" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="850" y="715" type="curve" smooth="yes"/>
+ <point x="850" y="368"/>
+ <point x="762" y="205"/>
+ <point x="600" y="205" type="curve" smooth="yes"/>
+ <point x="432" y="205"/>
+ <point x="350" y="375"/>
+ <point x="350" y="745" type="curve" smooth="yes"/>
+ <point x="350" y="1093"/>
+ <point x="437" y="1255"/>
+ <point x="600" y="1255" type="curve" smooth="yes"/>
+ <point x="772" y="1255"/>
+ <point x="850" y="1086"/>
+ </contour>
+ <contour>
+ <point x="1135" y="740" type="curve" smooth="yes"/>
+ <point x="1135" y="1286"/>
+ <point x="950" y="1485"/>
+ <point x="610" y="1485" type="curve" smooth="yes"/>
+ <point x="291" y="1485"/>
+ <point x="65" y="1283"/>
+ <point x="65" y="720" type="curve" smooth="yes"/>
+ <point x="65" y="165"/>
+ <point x="271" y="-25"/>
+ <point x="590" y="-25" type="curve" smooth="yes"/>
+ <point x="911" y="-25"/>
+ <point x="1135" y="161"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfrenameglyphs.ufo/glyphs/D_ollarS_gn.glif b/tests/reference/ufo/psfrenameglyphs.ufo/glyphs/D_ollarS_gn.glif
new file mode 100644
index 0000000..f8b49cd
--- /dev/null
+++ b/tests/reference/ufo/psfrenameglyphs.ufo/glyphs/D_ollarS_gn.glif
@@ -0,0 +1,57 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="DollarSgn" format="2">
+ <advance width="1200"/>
+ <unicode hex="0024"/>
+ <outline>
+ <contour>
+ <point x="1006" y="1316" type="line"/>
+ <point x="886" y="1374"/>
+ <point x="764" y="1389"/>
+ <point x="623" y="1389" type="curve" smooth="yes"/>
+ <point x="317" y="1389"/>
+ <point x="150" y="1203"/>
+ <point x="150" y="1017" type="curve" smooth="yes"/>
+ <point x="150" y="830"/>
+ <point x="275" y="730"/>
+ <point x="540" y="623" type="curve" smooth="yes"/>
+ <point x="802" y="517"/>
+ <point x="851" y="472"/>
+ <point x="851" y="386" type="curve" smooth="yes"/>
+ <point x="851" y="267"/>
+ <point x="744" y="211"/>
+ <point x="586" y="211" type="curve" smooth="yes"/>
+ <point x="440" y="211"/>
+ <point x="297" y="281"/>
+ <point x="195" y="383" type="curve"/>
+ <point x="123" y="124" type="line"/>
+ <point x="216" y="49"/>
+ <point x="388" y="0"/>
+ <point x="586" y="0" type="curve" smooth="yes"/>
+ <point x="847" y="0"/>
+ <point x="1086" y="147"/>
+ <point x="1086" y="414" type="curve" smooth="yes"/>
+ <point x="1086" y="633"/>
+ <point x="927" y="723"/>
+ <point x="679" y="826" type="curve" smooth="yes"/>
+ <point x="431" y="929"/>
+ <point x="385" y="969"/>
+ <point x="385" y="1040" type="curve" smooth="yes"/>
+ <point x="385" y="1132"/>
+ <point x="466" y="1188"/>
+ <point x="613" y="1188" type="curve" smooth="yes"/>
+ <point x="741" y="1188"/>
+ <point x="876" y="1154"/>
+ <point x="949" y="1077" type="curve"/>
+ </contour>
+ <contour>
+ <point x="548" y="1600" type="line"/>
+ <point x="548" y="788" type="line"/>
+ <point x="518" y="726" type="line"/>
+ <point x="518" y="-220" type="line"/>
+ <point x="688" y="-220" type="line"/>
+ <point x="688" y="668" type="line"/>
+ <point x="718" y="734" type="line"/>
+ <point x="718" y="1600" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfrenameglyphs.ufo/glyphs/D_ottedC_irc.glif b/tests/reference/ufo/psfrenameglyphs.ufo/glyphs/D_ottedC_irc.glif
new file mode 100644
index 0000000..4cf5cb4
--- /dev/null
+++ b/tests/reference/ufo/psfrenameglyphs.ufo/glyphs/D_ottedC_irc.glif
@@ -0,0 +1,235 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="DottedCirc" format="2">
+ <advance width="1106"/>
+ <unicode hex="25CC"/>
+ <anchor x="553" y="0" name="H"/>
+ <anchor x="553" y="-100" name="L"/>
+ <anchor x="810" y="0" name="O"/>
+ <anchor x="553" y="1000" name="U"/>
+ <outline>
+ <contour>
+ <point x="443" y="837" type="curve" smooth="yes"/>
+ <point x="443" y="864"/>
+ <point x="423" y="885"/>
+ <point x="398" y="885" type="curve" smooth="yes"/>
+ <point x="371" y="885"/>
+ <point x="348" y="861"/>
+ <point x="348" y="837" type="curve" smooth="yes"/>
+ <point x="348" y="809"/>
+ <point x="372" y="789"/>
+ <point x="398" y="789" type="curve" smooth="yes"/>
+ <point x="425" y="789"/>
+ <point x="443" y="812"/>
+ </contour>
+ <contour>
+ <point x="758" y="79" type="curve" smooth="yes"/>
+ <point x="758" y="106"/>
+ <point x="736" y="127"/>
+ <point x="710" y="127" type="curve" smooth="yes"/>
+ <point x="685" y="127"/>
+ <point x="662" y="103"/>
+ <point x="662" y="80" type="curve" smooth="yes"/>
+ <point x="662" y="52"/>
+ <point x="686" y="31"/>
+ <point x="710" y="31" type="curve" smooth="yes"/>
+ <point x="737" y="31"/>
+ <point x="758" y="55"/>
+ </contour>
+ <contour>
+ <point x="310" y="749" type="curve" smooth="yes"/>
+ <point x="310" y="775"/>
+ <point x="288" y="796"/>
+ <point x="263" y="796" type="curve" smooth="yes"/>
+ <point x="238" y="796"/>
+ <point x="215" y="774"/>
+ <point x="215" y="747" type="curve" smooth="yes"/>
+ <point x="215" y="722"/>
+ <point x="236" y="701"/>
+ <point x="263" y="701" type="curve" smooth="yes"/>
+ <point x="291" y="701"/>
+ <point x="310" y="720"/>
+ </contour>
+ <contour>
+ <point x="891" y="168" type="curve" smooth="yes"/>
+ <point x="891" y="197"/>
+ <point x="870" y="215"/>
+ <point x="843" y="215" type="curve" smooth="yes"/>
+ <point x="817" y="215"/>
+ <point x="795" y="194"/>
+ <point x="795" y="168" type="curve" smooth="yes"/>
+ <point x="795" y="143"/>
+ <point x="816" y="121"/>
+ <point x="843" y="121" type="curve" smooth="yes"/>
+ <point x="871" y="121"/>
+ <point x="891" y="143"/>
+ </contour>
+ <contour>
+ <point x="222" y="613" type="curve" smooth="yes"/>
+ <point x="222" y="640"/>
+ <point x="199" y="663"/>
+ <point x="173" y="663" type="curve" smooth="yes"/>
+ <point x="149" y="663"/>
+ <point x="126" y="642"/>
+ <point x="126" y="615" type="curve" smooth="yes"/>
+ <point x="126" y="591"/>
+ <point x="145" y="567"/>
+ <point x="173" y="567" type="curve" smooth="yes"/>
+ <point x="197" y="567"/>
+ <point x="222" y="587"/>
+ </contour>
+ <contour>
+ <point x="980" y="301" type="curve" smooth="yes"/>
+ <point x="980" y="327"/>
+ <point x="957" y="348"/>
+ <point x="932" y="348" type="curve" smooth="yes"/>
+ <point x="908" y="348"/>
+ <point x="884" y="332"/>
+ <point x="884" y="301" type="curve" smooth="yes"/>
+ <point x="884" y="277"/>
+ <point x="902" y="254"/>
+ <point x="932" y="254" type="curve" smooth="yes"/>
+ <point x="957" y="254"/>
+ <point x="980" y="274"/>
+ </contour>
+ <contour>
+ <point x="191" y="459" type="curve" smooth="yes"/>
+ <point x="191" y="484"/>
+ <point x="168" y="505"/>
+ <point x="143" y="505" type="curve" smooth="yes"/>
+ <point x="116" y="505"/>
+ <point x="95" y="484"/>
+ <point x="95" y="458" type="curve" smooth="yes"/>
+ <point x="95" y="433"/>
+ <point x="115" y="410"/>
+ <point x="143" y="410" type="curve" smooth="yes"/>
+ <point x="167" y="410"/>
+ <point x="191" y="432"/>
+ </contour>
+ <contour>
+ <point x="1011" y="458" type="curve" smooth="yes"/>
+ <point x="1011" y="484"/>
+ <point x="990" y="506"/>
+ <point x="964" y="506" type="curve" smooth="yes"/>
+ <point x="940" y="506"/>
+ <point x="915" y="484"/>
+ <point x="915" y="457" type="curve" smooth="yes"/>
+ <point x="915" y="433"/>
+ <point x="936" y="411"/>
+ <point x="964" y="411" type="curve" smooth="yes"/>
+ <point x="990" y="411"/>
+ <point x="1011" y="433"/>
+ </contour>
+ <contour>
+ <point x="222" y="302" type="curve" smooth="yes"/>
+ <point x="222" y="328"/>
+ <point x="200" y="348"/>
+ <point x="174" y="348" type="curve" smooth="yes"/>
+ <point x="147" y="348"/>
+ <point x="126" y="326"/>
+ <point x="126" y="302" type="curve" smooth="yes"/>
+ <point x="126" y="275"/>
+ <point x="149" y="253"/>
+ <point x="174" y="253" type="curve" smooth="yes"/>
+ <point x="201" y="253"/>
+ <point x="222" y="277"/>
+ </contour>
+ <contour>
+ <point x="980" y="615" type="curve" smooth="yes"/>
+ <point x="980" y="642"/>
+ <point x="955" y="663"/>
+ <point x="931" y="663" type="curve" smooth="yes"/>
+ <point x="904" y="663"/>
+ <point x="885" y="638"/>
+ <point x="885" y="614" type="curve" smooth="yes"/>
+ <point x="885" y="588"/>
+ <point x="907" y="567"/>
+ <point x="931" y="567" type="curve" smooth="yes"/>
+ <point x="959" y="567"/>
+ <point x="980" y="591"/>
+ </contour>
+ <contour>
+ <point x="310" y="168" type="curve" smooth="yes"/>
+ <point x="310" y="195"/>
+ <point x="291" y="215"/>
+ <point x="263" y="215" type="curve" smooth="yes"/>
+ <point x="238" y="215"/>
+ <point x="215" y="190"/>
+ <point x="215" y="168" type="curve" smooth="yes"/>
+ <point x="215" y="143"/>
+ <point x="238" y="120"/>
+ <point x="263" y="120" type="curve" smooth="yes"/>
+ <point x="289" y="120"/>
+ <point x="310" y="143"/>
+ </contour>
+ <contour>
+ <point x="890" y="748" type="curve" smooth="yes"/>
+ <point x="890" y="774"/>
+ <point x="870" y="796"/>
+ <point x="843" y="796" type="curve" smooth="yes"/>
+ <point x="815" y="796"/>
+ <point x="796" y="773"/>
+ <point x="796" y="748" type="curve" smooth="yes"/>
+ <point x="796" y="724"/>
+ <point x="817" y="700"/>
+ <point x="843" y="700" type="curve" smooth="yes"/>
+ <point x="869" y="700"/>
+ <point x="890" y="722"/>
+ </contour>
+ <contour>
+ <point x="444" y="78" type="curve" smooth="yes"/>
+ <point x="444" y="102"/>
+ <point x="423" y="126"/>
+ <point x="396" y="126" type="curve" smooth="yes"/>
+ <point x="370" y="126"/>
+ <point x="348" y="102"/>
+ <point x="348" y="78" type="curve" smooth="yes"/>
+ <point x="348" y="55"/>
+ <point x="370" y="31"/>
+ <point x="396" y="31" type="curve" smooth="yes"/>
+ <point x="420" y="31"/>
+ <point x="444" y="51"/>
+ </contour>
+ <contour>
+ <point x="758" y="836" type="curve" smooth="yes"/>
+ <point x="758" y="861"/>
+ <point x="737" y="885"/>
+ <point x="710" y="885" type="curve" smooth="yes"/>
+ <point x="684" y="885"/>
+ <point x="663" y="862"/>
+ <point x="663" y="838" type="curve" smooth="yes"/>
+ <point x="663" y="814"/>
+ <point x="683" y="789"/>
+ <point x="710" y="789" type="curve" smooth="yes"/>
+ <point x="734" y="789"/>
+ <point x="758" y="809"/>
+ </contour>
+ <contour>
+ <point x="601" y="47" type="curve" smooth="yes"/>
+ <point x="601" y="73"/>
+ <point x="579" y="95"/>
+ <point x="553" y="95" type="curve" smooth="yes"/>
+ <point x="527" y="95"/>
+ <point x="506" y="73"/>
+ <point x="506" y="47" type="curve" smooth="yes"/>
+ <point x="506" y="21"/>
+ <point x="527" y="0"/>
+ <point x="553" y="0" type="curve" smooth="yes"/>
+ <point x="579" y="0"/>
+ <point x="601" y="21"/>
+ </contour>
+ <contour>
+ <point x="601" y="868" type="curve" smooth="yes"/>
+ <point x="601" y="894"/>
+ <point x="579" y="916"/>
+ <point x="553" y="916" type="curve" smooth="yes"/>
+ <point x="527" y="916"/>
+ <point x="506" y="894"/>
+ <point x="506" y="868" type="curve" smooth="yes"/>
+ <point x="506" y="842"/>
+ <point x="527" y="821"/>
+ <point x="553" y="821" type="curve" smooth="yes"/>
+ <point x="579" y="821"/>
+ <point x="601" y="842"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfrenameglyphs.ufo/glyphs/E_qS_gn.glif b/tests/reference/ufo/psfrenameglyphs.ufo/glyphs/E_qS_gn.glif
new file mode 100644
index 0000000..9eeb2ef
--- /dev/null
+++ b/tests/reference/ufo/psfrenameglyphs.ufo/glyphs/E_qS_gn.glif
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="EqSgn" format="2">
+ <advance width="1200"/>
+ <unicode hex="003D"/>
+ <outline>
+ <contour>
+ <point x="120" y="440" type="line"/>
+ <point x="1080" y="440" type="line"/>
+ <point x="1080" y="650" type="line"/>
+ <point x="120" y="650" type="line"/>
+ </contour>
+ <contour>
+ <point x="120" y="810" type="line"/>
+ <point x="1080" y="810" type="line"/>
+ <point x="1080" y="1020" type="line"/>
+ <point x="120" y="1020" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfrenameglyphs.ufo/glyphs/E_xclamationM_rk.glif b/tests/reference/ufo/psfrenameglyphs.ufo/glyphs/E_xclamationM_rk.glif
new file mode 100644
index 0000000..cfdf1a6
--- /dev/null
+++ b/tests/reference/ufo/psfrenameglyphs.ufo/glyphs/E_xclamationM_rk.glif
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="ExclamationMrk" format="2">
+ <advance width="780"/>
+ <unicode hex="0021"/>
+ <outline>
+ <contour>
+ <point x="530" y="500" type="line"/>
+ <point x="536" y="790"/>
+ <point x="531" y="1076"/>
+ <point x="570" y="1510" type="curve"/>
+ <point x="235" y="1510" type="line"/>
+ <point x="273" y="1076"/>
+ <point x="268" y="790"/>
+ <point x="275" y="500" type="curve"/>
+ </contour>
+ <contour>
+ <point x="230" y="150" type="curve" smooth="yes"/>
+ <point x="230" y="46"/>
+ <point x="304" y="-25"/>
+ <point x="405" y="-25" type="curve" smooth="yes"/>
+ <point x="507" y="-25"/>
+ <point x="580" y="46"/>
+ <point x="580" y="150" type="curve" smooth="yes"/>
+ <point x="580" y="252"/>
+ <point x="507" y="325"/>
+ <point x="405" y="325" type="curve" smooth="yes"/>
+ <point x="304" y="325"/>
+ <point x="230" y="252"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfrenameglyphs.ufo/glyphs/F_ullS_top.glif b/tests/reference/ufo/psfrenameglyphs.ufo/glyphs/F_ullS_top.glif
new file mode 100644
index 0000000..b05d598
--- /dev/null
+++ b/tests/reference/ufo/psfrenameglyphs.ufo/glyphs/F_ullS_top.glif
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="FullStop" format="2">
+ <advance width="710"/>
+ <unicode hex="002E"/>
+ <outline>
+ <contour>
+ <point x="200" y="150" type="curve" smooth="yes"/>
+ <point x="200" y="46"/>
+ <point x="274" y="-25"/>
+ <point x="375" y="-25" type="curve" smooth="yes"/>
+ <point x="477" y="-25"/>
+ <point x="550" y="46"/>
+ <point x="550" y="150" type="curve" smooth="yes"/>
+ <point x="550" y="252"/>
+ <point x="477" y="325"/>
+ <point x="375" y="325" type="curve" smooth="yes"/>
+ <point x="274" y="325"/>
+ <point x="200" y="252"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfrenameglyphs.ufo/glyphs/G_T_S_gn.glif b/tests/reference/ufo/psfrenameglyphs.ufo/glyphs/G_T_S_gn.glif
new file mode 100644
index 0000000..650e4d2
--- /dev/null
+++ b/tests/reference/ufo/psfrenameglyphs.ufo/glyphs/G_T_S_gn.glif
@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="GTSgn" format="2">
+ <advance width="1200"/>
+ <unicode hex="003E"/>
+ <outline>
+ <contour>
+ <point x="130" y="245" type="line"/>
+ <point x="1090" y="635" type="line"/>
+ <point x="1090" y="825" type="line"/>
+ <point x="130" y="1215" type="line"/>
+ <point x="130" y="985" type="line"/>
+ <point x="810" y="730" type="line"/>
+ <point x="130" y="475" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfrenameglyphs.ufo/glyphs/G_raveA_ccent.glif b/tests/reference/ufo/psfrenameglyphs.ufo/glyphs/G_raveA_ccent.glif
new file mode 100644
index 0000000..83a5f21
--- /dev/null
+++ b/tests/reference/ufo/psfrenameglyphs.ufo/glyphs/G_raveA_ccent.glif
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="GraveAccent" format="2">
+ <advance width="640"/>
+ <unicode hex="0060"/>
+ <anchor x="500" y="1635" name="U"/>
+ <outline>
+ <contour>
+ <point x="0" y="1600" type="line"/>
+ <point x="400" y="1200" type="line"/>
+ <point x="640" y="1200" type="line"/>
+ <point x="350" y="1600" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfrenameglyphs.ufo/glyphs/H_yphen.glif b/tests/reference/ufo/psfrenameglyphs.ufo/glyphs/H_yphen.glif
new file mode 100644
index 0000000..d79c70a
--- /dev/null
+++ b/tests/reference/ufo/psfrenameglyphs.ufo/glyphs/H_yphen.glif
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="Hyphen" format="2">
+ <advance width="880"/>
+ <unicode hex="2010"/>
+ <anchor x="440" y="1100" name="U"/>
+ <outline>
+ <contour>
+ <point x="70" y="525" type="line"/>
+ <point x="810" y="525" type="line"/>
+ <point x="810" y="735" type="line"/>
+ <point x="70" y="735" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfrenameglyphs.ufo/glyphs/H_yphenM_inus.glif b/tests/reference/ufo/psfrenameglyphs.ufo/glyphs/H_yphenM_inus.glif
new file mode 100644
index 0000000..b88bdd4
--- /dev/null
+++ b/tests/reference/ufo/psfrenameglyphs.ufo/glyphs/H_yphenM_inus.glif
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="HyphenMinus" format="2">
+ <advance width="895"/>
+ <unicode hex="002D"/>
+ <anchor x="450" y="1100" name="U"/>
+ <outline>
+ <contour>
+ <point x="80" y="525" type="line"/>
+ <point x="815" y="525" type="line"/>
+ <point x="815" y="735" type="line"/>
+ <point x="80" y="735" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfrenameglyphs.ufo/glyphs/H_yphen_S_oft.glif b/tests/reference/ufo/psfrenameglyphs.ufo/glyphs/H_yphen_S_oft.glif
new file mode 100644
index 0000000..916f8cf
--- /dev/null
+++ b/tests/reference/ufo/psfrenameglyphs.ufo/glyphs/H_yphen_S_oft.glif
@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="Hyphen_Soft" format="2">
+ <advance width="895"/>
+ <unicode hex="00AD"/>
+ <anchor x="450" y="1100" name="U"/>
+ <outline>
+ <component base="HyphenMinus"/>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfrenameglyphs.ufo/glyphs/L_T_S_gn.glif b/tests/reference/ufo/psfrenameglyphs.ufo/glyphs/L_T_S_gn.glif
new file mode 100644
index 0000000..ab92cf3
--- /dev/null
+++ b/tests/reference/ufo/psfrenameglyphs.ufo/glyphs/L_T_S_gn.glif
@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LTSgn" format="2">
+ <advance width="1200"/>
+ <unicode hex="003C"/>
+ <outline>
+ <contour>
+ <point x="1070" y="475" type="line"/>
+ <point x="390" y="730" type="line"/>
+ <point x="1070" y="985" type="line"/>
+ <point x="1070" y="1215" type="line"/>
+ <point x="110" y="825" type="line"/>
+ <point x="110" y="635" type="line"/>
+ <point x="1070" y="245" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfrenameglyphs.ufo/glyphs/L_ftC_urlyB_rac.glif b/tests/reference/ufo/psfrenameglyphs.ufo/glyphs/L_ftC_urlyB_rac.glif
new file mode 100644
index 0000000..2370b56
--- /dev/null
+++ b/tests/reference/ufo/psfrenameglyphs.ufo/glyphs/L_ftC_urlyB_rac.glif
@@ -0,0 +1,47 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LftCurlyBrac" format="2">
+ <advance width="1040"/>
+ <unicode hex="007B"/>
+ <outline>
+ <contour>
+ <point x="895" y="-179" type="line"/>
+ <point x="828" y="-160"/>
+ <point x="704" y="-122"/>
+ <point x="685" y="-100" type="curve" smooth="yes"/>
+ <point x="650" y="-60"/>
+ <point x="663" y="411"/>
+ <point x="645" y="445" type="curve" smooth="yes"/>
+ <point x="621" y="491"/>
+ <point x="483" y="580"/>
+ <point x="483" y="615" type="curve" smooth="yes"/>
+ <point x="483" y="650"/>
+ <point x="620" y="740"/>
+ <point x="643" y="785" type="curve" smooth="yes"/>
+ <point x="661" y="820"/>
+ <point x="650" y="1289"/>
+ <point x="685" y="1330" type="curve" smooth="yes"/>
+ <point x="702" y="1351"/>
+ <point x="807" y="1390"/>
+ <point x="870" y="1409" type="curve"/>
+ <point x="820" y="1640" type="line"/>
+ <point x="692" y="1613"/>
+ <point x="502" y="1562"/>
+ <point x="455" y="1515" type="curve" smooth="yes"/>
+ <point x="381" y="1442"/>
+ <point x="392" y="852"/>
+ <point x="370" y="820" type="curve" smooth="yes"/>
+ <point x="340" y="777"/>
+ <point x="170" y="670"/>
+ <point x="170" y="615" type="curve" smooth="yes"/>
+ <point x="170" y="560"/>
+ <point x="340" y="453"/>
+ <point x="370" y="410" type="curve" smooth="yes"/>
+ <point x="392" y="378"/>
+ <point x="380" y="-213"/>
+ <point x="455" y="-285" type="curve" smooth="yes"/>
+ <point x="505" y="-333"/>
+ <point x="709" y="-383"/>
+ <point x="845" y="-410" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfrenameglyphs.ufo/glyphs/L_ftP_aren.glif b/tests/reference/ufo/psfrenameglyphs.ufo/glyphs/L_ftP_aren.glif
new file mode 100644
index 0000000..99e1982
--- /dev/null
+++ b/tests/reference/ufo/psfrenameglyphs.ufo/glyphs/L_ftP_aren.glif
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LftParen" format="2">
+ <advance width="860"/>
+ <unicode hex="0028"/>
+ <outline>
+ <contour>
+ <point x="555" y="1640" type="line"/>
+ <point x="290" y="1444"/>
+ <point x="115" y="1062"/>
+ <point x="115" y="625" type="curve" smooth="yes"/>
+ <point x="115" y="218"/>
+ <point x="260" y="-125"/>
+ <point x="535" y="-410" type="curve"/>
+ <point x="686" y="-240" type="line"/>
+ <point x="462" y="11"/>
+ <point x="376" y="335"/>
+ <point x="376" y="635" type="curve" smooth="yes"/>
+ <point x="376" y="938"/>
+ <point x="466" y="1261"/>
+ <point x="676" y="1455" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfrenameglyphs.ufo/glyphs/L_ftS_qrB_rac.glif b/tests/reference/ufo/psfrenameglyphs.ufo/glyphs/L_ftS_qrB_rac.glif
new file mode 100644
index 0000000..dcf019b
--- /dev/null
+++ b/tests/reference/ufo/psfrenameglyphs.ufo/glyphs/L_ftS_qrB_rac.glif
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LftSqrBrac" format="2">
+ <advance width="850"/>
+ <unicode hex="005B"/>
+ <outline>
+ <contour>
+ <point x="710" y="-410" type="line"/>
+ <point x="710" y="-200" type="line"/>
+ <point x="470" y="-200" type="line"/>
+ <point x="470" y="1390" type="line"/>
+ <point x="710" y="1390" type="line"/>
+ <point x="710" y="1600" type="line"/>
+ <point x="190" y="1600" type="line"/>
+ <point x="190" y="-410" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfrenameglyphs.ufo/glyphs/L_owL_ine.glif b/tests/reference/ufo/psfrenameglyphs.ufo/glyphs/L_owL_ine.glif
new file mode 100644
index 0000000..225c4ce
--- /dev/null
+++ b/tests/reference/ufo/psfrenameglyphs.ufo/glyphs/L_owL_ine.glif
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LowLine" format="2">
+ <advance width="1274"/>
+ <unicode hex="005F"/>
+ <outline>
+ <contour>
+ <point x="0" y="-350" type="line"/>
+ <point x="1274" y="-350" type="line"/>
+ <point x="1274" y="-140" type="line"/>
+ <point x="0" y="-140" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfrenameglyphs.ufo/glyphs/L_tnC_apA_.alt.glif b/tests/reference/ufo/psfrenameglyphs.ufo/glyphs/L_tnC_apA_.alt.glif
new file mode 100644
index 0000000..cf1b900
--- /dev/null
+++ b/tests/reference/ufo/psfrenameglyphs.ufo/glyphs/L_tnC_apA_.alt.glif
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnCapA.alt" format="2">
+ <advance width="1485"/>
+ <anchor x="1275" y="0" name="H"/>
+ <anchor x="732" y="-100" name="L"/>
+ <anchor x="1495" y="0" name="O"/>
+ <anchor x="732" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="1115" y="0" type="line"/>
+ <point x="1408" y="0" type="line"/>
+ <point x="1373" y="80"/>
+ <point x="1341" y="168"/>
+ <point x="1278" y="355" type="curve" smooth="yes"/>
+ <point x="908" y="1460" type="line"/>
+ <point x="552" y="1460" type="line"/>
+ <point x="182" y="355" type="line" smooth="yes"/>
+ <point x="119" y="166"/>
+ <point x="88" y="81"/>
+ <point x="52" y="0" type="curve"/>
+ <point x="350" y="0" type="line"/>
+ <point x="460" y="355" type="line"/>
+ <point x="1004" y="355" type="line"/>
+ </contour>
+ <contour>
+ <point x="730" y="1228" type="line"/>
+ <point x="936" y="570" type="line"/>
+ <point x="526" y="570" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfrenameglyphs.ufo/glyphs/L_tnC_apA_.glif b/tests/reference/ufo/psfrenameglyphs.ufo/glyphs/L_tnC_apA_.glif
new file mode 100644
index 0000000..9fa1f45
--- /dev/null
+++ b/tests/reference/ufo/psfrenameglyphs.ufo/glyphs/L_tnC_apA_.glif
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnCapA" format="2">
+ <advance width="1485"/>
+ <unicode hex="0041"/>
+ <anchor x="1275" y="0" name="H"/>
+ <anchor x="732" y="-100" name="L"/>
+ <anchor x="1495" y="0" name="O"/>
+ <anchor x="732" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="1115" y="0" type="line"/>
+ <point x="1408" y="0" type="line"/>
+ <point x="1373" y="80"/>
+ <point x="1341" y="168"/>
+ <point x="1278" y="355" type="curve" smooth="yes"/>
+ <point x="908" y="1460" type="line"/>
+ <point x="552" y="1460" type="line"/>
+ <point x="182" y="355" type="line" smooth="yes"/>
+ <point x="119" y="166"/>
+ <point x="88" y="81"/>
+ <point x="52" y="0" type="curve"/>
+ <point x="350" y="0" type="line"/>
+ <point x="460" y="355" type="line"/>
+ <point x="1004" y="355" type="line"/>
+ </contour>
+ <contour>
+ <point x="730" y="1228" type="line"/>
+ <point x="936" y="570" type="line"/>
+ <point x="526" y="570" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfrenameglyphs.ufo/glyphs/L_tnC_apA_D_iaer.glif b/tests/reference/ufo/psfrenameglyphs.ufo/glyphs/L_tnC_apA_D_iaer.glif
new file mode 100644
index 0000000..79101d0
--- /dev/null
+++ b/tests/reference/ufo/psfrenameglyphs.ufo/glyphs/L_tnC_apA_D_iaer.glif
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnCapADiaer" format="2">
+ <advance width="1485"/>
+ <unicode hex="00C4"/>
+ <anchor x="1275" y="0" name="H"/>
+ <anchor x="732" y="-100" name="L"/>
+ <anchor x="1495" y="0" name="O"/>
+ <anchor x="732" y="2015" name="U"/>
+ <outline>
+ <component base="LtnCapA"/>
+ <component base="CombDiaer" xOffset="1312" yOffset="430"/>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfrenameglyphs.ufo/glyphs/L_tnC_apB_.glif b/tests/reference/ufo/psfrenameglyphs.ufo/glyphs/L_tnC_apB_.glif
new file mode 100644
index 0000000..df49e47
--- /dev/null
+++ b/tests/reference/ufo/psfrenameglyphs.ufo/glyphs/L_tnC_apB_.glif
@@ -0,0 +1,62 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnCapB" format="2">
+ <advance width="1385"/>
+ <unicode hex="0042"/>
+ <anchor x="670" y="-100" name="L"/>
+ <anchor x="670" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="450" y="1248" type="line"/>
+ <point x="487" y="1250"/>
+ <point x="562" y="1253"/>
+ <point x="631" y="1253" type="curve" smooth="yes"/>
+ <point x="818" y="1253"/>
+ <point x="897" y="1196"/>
+ <point x="897" y="1077" type="curve" smooth="yes"/>
+ <point x="897" y="951"/>
+ <point x="794" y="875"/>
+ <point x="605" y="875" type="curve" smooth="yes"/>
+ <point x="450" y="875" type="line"/>
+ </contour>
+ <contour>
+ <point x="1245" y="430" type="curve" smooth="yes"/>
+ <point x="1245" y="672"/>
+ <point x="1084" y="760"/>
+ <point x="935" y="800" type="curve"/>
+ <point x="1065" y="850"/>
+ <point x="1170" y="947"/>
+ <point x="1170" y="1110" type="curve" smooth="yes"/>
+ <point x="1170" y="1378"/>
+ <point x="937" y="1470"/>
+ <point x="615" y="1470" type="curve" smooth="yes"/>
+ <point x="422" y="1470"/>
+ <point x="248" y="1466"/>
+ <point x="150" y="1460" type="curve"/>
+ <point x="165" y="1380"/>
+ <point x="165" y="1196"/>
+ <point x="165" y="1000" type="curve" smooth="yes"/>
+ <point x="165" y="455" type="line" smooth="yes"/>
+ <point x="165" y="257"/>
+ <point x="165" y="80"/>
+ <point x="150" y="0" type="curve"/>
+ <point x="150" y="0"/>
+ <point x="401" y="-10"/>
+ <point x="631" y="-10" type="curve" smooth="yes"/>
+ <point x="1055" y="-10"/>
+ <point x="1245" y="181"/>
+ </contour>
+ <contour>
+ <point x="450" y="658" type="line"/>
+ <point x="643" y="658" type="line" smooth="yes"/>
+ <point x="853" y="658"/>
+ <point x="972" y="587"/>
+ <point x="972" y="450" type="curve" smooth="yes"/>
+ <point x="972" y="269"/>
+ <point x="826" y="215"/>
+ <point x="652" y="215" type="curve" smooth="yes"/>
+ <point x="552" y="215"/>
+ <point x="483" y="218"/>
+ <point x="450" y="220" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfrenameglyphs.ufo/glyphs/L_tnC_apC_.glif b/tests/reference/ufo/psfrenameglyphs.ufo/glyphs/L_tnC_apC_.glif
new file mode 100644
index 0000000..78c5238
--- /dev/null
+++ b/tests/reference/ufo/psfrenameglyphs.ufo/glyphs/L_tnC_apC_.glif
@@ -0,0 +1,38 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnCapC" format="2">
+ <advance width="1385"/>
+ <unicode hex="0043"/>
+ <anchor x="745" y="0" name="H"/>
+ <anchor x="745" y="-100" name="L"/>
+ <anchor x="745" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="1215" y="405" type="line"/>
+ <point x="1105" y="293"/>
+ <point x="940" y="220"/>
+ <point x="790" y="220" type="curve" smooth="yes"/>
+ <point x="531" y="220"/>
+ <point x="375" y="413"/>
+ <point x="375" y="735" type="curve" smooth="yes"/>
+ <point x="375" y="1074"/>
+ <point x="557" y="1245"/>
+ <point x="800" y="1245" type="curve" smooth="yes"/>
+ <point x="931" y="1245"/>
+ <point x="1053" y="1205"/>
+ <point x="1180" y="1105" type="curve"/>
+ <point x="1250" y="1345" type="line"/>
+ <point x="1106" y="1449"/>
+ <point x="969" y="1485"/>
+ <point x="785" y="1485" type="curve" smooth="yes"/>
+ <point x="413" y="1485"/>
+ <point x="90" y="1225"/>
+ <point x="90" y="710" type="curve" smooth="yes"/>
+ <point x="90" y="260"/>
+ <point x="341" y="-25"/>
+ <point x="755" y="-25" type="curve" smooth="yes"/>
+ <point x="926" y="-25"/>
+ <point x="1142" y="42"/>
+ <point x="1265" y="140" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfrenameglyphs.ufo/glyphs/L_tnC_apD_.glif b/tests/reference/ufo/psfrenameglyphs.ufo/glyphs/L_tnC_apD_.glif
new file mode 100644
index 0000000..4dd3b9c
--- /dev/null
+++ b/tests/reference/ufo/psfrenameglyphs.ufo/glyphs/L_tnC_apD_.glif
@@ -0,0 +1,45 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnCapD" format="2">
+ <advance width="1485"/>
+ <unicode hex="0044"/>
+ <anchor x="800" y="-100" name="L"/>
+ <anchor x="800" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="165" y="455" type="line"/>
+ <point x="164" y="257"/>
+ <point x="165" y="80"/>
+ <point x="150" y="0" type="curve"/>
+ <point x="150" y="0"/>
+ <point x="474" y="-10"/>
+ <point x="609" y="-10" type="curve" smooth="yes"/>
+ <point x="919" y="-10"/>
+ <point x="1370" y="145"/>
+ <point x="1370" y="740" type="curve" smooth="yes"/>
+ <point x="1370" y="1374"/>
+ <point x="906" y="1470"/>
+ <point x="630" y="1470" type="curve" smooth="yes"/>
+ <point x="487" y="1470"/>
+ <point x="239" y="1466"/>
+ <point x="150" y="1460" type="curve"/>
+ <point x="165" y="1380"/>
+ <point x="165" y="1196"/>
+ <point x="165" y="1000" type="curve" smooth="yes"/>
+ </contour>
+ <contour>
+ <point x="450" y="1241" type="line"/>
+ <point x="492" y="1243"/>
+ <point x="582" y="1246"/>
+ <point x="637" y="1246" type="curve" smooth="yes"/>
+ <point x="897" y="1246"/>
+ <point x="1078" y="1118"/>
+ <point x="1078" y="720" type="curve" smooth="yes"/>
+ <point x="1078" y="357"/>
+ <point x="856" y="221"/>
+ <point x="633" y="221" type="curve" smooth="yes"/>
+ <point x="554" y="221"/>
+ <point x="489" y="227"/>
+ <point x="450" y="231" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfrenameglyphs.ufo/glyphs/L_tnC_apE_.glif b/tests/reference/ufo/psfrenameglyphs.ufo/glyphs/L_tnC_apE_.glif
new file mode 100644
index 0000000..9572dfd
--- /dev/null
+++ b/tests/reference/ufo/psfrenameglyphs.ufo/glyphs/L_tnC_apE_.glif
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnCapE" format="2">
+ <advance width="1212"/>
+ <unicode hex="0045"/>
+ <anchor x="610" y="0" name="H"/>
+ <anchor x="610" y="-100" name="L"/>
+ <anchor x="1004" y="0" name="O"/>
+ <anchor x="1247" y="1200" name="R"/>
+ <anchor x="610" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="450" y="875" type="line"/>
+ <point x="450" y="1230" type="line"/>
+ <point x="1072" y="1230" type="line"/>
+ <point x="1072" y="1460" type="line"/>
+ <point x="150" y="1460" type="line"/>
+ <point x="165" y="1380"/>
+ <point x="165" y="1222"/>
+ <point x="165" y="1025" type="curve" smooth="yes"/>
+ <point x="165" y="435" type="line" smooth="yes"/>
+ <point x="165" y="238"/>
+ <point x="165" y="80"/>
+ <point x="150" y="0" type="curve"/>
+ <point x="1102" y="0" type="line"/>
+ <point x="1102" y="245" type="line"/>
+ <point x="1024" y="231"/>
+ <point x="899" y="230"/>
+ <point x="708" y="230" type="curve" smooth="yes"/>
+ <point x="450" y="230" type="line"/>
+ <point x="450" y="650" type="line"/>
+ <point x="997" y="650" type="line"/>
+ <point x="997" y="875" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfrenameglyphs.ufo/glyphs/L_tnC_apF_.glif b/tests/reference/ufo/psfrenameglyphs.ufo/glyphs/L_tnC_apF_.glif
new file mode 100644
index 0000000..9f4f14b
--- /dev/null
+++ b/tests/reference/ufo/psfrenameglyphs.ufo/glyphs/L_tnC_apF_.glif
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnCapF" format="2">
+ <advance width="1200"/>
+ <unicode hex="0046"/>
+ <anchor x="630" y="-100" name="L"/>
+ <anchor x="630" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="450" y="860" type="line"/>
+ <point x="450" y="1230" type="line"/>
+ <point x="1090" y="1230" type="line"/>
+ <point x="1090" y="1460" type="line"/>
+ <point x="150" y="1460" type="line"/>
+ <point x="165" y="1380"/>
+ <point x="165" y="1217"/>
+ <point x="165" y="1020" type="curve" smooth="yes"/>
+ <point x="165" y="435" type="line" smooth="yes"/>
+ <point x="165" y="238"/>
+ <point x="165" y="80"/>
+ <point x="150" y="0" type="curve"/>
+ <point x="465" y="0" type="line"/>
+ <point x="450" y="73"/>
+ <point x="450" y="222"/>
+ <point x="450" y="408" type="curve" smooth="yes"/>
+ <point x="450" y="635" type="line"/>
+ <point x="1005" y="635" type="line"/>
+ <point x="1005" y="860" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfrenameglyphs.ufo/glyphs/L_tnC_apG_.glif b/tests/reference/ufo/psfrenameglyphs.ufo/glyphs/L_tnC_apG_.glif
new file mode 100644
index 0000000..8358b8a
--- /dev/null
+++ b/tests/reference/ufo/psfrenameglyphs.ufo/glyphs/L_tnC_apG_.glif
@@ -0,0 +1,42 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnCapG" format="2">
+ <advance width="1472"/>
+ <unicode hex="0047"/>
+ <anchor x="807" y="0" name="H"/>
+ <anchor x="807" y="-100" name="L"/>
+ <anchor x="807" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="1337" y="785" type="line"/>
+ <point x="767" y="785" type="line"/>
+ <point x="767" y="560" type="line"/>
+ <point x="1082" y="560" type="line"/>
+ <point x="1082" y="294" type="line"/>
+ <point x="966" y="236"/>
+ <point x="883" y="220"/>
+ <point x="769" y="220" type="curve" smooth="yes"/>
+ <point x="532" y="220"/>
+ <point x="375" y="420"/>
+ <point x="375" y="745" type="curve" smooth="yes"/>
+ <point x="375" y="1048"/>
+ <point x="545" y="1245"/>
+ <point x="810" y="1245" type="curve" smooth="yes"/>
+ <point x="953" y="1245"/>
+ <point x="1097" y="1205"/>
+ <point x="1236" y="1107" type="curve"/>
+ <point x="1322" y="1345" type="line"/>
+ <point x="1137" y="1462"/>
+ <point x="989" y="1485"/>
+ <point x="818" y="1485" type="curve" smooth="yes"/>
+ <point x="403" y="1485"/>
+ <point x="90" y="1199"/>
+ <point x="90" y="720" type="curve" smooth="yes"/>
+ <point x="90" y="241"/>
+ <point x="377" y="-25"/>
+ <point x="777" y="-25" type="curve" smooth="yes"/>
+ <point x="960" y="-25"/>
+ <point x="1120" y="11"/>
+ <point x="1337" y="155" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfrenameglyphs.ufo/glyphs/L_tnC_apH_.glif b/tests/reference/ufo/psfrenameglyphs.ufo/glyphs/L_tnC_apH_.glif
new file mode 100644
index 0000000..2e2e5e6
--- /dev/null
+++ b/tests/reference/ufo/psfrenameglyphs.ufo/glyphs/L_tnC_apH_.glif
@@ -0,0 +1,40 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnCapH" format="2">
+ <advance width="1515"/>
+ <unicode hex="0048"/>
+ <anchor x="305" y="0" name="H"/>
+ <anchor x="745" y="-100" name="L"/>
+ <anchor x="745" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="1040" y="1460" type="line"/>
+ <point x="1040" y="860" type="line"/>
+ <point x="450" y="860" type="line"/>
+ <point x="450" y="1460" type="line"/>
+ <point x="150" y="1460" type="line"/>
+ <point x="165" y="1380"/>
+ <point x="165" y="1227"/>
+ <point x="165" y="1030" type="curve" smooth="yes"/>
+ <point x="165" y="430" type="line" smooth="yes"/>
+ <point x="165" y="233"/>
+ <point x="165" y="80"/>
+ <point x="150" y="0" type="curve"/>
+ <point x="150" y="0"/>
+ <point x="450" y="0"/>
+ <point x="450" y="0" type="curve"/>
+ <point x="450" y="635" type="line"/>
+ <point x="1040" y="635" type="line"/>
+ <point x="1040" y="0" type="line"/>
+ <point x="1040" y="0"/>
+ <point x="1340" y="0"/>
+ <point x="1340" y="0" type="curve"/>
+ <point x="1325" y="80"/>
+ <point x="1325" y="233"/>
+ <point x="1325" y="430" type="curve" smooth="yes"/>
+ <point x="1325" y="1030" type="line" smooth="yes"/>
+ <point x="1325" y="1227"/>
+ <point x="1325" y="1380"/>
+ <point x="1340" y="1460" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfrenameglyphs.ufo/glyphs/L_tnC_apI_.glif b/tests/reference/ufo/psfrenameglyphs.ufo/glyphs/L_tnC_apI_.glif
new file mode 100644
index 0000000..388486b
--- /dev/null
+++ b/tests/reference/ufo/psfrenameglyphs.ufo/glyphs/L_tnC_apI_.glif
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnCapI" format="2">
+ <advance width="1045"/>
+ <unicode hex="0049"/>
+ <anchor x="520" y="0" name="H"/>
+ <anchor x="516" y="-100" name="L"/>
+ <anchor x="712" y="0" name="O"/>
+ <anchor x="1014" y="1200" name="R"/>
+ <anchor x="520" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="130" y="1460" type="line"/>
+ <point x="130" y="1255" type="line"/>
+ <point x="370" y="1255" type="line"/>
+ <point x="370" y="205" type="line"/>
+ <point x="130" y="205" type="line"/>
+ <point x="130" y="0" type="line"/>
+ <point x="895" y="0" type="line"/>
+ <point x="895" y="205" type="line"/>
+ <point x="655" y="205" type="line"/>
+ <point x="655" y="1255" type="line"/>
+ <point x="895" y="1255" type="line"/>
+ <point x="895" y="1460" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfrenameglyphs.ufo/glyphs/L_tnC_apJ_.glif b/tests/reference/ufo/psfrenameglyphs.ufo/glyphs/L_tnC_apJ_.glif
new file mode 100644
index 0000000..8ee9ce3
--- /dev/null
+++ b/tests/reference/ufo/psfrenameglyphs.ufo/glyphs/L_tnC_apJ_.glif
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnCapJ" format="2">
+ <advance width="1030"/>
+ <unicode hex="004A"/>
+ <anchor x="415" y="-100" name="L"/>
+ <anchor x="705" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="555" y="1460" type="line"/>
+ <point x="568" y="1354"/>
+ <point x="570" y="1175"/>
+ <point x="570" y="980" type="curve" smooth="yes"/>
+ <point x="570" y="558" type="line" smooth="yes"/>
+ <point x="570" y="383"/>
+ <point x="540" y="227"/>
+ <point x="365" y="227" type="curve" smooth="yes"/>
+ <point x="264" y="227"/>
+ <point x="153" y="270"/>
+ <point x="79" y="347" type="curve"/>
+ <point x="30" y="90" type="line"/>
+ <point x="109" y="9"/>
+ <point x="258" y="-25"/>
+ <point x="363" y="-25" type="curve" smooth="yes"/>
+ <point x="658" y="-25"/>
+ <point x="855" y="129"/>
+ <point x="855" y="535" type="curve" smooth="yes"/>
+ <point x="855" y="618"/>
+ <point x="855" y="1460"/>
+ <point x="855" y="1460" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfrenameglyphs.ufo/glyphs/L_tnC_apK_.glif b/tests/reference/ufo/psfrenameglyphs.ufo/glyphs/L_tnC_apK_.glif
new file mode 100644
index 0000000..abb6ff7
--- /dev/null
+++ b/tests/reference/ufo/psfrenameglyphs.ufo/glyphs/L_tnC_apK_.glif
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnCapK" format="2">
+ <advance width="1430"/>
+ <unicode hex="004B"/>
+ <anchor x="320" y="0" name="H"/>
+ <anchor x="740" y="-100" name="L"/>
+ <anchor x="725" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="944" y="1460" type="line"/>
+ <point x="371" y="732" type="line"/>
+ <point x="579" y="676" type="line"/>
+ <point x="1280" y="1460" type="line"/>
+ </contour>
+ <contour>
+ <point x="389" y="731" type="line"/>
+ <point x="990" y="0" type="line"/>
+ <point x="1360" y="0" type="line"/>
+ <point x="614" y="829" type="line"/>
+ </contour>
+ <contour>
+ <point x="450" y="1460" type="line"/>
+ <point x="150" y="1460" type="line"/>
+ <point x="165" y="1380"/>
+ <point x="165" y="1222"/>
+ <point x="165" y="1025" type="curve" smooth="yes"/>
+ <point x="165" y="435" type="line" smooth="yes"/>
+ <point x="165" y="238"/>
+ <point x="165" y="80"/>
+ <point x="150" y="0" type="curve"/>
+ <point x="450" y="0" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfrenameglyphs.ufo/glyphs/L_tnC_apL_.glif b/tests/reference/ufo/psfrenameglyphs.ufo/glyphs/L_tnC_apL_.glif
new file mode 100644
index 0000000..e1c1e2e
--- /dev/null
+++ b/tests/reference/ufo/psfrenameglyphs.ufo/glyphs/L_tnC_apL_.glif
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnCapL" format="2">
+ <advance width="1130"/>
+ <unicode hex="004C"/>
+ <anchor x="620" y="0" name="H"/>
+ <anchor x="620" y="-100" name="L"/>
+ <anchor x="650" y="1200" name="R"/>
+ <anchor x="620" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="450" y="230" type="line"/>
+ <point x="450" y="1460" type="line"/>
+ <point x="150" y="1460" type="line"/>
+ <point x="165" y="1380"/>
+ <point x="165" y="1222"/>
+ <point x="165" y="1025" type="curve" smooth="yes"/>
+ <point x="165" y="435" type="line" smooth="yes"/>
+ <point x="165" y="238"/>
+ <point x="165" y="80"/>
+ <point x="150" y="0" type="curve"/>
+ <point x="1085" y="0" type="line"/>
+ <point x="1085" y="245" type="line"/>
+ <point x="1008" y="231"/>
+ <point x="855" y="230"/>
+ <point x="666" y="230" type="curve" smooth="yes"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfrenameglyphs.ufo/glyphs/L_tnC_apM_.glif b/tests/reference/ufo/psfrenameglyphs.ufo/glyphs/L_tnC_apM_.glif
new file mode 100644
index 0000000..8da241e
--- /dev/null
+++ b/tests/reference/ufo/psfrenameglyphs.ufo/glyphs/L_tnC_apM_.glif
@@ -0,0 +1,38 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnCapM" format="2">
+ <advance width="1855"/>
+ <unicode hex="004D"/>
+ <anchor x="915" y="-100" name="L"/>
+ <anchor x="915" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="917" y="275" type="line"/>
+ <point x="575" y="1460" type="line"/>
+ <point x="315" y="1460" type="line"/>
+ <point x="436" y="1170" type="line"/>
+ <point x="770" y="0" type="line"/>
+ <point x="1065" y="0" type="line"/>
+ <point x="1397" y="1170" type="line"/>
+ <point x="1517" y="1460" type="line"/>
+ <point x="1260" y="1460" type="line"/>
+ </contour>
+ <contour>
+ <point x="220" y="1460" type="line"/>
+ <point x="220" y="1460"/>
+ <point x="176" y="198"/>
+ <point x="150" y="0" type="curve"/>
+ <point x="420" y="0" type="line"/>
+ <point x="449" y="1205" type="line"/>
+ <point x="485" y="1460" type="line"/>
+ </contour>
+ <contour>
+ <point x="1680" y="0" type="line"/>
+ <point x="1651" y="198"/>
+ <point x="1610" y="1460"/>
+ <point x="1610" y="1460" type="curve"/>
+ <point x="1340" y="1460" type="line"/>
+ <point x="1385" y="1205" type="line"/>
+ <point x="1410" y="0" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfrenameglyphs.ufo/glyphs/L_tnC_apN_.glif b/tests/reference/ufo/psfrenameglyphs.ufo/glyphs/L_tnC_apN_.glif
new file mode 100644
index 0000000..aa2b5c4
--- /dev/null
+++ b/tests/reference/ufo/psfrenameglyphs.ufo/glyphs/L_tnC_apN_.glif
@@ -0,0 +1,37 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnCapN" format="2">
+ <advance width="1545"/>
+ <unicode hex="004E"/>
+ <anchor x="1240" y="0" name="H"/>
+ <anchor x="765" y="-100" name="L"/>
+ <anchor x="765" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="223" y="1310" type="line"/>
+ <point x="1095" y="0" type="line"/>
+ <point x="1297" y="150" type="line"/>
+ <point x="425" y="1460" type="line"/>
+ </contour>
+ <contour>
+ <point x="1095" y="0" type="line"/>
+ <point x="1355" y="0" type="line"/>
+ <point x="1355" y="1025" type="line" smooth="yes"/>
+ <point x="1355" y="1222"/>
+ <point x="1356" y="1380"/>
+ <point x="1370" y="1460" type="curve"/>
+ <point x="1095" y="1460" type="line"/>
+ </contour>
+ <contour>
+ <point x="425" y="1460" type="line"/>
+ <point x="150" y="1460" type="line"/>
+ <point x="165" y="1380"/>
+ <point x="165" y="1222"/>
+ <point x="165" y="1025" type="curve" smooth="yes"/>
+ <point x="165" y="435" type="line" smooth="yes"/>
+ <point x="165" y="238"/>
+ <point x="165" y="80"/>
+ <point x="150" y="0" type="curve"/>
+ <point x="425" y="0" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfrenameglyphs.ufo/glyphs/L_tnC_apO_.glif b/tests/reference/ufo/psfrenameglyphs.ufo/glyphs/L_tnC_apO_.glif
new file mode 100644
index 0000000..10479ad
--- /dev/null
+++ b/tests/reference/ufo/psfrenameglyphs.ufo/glyphs/L_tnC_apO_.glif
@@ -0,0 +1,40 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnCapO" format="2">
+ <advance width="1500"/>
+ <unicode hex="004F"/>
+ <anchor x="740" y="0" name="H"/>
+ <anchor x="740" y="-100" name="L"/>
+ <anchor x="976" y="0" name="O"/>
+ <anchor x="1480" y="1200" name="R"/>
+ <anchor x="740" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="1100" y="715" type="curve" smooth="yes"/>
+ <point x="1100" y="404"/>
+ <point x="940" y="220"/>
+ <point x="740" y="220" type="curve" smooth="yes"/>
+ <point x="524" y="220"/>
+ <point x="375" y="423"/>
+ <point x="375" y="745" type="curve" smooth="yes"/>
+ <point x="375" y="1048"/>
+ <point x="529" y="1240"/>
+ <point x="740" y="1240" type="curve" smooth="yes"/>
+ <point x="951" y="1240"/>
+ <point x="1100" y="1041"/>
+ </contour>
+ <contour>
+ <point x="1385" y="740" type="curve" smooth="yes"/>
+ <point x="1385" y="1219"/>
+ <point x="1091" y="1485"/>
+ <point x="750" y="1485" type="curve" smooth="yes"/>
+ <point x="404" y="1485"/>
+ <point x="90" y="1199"/>
+ <point x="90" y="720" type="curve" smooth="yes"/>
+ <point x="90" y="241"/>
+ <point x="385" y="-25"/>
+ <point x="730" y="-25" type="curve" smooth="yes"/>
+ <point x="1072" y="-25"/>
+ <point x="1385" y="260"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfrenameglyphs.ufo/glyphs/L_tnC_apP_.glif b/tests/reference/ufo/psfrenameglyphs.ufo/glyphs/L_tnC_apP_.glif
new file mode 100644
index 0000000..18e9ee0
--- /dev/null
+++ b/tests/reference/ufo/psfrenameglyphs.ufo/glyphs/L_tnC_apP_.glif
@@ -0,0 +1,50 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnCapP" format="2">
+ <advance width="1275"/>
+ <unicode hex="0050"/>
+ <anchor x="685" y="-100" name="L"/>
+ <anchor x="685" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="450" y="523" type="line"/>
+ <point x="515" y="516"/>
+ <point x="575" y="513"/>
+ <point x="648" y="513" type="curve" smooth="yes"/>
+ <point x="977" y="513"/>
+ <point x="1200" y="702"/>
+ <point x="1200" y="1010" type="curve" smooth="yes"/>
+ <point x="1200" y="1316"/>
+ <point x="981" y="1470"/>
+ <point x="658" y="1470" type="curve" smooth="yes"/>
+ <point x="445" y="1470"/>
+ <point x="150" y="1460"/>
+ <point x="150" y="1460" type="curve"/>
+ <point x="165" y="1380"/>
+ <point x="165" y="1196"/>
+ <point x="165" y="1000" type="curve" smooth="yes"/>
+ <point x="165" y="435" type="line" smooth="yes"/>
+ <point x="165" y="238"/>
+ <point x="165" y="80"/>
+ <point x="150" y="0" type="curve"/>
+ <point x="465" y="0" type="line"/>
+ <point x="451" y="78"/>
+ <point x="450" y="237"/>
+ <point x="450" y="435" type="curve" smooth="yes"/>
+ </contour>
+ <contour>
+ <point x="450" y="1240" type="line"/>
+ <point x="506" y="1243"/>
+ <point x="544" y="1245"/>
+ <point x="622" y="1245" type="curve" smooth="yes"/>
+ <point x="833" y="1245"/>
+ <point x="915" y="1145"/>
+ <point x="915" y="1000" type="curve" smooth="yes"/>
+ <point x="915" y="820"/>
+ <point x="811" y="730"/>
+ <point x="618" y="730" type="curve" smooth="yes"/>
+ <point x="556" y="730"/>
+ <point x="493" y="733"/>
+ <point x="450" y="740" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfrenameglyphs.ufo/glyphs/L_tnC_apQ_.glif b/tests/reference/ufo/psfrenameglyphs.ufo/glyphs/L_tnC_apQ_.glif
new file mode 100644
index 0000000..433087c
--- /dev/null
+++ b/tests/reference/ufo/psfrenameglyphs.ufo/glyphs/L_tnC_apQ_.glif
@@ -0,0 +1,49 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnCapQ" format="2">
+ <advance width="1545"/>
+ <unicode hex="0051"/>
+ <anchor x="747" y="-270" name="L"/>
+ <anchor x="747" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="1385" y="740" type="curve" smooth="yes"/>
+ <point x="1385" y="1219"/>
+ <point x="1091" y="1485"/>
+ <point x="750" y="1485" type="curve" smooth="yes"/>
+ <point x="404" y="1485"/>
+ <point x="90" y="1199"/>
+ <point x="90" y="720" type="curve" smooth="yes"/>
+ <point x="90" y="241"/>
+ <point x="385" y="-25"/>
+ <point x="730" y="-25" type="curve" smooth="yes"/>
+ <point x="807" y="-25"/>
+ <point x="840" y="-23"/>
+ <point x="889" y="-15" type="curve"/>
+ <point x="958" y="-15"/>
+ <point x="1266" y="-228"/>
+ <point x="1350" y="-228" type="curve" smooth="yes"/>
+ <point x="1424" y="-228"/>
+ <point x="1502" y="-68"/>
+ <point x="1535" y="-15" type="curve"/>
+ <point x="1394" y="1"/>
+ <point x="1277" y="68"/>
+ <point x="1146" y="142" type="curve"/>
+ <point x="1294" y="283"/>
+ <point x="1385" y="471"/>
+ </contour>
+ <contour>
+ <point x="1100" y="715" type="curve" smooth="yes"/>
+ <point x="1100" y="404"/>
+ <point x="943" y="220"/>
+ <point x="740" y="220" type="curve" smooth="yes"/>
+ <point x="524" y="220"/>
+ <point x="375" y="423"/>
+ <point x="375" y="745" type="curve" smooth="yes"/>
+ <point x="375" y="1048"/>
+ <point x="529" y="1240"/>
+ <point x="740" y="1240" type="curve" smooth="yes"/>
+ <point x="951" y="1240"/>
+ <point x="1100" y="1041"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfrenameglyphs.ufo/glyphs/L_tnC_apR_.glif b/tests/reference/ufo/psfrenameglyphs.ufo/glyphs/L_tnC_apR_.glif
new file mode 100644
index 0000000..6103056
--- /dev/null
+++ b/tests/reference/ufo/psfrenameglyphs.ufo/glyphs/L_tnC_apR_.glif
@@ -0,0 +1,55 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnCapR" format="2">
+ <advance width="1380"/>
+ <unicode hex="0052"/>
+ <anchor x="690" y="0" name="H"/>
+ <anchor x="690" y="-100" name="L"/>
+ <anchor x="660" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="450" y="585" type="line"/>
+ <point x="625" y="585" type="line" smooth="yes"/>
+ <point x="910" y="585"/>
+ <point x="1175" y="723"/>
+ <point x="1175" y="1040" type="curve" smooth="yes"/>
+ <point x="1175" y="1329"/>
+ <point x="961" y="1470"/>
+ <point x="650" y="1470" type="curve" smooth="yes"/>
+ <point x="416" y="1470"/>
+ <point x="150" y="1460"/>
+ <point x="150" y="1460" type="curve"/>
+ <point x="165" y="1380"/>
+ <point x="165" y="1196"/>
+ <point x="165" y="1000" type="curve" smooth="yes"/>
+ <point x="165" y="435" type="line" smooth="yes"/>
+ <point x="165" y="238"/>
+ <point x="165" y="80"/>
+ <point x="150" y="0" type="curve"/>
+ <point x="465" y="0" type="line"/>
+ <point x="451" y="78"/>
+ <point x="450" y="238"/>
+ <point x="450" y="435" type="curve" smooth="yes"/>
+ </contour>
+ <contour>
+ <point x="450" y="1240" type="line"/>
+ <point x="503" y="1243"/>
+ <point x="537" y="1245"/>
+ <point x="615" y="1245" type="curve" smooth="yes"/>
+ <point x="792" y="1245"/>
+ <point x="890" y="1186"/>
+ <point x="890" y="1035" type="curve" smooth="yes"/>
+ <point x="890" y="859"/>
+ <point x="780" y="800"/>
+ <point x="605" y="800" type="curve" smooth="yes"/>
+ <point x="450" y="800" type="line"/>
+ </contour>
+ <contour>
+ <point x="556" y="635" type="line"/>
+ <point x="975" y="0" type="line"/>
+ <point x="1330" y="0" type="line"/>
+ <point x="1263" y="73"/>
+ <point x="827" y="687"/>
+ <point x="827" y="687" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfrenameglyphs.ufo/glyphs/L_tnC_apS_.glif b/tests/reference/ufo/psfrenameglyphs.ufo/glyphs/L_tnC_apS_.glif
new file mode 100644
index 0000000..486ff77
--- /dev/null
+++ b/tests/reference/ufo/psfrenameglyphs.ufo/glyphs/L_tnC_apS_.glif
@@ -0,0 +1,50 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnCapS" format="2">
+ <advance width="1243"/>
+ <unicode hex="0053"/>
+ <anchor x="616" y="0" name="H"/>
+ <anchor x="616" y="-100" name="L"/>
+ <anchor x="616" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="1075" y="1395" type="line"/>
+ <point x="932" y="1458"/>
+ <point x="810" y="1485"/>
+ <point x="640" y="1485" type="curve" smooth="yes"/>
+ <point x="280" y="1485"/>
+ <point x="130" y="1239"/>
+ <point x="130" y="1060" type="curve" smooth="yes"/>
+ <point x="130" y="882"/>
+ <point x="196" y="754"/>
+ <point x="510" y="655" type="curve" smooth="yes"/>
+ <point x="800" y="563"/>
+ <point x="851" y="504"/>
+ <point x="851" y="420" type="curve" smooth="yes"/>
+ <point x="851" y="293"/>
+ <point x="730" y="220"/>
+ <point x="600" y="220" type="curve" smooth="yes"/>
+ <point x="439" y="220"/>
+ <point x="283" y="270"/>
+ <point x="140" y="385" type="curve"/>
+ <point x="90" y="110" type="line"/>
+ <point x="201" y="31"/>
+ <point x="391" y="-25"/>
+ <point x="600" y="-25" type="curve" smooth="yes"/>
+ <point x="895" y="-25"/>
+ <point x="1138" y="169"/>
+ <point x="1138" y="455" type="curve" smooth="yes"/>
+ <point x="1138" y="666"/>
+ <point x="994" y="787"/>
+ <point x="727" y="870" type="curve" smooth="yes"/>
+ <point x="464" y="952"/>
+ <point x="416" y="994"/>
+ <point x="416" y="1080" type="curve" smooth="yes"/>
+ <point x="416" y="1162"/>
+ <point x="506" y="1245"/>
+ <point x="630" y="1245" type="curve" smooth="yes"/>
+ <point x="771" y="1245"/>
+ <point x="873" y="1209"/>
+ <point x="1030" y="1130" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfrenameglyphs.ufo/glyphs/L_tnC_apT_.glif b/tests/reference/ufo/psfrenameglyphs.ufo/glyphs/L_tnC_apT_.glif
new file mode 100644
index 0000000..5f87c10
--- /dev/null
+++ b/tests/reference/ufo/psfrenameglyphs.ufo/glyphs/L_tnC_apT_.glif
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnCapT" format="2">
+ <advance width="1275"/>
+ <unicode hex="0054"/>
+ <anchor x="632" y="0" name="H"/>
+ <anchor x="632" y="-100" name="L"/>
+ <anchor x="632" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="45" y="1460" type="line"/>
+ <point x="45" y="1210" type="line"/>
+ <point x="117" y="1227"/>
+ <point x="196" y="1230"/>
+ <point x="276" y="1230" type="curve" smooth="yes"/>
+ <point x="488" y="1230" type="line"/>
+ <point x="488" y="413" type="line" smooth="yes"/>
+ <point x="488" y="226"/>
+ <point x="485" y="76"/>
+ <point x="468" y="0" type="curve"/>
+ <point x="793" y="0" type="line"/>
+ <point x="776" y="76"/>
+ <point x="773" y="226"/>
+ <point x="773" y="413" type="curve" smooth="yes"/>
+ <point x="773" y="1230" type="line"/>
+ <point x="989" y="1230" type="line" smooth="yes"/>
+ <point x="1070" y="1230"/>
+ <point x="1148" y="1227"/>
+ <point x="1220" y="1210" type="curve"/>
+ <point x="1220" y="1460" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfrenameglyphs.ufo/glyphs/L_tnC_apU_.glif b/tests/reference/ufo/psfrenameglyphs.ufo/glyphs/L_tnC_apU_.glif
new file mode 100644
index 0000000..b3f6b6f
--- /dev/null
+++ b/tests/reference/ufo/psfrenameglyphs.ufo/glyphs/L_tnC_apU_.glif
@@ -0,0 +1,38 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnCapU" format="2">
+ <advance width="1490"/>
+ <unicode hex="0055"/>
+ <anchor x="732" y="0" name="H"/>
+ <anchor x="732" y="-100" name="L"/>
+ <anchor x="950" y="0" name="O"/>
+ <anchor x="1480" y="1200" name="R"/>
+ <anchor x="732" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="1015" y="1460" type="line"/>
+ <point x="1015" y="560" type="line" smooth="yes"/>
+ <point x="1015" y="344"/>
+ <point x="952" y="204"/>
+ <point x="735" y="204" type="curve" smooth="yes"/>
+ <point x="513" y="204"/>
+ <point x="450" y="344"/>
+ <point x="450" y="560" type="curve" smooth="yes"/>
+ <point x="450" y="1460" type="line"/>
+ <point x="150" y="1460" type="line"/>
+ <point x="164" y="1380"/>
+ <point x="165" y="1222"/>
+ <point x="165" y="1025" type="curve" smooth="yes"/>
+ <point x="165" y="515" type="line" smooth="yes"/>
+ <point x="165" y="190"/>
+ <point x="356" y="-25"/>
+ <point x="735" y="-25" type="curve" smooth="yes"/>
+ <point x="1110" y="-25"/>
+ <point x="1300" y="190"/>
+ <point x="1300" y="515" type="curve" smooth="yes"/>
+ <point x="1300" y="1025" type="line" smooth="yes"/>
+ <point x="1300" y="1232"/>
+ <point x="1302" y="1380"/>
+ <point x="1315" y="1460" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfrenameglyphs.ufo/glyphs/L_tnC_apV_.glif b/tests/reference/ufo/psfrenameglyphs.ufo/glyphs/L_tnC_apV_.glif
new file mode 100644
index 0000000..3468784
--- /dev/null
+++ b/tests/reference/ufo/psfrenameglyphs.ufo/glyphs/L_tnC_apV_.glif
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnCapV" format="2">
+ <advance width="1465"/>
+ <unicode hex="0056"/>
+ <anchor x="730" y="0" name="H"/>
+ <anchor x="722" y="-100" name="L"/>
+ <anchor x="930" y="0" name="O"/>
+ <anchor x="722" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="1115" y="1460" type="line"/>
+ <point x="722" y="260" type="line"/>
+ <point x="330" y="1460" type="line"/>
+ <point x="25" y="1460" type="line"/>
+ <point x="58" y="1378"/>
+ <point x="96" y="1288"/>
+ <point x="165" y="1095" type="curve" smooth="yes"/>
+ <point x="555" y="0" type="line"/>
+ <point x="890" y="0" type="line"/>
+ <point x="1280" y="1095" type="line" smooth="yes"/>
+ <point x="1348" y="1289"/>
+ <point x="1384" y="1378"/>
+ <point x="1420" y="1460" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfrenameglyphs.ufo/glyphs/L_tnC_apW_.glif b/tests/reference/ufo/psfrenameglyphs.ufo/glyphs/L_tnC_apW_.glif
new file mode 100644
index 0000000..98329a0
--- /dev/null
+++ b/tests/reference/ufo/psfrenameglyphs.ufo/glyphs/L_tnC_apW_.glif
@@ -0,0 +1,45 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnCapW" format="2">
+ <advance width="2135"/>
+ <unicode hex="0057"/>
+ <anchor x="1052" y="-100" name="L"/>
+ <anchor x="1052" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="1490" y="0" type="line"/>
+ <point x="1655" y="0" type="line"/>
+ <point x="1965" y="1095" type="line" smooth="yes"/>
+ <point x="2020" y="1289"/>
+ <point x="2048" y="1378"/>
+ <point x="2080" y="1460" type="curve"/>
+ <point x="1770" y="1460" type="line"/>
+ <point x="1470" y="130" type="line"/>
+ </contour>
+ <contour>
+ <point x="1180" y="1460" type="line"/>
+ <point x="920" y="1460" type="line"/>
+ <point x="995" y="1305" type="line"/>
+ <point x="1340" y="0" type="line"/>
+ <point x="1510" y="0" type="line"/>
+ <point x="1530" y="130" type="line"/>
+ </contour>
+ <contour>
+ <point x="600" y="0" type="line"/>
+ <point x="765" y="0" type="line"/>
+ <point x="1105" y="1305" type="line"/>
+ <point x="1180" y="1460" type="line"/>
+ <point x="920" y="1460" type="line"/>
+ <point x="580" y="130" type="line"/>
+ </contour>
+ <contour>
+ <point x="340" y="1460" type="line"/>
+ <point x="30" y="1460" type="line"/>
+ <point x="61" y="1381"/>
+ <point x="92" y="1286"/>
+ <point x="145" y="1095" type="curve" smooth="yes"/>
+ <point x="450" y="0" type="line"/>
+ <point x="620" y="0" type="line"/>
+ <point x="640" y="130" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfrenameglyphs.ufo/glyphs/L_tnC_apX_.glif b/tests/reference/ufo/psfrenameglyphs.ufo/glyphs/L_tnC_apX_.glif
new file mode 100644
index 0000000..17126dd
--- /dev/null
+++ b/tests/reference/ufo/psfrenameglyphs.ufo/glyphs/L_tnC_apX_.glif
@@ -0,0 +1,39 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnCapX" format="2">
+ <advance width="1365"/>
+ <unicode hex="0058"/>
+ <anchor x="670" y="-100" name="L"/>
+ <anchor x="670" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="990" y="0" type="line"/>
+ <point x="1310" y="0" type="line"/>
+ <point x="1249" y="82"/>
+ <point x="1211" y="125"/>
+ <point x="1083" y="336" type="curve" smooth="yes"/>
+ <point x="400" y="1460" type="line"/>
+ <point x="75" y="1460" type="line"/>
+ <point x="139" y="1376"/>
+ <point x="189" y="1317"/>
+ <point x="315" y="1110" type="curve"/>
+ </contour>
+ <contour>
+ <point x="605" y="947" type="line"/>
+ <point x="255" y="340" type="line" smooth="yes"/>
+ <point x="133" y="128"/>
+ <point x="93" y="86"/>
+ <point x="30" y="0" type="curve"/>
+ <point x="350" y="0" type="line"/>
+ <point x="700" y="609" type="line"/>
+ </contour>
+ <contour>
+ <point x="750" y="609" type="line"/>
+ <point x="1040" y="1110" type="line" smooth="yes"/>
+ <point x="1153" y="1306"/>
+ <point x="1211" y="1383"/>
+ <point x="1275" y="1460" type="curve"/>
+ <point x="950" y="1460" type="line"/>
+ <point x="655" y="947" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfrenameglyphs.ufo/glyphs/L_tnC_apY_.glif b/tests/reference/ufo/psfrenameglyphs.ufo/glyphs/L_tnC_apY_.glif
new file mode 100644
index 0000000..a7a345d
--- /dev/null
+++ b/tests/reference/ufo/psfrenameglyphs.ufo/glyphs/L_tnC_apY_.glif
@@ -0,0 +1,39 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnCapY" format="2">
+ <advance width="1364"/>
+ <unicode hex="0059"/>
+ <anchor x="672" y="-100" name="L"/>
+ <anchor x="672" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="575" y="560" type="line"/>
+ <point x="782" y="675" type="line"/>
+ <point x="357" y="1460" type="line"/>
+ <point x="25" y="1460" type="line"/>
+ <point x="137" y="1311"/>
+ <point x="203" y="1197"/>
+ <point x="280" y="1065" type="curve" smooth="yes"/>
+ </contour>
+ <contour>
+ <point x="770" y="560" type="line"/>
+ <point x="1069" y="1065" type="line" smooth="yes"/>
+ <point x="1145" y="1195"/>
+ <point x="1201" y="1291"/>
+ <point x="1319" y="1460" type="curve"/>
+ <point x="997" y="1460" type="line"/>
+ <point x="577" y="675" type="line"/>
+ </contour>
+ <contour>
+ <point x="530" y="695" type="line"/>
+ <point x="530" y="435" type="line" smooth="yes"/>
+ <point x="530" y="238"/>
+ <point x="530" y="80"/>
+ <point x="515" y="0" type="curve"/>
+ <point x="830" y="0" type="line"/>
+ <point x="815" y="80"/>
+ <point x="815" y="238"/>
+ <point x="815" y="435" type="curve" smooth="yes"/>
+ <point x="815" y="695" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfrenameglyphs.ufo/glyphs/L_tnS_mA_.glif b/tests/reference/ufo/psfrenameglyphs.ufo/glyphs/L_tnS_mA_.glif
new file mode 100644
index 0000000..7885750
--- /dev/null
+++ b/tests/reference/ufo/psfrenameglyphs.ufo/glyphs/L_tnS_mA_.glif
@@ -0,0 +1,76 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmA" format="2">
+ <advance width="1205"/>
+ <unicode hex="0061"/>
+ <note>
+
+
+
+
+ GlyphNote A
+
+
+
+
+ </note>
+ <anchor x="985" y="0" name="H"/>
+ <anchor x="610" y="-100" name="L"/>
+ <anchor x="1185" y="0" name="O"/>
+ <anchor x="1145" y="1000" name="R"/>
+ <anchor x="610" y="1100" name="U"/>
+ <outline>
+ <contour>
+ <point x="1120" y="0" type="line"/>
+ <point x="1078" y="112"/>
+ <point x="1050" y="226"/>
+ <point x="1050" y="370" type="curve"/>
+ <point x="1050" y="760" type="line"/>
+ <point x="1050" y="919"/>
+ <point x="877" y="1040"/>
+ <point x="615" y="1040" type="curve" smooth="yes"/>
+ <point x="446" y="1040"/>
+ <point x="330" y="994"/>
+ <point x="216" y="950" type="curve"/>
+ <point x="210" y="868"/>
+ <point x="207" y="735"/>
+ <point x="206" y="691" type="curve"/>
+ <point x="323" y="773"/>
+ <point x="424" y="816"/>
+ <point x="530" y="816" type="curve" smooth="yes"/>
+ <point x="680" y="816"/>
+ <point x="770" y="785"/>
+ <point x="770" y="710" type="curve" smooth="yes"/>
+ <point x="770" y="660" type="line"/>
+ <point x="729" y="659"/>
+ <point x="569" y="649"/>
+ <point x="500" y="642" type="curve" smooth="yes"/>
+ <point x="191" y="612"/>
+ <point x="100" y="438"/>
+ <point x="100" y="285" type="curve" smooth="yes"/>
+ <point x="100" y="121"/>
+ <point x="245" y="-25"/>
+ <point x="445" y="-25" type="curve" smooth="yes"/>
+ <point x="562" y="-25"/>
+ <point x="688" y="23"/>
+ <point x="800" y="135" type="curve"/>
+ <point x="814" y="79"/>
+ <point x="838" y="28"/>
+ <point x="850" y="0" type="curve"/>
+ </contour>
+ <contour>
+ <point x="770" y="355" type="line"/>
+ <point x="674" y="225"/>
+ <point x="600" y="205"/>
+ <point x="518" y="205" type="curve" smooth="yes"/>
+ <point x="436" y="205"/>
+ <point x="380" y="256"/>
+ <point x="380" y="320" type="curve" smooth="yes"/>
+ <point x="380" y="386"/>
+ <point x="422" y="442"/>
+ <point x="560" y="457" type="curve" smooth="yes"/>
+ <point x="611" y="463"/>
+ <point x="730" y="474"/>
+ <point x="770" y="475" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfrenameglyphs.ufo/glyphs/L_tnS_mA_A_cute.glif b/tests/reference/ufo/psfrenameglyphs.ufo/glyphs/L_tnS_mA_A_cute.glif
new file mode 100644
index 0000000..f1c66a5
--- /dev/null
+++ b/tests/reference/ufo/psfrenameglyphs.ufo/glyphs/L_tnS_mA_A_cute.glif
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmAAcute" format="2">
+ <advance width="1205"/>
+ <unicode hex="00E1"/>
+ <anchor x="985" y="0" name="H"/>
+ <anchor x="610" y="-100" name="L"/>
+ <anchor x="1185" y="0" name="O"/>
+ <anchor x="1145" y="1000" name="R"/>
+ <anchor x="550" y="1635" name="U"/>
+ <outline>
+ <component base="LtnSmA"/>
+ <component base="CombAcute" xOffset="1150"/>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfrenameglyphs.ufo/glyphs/L_tnS_mA_C_ircum.glif b/tests/reference/ufo/psfrenameglyphs.ufo/glyphs/L_tnS_mA_C_ircum.glif
new file mode 100644
index 0000000..218d694
--- /dev/null
+++ b/tests/reference/ufo/psfrenameglyphs.ufo/glyphs/L_tnS_mA_C_ircum.glif
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmACircum" format="2">
+ <advance width="1205"/>
+ <unicode hex="00E2"/>
+ <anchor x="985" y="0" name="H"/>
+ <anchor x="610" y="-100" name="L"/>
+ <anchor x="1185" y="0" name="O"/>
+ <anchor x="1145" y="1000" name="R"/>
+ <anchor x="602" y="1635" name="U"/>
+ <outline>
+ <component base="LtnSmA"/>
+ <component base="CombCircum" xOffset="1190"/>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfrenameglyphs.ufo/glyphs/L_tnS_mA_D_iaer.glif b/tests/reference/ufo/psfrenameglyphs.ufo/glyphs/L_tnS_mA_D_iaer.glif
new file mode 100644
index 0000000..bb0ea2c
--- /dev/null
+++ b/tests/reference/ufo/psfrenameglyphs.ufo/glyphs/L_tnS_mA_D_iaer.glif
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmADiaer" format="2">
+ <advance width="1205"/>
+ <unicode hex="00E4"/>
+ <anchor x="985" y="0" name="H"/>
+ <anchor x="610" y="-100" name="L"/>
+ <anchor x="1185" y="0" name="O"/>
+ <anchor x="1145" y="1000" name="R"/>
+ <anchor x="610" y="1585" name="U"/>
+ <outline>
+ <component base="LtnSmA"/>
+ <component base="CombDiaer" xOffset="1190"/>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfrenameglyphs.ufo/glyphs/L_tnS_mA_G_rave.glif b/tests/reference/ufo/psfrenameglyphs.ufo/glyphs/L_tnS_mA_G_rave.glif
new file mode 100644
index 0000000..3153364
--- /dev/null
+++ b/tests/reference/ufo/psfrenameglyphs.ufo/glyphs/L_tnS_mA_G_rave.glif
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmAGrave" format="2">
+ <advance width="1205"/>
+ <unicode hex="00E0"/>
+ <anchor x="985" y="0" name="H"/>
+ <anchor x="610" y="-100" name="L"/>
+ <anchor x="1185" y="0" name="O"/>
+ <anchor x="1145" y="1000" name="R"/>
+ <anchor x="650" y="1635" name="U"/>
+ <outline>
+ <component base="LtnSmA"/>
+ <component base="CombGrave" xOffset="1240"/>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfrenameglyphs.ufo/glyphs/L_tnS_mA_R_ingA_bv.glif b/tests/reference/ufo/psfrenameglyphs.ufo/glyphs/L_tnS_mA_R_ingA_bv.glif
new file mode 100644
index 0000000..3b8da5a
--- /dev/null
+++ b/tests/reference/ufo/psfrenameglyphs.ufo/glyphs/L_tnS_mA_R_ingA_bv.glif
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmARingAbv" format="2">
+ <advance width="1205"/>
+ <unicode hex="00E5"/>
+ <anchor x="985" y="0" name="H"/>
+ <anchor x="610" y="-100" name="L"/>
+ <anchor x="1185" y="0" name="O"/>
+ <anchor x="1145" y="1000" name="R"/>
+ <anchor x="612" y="1635" name="U"/>
+ <outline>
+ <component base="LtnSmA"/>
+ <component base="CombRingAbv" xOffset="1182"/>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfrenameglyphs.ufo/glyphs/L_tnS_mA_T_ilde.glif b/tests/reference/ufo/psfrenameglyphs.ufo/glyphs/L_tnS_mA_T_ilde.glif
new file mode 100644
index 0000000..b3a8515
--- /dev/null
+++ b/tests/reference/ufo/psfrenameglyphs.ufo/glyphs/L_tnS_mA_T_ilde.glif
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmATilde" format="2">
+ <advance width="1205"/>
+ <unicode hex="00E3"/>
+ <anchor x="985" y="0" name="H"/>
+ <anchor x="610" y="-100" name="L"/>
+ <anchor x="1185" y="0" name="O"/>
+ <anchor x="1145" y="1000" name="R"/>
+ <anchor x="610" y="1490" name="U"/>
+ <outline>
+ <component base="LtnSmA"/>
+ <component base="CombTilde" xOffset="1190"/>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfrenameglyphs.ufo/glyphs/L_tnS_mB_.glif b/tests/reference/ufo/psfrenameglyphs.ufo/glyphs/L_tnS_mB_.glif
new file mode 100644
index 0000000..6cc6671
--- /dev/null
+++ b/tests/reference/ufo/psfrenameglyphs.ufo/glyphs/L_tnS_mB_.glif
@@ -0,0 +1,50 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmB" format="2">
+ <advance width="1215"/>
+ <unicode hex="0062"/>
+ <anchor x="610" y="0" name="H"/>
+ <anchor x="610" y="-100" name="L"/>
+ <anchor x="1215" y="1000" name="R"/>
+ <anchor x="610" y="1635" name="U"/>
+ <outline>
+ <contour>
+ <point x="120" y="1600" type="line"/>
+ <point x="135" y="1488"/>
+ <point x="135" y="1273"/>
+ <point x="135" y="1130" type="curve" smooth="yes"/>
+ <point x="135" y="936"/>
+ <point x="135" y="228"/>
+ <point x="135" y="65" type="curve"/>
+ <point x="286" y="26"/>
+ <point x="457" y="-25"/>
+ <point x="650" y="-25" type="curve" smooth="yes"/>
+ <point x="939" y="-25"/>
+ <point x="1125" y="197"/>
+ <point x="1125" y="540" type="curve" smooth="yes"/>
+ <point x="1125" y="832"/>
+ <point x="986" y="1040"/>
+ <point x="789" y="1040" type="curve" smooth="yes"/>
+ <point x="626" y="1040"/>
+ <point x="505" y="956"/>
+ <point x="415" y="845" type="curve"/>
+ <point x="415" y="934"/>
+ <point x="415" y="1600"/>
+ <point x="415" y="1600" type="curve"/>
+ </contour>
+ <contour>
+ <point x="415" y="585" type="line"/>
+ <point x="471" y="709"/>
+ <point x="580" y="795"/>
+ <point x="683" y="795" type="curve" smooth="yes"/>
+ <point x="793" y="795"/>
+ <point x="855" y="684"/>
+ <point x="855" y="505" type="curve" smooth="yes"/>
+ <point x="855" y="317"/>
+ <point x="750" y="190"/>
+ <point x="605" y="190" type="curve" smooth="yes"/>
+ <point x="538" y="190"/>
+ <point x="492" y="204"/>
+ <point x="415" y="240" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfrenameglyphs.ufo/glyphs/L_tnS_mC_.glif b/tests/reference/ufo/psfrenameglyphs.ufo/glyphs/L_tnS_mC_.glif
new file mode 100644
index 0000000..19a8a6d
--- /dev/null
+++ b/tests/reference/ufo/psfrenameglyphs.ufo/glyphs/L_tnS_mC_.glif
@@ -0,0 +1,39 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmC" format="2">
+ <advance width="1022"/>
+ <unicode hex="0063"/>
+ <anchor x="555" y="0" name="H"/>
+ <anchor x="575" y="-100" name="L"/>
+ <anchor x="1020" y="1000" name="R"/>
+ <anchor x="575" y="1100" name="U"/>
+ <outline>
+ <contour>
+ <point x="922" y="969" type="line"/>
+ <point x="849" y="1007"/>
+ <point x="744" y="1040"/>
+ <point x="612" y="1040" type="curve" smooth="yes"/>
+ <point x="295" y="1040"/>
+ <point x="90" y="802"/>
+ <point x="90" y="490" type="curve" smooth="yes"/>
+ <point x="90" y="161"/>
+ <point x="309" y="-25"/>
+ <point x="578" y="-25" type="curve" smooth="yes"/>
+ <point x="727" y="-25"/>
+ <point x="831" y="8"/>
+ <point x="932" y="70" type="curve"/>
+ <point x="902" y="314" type="line"/>
+ <point x="815" y="245"/>
+ <point x="737" y="205"/>
+ <point x="617" y="205" type="curve" smooth="yes"/>
+ <point x="467" y="205"/>
+ <point x="370" y="324"/>
+ <point x="370" y="500" type="curve" smooth="yes"/>
+ <point x="370" y="694"/>
+ <point x="478" y="810"/>
+ <point x="617" y="810" type="curve" smooth="yes"/>
+ <point x="720" y="810"/>
+ <point x="788" y="779"/>
+ <point x="878" y="717" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfrenameglyphs.ufo/glyphs/L_tnS_mD_.glif b/tests/reference/ufo/psfrenameglyphs.ufo/glyphs/L_tnS_mD_.glif
new file mode 100644
index 0000000..fc1cc76
--- /dev/null
+++ b/tests/reference/ufo/psfrenameglyphs.ufo/glyphs/L_tnS_mD_.glif
@@ -0,0 +1,53 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmD" format="2">
+ <advance width="1265"/>
+ <unicode hex="0064"/>
+ <anchor x="595" y="0" name="H"/>
+ <anchor x="595" y="-100" name="L"/>
+ <anchor x="1285" y="1000" name="R"/>
+ <anchor x="610" y="1635" name="U"/>
+ <outline>
+ <contour>
+ <point x="1115" y="1600" type="line"/>
+ <point x="810" y="1600" type="line"/>
+ <point x="829" y="1516"/>
+ <point x="835" y="1395"/>
+ <point x="835" y="1235" type="curve" smooth="yes"/>
+ <point x="835" y="955" type="line"/>
+ <point x="763" y="999"/>
+ <point x="669" y="1040"/>
+ <point x="590" y="1040" type="curve" smooth="yes"/>
+ <point x="319" y="1040"/>
+ <point x="100" y="814"/>
+ <point x="100" y="460" type="curve" smooth="yes"/>
+ <point x="100" y="167"/>
+ <point x="268" y="-25"/>
+ <point x="515" y="-25" type="curve" smooth="yes"/>
+ <point x="654" y="-25"/>
+ <point x="770" y="47"/>
+ <point x="860" y="175" type="curve"/>
+ <point x="877" y="105"/>
+ <point x="900" y="32"/>
+ <point x="915" y="0" type="curve"/>
+ <point x="1190" y="0" type="line"/>
+ <point x="1147" y="112"/>
+ <point x="1115" y="278"/>
+ <point x="1115" y="530" type="curve" smooth="yes"/>
+ </contour>
+ <contour>
+ <point x="835" y="400" type="line"/>
+ <point x="787" y="300"/>
+ <point x="676" y="200"/>
+ <point x="570" y="200" type="curve" smooth="yes"/>
+ <point x="443" y="200"/>
+ <point x="380" y="300"/>
+ <point x="380" y="490" type="curve" smooth="yes"/>
+ <point x="380" y="685"/>
+ <point x="485" y="800"/>
+ <point x="590" y="800" type="curve" smooth="yes"/>
+ <point x="683" y="800"/>
+ <point x="743" y="783"/>
+ <point x="835" y="738" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfrenameglyphs.ufo/glyphs/L_tnS_mE_.glif b/tests/reference/ufo/psfrenameglyphs.ufo/glyphs/L_tnS_mE_.glif
new file mode 100644
index 0000000..5c67455
--- /dev/null
+++ b/tests/reference/ufo/psfrenameglyphs.ufo/glyphs/L_tnS_mE_.glif
@@ -0,0 +1,45 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmE" format="2">
+ <advance width="1110"/>
+ <unicode hex="0065"/>
+ <anchor x="569" y="0" name="H"/>
+ <anchor x="589" y="-100" name="L"/>
+ <anchor x="900" y="0" name="O"/>
+ <anchor x="1130" y="1000" name="R"/>
+ <anchor x="537" y="1100" name="U"/>
+ <outline>
+ <contour>
+ <point x="1010" y="450" type="line"/>
+ <point x="1010" y="469"/>
+ <point x="1009" y="513"/>
+ <point x="1009" y="532" type="curve" smooth="yes"/>
+ <point x="1009" y="782"/>
+ <point x="924" y="1040"/>
+ <point x="589" y="1040" type="curve" smooth="yes"/>
+ <point x="281" y="1040"/>
+ <point x="90" y="826"/>
+ <point x="90" y="495" type="curve" smooth="yes"/>
+ <point x="90" y="155"/>
+ <point x="324" y="-25"/>
+ <point x="589" y="-25" type="curve" smooth="yes"/>
+ <point x="745" y="-25"/>
+ <point x="871" y="2"/>
+ <point x="1015" y="75" type="curve"/>
+ <point x="994" y="306" type="line"/>
+ <point x="870" y="232"/>
+ <point x="745" y="205"/>
+ <point x="614" y="205" type="curve" smooth="yes"/>
+ <point x="448" y="205"/>
+ <point x="362" y="293"/>
+ <point x="362" y="505" type="curve" smooth="yes"/>
+ <point x="362" y="739"/>
+ <point x="431" y="830"/>
+ <point x="575" y="830" type="curve" smooth="yes"/>
+ <point x="693" y="830"/>
+ <point x="755" y="770"/>
+ <point x="755" y="630" type="curve"/>
+ <point x="242" y="630" type="line"/>
+ <point x="242" y="450" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfrenameglyphs.ufo/glyphs/L_tnS_mF_.glif b/tests/reference/ufo/psfrenameglyphs.ufo/glyphs/L_tnS_mF_.glif
new file mode 100644
index 0000000..8a5996d
--- /dev/null
+++ b/tests/reference/ufo/psfrenameglyphs.ufo/glyphs/L_tnS_mF_.glif
@@ -0,0 +1,39 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmF" format="2">
+ <advance width="800"/>
+ <unicode hex="0066"/>
+ <anchor x="380" y="0" name="H"/>
+ <anchor x="400" y="-100" name="L"/>
+ <anchor x="600" y="1635" name="U"/>
+ <outline>
+ <contour>
+ <point x="30" y="805" type="line"/>
+ <point x="230" y="805" type="line"/>
+ <point x="230" y="0" type="line"/>
+ <point x="540" y="0" type="line"/>
+ <point x="518" y="105"/>
+ <point x="510" y="300"/>
+ <point x="510" y="494" type="curve" smooth="yes"/>
+ <point x="510" y="805" type="line"/>
+ <point x="765" y="805" type="line"/>
+ <point x="765" y="1005" type="line"/>
+ <point x="510" y="1005" type="line"/>
+ <point x="510" y="1159" type="line" smooth="yes"/>
+ <point x="510" y="1322"/>
+ <point x="552" y="1387"/>
+ <point x="648" y="1387" type="curve" smooth="yes"/>
+ <point x="697" y="1387"/>
+ <point x="765" y="1362"/>
+ <point x="808" y="1322" type="curve"/>
+ <point x="865" y="1550" type="line"/>
+ <point x="806" y="1588"/>
+ <point x="699" y="1620"/>
+ <point x="625" y="1620" type="curve" smooth="yes"/>
+ <point x="378" y="1620"/>
+ <point x="230" y="1470"/>
+ <point x="230" y="1170" type="curve" smooth="yes"/>
+ <point x="230" y="1005" type="line"/>
+ <point x="30" y="1005" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfrenameglyphs.ufo/glyphs/L_tnS_mG_.glif b/tests/reference/ufo/psfrenameglyphs.ufo/glyphs/L_tnS_mG_.glif
new file mode 100644
index 0000000..871e4e9
--- /dev/null
+++ b/tests/reference/ufo/psfrenameglyphs.ufo/glyphs/L_tnS_mG_.glif
@@ -0,0 +1,91 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmG" format="2">
+ <advance width="1170"/>
+ <unicode hex="0067"/>
+ <anchor x="597" y="-465" name="H"/>
+ <anchor x="597" y="-535" name="L"/>
+ <anchor x="1187" y="1000" name="R"/>
+ <anchor x="567" y="1100" name="U"/>
+ <outline>
+ <contour>
+ <point x="352" y="395" type="line"/>
+ <point x="256" y="357"/>
+ <point x="202" y="275"/>
+ <point x="202" y="215" type="curve" smooth="yes"/>
+ <point x="202" y="113"/>
+ <point x="280" y="12"/>
+ <point x="547" y="-23" type="curve" smooth="yes"/>
+ <point x="797" y="-50"/>
+ <point x="870" y="-99"/>
+ <point x="870" y="-170" type="curve" smooth="yes"/>
+ <point x="870" y="-229"/>
+ <point x="748" y="-302"/>
+ <point x="602" y="-302" type="curve" smooth="yes"/>
+ <point x="418" y="-302"/>
+ <point x="330" y="-235"/>
+ <point x="330" y="-180" type="curve" smooth="yes"/>
+ <point x="330" y="-121"/>
+ <point x="357" y="-56"/>
+ <point x="562" y="20" type="curve"/>
+ <point x="554" y="49"/>
+ <point x="322" y="75"/>
+ <point x="322" y="75" type="curve"/>
+ <point x="138" y="2"/>
+ <point x="50" y="-89"/>
+ <point x="50" y="-200" type="curve" smooth="yes"/>
+ <point x="50" y="-409"/>
+ <point x="341" y="-505"/>
+ <point x="587" y="-505" type="curve" smooth="yes"/>
+ <point x="843" y="-505"/>
+ <point x="1150" y="-375"/>
+ <point x="1150" y="-160" type="curve" smooth="yes"/>
+ <point x="1150" y="13"/>
+ <point x="1049" y="125"/>
+ <point x="752" y="165" type="curve" smooth="yes"/>
+ <point x="497" y="191"/>
+ <point x="433" y="216"/>
+ <point x="433" y="255" type="curve" smooth="yes"/>
+ <point x="433" y="285"/>
+ <point x="472" y="322"/>
+ <point x="588" y="350" type="curve"/>
+ </contour>
+ <contour>
+ <point x="1102" y="1040" type="line"/>
+ <point x="1003" y="1033"/>
+ <point x="871" y="997"/>
+ <point x="782" y="940" type="curve"/>
+ <point x="847" y="770" type="line"/>
+ <point x="939" y="808"/>
+ <point x="1019" y="823"/>
+ <point x="1092" y="825" type="curve"/>
+ </contour>
+ <contour>
+ <point x="122" y="670" type="curve" smooth="yes"/>
+ <point x="122" y="455"/>
+ <point x="316" y="305"/>
+ <point x="567" y="305" type="curve" smooth="yes"/>
+ <point x="820" y="305"/>
+ <point x="1012" y="465"/>
+ <point x="1012" y="680" type="curve" smooth="yes"/>
+ <point x="1012" y="884"/>
+ <point x="820" y="1040"/>
+ <point x="567" y="1040" type="curve" smooth="yes"/>
+ <point x="316" y="1040"/>
+ <point x="122" y="874"/>
+ </contour>
+ <contour>
+ <point x="377" y="680" type="curve" smooth="yes"/>
+ <point x="377" y="770"/>
+ <point x="457" y="847"/>
+ <point x="567" y="847" type="curve" smooth="yes"/>
+ <point x="678" y="847"/>
+ <point x="757" y="770"/>
+ <point x="757" y="680" type="curve" smooth="yes"/>
+ <point x="757" y="578"/>
+ <point x="678" y="501"/>
+ <point x="567" y="501" type="curve" smooth="yes"/>
+ <point x="457" y="501"/>
+ <point x="377" y="578"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfrenameglyphs.ufo/glyphs/L_tnS_mH_.glif b/tests/reference/ufo/psfrenameglyphs.ufo/glyphs/L_tnS_mH_.glif
new file mode 100644
index 0000000..15fc451
--- /dev/null
+++ b/tests/reference/ufo/psfrenameglyphs.ufo/glyphs/L_tnS_mH_.glif
@@ -0,0 +1,43 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmH" format="2">
+ <advance width="1235"/>
+ <unicode hex="0068"/>
+ <anchor x="280" y="0" name="H"/>
+ <anchor x="620" y="-100" name="L"/>
+ <anchor x="620" y="1635" name="U"/>
+ <outline>
+ <contour>
+ <point x="415" y="580" type="line"/>
+ <point x="450" y="683"/>
+ <point x="560" y="795"/>
+ <point x="675" y="795" type="curve" smooth="yes"/>
+ <point x="782" y="795"/>
+ <point x="830" y="744"/>
+ <point x="830" y="550" type="curve" smooth="yes"/>
+ <point x="830" y="413"/>
+ <point x="830" y="0"/>
+ <point x="830" y="0" type="curve"/>
+ <point x="1110" y="0" type="line"/>
+ <point x="1110" y="0"/>
+ <point x="1110" y="459"/>
+ <point x="1110" y="625" type="curve" smooth="yes"/>
+ <point x="1110" y="900"/>
+ <point x="1008" y="1040"/>
+ <point x="805" y="1040" type="curve" smooth="yes"/>
+ <point x="662" y="1040"/>
+ <point x="513" y="976"/>
+ <point x="415" y="850" type="curve"/>
+ <point x="415" y="894"/>
+ <point x="415" y="1600"/>
+ <point x="415" y="1600" type="curve"/>
+ <point x="120" y="1600" type="line"/>
+ <point x="135" y="1514"/>
+ <point x="135" y="1345"/>
+ <point x="135" y="1130" type="curve" smooth="yes"/>
+ <point x="135" y="935"/>
+ <point x="135" y="0"/>
+ <point x="135" y="0" type="curve"/>
+ <point x="415" y="0" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfrenameglyphs.ufo/glyphs/L_tnS_mI_.glif b/tests/reference/ufo/psfrenameglyphs.ufo/glyphs/L_tnS_mI_.glif
new file mode 100644
index 0000000..05022d4
--- /dev/null
+++ b/tests/reference/ufo/psfrenameglyphs.ufo/glyphs/L_tnS_mI_.glif
@@ -0,0 +1,42 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmI" format="2">
+ <advance width="640"/>
+ <unicode hex="0069"/>
+ <anchor x="320" y="0" name="H"/>
+ <anchor x="320" y="-100" name="L"/>
+ <anchor x="580" y="0" name="O"/>
+ <anchor x="640" y="1000" name="R"/>
+ <anchor x="320" y="1100" name="U"/>
+ <outline>
+ <contour>
+ <point x="165" y="1020" type="line"/>
+ <point x="178" y="915"/>
+ <point x="180" y="725"/>
+ <point x="180" y="530" type="curve" smooth="yes"/>
+ <point x="180" y="336"/>
+ <point x="180" y="0"/>
+ <point x="180" y="0" type="curve"/>
+ <point x="480" y="0" type="line"/>
+ <point x="467" y="107"/>
+ <point x="460" y="346"/>
+ <point x="460" y="475" type="curve" smooth="yes"/>
+ <point x="460" y="558"/>
+ <point x="460" y="1020"/>
+ <point x="460" y="1020" type="curve"/>
+ </contour>
+ <contour>
+ <point x="145" y="1385" type="curve" smooth="yes"/>
+ <point x="145" y="1281"/>
+ <point x="219" y="1210"/>
+ <point x="320" y="1210" type="curve" smooth="yes"/>
+ <point x="422" y="1210"/>
+ <point x="495" y="1281"/>
+ <point x="495" y="1385" type="curve" smooth="yes"/>
+ <point x="495" y="1487"/>
+ <point x="422" y="1560"/>
+ <point x="320" y="1560" type="curve" smooth="yes"/>
+ <point x="219" y="1560"/>
+ <point x="145" y="1487"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfrenameglyphs.ufo/glyphs/L_tnS_mJ_.glif b/tests/reference/ufo/psfrenameglyphs.ufo/glyphs/L_tnS_mJ_.glif
new file mode 100644
index 0000000..6e044af
--- /dev/null
+++ b/tests/reference/ufo/psfrenameglyphs.ufo/glyphs/L_tnS_mJ_.glif
@@ -0,0 +1,44 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmJ" format="2">
+ <advance width="670"/>
+ <unicode hex="006A"/>
+ <anchor x="140" y="-500" name="L"/>
+ <anchor x="355" y="1100" name="U"/>
+ <outline>
+ <contour>
+ <point x="185" y="1385" type="curve" smooth="yes"/>
+ <point x="185" y="1281"/>
+ <point x="259" y="1210"/>
+ <point x="360" y="1210" type="curve" smooth="yes"/>
+ <point x="462" y="1210"/>
+ <point x="535" y="1281"/>
+ <point x="535" y="1385" type="curve" smooth="yes"/>
+ <point x="535" y="1487"/>
+ <point x="462" y="1560"/>
+ <point x="360" y="1560" type="curve" smooth="yes"/>
+ <point x="259" y="1560"/>
+ <point x="185" y="1487"/>
+ </contour>
+ <contour>
+ <point x="500" y="1020" type="line"/>
+ <point x="205" y="1020" type="line"/>
+ <point x="218" y="915"/>
+ <point x="220" y="725"/>
+ <point x="220" y="530" type="curve"/>
+ <point x="220" y="20" type="line"/>
+ <point x="220" y="-150"/>
+ <point x="165" y="-232"/>
+ <point x="48" y="-232" type="curve" smooth="yes"/>
+ <point x="-20" y="-232"/>
+ <point x="-101" y="-195"/>
+ <point x="-145" y="-152" type="curve"/>
+ <point x="-190" y="-389" type="line"/>
+ <point x="-148" y="-421"/>
+ <point x="-37" y="-470"/>
+ <point x="56" y="-470" type="curve" smooth="yes"/>
+ <point x="306" y="-470"/>
+ <point x="500" y="-348"/>
+ <point x="500" y="25" type="curve" smooth="yes"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfrenameglyphs.ufo/glyphs/L_tnS_mK_.glif b/tests/reference/ufo/psfrenameglyphs.ufo/glyphs/L_tnS_mK_.glif
new file mode 100644
index 0000000..529f7dd
--- /dev/null
+++ b/tests/reference/ufo/psfrenameglyphs.ufo/glyphs/L_tnS_mK_.glif
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmK" format="2">
+ <advance width="1138"/>
+ <unicode hex="006B"/>
+ <anchor x="940" y="0" name="H"/>
+ <anchor x="585" y="-100" name="L"/>
+ <anchor x="1140" y="1000" name="R"/>
+ <anchor x="595" y="1635" name="U"/>
+ <outline>
+ <contour>
+ <point x="415" y="0" type="line"/>
+ <point x="415" y="1600" type="line"/>
+ <point x="120" y="1600" type="line"/>
+ <point x="135" y="1514"/>
+ <point x="135" y="1345"/>
+ <point x="135" y="1130" type="curve" smooth="yes"/>
+ <point x="135" y="934"/>
+ <point x="135" y="0"/>
+ <point x="135" y="0" type="curve"/>
+ </contour>
+ <contour>
+ <point x="723" y="1020" type="line"/>
+ <point x="353" y="570" type="line"/>
+ <point x="572" y="528" type="line"/>
+ <point x="1098" y="1020" type="line"/>
+ </contour>
+ <contour>
+ <point x="350" y="570" type="line"/>
+ <point x="761" y="0" type="line"/>
+ <point x="1128" y="0" type="line"/>
+ <point x="540" y="664" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfrenameglyphs.ufo/glyphs/L_tnS_mL_.glif b/tests/reference/ufo/psfrenameglyphs.ufo/glyphs/L_tnS_mL_.glif
new file mode 100644
index 0000000..0b21294
--- /dev/null
+++ b/tests/reference/ufo/psfrenameglyphs.ufo/glyphs/L_tnS_mL_.glif
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmL" format="2">
+ <advance width="640"/>
+ <unicode hex="006C"/>
+ <anchor x="335" y="0" name="H"/>
+ <anchor x="335" y="-100" name="L"/>
+ <anchor x="660" y="1000" name="R"/>
+ <anchor x="320" y="1635" name="U"/>
+ <outline>
+ <contour>
+ <point x="460" y="1600" type="line"/>
+ <point x="160" y="1600" type="line"/>
+ <point x="173" y="1485"/>
+ <point x="180" y="1324"/>
+ <point x="180" y="1130" type="curve" smooth="yes"/>
+ <point x="180" y="0" type="line"/>
+ <point x="480" y="0" type="line"/>
+ <point x="467" y="109"/>
+ <point x="460" y="346"/>
+ <point x="460" y="475" type="curve" smooth="yes"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfrenameglyphs.ufo/glyphs/L_tnS_mM_.glif b/tests/reference/ufo/psfrenameglyphs.ufo/glyphs/L_tnS_mM_.glif
new file mode 100644
index 0000000..eace489
--- /dev/null
+++ b/tests/reference/ufo/psfrenameglyphs.ufo/glyphs/L_tnS_mM_.glif
@@ -0,0 +1,52 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmM" format="2">
+ <advance width="1760"/>
+ <unicode hex="006D"/>
+ <anchor x="890" y="0" name="H"/>
+ <anchor x="890" y="-100" name="L"/>
+ <anchor x="890" y="1100" name="U"/>
+ <outline>
+ <contour>
+ <point x="115" y="1020" type="line"/>
+ <point x="136" y="951"/>
+ <point x="165" y="811"/>
+ <point x="165" y="615" type="curve" smooth="yes"/>
+ <point x="165" y="0" type="line"/>
+ <point x="445" y="0" type="line"/>
+ <point x="445" y="640" type="line"/>
+ <point x="484" y="731"/>
+ <point x="560" y="795"/>
+ <point x="635" y="795" type="curve" smooth="yes"/>
+ <point x="723" y="795"/>
+ <point x="750" y="759"/>
+ <point x="750" y="570" type="curve" smooth="yes"/>
+ <point x="750" y="0" type="line"/>
+ <point x="1030" y="0" type="line"/>
+ <point x="1030" y="660" type="line"/>
+ <point x="1073" y="742"/>
+ <point x="1147" y="795"/>
+ <point x="1220" y="795" type="curve" smooth="yes"/>
+ <point x="1310" y="795"/>
+ <point x="1335" y="751"/>
+ <point x="1335" y="550" type="curve" smooth="yes"/>
+ <point x="1335" y="0" type="line"/>
+ <point x="1615" y="0" type="line"/>
+ <point x="1615" y="660" type="line" smooth="yes"/>
+ <point x="1615" y="907"/>
+ <point x="1548" y="1040"/>
+ <point x="1345" y="1040" type="curve" smooth="yes"/>
+ <point x="1240" y="1040"/>
+ <point x="1131" y="1007"/>
+ <point x="1006" y="872" type="curve"/>
+ <point x="973" y="960"/>
+ <point x="891" y="1040"/>
+ <point x="760" y="1040" type="curve" smooth="yes"/>
+ <point x="644" y="1040"/>
+ <point x="544" y="1008"/>
+ <point x="422" y="875" type="curve"/>
+ <point x="412" y="920"/>
+ <point x="397" y="981"/>
+ <point x="375" y="1020" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfrenameglyphs.ufo/glyphs/L_tnS_mN_.glif b/tests/reference/ufo/psfrenameglyphs.ufo/glyphs/L_tnS_mN_.glif
new file mode 100644
index 0000000..f7abb6f
--- /dev/null
+++ b/tests/reference/ufo/psfrenameglyphs.ufo/glyphs/L_tnS_mN_.glif
@@ -0,0 +1,43 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmN" format="2">
+ <advance width="1245"/>
+ <unicode hex="006E"/>
+ <anchor x="620" y="0" name="H"/>
+ <anchor x="620" y="-100" name="L"/>
+ <anchor x="620" y="1100" name="U"/>
+ <outline>
+ <contour>
+ <point x="1120" y="0" type="line"/>
+ <point x="1120" y="0"/>
+ <point x="1120" y="459"/>
+ <point x="1120" y="625" type="curve" smooth="yes"/>
+ <point x="1120" y="900"/>
+ <point x="998" y="1040"/>
+ <point x="795" y="1040" type="curve" smooth="yes"/>
+ <point x="654" y="1040"/>
+ <point x="537" y="980"/>
+ <point x="410" y="835" type="curve"/>
+ <point x="403" y="881"/>
+ <point x="385" y="980"/>
+ <point x="370" y="1020" type="curve"/>
+ <point x="95" y="1020" type="line"/>
+ <point x="117" y="951"/>
+ <point x="145" y="811"/>
+ <point x="145" y="615" type="curve" smooth="yes"/>
+ <point x="145" y="420"/>
+ <point x="145" y="0"/>
+ <point x="145" y="0" type="curve"/>
+ <point x="425" y="0" type="line"/>
+ <point x="425" y="580" type="line"/>
+ <point x="460" y="683"/>
+ <point x="570" y="795"/>
+ <point x="685" y="795" type="curve" smooth="yes"/>
+ <point x="792" y="795"/>
+ <point x="840" y="734"/>
+ <point x="840" y="550" type="curve" smooth="yes"/>
+ <point x="840" y="413"/>
+ <point x="840" y="0"/>
+ <point x="840" y="0" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfrenameglyphs.ufo/glyphs/L_tnS_mO_.glif b/tests/reference/ufo/psfrenameglyphs.ufo/glyphs/L_tnS_mO_.glif
new file mode 100644
index 0000000..063c297
--- /dev/null
+++ b/tests/reference/ufo/psfrenameglyphs.ufo/glyphs/L_tnS_mO_.glif
@@ -0,0 +1,40 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmO" format="2">
+ <advance width="1160"/>
+ <unicode hex="006F"/>
+ <anchor x="578" y="0" name="H"/>
+ <anchor x="580" y="-100" name="L"/>
+ <anchor x="790" y="0" name="O"/>
+ <anchor x="1160" y="1000" name="R"/>
+ <anchor x="580" y="1100" name="U"/>
+ <outline>
+ <contour>
+ <point x="90" y="507" type="curve" smooth="yes"/>
+ <point x="90" y="163"/>
+ <point x="288" y="-25"/>
+ <point x="570" y="-25" type="curve" smooth="yes"/>
+ <point x="840" y="-25"/>
+ <point x="1070" y="163"/>
+ <point x="1070" y="507" type="curve" smooth="yes"/>
+ <point x="1070" y="851"/>
+ <point x="873" y="1040"/>
+ <point x="590" y="1040" type="curve" smooth="yes"/>
+ <point x="320" y="1040"/>
+ <point x="90" y="851"/>
+ </contour>
+ <contour>
+ <point x="370" y="507" type="curve" smooth="yes"/>
+ <point x="370" y="699"/>
+ <point x="451" y="815"/>
+ <point x="580" y="815" type="curve" smooth="yes"/>
+ <point x="717" y="815"/>
+ <point x="790" y="699"/>
+ <point x="790" y="507" type="curve" smooth="yes"/>
+ <point x="790" y="316"/>
+ <point x="709" y="200"/>
+ <point x="580" y="200" type="curve" smooth="yes"/>
+ <point x="443" y="200"/>
+ <point x="370" y="316"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfrenameglyphs.ufo/glyphs/L_tnS_mP_.glif b/tests/reference/ufo/psfrenameglyphs.ufo/glyphs/L_tnS_mP_.glif
new file mode 100644
index 0000000..4fe224b
--- /dev/null
+++ b/tests/reference/ufo/psfrenameglyphs.ufo/glyphs/L_tnS_mP_.glif
@@ -0,0 +1,59 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmP" format="2">
+ <advance width="1235"/>
+ <unicode hex="0070"/>
+ <anchor x="290" y="-435" name="H"/>
+ <anchor x="640" y="-500" name="L"/>
+ <anchor x="1235" y="1000" name="R"/>
+ <anchor x="640" y="1100" name="U"/>
+ <outline>
+ <contour>
+ <point x="450" y="-490" type="line"/>
+ <point x="433" y="-405"/>
+ <point x="425" y="-310"/>
+ <point x="425" y="-150" type="curve" smooth="yes"/>
+ <point x="425" y="-71"/>
+ <point x="425" y="-41"/>
+ <point x="425" y="65" type="curve"/>
+ <point x="518" y="10"/>
+ <point x="594" y="-25"/>
+ <point x="699" y="-25" type="curve" smooth="yes"/>
+ <point x="945" y="-25"/>
+ <point x="1145" y="193"/>
+ <point x="1145" y="535" type="curve" smooth="yes"/>
+ <point x="1145" y="828"/>
+ <point x="996" y="1040"/>
+ <point x="773" y="1040" type="curve" smooth="yes"/>
+ <point x="628" y="1040"/>
+ <point x="502" y="962"/>
+ <point x="410" y="850" type="curve"/>
+ <point x="401" y="932"/>
+ <point x="385" y="990"/>
+ <point x="370" y="1020" type="curve"/>
+ <point x="95" y="1020" type="line"/>
+ <point x="140" y="907"/>
+ <point x="145" y="734"/>
+ <point x="145" y="485" type="curve" smooth="yes"/>
+ <point x="145" y="291"/>
+ <point x="145" y="-345"/>
+ <point x="145" y="-490" type="curve"/>
+ </contour>
+ <contour>
+ <point x="633" y="206" type="curve" smooth="yes"/>
+ <point x="564" y="206"/>
+ <point x="527" y="225"/>
+ <point x="425" y="300" type="curve"/>
+ <point x="425" y="390"/>
+ <point x="425" y="507"/>
+ <point x="425" y="585" type="curve"/>
+ <point x="482" y="726"/>
+ <point x="583" y="802"/>
+ <point x="672" y="802" type="curve" smooth="yes"/>
+ <point x="793" y="802"/>
+ <point x="865" y="686"/>
+ <point x="865" y="505" type="curve" smooth="yes"/>
+ <point x="865" y="320"/>
+ <point x="755" y="206"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfrenameglyphs.ufo/glyphs/L_tnS_mQ_.glif b/tests/reference/ufo/psfrenameglyphs.ufo/glyphs/L_tnS_mQ_.glif
new file mode 100644
index 0000000..9727ad7
--- /dev/null
+++ b/tests/reference/ufo/psfrenameglyphs.ufo/glyphs/L_tnS_mQ_.glif
@@ -0,0 +1,47 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmQ" format="2">
+ <advance width="1210"/>
+ <unicode hex="0071"/>
+ <anchor x="600" y="-500" name="L"/>
+ <anchor x="1210" y="1000" name="R"/>
+ <anchor x="600" y="1100" name="U"/>
+ <outline>
+ <contour>
+ <point x="790" y="-490" type="line"/>
+ <point x="1095" y="-490" type="line"/>
+ <point x="1078" y="-405"/>
+ <point x="1070" y="-310"/>
+ <point x="1070" y="-150" type="curve" smooth="yes"/>
+ <point x="1070" y="-26"/>
+ <point x="1070" y="965"/>
+ <point x="1070" y="965" type="curve"/>
+ <point x="934" y="1001"/>
+ <point x="773" y="1040"/>
+ <point x="620" y="1040" type="curve" smooth="yes"/>
+ <point x="255" y="1040"/>
+ <point x="100" y="742"/>
+ <point x="100" y="435" type="curve" smooth="yes"/>
+ <point x="100" y="117"/>
+ <point x="316" y="-25"/>
+ <point x="500" y="-25" type="curve" smooth="yes"/>
+ <point x="593" y="-25"/>
+ <point x="686" y="14"/>
+ <point x="790" y="120" type="curve"/>
+ </contour>
+ <contour>
+ <point x="790" y="368" type="line"/>
+ <point x="727" y="258"/>
+ <point x="650" y="203"/>
+ <point x="580" y="203" type="curve" smooth="yes"/>
+ <point x="475" y="203"/>
+ <point x="380" y="287"/>
+ <point x="380" y="485" type="curve" smooth="yes"/>
+ <point x="380" y="641"/>
+ <point x="456" y="802"/>
+ <point x="655" y="802" type="curve" smooth="yes"/>
+ <point x="696" y="802"/>
+ <point x="749" y="789"/>
+ <point x="790" y="770" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfrenameglyphs.ufo/glyphs/L_tnS_mR_.glif b/tests/reference/ufo/psfrenameglyphs.ufo/glyphs/L_tnS_mR_.glif
new file mode 100644
index 0000000..8a81116
--- /dev/null
+++ b/tests/reference/ufo/psfrenameglyphs.ufo/glyphs/L_tnS_mR_.glif
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmR" format="2">
+ <advance width="995"/>
+ <unicode hex="0072"/>
+ <anchor x="285" y="0" name="H"/>
+ <anchor x="275" y="-100" name="L"/>
+ <anchor x="550" y="1100" name="U"/>
+ <outline>
+ <contour>
+ <point x="425" y="0" type="line"/>
+ <point x="425" y="530" type="line"/>
+ <point x="460" y="654"/>
+ <point x="570" y="781"/>
+ <point x="637" y="781" type="curve" smooth="yes"/>
+ <point x="722" y="781"/>
+ <point x="755" y="721"/>
+ <point x="762" y="630" type="curve"/>
+ <point x="985" y="665" type="line"/>
+ <point x="985" y="868"/>
+ <point x="913" y="1040"/>
+ <point x="725" y="1040" type="curve" smooth="yes"/>
+ <point x="634" y="1040"/>
+ <point x="507" y="964"/>
+ <point x="410" y="825" type="curve"/>
+ <point x="403" y="873"/>
+ <point x="385" y="978"/>
+ <point x="370" y="1020" type="curve"/>
+ <point x="95" y="1020" type="line"/>
+ <point x="117" y="951"/>
+ <point x="145" y="811"/>
+ <point x="145" y="615" type="curve" smooth="yes"/>
+ <point x="145" y="0" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfrenameglyphs.ufo/glyphs/L_tnS_mS_.glif b/tests/reference/ufo/psfrenameglyphs.ufo/glyphs/L_tnS_mS_.glif
new file mode 100644
index 0000000..06b1a9a
--- /dev/null
+++ b/tests/reference/ufo/psfrenameglyphs.ufo/glyphs/L_tnS_mS_.glif
@@ -0,0 +1,50 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmS" format="2">
+ <advance width="1035"/>
+ <unicode hex="0073"/>
+ <anchor x="515" y="0" name="H"/>
+ <anchor x="515" y="-100" name="L"/>
+ <anchor x="530" y="1100" name="U"/>
+ <outline>
+ <contour>
+ <point x="905" y="960" type="line"/>
+ <point x="827" y="998"/>
+ <point x="708" y="1040"/>
+ <point x="545" y="1040" type="curve" smooth="yes"/>
+ <point x="202" y="1040"/>
+ <point x="110" y="818"/>
+ <point x="110" y="720" type="curve" smooth="yes"/>
+ <point x="110" y="594"/>
+ <point x="171" y="491"/>
+ <point x="455" y="432" type="curve" smooth="yes"/>
+ <point x="646" y="390"/>
+ <point x="690" y="348"/>
+ <point x="690" y="290" type="curve" smooth="yes"/>
+ <point x="690" y="243"/>
+ <point x="624" y="199"/>
+ <point x="530" y="199" type="curve" smooth="yes"/>
+ <point x="413" y="199"/>
+ <point x="254" y="253"/>
+ <point x="155" y="334" type="curve"/>
+ <point x="100" y="90" type="line"/>
+ <point x="187" y="28"/>
+ <point x="346" y="-25"/>
+ <point x="525" y="-25" type="curve" smooth="yes"/>
+ <point x="768" y="-25"/>
+ <point x="960" y="123"/>
+ <point x="960" y="315" type="curve" smooth="yes"/>
+ <point x="960" y="504"/>
+ <point x="788" y="583"/>
+ <point x="580" y="625" type="curve" smooth="yes"/>
+ <point x="405" y="659"/>
+ <point x="380" y="681"/>
+ <point x="380" y="730" type="curve" smooth="yes"/>
+ <point x="380" y="770"/>
+ <point x="418" y="816"/>
+ <point x="535" y="816" type="curve" smooth="yes"/>
+ <point x="674" y="816"/>
+ <point x="791" y="760"/>
+ <point x="866" y="721" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfrenameglyphs.ufo/glyphs/L_tnS_mT_.glif b/tests/reference/ufo/psfrenameglyphs.ufo/glyphs/L_tnS_mT_.glif
new file mode 100644
index 0000000..d4123c7
--- /dev/null
+++ b/tests/reference/ufo/psfrenameglyphs.ufo/glyphs/L_tnS_mT_.glif
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmT" format="2">
+ <advance width="885"/>
+ <unicode hex="0074"/>
+ <anchor x="530" y="0" name="H"/>
+ <anchor x="530" y="-100" name="L"/>
+ <anchor x="885" y="1000" name="R"/>
+ <anchor x="360" y="1360" name="U"/>
+ <outline>
+ <contour>
+ <point x="220" y="270" type="line"/>
+ <point x="220" y="39"/>
+ <point x="374" y="-25"/>
+ <point x="563" y="-25" type="curve" smooth="yes"/>
+ <point x="635" y="-25"/>
+ <point x="725" y="-3"/>
+ <point x="820" y="57" type="curve"/>
+ <point x="820" y="281" type="line"/>
+ <point x="741" y="232"/>
+ <point x="678" y="206"/>
+ <point x="627" y="206" type="curve" smooth="yes"/>
+ <point x="537" y="206"/>
+ <point x="500" y="235"/>
+ <point x="500" y="462" type="curve" smooth="yes"/>
+ <point x="500" y="1320" type="line"/>
+ <point x="220" y="1320" type="line"/>
+ </contour>
+ <contour>
+ <point x="805" y="805" type="line"/>
+ <point x="805" y="1005" type="line"/>
+ <point x="30" y="1005" type="line"/>
+ <point x="30" y="805" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfrenameglyphs.ufo/glyphs/L_tnS_mU_.glif b/tests/reference/ufo/psfrenameglyphs.ufo/glyphs/L_tnS_mU_.glif
new file mode 100644
index 0000000..5b8d434
--- /dev/null
+++ b/tests/reference/ufo/psfrenameglyphs.ufo/glyphs/L_tnS_mU_.glif
@@ -0,0 +1,51 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmU" format="2">
+ <advance width="1245"/>
+ <unicode hex="0075"/>
+ <anchor x="515" y="0" name="H"/>
+ <anchor x="615" y="-100" name="L"/>
+ <anchor x="690" y="0" name="O"/>
+ <anchor x="1258" y="1000" name="R"/>
+ <anchor x="615" y="1100" name="U"/>
+ <outline>
+ <contour>
+ <point x="1160" y="0" type="line"/>
+ <point x="1118" y="112"/>
+ <point x="1095" y="256"/>
+ <point x="1095" y="450" type="curve" smooth="yes"/>
+ <point x="1095" y="646"/>
+ <point x="1095" y="1020"/>
+ <point x="1095" y="1020" type="curve"/>
+ <point x="795" y="1020" type="line"/>
+ <point x="813" y="898"/>
+ <point x="815" y="832"/>
+ <point x="815" y="700" type="curve" smooth="yes"/>
+ <point x="815" y="418" type="line"/>
+ <point x="774" y="326"/>
+ <point x="651" y="206"/>
+ <point x="560" y="206" type="curve" smooth="yes"/>
+ <point x="458" y="206"/>
+ <point x="425" y="284"/>
+ <point x="425" y="465" type="curve" smooth="yes"/>
+ <point x="425" y="603"/>
+ <point x="425" y="1020"/>
+ <point x="425" y="1020" type="curve"/>
+ <point x="125" y="1020" type="line"/>
+ <point x="143" y="900"/>
+ <point x="145" y="827"/>
+ <point x="145" y="700" type="curve" smooth="yes"/>
+ <point x="145" y="681"/>
+ <point x="145" y="424"/>
+ <point x="145" y="405" type="curve" smooth="yes"/>
+ <point x="145" y="120"/>
+ <point x="250" y="-25"/>
+ <point x="458" y="-25" type="curve" smooth="yes"/>
+ <point x="595" y="-25"/>
+ <point x="722" y="48"/>
+ <point x="840" y="185" type="curve"/>
+ <point x="850" y="116"/>
+ <point x="876" y="43"/>
+ <point x="895" y="0" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfrenameglyphs.ufo/glyphs/L_tnS_mV_.glif b/tests/reference/ufo/psfrenameglyphs.ufo/glyphs/L_tnS_mV_.glif
new file mode 100644
index 0000000..daf1468
--- /dev/null
+++ b/tests/reference/ufo/psfrenameglyphs.ufo/glyphs/L_tnS_mV_.glif
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmV" format="2">
+ <advance width="1104"/>
+ <unicode hex="0076"/>
+ <anchor x="565" y="0" name="H"/>
+ <anchor x="565" y="-100" name="L"/>
+ <anchor x="750" y="0" name="O"/>
+ <anchor x="565" y="1100" name="U"/>
+ <outline>
+ <contour>
+ <point x="786" y="1020" type="line"/>
+ <point x="556" y="290" type="line"/>
+ <point x="322" y="1020" type="line"/>
+ <point x="10" y="1020" type="line"/>
+ <point x="65" y="905"/>
+ <point x="133" y="746"/>
+ <point x="165" y="665" type="curve" smooth="yes"/>
+ <point x="227" y="510"/>
+ <point x="430" y="0"/>
+ <point x="430" y="0" type="curve"/>
+ <point x="674" y="0" type="line"/>
+ <point x="674" y="0"/>
+ <point x="886" y="536"/>
+ <point x="939" y="665" type="curve" smooth="yes"/>
+ <point x="972" y="744"/>
+ <point x="1037" y="905"/>
+ <point x="1094" y="1020" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfrenameglyphs.ufo/glyphs/L_tnS_mW_.glif b/tests/reference/ufo/psfrenameglyphs.ufo/glyphs/L_tnS_mW_.glif
new file mode 100644
index 0000000..1ca1ec4
--- /dev/null
+++ b/tests/reference/ufo/psfrenameglyphs.ufo/glyphs/L_tnS_mW_.glif
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmW" format="2">
+ <advance width="1570"/>
+ <unicode hex="0077"/>
+ <anchor x="785" y="-100" name="L"/>
+ <anchor x="785" y="1100" name="U"/>
+ <outline>
+ <contour>
+ <point x="665" y="1020" type="line"/>
+ <point x="480" y="285" type="line"/>
+ <point x="323" y="1020" type="line"/>
+ <point x="35" y="1020" type="line"/>
+ <point x="82" y="867"/>
+ <point x="110" y="771"/>
+ <point x="140" y="665" type="curve" smooth="yes"/>
+ <point x="325" y="0" type="line"/>
+ <point x="615" y="0" type="line"/>
+ <point x="785" y="695" type="line"/>
+ <point x="955" y="0" type="line"/>
+ <point x="1245" y="0" type="line"/>
+ <point x="1430" y="665" type="line" smooth="yes"/>
+ <point x="1464" y="785"/>
+ <point x="1488" y="868"/>
+ <point x="1535" y="1020" type="curve"/>
+ <point x="1247" y="1020" type="line"/>
+ <point x="1090" y="285" type="line"/>
+ <point x="905" y="1020" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfrenameglyphs.ufo/glyphs/L_tnS_mX_.glif b/tests/reference/ufo/psfrenameglyphs.ufo/glyphs/L_tnS_mX_.glif
new file mode 100644
index 0000000..971c129
--- /dev/null
+++ b/tests/reference/ufo/psfrenameglyphs.ufo/glyphs/L_tnS_mX_.glif
@@ -0,0 +1,40 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmX" format="2">
+ <advance width="1185"/>
+ <unicode hex="0078"/>
+ <anchor x="960" y="0" name="H"/>
+ <anchor x="590" y="-100" name="L"/>
+ <anchor x="615" y="1100" name="U"/>
+ <outline>
+ <contour>
+ <point x="815" y="0" type="line"/>
+ <point x="1145" y="0" type="line"/>
+ <point x="1037" y="129"/>
+ <point x="989" y="190"/>
+ <point x="930" y="270" type="curve" smooth="yes"/>
+ <point x="380" y="1020" type="line"/>
+ <point x="50" y="1020" type="line"/>
+ <point x="158" y="887"/>
+ <point x="192" y="842"/>
+ <point x="260" y="750" type="curve" smooth="yes"/>
+ </contour>
+ <contour>
+ <point x="499" y="616" type="line"/>
+ <point x="245" y="270" type="line" smooth="yes"/>
+ <point x="195" y="201"/>
+ <point x="150" y="143"/>
+ <point x="40" y="0" type="curve"/>
+ <point x="345" y="0" type="line"/>
+ <point x="584" y="359" type="line"/>
+ </contour>
+ <contour>
+ <point x="675" y="405" type="line"/>
+ <point x="925" y="750" type="line" smooth="yes"/>
+ <point x="980" y="826"/>
+ <point x="1027" y="886"/>
+ <point x="1130" y="1020" type="curve"/>
+ <point x="825" y="1020" type="line"/>
+ <point x="595" y="668" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfrenameglyphs.ufo/glyphs/L_tnS_mY_.glif b/tests/reference/ufo/psfrenameglyphs.ufo/glyphs/L_tnS_mY_.glif
new file mode 100644
index 0000000..ea8d25e
--- /dev/null
+++ b/tests/reference/ufo/psfrenameglyphs.ufo/glyphs/L_tnS_mY_.glif
@@ -0,0 +1,39 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmY" format="2">
+ <advance width="1100"/>
+ <unicode hex="0079"/>
+ <anchor x="845" y="-100" name="L"/>
+ <anchor x="1155" y="1000" name="R"/>
+ <anchor x="565" y="1100" name="U"/>
+ <outline>
+ <contour>
+ <point x="945" y="665" type="line" smooth="yes"/>
+ <point x="978" y="758"/>
+ <point x="1021" y="865"/>
+ <point x="1090" y="1020" type="curve"/>
+ <point x="777" y="1020" type="line"/>
+ <point x="777" y="1020"/>
+ <point x="646" y="549"/>
+ <point x="573" y="293" type="curve"/>
+ <point x="333" y="1020" type="line"/>
+ <point x="20" y="1020" type="line"/>
+ <point x="97" y="864"/>
+ <point x="144" y="757"/>
+ <point x="180" y="665" type="curve" smooth="yes"/>
+ <point x="445" y="-18" type="line"/>
+ <point x="366" y="-209"/>
+ <point x="304" y="-242"/>
+ <point x="245" y="-242" type="curve" smooth="yes"/>
+ <point x="179" y="-242"/>
+ <point x="102" y="-202"/>
+ <point x="60" y="-167" type="curve"/>
+ <point x="-10" y="-385" type="line"/>
+ <point x="63" y="-439"/>
+ <point x="154" y="-470"/>
+ <point x="245" y="-470" type="curve" smooth="yes"/>
+ <point x="427" y="-470"/>
+ <point x="565" y="-387"/>
+ <point x="705" y="0" type="curve" smooth="yes"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfrenameglyphs.ufo/glyphs/N_onB_reakingH_yphen.glif b/tests/reference/ufo/psfrenameglyphs.ufo/glyphs/N_onB_reakingH_yphen.glif
new file mode 100644
index 0000000..7dc67c0
--- /dev/null
+++ b/tests/reference/ufo/psfrenameglyphs.ufo/glyphs/N_onB_reakingH_yphen.glif
@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="NonBreakingHyphen" format="2">
+ <advance width="895"/>
+ <unicode hex="2011"/>
+ <anchor x="450" y="1100" name="U"/>
+ <outline>
+ <component base="HyphenMinus"/>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfrenameglyphs.ufo/glyphs/N_umS_gn.glif b/tests/reference/ufo/psfrenameglyphs.ufo/glyphs/N_umS_gn.glif
new file mode 100644
index 0000000..54b82cb
--- /dev/null
+++ b/tests/reference/ufo/psfrenameglyphs.ufo/glyphs/N_umS_gn.glif
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="NumSgn" format="2">
+ <advance width="1200"/>
+ <unicode hex="0023"/>
+ <outline>
+ <contour>
+ <point x="412" y="1360" type="line"/>
+ <point x="52" y="100" type="line"/>
+ <point x="272" y="100" type="line"/>
+ <point x="632" y="1360" type="line"/>
+ </contour>
+ <contour>
+ <point x="10" y="425" type="line"/>
+ <point x="1101" y="425" type="line"/>
+ <point x="1101" y="635" type="line"/>
+ <point x="10" y="635" type="line"/>
+ </contour>
+ <contour>
+ <point x="69" y="850" type="line"/>
+ <point x="1160" y="850" type="line"/>
+ <point x="1160" y="1060" type="line"/>
+ <point x="69" y="1060" type="line"/>
+ </contour>
+ <contour>
+ <point x="887" y="1360" type="line"/>
+ <point x="527" y="100" type="line"/>
+ <point x="747" y="100" type="line"/>
+ <point x="1107" y="1360" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfrenameglyphs.ufo/glyphs/P_ercentS_gn.glif b/tests/reference/ufo/psfrenameglyphs.ufo/glyphs/P_ercentS_gn.glif
new file mode 100644
index 0000000..5017543
--- /dev/null
+++ b/tests/reference/ufo/psfrenameglyphs.ufo/glyphs/P_ercentS_gn.glif
@@ -0,0 +1,69 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="PercentSgn" format="2">
+ <advance width="1565"/>
+ <unicode hex="0025"/>
+ <outline>
+ <contour>
+ <point x="1073" y="1480" type="line"/>
+ <point x="291" y="-25" type="line"/>
+ <point x="499" y="-25" type="line"/>
+ <point x="1279" y="1480" type="line"/>
+ </contour>
+ <contour>
+ <point x="511" y="1076" type="curve" smooth="yes"/>
+ <point x="511" y="892"/>
+ <point x="470" y="815"/>
+ <point x="394" y="815" type="curve" smooth="yes"/>
+ <point x="315" y="815"/>
+ <point x="279" y="891"/>
+ <point x="279" y="1091" type="curve" smooth="yes"/>
+ <point x="279" y="1275"/>
+ <point x="317" y="1350"/>
+ <point x="394" y="1350" type="curve" smooth="yes"/>
+ <point x="475" y="1350"/>
+ <point x="511" y="1276"/>
+ </contour>
+ <contour>
+ <point x="721" y="1089" type="curve" smooth="yes"/>
+ <point x="721" y="1362"/>
+ <point x="584" y="1480"/>
+ <point x="399" y="1480" type="curve" smooth="yes"/>
+ <point x="215" y="1480"/>
+ <point x="69" y="1360"/>
+ <point x="69" y="1078" type="curve" smooth="yes"/>
+ <point x="69" y="796"/>
+ <point x="205" y="685"/>
+ <point x="390" y="685" type="curve" smooth="yes"/>
+ <point x="575" y="685"/>
+ <point x="721" y="794"/>
+ </contour>
+ <contour>
+ <point x="1286" y="366" type="curve" smooth="yes"/>
+ <point x="1286" y="182"/>
+ <point x="1245" y="105"/>
+ <point x="1169" y="105" type="curve" smooth="yes"/>
+ <point x="1090" y="105"/>
+ <point x="1054" y="181"/>
+ <point x="1054" y="381" type="curve" smooth="yes"/>
+ <point x="1054" y="565"/>
+ <point x="1092" y="640"/>
+ <point x="1169" y="640" type="curve" smooth="yes"/>
+ <point x="1250" y="640"/>
+ <point x="1286" y="566"/>
+ </contour>
+ <contour>
+ <point x="1496" y="379" type="curve" smooth="yes"/>
+ <point x="1496" y="652"/>
+ <point x="1359" y="770"/>
+ <point x="1174" y="770" type="curve" smooth="yes"/>
+ <point x="990" y="770"/>
+ <point x="844" y="650"/>
+ <point x="844" y="368" type="curve" smooth="yes"/>
+ <point x="844" y="86"/>
+ <point x="980" y="-25"/>
+ <point x="1165" y="-25" type="curve" smooth="yes"/>
+ <point x="1350" y="-25"/>
+ <point x="1496" y="84"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfrenameglyphs.ufo/glyphs/P_lusS_gn.glif b/tests/reference/ufo/psfrenameglyphs.ufo/glyphs/P_lusS_gn.glif
new file mode 100644
index 0000000..a1a4c93
--- /dev/null
+++ b/tests/reference/ufo/psfrenameglyphs.ufo/glyphs/P_lusS_gn.glif
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="PlusSgn" format="2">
+ <advance width="1200"/>
+ <unicode hex="002B"/>
+ <outline>
+ <contour>
+ <point x="495" y="1180" type="line"/>
+ <point x="495" y="285" type="line"/>
+ <point x="705" y="285" type="line"/>
+ <point x="705" y="1180" type="line"/>
+ </contour>
+ <contour>
+ <point x="155" y="630" type="line"/>
+ <point x="1045" y="630" type="line"/>
+ <point x="1045" y="840" type="line"/>
+ <point x="155" y="840" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfrenameglyphs.ufo/glyphs/Q_stnM_rk.glif b/tests/reference/ufo/psfrenameglyphs.ufo/glyphs/Q_stnM_rk.glif
new file mode 100644
index 0000000..c9bbb28
--- /dev/null
+++ b/tests/reference/ufo/psfrenameglyphs.ufo/glyphs/Q_stnM_rk.glif
@@ -0,0 +1,49 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="QstnMrk" format="2">
+ <advance width="1090"/>
+ <unicode hex="003F"/>
+ <outline>
+ <contour>
+ <point x="640" y="500" type="line"/>
+ <point x="640" y="671"/>
+ <point x="668" y="805"/>
+ <point x="767" y="956" type="curve" smooth="yes"/>
+ <point x="837" y="1063"/>
+ <point x="900" y="1117"/>
+ <point x="900" y="1220" type="curve" smooth="yes"/>
+ <point x="900" y="1402"/>
+ <point x="757" y="1540"/>
+ <point x="500" y="1540" type="curve" smooth="yes"/>
+ <point x="355" y="1540"/>
+ <point x="206" y="1470"/>
+ <point x="140" y="1407" type="curve"/>
+ <point x="185" y="1168" type="line"/>
+ <point x="261" y="1247"/>
+ <point x="372" y="1295"/>
+ <point x="472" y="1295" type="curve" smooth="yes"/>
+ <point x="569" y="1295"/>
+ <point x="615" y="1249"/>
+ <point x="615" y="1190" type="curve" smooth="yes"/>
+ <point x="615" y="1139"/>
+ <point x="565" y="1096"/>
+ <point x="495" y="980" type="curve" smooth="yes"/>
+ <point x="434" y="879"/>
+ <point x="375" y="710"/>
+ <point x="375" y="500" type="curve"/>
+ </contour>
+ <contour>
+ <point x="335" y="150" type="curve" smooth="yes"/>
+ <point x="335" y="46"/>
+ <point x="409" y="-25"/>
+ <point x="510" y="-25" type="curve" smooth="yes"/>
+ <point x="612" y="-25"/>
+ <point x="685" y="46"/>
+ <point x="685" y="150" type="curve" smooth="yes"/>
+ <point x="685" y="252"/>
+ <point x="612" y="325"/>
+ <point x="510" y="325" type="curve" smooth="yes"/>
+ <point x="409" y="325"/>
+ <point x="335" y="252"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfrenameglyphs.ufo/glyphs/Q_uotM_rk.glif b/tests/reference/ufo/psfrenameglyphs.ufo/glyphs/Q_uotM_rk.glif
new file mode 100644
index 0000000..794a655
--- /dev/null
+++ b/tests/reference/ufo/psfrenameglyphs.ufo/glyphs/Q_uotM_rk.glif
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="QuotMrk" format="2">
+ <advance width="1085"/>
+ <unicode hex="0022"/>
+ <outline>
+ <contour>
+ <point x="450" y="1045" type="line"/>
+ <point x="455" y="1186"/>
+ <point x="456" y="1339"/>
+ <point x="485" y="1585" type="curve"/>
+ <point x="240" y="1585" type="line"/>
+ <point x="271" y="1339"/>
+ <point x="271" y="1186"/>
+ <point x="275" y="1045" type="curve"/>
+ </contour>
+ <contour>
+ <point x="810" y="1045" type="line"/>
+ <point x="815" y="1186"/>
+ <point x="816" y="1339"/>
+ <point x="845" y="1585" type="curve"/>
+ <point x="600" y="1585" type="line"/>
+ <point x="631" y="1339"/>
+ <point x="631" y="1186"/>
+ <point x="635" y="1045" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfrenameglyphs.ufo/glyphs/R_everseS_olidus.glif b/tests/reference/ufo/psfrenameglyphs.ufo/glyphs/R_everseS_olidus.glif
new file mode 100644
index 0000000..799c999
--- /dev/null
+++ b/tests/reference/ufo/psfrenameglyphs.ufo/glyphs/R_everseS_olidus.glif
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="ReverseSolidus" format="2">
+ <advance width="1080"/>
+ <unicode hex="005C"/>
+ <outline>
+ <contour>
+ <point x="10" y="1600" type="line"/>
+ <point x="840" y="-245" type="line"/>
+ <point x="1070" y="-245" type="line"/>
+ <point x="240" y="1600" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfrenameglyphs.ufo/glyphs/R_tC_urlyB_rac.glif b/tests/reference/ufo/psfrenameglyphs.ufo/glyphs/R_tC_urlyB_rac.glif
new file mode 100644
index 0000000..48383fb
--- /dev/null
+++ b/tests/reference/ufo/psfrenameglyphs.ufo/glyphs/R_tC_urlyB_rac.glif
@@ -0,0 +1,47 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="RtCurlyBrac" format="2">
+ <advance width="1040"/>
+ <unicode hex="007D"/>
+ <outline>
+ <contour>
+ <point x="180" y="-410" type="line"/>
+ <point x="316" y="-383"/>
+ <point x="520" y="-333"/>
+ <point x="570" y="-285" type="curve" smooth="yes"/>
+ <point x="645" y="-213"/>
+ <point x="633" y="378"/>
+ <point x="655" y="410" type="curve" smooth="yes"/>
+ <point x="685" y="453"/>
+ <point x="855" y="560"/>
+ <point x="855" y="615" type="curve" smooth="yes"/>
+ <point x="855" y="670"/>
+ <point x="685" y="777"/>
+ <point x="655" y="820" type="curve" smooth="yes"/>
+ <point x="633" y="852"/>
+ <point x="644" y="1442"/>
+ <point x="570" y="1515" type="curve" smooth="yes"/>
+ <point x="523" y="1562"/>
+ <point x="333" y="1613"/>
+ <point x="205" y="1640" type="curve"/>
+ <point x="155" y="1409" type="line"/>
+ <point x="218" y="1390"/>
+ <point x="323" y="1351"/>
+ <point x="340" y="1330" type="curve" smooth="yes"/>
+ <point x="375" y="1289"/>
+ <point x="364" y="820"/>
+ <point x="382" y="785" type="curve" smooth="yes"/>
+ <point x="405" y="740"/>
+ <point x="542" y="650"/>
+ <point x="542" y="615" type="curve" smooth="yes"/>
+ <point x="542" y="580"/>
+ <point x="404" y="491"/>
+ <point x="380" y="445" type="curve" smooth="yes"/>
+ <point x="362" y="411"/>
+ <point x="375" y="-60"/>
+ <point x="340" y="-100" type="curve" smooth="yes"/>
+ <point x="321" y="-122"/>
+ <point x="197" y="-160"/>
+ <point x="130" y="-179" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfrenameglyphs.ufo/glyphs/R_tP_aren.glif b/tests/reference/ufo/psfrenameglyphs.ufo/glyphs/R_tP_aren.glif
new file mode 100644
index 0000000..ae49fca
--- /dev/null
+++ b/tests/reference/ufo/psfrenameglyphs.ufo/glyphs/R_tP_aren.glif
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="RtParen" format="2">
+ <advance width="860"/>
+ <unicode hex="0029"/>
+ <outline>
+ <contour>
+ <point x="185" y="1455" type="line"/>
+ <point x="395" y="1261"/>
+ <point x="485" y="938"/>
+ <point x="485" y="635" type="curve" smooth="yes"/>
+ <point x="485" y="335"/>
+ <point x="399" y="11"/>
+ <point x="175" y="-240" type="curve"/>
+ <point x="326" y="-410" type="line"/>
+ <point x="601" y="-125"/>
+ <point x="746" y="218"/>
+ <point x="746" y="625" type="curve" smooth="yes"/>
+ <point x="746" y="1062"/>
+ <point x="571" y="1444"/>
+ <point x="306" y="1640" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfrenameglyphs.ufo/glyphs/R_tS_qrB_rac.glif b/tests/reference/ufo/psfrenameglyphs.ufo/glyphs/R_tS_qrB_rac.glif
new file mode 100644
index 0000000..325e575
--- /dev/null
+++ b/tests/reference/ufo/psfrenameglyphs.ufo/glyphs/R_tS_qrB_rac.glif
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="RtSqrBrac" format="2">
+ <advance width="850"/>
+ <unicode hex="005D"/>
+ <outline>
+ <contour>
+ <point x="660" y="-410" type="line"/>
+ <point x="660" y="1600" type="line"/>
+ <point x="140" y="1600" type="line"/>
+ <point x="140" y="1390" type="line"/>
+ <point x="380" y="1390" type="line"/>
+ <point x="380" y="-200" type="line"/>
+ <point x="140" y="-200" type="line"/>
+ <point x="140" y="-410" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfrenameglyphs.ufo/glyphs/S_emicolon.glif b/tests/reference/ufo/psfrenameglyphs.ufo/glyphs/S_emicolon.glif
new file mode 100644
index 0000000..ae95657
--- /dev/null
+++ b/tests/reference/ufo/psfrenameglyphs.ufo/glyphs/S_emicolon.glif
@@ -0,0 +1,38 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="Semicolon" format="2">
+ <advance width="710"/>
+ <unicode hex="003B"/>
+ <outline>
+ <contour>
+ <point x="200" y="750" type="curve" smooth="yes"/>
+ <point x="200" y="646"/>
+ <point x="274" y="575"/>
+ <point x="375" y="575" type="curve" smooth="yes"/>
+ <point x="477" y="575"/>
+ <point x="550" y="646"/>
+ <point x="550" y="750" type="curve" smooth="yes"/>
+ <point x="550" y="852"/>
+ <point x="477" y="925"/>
+ <point x="375" y="925" type="curve" smooth="yes"/>
+ <point x="274" y="925"/>
+ <point x="200" y="852"/>
+ </contour>
+ <contour>
+ <point x="185" y="50" type="line"/>
+ <point x="345" y="50" type="line"/>
+ <point x="345" y="-34"/>
+ <point x="290" y="-153"/>
+ <point x="185" y="-265" type="curve"/>
+ <point x="330" y="-335" type="line"/>
+ <point x="454" y="-228"/>
+ <point x="560" y="-49"/>
+ <point x="560" y="130" type="curve" smooth="yes"/>
+ <point x="560" y="254"/>
+ <point x="489" y="340"/>
+ <point x="375" y="340" type="curve" smooth="yes"/>
+ <point x="262" y="340"/>
+ <point x="185" y="255"/>
+ <point x="185" y="180" type="curve" smooth="yes"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfrenameglyphs.ufo/glyphs/S_olidus.glif b/tests/reference/ufo/psfrenameglyphs.ufo/glyphs/S_olidus.glif
new file mode 100644
index 0000000..1e33c05
--- /dev/null
+++ b/tests/reference/ufo/psfrenameglyphs.ufo/glyphs/S_olidus.glif
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="Solidus" format="2">
+ <advance width="1080"/>
+ <unicode hex="002F"/>
+ <outline>
+ <contour>
+ <point x="840" y="1600" type="line"/>
+ <point x="10" y="-245" type="line"/>
+ <point x="240" y="-245" type="line"/>
+ <point x="1070" y="1600" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfrenameglyphs.ufo/glyphs/S_pace.glif b/tests/reference/ufo/psfrenameglyphs.ufo/glyphs/S_pace.glif
new file mode 100644
index 0000000..ef0bed7
--- /dev/null
+++ b/tests/reference/ufo/psfrenameglyphs.ufo/glyphs/S_pace.glif
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="Space" format="2">
+ <advance width="550"/>
+ <unicode hex="0020"/>
+ <outline/>
+</glyph>
diff --git a/tests/reference/ufo/psfrenameglyphs.ufo/glyphs/S_tar.glif b/tests/reference/ufo/psfrenameglyphs.ufo/glyphs/S_tar.glif
new file mode 100644
index 0000000..07072d0
--- /dev/null
+++ b/tests/reference/ufo/psfrenameglyphs.ufo/glyphs/S_tar.glif
@@ -0,0 +1,51 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="Star" format="2">
+ <advance width="1040"/>
+ <unicode hex="002A"/>
+ <outline>
+ <contour>
+ <point x="827" y="1493" type="line"/>
+ <point x="747" y="1426"/>
+ <point x="679" y="1367"/>
+ <point x="594" y="1308" type="curve"/>
+ <point x="599" y="1405"/>
+ <point x="609" y="1486"/>
+ <point x="624" y="1600" type="curve"/>
+ <point x="425" y="1600" type="line"/>
+ <point x="444" y="1497"/>
+ <point x="460" y="1412"/>
+ <point x="468" y="1308" type="curve"/>
+ <point x="383" y="1360"/>
+ <point x="312" y="1408"/>
+ <point x="228" y="1476" type="curve"/>
+ <point x="126" y="1306" type="line"/>
+ <point x="231" y="1271"/>
+ <point x="331" y="1234"/>
+ <point x="412" y="1196" type="curve"/>
+ <point x="328" y="1153"/>
+ <point x="243" y="1120"/>
+ <point x="136" y="1077" type="curve"/>
+ <point x="237" y="897" type="line"/>
+ <point x="316" y="968"/>
+ <point x="382" y="1026"/>
+ <point x="466" y="1087" type="curve"/>
+ <point x="459" y="983"/>
+ <point x="449" y="896"/>
+ <point x="431" y="793" type="curve"/>
+ <point x="632" y="793" type="line"/>
+ <point x="610" y="906"/>
+ <point x="602" y="987"/>
+ <point x="593" y="1084" type="curve"/>
+ <point x="682" y="1027"/>
+ <point x="747" y="981"/>
+ <point x="830" y="914" type="curve"/>
+ <point x="936" y="1089" type="line"/>
+ <point x="827" y="1127"/>
+ <point x="743" y="1155"/>
+ <point x="651" y="1196" type="curve"/>
+ <point x="738" y="1241"/>
+ <point x="820" y="1277"/>
+ <point x="924" y="1321" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfrenameglyphs.ufo/glyphs/T_ilde.glif b/tests/reference/ufo/psfrenameglyphs.ufo/glyphs/T_ilde.glif
new file mode 100644
index 0000000..ec9fc73
--- /dev/null
+++ b/tests/reference/ufo/psfrenameglyphs.ufo/glyphs/T_ilde.glif
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="Tilde" format="2">
+ <advance width="1115"/>
+ <unicode hex="007E"/>
+ <outline>
+ <contour>
+ <point x="165" y="345" type="line"/>
+ <point x="170" y="394"/>
+ <point x="202" y="435"/>
+ <point x="280" y="435" type="curve" smooth="yes"/>
+ <point x="435" y="435"/>
+ <point x="615" y="330"/>
+ <point x="825" y="330" type="curve" smooth="yes"/>
+ <point x="984" y="330"/>
+ <point x="1080" y="512"/>
+ <point x="1080" y="640" type="curve"/>
+ <point x="935" y="640" type="line"/>
+ <point x="928" y="594"/>
+ <point x="898" y="540"/>
+ <point x="815" y="540" type="curve" smooth="yes"/>
+ <point x="599" y="540"/>
+ <point x="461" y="645"/>
+ <point x="260" y="645" type="curve" smooth="yes"/>
+ <point x="104" y="645"/>
+ <point x="20" y="467"/>
+ <point x="20" y="345" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfrenameglyphs.ufo/glyphs/V_ertL_ine.glif b/tests/reference/ufo/psfrenameglyphs.ufo/glyphs/V_ertL_ine.glif
new file mode 100644
index 0000000..d7caa84
--- /dev/null
+++ b/tests/reference/ufo/psfrenameglyphs.ufo/glyphs/V_ertL_ine.glif
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="VertLine" format="2">
+ <advance width="690"/>
+ <unicode hex="007C"/>
+ <outline>
+ <contour>
+ <point x="240" y="1600" type="line"/>
+ <point x="240" y="-390" type="line"/>
+ <point x="450" y="-390" type="line"/>
+ <point x="450" y="1600" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfrenameglyphs.ufo/glyphs/_notdef.glif b/tests/reference/ufo/psfrenameglyphs.ufo/glyphs/_notdef.glif
new file mode 100644
index 0000000..a3e9354
--- /dev/null
+++ b/tests/reference/ufo/psfrenameglyphs.ufo/glyphs/_notdef.glif
@@ -0,0 +1,18 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name=".notdef" format="2">
+ <advance width="1400"/>
+ <outline>
+ <contour>
+ <point x="100" y="0" type="line"/>
+ <point x="1300" y="0" type="line"/>
+ <point x="1300" y="1800" type="line"/>
+ <point x="100" y="1800" type="line"/>
+ </contour>
+ <contour>
+ <point x="150" y="1750" type="line"/>
+ <point x="1250" y="1750" type="line"/>
+ <point x="1250" y="50" type="line"/>
+ <point x="150" y="50" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfrenameglyphs.ufo/glyphs/_null.glif b/tests/reference/ufo/psfrenameglyphs.ufo/glyphs/_null.glif
new file mode 100644
index 0000000..0b9caa6
--- /dev/null
+++ b/tests/reference/ufo/psfrenameglyphs.ufo/glyphs/_null.glif
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name=".null" format="2">
+ <outline/>
+</glyph>
diff --git a/tests/reference/ufo/psfrenameglyphs.ufo/glyphs/contents.plist b/tests/reference/ufo/psfrenameglyphs.ufo/glyphs/contents.plist
new file mode 100644
index 0000000..33b59ec
--- /dev/null
+++ b/tests/reference/ufo/psfrenameglyphs.ufo/glyphs/contents.plist
@@ -0,0 +1,234 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+ <key>.notdef</key>
+ <string>_notdef.glif</string>
+ <key>.null</key>
+ <string>_null.glif</string>
+ <key>Ampersand</key>
+ <string>A_mpersand.glif</string>
+ <key>AtSgn</key>
+ <string>A_tS_gn.glif</string>
+ <key>Bpos</key>
+ <string>B_pos.glif</string>
+ <key>CircumAccent</key>
+ <string>C_ircumA_ccent.glif</string>
+ <key>Colon</key>
+ <string>C_olon.glif</string>
+ <key>CombAcute</key>
+ <string>C_ombA_cute.glif</string>
+ <key>CombCircum</key>
+ <string>C_ombC_ircum.glif</string>
+ <key>CombDiaer</key>
+ <string>C_ombD_iaer.glif</string>
+ <key>CombGrave</key>
+ <string>C_ombG_rave.glif</string>
+ <key>CombRingAbv</key>
+ <string>C_ombR_ingA_bv.glif</string>
+ <key>CombTilde</key>
+ <string>C_ombT_ilde.glif</string>
+ <key>Comma</key>
+ <string>C_omma.glif</string>
+ <key>DigitEight</key>
+ <string>D_igitE_ight.glif</string>
+ <key>DigitFive</key>
+ <string>D_igitF_ive.glif</string>
+ <key>DigitFour</key>
+ <string>D_igitF_our.glif</string>
+ <key>DigitNine</key>
+ <string>D_igitN_ine.glif</string>
+ <key>DigitOne</key>
+ <string>D_igitO_ne.glif</string>
+ <key>DigitSeven</key>
+ <string>D_igitS_even.glif</string>
+ <key>DigitSix</key>
+ <string>D_igitS_ix.glif</string>
+ <key>DigitThree</key>
+ <string>D_igitT_hree.glif</string>
+ <key>DigitTwo</key>
+ <string>D_igitT_wo.glif</string>
+ <key>DigitZero</key>
+ <string>D_igitZ_ero.glif</string>
+ <key>DollarSgn</key>
+ <string>D_ollarS_gn.glif</string>
+ <key>DottedCirc</key>
+ <string>D_ottedC_irc.glif</string>
+ <key>EqSgn</key>
+ <string>E_qS_gn.glif</string>
+ <key>ExclamationMrk</key>
+ <string>E_xclamationM_rk.glif</string>
+ <key>FullStop</key>
+ <string>F_ullS_top.glif</string>
+ <key>GTSgn</key>
+ <string>G_T_S_gn.glif</string>
+ <key>GraveAccent</key>
+ <string>G_raveA_ccent.glif</string>
+ <key>Hyphen</key>
+ <string>H_yphen.glif</string>
+ <key>HyphenMinus</key>
+ <string>H_yphenM_inus.glif</string>
+ <key>Hyphen_Soft</key>
+ <string>H_yphen_S_oft.glif</string>
+ <key>LTSgn</key>
+ <string>L_T_S_gn.glif</string>
+ <key>LftCurlyBrac</key>
+ <string>L_ftC_urlyB_rac.glif</string>
+ <key>LftParen</key>
+ <string>L_ftP_aren.glif</string>
+ <key>LftSqrBrac</key>
+ <string>L_ftS_qrB_rac.glif</string>
+ <key>LowLine</key>
+ <string>L_owL_ine.glif</string>
+ <key>LtnCapA</key>
+ <string>L_tnC_apA_.glif</string>
+ <key>LtnCapA.alt</key>
+ <string>L_tnC_apA_.alt.glif</string>
+ <key>LtnCapADiaer</key>
+ <string>L_tnC_apA_D_iaer.glif</string>
+ <key>LtnCapB</key>
+ <string>L_tnC_apB_.glif</string>
+ <key>LtnCapC</key>
+ <string>L_tnC_apC_.glif</string>
+ <key>LtnCapD</key>
+ <string>L_tnC_apD_.glif</string>
+ <key>LtnCapE</key>
+ <string>L_tnC_apE_.glif</string>
+ <key>LtnCapF</key>
+ <string>L_tnC_apF_.glif</string>
+ <key>LtnCapG</key>
+ <string>L_tnC_apG_.glif</string>
+ <key>LtnCapH</key>
+ <string>L_tnC_apH_.glif</string>
+ <key>LtnCapI</key>
+ <string>L_tnC_apI_.glif</string>
+ <key>LtnCapJ</key>
+ <string>L_tnC_apJ_.glif</string>
+ <key>LtnCapK</key>
+ <string>L_tnC_apK_.glif</string>
+ <key>LtnCapL</key>
+ <string>L_tnC_apL_.glif</string>
+ <key>LtnCapM</key>
+ <string>L_tnC_apM_.glif</string>
+ <key>LtnCapN</key>
+ <string>L_tnC_apN_.glif</string>
+ <key>LtnCapO</key>
+ <string>L_tnC_apO_.glif</string>
+ <key>LtnCapP</key>
+ <string>L_tnC_apP_.glif</string>
+ <key>LtnCapQ</key>
+ <string>L_tnC_apQ_.glif</string>
+ <key>LtnCapR</key>
+ <string>L_tnC_apR_.glif</string>
+ <key>LtnCapS</key>
+ <string>L_tnC_apS_.glif</string>
+ <key>LtnCapT</key>
+ <string>L_tnC_apT_.glif</string>
+ <key>LtnCapU</key>
+ <string>L_tnC_apU_.glif</string>
+ <key>LtnCapV</key>
+ <string>L_tnC_apV_.glif</string>
+ <key>LtnCapW</key>
+ <string>L_tnC_apW_.glif</string>
+ <key>LtnCapX</key>
+ <string>L_tnC_apX_.glif</string>
+ <key>LtnCapY</key>
+ <string>L_tnC_apY_.glif</string>
+ <key>LtnSmA</key>
+ <string>L_tnS_mA_.glif</string>
+ <key>LtnSmAAcute</key>
+ <string>L_tnS_mA_A_cute.glif</string>
+ <key>LtnSmACircum</key>
+ <string>L_tnS_mA_C_ircum.glif</string>
+ <key>LtnSmADiaer</key>
+ <string>L_tnS_mA_D_iaer.glif</string>
+ <key>LtnSmAGrave</key>
+ <string>L_tnS_mA_G_rave.glif</string>
+ <key>LtnSmARingAbv</key>
+ <string>L_tnS_mA_R_ingA_bv.glif</string>
+ <key>LtnSmATilde</key>
+ <string>L_tnS_mA_T_ilde.glif</string>
+ <key>LtnSmB</key>
+ <string>L_tnS_mB_.glif</string>
+ <key>LtnSmC</key>
+ <string>L_tnS_mC_.glif</string>
+ <key>LtnSmD</key>
+ <string>L_tnS_mD_.glif</string>
+ <key>LtnSmE</key>
+ <string>L_tnS_mE_.glif</string>
+ <key>LtnSmF</key>
+ <string>L_tnS_mF_.glif</string>
+ <key>LtnSmG</key>
+ <string>L_tnS_mG_.glif</string>
+ <key>LtnSmH</key>
+ <string>L_tnS_mH_.glif</string>
+ <key>LtnSmI</key>
+ <string>L_tnS_mI_.glif</string>
+ <key>LtnSmJ</key>
+ <string>L_tnS_mJ_.glif</string>
+ <key>LtnSmK</key>
+ <string>L_tnS_mK_.glif</string>
+ <key>LtnSmL</key>
+ <string>L_tnS_mL_.glif</string>
+ <key>LtnSmM</key>
+ <string>L_tnS_mM_.glif</string>
+ <key>LtnSmN</key>
+ <string>L_tnS_mN_.glif</string>
+ <key>LtnSmO</key>
+ <string>L_tnS_mO_.glif</string>
+ <key>LtnSmP</key>
+ <string>L_tnS_mP_.glif</string>
+ <key>LtnSmQ</key>
+ <string>L_tnS_mQ_.glif</string>
+ <key>LtnSmR</key>
+ <string>L_tnS_mR_.glif</string>
+ <key>LtnSmS</key>
+ <string>L_tnS_mS_.glif</string>
+ <key>LtnSmT</key>
+ <string>L_tnS_mT_.glif</string>
+ <key>LtnSmU</key>
+ <string>L_tnS_mU_.glif</string>
+ <key>LtnSmV</key>
+ <string>L_tnS_mV_.glif</string>
+ <key>LtnSmW</key>
+ <string>L_tnS_mW_.glif</string>
+ <key>LtnSmX</key>
+ <string>L_tnS_mX_.glif</string>
+ <key>LtnSmY</key>
+ <string>L_tnS_mY_.glif</string>
+ <key>NonBreakingHyphen</key>
+ <string>N_onB_reakingH_yphen.glif</string>
+ <key>NumSgn</key>
+ <string>N_umS_gn.glif</string>
+ <key>PercentSgn</key>
+ <string>P_ercentS_gn.glif</string>
+ <key>PlusSgn</key>
+ <string>P_lusS_gn.glif</string>
+ <key>QstnMrk</key>
+ <string>Q_stnM_rk.glif</string>
+ <key>QuotMrk</key>
+ <string>Q_uotM_rk.glif</string>
+ <key>ReverseSolidus</key>
+ <string>R_everseS_olidus.glif</string>
+ <key>RtCurlyBrac</key>
+ <string>R_tC_urlyB_rac.glif</string>
+ <key>RtParen</key>
+ <string>R_tP_aren.glif</string>
+ <key>RtSqrBrac</key>
+ <string>R_tS_qrB_rac.glif</string>
+ <key>Semicolon</key>
+ <string>S_emicolon.glif</string>
+ <key>Solidus</key>
+ <string>S_olidus.glif</string>
+ <key>Space</key>
+ <string>S_pace.glif</string>
+ <key>Star</key>
+ <string>S_tar.glif</string>
+ <key>Tilde</key>
+ <string>T_ilde.glif</string>
+ <key>VertLine</key>
+ <string>V_ertL_ine.glif</string>
+ <key>nonmarkingreturn</key>
+ <string>nonmarkingreturn.glif</string>
+</dict>
+</plist>
diff --git a/tests/reference/ufo/psfrenameglyphs.ufo/glyphs/nonmarkingreturn.glif b/tests/reference/ufo/psfrenameglyphs.ufo/glyphs/nonmarkingreturn.glif
new file mode 100644
index 0000000..ee41448
--- /dev/null
+++ b/tests/reference/ufo/psfrenameglyphs.ufo/glyphs/nonmarkingreturn.glif
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="nonmarkingreturn" format="2">
+ <advance width="1024"/>
+ <outline/>
+</glyph>
diff --git a/tests/reference/ufo/psfrenameglyphs.ufo/layercontents.plist b/tests/reference/ufo/psfrenameglyphs.ufo/layercontents.plist
new file mode 100644
index 0000000..42b7482
--- /dev/null
+++ b/tests/reference/ufo/psfrenameglyphs.ufo/layercontents.plist
@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<array>
+ <array>
+ <string>public.default</string>
+ <string>glyphs</string>
+ </array>
+</array>
+</plist>
diff --git a/tests/reference/ufo/psfrenameglyphs.ufo/lib.plist b/tests/reference/ufo/psfrenameglyphs.ufo/lib.plist
new file mode 100644
index 0000000..72c2421
--- /dev/null
+++ b/tests/reference/ufo/psfrenameglyphs.ufo/lib.plist
@@ -0,0 +1,531 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+ <key>com.schriftgestaltung.Glyphs.fontUserData</key>
+ <dict/>
+ <key>com.schriftgestaltung.appVersion</key>
+ <string>1161</string>
+ <key>com.schriftgestaltung.customParameter.GSFont.DisplayStrings</key>
+ <string/>
+ <key>com.schriftgestaltung.customParameter.GSFont.disablesAutomaticAlignment</key>
+ <true/>
+ <key>com.schriftgestaltung.customParameter.GSFont.disablesLastChange</key>
+ <true/>
+ <key>com.schriftgestaltung.customParameter.GSFont.useNiceNames</key>
+ <integer>0</integer>
+ <key>com.schriftgestaltung.customParameter.GSFontMaster.customValue</key>
+ <integer>0</integer>
+ <key>com.schriftgestaltung.customParameter.GSFontMaster.customValue1</key>
+ <integer>0</integer>
+ <key>com.schriftgestaltung.customParameter.GSFontMaster.customValue2</key>
+ <integer>0</integer>
+ <key>com.schriftgestaltung.customParameter.GSFontMaster.customValue3</key>
+ <integer>0</integer>
+ <key>com.schriftgestaltung.customParameter.GSFontMaster.iconName</key>
+ <string/>
+ <key>com.schriftgestaltung.customParameter.GSFontMaster.weightValue</key>
+ <integer>700</integer>
+ <key>com.schriftgestaltung.customParameter.GSFontMaster.widthValue</key>
+ <integer>100</integer>
+ <key>com.schriftgestaltung.fontMasterOrder</key>
+ <integer>1</integer>
+ <key>com.schriftgestaltung.glyphOrder</key>
+ <array>
+ <string>.notdef</string>
+ <string>.null</string>
+ <string>nonmarkingreturn</string>
+ <string>Space</string>
+ <string>ExclamationMrk</string>
+ <string>QuotMrk</string>
+ <string>NumSgn</string>
+ <string>DollarSgn</string>
+ <string>PercentSgn</string>
+ <string>Ampersand</string>
+ <string>Bpos</string>
+ <string>LftParen</string>
+ <string>RtParen</string>
+ <string>Star</string>
+ <string>PlusSgn</string>
+ <string>Comma</string>
+ <string>HyphenMinus</string>
+ <string>FullStop</string>
+ <string>Solidus</string>
+ <string>DigitOne</string>
+ <string>DigitTwo</string>
+ <string>DigitThree</string>
+ <string>DigitFour</string>
+ <string>DigitFive</string>
+ <string>DigitSix</string>
+ <string>DigitSeven</string>
+ <string>DigitEight</string>
+ <string>DigitNine</string>
+ <string>Colon</string>
+ <string>Semicolon</string>
+ <string>LTSgn</string>
+ <string>EqSgn</string>
+ <string>GTSgn</string>
+ <string>QstnMrk</string>
+ <string>AtSgn</string>
+ <string>LtnCapA</string>
+ <string>LtnCapA.alt</string>
+ <string>LtnCapB</string>
+ <string>LtnCapC</string>
+ <string>LtnCapD</string>
+ <string>LtnCapE</string>
+ <string>LtnCapF</string>
+ <string>LtnCapG</string>
+ <string>LtnCapH</string>
+ <string>LtnCapI</string>
+ <string>LtnCapJ</string>
+ <string>LtnCapK</string>
+ <string>LtnCapL</string>
+ <string>LtnCapM</string>
+ <string>LtnCapN</string>
+ <string>LtnCapO</string>
+ <string>LtnCapP</string>
+ <string>LtnCapQ</string>
+ <string>LtnCapR</string>
+ <string>LtnCapS</string>
+ <string>LtnCapT</string>
+ <string>LtnCapU</string>
+ <string>LtnCapV</string>
+ <string>LtnCapW</string>
+ <string>LtnCapX</string>
+ <string>LtnCapY</string>
+ <string>LftSqrBrac</string>
+ <string>ReverseSolidus</string>
+ <string>RtSqrBrac</string>
+ <string>CircumAccent</string>
+ <string>LowLine</string>
+ <string>GraveAccent</string>
+ <string>LtnSmA</string>
+ <string>LtnSmB</string>
+ <string>LtnSmC</string>
+ <string>LtnSmD</string>
+ <string>LtnSmE</string>
+ <string>LtnSmF</string>
+ <string>LtnSmG</string>
+ <string>LtnSmH</string>
+ <string>LtnSmI</string>
+ <string>LtnSmJ</string>
+ <string>LtnSmK</string>
+ <string>LtnSmL</string>
+ <string>LtnSmM</string>
+ <string>LtnSmN</string>
+ <string>LtnSmO</string>
+ <string>LtnSmP</string>
+ <string>LtnSmQ</string>
+ <string>LtnSmR</string>
+ <string>LtnSmS</string>
+ <string>LtnSmT</string>
+ <string>LtnSmU</string>
+ <string>LtnSmV</string>
+ <string>LtnSmW</string>
+ <string>LtnSmX</string>
+ <string>LtnSmY</string>
+ <string>LftCurlyBrac</string>
+ <string>VertLine</string>
+ <string>RtCurlyBrac</string>
+ <string>Tilde</string>
+ <string>LtnCapADiaer</string>
+ <string>LtnSmAAcute</string>
+ <string>LtnSmAGrave</string>
+ <string>LtnSmACircum</string>
+ <string>LtnSmADiaer</string>
+ <string>LtnSmATilde</string>
+ <string>LtnSmARingAbv</string>
+ <string>DottedCirc</string>
+ <string>Hyphen</string>
+ <string>NonBreakingHyphen</string>
+ <string>Hyphen_Soft</string>
+ <string>CombAcute</string>
+ <string>CombGrave</string>
+ <string>CombCircum</string>
+ <string>CombTilde</string>
+ <string>CombDiaer</string>
+ <string>CombRingAbv</string>
+ </array>
+ <key>com.schriftgestaltung.keyboardIncrement</key>
+ <integer>1</integer>
+ <key>com.schriftgestaltung.weight</key>
+ <string>Bold</string>
+ <key>com.schriftgestaltung.weightValue</key>
+ <integer>700</integer>
+ <key>com.schriftgestaltung.width</key>
+ <string>Regular</string>
+ <key>com.schriftgestaltung.widthValue</key>
+ <integer>100</integer>
+ <key>org.sil.lcg.toneLetters</key>
+ <dict>
+ <key>contourWidth</key>
+ <integer>540</integer>
+ <key>dotSize</key>
+ <integer>280</integer>
+ <key>dotSpacing</key>
+ <integer>200</integer>
+ <key>glyphDepth</key>
+ <integer>-25</integer>
+ <key>glyphHeight</key>
+ <integer>1600</integer>
+ <key>italicAngle</key>
+ <integer>0</integer>
+ <key>marginDotLeft</key>
+ <integer>100</integer>
+ <key>marginDotRight</key>
+ <integer>140</integer>
+ <key>marginFlatLeft</key>
+ <integer>100</integer>
+ <key>marginFlatRight</key>
+ <integer>140</integer>
+ <key>marginPointLeft</key>
+ <integer>80</integer>
+ <key>marginPointRight</key>
+ <integer>120</integer>
+ <key>strokeThickness</key>
+ <integer>200</integer>
+ </dict>
+ <key>public.glyphOrder</key>
+ <array>
+ <string>.notdef</string>
+ <string>.null</string>
+ <string>nonmarkingreturn</string>
+ <string>Space</string>
+ <string>ExclamationMrk</string>
+ <string>QuotMrk</string>
+ <string>NumSgn</string>
+ <string>DollarSgn</string>
+ <string>PercentSgn</string>
+ <string>Ampersand</string>
+ <string>Bpos</string>
+ <string>LftParen</string>
+ <string>RtParen</string>
+ <string>Star</string>
+ <string>PlusSgn</string>
+ <string>Comma</string>
+ <string>HyphenMinus</string>
+ <string>FullStop</string>
+ <string>Solidus</string>
+ <string>DigitZero</string>
+ <string>DigitOne</string>
+ <string>DigitTwo</string>
+ <string>DigitThree</string>
+ <string>DigitFour</string>
+ <string>DigitFive</string>
+ <string>DigitSix</string>
+ <string>DigitSeven</string>
+ <string>DigitEight</string>
+ <string>DigitNine</string>
+ <string>Colon</string>
+ <string>Semicolon</string>
+ <string>LTSgn</string>
+ <string>EqSgn</string>
+ <string>GTSgn</string>
+ <string>QstnMrk</string>
+ <string>AtSgn</string>
+ <string>LtnCapA</string>
+ <string>LtnCapA.alt</string>
+ <string>LtnCapB</string>
+ <string>LtnCapC</string>
+ <string>LtnCapD</string>
+ <string>LtnCapE</string>
+ <string>LtnCapF</string>
+ <string>LtnCapG</string>
+ <string>LtnCapH</string>
+ <string>LtnCapI</string>
+ <string>LtnCapJ</string>
+ <string>LtnCapK</string>
+ <string>LtnCapL</string>
+ <string>LtnCapM</string>
+ <string>LtnCapN</string>
+ <string>LtnCapO</string>
+ <string>LtnCapP</string>
+ <string>LtnCapQ</string>
+ <string>LtnCapR</string>
+ <string>LtnCapS</string>
+ <string>LtnCapT</string>
+ <string>LtnCapU</string>
+ <string>LtnCapV</string>
+ <string>LtnCapW</string>
+ <string>LtnCapX</string>
+ <string>LtnCapY</string>
+ <string>LftSqrBrac</string>
+ <string>ReverseSolidus</string>
+ <string>RtSqrBrac</string>
+ <string>CircumAccent</string>
+ <string>LowLine</string>
+ <string>GraveAccent</string>
+ <string>LtnSmA</string>
+ <string>LtnSmB</string>
+ <string>LtnSmC</string>
+ <string>LtnSmD</string>
+ <string>LtnSmE</string>
+ <string>LtnSmF</string>
+ <string>LtnSmG</string>
+ <string>LtnSmH</string>
+ <string>LtnSmI</string>
+ <string>LtnSmJ</string>
+ <string>LtnSmK</string>
+ <string>LtnSmL</string>
+ <string>LtnSmM</string>
+ <string>LtnSmN</string>
+ <string>LtnSmO</string>
+ <string>LtnSmP</string>
+ <string>LtnSmQ</string>
+ <string>LtnSmR</string>
+ <string>LtnSmS</string>
+ <string>LtnSmT</string>
+ <string>LtnSmU</string>
+ <string>LtnSmV</string>
+ <string>LtnSmW</string>
+ <string>LtnSmX</string>
+ <string>LtnSmY</string>
+ <string>LftCurlyBrac</string>
+ <string>VertLine</string>
+ <string>RtCurlyBrac</string>
+ <string>Tilde</string>
+ <string>LtnCapADiaer</string>
+ <string>LtnSmAAcute</string>
+ <string>LtnSmAGrave</string>
+ <string>LtnSmACircum</string>
+ <string>LtnSmADiaer</string>
+ <string>LtnSmATilde</string>
+ <string>LtnSmARingAbv</string>
+ <string>DottedCirc</string>
+ <string>Hyphen</string>
+ <string>NonBreakingHyphen</string>
+ <string>Hyphen_Soft</string>
+ <string>CombAcute</string>
+ <string>CombGrave</string>
+ <string>CombCircum</string>
+ <string>CombTilde</string>
+ <string>CombDiaer</string>
+ <string>CombRingAbv</string>
+ </array>
+ <key>public.postscriptNames</key>
+ <dict>
+ <key>Ampersand</key>
+ <string>ampersand</string>
+ <key>AtSgn</key>
+ <string>at</string>
+ <key>Bpos</key>
+ <string>quotesingle</string>
+ <key>CircumAccent</key>
+ <string>asciicircum</string>
+ <key>Colon</key>
+ <string>colon</string>
+ <key>CombAcute</key>
+ <string>acutecomb</string>
+ <key>CombCircum</key>
+ <string>uni0302</string>
+ <key>CombDiaer</key>
+ <string>uni0308</string>
+ <key>CombGrave</key>
+ <string>gravecomb</string>
+ <key>CombRingAbv</key>
+ <string>uni030A</string>
+ <key>CombTilde</key>
+ <string>tildecomb</string>
+ <key>Comma</key>
+ <string>comma</string>
+ <key>DigitEight</key>
+ <string>eight</string>
+ <key>DigitFive</key>
+ <string>five</string>
+ <key>DigitFour</key>
+ <string>four</string>
+ <key>DigitNine</key>
+ <string>nine</string>
+ <key>DigitOne</key>
+ <string>one</string>
+ <key>DigitSeven</key>
+ <string>seven</string>
+ <key>DigitSix</key>
+ <string>six</string>
+ <key>DigitThree</key>
+ <string>three</string>
+ <key>DigitTwo</key>
+ <string>two</string>
+ <key>DigitZero</key>
+ <string>zero</string>
+ <key>DollarSgn</key>
+ <string>dollar</string>
+ <key>DottedCirc</key>
+ <string>uni25CC</string>
+ <key>EqSgn</key>
+ <string>equal</string>
+ <key>ExclamationMrk</key>
+ <string>exclam</string>
+ <key>FullStop</key>
+ <string>period</string>
+ <key>GTSgn</key>
+ <string>greater</string>
+ <key>GraveAccent</key>
+ <string>grave</string>
+ <key>Hyphen</key>
+ <string>uni2010</string>
+ <key>HyphenMinus</key>
+ <string>hyphen</string>
+ <key>Hyphen_Soft</key>
+ <string>uni00AD</string>
+ <key>LTSgn</key>
+ <string>less</string>
+ <key>LftCurlyBrac</key>
+ <string>braceleft</string>
+ <key>LftParen</key>
+ <string>parenleft</string>
+ <key>LftSqrBrac</key>
+ <string>bracketleft</string>
+ <key>LowLine</key>
+ <string>underscore</string>
+ <key>LtnCapA</key>
+ <string>A</string>
+ <key>LtnCapA.alt</key>
+ <string>A</string>
+ <key>LtnCapADiaer</key>
+ <string>Adieresis</string>
+ <key>LtnCapB</key>
+ <string>B</string>
+ <key>LtnCapC</key>
+ <string>C</string>
+ <key>LtnCapD</key>
+ <string>D</string>
+ <key>LtnCapE</key>
+ <string>E</string>
+ <key>LtnCapF</key>
+ <string>F</string>
+ <key>LtnCapG</key>
+ <string>G</string>
+ <key>LtnCapH</key>
+ <string>H</string>
+ <key>LtnCapI</key>
+ <string>I</string>
+ <key>LtnCapJ</key>
+ <string>J</string>
+ <key>LtnCapK</key>
+ <string>K</string>
+ <key>LtnCapL</key>
+ <string>L</string>
+ <key>LtnCapM</key>
+ <string>M</string>
+ <key>LtnCapN</key>
+ <string>N</string>
+ <key>LtnCapO</key>
+ <string>O</string>
+ <key>LtnCapP</key>
+ <string>P</string>
+ <key>LtnCapQ</key>
+ <string>Q</string>
+ <key>LtnCapR</key>
+ <string>R</string>
+ <key>LtnCapS</key>
+ <string>S</string>
+ <key>LtnCapT</key>
+ <string>T</string>
+ <key>LtnCapU</key>
+ <string>U</string>
+ <key>LtnCapV</key>
+ <string>V</string>
+ <key>LtnCapW</key>
+ <string>W</string>
+ <key>LtnCapX</key>
+ <string>X</string>
+ <key>LtnCapY</key>
+ <string>Y</string>
+ <key>LtnSmA</key>
+ <string>a</string>
+ <key>LtnSmAAcute</key>
+ <string>aacute</string>
+ <key>LtnSmACircum</key>
+ <string>acircumflex</string>
+ <key>LtnSmADiaer</key>
+ <string>adieresis</string>
+ <key>LtnSmAGrave</key>
+ <string>agrave</string>
+ <key>LtnSmARingAbv</key>
+ <string>aring</string>
+ <key>LtnSmATilde</key>
+ <string>atilde</string>
+ <key>LtnSmB</key>
+ <string>b</string>
+ <key>LtnSmC</key>
+ <string>c</string>
+ <key>LtnSmD</key>
+ <string>d</string>
+ <key>LtnSmE</key>
+ <string>e</string>
+ <key>LtnSmF</key>
+ <string>f</string>
+ <key>LtnSmG</key>
+ <string>g</string>
+ <key>LtnSmH</key>
+ <string>h</string>
+ <key>LtnSmI</key>
+ <string>i</string>
+ <key>LtnSmJ</key>
+ <string>j</string>
+ <key>LtnSmK</key>
+ <string>k</string>
+ <key>LtnSmL</key>
+ <string>l</string>
+ <key>LtnSmM</key>
+ <string>m</string>
+ <key>LtnSmN</key>
+ <string>n</string>
+ <key>LtnSmO</key>
+ <string>o</string>
+ <key>LtnSmP</key>
+ <string>p</string>
+ <key>LtnSmQ</key>
+ <string>q</string>
+ <key>LtnSmR</key>
+ <string>r</string>
+ <key>LtnSmS</key>
+ <string>s</string>
+ <key>LtnSmT</key>
+ <string>t</string>
+ <key>LtnSmU</key>
+ <string>u</string>
+ <key>LtnSmV</key>
+ <string>v</string>
+ <key>LtnSmW</key>
+ <string>w</string>
+ <key>LtnSmX</key>
+ <string>x</string>
+ <key>LtnSmY</key>
+ <string>y</string>
+ <key>NonBreakingHyphen</key>
+ <string>uni2011</string>
+ <key>NumSgn</key>
+ <string>numbersign</string>
+ <key>PercentSgn</key>
+ <string>percent</string>
+ <key>PlusSgn</key>
+ <string>plus</string>
+ <key>QstnMrk</key>
+ <string>question</string>
+ <key>QuotMrk</key>
+ <string>quotedbl</string>
+ <key>ReverseSolidus</key>
+ <string>backslash</string>
+ <key>RtCurlyBrac</key>
+ <string>braceright</string>
+ <key>RtParen</key>
+ <string>parenright</string>
+ <key>RtSqrBrac</key>
+ <string>bracketright</string>
+ <key>Semicolon</key>
+ <string>semicolon</string>
+ <key>Solidus</key>
+ <string>slash</string>
+ <key>Space</key>
+ <string>space</string>
+ <key>Star</key>
+ <string>asterisk</string>
+ <key>Tilde</key>
+ <string>asciitilde</string>
+ <key>VertLine</key>
+ <string>bar</string>
+ </dict>
+</dict>
+</plist>
diff --git a/tests/reference/ufo/psfrenameglyphs.ufo/metainfo.plist b/tests/reference/ufo/psfrenameglyphs.ufo/metainfo.plist
new file mode 100644
index 0000000..aa10c5c
--- /dev/null
+++ b/tests/reference/ufo/psfrenameglyphs.ufo/metainfo.plist
@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+ <key>creator</key>
+ <string>org.sil.scripts.pysilfont</string>
+ <key>formatVersion</key>
+ <integer>3</integer>
+</dict>
+</plist>
diff --git a/tests/reference/ufo/psfsetassocfeat.lg b/tests/reference/ufo/psfsetassocfeat.lg
new file mode 100644
index 0000000..d0f1b38
--- /dev/null
+++ b/tests/reference/ufo/psfsetassocfeat.lg
@@ -0,0 +1,30 @@
+2021-06-29 14:42:22 Progress: Running: psfsetassocfeat tests/input/font-psf-test/source/PsfTest-Italic.ufo -i tests/input/psfsetassocfeat.csv -l local/testresults/ufo/psfsetassocfeat.log -p loglevel=i
+2021-06-29 14:42:22 Progress: Opening file for input: tests/input/psfsetassocfeat.csv
+2021-06-29 14:42:22 Progress: Reading UFO: tests/input/font-psf-test/source/PsfTest-Italic.ufo
+2021-06-29 14:42:22 Info: Processing Glyph Layer 0: public.defaultglyphs
+2021-06-29 14:42:22 Progress: Checking fontinfo.plist metadata
+2021-06-29 14:42:22 Warning: openTypeOS2FamilyClass would be removed from fontinfo Old value: [0, 0]
+2021-06-29 14:42:22 Info: Types: Old - list, New - NoneType
+2021-06-29 14:42:22 Warning: year would be removed from fontinfo Old value: 2021
+2021-06-29 14:42:22 Info: Types: Old - int, New - NoneType
+2021-06-29 14:42:22 Warning: capHeight would be updated Old value: 1485.3, new value: 1485
+2021-06-29 14:42:22 Info: Types: Old - float, New - int
+2021-06-29 14:42:22 Warning: styleMapFamilyName would be uppdated Old value: Psf test, new value: Psf Test
+2021-06-29 14:42:22 Info: Types: Old - string, New - string
+2021-06-29 14:42:22 Warning: openTypeOS2TypoLineGap would be updated Old value: 1, new value: 0
+2021-06-29 14:42:22 Info: Types: Old - int, New - int
+2021-06-29 14:42:22 Warning: openTypeOS2Selection would be added New value: [7]
+2021-06-29 14:42:22 Info: Types: Old - NoneType, New - list
+2021-06-29 14:42:22 Warning: openTypeNamePreferredFamilyName would be updated Old value: Psf Testing, new value: Psf Test
+2021-06-29 14:42:22 Info: Types: Old - string, New - string
+2021-06-29 14:42:22 Progress: Checking lib.plist metadata
+2021-06-29 14:42:22 Warning: com.schriftgestaltung.disablesAutomaticAlignment would be deleted - obsolete key Old value: True
+2021-06-29 14:42:22 Info: Types: Old - bool, New - NoneType
+2021-06-29 14:42:22 Warning: com.schriftgestaltung.disablesLastChange would be deleted - obsolete key Old value: True
+2021-06-29 14:42:22 Info: Types: Old - bool, New - NoneType
+2021-06-29 14:42:22 Progress: Check & fix results:- Errors: 0, Changes to make: 9, Other warnings: 0
+2021-06-29 14:42:22 Progress: See log file for details
+2021-06-29 14:42:22 Progress: Processing font for output
+2021-06-29 14:42:22 Progress: Output UFO already exists - reading for comparison
+2021-06-29 14:42:22 Progress: Writing font to local/testresults/ufo/psfsetassocfeat.ufo
+2021-06-29 14:42:22 Info: Processing glyphs directory
diff --git a/tests/reference/ufo/psfsetassocfeat.ufo/fontinfo.plist b/tests/reference/ufo/psfsetassocfeat.ufo/fontinfo.plist
new file mode 100644
index 0000000..52c03d6
--- /dev/null
+++ b/tests/reference/ufo/psfsetassocfeat.ufo/fontinfo.plist
@@ -0,0 +1,243 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+ <key>ascender</key>
+ <integer>2100</integer>
+ <key>capHeight</key>
+ <real>1485.3</real>
+ <key>copyright</key>
+ <string>Copyright (c) 2004-2021 SIL International</string>
+ <key>descender</key>
+ <integer>-550</integer>
+ <key>familyName</key>
+ <string>Psf Test</string>
+ <key>italicAngle</key>
+ <integer>-14</integer>
+ <key>openTypeHeadCreated</key>
+ <string>2021/01/29 10:05:06</string>
+ <key>openTypeHheaAscender</key>
+ <integer>2100</integer>
+ <key>openTypeHheaDescender</key>
+ <integer>-550</integer>
+ <key>openTypeHheaLineGap</key>
+ <integer>0</integer>
+ <key>openTypeNameDescription</key>
+ <string>Copyright (c) 2004-2021 SIL International</string>
+ <key>openTypeNameDesigner</key>
+ <string>Victor Gaultney, Annie Olsen, Julie Remington, Don Collingsworth, Eric Hays, Becca Hirsbrunner</string>
+ <key>openTypeNameDesignerURL</key>
+ <string>http://scripts.sil.org/</string>
+ <key>openTypeNameLicense</key>
+ <string>Copyright (c) 2004-2021 SIL International (http://www.sil.org/) with Reserved Font Names "Andika" and "SIL".
+
+This Font Software is licensed under the SIL Open Font License, Version 1.1. This license is copied below, and is also available with a FAQ at: http://scripts.sil.org/OFL
+
+
+-----------------------------------------------------------
+SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007
+-----------------------------------------------------------
+
+PREAMBLE
+The goals of the Open Font License (OFL) are to stimulate worldwide development of collaborative font projects, to support the font creation efforts of academic and linguistic communities, and to provide a free and open framework in which fonts may be shared and improved in partnership with others.
+
+The OFL allows the licensed fonts to be used, studied, modified and redistributed freely as long as they are not sold by themselves. The fonts, including any derivative works, can be bundled, embedded, redistributed and/or sold with any software provided that any reserved names are not used by derivative works. The fonts and derivatives, however, cannot be released under any other type of license. The requirement for fonts to remain under this license does not apply to any document created using the fonts or their derivatives.
+
+DEFINITIONS
+"Font Software" refers to the set of files released by the Copyright Holder(s) under this license and clearly marked as such. This may include source files, build scripts and documentation.
+
+"Reserved Font Name" refers to any names specified as such after the copyright statement(s).
+
+"Original Version" refers to the collection of Font Software components as distributed by the Copyright Holder(s).
+
+"Modified Version" refers to any derivative made by adding to, deleting, or substituting -- in part or in whole -- any of the components of the Original Version, by changing formats or by porting the Font Software to a new environment.
+
+"Author" refers to any designer, engineer, programmer, technical writer or other person who contributed to the Font Software.
+
+PERMISSION &amp; CONDITIONS
+Permission is hereby granted, free of charge, to any person obtaining a copy of the Font Software, to use, study, copy, merge, embed, modify, redistribute, and sell modified and unmodified copies of the Font Software, subject to the following conditions:
+
+1) Neither the Font Software nor any of its individual components, in Original or Modified Versions, may be sold by itself.
+
+2) Original or Modified Versions of the Font Software may be bundled, redistributed and/or sold with any software, provided that each copy contains the above copyright notice and this license. These can be included either as stand-alone text files, human-readable headers or in the appropriate machine-readable metadata fields within text or binary files as long as those fields can be easily viewed by the user.
+
+3) No Modified Version of the Font Software may use the Reserved Font Name(s) unless explicit written permission is granted by the corresponding Copyright Holder. This restriction only applies to the primary font name as presented to the users.
+
+4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font Software shall not be used to promote, endorse or advertise any Modified Version, except to acknowledge the contribution(s) of the Copyright Holder(s) and the Author(s) or with their explicit written permission.
+
+5) The Font Software, modified or unmodified, in part or in whole, must be distributed entirely under this license, and must not be distributed under any other license. The requirement for fonts to remain under this license does not apply to any document created using the Font Software.
+
+TERMINATION
+This license becomes null and void if any of the above conditions are not met.
+
+DISCLAIMER
+THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM OTHER DEALINGS IN THE FONT SOFTWARE.</string>
+ <key>openTypeNameLicenseURL</key>
+ <string>http://scripts.sil.org/OFL</string>
+ <key>openTypeNameManufacturer</key>
+ <string>SIL International</string>
+ <key>openTypeNameManufacturerURL</key>
+ <string>http://scripts.sil.org</string>
+ <key>openTypeNamePreferredFamilyName</key>
+ <string>Psf Testing</string>
+ <key>openTypeNamePreferredSubfamilyName</key>
+ <string>Italic</string>
+ <key>openTypeNameUniqueID</key>
+ <string>SIL International: Psf Test Italic: 2022</string>
+ <key>openTypeNameVersion</key>
+ <string>Version 5.550</string>
+ <key>openTypeOS2CodePageRanges</key>
+ <array>
+ <integer>0</integer>
+ <integer>1</integer>
+ <integer>2</integer>
+ <integer>4</integer>
+ <integer>7</integer>
+ <integer>8</integer>
+ </array>
+ <key>openTypeOS2FamilyClass</key>
+ <array>
+ <integer>0</integer>
+ <integer>0</integer>
+ </array>
+ <key>openTypeOS2Panose</key>
+ <array>
+ <integer>2</integer>
+ <integer>0</integer>
+ <integer>0</integer>
+ <integer>0</integer>
+ <integer>0</integer>
+ <integer>0</integer>
+ <integer>0</integer>
+ <integer>0</integer>
+ <integer>0</integer>
+ <integer>0</integer>
+ </array>
+ <key>openTypeOS2StrikeoutPosition</key>
+ <integer>700</integer>
+ <key>openTypeOS2StrikeoutSize</key>
+ <integer>100</integer>
+ <key>openTypeOS2SubscriptXOffset</key>
+ <integer>0</integer>
+ <key>openTypeOS2SubscriptXSize</key>
+ <integer>1433</integer>
+ <key>openTypeOS2SubscriptYOffset</key>
+ <integer>286</integer>
+ <key>openTypeOS2SubscriptYSize</key>
+ <integer>1331</integer>
+ <key>openTypeOS2SuperscriptXOffset</key>
+ <integer>0</integer>
+ <key>openTypeOS2SuperscriptXSize</key>
+ <integer>1433</integer>
+ <key>openTypeOS2SuperscriptYOffset</key>
+ <integer>976</integer>
+ <key>openTypeOS2SuperscriptYSize</key>
+ <integer>1331</integer>
+ <key>openTypeOS2Type</key>
+ <array/>
+ <key>openTypeOS2TypoAscender</key>
+ <integer>2100</integer>
+ <key>openTypeOS2TypoDescender</key>
+ <integer>-550</integer>
+ <key>openTypeOS2TypoLineGap</key>
+ <integer>1</integer>
+ <key>openTypeOS2UnicodeRanges</key>
+ <array>
+ <integer>0</integer>
+ <integer>1</integer>
+ <integer>6</integer>
+ <integer>7</integer>
+ <integer>31</integer>
+ <integer>33</integer>
+ <integer>35</integer>
+ <integer>36</integer>
+ <integer>37</integer>
+ <integer>38</integer>
+ <integer>39</integer>
+ <integer>40</integer>
+ <integer>45</integer>
+ <integer>46</integer>
+ <integer>47</integer>
+ <integer>57</integer>
+ <integer>60</integer>
+ <integer>62</integer>
+ <integer>64</integer>
+ <integer>67</integer>
+ <integer>69</integer>
+ <integer>89</integer>
+ </array>
+ <key>openTypeOS2VendorID</key>
+ <string>SIL</string>
+ <key>openTypeOS2WeightClass</key>
+ <integer>400</integer>
+ <key>openTypeOS2WidthClass</key>
+ <integer>5</integer>
+ <key>openTypeOS2WinAscent</key>
+ <integer>2100</integer>
+ <key>openTypeOS2WinDescent</key>
+ <integer>550</integer>
+ <key>postscriptBlueValues</key>
+ <array>
+ <integer>-490</integer>
+ <integer>-490</integer>
+ <integer>-25</integer>
+ <integer>0</integer>
+ <integer>1020</integer>
+ <integer>1040</integer>
+ <integer>1455</integer>
+ <integer>1485</integer>
+ <integer>1600</integer>
+ <integer>1620</integer>
+ </array>
+ <key>postscriptFontName</key>
+ <string>PsfTest-Italic</string>
+ <key>postscriptFullName</key>
+ <string>Psf Test Italic</string>
+ <key>postscriptStemSnapH</key>
+ <array>
+ <integer>140</integer>
+ <integer>145</integer>
+ <integer>150</integer>
+ <integer>155</integer>
+ <integer>160</integer>
+ <integer>165</integer>
+ <integer>170</integer>
+ <integer>175</integer>
+ <integer>185</integer>
+ <integer>270</integer>
+ </array>
+ <key>postscriptStemSnapV</key>
+ <array>
+ <integer>165</integer>
+ <integer>180</integer>
+ <integer>185</integer>
+ <integer>190</integer>
+ <integer>195</integer>
+ <integer>200</integer>
+ <integer>205</integer>
+ <integer>270</integer>
+ </array>
+ <key>postscriptUnderlinePosition</key>
+ <integer>-110</integer>
+ <key>postscriptUnderlineThickness</key>
+ <integer>80</integer>
+ <key>styleMapFamilyName</key>
+ <string>Psf test</string>
+ <key>styleMapStyleName</key>
+ <string>italic</string>
+ <key>styleName</key>
+ <string>Italic</string>
+ <key>trademark</key>
+ <string>Andika is a trademark of SIL International.</string>
+ <key>unitsPerEm</key>
+ <integer>2048</integer>
+ <key>versionMajor</key>
+ <integer>5</integer>
+ <key>versionMinor</key>
+ <integer>550</integer>
+ <key>xHeight</key>
+ <integer>1040</integer>
+ <key>year</key>
+ <integer>2021</integer>
+</dict>
+</plist>
diff --git a/tests/reference/ufo/psfsetassocfeat.ufo/glyphs/A_mpersand.glif b/tests/reference/ufo/psfsetassocfeat.ufo/glyphs/A_mpersand.glif
new file mode 100644
index 0000000..689cb3e
--- /dev/null
+++ b/tests/reference/ufo/psfsetassocfeat.ufo/glyphs/A_mpersand.glif
@@ -0,0 +1,61 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="Ampersand" format="2">
+ <advance width="1202"/>
+ <unicode hex="0026"/>
+ <outline>
+ <contour>
+ <point x="1054" y="559" type="line"/>
+ <point x="949" y="395"/>
+ <point x="616" y="147"/>
+ <point x="441" y="147" type="curve" smooth="yes"/>
+ <point x="318" y="147"/>
+ <point x="256" y="224"/>
+ <point x="256" y="314" type="curve" smooth="yes"/>
+ <point x="256" y="453"/>
+ <point x="369" y="575"/>
+ <point x="590" y="725" type="curve" smooth="yes"/>
+ <point x="836" y="892"/>
+ <point x="1022" y="1067"/>
+ <point x="1022" y="1223" type="curve" smooth="yes"/>
+ <point x="1022" y="1363"/>
+ <point x="894" y="1455"/>
+ <point x="762" y="1455" type="curve" smooth="yes"/>
+ <point x="504" y="1455"/>
+ <point x="378" y="1328"/>
+ <point x="378" y="1114" type="curve" smooth="yes"/>
+ <point x="378" y="953"/>
+ <point x="514" y="771"/>
+ <point x="614" y="559" type="curve" smooth="yes"/>
+ <point x="783" y="198"/>
+ <point x="906" y="-25"/>
+ <point x="958" y="-25" type="curve" smooth="yes"/>
+ <point x="993" y="-25"/>
+ <point x="1087" y="37"/>
+ <point x="1132" y="69" type="curve"/>
+ <point x="1046" y="108"/>
+ <point x="926" y="291"/>
+ <point x="756" y="666" type="curve" smooth="yes"/>
+ <point x="665" y="866"/>
+ <point x="544" y="1029"/>
+ <point x="544" y="1149" type="curve" smooth="yes"/>
+ <point x="544" y="1252"/>
+ <point x="632" y="1323"/>
+ <point x="724" y="1323" type="curve" smooth="yes"/>
+ <point x="794" y="1323"/>
+ <point x="858" y="1266"/>
+ <point x="858" y="1193" type="curve" smooth="yes"/>
+ <point x="858" y="1107"/>
+ <point x="743" y="1004"/>
+ <point x="492" y="826" type="curve" smooth="yes"/>
+ <point x="182" y="606"/>
+ <point x="73" y="439"/>
+ <point x="73" y="288" type="curve" smooth="yes"/>
+ <point x="73" y="113"/>
+ <point x="195" y="-25"/>
+ <point x="383" y="-25" type="curve" smooth="yes"/>
+ <point x="656" y="-25"/>
+ <point x="1009" y="269"/>
+ <point x="1126" y="426" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetassocfeat.ufo/glyphs/A_pos.glif b/tests/reference/ufo/psfsetassocfeat.ufo/glyphs/A_pos.glif
new file mode 100644
index 0000000..deb1650
--- /dev/null
+++ b/tests/reference/ufo/psfsetassocfeat.ufo/glyphs/A_pos.glif
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="Apos" format="2">
+ <advance width="585"/>
+ <unicode hex="0027"/>
+ <outline>
+ <contour>
+ <point x="560" y="1024" type="line"/>
+ <point x="599" y="1162"/>
+ <point x="643" y="1312"/>
+ <point x="732" y="1553" type="curve"/>
+ <point x="527" y="1553" type="line"/>
+ <point x="498" y="1312"/>
+ <point x="465" y="1162"/>
+ <point x="435" y="1024" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetassocfeat.ufo/glyphs/A_sterisk.glif b/tests/reference/ufo/psfsetassocfeat.ufo/glyphs/A_sterisk.glif
new file mode 100644
index 0000000..3027a5d
--- /dev/null
+++ b/tests/reference/ufo/psfsetassocfeat.ufo/glyphs/A_sterisk.glif
@@ -0,0 +1,51 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="Asterisk" format="2">
+ <advance width="1008"/>
+ <unicode hex="002A"/>
+ <outline>
+ <contour>
+ <point x="745" y="1568" type="line"/>
+ <point x="733" y="1438"/>
+ <point x="725" y="1359"/>
+ <point x="707" y="1274" type="curve"/>
+ <point x="644" y="1317"/>
+ <point x="587" y="1359"/>
+ <point x="498" y="1436" type="curve"/>
+ <point x="392" y="1313" type="line"/>
+ <point x="505" y="1264"/>
+ <point x="575" y="1236"/>
+ <point x="643" y="1196" type="curve"/>
+ <point x="556" y="1153"/>
+ <point x="474" y="1117"/>
+ <point x="340" y="1063" type="curve"/>
+ <point x="379" y="941" type="line"/>
+ <point x="504" y="1021"/>
+ <point x="584" y="1072"/>
+ <point x="668" y="1117" type="curve"/>
+ <point x="645" y="1034"/>
+ <point x="619" y="954"/>
+ <point x="575" y="823" type="curve"/>
+ <point x="715" y="823" type="line"/>
+ <point x="727" y="954"/>
+ <point x="741" y="1031"/>
+ <point x="758" y="1117" type="curve"/>
+ <point x="821" y="1073"/>
+ <point x="878" y="1032"/>
+ <point x="968" y="956" type="curve"/>
+ <point x="1073" y="1078" type="line"/>
+ <point x="959" y="1126"/>
+ <point x="890" y="1155"/>
+ <point x="823" y="1196" type="curve"/>
+ <point x="909" y="1236"/>
+ <point x="990" y="1273"/>
+ <point x="1126" y="1328" type="curve"/>
+ <point x="1086" y="1450" type="line"/>
+ <point x="961" y="1368"/>
+ <point x="883" y="1321"/>
+ <point x="797" y="1274" type="curve"/>
+ <point x="819" y="1359"/>
+ <point x="845" y="1438"/>
+ <point x="890" y="1568" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetassocfeat.ufo/glyphs/A_tS_gn.glif b/tests/reference/ufo/psfsetassocfeat.ufo/glyphs/A_tS_gn.glif
new file mode 100644
index 0000000..2cd2542
--- /dev/null
+++ b/tests/reference/ufo/psfsetassocfeat.ufo/glyphs/A_tS_gn.glif
@@ -0,0 +1,104 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="AtSgn" format="2">
+ <advance width="1682"/>
+ <unicode hex="0040"/>
+ <outline>
+ <contour>
+ <point x="1082" y="-10" type="line"/>
+ <point x="980" y="-69"/>
+ <point x="889" y="-93"/>
+ <point x="796" y="-93" type="curve" smooth="yes"/>
+ <point x="507" y="-93"/>
+ <point x="301" y="104"/>
+ <point x="301" y="414" type="curve" smooth="yes"/>
+ <point x="301" y="476"/>
+ <point x="309" y="543"/>
+ <point x="327" y="613" type="curve" smooth="yes"/>
+ <point x="425" y="1003"/>
+ <point x="782" y="1245"/>
+ <point x="1110" y="1245" type="curve" smooth="yes"/>
+ <point x="1433" y="1245"/>
+ <point x="1590" y="1060"/>
+ <point x="1590" y="813" type="curve" smooth="yes"/>
+ <point x="1590" y="760"/>
+ <point x="1582" y="705"/>
+ <point x="1568" y="647" type="curve" smooth="yes"/>
+ <point x="1510" y="413"/>
+ <point x="1365" y="309"/>
+ <point x="1297" y="309" type="curve" smooth="yes"/>
+ <point x="1261" y="309"/>
+ <point x="1238" y="344"/>
+ <point x="1238" y="420" type="curve" smooth="yes"/>
+ <point x="1238" y="468"/>
+ <point x="1247" y="533"/>
+ <point x="1268" y="617" type="curve" smooth="yes"/>
+ <point x="1354" y="960" type="line"/>
+ <point x="1276" y="995"/>
+ <point x="1155" y="1019"/>
+ <point x="1074" y="1019" type="curve" smooth="yes"/>
+ <point x="910" y="1019"/>
+ <point x="790" y="962"/>
+ <point x="673" y="828" type="curve" smooth="yes"/>
+ <point x="607" y="751"/>
+ <point x="554" y="650"/>
+ <point x="524" y="529" type="curve" smooth="yes"/>
+ <point x="514" y="488"/>
+ <point x="509" y="450"/>
+ <point x="509" y="416" type="curve" smooth="yes"/>
+ <point x="509" y="259"/>
+ <point x="609" y="179"/>
+ <point x="719" y="179" type="curve" smooth="yes"/>
+ <point x="836" y="179"/>
+ <point x="1017" y="359"/>
+ <point x="1099" y="480" type="curve"/>
+ <point x="1093" y="446"/>
+ <point x="1089" y="413"/>
+ <point x="1089" y="382" type="curve" smooth="yes"/>
+ <point x="1089" y="264"/>
+ <point x="1136" y="176"/>
+ <point x="1233" y="176" type="curve" smooth="yes"/>
+ <point x="1408" y="176"/>
+ <point x="1635" y="331"/>
+ <point x="1716" y="656" type="curve" smooth="yes"/>
+ <point x="1732" y="722"/>
+ <point x="1740" y="784"/>
+ <point x="1740" y="843" type="curve" smooth="yes"/>
+ <point x="1740" y="1161"/>
+ <point x="1513" y="1377"/>
+ <point x="1153" y="1377" type="curve" smooth="yes"/>
+ <point x="738" y="1377"/>
+ <point x="310" y="1143"/>
+ <point x="175" y="603" type="curve" smooth="yes"/>
+ <point x="155" y="522"/>
+ <point x="145" y="446"/>
+ <point x="145" y="375" type="curve" smooth="yes"/>
+ <point x="145" y="-5"/>
+ <point x="417" y="-230"/>
+ <point x="747" y="-230" type="curve" smooth="yes"/>
+ <point x="882" y="-230"/>
+ <point x="1044" y="-184"/>
+ <point x="1161" y="-116" type="curve"/>
+ </contour>
+ <contour>
+ <point x="1141" y="706" type="line"/>
+ <point x="1075" y="570"/>
+ <point x="856" y="314"/>
+ <point x="766" y="314" type="curve" smooth="yes"/>
+ <point x="712" y="314"/>
+ <point x="669" y="362"/>
+ <point x="669" y="459" type="curve" smooth="yes"/>
+ <point x="669" y="491"/>
+ <point x="674" y="530"/>
+ <point x="685" y="573" type="curve" smooth="yes"/>
+ <point x="704" y="649"/>
+ <point x="739" y="726"/>
+ <point x="780" y="774" type="curve" smooth="yes"/>
+ <point x="859" y="868"/>
+ <point x="943" y="887"/>
+ <point x="1011" y="887" type="curve" smooth="yes"/>
+ <point x="1085" y="887"/>
+ <point x="1148" y="868"/>
+ <point x="1177" y="853" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetassocfeat.ufo/glyphs/C_ircumA_ccent.glif b/tests/reference/ufo/psfsetassocfeat.ufo/glyphs/C_ircumA_ccent.glif
new file mode 100644
index 0000000..91ab811
--- /dev/null
+++ b/tests/reference/ufo/psfsetassocfeat.ufo/glyphs/C_ircumA_ccent.glif
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="CircumAccent" format="2">
+ <advance width="830"/>
+ <unicode hex="005E"/>
+ <anchor x="705" y="1635" name="U"/>
+ <outline>
+ <contour>
+ <point x="316" y="1147" type="line"/>
+ <point x="660" y="1421" type="line"/>
+ <point x="866" y="1147" type="line"/>
+ <point x="1015" y="1147" type="line"/>
+ <point x="761" y="1568" type="line"/>
+ <point x="591" y="1568" type="line"/>
+ <point x="166" y="1147" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetassocfeat.ufo/glyphs/C_olon.glif b/tests/reference/ufo/psfsetassocfeat.ufo/glyphs/C_olon.glif
new file mode 100644
index 0000000..bcccfc2
--- /dev/null
+++ b/tests/reference/ufo/psfsetassocfeat.ufo/glyphs/C_olon.glif
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="Colon" format="2">
+ <advance width="620"/>
+ <unicode hex="003A"/>
+ <outline>
+ <contour>
+ <point x="314" y="758" type="curve" smooth="yes"/>
+ <point x="314" y="696"/>
+ <point x="365" y="642"/>
+ <point x="430" y="642" type="curve" smooth="yes"/>
+ <point x="514" y="642"/>
+ <point x="590" y="712"/>
+ <point x="590" y="792" type="curve" smooth="yes"/>
+ <point x="590" y="854"/>
+ <point x="540" y="907"/>
+ <point x="476" y="907" type="curve" smooth="yes"/>
+ <point x="393" y="907"/>
+ <point x="314" y="837"/>
+ </contour>
+ <contour>
+ <point x="148" y="90" type="curve" smooth="yes"/>
+ <point x="148" y="28"/>
+ <point x="198" y="-25"/>
+ <point x="263" y="-25" type="curve" smooth="yes"/>
+ <point x="347" y="-25"/>
+ <point x="424" y="45"/>
+ <point x="424" y="125" type="curve" smooth="yes"/>
+ <point x="424" y="186"/>
+ <point x="374" y="240"/>
+ <point x="309" y="240" type="curve" smooth="yes"/>
+ <point x="225" y="240"/>
+ <point x="148" y="170"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetassocfeat.ufo/glyphs/C_ombA_cute.glif b/tests/reference/ufo/psfsetassocfeat.ufo/glyphs/C_ombA_cute.glif
new file mode 100644
index 0000000..a7607fe
--- /dev/null
+++ b/tests/reference/ufo/psfsetassocfeat.ufo/glyphs/C_ombA_cute.glif
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="CombAcute" format="2">
+ <unicode hex="0301"/>
+ <anchor x="-221" y="1635" name="U"/>
+ <anchor x="-355" y="1100" name="_U"/>
+ <outline>
+ <contour>
+ <point x="-99" y="1568" type="line"/>
+ <point x="-524" y="1147" type="line"/>
+ <point x="-354" y="1147" type="line"/>
+ <point x="150" y="1568" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetassocfeat.ufo/glyphs/C_ombC_ircum.glif b/tests/reference/ufo/psfsetassocfeat.ufo/glyphs/C_ombC_ircum.glif
new file mode 100644
index 0000000..6614f85
--- /dev/null
+++ b/tests/reference/ufo/psfsetassocfeat.ufo/glyphs/C_ombC_ircum.glif
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="CombCircum" format="2">
+ <unicode hex="0302"/>
+ <anchor x="-221" y="1635" name="U"/>
+ <anchor x="-320" y="1100" name="_U"/>
+ <outline>
+ <contour>
+ <point x="-619" y="1147" type="line"/>
+ <point x="-275" y="1421" type="line"/>
+ <point x="-69" y="1147" type="line"/>
+ <point x="80" y="1147" type="line"/>
+ <point x="-174" y="1568" type="line"/>
+ <point x="-344" y="1568" type="line"/>
+ <point x="-769" y="1147" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetassocfeat.ufo/glyphs/C_ombD_iaer.glif b/tests/reference/ufo/psfsetassocfeat.ufo/glyphs/C_ombD_iaer.glif
new file mode 100644
index 0000000..d6b35b7
--- /dev/null
+++ b/tests/reference/ufo/psfsetassocfeat.ufo/glyphs/C_ombD_iaer.glif
@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="CombDiaer" format="2">
+ <unicode hex="0308"/>
+ <anchor x="-253" y="1505" name="U"/>
+ <anchor x="-350" y="1100" name="_U"/>
+ <outline>
+ <contour>
+ <point x="39" y="1338" type="curve" smooth="yes"/>
+ <point x="39" y="1399"/>
+ <point x="-7" y="1450"/>
+ <point x="-72" y="1450" type="curve" smooth="yes"/>
+ <point x="-167" y="1450"/>
+ <point x="-229" y="1372"/>
+ <point x="-229" y="1299" type="curve" smooth="yes"/>
+ <point x="-229" y="1238"/>
+ <point x="-182" y="1186"/>
+ <point x="-118" y="1186" type="curve" smooth="yes"/>
+ <point x="-33" y="1186"/>
+ <point x="39" y="1259"/>
+ </contour>
+ <contour>
+ <point x="-381" y="1338" type="curve" smooth="yes"/>
+ <point x="-381" y="1399"/>
+ <point x="-427" y="1450"/>
+ <point x="-492" y="1450" type="curve" smooth="yes"/>
+ <point x="-587" y="1450"/>
+ <point x="-649" y="1372"/>
+ <point x="-649" y="1299" type="curve" smooth="yes"/>
+ <point x="-649" y="1238"/>
+ <point x="-602" y="1186"/>
+ <point x="-538" y="1186" type="curve" smooth="yes"/>
+ <point x="-453" y="1186"/>
+ <point x="-381" y="1259"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetassocfeat.ufo/glyphs/C_ombG_rave.glif b/tests/reference/ufo/psfsetassocfeat.ufo/glyphs/C_ombG_rave.glif
new file mode 100644
index 0000000..8869bb9
--- /dev/null
+++ b/tests/reference/ufo/psfsetassocfeat.ufo/glyphs/C_ombG_rave.glif
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="CombGrave" format="2">
+ <unicode hex="0300"/>
+ <anchor x="-201" y="1635" name="U"/>
+ <anchor x="-335" y="1100" name="_U"/>
+ <outline>
+ <contour>
+ <point x="-619" y="1568" type="line"/>
+ <point x="-284" y="1147" type="line"/>
+ <point x="-134" y="1147" type="line"/>
+ <point x="-409" y="1568" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetassocfeat.ufo/glyphs/C_ombR_ingA_bv.glif b/tests/reference/ufo/psfsetassocfeat.ufo/glyphs/C_ombR_ingA_bv.glif
new file mode 100644
index 0000000..38232a0
--- /dev/null
+++ b/tests/reference/ufo/psfsetassocfeat.ufo/glyphs/C_ombR_ingA_bv.glif
@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="CombRingAbv" format="2">
+ <unicode hex="030A"/>
+ <anchor x="-221" y="1635" name="U"/>
+ <anchor x="-385" y="1100" name="_U"/>
+ <outline>
+ <contour>
+ <point x="-377" y="1259" type="curve" smooth="yes"/>
+ <point x="-427" y="1259"/>
+ <point x="-456" y="1287"/>
+ <point x="-456" y="1329" type="curve" smooth="yes"/>
+ <point x="-456" y="1400"/>
+ <point x="-393" y="1455"/>
+ <point x="-328" y="1455" type="curve" smooth="yes"/>
+ <point x="-278" y="1455"/>
+ <point x="-248" y="1428"/>
+ <point x="-248" y="1385" type="curve" smooth="yes"/>
+ <point x="-248" y="1314"/>
+ <point x="-312" y="1259"/>
+ </contour>
+ <contour>
+ <point x="-573" y="1320" type="curve" smooth="yes"/>
+ <point x="-573" y="1224"/>
+ <point x="-498" y="1147"/>
+ <point x="-395" y="1147" type="curve" smooth="yes"/>
+ <point x="-257" y="1147"/>
+ <point x="-131" y="1263"/>
+ <point x="-131" y="1394" type="curve" smooth="yes"/>
+ <point x="-131" y="1491"/>
+ <point x="-206" y="1568"/>
+ <point x="-310" y="1568" type="curve" smooth="yes"/>
+ <point x="-448" y="1568"/>
+ <point x="-573" y="1451"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetassocfeat.ufo/glyphs/C_ombT_ilde.glif b/tests/reference/ufo/psfsetassocfeat.ufo/glyphs/C_ombT_ilde.glif
new file mode 100644
index 0000000..f79322e
--- /dev/null
+++ b/tests/reference/ufo/psfsetassocfeat.ufo/glyphs/C_ombT_ilde.glif
@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="CombTilde" format="2">
+ <unicode hex="0303"/>
+ <anchor x="-290" y="1475" name="U"/>
+ <anchor x="-385" y="1100" name="_U"/>
+ <outline>
+ <contour>
+ <point x="-646" y="1181" type="line"/>
+ <point x="-629" y="1229"/>
+ <point x="-589" y="1269"/>
+ <point x="-540" y="1269" type="curve" smooth="yes"/>
+ <point x="-503" y="1269"/>
+ <point x="-466" y="1253"/>
+ <point x="-398" y="1218" type="curve" smooth="yes"/>
+ <point x="-344" y="1190"/>
+ <point x="-296" y="1171"/>
+ <point x="-243" y="1171" type="curve" smooth="yes"/>
+ <point x="-120" y="1171"/>
+ <point x="-15" y="1286"/>
+ <point x="16" y="1411" type="curve"/>
+ <point x="-89" y="1411" type="line"/>
+ <point x="-107" y="1366"/>
+ <point x="-147" y="1323"/>
+ <point x="-194" y="1323" type="curve" smooth="yes"/>
+ <point x="-236" y="1323"/>
+ <point x="-273" y="1342"/>
+ <point x="-338" y="1370" type="curve" smooth="yes"/>
+ <point x="-401" y="1397"/>
+ <point x="-442" y="1421"/>
+ <point x="-498" y="1421" type="curve" smooth="yes"/>
+ <point x="-617" y="1421"/>
+ <point x="-721" y="1300"/>
+ <point x="-751" y="1181" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetassocfeat.ufo/glyphs/C_omma.glif b/tests/reference/ufo/psfsetassocfeat.ufo/glyphs/C_omma.glif
new file mode 100644
index 0000000..eaff517
--- /dev/null
+++ b/tests/reference/ufo/psfsetassocfeat.ufo/glyphs/C_omma.glif
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="Comma" format="2">
+ <advance width="630"/>
+ <unicode hex="002C"/>
+ <outline>
+ <contour>
+ <point x="137" y="49" type="line"/>
+ <point x="277" y="49" type="line"/>
+ <point x="252" y="-50"/>
+ <point x="145" y="-169"/>
+ <point x="73" y="-225" type="curve"/>
+ <point x="163" y="-265" type="line"/>
+ <point x="280" y="-175"/>
+ <point x="431" y="-28"/>
+ <point x="431" y="118" type="curve" smooth="yes"/>
+ <point x="431" y="193"/>
+ <point x="378" y="245"/>
+ <point x="311" y="245" type="curve" smooth="yes"/>
+ <point x="254" y="245"/>
+ <point x="190" y="209"/>
+ <point x="161" y="147" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetassocfeat.ufo/glyphs/D_igitE_ight.glif b/tests/reference/ufo/psfsetassocfeat.ufo/glyphs/D_igitE_ight.glif
new file mode 100644
index 0000000..262f860
--- /dev/null
+++ b/tests/reference/ufo/psfsetassocfeat.ufo/glyphs/D_igitE_ight.glif
@@ -0,0 +1,63 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="DigitEight" format="2">
+ <advance width="1180"/>
+ <unicode hex="0038"/>
+ <anchor x="515" y="-100" name="L"/>
+ <anchor x="922" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="542" y="-25" type="curve" smooth="yes"/>
+ <point x="839" y="-25"/>
+ <point x="1160" y="170"/>
+ <point x="1160" y="475" type="curve" smooth="yes"/>
+ <point x="1160" y="626"/>
+ <point x="1068" y="733"/>
+ <point x="988" y="779" type="curve"/>
+ <point x="1155" y="860"/>
+ <point x="1270" y="970"/>
+ <point x="1270" y="1151" type="curve" smooth="yes"/>
+ <point x="1270" y="1340"/>
+ <point x="1102" y="1455"/>
+ <point x="901" y="1455" type="curve" smooth="yes"/>
+ <point x="620" y="1455"/>
+ <point x="348" y="1292"/>
+ <point x="348" y="1018" type="curve" smooth="yes"/>
+ <point x="348" y="891"/>
+ <point x="427" y="814"/>
+ <point x="483" y="779" type="curve"/>
+ <point x="297" y="706"/>
+ <point x="115" y="549"/>
+ <point x="115" y="325" type="curve" smooth="yes"/>
+ <point x="115" y="111"/>
+ <point x="317" y="-25"/>
+ </contour>
+ <contour>
+ <point x="750" y="848" type="curve" smooth="yes"/>
+ <point x="628" y="848"/>
+ <point x="541" y="917"/>
+ <point x="541" y="1029" type="curve" smooth="yes"/>
+ <point x="541" y="1205"/>
+ <point x="704" y="1299"/>
+ <point x="862" y="1299" type="curve" smooth="yes"/>
+ <point x="985" y="1299"/>
+ <point x="1076" y="1235"/>
+ <point x="1076" y="1128" type="curve" smooth="yes"/>
+ <point x="1076" y="955"/>
+ <point x="907" y="848"/>
+ </contour>
+ <contour>
+ <point x="564" y="142" type="curve" smooth="yes"/>
+ <point x="413" y="142"/>
+ <point x="322" y="225"/>
+ <point x="322" y="350" type="curve" smooth="yes"/>
+ <point x="322" y="557"/>
+ <point x="520" y="696"/>
+ <point x="712" y="696" type="curve" smooth="yes"/>
+ <point x="864" y="696"/>
+ <point x="961" y="602"/>
+ <point x="961" y="476" type="curve" smooth="yes"/>
+ <point x="961" y="266"/>
+ <point x="753" y="142"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetassocfeat.ufo/glyphs/D_igitF_ive.glif b/tests/reference/ufo/psfsetassocfeat.ufo/glyphs/D_igitF_ive.glif
new file mode 100644
index 0000000..a224838
--- /dev/null
+++ b/tests/reference/ufo/psfsetassocfeat.ufo/glyphs/D_igitF_ive.glif
@@ -0,0 +1,44 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="DigitFive" format="2">
+ <advance width="1180"/>
+ <unicode hex="0035"/>
+ <anchor x="515" y="-100" name="L"/>
+ <anchor x="922" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="1296" y="1431" type="line"/>
+ <point x="491" y="1431" type="line"/>
+ <point x="302" y="671" type="line"/>
+ <point x="438" y="718"/>
+ <point x="537" y="735"/>
+ <point x="643" y="735" type="curve" smooth="yes"/>
+ <point x="784" y="735"/>
+ <point x="933" y="660"/>
+ <point x="933" y="508" type="curve" smooth="yes"/>
+ <point x="933" y="273"/>
+ <point x="710" y="152"/>
+ <point x="497" y="152" type="curve" smooth="yes"/>
+ <point x="357" y="152"/>
+ <point x="263" y="195"/>
+ <point x="170" y="284" type="curve"/>
+ <point x="89" y="78" type="line"/>
+ <point x="195" y="2"/>
+ <point x="326" y="-25"/>
+ <point x="481" y="-25" type="curve" smooth="yes"/>
+ <point x="807" y="-25"/>
+ <point x="1129" y="190"/>
+ <point x="1129" y="546" type="curve" smooth="yes"/>
+ <point x="1129" y="757"/>
+ <point x="951" y="911"/>
+ <point x="702" y="911" type="curve" smooth="yes"/>
+ <point x="629" y="911"/>
+ <point x="576" y="906"/>
+ <point x="544" y="902" type="curve"/>
+ <point x="635" y="1264" type="line"/>
+ <point x="1020" y="1264" type="line" smooth="yes"/>
+ <point x="1104" y="1264"/>
+ <point x="1179" y="1260"/>
+ <point x="1250" y="1245" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetassocfeat.ufo/glyphs/D_igitF_our.glif b/tests/reference/ufo/psfsetassocfeat.ufo/glyphs/D_igitF_our.glif
new file mode 100644
index 0000000..eeccb48
--- /dev/null
+++ b/tests/reference/ufo/psfsetassocfeat.ufo/glyphs/D_igitF_our.glif
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="DigitFour" format="2">
+ <advance width="1180"/>
+ <unicode hex="0034"/>
+ <anchor x="522" y="-100" name="L"/>
+ <anchor x="929" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="1161" y="387" type="line"/>
+ <point x="1199" y="539" type="line"/>
+ <point x="1009" y="539" type="line"/>
+ <point x="1236" y="1450" type="line"/>
+ <point x="1026" y="1450" type="line"/>
+ <point x="144" y="539" type="line"/>
+ <point x="106" y="387" type="line"/>
+ <point x="781" y="387" type="line"/>
+ <point x="685" y="0" type="line"/>
+ <point x="875" y="0" type="line"/>
+ <point x="971" y="387" type="line"/>
+ </contour>
+ <contour>
+ <point x="985" y="1205" type="line"/>
+ <point x="819" y="539" type="line"/>
+ <point x="337" y="539" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetassocfeat.ufo/glyphs/D_igitN_ine.glif b/tests/reference/ufo/psfsetassocfeat.ufo/glyphs/D_igitN_ine.glif
new file mode 100644
index 0000000..191cd79
--- /dev/null
+++ b/tests/reference/ufo/psfsetassocfeat.ufo/glyphs/D_igitN_ine.glif
@@ -0,0 +1,49 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="DigitNine" format="2">
+ <advance width="1180"/>
+ <unicode hex="0039"/>
+ <anchor x="515" y="-100" name="L"/>
+ <anchor x="922" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="157" y="94" type="line"/>
+ <point x="208" y="29"/>
+ <point x="355" y="-25"/>
+ <point x="473" y="-25" type="curve" smooth="yes"/>
+ <point x="999" y="-25"/>
+ <point x="1267" y="520"/>
+ <point x="1267" y="982" type="curve" smooth="yes"/>
+ <point x="1267" y="1248"/>
+ <point x="1127" y="1455"/>
+ <point x="866" y="1455" type="curve" smooth="yes"/>
+ <point x="596" y="1455"/>
+ <point x="303" y="1269"/>
+ <point x="303" y="932" type="curve" smooth="yes"/>
+ <point x="303" y="761"/>
+ <point x="425" y="574"/>
+ <point x="661" y="574" type="curve" smooth="yes"/>
+ <point x="852" y="574"/>
+ <point x="1036" y="683"/>
+ <point x="1172" y="840" type="curve"/>
+ <point x="1121" y="922" type="line"/>
+ <point x="1019" y="810"/>
+ <point x="872" y="745"/>
+ <point x="717" y="745" type="curve" smooth="yes"/>
+ <point x="584" y="745"/>
+ <point x="498" y="833"/>
+ <point x="498" y="956" type="curve" smooth="yes"/>
+ <point x="498" y="1146"/>
+ <point x="638" y="1284"/>
+ <point x="821" y="1284" type="curve" smooth="yes"/>
+ <point x="998" y="1284"/>
+ <point x="1073" y="1119"/>
+ <point x="1073" y="956" type="curve" smooth="yes"/>
+ <point x="1073" y="455"/>
+ <point x="760" y="147"/>
+ <point x="496" y="147" type="curve" smooth="yes"/>
+ <point x="410" y="147"/>
+ <point x="298" y="209"/>
+ <point x="249" y="285" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetassocfeat.ufo/glyphs/D_igitO_ne.glif b/tests/reference/ufo/psfsetassocfeat.ufo/glyphs/D_igitO_ne.glif
new file mode 100644
index 0000000..a639774
--- /dev/null
+++ b/tests/reference/ufo/psfsetassocfeat.ufo/glyphs/D_igitO_ne.glif
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="DigitOne" format="2">
+ <advance width="1180"/>
+ <unicode hex="0031"/>
+ <anchor x="515" y="-100" name="L"/>
+ <anchor x="922" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="1021" y="167" type="line"/>
+ <point x="706" y="167" type="line"/>
+ <point x="1026" y="1450" type="line"/>
+ <point x="856" y="1450" type="line"/>
+ <point x="459" y="1243" type="line"/>
+ <point x="440" y="1066" type="line"/>
+ <point x="782" y="1235" type="line"/>
+ <point x="516" y="167" type="line"/>
+ <point x="201" y="167" type="line"/>
+ <point x="160" y="0" type="line"/>
+ <point x="980" y="0" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetassocfeat.ufo/glyphs/D_igitS_even.glif b/tests/reference/ufo/psfsetassocfeat.ufo/glyphs/D_igitS_even.glif
new file mode 100644
index 0000000..68c6ef6
--- /dev/null
+++ b/tests/reference/ufo/psfsetassocfeat.ufo/glyphs/D_igitS_even.glif
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="DigitSeven" format="2">
+ <advance width="1180"/>
+ <unicode hex="0037"/>
+ <anchor x="515" y="-100" name="L"/>
+ <anchor x="922" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="420" y="0" type="line"/>
+ <point x="661" y="450"/>
+ <point x="972" y="877"/>
+ <point x="1367" y="1274" type="curve"/>
+ <point x="1406" y="1431" type="line"/>
+ <point x="386" y="1431" type="line"/>
+ <point x="341" y="1245" type="line"/>
+ <point x="421" y="1260"/>
+ <point x="538" y="1264"/>
+ <point x="726" y="1264" type="curve" smooth="yes"/>
+ <point x="1126" y="1264" type="line"/>
+ <point x="774" y="889"/>
+ <point x="517" y="555"/>
+ <point x="215" y="0" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetassocfeat.ufo/glyphs/D_igitS_ix.glif b/tests/reference/ufo/psfsetassocfeat.ufo/glyphs/D_igitS_ix.glif
new file mode 100644
index 0000000..b6be793
--- /dev/null
+++ b/tests/reference/ufo/psfsetassocfeat.ufo/glyphs/D_igitS_ix.glif
@@ -0,0 +1,49 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="DigitSix" format="2">
+ <advance width="1180"/>
+ <unicode hex="0036"/>
+ <anchor x="515" y="-100" name="L"/>
+ <anchor x="922" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="1313" y="1347" type="line"/>
+ <point x="1248" y="1418"/>
+ <point x="1135" y="1455"/>
+ <point x="1017" y="1455" type="curve" smooth="yes"/>
+ <point x="481" y="1454"/>
+ <point x="208" y="915"/>
+ <point x="208" y="475" type="curve" smooth="yes"/>
+ <point x="208" y="167"/>
+ <point x="392" y="-25"/>
+ <point x="623" y="-25" type="curve" smooth="yes"/>
+ <point x="947" y="-25"/>
+ <point x="1183" y="169"/>
+ <point x="1183" y="517" type="curve" smooth="yes"/>
+ <point x="1183" y="709"/>
+ <point x="1029" y="887"/>
+ <point x="793" y="887" type="curve" smooth="yes"/>
+ <point x="636" y="887"/>
+ <point x="432" y="784"/>
+ <point x="317" y="633" type="curve"/>
+ <point x="364" y="559" type="line"/>
+ <point x="471" y="660"/>
+ <point x="596" y="716"/>
+ <point x="751" y="716" type="curve" smooth="yes"/>
+ <point x="898" y="716"/>
+ <point x="987" y="614"/>
+ <point x="987" y="454" type="curve" smooth="yes"/>
+ <point x="987" y="263"/>
+ <point x="816" y="147"/>
+ <point x="656" y="147" type="curve" smooth="yes"/>
+ <point x="491" y="147"/>
+ <point x="403" y="284"/>
+ <point x="403" y="472" type="curve" smooth="yes"/>
+ <point x="403" y="962"/>
+ <point x="664" y="1284"/>
+ <point x="985" y="1284" type="curve" smooth="yes"/>
+ <point x="1081" y="1284"/>
+ <point x="1174" y="1235"/>
+ <point x="1222" y="1156" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetassocfeat.ufo/glyphs/D_igitT_hree.glif b/tests/reference/ufo/psfsetassocfeat.ufo/glyphs/D_igitT_hree.glif
new file mode 100644
index 0000000..e01df2c
--- /dev/null
+++ b/tests/reference/ufo/psfsetassocfeat.ufo/glyphs/D_igitT_hree.glif
@@ -0,0 +1,52 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="DigitThree" format="2">
+ <advance width="1180"/>
+ <unicode hex="0033"/>
+ <anchor x="515" y="-100" name="L"/>
+ <anchor x="922" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="562" y="853" type="line"/>
+ <point x="521" y="686" type="line"/>
+ <point x="591" y="686" type="line" smooth="yes"/>
+ <point x="802" y="686"/>
+ <point x="944" y="606"/>
+ <point x="944" y="476" type="curve" smooth="yes"/>
+ <point x="944" y="268"/>
+ <point x="738" y="147"/>
+ <point x="551" y="147" type="curve" smooth="yes"/>
+ <point x="371" y="147"/>
+ <point x="260" y="227"/>
+ <point x="181" y="348" type="curve"/>
+ <point x="104" y="137" type="line"/>
+ <point x="185" y="41"/>
+ <point x="341" y="-25"/>
+ <point x="518" y="-25" type="curve" smooth="yes"/>
+ <point x="815" y="-25"/>
+ <point x="1141" y="168"/>
+ <point x="1141" y="475" type="curve" smooth="yes"/>
+ <point x="1141" y="670"/>
+ <point x="973" y="763"/>
+ <point x="855" y="784" type="curve"/>
+ <point x="1046" y="827"/>
+ <point x="1266" y="955"/>
+ <point x="1266" y="1163" type="curve" smooth="yes"/>
+ <point x="1266" y="1338"/>
+ <point x="1073" y="1455"/>
+ <point x="852" y="1455" type="curve" smooth="yes"/>
+ <point x="685" y="1455"/>
+ <point x="536" y="1388"/>
+ <point x="433" y="1299" type="curve"/>
+ <point x="427" y="1132" type="line"/>
+ <point x="568" y="1246"/>
+ <point x="696" y="1284"/>
+ <point x="850" y="1284" type="curve" smooth="yes"/>
+ <point x="957" y="1284"/>
+ <point x="1068" y="1236"/>
+ <point x="1068" y="1137" type="curve" smooth="yes"/>
+ <point x="1068" y="949"/>
+ <point x="781" y="853"/>
+ <point x="632" y="853" type="curve" smooth="yes"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetassocfeat.ufo/glyphs/D_igitT_wo.glif b/tests/reference/ufo/psfsetassocfeat.ufo/glyphs/D_igitT_wo.glif
new file mode 100644
index 0000000..d1bbb54
--- /dev/null
+++ b/tests/reference/ufo/psfsetassocfeat.ufo/glyphs/D_igitT_wo.glif
@@ -0,0 +1,37 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="DigitTwo" format="2">
+ <advance width="1180"/>
+ <unicode hex="0032"/>
+ <anchor x="515" y="-100" name="L"/>
+ <anchor x="882" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="1063" y="176" type="line"/>
+ <point x="980" y="163"/>
+ <point x="822" y="162"/>
+ <point x="625" y="162" type="curve" smooth="yes"/>
+ <point x="370" y="162" type="line"/>
+ <point x="783" y="393"/>
+ <point x="1210" y="830"/>
+ <point x="1210" y="1098" type="curve" smooth="yes"/>
+ <point x="1210" y="1296"/>
+ <point x="1075" y="1455"/>
+ <point x="842" y="1455" type="curve" smooth="yes"/>
+ <point x="673" y="1455"/>
+ <point x="488" y="1374"/>
+ <point x="380" y="1264" type="curve"/>
+ <point x="388" y="1098" type="line"/>
+ <point x="503" y="1203"/>
+ <point x="660" y="1279"/>
+ <point x="783" y="1279" type="curve" smooth="yes"/>
+ <point x="915" y="1279"/>
+ <point x="1003" y="1199"/>
+ <point x="1003" y="1063" type="curve" smooth="yes"/>
+ <point x="1003" y="848"/>
+ <point x="506" y="386"/>
+ <point x="101" y="167" type="curve"/>
+ <point x="60" y="0" type="line"/>
+ <point x="1020" y="0" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetassocfeat.ufo/glyphs/D_igitZ_ero.glif b/tests/reference/ufo/psfsetassocfeat.ufo/glyphs/D_igitZ_ero.glif
new file mode 100644
index 0000000..5d1bf0e
--- /dev/null
+++ b/tests/reference/ufo/psfsetassocfeat.ufo/glyphs/D_igitZ_ero.glif
@@ -0,0 +1,49 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="DigitZero" format="2">
+ <advance width="1180"/>
+ <unicode hex="0030"/>
+ <anchor x="520" y="-100" name="L"/>
+ <anchor x="927" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="1024" y="711" type="curve" smooth="yes"/>
+ <point x="925" y="312"/>
+ <point x="747" y="142"/>
+ <point x="565" y="142" type="curve" smooth="yes"/>
+ <point x="432" y="142"/>
+ <point x="360" y="218"/>
+ <point x="360" y="383" type="curve" smooth="yes"/>
+ <point x="360" y="468"/>
+ <point x="377" y="579"/>
+ <point x="412" y="720" type="curve" smooth="yes"/>
+ <point x="512" y="1120"/>
+ <point x="678" y="1289"/>
+ <point x="871" y="1289" type="curve" smooth="yes"/>
+ <point x="1006" y="1289"/>
+ <point x="1077" y="1223"/>
+ <point x="1077" y="1051" type="curve" smooth="yes"/>
+ <point x="1077" y="966"/>
+ <point x="1060" y="854"/>
+ </contour>
+ <contour>
+ <point x="1230" y="715" type="curve" smooth="yes"/>
+ <point x="1262" y="841"/>
+ <point x="1276" y="949"/>
+ <point x="1276" y="1040" type="curve" smooth="yes"/>
+ <point x="1276" y="1335"/>
+ <point x="1124" y="1455"/>
+ <point x="902" y="1455" type="curve" smooth="yes"/>
+ <point x="613" y="1455"/>
+ <point x="344" y="1267"/>
+ <point x="206" y="716" type="curve" smooth="yes"/>
+ <point x="173" y="584"/>
+ <point x="158" y="474"/>
+ <point x="158" y="381" type="curve" smooth="yes"/>
+ <point x="158" y="104"/>
+ <point x="313" y="-25"/>
+ <point x="533" y="-25" type="curve" smooth="yes"/>
+ <point x="804" y="-25"/>
+ <point x="1086" y="138"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetassocfeat.ufo/glyphs/D_ollarS_gn.glif b/tests/reference/ufo/psfsetassocfeat.ufo/glyphs/D_ollarS_gn.glif
new file mode 100644
index 0000000..5c2db20
--- /dev/null
+++ b/tests/reference/ufo/psfsetassocfeat.ufo/glyphs/D_ollarS_gn.glif
@@ -0,0 +1,53 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="DollarSgn" format="2">
+ <advance width="1180"/>
+ <unicode hex="0024"/>
+ <outline>
+ <contour>
+ <point x="1225" y="1280" type="line"/>
+ <point x="1119" y="1337"/>
+ <point x="1023" y="1361"/>
+ <point x="882" y="1361" type="curve" smooth="yes"/>
+ <point x="513" y="1361"/>
+ <point x="354" y="1182"/>
+ <point x="354" y="992" type="curve" smooth="yes"/>
+ <point x="354" y="837"/>
+ <point x="446" y="771"/>
+ <point x="639" y="650" type="curve" smooth="yes"/>
+ <point x="844" y="521"/>
+ <point x="919" y="439"/>
+ <point x="919" y="357" type="curve" smooth="yes"/>
+ <point x="919" y="244"/>
+ <point x="826" y="158"/>
+ <point x="635" y="158" type="curve" smooth="yes"/>
+ <point x="469" y="158"/>
+ <point x="314" y="266"/>
+ <point x="251" y="347" type="curve"/>
+ <point x="163" y="162" type="line"/>
+ <point x="304" y="58"/>
+ <point x="453" y="0"/>
+ <point x="606" y="0" type="curve" smooth="yes"/>
+ <point x="872" y="0"/>
+ <point x="1102" y="119"/>
+ <point x="1102" y="381" type="curve" smooth="yes"/>
+ <point x="1102" y="528"/>
+ <point x="981" y="657"/>
+ <point x="801" y="771" type="curve" smooth="yes"/>
+ <point x="610" y="892"/>
+ <point x="535" y="943"/>
+ <point x="535" y="1024" type="curve" smooth="yes"/>
+ <point x="535" y="1116"/>
+ <point x="657" y="1203"/>
+ <point x="832" y="1203" type="curve" smooth="yes"/>
+ <point x="950" y="1203"/>
+ <point x="1031" y="1176"/>
+ <point x="1144" y="1104" type="curve"/>
+ </contour>
+ <contour>
+ <point x="878" y="1568" type="line"/>
+ <point x="434" y="-216" type="line"/>
+ <point x="574" y="-216" type="line"/>
+ <point x="1018" y="1568" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetassocfeat.ufo/glyphs/D_ottedC_irc.glif b/tests/reference/ufo/psfsetassocfeat.ufo/glyphs/D_ottedC_irc.glif
new file mode 100644
index 0000000..2cdf8fd
--- /dev/null
+++ b/tests/reference/ufo/psfsetassocfeat.ufo/glyphs/D_ottedC_irc.glif
@@ -0,0 +1,235 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="DottedCirc" format="2">
+ <advance width="1086"/>
+ <unicode hex="25CC"/>
+ <anchor x="493" y="0" name="H"/>
+ <anchor x="468" y="-100" name="L"/>
+ <anchor x="750" y="0" name="O"/>
+ <anchor x="743" y="1000" name="U"/>
+ <outline>
+ <contour>
+ <point x="588" y="834" type="curve" smooth="yes"/>
+ <point x="588" y="858"/>
+ <point x="571" y="867"/>
+ <point x="553" y="867" type="curve" smooth="yes"/>
+ <point x="521" y="867"/>
+ <point x="491" y="837"/>
+ <point x="491" y="809" type="curve" smooth="yes"/>
+ <point x="491" y="788"/>
+ <point x="508" y="773"/>
+ <point x="530" y="773" type="curve" smooth="yes"/>
+ <point x="564" y="773"/>
+ <point x="588" y="805"/>
+ </contour>
+ <contour>
+ <point x="677" y="124" type="curve" smooth="yes"/>
+ <point x="647" y="124"/>
+ <point x="620" y="93"/>
+ <point x="620" y="67" type="curve" smooth="yes"/>
+ <point x="620" y="46"/>
+ <point x="636" y="30"/>
+ <point x="657" y="30" type="curve" smooth="yes"/>
+ <point x="687" y="30"/>
+ <point x="718" y="60"/>
+ <point x="718" y="86" type="curve" smooth="yes"/>
+ <point x="718" y="109"/>
+ <point x="700" y="124"/>
+ </contour>
+ <contour>
+ <point x="396" y="780" type="curve" smooth="yes"/>
+ <point x="369" y="780"/>
+ <point x="336" y="753"/>
+ <point x="336" y="722" type="curve" smooth="yes"/>
+ <point x="336" y="702"/>
+ <point x="351" y="687"/>
+ <point x="374" y="687" type="curve" smooth="yes"/>
+ <point x="403" y="687"/>
+ <point x="434" y="711"/>
+ <point x="434" y="744" type="curve" smooth="yes"/>
+ <point x="434" y="764"/>
+ <point x="414" y="780"/>
+ </contour>
+ <contour>
+ <point x="873" y="175" type="curve" smooth="yes"/>
+ <point x="872" y="199"/>
+ <point x="854" y="211"/>
+ <point x="833" y="211" type="curve" smooth="yes"/>
+ <point x="803" y="211"/>
+ <point x="774" y="183"/>
+ <point x="774" y="153" type="curve" smooth="yes"/>
+ <point x="774" y="133"/>
+ <point x="789" y="119"/>
+ <point x="812" y="119" type="curve" smooth="yes"/>
+ <point x="843" y="119"/>
+ <point x="873" y="146"/>
+ </contour>
+ <contour>
+ <point x="313" y="612" type="curve" smooth="yes"/>
+ <point x="312" y="633"/>
+ <point x="296" y="650"/>
+ <point x="275" y="650" type="curve" smooth="yes"/>
+ <point x="247" y="650"/>
+ <point x="215" y="623"/>
+ <point x="215" y="592" type="curve" smooth="yes"/>
+ <point x="215" y="573"/>
+ <point x="227" y="556"/>
+ <point x="251" y="556" type="curve" smooth="yes"/>
+ <point x="278" y="556"/>
+ <point x="313" y="581"/>
+ </contour>
+ <contour>
+ <point x="994" y="306" type="curve" smooth="yes"/>
+ <point x="993" y="327"/>
+ <point x="978" y="341"/>
+ <point x="958" y="341" type="curve" smooth="yes"/>
+ <point x="933" y="341"/>
+ <point x="896" y="321"/>
+ <point x="896" y="284" type="curve" smooth="yes"/>
+ <point x="896" y="265"/>
+ <point x="909" y="249"/>
+ <point x="934" y="249" type="curve" smooth="yes"/>
+ <point x="963" y="249"/>
+ <point x="994" y="275"/>
+ </contour>
+ <contour>
+ <point x="205" y="495" type="curve" smooth="yes"/>
+ <point x="175" y="495"/>
+ <point x="145" y="468"/>
+ <point x="145" y="438" type="curve" smooth="yes"/>
+ <point x="145" y="418"/>
+ <point x="159" y="402"/>
+ <point x="183" y="402" type="curve" smooth="yes"/>
+ <point x="208" y="402"/>
+ <point x="244" y="428"/>
+ <point x="244" y="459" type="curve" smooth="yes"/>
+ <point x="244" y="479"/>
+ <point x="227" y="495"/>
+ </contour>
+ <contour>
+ <point x="1026" y="496" type="curve" smooth="yes"/>
+ <point x="999" y="496"/>
+ <point x="965" y="469"/>
+ <point x="965" y="438" type="curve" smooth="yes"/>
+ <point x="965" y="418"/>
+ <point x="979" y="403"/>
+ <point x="1004" y="403" type="curve" smooth="yes"/>
+ <point x="1033" y="403"/>
+ <point x="1064" y="431"/>
+ <point x="1064" y="460" type="curve" smooth="yes"/>
+ <point x="1064" y="480"/>
+ <point x="1048" y="496"/>
+ </contour>
+ <contour>
+ <point x="237" y="307" type="curve" smooth="yes"/>
+ <point x="237" y="327"/>
+ <point x="221" y="341"/>
+ <point x="199" y="341" type="curve" smooth="yes"/>
+ <point x="169" y="341"/>
+ <point x="138" y="314"/>
+ <point x="138" y="285" type="curve" smooth="yes"/>
+ <point x="138" y="263"/>
+ <point x="153" y="248"/>
+ <point x="175" y="248" type="curve" smooth="yes"/>
+ <point x="206" y="248"/>
+ <point x="237" y="278"/>
+ </contour>
+ <contour>
+ <point x="1071" y="613" type="curve" smooth="yes"/>
+ <point x="1071" y="634"/>
+ <point x="1055" y="650"/>
+ <point x="1034" y="650" type="curve" smooth="yes"/>
+ <point x="1003" y="650"/>
+ <point x="973" y="619"/>
+ <point x="973" y="590" type="curve" smooth="yes"/>
+ <point x="973" y="570"/>
+ <point x="989" y="556"/>
+ <point x="1009" y="556" type="curve" smooth="yes"/>
+ <point x="1041" y="556"/>
+ <point x="1071" y="585"/>
+ </contour>
+ <contour>
+ <point x="292" y="177" type="curve" smooth="yes"/>
+ <point x="292" y="197"/>
+ <point x="277" y="211"/>
+ <point x="253" y="211" type="curve" smooth="yes"/>
+ <point x="224" y="211"/>
+ <point x="194" y="181"/>
+ <point x="194" y="154" type="curve" smooth="yes"/>
+ <point x="194" y="134"/>
+ <point x="211" y="118"/>
+ <point x="232" y="118" type="curve" smooth="yes"/>
+ <point x="262" y="118"/>
+ <point x="292" y="148"/>
+ </contour>
+ <contour>
+ <point x="917" y="724" type="curve" smooth="yes"/>
+ <point x="917" y="704"/>
+ <point x="931" y="686"/>
+ <point x="954" y="686" type="curve" smooth="yes"/>
+ <point x="984" y="686"/>
+ <point x="1014" y="716"/>
+ <point x="1014" y="745" type="curve" smooth="yes"/>
+ <point x="1014" y="765"/>
+ <point x="1000" y="780"/>
+ <point x="977" y="780" type="curve" smooth="yes"/>
+ <point x="947" y="780"/>
+ <point x="917" y="753"/>
+ </contour>
+ <contour>
+ <point x="403" y="87" type="curve" smooth="yes"/>
+ <point x="403" y="107"/>
+ <point x="390" y="123"/>
+ <point x="367" y="123" type="curve" smooth="yes"/>
+ <point x="339" y="123"/>
+ <point x="305" y="96"/>
+ <point x="305" y="68" type="curve" smooth="yes"/>
+ <point x="305" y="49"/>
+ <point x="320" y="30"/>
+ <point x="343" y="30" type="curve" smooth="yes"/>
+ <point x="371" y="30"/>
+ <point x="403" y="56"/>
+ </contour>
+ <contour>
+ <point x="806" y="810" type="curve" smooth="yes"/>
+ <point x="806" y="791"/>
+ <point x="819" y="773"/>
+ <point x="842" y="773" type="curve" smooth="yes"/>
+ <point x="869" y="773"/>
+ <point x="903" y="799"/>
+ <point x="903" y="830" type="curve" smooth="yes"/>
+ <point x="903" y="850"/>
+ <point x="889" y="867"/>
+ <point x="866" y="867" type="curve" smooth="yes"/>
+ <point x="836" y="867"/>
+ <point x="806" y="839"/>
+ </contour>
+ <contour>
+ <point x="553" y="57" type="curve" smooth="yes"/>
+ <point x="553" y="78"/>
+ <point x="538" y="93"/>
+ <point x="516" y="93" type="curve" smooth="yes"/>
+ <point x="485" y="93"/>
+ <point x="456" y="65"/>
+ <point x="456" y="36" type="curve" smooth="yes"/>
+ <point x="456" y="16"/>
+ <point x="471" y="0"/>
+ <point x="493" y="0" type="curve" smooth="yes"/>
+ <point x="523" y="0"/>
+ <point x="553" y="27"/>
+ </contour>
+ <contour>
+ <point x="656" y="839" type="curve" smooth="yes"/>
+ <point x="656" y="819"/>
+ <point x="671" y="805"/>
+ <point x="693" y="805" type="curve" smooth="yes"/>
+ <point x="721" y="805"/>
+ <point x="754" y="830"/>
+ <point x="754" y="861" type="curve" smooth="yes"/>
+ <point x="754" y="882"/>
+ <point x="738" y="898"/>
+ <point x="716" y="898" type="curve" smooth="yes"/>
+ <point x="685" y="898"/>
+ <point x="656" y="868"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetassocfeat.ufo/glyphs/E_qS_gn.glif b/tests/reference/ufo/psfsetassocfeat.ufo/glyphs/E_qS_gn.glif
new file mode 100644
index 0000000..3d756e8
--- /dev/null
+++ b/tests/reference/ufo/psfsetassocfeat.ufo/glyphs/E_qS_gn.glif
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="EqSgn" format="2">
+ <advance width="1180"/>
+ <unicode hex="003D"/>
+ <outline>
+ <contour>
+ <point x="177" y="470" type="line"/>
+ <point x="1137" y="470" type="line"/>
+ <point x="1173" y="617" type="line"/>
+ <point x="213" y="617" type="line"/>
+ </contour>
+ <contour>
+ <point x="262" y="813" type="line"/>
+ <point x="1222" y="813" type="line"/>
+ <point x="1259" y="960" type="line"/>
+ <point x="299" y="960" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetassocfeat.ufo/glyphs/E_xclamationM_rk.glif b/tests/reference/ufo/psfsetassocfeat.ufo/glyphs/E_xclamationM_rk.glif
new file mode 100644
index 0000000..a1c14d9
--- /dev/null
+++ b/tests/reference/ufo/psfsetassocfeat.ufo/glyphs/E_xclamationM_rk.glif
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="ExclamationMrk" format="2">
+ <advance width="744"/>
+ <unicode hex="0021"/>
+ <outline>
+ <contour>
+ <point x="497" y="431" type="line"/>
+ <point x="574" y="715"/>
+ <point x="653" y="1054"/>
+ <point x="799" y="1480" type="curve"/>
+ <point x="544" y="1480" type="line"/>
+ <point x="475" y="1054"/>
+ <point x="386" y="715"/>
+ <point x="322" y="431" type="curve"/>
+ </contour>
+ <contour>
+ <point x="188" y="90" type="curve" smooth="yes"/>
+ <point x="188" y="28"/>
+ <point x="238" y="-25"/>
+ <point x="303" y="-25" type="curve" smooth="yes"/>
+ <point x="387" y="-25"/>
+ <point x="464" y="45"/>
+ <point x="464" y="125" type="curve" smooth="yes"/>
+ <point x="464" y="186"/>
+ <point x="414" y="240"/>
+ <point x="349" y="240" type="curve" smooth="yes"/>
+ <point x="265" y="240"/>
+ <point x="188" y="170"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetassocfeat.ufo/glyphs/F_ullS_top.glif b/tests/reference/ufo/psfsetassocfeat.ufo/glyphs/F_ullS_top.glif
new file mode 100644
index 0000000..a6c4d08
--- /dev/null
+++ b/tests/reference/ufo/psfsetassocfeat.ufo/glyphs/F_ullS_top.glif
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="FullStop" format="2">
+ <advance width="620"/>
+ <unicode hex="002E"/>
+ <outline>
+ <contour>
+ <point x="148" y="90" type="curve" smooth="yes"/>
+ <point x="148" y="28"/>
+ <point x="198" y="-25"/>
+ <point x="263" y="-25" type="curve" smooth="yes"/>
+ <point x="347" y="-25"/>
+ <point x="424" y="45"/>
+ <point x="424" y="125" type="curve" smooth="yes"/>
+ <point x="424" y="186"/>
+ <point x="374" y="240"/>
+ <point x="309" y="240" type="curve" smooth="yes"/>
+ <point x="225" y="240"/>
+ <point x="148" y="170"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetassocfeat.ufo/glyphs/G_T_S_gn.glif b/tests/reference/ufo/psfsetassocfeat.ufo/glyphs/G_T_S_gn.glif
new file mode 100644
index 0000000..12da8b3
--- /dev/null
+++ b/tests/reference/ufo/psfsetassocfeat.ufo/glyphs/G_T_S_gn.glif
@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="GTSgn" format="2">
+ <advance width="1180"/>
+ <unicode hex="003E"/>
+ <outline>
+ <contour>
+ <point x="312" y="1014" type="line"/>
+ <point x="1028" y="725" type="line"/>
+ <point x="163" y="417" type="line"/>
+ <point x="119" y="240" type="line"/>
+ <point x="1197" y="632" type="line"/>
+ <point x="1239" y="799" type="line"/>
+ <point x="356" y="1191" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetassocfeat.ufo/glyphs/G_raveA_ccent.glif b/tests/reference/ufo/psfsetassocfeat.ufo/glyphs/G_raveA_ccent.glif
new file mode 100644
index 0000000..48adfc4
--- /dev/null
+++ b/tests/reference/ufo/psfsetassocfeat.ufo/glyphs/G_raveA_ccent.glif
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="GraveAccent" format="2">
+ <advance width="560"/>
+ <unicode hex="0060"/>
+ <anchor x="738" y="1635" name="U"/>
+ <outline>
+ <contour>
+ <point x="261" y="1568" type="line"/>
+ <point x="596" y="1147" type="line"/>
+ <point x="746" y="1147" type="line"/>
+ <point x="471" y="1568" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetassocfeat.ufo/glyphs/H_yphen.glif b/tests/reference/ufo/psfsetassocfeat.ufo/glyphs/H_yphen.glif
new file mode 100644
index 0000000..ae8cad5
--- /dev/null
+++ b/tests/reference/ufo/psfsetassocfeat.ufo/glyphs/H_yphen.glif
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="Hyphen" format="2">
+ <advance width="840"/>
+ <unicode hex="2010"/>
+ <anchor x="645" y="1100" name="U"/>
+ <outline>
+ <contour>
+ <point x="155" y="544" type="line"/>
+ <point x="855" y="544" type="line"/>
+ <point x="892" y="691" type="line"/>
+ <point x="192" y="691" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetassocfeat.ufo/glyphs/H_yphenM_inus.glif b/tests/reference/ufo/psfsetassocfeat.ufo/glyphs/H_yphenM_inus.glif
new file mode 100644
index 0000000..155b460
--- /dev/null
+++ b/tests/reference/ufo/psfsetassocfeat.ufo/glyphs/H_yphenM_inus.glif
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="HyphenMinus" format="2">
+ <advance width="840"/>
+ <unicode hex="002D"/>
+ <anchor x="645" y="1100" name="U"/>
+ <outline>
+ <contour>
+ <point x="155" y="544" type="line"/>
+ <point x="855" y="544" type="line"/>
+ <point x="892" y="691" type="line"/>
+ <point x="192" y="691" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetassocfeat.ufo/glyphs/H_yphen_S_oft.glif b/tests/reference/ufo/psfsetassocfeat.ufo/glyphs/H_yphen_S_oft.glif
new file mode 100644
index 0000000..0c7b834
--- /dev/null
+++ b/tests/reference/ufo/psfsetassocfeat.ufo/glyphs/H_yphen_S_oft.glif
@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="Hyphen_Soft" format="2">
+ <advance width="840"/>
+ <unicode hex="00AD"/>
+ <anchor x="645" y="1100" name="U"/>
+ <outline>
+ <component base="HyphenMinus"/>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetassocfeat.ufo/glyphs/L_T_S_gn.glif b/tests/reference/ufo/psfsetassocfeat.ufo/glyphs/L_T_S_gn.glif
new file mode 100644
index 0000000..3c857a5
--- /dev/null
+++ b/tests/reference/ufo/psfsetassocfeat.ufo/glyphs/L_T_S_gn.glif
@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LTSgn" format="2">
+ <advance width="1180"/>
+ <unicode hex="003C"/>
+ <outline>
+ <contour>
+ <point x="1123" y="417" type="line"/>
+ <point x="408" y="705" type="line"/>
+ <point x="1272" y="1014" type="line"/>
+ <point x="1316" y="1191" type="line"/>
+ <point x="239" y="799" type="line"/>
+ <point x="197" y="632" type="line"/>
+ <point x="1079" y="240" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetassocfeat.ufo/glyphs/L_ftC_urlyB_rac.glif b/tests/reference/ufo/psfsetassocfeat.ufo/glyphs/L_ftC_urlyB_rac.glif
new file mode 100644
index 0000000..4f8c90c
--- /dev/null
+++ b/tests/reference/ufo/psfsetassocfeat.ufo/glyphs/L_ftC_urlyB_rac.glif
@@ -0,0 +1,50 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LftCurlyBrac" format="2">
+ <advance width="980"/>
+ <unicode hex="007B"/>
+ <outline>
+ <contour>
+ <point x="713" y="-265" type="line"/>
+ <point x="660" y="-250"/>
+ <point x="526" y="-188"/>
+ <point x="526" y="-158" type="curve" smooth="yes"/>
+ <point x="526" y="-59"/>
+ <point x="649" y="404"/>
+ <point x="649" y="469" type="curve" smooth="yes"/>
+ <point x="649" y="509"/>
+ <point x="520" y="577"/>
+ <point x="520" y="602" type="curve" smooth="yes"/>
+ <point x="520" y="620"/>
+ <point x="688" y="700"/>
+ <point x="712" y="730" type="curve" smooth="yes"/>
+ <point x="741" y="767"/>
+ <point x="867" y="1326"/>
+ <point x="912" y="1372" type="curve" smooth="yes"/>
+ <point x="938" y="1399"/>
+ <point x="1073" y="1447"/>
+ <point x="1146" y="1470" type="curve"/>
+ <point x="1140" y="1607" type="line"/>
+ <point x="1030" y="1581"/>
+ <point x="856" y="1529"/>
+ <point x="805" y="1485" type="curve" smooth="yes"/>
+ <point x="714" y="1406"/>
+ <point x="572" y="796"/>
+ <point x="540" y="764" type="curve" smooth="yes"/>
+ <point x="504" y="729"/>
+ <point x="300" y="633"/>
+ <point x="300" y="601" type="curve" smooth="yes"/>
+ <point x="300" y="560"/>
+ <point x="460" y="468"/>
+ <point x="460" y="432" type="curve" smooth="yes"/>
+ <point x="460" y="362"/>
+ <point x="355" y="-53"/>
+ <point x="355" y="-219" type="curve" smooth="yes"/>
+ <point x="355" y="-247"/>
+ <point x="358" y="-268"/>
+ <point x="365" y="-279" type="curve" smooth="yes"/>
+ <point x="394" y="-323"/>
+ <point x="542" y="-375"/>
+ <point x="639" y="-402" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetassocfeat.ufo/glyphs/L_ftP_aren.glif b/tests/reference/ufo/psfsetassocfeat.ufo/glyphs/L_ftP_aren.glif
new file mode 100644
index 0000000..bc65fc1
--- /dev/null
+++ b/tests/reference/ufo/psfsetassocfeat.ufo/glyphs/L_ftP_aren.glif
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LftParen" format="2">
+ <advance width="775"/>
+ <unicode hex="0028"/>
+ <outline>
+ <contour>
+ <point x="895" y="1607" type="line"/>
+ <point x="582" y="1415"/>
+ <point x="314" y="1061"/>
+ <point x="207" y="633" type="curve" smooth="yes"/>
+ <point x="176" y="508"/>
+ <point x="161" y="386"/>
+ <point x="161" y="270" type="curve" smooth="yes"/>
+ <point x="161" y="17"/>
+ <point x="233" y="-211"/>
+ <point x="374" y="-402" type="curve"/>
+ <point x="505" y="-260" type="line"/>
+ <point x="397" y="-102"/>
+ <point x="348" y="75"/>
+ <point x="348" y="270" type="curve" smooth="yes"/>
+ <point x="348" y="385"/>
+ <point x="365" y="506"/>
+ <point x="397" y="633" type="curve" smooth="yes"/>
+ <point x="484" y="982"/>
+ <point x="647" y="1254"/>
+ <point x="932" y="1455" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetassocfeat.ufo/glyphs/L_ftS_qrB_rac.glif b/tests/reference/ufo/psfsetassocfeat.ufo/glyphs/L_ftS_qrB_rac.glif
new file mode 100644
index 0000000..6d064d1
--- /dev/null
+++ b/tests/reference/ufo/psfsetassocfeat.ufo/glyphs/L_ftS_qrB_rac.glif
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LftSqrBrac" format="2">
+ <advance width="770"/>
+ <unicode hex="005B"/>
+ <outline>
+ <contour>
+ <point x="484" y="-402" type="line"/>
+ <point x="521" y="-255" type="line"/>
+ <point x="266" y="-255" type="line"/>
+ <point x="679" y="1421" type="line"/>
+ <point x="934" y="1421" type="line"/>
+ <point x="970" y="1568" type="line"/>
+ <point x="530" y="1568" type="line"/>
+ <point x="44" y="-402" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetassocfeat.ufo/glyphs/L_owL_ine.glif b/tests/reference/ufo/psfsetassocfeat.ufo/glyphs/L_owL_ine.glif
new file mode 100644
index 0000000..879d36b
--- /dev/null
+++ b/tests/reference/ufo/psfsetassocfeat.ufo/glyphs/L_owL_ine.glif
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LowLine" format="2">
+ <advance width="1254"/>
+ <unicode hex="005F"/>
+ <outline>
+ <contour>
+ <point x="-138" y="-314" type="line"/>
+ <point x="1135" y="-314" type="line"/>
+ <point x="1172" y="-167" type="line"/>
+ <point x="-101" y="-167" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetassocfeat.ufo/glyphs/L_tnC_apA_.glif b/tests/reference/ufo/psfsetassocfeat.ufo/glyphs/L_tnC_apA_.glif
new file mode 100644
index 0000000..a186541
--- /dev/null
+++ b/tests/reference/ufo/psfsetassocfeat.ufo/glyphs/L_tnC_apA_.glif
@@ -0,0 +1,38 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnCapA" format="2">
+ <advance width="1395"/>
+ <unicode hex="0041"/>
+ <anchor x="1170" y="0" name="H"/>
+ <anchor x="602" y="-100" name="L"/>
+ <anchor x="1390" y="0" name="O"/>
+ <anchor x="1009" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="1080" y="0" type="line"/>
+ <point x="1275" y="0" type="line"/>
+ <point x="1259" y="78"/>
+ <point x="1243" y="166"/>
+ <point x="1221" y="348" type="curve" smooth="yes"/>
+ <point x="1091" y="1431" type="line"/>
+ <point x="876" y="1431" type="line"/>
+ <point x="206" y="348" type="line" smooth="yes"/>
+ <point x="93" y="165"/>
+ <point x="35" y="79"/>
+ <point x="-20" y="0" type="curve"/>
+ <point x="195" y="0" type="line"/>
+ <point x="422" y="377" type="line"/>
+ <point x="1038" y="377" type="line"/>
+ </contour>
+ <contour>
+ <point x="944" y="1240" type="line"/>
+ <point x="1022" y="529" type="line"/>
+ <point x="514" y="529" type="line"/>
+ </contour>
+ </outline>
+ <lib>
+ <dict>
+ <key>org.sil.assocFeature</key>
+ <string>fea1</string>
+ </dict>
+ </lib>
+</glyph>
diff --git a/tests/reference/ufo/psfsetassocfeat.ufo/glyphs/L_tnC_apA_D_iaer.glif b/tests/reference/ufo/psfsetassocfeat.ufo/glyphs/L_tnC_apA_D_iaer.glif
new file mode 100644
index 0000000..6c3502c
--- /dev/null
+++ b/tests/reference/ufo/psfsetassocfeat.ufo/glyphs/L_tnC_apA_D_iaer.glif
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnCapADiaer" format="2">
+ <advance width="1395"/>
+ <unicode hex="00C4"/>
+ <anchor x="1170" y="0" name="H"/>
+ <anchor x="602" y="-100" name="L"/>
+ <anchor x="1390" y="0" name="O"/>
+ <anchor x="1106" y="1935" name="U"/>
+ <outline>
+ <component base="LtnCapA"/>
+ <component base="CombDiaer" xOffset="1359" yOffset="430"/>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetassocfeat.ufo/glyphs/L_tnC_apB_.glif b/tests/reference/ufo/psfsetassocfeat.ufo/glyphs/L_tnC_apB_.glif
new file mode 100644
index 0000000..5445f93
--- /dev/null
+++ b/tests/reference/ufo/psfsetassocfeat.ufo/glyphs/L_tnC_apB_.glif
@@ -0,0 +1,62 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnCapB" format="2">
+ <advance width="1271"/>
+ <unicode hex="0042"/>
+ <anchor x="530" y="-100" name="L"/>
+ <anchor x="937" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="625" y="1284" type="line"/>
+ <point x="667" y="1286"/>
+ <point x="733" y="1289"/>
+ <point x="811" y="1289" type="curve" smooth="yes"/>
+ <point x="993" y="1289"/>
+ <point x="1080" y="1230"/>
+ <point x="1080" y="1105" type="curve" smooth="yes"/>
+ <point x="1080" y="932"/>
+ <point x="931" y="838"/>
+ <point x="698" y="838" type="curve" smooth="yes"/>
+ <point x="513" y="838" type="line"/>
+ </contour>
+ <contour>
+ <point x="226" y="446" type="line"/>
+ <point x="178" y="252"/>
+ <point x="134" y="78"/>
+ <point x="100" y="0" type="curve"/>
+ <point x="151" y="-5"/>
+ <point x="359" y="-10"/>
+ <point x="562" y="-10" type="curve" smooth="yes"/>
+ <point x="960" y="-10"/>
+ <point x="1201" y="149"/>
+ <point x="1201" y="453" type="curve" smooth="yes"/>
+ <point x="1201" y="644"/>
+ <point x="1067" y="736"/>
+ <point x="955" y="764" type="curve"/>
+ <point x="1155" y="819"/>
+ <point x="1283" y="941"/>
+ <point x="1283" y="1140" type="curve" smooth="yes"/>
+ <point x="1283" y="1310"/>
+ <point x="1136" y="1441"/>
+ <point x="869" y="1441" type="curve" smooth="yes"/>
+ <point x="700" y="1441"/>
+ <point x="546" y="1437"/>
+ <point x="456" y="1431" type="curve"/>
+ <point x="452" y="1352"/>
+ <point x="407" y="1172"/>
+ <point x="359" y="980" type="curve" smooth="yes"/>
+ </contour>
+ <contour>
+ <point x="476" y="686" type="line"/>
+ <point x="721" y="686" type="line" smooth="yes"/>
+ <point x="892" y="686"/>
+ <point x="1011" y="598"/>
+ <point x="1011" y="450" type="curve" smooth="yes"/>
+ <point x="1011" y="218"/>
+ <point x="806" y="147"/>
+ <point x="586" y="147" type="curve" smooth="yes"/>
+ <point x="474" y="147"/>
+ <point x="379" y="150"/>
+ <point x="342" y="152" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetassocfeat.ufo/glyphs/L_tnC_apC_.glif b/tests/reference/ufo/psfsetassocfeat.ufo/glyphs/L_tnC_apC_.glif
new file mode 100644
index 0000000..c2e4948
--- /dev/null
+++ b/tests/reference/ufo/psfsetassocfeat.ufo/glyphs/L_tnC_apC_.glif
@@ -0,0 +1,38 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnCapC" format="2">
+ <advance width="1341"/>
+ <unicode hex="0043"/>
+ <anchor x="690" y="0" name="H"/>
+ <anchor x="665" y="-100" name="L"/>
+ <anchor x="1072" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="1237" y="318" type="line"/>
+ <point x="1115" y="222"/>
+ <point x="934" y="147"/>
+ <point x="752" y="147" type="curve" smooth="yes"/>
+ <point x="537" y="147"/>
+ <point x="385" y="304"/>
+ <point x="385" y="532" type="curve" smooth="yes"/>
+ <point x="385" y="964"/>
+ <point x="704" y="1289"/>
+ <point x="1037" y="1289" type="curve" smooth="yes"/>
+ <point x="1168" y="1289"/>
+ <point x="1310" y="1235"/>
+ <point x="1385" y="1132" type="curve"/>
+ <point x="1489" y="1308" type="line"/>
+ <point x="1388" y="1408"/>
+ <point x="1201" y="1455"/>
+ <point x="1058" y="1455" type="curve" smooth="yes"/>
+ <point x="645" y="1455"/>
+ <point x="185" y="1093"/>
+ <point x="185" y="513" type="curve" smooth="yes"/>
+ <point x="185" y="202"/>
+ <point x="381" y="-25"/>
+ <point x="709" y="-25" type="curve" smooth="yes"/>
+ <point x="896" y="-25"/>
+ <point x="1087" y="21"/>
+ <point x="1230" y="127" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetassocfeat.ufo/glyphs/L_tnC_apD_.glif b/tests/reference/ufo/psfsetassocfeat.ufo/glyphs/L_tnC_apD_.glif
new file mode 100644
index 0000000..3b93811
--- /dev/null
+++ b/tests/reference/ufo/psfsetassocfeat.ufo/glyphs/L_tnC_apD_.glif
@@ -0,0 +1,51 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnCapD" format="2">
+ <advance width="1421"/>
+ <unicode hex="0044"/>
+ <anchor x="630" y="-100" name="L"/>
+ <anchor x="1037" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="226" y="446" type="line"/>
+ <point x="176" y="252"/>
+ <point x="134" y="78"/>
+ <point x="100" y="0" type="curve"/>
+ <point x="100" y="0"/>
+ <point x="414" y="-10"/>
+ <point x="542" y="-10" type="curve" smooth="yes"/>
+ <point x="985" y="-10"/>
+ <point x="1299" y="181"/>
+ <point x="1415" y="648" type="curve" smooth="yes"/>
+ <point x="1437" y="738"/>
+ <point x="1447" y="819"/>
+ <point x="1447" y="891" type="curve" smooth="yes"/>
+ <point x="1447" y="1279"/>
+ <point x="1188" y="1441"/>
+ <point x="894" y="1441" type="curve" smooth="yes"/>
+ <point x="759" y="1441"/>
+ <point x="543" y="1437"/>
+ <point x="456" y="1431" type="curve"/>
+ <point x="452" y="1352"/>
+ <point x="407" y="1172"/>
+ <point x="359" y="980" type="curve" smooth="yes"/>
+ </contour>
+ <contour>
+ <point x="623" y="1279" type="line"/>
+ <point x="674" y="1281"/>
+ <point x="764" y="1284"/>
+ <point x="830" y="1284" type="curve" smooth="yes"/>
+ <point x="1105" y="1284"/>
+ <point x="1246" y="1140"/>
+ <point x="1246" y="850" type="curve" smooth="yes"/>
+ <point x="1246" y="784"/>
+ <point x="1236" y="710"/>
+ <point x="1216" y="629" type="curve" smooth="yes"/>
+ <point x="1134" y="300"/>
+ <point x="925" y="152"/>
+ <point x="572" y="152" type="curve" smooth="yes"/>
+ <point x="477" y="152"/>
+ <point x="391" y="158"/>
+ <point x="345" y="162" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetassocfeat.ufo/glyphs/L_tnC_apE_.glif b/tests/reference/ufo/psfsetassocfeat.ufo/glyphs/L_tnC_apE_.glif
new file mode 100644
index 0000000..8b5f8b9
--- /dev/null
+++ b/tests/reference/ufo/psfsetassocfeat.ufo/glyphs/L_tnC_apE_.glif
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnCapE" format="2">
+ <advance width="1140"/>
+ <unicode hex="0045"/>
+ <anchor x="540" y="0" name="H"/>
+ <anchor x="515" y="-100" name="L"/>
+ <anchor x="857" y="0" name="O"/>
+ <anchor x="1400" y="1200" name="R"/>
+ <anchor x="922" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="511" y="828" type="line"/>
+ <point x="621" y="1269" type="line"/>
+ <point x="1266" y="1269" type="line"/>
+ <point x="1306" y="1431" type="line"/>
+ <point x="456" y="1431" type="line"/>
+ <point x="452" y="1352"/>
+ <point x="413" y="1197"/>
+ <point x="365" y="1005" type="curve" smooth="yes"/>
+ <point x="221" y="426" type="line" smooth="yes"/>
+ <point x="173" y="233"/>
+ <point x="134" y="78"/>
+ <point x="100" y="0" type="curve"/>
+ <point x="980" y="0" type="line"/>
+ <point x="1023" y="176" type="line"/>
+ <point x="940" y="163"/>
+ <point x="806" y="162"/>
+ <point x="609" y="162" type="curve" smooth="yes"/>
+ <point x="345" y="162" type="line"/>
+ <point x="472" y="671" type="line"/>
+ <point x="1042" y="671" type="line"/>
+ <point x="1081" y="828" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetassocfeat.ufo/glyphs/L_tnC_apF_.glif b/tests/reference/ufo/psfsetassocfeat.ufo/glyphs/L_tnC_apF_.glif
new file mode 100644
index 0000000..cbc1726
--- /dev/null
+++ b/tests/reference/ufo/psfsetassocfeat.ufo/glyphs/L_tnC_apF_.glif
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnCapF" format="2">
+ <advance width="1130"/>
+ <unicode hex="0046"/>
+ <anchor x="510" y="-100" name="L"/>
+ <anchor x="917" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="508" y="818" type="line"/>
+ <point x="621" y="1269" type="line"/>
+ <point x="1286" y="1269" type="line"/>
+ <point x="1326" y="1431" type="line"/>
+ <point x="456" y="1431" type="line"/>
+ <point x="452" y="1352"/>
+ <point x="412" y="1193"/>
+ <point x="364" y="1000" type="curve" smooth="yes"/>
+ <point x="221" y="426" type="line" smooth="yes"/>
+ <point x="173" y="233"/>
+ <point x="134" y="78"/>
+ <point x="100" y="0" type="curve"/>
+ <point x="320" y="0" type="line"/>
+ <point x="323" y="76"/>
+ <point x="362" y="232"/>
+ <point x="411" y="426" type="curve" smooth="yes"/>
+ <point x="470" y="662" type="line"/>
+ <point x="1050" y="662" type="line"/>
+ <point x="1088" y="818" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetassocfeat.ufo/glyphs/L_tnC_apG_.glif b/tests/reference/ufo/psfsetassocfeat.ufo/glyphs/L_tnC_apG_.glif
new file mode 100644
index 0000000..c39b75a
--- /dev/null
+++ b/tests/reference/ufo/psfsetassocfeat.ufo/glyphs/L_tnC_apG_.glif
@@ -0,0 +1,48 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnCapG" format="2">
+ <advance width="1406"/>
+ <unicode hex="0047"/>
+ <anchor x="685" y="0" name="H"/>
+ <anchor x="660" y="-100" name="L"/>
+ <anchor x="1067" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="1403" y="710" type="line"/>
+ <point x="863" y="710" type="line"/>
+ <point x="822" y="548" type="line"/>
+ <point x="1172" y="548" type="line"/>
+ <point x="1090" y="220" type="line"/>
+ <point x="1012" y="176"/>
+ <point x="858" y="147"/>
+ <point x="739" y="147" type="curve" smooth="yes"/>
+ <point x="520" y="147"/>
+ <point x="384" y="272"/>
+ <point x="384" y="493" type="curve" smooth="yes"/>
+ <point x="384" y="560"/>
+ <point x="394" y="636"/>
+ <point x="415" y="720" type="curve" smooth="yes"/>
+ <point x="500" y="1062"/>
+ <point x="747" y="1289"/>
+ <point x="1052" y="1289" type="curve" smooth="yes"/>
+ <point x="1195" y="1289"/>
+ <point x="1335" y="1233"/>
+ <point x="1425" y="1122" type="curve"/>
+ <point x="1534" y="1298" type="line"/>
+ <point x="1409" y="1405"/>
+ <point x="1235" y="1455"/>
+ <point x="1063" y="1455" type="curve" smooth="yes"/>
+ <point x="680" y="1455"/>
+ <point x="334" y="1195"/>
+ <point x="217" y="726" type="curve" smooth="yes"/>
+ <point x="195" y="639"/>
+ <point x="185" y="559"/>
+ <point x="185" y="486" type="curve" smooth="yes"/>
+ <point x="185" y="162"/>
+ <point x="406" y="-25"/>
+ <point x="714" y="-25" type="curve" smooth="yes"/>
+ <point x="907" y="-25"/>
+ <point x="1149" y="50"/>
+ <point x="1258" y="132" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetassocfeat.ufo/glyphs/L_tnC_apH_.glif b/tests/reference/ufo/psfsetassocfeat.ufo/glyphs/L_tnC_apH_.glif
new file mode 100644
index 0000000..f454288
--- /dev/null
+++ b/tests/reference/ufo/psfsetassocfeat.ufo/glyphs/L_tnC_apH_.glif
@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnCapH" format="2">
+ <advance width="1455"/>
+ <unicode hex="0048"/>
+ <anchor x="225" y="0" name="H"/>
+ <anchor x="640" y="-100" name="L"/>
+ <anchor x="1047" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="1230" y="0" type="line"/>
+ <point x="1234" y="78"/>
+ <point x="1273" y="233"/>
+ <point x="1321" y="426" type="curve" smooth="yes"/>
+ <point x="1465" y="1005" type="line" smooth="yes"/>
+ <point x="1513" y="1198"/>
+ <point x="1552" y="1352"/>
+ <point x="1586" y="1431" type="curve"/>
+ <point x="1381" y="1431" type="line"/>
+ <point x="1228" y="818" type="line"/>
+ <point x="508" y="818" type="line"/>
+ <point x="661" y="1431" type="line"/>
+ <point x="456" y="1431" type="line"/>
+ <point x="452" y="1352"/>
+ <point x="413" y="1197"/>
+ <point x="365" y="1005" type="curve" smooth="yes"/>
+ <point x="221" y="426" type="line" smooth="yes"/>
+ <point x="173" y="233"/>
+ <point x="134" y="78"/>
+ <point x="100" y="0" type="curve"/>
+ <point x="305" y="0" type="line"/>
+ <point x="470" y="662" type="line"/>
+ <point x="1190" y="662" type="line"/>
+ <point x="1025" y="0" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetassocfeat.ufo/glyphs/L_tnC_apI_.glif b/tests/reference/ufo/psfsetassocfeat.ufo/glyphs/L_tnC_apI_.glif
new file mode 100644
index 0000000..78b151c
--- /dev/null
+++ b/tests/reference/ufo/psfsetassocfeat.ufo/glyphs/L_tnC_apI_.glif
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnCapI" format="2">
+ <advance width="955"/>
+ <unicode hex="0049"/>
+ <anchor x="417" y="0" name="H"/>
+ <anchor x="392" y="-100" name="L"/>
+ <anchor x="613" y="0" name="O"/>
+ <anchor x="1215" y="1200" name="R"/>
+ <anchor x="799" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="436" y="1431" type="line"/>
+ <point x="401" y="1289" type="line"/>
+ <point x="641" y="1289" type="line"/>
+ <point x="355" y="142" type="line"/>
+ <point x="115" y="142" type="line"/>
+ <point x="80" y="0" type="line"/>
+ <point x="755" y="0" type="line"/>
+ <point x="790" y="142" type="line"/>
+ <point x="545" y="142" type="line"/>
+ <point x="831" y="1289" type="line"/>
+ <point x="1076" y="1289" type="line"/>
+ <point x="1111" y="1431" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetassocfeat.ufo/glyphs/L_tnC_apJ_.glif b/tests/reference/ufo/psfsetassocfeat.ufo/glyphs/L_tnC_apJ_.glif
new file mode 100644
index 0000000..417d1f8
--- /dev/null
+++ b/tests/reference/ufo/psfsetassocfeat.ufo/glyphs/L_tnC_apJ_.glif
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnCapJ" format="2">
+ <advance width="996"/>
+ <unicode hex="004A"/>
+ <anchor x="325" y="-100" name="L"/>
+ <anchor x="997" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="871" y="1431" type="line"/>
+ <point x="858" y="1327"/>
+ <point x="817" y="1151"/>
+ <point x="769" y="960" type="curve" smooth="yes"/>
+ <point x="648" y="475" type="line" smooth="yes"/>
+ <point x="592" y="251"/>
+ <point x="484" y="152"/>
+ <point x="337" y="152" type="curve" smooth="yes"/>
+ <point x="245" y="152"/>
+ <point x="145" y="224"/>
+ <point x="97" y="299" type="curve"/>
+ <point x="6" y="118" type="line"/>
+ <point x="58" y="39"/>
+ <point x="193" y="-25"/>
+ <point x="298" y="-25" type="curve" smooth="yes"/>
+ <point x="555" y="-25"/>
+ <point x="749" y="117"/>
+ <point x="850" y="524" type="curve" smooth="yes"/>
+ <point x="1076" y="1431" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetassocfeat.ufo/glyphs/L_tnC_apK_.glif b/tests/reference/ufo/psfsetassocfeat.ufo/glyphs/L_tnC_apK_.glif
new file mode 100644
index 0000000..8e54a6d
--- /dev/null
+++ b/tests/reference/ufo/psfsetassocfeat.ufo/glyphs/L_tnC_apK_.glif
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnCapK" format="2">
+ <advance width="1261"/>
+ <unicode hex="004B"/>
+ <anchor x="210" y="0" name="H"/>
+ <anchor x="610" y="-100" name="L"/>
+ <anchor x="972" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="1221" y="1431" type="line"/>
+ <point x="406" y="689" type="line"/>
+ <point x="547" y="730" type="line"/>
+ <point x="660" y="725" type="line"/>
+ <point x="1461" y="1431" type="line"/>
+ </contour>
+ <contour>
+ <point x="1170" y="0" type="line"/>
+ <point x="615" y="823" type="line"/>
+ <point x="469" y="720" type="line"/>
+ <point x="925" y="0" type="line"/>
+ </contour>
+ <contour>
+ <point x="661" y="1431" type="line"/>
+ <point x="456" y="1431" type="line"/>
+ <point x="452" y="1352"/>
+ <point x="413" y="1197"/>
+ <point x="365" y="1005" type="curve" smooth="yes"/>
+ <point x="221" y="426" type="line" smooth="yes"/>
+ <point x="173" y="233"/>
+ <point x="134" y="78"/>
+ <point x="100" y="0" type="curve"/>
+ <point x="305" y="0" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetassocfeat.ufo/glyphs/L_tnC_apL_.glif b/tests/reference/ufo/psfsetassocfeat.ufo/glyphs/L_tnC_apL_.glif
new file mode 100644
index 0000000..d2eb932
--- /dev/null
+++ b/tests/reference/ufo/psfsetassocfeat.ufo/glyphs/L_tnC_apL_.glif
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnCapL" format="2">
+ <advance width="1060"/>
+ <unicode hex="004C"/>
+ <anchor x="532" y="0" name="H"/>
+ <anchor x="507" y="-100" name="L"/>
+ <anchor x="780" y="1200" name="R"/>
+ <anchor x="914" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="345" y="162" type="line"/>
+ <point x="661" y="1431" type="line"/>
+ <point x="456" y="1431" type="line"/>
+ <point x="452" y="1352"/>
+ <point x="413" y="1197"/>
+ <point x="365" y="1005" type="curve" smooth="yes"/>
+ <point x="221" y="426" type="line" smooth="yes"/>
+ <point x="173" y="233"/>
+ <point x="134" y="78"/>
+ <point x="100" y="0" type="curve"/>
+ <point x="965" y="0" type="line"/>
+ <point x="1008" y="176" type="line"/>
+ <point x="925" y="163"/>
+ <point x="766" y="162"/>
+ <point x="569" y="162" type="curve" smooth="yes"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetassocfeat.ufo/glyphs/L_tnC_apM_.glif b/tests/reference/ufo/psfsetassocfeat.ufo/glyphs/L_tnC_apM_.glif
new file mode 100644
index 0000000..7c3c824
--- /dev/null
+++ b/tests/reference/ufo/psfsetassocfeat.ufo/glyphs/L_tnC_apM_.glif
@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnCapM" format="2">
+ <advance width="1785"/>
+ <unicode hex="004D"/>
+ <anchor x="800" y="-100" name="L"/>
+ <anchor x="1207" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="880" y="201" type="line"/>
+ <point x="751" y="1431" type="line"/>
+ <point x="591" y="1431" type="line"/>
+ <point x="740" y="0" type="line"/>
+ <point x="935" y="0" type="line"/>
+ <point x="1793" y="1431" type="line"/>
+ <point x="1616" y="1431" type="line"/>
+ </contour>
+ <contour>
+ <point x="536" y="1431" type="line"/>
+ <point x="536" y="1431"/>
+ <point x="184" y="194"/>
+ <point x="110" y="0" type="curve"/>
+ <point x="295" y="0" type="line"/>
+ <point x="621" y="1181" type="line"/>
+ <point x="711" y="1431" type="line"/>
+ </contour>
+ <contour>
+ <point x="1560" y="0" type="line"/>
+ <point x="1579" y="194"/>
+ <point x="1846" y="1431"/>
+ <point x="1846" y="1431" type="curve"/>
+ <point x="1671" y="1431" type="line"/>
+ <point x="1641" y="1181" type="line"/>
+ <point x="1375" y="0" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetassocfeat.ufo/glyphs/L_tnC_apN_.glif b/tests/reference/ufo/psfsetassocfeat.ufo/glyphs/L_tnC_apN_.glif
new file mode 100644
index 0000000..7306669
--- /dev/null
+++ b/tests/reference/ufo/psfsetassocfeat.ufo/glyphs/L_tnC_apN_.glif
@@ -0,0 +1,37 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnCapN" format="2">
+ <advance width="1480"/>
+ <unicode hex="004E"/>
+ <anchor x="1170" y="0" name="H"/>
+ <anchor x="652" y="-100" name="L"/>
+ <anchor x="1059" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="491" y="1328" type="line"/>
+ <point x="1075" y="0" type="line"/>
+ <point x="1219" y="98" type="line"/>
+ <point x="636" y="1431" type="line"/>
+ </contour>
+ <contour>
+ <point x="1075" y="0" type="line"/>
+ <point x="1250" y="0" type="line"/>
+ <point x="1500" y="1005" type="line" smooth="yes"/>
+ <point x="1548" y="1198"/>
+ <point x="1588" y="1352"/>
+ <point x="1621" y="1431" type="curve"/>
+ <point x="1431" y="1431" type="line"/>
+ </contour>
+ <contour>
+ <point x="636" y="1431" type="line"/>
+ <point x="446" y="1431" type="line"/>
+ <point x="442" y="1352"/>
+ <point x="403" y="1197"/>
+ <point x="355" y="1005" type="curve" smooth="yes"/>
+ <point x="211" y="426" type="line" smooth="yes"/>
+ <point x="163" y="233"/>
+ <point x="124" y="78"/>
+ <point x="90" y="0" type="curve"/>
+ <point x="280" y="0" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetassocfeat.ufo/glyphs/L_tnC_apO_.glif b/tests/reference/ufo/psfsetassocfeat.ufo/glyphs/L_tnC_apO_.glif
new file mode 100644
index 0000000..19c4886
--- /dev/null
+++ b/tests/reference/ufo/psfsetassocfeat.ufo/glyphs/L_tnC_apO_.glif
@@ -0,0 +1,40 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnCapO" format="2">
+ <advance width="1447"/>
+ <unicode hex="004F"/>
+ <anchor x="657" y="0" name="H"/>
+ <anchor x="632" y="-100" name="L"/>
+ <anchor x="896" y="0" name="O"/>
+ <anchor x="1700" y="1200" name="R"/>
+ <anchor x="1039" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="719" y="147" type="curve" smooth="yes"/>
+ <point x="514" y="147"/>
+ <point x="386" y="300"/>
+ <point x="386" y="541" type="curve" smooth="yes"/>
+ <point x="386" y="871"/>
+ <point x="606" y="1284"/>
+ <point x="963" y="1284" type="curve" smooth="yes"/>
+ <point x="1164" y="1284"/>
+ <point x="1291" y="1133"/>
+ <point x="1291" y="892" type="curve" smooth="yes"/>
+ <point x="1291" y="563"/>
+ <point x="1077" y="147"/>
+ </contour>
+ <contour>
+ <point x="1492" y="931" type="curve" smooth="yes"/>
+ <point x="1492" y="1263"/>
+ <point x="1278" y="1455"/>
+ <point x="1015" y="1455" type="curve" smooth="yes"/>
+ <point x="599" y="1455"/>
+ <point x="185" y="1036"/>
+ <point x="185" y="500" type="curve" smooth="yes"/>
+ <point x="185" y="167"/>
+ <point x="400" y="-25"/>
+ <point x="666" y="-25" type="curve" smooth="yes"/>
+ <point x="1078" y="-25"/>
+ <point x="1492" y="395"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetassocfeat.ufo/glyphs/L_tnC_apP_.glif b/tests/reference/ufo/psfsetassocfeat.ufo/glyphs/L_tnC_apP_.glif
new file mode 100644
index 0000000..5b51a57
--- /dev/null
+++ b/tests/reference/ufo/psfsetassocfeat.ufo/glyphs/L_tnC_apP_.glif
@@ -0,0 +1,50 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnCapP" format="2">
+ <advance width="1190"/>
+ <unicode hex="0050"/>
+ <anchor x="552" y="-100" name="L"/>
+ <anchor x="959" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="443" y="554" type="line"/>
+ <point x="506" y="547"/>
+ <point x="597" y="544"/>
+ <point x="670" y="544" type="curve" smooth="yes"/>
+ <point x="1058" y="544"/>
+ <point x="1321" y="733"/>
+ <point x="1321" y="1084" type="curve" smooth="yes"/>
+ <point x="1321" y="1302"/>
+ <point x="1141" y="1441"/>
+ <point x="864" y="1441" type="curve" smooth="yes"/>
+ <point x="651" y="1441"/>
+ <point x="456" y="1431"/>
+ <point x="456" y="1431" type="curve"/>
+ <point x="452" y="1352"/>
+ <point x="407" y="1172"/>
+ <point x="359" y="980" type="curve"/>
+ <point x="221" y="426" type="line" smooth="yes"/>
+ <point x="173" y="233"/>
+ <point x="134" y="78"/>
+ <point x="100" y="0" type="curve"/>
+ <point x="320" y="0" type="line"/>
+ <point x="324" y="76"/>
+ <point x="362" y="232"/>
+ <point x="411" y="426" type="curve" smooth="yes"/>
+ </contour>
+ <contour>
+ <point x="623" y="1279" type="line"/>
+ <point x="692" y="1282"/>
+ <point x="721" y="1284"/>
+ <point x="815" y="1284" type="curve" smooth="yes"/>
+ <point x="1036" y="1284"/>
+ <point x="1121" y="1172"/>
+ <point x="1121" y="1048" type="curve" smooth="yes"/>
+ <point x="1121" y="845"/>
+ <point x="968" y="696"/>
+ <point x="693" y="696" type="curve" smooth="yes"/>
+ <point x="618" y="696"/>
+ <point x="542" y="698"/>
+ <point x="481" y="706" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetassocfeat.ufo/glyphs/L_tnC_apQ_.glif b/tests/reference/ufo/psfsetassocfeat.ufo/glyphs/L_tnC_apQ_.glif
new file mode 100644
index 0000000..3dcbc8d
--- /dev/null
+++ b/tests/reference/ufo/psfsetassocfeat.ufo/glyphs/L_tnC_apQ_.glif
@@ -0,0 +1,52 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnCapQ" format="2">
+ <advance width="1459"/>
+ <unicode hex="0051"/>
+ <anchor x="589" y="-270" name="L"/>
+ <anchor x="1039" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="1495" y="939" type="curve" smooth="yes"/>
+ <point x="1495" y="1266"/>
+ <point x="1306" y="1455"/>
+ <point x="1026" y="1455" type="curve" smooth="yes"/>
+ <point x="703" y="1455"/>
+ <point x="332" y="1195"/>
+ <point x="215" y="726" type="curve" smooth="yes"/>
+ <point x="194" y="642"/>
+ <point x="185" y="564"/>
+ <point x="185" y="492" type="curve" smooth="yes"/>
+ <point x="185" y="165"/>
+ <point x="388" y="-25"/>
+ <point x="652" y="-25" type="curve" smooth="yes"/>
+ <point x="714" y="-25"/>
+ <point x="781" y="-17"/>
+ <point x="829" y="0" type="curve"/>
+ <point x="898" y="0"/>
+ <point x="1133" y="-186"/>
+ <point x="1217" y="-186" type="curve" smooth="yes"/>
+ <point x="1271" y="-186"/>
+ <point x="1355" y="-79"/>
+ <point x="1388" y="-44" type="curve"/>
+ <point x="1258" y="-27"/>
+ <point x="1155" y="27"/>
+ <point x="1049" y="103" type="curve"/>
+ <point x="1253" y="217"/>
+ <point x="1495" y="528"/>
+ </contour>
+ <contour>
+ <point x="690" y="147" type="curve" smooth="yes"/>
+ <point x="492" y="147"/>
+ <point x="384" y="284"/>
+ <point x="384" y="508" type="curve" smooth="yes"/>
+ <point x="384" y="856"/>
+ <point x="609" y="1284"/>
+ <point x="994" y="1284" type="curve" smooth="yes"/>
+ <point x="1188" y="1284"/>
+ <point x="1295" y="1149"/>
+ <point x="1295" y="925" type="curve" smooth="yes"/>
+ <point x="1295" y="490"/>
+ <point x="985" y="147"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetassocfeat.ufo/glyphs/L_tnC_apR_.glif b/tests/reference/ufo/psfsetassocfeat.ufo/glyphs/L_tnC_apR_.glif
new file mode 100644
index 0000000..c8f8186
--- /dev/null
+++ b/tests/reference/ufo/psfsetassocfeat.ufo/glyphs/L_tnC_apR_.glif
@@ -0,0 +1,55 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnCapR" format="2">
+ <advance width="1295"/>
+ <unicode hex="0052"/>
+ <anchor x="590" y="0" name="H"/>
+ <anchor x="525" y="-100" name="L"/>
+ <anchor x="932" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="457" y="613" type="line"/>
+ <point x="712" y="613" type="line" smooth="yes"/>
+ <point x="1010" y="613"/>
+ <point x="1303" y="784"/>
+ <point x="1303" y="1114" type="curve" smooth="yes"/>
+ <point x="1303" y="1326"/>
+ <point x="1114" y="1441"/>
+ <point x="844" y="1441" type="curve" smooth="yes"/>
+ <point x="610" y="1441"/>
+ <point x="456" y="1431"/>
+ <point x="456" y="1431" type="curve"/>
+ <point x="452" y="1352"/>
+ <point x="407" y="1172"/>
+ <point x="359" y="980" type="curve" smooth="yes"/>
+ <point x="221" y="426" type="line"/>
+ <point x="173" y="233"/>
+ <point x="134" y="78"/>
+ <point x="100" y="0" type="curve"/>
+ <point x="320" y="0" type="line"/>
+ <point x="324" y="76"/>
+ <point x="363" y="233"/>
+ <point x="411" y="426" type="curve"/>
+ </contour>
+ <contour>
+ <point x="623" y="1279" type="line"/>
+ <point x="677" y="1281"/>
+ <point x="725" y="1284"/>
+ <point x="795" y="1284" type="curve" smooth="yes"/>
+ <point x="1003" y="1284"/>
+ <point x="1104" y="1203"/>
+ <point x="1104" y="1076" type="curve" smooth="yes"/>
+ <point x="1104" y="856"/>
+ <point x="921" y="764"/>
+ <point x="685" y="764" type="curve" smooth="yes"/>
+ <point x="495" y="764" type="line"/>
+ </contour>
+ <contour>
+ <point x="656" y="622" type="line"/>
+ <point x="930" y="0" type="line"/>
+ <point x="1185" y="0" type="line"/>
+ <point x="1122" y="89"/>
+ <point x="864" y="602"/>
+ <point x="828" y="676" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetassocfeat.ufo/glyphs/L_tnC_apS_.glif b/tests/reference/ufo/psfsetassocfeat.ufo/glyphs/L_tnC_apS_.glif
new file mode 100644
index 0000000..01e9f47
--- /dev/null
+++ b/tests/reference/ufo/psfsetassocfeat.ufo/glyphs/L_tnC_apS_.glif
@@ -0,0 +1,50 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnCapS" format="2">
+ <advance width="1155"/>
+ <unicode hex="0053"/>
+ <anchor x="520" y="0" name="H"/>
+ <anchor x="495" y="-100" name="L"/>
+ <anchor x="902" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="1260" y="1347" type="line"/>
+ <point x="1146" y="1419"/>
+ <point x="1021" y="1455"/>
+ <point x="867" y="1455" type="curve" smooth="yes"/>
+ <point x="549" y="1455"/>
+ <point x="320" y="1303"/>
+ <point x="320" y="1040" type="curve" smooth="yes"/>
+ <point x="320" y="901"/>
+ <point x="438" y="794"/>
+ <point x="622" y="691" type="curve" smooth="yes"/>
+ <point x="877" y="549"/>
+ <point x="914" y="461"/>
+ <point x="914" y="378" type="curve" smooth="yes"/>
+ <point x="914" y="256"/>
+ <point x="792" y="147"/>
+ <point x="621" y="147" type="curve" smooth="yes"/>
+ <point x="473" y="147"/>
+ <point x="278" y="235"/>
+ <point x="161" y="378" type="curve"/>
+ <point x="65" y="187" type="line"/>
+ <point x="178" y="73"/>
+ <point x="365" y="-25"/>
+ <point x="558" y="-25" type="curve" smooth="yes"/>
+ <point x="852" y="-25"/>
+ <point x="1114" y="115"/>
+ <point x="1114" y="414" type="curve" smooth="yes"/>
+ <point x="1114" y="526"/>
+ <point x="1057" y="679"/>
+ <point x="800" y="828" type="curve" smooth="yes"/>
+ <point x="597" y="946"/>
+ <point x="510" y="1005"/>
+ <point x="510" y="1079" type="curve" smooth="yes"/>
+ <point x="510" y="1210"/>
+ <point x="659" y="1284"/>
+ <point x="845" y="1284" type="curve" smooth="yes"/>
+ <point x="959" y="1284"/>
+ <point x="1075" y="1240"/>
+ <point x="1173" y="1156" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetassocfeat.ufo/glyphs/L_tnC_apT_.glif b/tests/reference/ufo/psfsetassocfeat.ufo/glyphs/L_tnC_apT_.glif
new file mode 100644
index 0000000..0eeece4
--- /dev/null
+++ b/tests/reference/ufo/psfsetassocfeat.ufo/glyphs/L_tnC_apT_.glif
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnCapT" format="2">
+ <advance width="1245"/>
+ <unicode hex="0054"/>
+ <anchor x="562" y="0" name="H"/>
+ <anchor x="562" y="-100" name="L"/>
+ <anchor x="944" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="341" y="1431" type="line"/>
+ <point x="296" y="1250" type="line"/>
+ <point x="380" y="1266"/>
+ <point x="457" y="1269"/>
+ <point x="546" y="1269" type="curve" smooth="yes"/>
+ <point x="781" y="1269" type="line"/>
+ <point x="571" y="426" type="line" smooth="yes"/>
+ <point x="523" y="233"/>
+ <point x="481" y="78"/>
+ <point x="445" y="0" type="curve"/>
+ <point x="675" y="0" type="line"/>
+ <point x="677" y="78"/>
+ <point x="713" y="233"/>
+ <point x="761" y="426" type="curve" smooth="yes"/>
+ <point x="971" y="1269" type="line"/>
+ <point x="1211" y="1269" type="line" smooth="yes"/>
+ <point x="1301" y="1269"/>
+ <point x="1375" y="1266"/>
+ <point x="1451" y="1250" type="curve"/>
+ <point x="1496" y="1431" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetassocfeat.ufo/glyphs/L_tnC_apU_.glif b/tests/reference/ufo/psfsetassocfeat.ufo/glyphs/L_tnC_apU_.glif
new file mode 100644
index 0000000..ed6e991
--- /dev/null
+++ b/tests/reference/ufo/psfsetassocfeat.ufo/glyphs/L_tnC_apU_.glif
@@ -0,0 +1,50 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnCapU" format="2">
+ <advance width="1420"/>
+ <unicode hex="0055"/>
+ <anchor x="647" y="0" name="H"/>
+ <anchor x="622" y="-100" name="L"/>
+ <anchor x="865" y="0" name="O"/>
+ <anchor x="1640" y="1200" name="R"/>
+ <anchor x="1029" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="1346" y="1431" type="line"/>
+ <point x="1126" y="549" type="line" smooth="yes"/>
+ <point x="1055" y="264"/>
+ <point x="916" y="132"/>
+ <point x="682" y="132" type="curve" smooth="yes"/>
+ <point x="485" y="132"/>
+ <point x="421" y="244"/>
+ <point x="421" y="391" type="curve" smooth="yes"/>
+ <point x="421" y="451"/>
+ <point x="431" y="516"/>
+ <point x="448" y="582" type="curve" smooth="yes"/>
+ <point x="661" y="1431" type="line"/>
+ <point x="456" y="1431" type="line"/>
+ <point x="451" y="1352"/>
+ <point x="414" y="1198"/>
+ <point x="365" y="1005" type="curve" smooth="yes"/>
+ <point x="251" y="552" type="line" smooth="yes"/>
+ <point x="236" y="493"/>
+ <point x="228" y="435"/>
+ <point x="228" y="379" type="curve" smooth="yes"/>
+ <point x="228" y="157"/>
+ <point x="351" y="-25"/>
+ <point x="643" y="-25" type="curve" smooth="yes"/>
+ <point x="1020" y="-25"/>
+ <point x="1223" y="177"/>
+ <point x="1299" y="480" type="curve" smooth="yes"/>
+ <point x="1430" y="1005" type="line" smooth="yes"/>
+ <point x="1480" y="1207"/>
+ <point x="1519" y="1352"/>
+ <point x="1551" y="1431" type="curve"/>
+ </contour>
+ </outline>
+ <lib>
+ <dict>
+ <key>org.sil.assocFeature</key>
+ <string>fea2</string>
+ </dict>
+ </lib>
+</glyph>
diff --git a/tests/reference/ufo/psfsetassocfeat.ufo/glyphs/L_tnC_apV_.glif b/tests/reference/ufo/psfsetassocfeat.ufo/glyphs/L_tnC_apV_.glif
new file mode 100644
index 0000000..2bf8b96
--- /dev/null
+++ b/tests/reference/ufo/psfsetassocfeat.ufo/glyphs/L_tnC_apV_.glif
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnCapV" format="2">
+ <advance width="1345"/>
+ <unicode hex="0056"/>
+ <anchor x="620" y="0" name="H"/>
+ <anchor x="587" y="-100" name="L"/>
+ <anchor x="820" y="0" name="O"/>
+ <anchor x="994" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="1381" y="1431" type="line"/>
+ <point x="654" y="191" type="line"/>
+ <point x="536" y="1431" type="line"/>
+ <point x="331" y="1431" type="line"/>
+ <point x="344" y="1350"/>
+ <point x="355" y="1262"/>
+ <point x="377" y="1073" type="curve" smooth="yes"/>
+ <point x="500" y="0" type="line"/>
+ <point x="725" y="0" type="line"/>
+ <point x="1377" y="1073" type="line" smooth="yes"/>
+ <point x="1492" y="1263"/>
+ <point x="1550" y="1350"/>
+ <point x="1606" y="1431" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetassocfeat.ufo/glyphs/L_tnC_apW_.glif b/tests/reference/ufo/psfsetassocfeat.ufo/glyphs/L_tnC_apW_.glif
new file mode 100644
index 0000000..553ea17
--- /dev/null
+++ b/tests/reference/ufo/psfsetassocfeat.ufo/glyphs/L_tnC_apW_.glif
@@ -0,0 +1,44 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnCapW" format="2">
+ <advance width="2060"/>
+ <unicode hex="0057"/>
+ <anchor x="942" y="-100" name="L"/>
+ <anchor x="1349" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="1535" y="0" type="line"/>
+ <point x="2107" y="1073" type="line" smooth="yes"/>
+ <point x="2208" y="1263"/>
+ <point x="2259" y="1350"/>
+ <point x="2311" y="1431" type="curve"/>
+ <point x="2081" y="1431" type="line"/>
+ <point x="1431" y="127" type="line"/>
+ <point x="1420" y="0" type="line"/>
+ </contour>
+ <contour>
+ <point x="1310" y="0" type="line"/>
+ <point x="1420" y="0" type="line"/>
+ <point x="1461" y="127" type="line"/>
+ <point x="1406" y="1431" type="line"/>
+ <point x="1231" y="1431" type="line"/>
+ <point x="1248" y="1279" type="line"/>
+ </contour>
+ <contour>
+ <point x="625" y="0" type="line"/>
+ <point x="1406" y="1431" type="line"/>
+ <point x="1221" y="1431" type="line"/>
+ <point x="521" y="127" type="line"/>
+ <point x="521" y="0" type="line"/>
+ </contour>
+ <contour>
+ <point x="546" y="1431" type="line"/>
+ <point x="336" y="1431" type="line"/>
+ <point x="348" y="1353"/>
+ <point x="355" y="1260"/>
+ <point x="362" y="1073" type="curve" smooth="yes"/>
+ <point x="400" y="0" type="line"/>
+ <point x="521" y="0" type="line"/>
+ <point x="551" y="127" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetassocfeat.ufo/glyphs/L_tnC_apX_.glif b/tests/reference/ufo/psfsetassocfeat.ufo/glyphs/L_tnC_apX_.glif
new file mode 100644
index 0000000..2da5787
--- /dev/null
+++ b/tests/reference/ufo/psfsetassocfeat.ufo/glyphs/L_tnC_apX_.glif
@@ -0,0 +1,39 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnCapX" format="2">
+ <advance width="1305"/>
+ <unicode hex="0058"/>
+ <anchor x="565" y="-100" name="L"/>
+ <anchor x="972" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="970" y="0" type="line"/>
+ <point x="1190" y="0" type="line"/>
+ <point x="1148" y="80"/>
+ <point x="1125" y="124"/>
+ <point x="1045" y="329" type="curve" smooth="yes"/>
+ <point x="611" y="1431" type="line"/>
+ <point x="386" y="1431" type="line"/>
+ <point x="430" y="1348"/>
+ <point x="462" y="1289"/>
+ <point x="541" y="1088" type="curve" smooth="yes"/>
+ </contour>
+ <contour>
+ <point x="752" y="872" type="line"/>
+ <point x="278" y="333" type="line" smooth="yes"/>
+ <point x="98" y="129"/>
+ <point x="53" y="84"/>
+ <point x="-30" y="0" type="curve"/>
+ <point x="210" y="0" type="line"/>
+ <point x="750" y="622" type="line"/>
+ </contour>
+ <contour>
+ <point x="765" y="622" type="line"/>
+ <point x="1183" y="1088" type="line" smooth="yes"/>
+ <point x="1360" y="1285"/>
+ <point x="1425" y="1355"/>
+ <point x="1506" y="1431" type="curve"/>
+ <point x="1261" y="1431" type="line"/>
+ <point x="767" y="872" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetassocfeat.ufo/glyphs/L_tnC_apY_.glif b/tests/reference/ufo/psfsetassocfeat.ufo/glyphs/L_tnC_apY_.glif
new file mode 100644
index 0000000..9ec65ef
--- /dev/null
+++ b/tests/reference/ufo/psfsetassocfeat.ufo/glyphs/L_tnC_apY_.glif
@@ -0,0 +1,39 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnCapY" format="2">
+ <advance width="1300"/>
+ <unicode hex="0059"/>
+ <anchor x="565" y="-100" name="L"/>
+ <anchor x="972" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="331" y="1431" type="line"/>
+ <point x="407" y="1285"/>
+ <point x="446" y="1173"/>
+ <point x="490" y="1044" type="curve"/>
+ <point x="661" y="549" type="line"/>
+ <point x="829" y="661" type="line"/>
+ <point x="551" y="1431" type="line"/>
+ </contour>
+ <contour>
+ <point x="1321" y="1431" type="line"/>
+ <point x="684" y="661" type="line"/>
+ <point x="796" y="549" type="line"/>
+ <point x="1215" y="1044" type="line" smooth="yes"/>
+ <point x="1322" y="1171"/>
+ <point x="1402" y="1265"/>
+ <point x="1561" y="1431" type="curve"/>
+ </contour>
+ <contour>
+ <point x="700" y="0" type="line"/>
+ <point x="704" y="78"/>
+ <point x="743" y="233"/>
+ <point x="791" y="426" type="curve" smooth="yes"/>
+ <point x="854" y="681" type="line"/>
+ <point x="664" y="681" type="line"/>
+ <point x="601" y="426" type="line" smooth="yes"/>
+ <point x="553" y="233"/>
+ <point x="514" y="78"/>
+ <point x="480" y="0" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetassocfeat.ufo/glyphs/L_tnS_mA_.glif b/tests/reference/ufo/psfsetassocfeat.ufo/glyphs/L_tnS_mA_.glif
new file mode 100644
index 0000000..586e494
--- /dev/null
+++ b/tests/reference/ufo/psfsetassocfeat.ufo/glyphs/L_tnS_mA_.glif
@@ -0,0 +1,77 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmA" format="2">
+ <advance width="1107"/>
+ <unicode hex="0061"/>
+ <anchor x="860" y="0" name="H"/>
+ <anchor x="455" y="-100" name="L"/>
+ <anchor x="1065" y="0" name="O"/>
+ <anchor x="1310" y="1000" name="R"/>
+ <anchor x="755" y="1100" name="U"/>
+ <outline>
+ <contour>
+ <point x="972" y="0" type="line"/>
+ <point x="965" y="48"/>
+ <point x="960" y="98"/>
+ <point x="960" y="149" type="curve" smooth="yes"/>
+ <point x="960" y="214"/>
+ <point x="967" y="284"/>
+ <point x="987" y="363" type="curve"/>
+ <point x="1077" y="726" type="line"/>
+ <point x="1081" y="744"/>
+ <point x="1084" y="762"/>
+ <point x="1084" y="779" type="curve" smooth="yes"/>
+ <point x="1084" y="912"/>
+ <point x="955" y="1019"/>
+ <point x="751" y="1019" type="curve" smooth="yes"/>
+ <point x="599" y="1019"/>
+ <point x="502" y="974"/>
+ <point x="389" y="931" type="curve"/>
+ <point x="373" y="889"/>
+ <point x="343" y="783"/>
+ <point x="331" y="740" type="curve"/>
+ <point x="468" y="820"/>
+ <point x="560" y="862"/>
+ <point x="666" y="862" type="curve" smooth="yes"/>
+ <point x="798" y="862"/>
+ <point x="885" y="810"/>
+ <point x="885" y="718" type="curve" smooth="yes"/>
+ <point x="885" y="705"/>
+ <point x="884" y="691"/>
+ <point x="880" y="677" type="curve" smooth="yes"/>
+ <point x="867" y="622" type="line"/>
+ <point x="825" y="619"/>
+ <point x="661" y="605"/>
+ <point x="591" y="598" type="curve" smooth="yes"/>
+ <point x="282" y="568"/>
+ <point x="102" y="415"/>
+ <point x="102" y="233" type="curve" smooth="yes"/>
+ <point x="102" y="103"/>
+ <point x="223" y="-25"/>
+ <point x="390" y="-25" type="curve" smooth="yes"/>
+ <point x="514" y="-25"/>
+ <point x="674" y="47"/>
+ <point x="779" y="152" type="curve"/>
+ <point x="779" y="89"/>
+ <point x="787" y="31"/>
+ <point x="792" y="0" type="curve"/>
+ </contour>
+ <contour>
+ <point x="791" y="319" type="line"/>
+ <point x="674" y="191"/>
+ <point x="553" y="137"/>
+ <point x="451" y="137" type="curve" smooth="yes"/>
+ <point x="355" y="137"/>
+ <point x="290" y="192"/>
+ <point x="290" y="264" type="curve" smooth="yes"/>
+ <point x="290" y="274"/>
+ <point x="291" y="285"/>
+ <point x="294" y="296" type="curve" smooth="yes"/>
+ <point x="315" y="380"/>
+ <point x="432" y="450"/>
+ <point x="566" y="461" type="curve" smooth="yes"/>
+ <point x="631" y="466"/>
+ <point x="782" y="483"/>
+ <point x="832" y="485" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetassocfeat.ufo/glyphs/L_tnS_mA_A_cute.glif b/tests/reference/ufo/psfsetassocfeat.ufo/glyphs/L_tnS_mA_A_cute.glif
new file mode 100644
index 0000000..198d6db
--- /dev/null
+++ b/tests/reference/ufo/psfsetassocfeat.ufo/glyphs/L_tnS_mA_A_cute.glif
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmAAcute" format="2">
+ <advance width="1107"/>
+ <unicode hex="00E1"/>
+ <anchor x="860" y="0" name="H"/>
+ <anchor x="455" y="-100" name="L"/>
+ <anchor x="1065" y="0" name="O"/>
+ <anchor x="1310" y="1000" name="R"/>
+ <anchor x="889" y="1635" name="U"/>
+ <outline>
+ <component base="LtnSmA"/>
+ <component base="CombAcute" xOffset="1110"/>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetassocfeat.ufo/glyphs/L_tnS_mA_C_ircum.glif b/tests/reference/ufo/psfsetassocfeat.ufo/glyphs/L_tnS_mA_C_ircum.glif
new file mode 100644
index 0000000..f5cfb16
--- /dev/null
+++ b/tests/reference/ufo/psfsetassocfeat.ufo/glyphs/L_tnS_mA_C_ircum.glif
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmACircum" format="2">
+ <advance width="1107"/>
+ <unicode hex="00E2"/>
+ <anchor x="860" y="0" name="H"/>
+ <anchor x="455" y="-100" name="L"/>
+ <anchor x="1065" y="0" name="O"/>
+ <anchor x="1310" y="1000" name="R"/>
+ <anchor x="854" y="1635" name="U"/>
+ <outline>
+ <component base="LtnSmA"/>
+ <component base="CombCircum" xOffset="1075"/>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetassocfeat.ufo/glyphs/L_tnS_mA_D_iaer.glif b/tests/reference/ufo/psfsetassocfeat.ufo/glyphs/L_tnS_mA_D_iaer.glif
new file mode 100644
index 0000000..6f05301
--- /dev/null
+++ b/tests/reference/ufo/psfsetassocfeat.ufo/glyphs/L_tnS_mA_D_iaer.glif
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmADiaer" format="2">
+ <advance width="1107"/>
+ <unicode hex="00E4"/>
+ <anchor x="860" y="0" name="H"/>
+ <anchor x="455" y="-100" name="L"/>
+ <anchor x="1065" y="0" name="O"/>
+ <anchor x="1310" y="1000" name="R"/>
+ <anchor x="852" y="1505" name="U"/>
+ <outline>
+ <component base="LtnSmA"/>
+ <component base="CombDiaer" xOffset="1105"/>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetassocfeat.ufo/glyphs/L_tnS_mA_G_rave.glif b/tests/reference/ufo/psfsetassocfeat.ufo/glyphs/L_tnS_mA_G_rave.glif
new file mode 100644
index 0000000..9048920
--- /dev/null
+++ b/tests/reference/ufo/psfsetassocfeat.ufo/glyphs/L_tnS_mA_G_rave.glif
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmAGrave" format="2">
+ <advance width="1107"/>
+ <unicode hex="00E0"/>
+ <anchor x="860" y="0" name="H"/>
+ <anchor x="455" y="-100" name="L"/>
+ <anchor x="1065" y="0" name="O"/>
+ <anchor x="1310" y="1000" name="R"/>
+ <anchor x="889" y="1635" name="U"/>
+ <outline>
+ <component base="LtnSmA"/>
+ <component base="CombGrave" xOffset="1090"/>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetassocfeat.ufo/glyphs/L_tnS_mA_R_ingA_bv.glif b/tests/reference/ufo/psfsetassocfeat.ufo/glyphs/L_tnS_mA_R_ingA_bv.glif
new file mode 100644
index 0000000..8ada58f
--- /dev/null
+++ b/tests/reference/ufo/psfsetassocfeat.ufo/glyphs/L_tnS_mA_R_ingA_bv.glif
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmARingAbv" format="2">
+ <advance width="1107"/>
+ <unicode hex="00E5"/>
+ <anchor x="860" y="0" name="H"/>
+ <anchor x="455" y="-100" name="L"/>
+ <anchor x="1065" y="0" name="O"/>
+ <anchor x="1310" y="1000" name="R"/>
+ <anchor x="919" y="1635" name="U"/>
+ <outline>
+ <component base="LtnSmA"/>
+ <component base="CombRingAbv" xOffset="1140"/>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetassocfeat.ufo/glyphs/L_tnS_mA_T_ilde.glif b/tests/reference/ufo/psfsetassocfeat.ufo/glyphs/L_tnS_mA_T_ilde.glif
new file mode 100644
index 0000000..c29348b
--- /dev/null
+++ b/tests/reference/ufo/psfsetassocfeat.ufo/glyphs/L_tnS_mA_T_ilde.glif
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmATilde" format="2">
+ <advance width="1107"/>
+ <unicode hex="00E3"/>
+ <anchor x="860" y="0" name="H"/>
+ <anchor x="455" y="-100" name="L"/>
+ <anchor x="1065" y="0" name="O"/>
+ <anchor x="1310" y="1000" name="R"/>
+ <anchor x="850" y="1475" name="U"/>
+ <outline>
+ <component base="LtnSmA"/>
+ <component base="CombTilde" xOffset="1140"/>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetassocfeat.ufo/glyphs/L_tnS_mB_.glif b/tests/reference/ufo/psfsetassocfeat.ufo/glyphs/L_tnS_mB_.glif
new file mode 100644
index 0000000..b3a3696
--- /dev/null
+++ b/tests/reference/ufo/psfsetassocfeat.ufo/glyphs/L_tnS_mB_.glif
@@ -0,0 +1,55 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmB" format="2">
+ <advance width="1144"/>
+ <unicode hex="0062"/>
+ <anchor x="530" y="0" name="H"/>
+ <anchor x="505" y="-100" name="L"/>
+ <anchor x="1345" y="1000" name="R"/>
+ <anchor x="938" y="1635" name="U"/>
+ <outline>
+ <contour>
+ <point x="437" y="1570" type="line"/>
+ <point x="437" y="1456"/>
+ <point x="402" y="1246"/>
+ <point x="367" y="1105" type="curve" smooth="yes"/>
+ <point x="110" y="85" type="line"/>
+ <point x="198" y="44"/>
+ <point x="355" y="-25"/>
+ <point x="517" y="-25" type="curve" smooth="yes"/>
+ <point x="675" y="-25"/>
+ <point x="795" y="24"/>
+ <point x="907" y="125" type="curve" smooth="yes"/>
+ <point x="1050" y="255"/>
+ <point x="1162" y="466"/>
+ <point x="1162" y="695" type="curve" smooth="yes"/>
+ <point x="1162" y="930"/>
+ <point x="1046" y="1020"/>
+ <point x="907" y="1020" type="curve" smooth="yes"/>
+ <point x="754" y="1020"/>
+ <point x="584" y="878"/>
+ <point x="456" y="719" type="curve"/>
+ <point x="552" y="1105" type="line" smooth="yes"/>
+ <point x="600" y="1296"/>
+ <point x="627" y="1508"/>
+ <point x="627" y="1570" type="curve"/>
+ </contour>
+ <contour>
+ <point x="382" y="429" type="line"/>
+ <point x="485" y="617"/>
+ <point x="708" y="850"/>
+ <point x="822" y="850" type="curve" smooth="yes"/>
+ <point x="913" y="850"/>
+ <point x="972" y="784"/>
+ <point x="972" y="635" type="curve" smooth="yes"/>
+ <point x="972" y="469"/>
+ <point x="909" y="336"/>
+ <point x="822" y="250" type="curve" smooth="yes"/>
+ <point x="741" y="169"/>
+ <point x="638" y="125"/>
+ <point x="552" y="125" type="curve" smooth="yes"/>
+ <point x="466" y="125"/>
+ <point x="376" y="167"/>
+ <point x="325" y="200" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetassocfeat.ufo/glyphs/L_tnS_mC_.glif b/tests/reference/ufo/psfsetassocfeat.ufo/glyphs/L_tnS_mC_.glif
new file mode 100644
index 0000000..f54fbe9
--- /dev/null
+++ b/tests/reference/ufo/psfsetassocfeat.ufo/glyphs/L_tnS_mC_.glif
@@ -0,0 +1,39 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmC" format="2">
+ <advance width="989"/>
+ <unicode hex="0063"/>
+ <anchor x="520" y="0" name="H"/>
+ <anchor x="495" y="-100" name="L"/>
+ <anchor x="1210" y="1000" name="R"/>
+ <anchor x="785" y="1100" name="U"/>
+ <outline>
+ <contour>
+ <point x="917" y="255" type="line"/>
+ <point x="811" y="179"/>
+ <point x="703" y="137"/>
+ <point x="583" y="137" type="curve" smooth="yes"/>
+ <point x="427" y="137"/>
+ <point x="331" y="239"/>
+ <point x="331" y="406" type="curve" smooth="yes"/>
+ <point x="331" y="619"/>
+ <point x="499" y="858"/>
+ <point x="742" y="858" type="curve" smooth="yes"/>
+ <point x="845" y="858"/>
+ <point x="924" y="824"/>
+ <point x="998" y="760" type="curve"/>
+ <point x="1077" y="936" type="line"/>
+ <point x="1016" y="985"/>
+ <point x="902" y="1020"/>
+ <point x="789" y="1020" type="curve" smooth="yes"/>
+ <point x="420" y="1020"/>
+ <point x="139" y="737"/>
+ <point x="139" y="381" type="curve" smooth="yes"/>
+ <point x="139" y="130"/>
+ <point x="309" y="-25"/>
+ <point x="532" y="-25" type="curve" smooth="yes"/>
+ <point x="682" y="-25"/>
+ <point x="785" y="9"/>
+ <point x="904" y="83" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetassocfeat.ufo/glyphs/L_tnS_mD_.glif b/tests/reference/ufo/psfsetassocfeat.ufo/glyphs/L_tnS_mD_.glif
new file mode 100644
index 0000000..4ea9ea1
--- /dev/null
+++ b/tests/reference/ufo/psfsetassocfeat.ufo/glyphs/L_tnS_mD_.glif
@@ -0,0 +1,65 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmD" format="2">
+ <advance width="1197"/>
+ <unicode hex="0064"/>
+ <anchor x="545" y="0" name="H"/>
+ <anchor x="520" y="-100" name="L"/>
+ <anchor x="1380" y="1000" name="R"/>
+ <anchor x="953" y="1635" name="U"/>
+ <outline>
+ <contour>
+ <point x="1144" y="1570" type="line"/>
+ <point x="1144" y="1456"/>
+ <point x="1114" y="1327"/>
+ <point x="1079" y="1175" type="curve" smooth="yes"/>
+ <point x="1024" y="935" type="line"/>
+ <point x="957" y="978"/>
+ <point x="854" y="1020"/>
+ <point x="759" y="1020" type="curve" smooth="yes"/>
+ <point x="650" y="1020"/>
+ <point x="534" y="979"/>
+ <point x="429" y="895" type="curve" smooth="yes"/>
+ <point x="262" y="761"/>
+ <point x="139" y="532"/>
+ <point x="139" y="288" type="curve" smooth="yes"/>
+ <point x="139" y="94"/>
+ <point x="250" y="-25"/>
+ <point x="424" y="-25" type="curve" smooth="yes"/>
+ <point x="563" y="-25"/>
+ <point x="791" y="141"/>
+ <point x="899" y="305" type="curve"/>
+ <point x="875" y="196"/>
+ <point x="869" y="93"/>
+ <point x="869" y="0" type="curve"/>
+ <point x="1052" y="0" type="line"/>
+ <point x="1048" y="23"/>
+ <point x="1047" y="53"/>
+ <point x="1047" y="90" type="curve" smooth="yes"/>
+ <point x="1047" y="190"/>
+ <point x="1063" y="340"/>
+ <point x="1107" y="520" type="curve" smooth="yes"/>
+ <point x="1267" y="1175" type="line" smooth="yes"/>
+ <point x="1310" y="1351"/>
+ <point x="1337" y="1475"/>
+ <point x="1337" y="1570" type="curve"/>
+ </contour>
+ <contour>
+ <point x="930" y="545" type="line"/>
+ <point x="846" y="370"/>
+ <point x="592" y="130"/>
+ <point x="479" y="130" type="curve" smooth="yes"/>
+ <point x="374" y="130"/>
+ <point x="330" y="195"/>
+ <point x="330" y="316" type="curve" smooth="yes"/>
+ <point x="330" y="460"/>
+ <point x="397" y="649"/>
+ <point x="509" y="760" type="curve" smooth="yes"/>
+ <point x="572" y="822"/>
+ <point x="643" y="855"/>
+ <point x="734" y="855" type="curve" smooth="yes"/>
+ <point x="835" y="855"/>
+ <point x="898" y="832"/>
+ <point x="984" y="780" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetassocfeat.ufo/glyphs/L_tnS_mE_.glif b/tests/reference/ufo/psfsetassocfeat.ufo/glyphs/L_tnS_mE_.glif
new file mode 100644
index 0000000..a3a6490
--- /dev/null
+++ b/tests/reference/ufo/psfsetassocfeat.ufo/glyphs/L_tnS_mE_.glif
@@ -0,0 +1,52 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmE" format="2">
+ <advance width="1042"/>
+ <unicode hex="0065"/>
+ <anchor x="485" y="0" name="H"/>
+ <anchor x="484" y="-100" name="L"/>
+ <anchor x="840" y="0" name="O"/>
+ <anchor x="1285" y="1000" name="R"/>
+ <anchor x="784" y="1100" name="U"/>
+ <outline>
+ <contour>
+ <point x="967" y="270" type="line"/>
+ <point x="854" y="189"/>
+ <point x="700" y="135"/>
+ <point x="567" y="135" type="curve" smooth="yes"/>
+ <point x="386" y="135"/>
+ <point x="317" y="263"/>
+ <point x="317" y="420" type="curve" smooth="yes"/>
+ <point x="317" y="686"/>
+ <point x="522" y="872"/>
+ <point x="720" y="872" type="curve" smooth="yes"/>
+ <point x="813" y="872"/>
+ <point x="883" y="823"/>
+ <point x="883" y="753" type="curve" smooth="yes"/>
+ <point x="883" y="660"/>
+ <point x="766" y="590"/>
+ <point x="539" y="590" type="curve" smooth="yes"/>
+ <point x="468" y="590"/>
+ <point x="382" y="596"/>
+ <point x="279" y="610" type="curve"/>
+ <point x="279" y="477" type="line"/>
+ <point x="391" y="461"/>
+ <point x="487" y="453"/>
+ <point x="569" y="453" type="curve" smooth="yes"/>
+ <point x="931" y="453"/>
+ <point x="1077" y="609"/>
+ <point x="1077" y="791" type="curve" smooth="yes"/>
+ <point x="1077" y="899"/>
+ <point x="986" y="1020"/>
+ <point x="772" y="1020" type="curve" smooth="yes"/>
+ <point x="399" y="1020"/>
+ <point x="137" y="710"/>
+ <point x="137" y="380" type="curve" smooth="yes"/>
+ <point x="137" y="147"/>
+ <point x="258" y="-25"/>
+ <point x="523" y="-25" type="curve" smooth="yes"/>
+ <point x="689" y="-25"/>
+ <point x="849" y="26"/>
+ <point x="955" y="83" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetassocfeat.ufo/glyphs/L_tnS_mF_.glif b/tests/reference/ufo/psfsetassocfeat.ufo/glyphs/L_tnS_mF_.glif
new file mode 100644
index 0000000..ede52a9
--- /dev/null
+++ b/tests/reference/ufo/psfsetassocfeat.ufo/glyphs/L_tnS_mF_.glif
@@ -0,0 +1,44 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmF" format="2">
+ <advance width="756"/>
+ <unicode hex="0066"/>
+ <anchor x="290" y="0" name="H"/>
+ <anchor x="315" y="-100" name="L"/>
+ <anchor x="908" y="1635" name="U"/>
+ <outline>
+ <contour>
+ <point x="180" y="833" type="line"/>
+ <point x="835" y="833" type="line"/>
+ <point x="871" y="975" type="line"/>
+ <point x="216" y="975" type="line"/>
+ </contour>
+ <contour>
+ <point x="1106" y="1519" type="line"/>
+ <point x="1062" y="1555"/>
+ <point x="981" y="1588"/>
+ <point x="903" y="1588" type="curve" smooth="yes"/>
+ <point x="687" y="1588"/>
+ <point x="533" y="1478"/>
+ <point x="448" y="1147" type="curve" smooth="yes"/>
+ <point x="403" y="972"/>
+ <point x="244" y="334"/>
+ <point x="223" y="0" type="curve"/>
+ <point x="436" y="0" type="line"/>
+ <point x="430" y="28"/>
+ <point x="427" y="66"/>
+ <point x="427" y="110" type="curve" smooth="yes"/>
+ <point x="427" y="213"/>
+ <point x="447" y="351"/>
+ <point x="476" y="484" type="curve" smooth="yes"/>
+ <point x="510" y="641"/>
+ <point x="558" y="846"/>
+ <point x="641" y="1186" type="curve" smooth="yes"/>
+ <point x="682" y="1353"/>
+ <point x="758" y="1421"/>
+ <point x="862" y="1421" type="curve" smooth="yes"/>
+ <point x="920" y="1421"/>
+ <point x="988" y="1392"/>
+ <point x="1022" y="1362" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetassocfeat.ufo/glyphs/L_tnS_mG_.glif b/tests/reference/ufo/psfsetassocfeat.ufo/glyphs/L_tnS_mG_.glif
new file mode 100644
index 0000000..8931f8d
--- /dev/null
+++ b/tests/reference/ufo/psfsetassocfeat.ufo/glyphs/L_tnS_mG_.glif
@@ -0,0 +1,100 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmG" format="2">
+ <advance width="1075"/>
+ <unicode hex="0067"/>
+ <anchor x="368" y="-465" name="H"/>
+ <anchor x="351" y="-535" name="L"/>
+ <anchor x="1285" y="1000" name="R"/>
+ <anchor x="730" y="1100" name="U"/>
+ <outline>
+ <contour>
+ <point x="360" y="389" type="line"/>
+ <point x="277" y="352"/>
+ <point x="168" y="266"/>
+ <point x="168" y="176" type="curve" smooth="yes"/>
+ <point x="168" y="96"/>
+ <point x="246" y="33"/>
+ <point x="483" y="-5" type="curve" smooth="yes"/>
+ <point x="707" y="-41"/>
+ <point x="781" y="-94"/>
+ <point x="781" y="-151" type="curve" smooth="yes"/>
+ <point x="781" y="-256"/>
+ <point x="580" y="-353"/>
+ <point x="411" y="-353" type="curve" smooth="yes"/>
+ <point x="202" y="-353"/>
+ <point x="104" y="-271"/>
+ <point x="104" y="-196" type="curve" smooth="yes"/>
+ <point x="104" y="-189"/>
+ <point x="104" y="-183"/>
+ <point x="106" y="-176" type="curve" smooth="yes"/>
+ <point x="120" y="-119"/>
+ <point x="170" y="-55"/>
+ <point x="409" y="20" type="curve"/>
+ <point x="410" y="48"/>
+ <point x="248" y="73"/>
+ <point x="248" y="73" type="curve"/>
+ <point x="53" y="12"/>
+ <point x="-51" y="-77"/>
+ <point x="-78" y="-186" type="curve" smooth="yes"/>
+ <point x="-82" y="-201"/>
+ <point x="-84" y="-217"/>
+ <point x="-84" y="-231" type="curve" smooth="yes"/>
+ <point x="-84" y="-396"/>
+ <point x="158" y="-495"/>
+ <point x="371" y="-495" type="curve" smooth="yes"/>
+ <point x="632" y="-495"/>
+ <point x="972" y="-360"/>
+ <point x="972" y="-125" type="curve" smooth="yes"/>
+ <point x="972" y="0"/>
+ <point x="849" y="90"/>
+ <point x="619" y="127" type="curve" smooth="yes"/>
+ <point x="403" y="162"/>
+ <point x="341" y="184"/>
+ <point x="341" y="218" type="curve" smooth="yes"/>
+ <point x="341" y="263"/>
+ <point x="447" y="325"/>
+ <point x="522" y="342" type="curve"/>
+ </contour>
+ <contour>
+ <point x="1244" y="1019" type="line"/>
+ <point x="1143" y="1012"/>
+ <point x="1002" y="977"/>
+ <point x="899" y="921" type="curve"/>
+ <point x="936" y="809" type="line"/>
+ <point x="1037" y="846"/>
+ <point x="1121" y="860"/>
+ <point x="1194" y="862" type="curve"/>
+ </contour>
+ <contour>
+ <point x="212" y="613" type="curve" smooth="yes"/>
+ <point x="212" y="449"/>
+ <point x="356" y="319"/>
+ <point x="554" y="319" type="curve" smooth="yes"/>
+ <point x="791" y="319"/>
+ <point x="1030" y="495"/>
+ <point x="1030" y="729" type="curve" smooth="yes"/>
+ <point x="1030" y="894"/>
+ <point x="887" y="1019"/>
+ <point x="689" y="1019" type="curve" smooth="yes"/>
+ <point x="441" y="1019"/>
+ <point x="212" y="847"/>
+ </contour>
+ <contour>
+ <point x="857" y="704" type="curve" smooth="yes"/>
+ <point x="857" y="555"/>
+ <point x="712" y="456"/>
+ <point x="578" y="456" type="curve" smooth="yes"/>
+ <point x="463" y="456"/>
+ <point x="385" y="530"/>
+ <point x="385" y="628" type="curve" smooth="yes"/>
+ <point x="385" y="643"/>
+ <point x="387" y="660"/>
+ <point x="391" y="676" type="curve" smooth="yes"/>
+ <point x="421" y="797"/>
+ <point x="530" y="877"/>
+ <point x="663" y="877" type="curve" smooth="yes"/>
+ <point x="779" y="877"/>
+ <point x="857" y="802"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetassocfeat.ufo/glyphs/L_tnS_mH_.glif b/tests/reference/ufo/psfsetassocfeat.ufo/glyphs/L_tnS_mH_.glif
new file mode 100644
index 0000000..08afbac
--- /dev/null
+++ b/tests/reference/ufo/psfsetassocfeat.ufo/glyphs/L_tnS_mH_.glif
@@ -0,0 +1,54 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmH" format="2">
+ <advance width="1185"/>
+ <unicode hex="0068"/>
+ <anchor x="190" y="0" name="H"/>
+ <anchor x="550" y="-100" name="L"/>
+ <anchor x="933" y="1635" name="U"/>
+ <outline>
+ <contour>
+ <point x="1055" y="0" type="line"/>
+ <point x="1047" y="30"/>
+ <point x="1043" y="65"/>
+ <point x="1043" y="102" type="curve" smooth="yes"/>
+ <point x="1043" y="143"/>
+ <point x="1048" y="188"/>
+ <point x="1055" y="238" type="curve" smooth="yes"/>
+ <point x="1069" y="327"/>
+ <point x="1170" y="636"/>
+ <point x="1170" y="745" type="curve" smooth="yes"/>
+ <point x="1170" y="917"/>
+ <point x="1095" y="1020"/>
+ <point x="930" y="1020" type="curve" smooth="yes"/>
+ <point x="760" y="1020"/>
+ <point x="591" y="877"/>
+ <point x="475" y="723" type="curve"/>
+ <point x="571" y="1105" type="line" smooth="yes"/>
+ <point x="609" y="1259"/>
+ <point x="645" y="1482"/>
+ <point x="645" y="1570" type="curve"/>
+ <point x="455" y="1570" type="line"/>
+ <point x="455" y="1456"/>
+ <point x="423" y="1257"/>
+ <point x="385" y="1105" type="curve" smooth="yes"/>
+ <point x="110" y="0" type="line"/>
+ <point x="295" y="0" type="line"/>
+ <point x="397" y="408" type="line"/>
+ <point x="492" y="612"/>
+ <point x="717" y="850"/>
+ <point x="840" y="850" type="curve" smooth="yes"/>
+ <point x="937" y="850"/>
+ <point x="970" y="798"/>
+ <point x="970" y="680" type="curve" smooth="yes"/>
+ <point x="970" y="592"/>
+ <point x="886" y="319"/>
+ <point x="872" y="203" type="curve" smooth="yes"/>
+ <point x="867" y="158"/>
+ <point x="864" y="115"/>
+ <point x="864" y="77" type="curve" smooth="yes"/>
+ <point x="864" y="48"/>
+ <point x="866" y="21"/>
+ <point x="870" y="0" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetassocfeat.ufo/glyphs/L_tnS_mI_.glif b/tests/reference/ufo/psfsetassocfeat.ufo/glyphs/L_tnS_mI_.glif
new file mode 100644
index 0000000..65ed550
--- /dev/null
+++ b/tests/reference/ufo/psfsetassocfeat.ufo/glyphs/L_tnS_mI_.glif
@@ -0,0 +1,50 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmI" format="2">
+ <advance width="554"/>
+ <unicode hex="0069"/>
+ <anchor x="235" y="0" name="H"/>
+ <anchor x="250" y="-100" name="L"/>
+ <anchor x="455" y="0" name="O"/>
+ <anchor x="745" y="1000" name="R"/>
+ <anchor x="472" y="1100" name="U"/>
+ <outline>
+ <contour>
+ <point x="361" y="1297" type="curve" smooth="yes"/>
+ <point x="361" y="1237"/>
+ <point x="404" y="1186"/>
+ <point x="467" y="1186" type="curve" smooth="yes"/>
+ <point x="552" y="1186"/>
+ <point x="624" y="1259"/>
+ <point x="624" y="1338" type="curve" smooth="yes"/>
+ <point x="624" y="1399"/>
+ <point x="578" y="1450"/>
+ <point x="513" y="1450" type="curve" smooth="yes"/>
+ <point x="428" y="1450"/>
+ <point x="361" y="1375"/>
+ </contour>
+ <contour>
+ <point x="335" y="1000" type="line"/>
+ <point x="335" y="886"/>
+ <point x="286" y="688"/>
+ <point x="246" y="537" type="curve" smooth="yes"/>
+ <point x="207" y="388" type="line" smooth="yes"/>
+ <point x="180" y="284"/>
+ <point x="165" y="172"/>
+ <point x="165" y="87" type="curve" smooth="yes"/>
+ <point x="165" y="53"/>
+ <point x="167" y="24"/>
+ <point x="172" y="0" type="curve"/>
+ <point x="372" y="0" type="line"/>
+ <point x="365" y="37"/>
+ <point x="360" y="85"/>
+ <point x="360" y="136" type="curve" smooth="yes"/>
+ <point x="360" y="208"/>
+ <point x="368" y="287"/>
+ <point x="386" y="357" type="curve" smooth="yes"/>
+ <point x="431" y="536" type="line" smooth="yes"/>
+ <point x="476" y="712"/>
+ <point x="525" y="912"/>
+ <point x="525" y="1000" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetassocfeat.ufo/glyphs/L_tnS_mJ_.glif b/tests/reference/ufo/psfsetassocfeat.ufo/glyphs/L_tnS_mJ_.glif
new file mode 100644
index 0000000..e9e18b8
--- /dev/null
+++ b/tests/reference/ufo/psfsetassocfeat.ufo/glyphs/L_tnS_mJ_.glif
@@ -0,0 +1,45 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmJ" format="2">
+ <advance width="602"/>
+ <unicode hex="006A"/>
+ <anchor x="-60" y="-500" name="L"/>
+ <anchor x="510" y="1100" name="U"/>
+ <outline>
+ <contour>
+ <point x="370" y="1000" type="line"/>
+ <point x="370" y="856"/>
+ <point x="288" y="374"/>
+ <point x="214" y="77" type="curve" smooth="yes"/>
+ <point x="152" y="-173"/>
+ <point x="29" y="-295"/>
+ <point x="-77" y="-295" type="curve" smooth="yes"/>
+ <point x="-133" y="-295"/>
+ <point x="-217" y="-264"/>
+ <point x="-253" y="-229" type="curve"/>
+ <point x="-328" y="-397" type="line"/>
+ <point x="-278" y="-437"/>
+ <point x="-170" y="-465"/>
+ <point x="-114" y="-465" type="curve" smooth="yes"/>
+ <point x="103" y="-465"/>
+ <point x="303" y="-314"/>
+ <point x="396" y="66" type="curve" smooth="yes"/>
+ <point x="455" y="307"/>
+ <point x="560" y="872"/>
+ <point x="560" y="1000" type="curve"/>
+ </contour>
+ <contour>
+ <point x="397" y="1297" type="curve" smooth="yes"/>
+ <point x="397" y="1237"/>
+ <point x="440" y="1186"/>
+ <point x="503" y="1186" type="curve" smooth="yes"/>
+ <point x="588" y="1186"/>
+ <point x="660" y="1259"/>
+ <point x="660" y="1338" type="curve" smooth="yes"/>
+ <point x="660" y="1399"/>
+ <point x="614" y="1450"/>
+ <point x="549" y="1450" type="curve" smooth="yes"/>
+ <point x="464" y="1450"/>
+ <point x="397" y="1375"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetassocfeat.ufo/glyphs/L_tnS_mK_.glif b/tests/reference/ufo/psfsetassocfeat.ufo/glyphs/L_tnS_mK_.glif
new file mode 100644
index 0000000..28fbc71
--- /dev/null
+++ b/tests/reference/ufo/psfsetassocfeat.ufo/glyphs/L_tnS_mK_.glif
@@ -0,0 +1,50 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmK" format="2">
+ <advance width="1059"/>
+ <unicode hex="006B"/>
+ <anchor x="840" y="0" name="H"/>
+ <anchor x="537" y="-100" name="L"/>
+ <anchor x="1225" y="1000" name="R"/>
+ <anchor x="920" y="1635" name="U"/>
+ <outline>
+ <contour>
+ <point x="295" y="0" type="line"/>
+ <point x="570" y="1105" type="line" smooth="yes"/>
+ <point x="614" y="1280"/>
+ <point x="645" y="1482"/>
+ <point x="645" y="1570" type="curve"/>
+ <point x="455" y="1570" type="line"/>
+ <point x="455" y="1456"/>
+ <point x="424" y="1259"/>
+ <point x="386" y="1107" type="curve" smooth="yes"/>
+ <point x="338" y="915"/>
+ <point x="110" y="0"/>
+ <point x="110" y="0" type="curve"/>
+ </contour>
+ <contour>
+ <point x="909" y="1000" type="line"/>
+ <point x="885" y="863"/>
+ <point x="654" y="700"/>
+ <point x="379" y="539" type="curve"/>
+ <point x="386" y="540"/>
+ <point x="393" y="540"/>
+ <point x="400" y="540" type="curve" smooth="yes"/>
+ <point x="467" y="540"/>
+ <point x="559" y="514"/>
+ <point x="559" y="514" type="curve"/>
+ <point x="902" y="702"/>
+ <point x="1134" y="884"/>
+ <point x="1134" y="1000" type="curve"/>
+ </contour>
+ <contour>
+ <point x="1010" y="0" type="line"/>
+ <point x="863" y="238"/>
+ <point x="718" y="600"/>
+ <point x="527" y="600" type="curve"/>
+ <point x="385" y="529" type="line"/>
+ <point x="540" y="529"/>
+ <point x="667" y="246"/>
+ <point x="775" y="0" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetassocfeat.ufo/glyphs/L_tnS_mL_.glif b/tests/reference/ufo/psfsetassocfeat.ufo/glyphs/L_tnS_mL_.glif
new file mode 100644
index 0000000..06d68fd
--- /dev/null
+++ b/tests/reference/ufo/psfsetassocfeat.ufo/glyphs/L_tnS_mL_.glif
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmL" format="2">
+ <advance width="575"/>
+ <unicode hex="006C"/>
+ <anchor x="230" y="0" name="H"/>
+ <anchor x="255" y="-100" name="L"/>
+ <anchor x="740" y="1000" name="R"/>
+ <anchor x="630" y="1635" name="U"/>
+ <outline>
+ <contour>
+ <point x="465" y="1570" type="line"/>
+ <point x="465" y="1456"/>
+ <point x="434" y="1259"/>
+ <point x="396" y="1107" type="curve" smooth="yes"/>
+ <point x="241" y="489" type="line" smooth="yes"/>
+ <point x="204" y="343"/>
+ <point x="186" y="220"/>
+ <point x="186" y="104" type="curve" smooth="yes"/>
+ <point x="186" y="69"/>
+ <point x="188" y="34"/>
+ <point x="191" y="0" type="curve"/>
+ <point x="391" y="0" type="line"/>
+ <point x="386" y="32"/>
+ <point x="384" y="70"/>
+ <point x="384" y="112" type="curve" smooth="yes"/>
+ <point x="384" y="230"/>
+ <point x="402" y="380"/>
+ <point x="436" y="517" type="curve" smooth="yes"/>
+ <point x="580" y="1105" type="line" smooth="yes"/>
+ <point x="623" y="1280"/>
+ <point x="655" y="1482"/>
+ <point x="655" y="1570" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetassocfeat.ufo/glyphs/L_tnS_mM_.glif b/tests/reference/ufo/psfsetassocfeat.ufo/glyphs/L_tnS_mM_.glif
new file mode 100644
index 0000000..a6b80db
--- /dev/null
+++ b/tests/reference/ufo/psfsetassocfeat.ufo/glyphs/L_tnS_mM_.glif
@@ -0,0 +1,80 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmM" format="2">
+ <advance width="1680"/>
+ <unicode hex="006D"/>
+ <anchor x="805" y="0" name="H"/>
+ <anchor x="780" y="-100" name="L"/>
+ <anchor x="1080" y="1100" name="U"/>
+ <outline>
+ <contour>
+ <point x="1520" y="0" type="line"/>
+ <point x="1512" y="30"/>
+ <point x="1510" y="65"/>
+ <point x="1510" y="102" type="curve" smooth="yes"/>
+ <point x="1510" y="143"/>
+ <point x="1515" y="188"/>
+ <point x="1522" y="238" type="curve" smooth="yes"/>
+ <point x="1536" y="327"/>
+ <point x="1655" y="691"/>
+ <point x="1655" y="800" type="curve" smooth="yes"/>
+ <point x="1655" y="930"/>
+ <point x="1594" y="1020"/>
+ <point x="1445" y="1020" type="curve" smooth="yes"/>
+ <point x="1292" y="1020"/>
+ <point x="1124" y="867"/>
+ <point x="1026" y="680" type="curve"/>
+ <point x="1030" y="704"/>
+ <point x="1045" y="778"/>
+ <point x="1045" y="800" type="curve" smooth="yes"/>
+ <point x="1045" y="932"/>
+ <point x="982" y="1020"/>
+ <point x="860" y="1020" type="curve" smooth="yes"/>
+ <point x="717" y="1020"/>
+ <point x="563" y="879"/>
+ <point x="446" y="680" type="curve"/>
+ <point x="466" y="753"/>
+ <point x="476" y="880"/>
+ <point x="476" y="961" type="curve" smooth="yes"/>
+ <point x="476" y="976"/>
+ <point x="476" y="989"/>
+ <point x="475" y="1000" type="curve"/>
+ <point x="295" y="1000" type="line"/>
+ <point x="296" y="983"/>
+ <point x="296" y="964"/>
+ <point x="296" y="945" type="curve" smooth="yes"/>
+ <point x="296" y="825"/>
+ <point x="283" y="680"/>
+ <point x="262" y="595" type="curve" smooth="yes"/>
+ <point x="115" y="0" type="line"/>
+ <point x="300" y="0" type="line"/>
+ <point x="389" y="359" type="line"/>
+ <point x="475" y="573"/>
+ <point x="685" y="850"/>
+ <point x="775" y="850" type="curve" smooth="yes"/>
+ <point x="833" y="850"/>
+ <point x="865" y="813"/>
+ <point x="865" y="720" type="curve" smooth="yes"/>
+ <point x="865" y="679"/>
+ <point x="846" y="583"/>
+ <point x="822" y="486" type="curve" smooth="yes"/>
+ <point x="700" y="0" type="line"/>
+ <point x="885" y="0" type="line"/>
+ <point x="974" y="359" type="line"/>
+ <point x="1032" y="531"/>
+ <point x="1242" y="850"/>
+ <point x="1357" y="850" type="curve" smooth="yes"/>
+ <point x="1425" y="850"/>
+ <point x="1457" y="813"/>
+ <point x="1457" y="720" type="curve" smooth="yes"/>
+ <point x="1457" y="632"/>
+ <point x="1349" y="319"/>
+ <point x="1335" y="203" type="curve" smooth="yes"/>
+ <point x="1330" y="158"/>
+ <point x="1327" y="115"/>
+ <point x="1327" y="77" type="curve" smooth="yes"/>
+ <point x="1327" y="48"/>
+ <point x="1331" y="21"/>
+ <point x="1335" y="0" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetassocfeat.ufo/glyphs/L_tnS_mN_.glif b/tests/reference/ufo/psfsetassocfeat.ufo/glyphs/L_tnS_mN_.glif
new file mode 100644
index 0000000..1f38f20
--- /dev/null
+++ b/tests/reference/ufo/psfsetassocfeat.ufo/glyphs/L_tnS_mN_.glif
@@ -0,0 +1,57 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmN" format="2">
+ <advance width="1195"/>
+ <unicode hex="006E"/>
+ <anchor x="540" y="0" name="H"/>
+ <anchor x="565" y="-100" name="L"/>
+ <anchor x="815" y="1100" name="U"/>
+ <outline>
+ <contour>
+ <point x="1060" y="0" type="line"/>
+ <point x="1052" y="30"/>
+ <point x="1050" y="65"/>
+ <point x="1050" y="102" type="curve" smooth="yes"/>
+ <point x="1050" y="143"/>
+ <point x="1055" y="188"/>
+ <point x="1062" y="238" type="curve" smooth="yes"/>
+ <point x="1075" y="327"/>
+ <point x="1175" y="636"/>
+ <point x="1175" y="745" type="curve" smooth="yes"/>
+ <point x="1175" y="917"/>
+ <point x="1100" y="1020"/>
+ <point x="935" y="1020" type="curve" smooth="yes"/>
+ <point x="755" y="1020"/>
+ <point x="581" y="870"/>
+ <point x="445" y="672" type="curve"/>
+ <point x="463" y="740"/>
+ <point x="477" y="873"/>
+ <point x="477" y="957" type="curve" smooth="yes"/>
+ <point x="477" y="973"/>
+ <point x="476" y="988"/>
+ <point x="475" y="1000" type="curve"/>
+ <point x="295" y="1000" type="line"/>
+ <point x="295" y="961" type="line" smooth="yes"/>
+ <point x="295" y="833"/>
+ <point x="283" y="679"/>
+ <point x="262" y="595" type="curve" smooth="yes"/>
+ <point x="115" y="0" type="line"/>
+ <point x="300" y="0" type="line"/>
+ <point x="392" y="370" type="line"/>
+ <point x="478" y="573"/>
+ <point x="708" y="850"/>
+ <point x="835" y="850" type="curve" smooth="yes"/>
+ <point x="927" y="850"/>
+ <point x="975" y="798"/>
+ <point x="975" y="680" type="curve" smooth="yes"/>
+ <point x="975" y="592"/>
+ <point x="888" y="319"/>
+ <point x="875" y="203" type="curve" smooth="yes"/>
+ <point x="870" y="158"/>
+ <point x="867" y="115"/>
+ <point x="867" y="77" type="curve" smooth="yes"/>
+ <point x="867" y="48"/>
+ <point x="871" y="21"/>
+ <point x="875" y="0" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetassocfeat.ufo/glyphs/L_tnS_mO_.glif b/tests/reference/ufo/psfsetassocfeat.ufo/glyphs/L_tnS_mO_.glif
new file mode 100644
index 0000000..bec7b9e
--- /dev/null
+++ b/tests/reference/ufo/psfsetassocfeat.ufo/glyphs/L_tnS_mO_.glif
@@ -0,0 +1,40 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmO" format="2">
+ <advance width="1133"/>
+ <unicode hex="006F"/>
+ <anchor x="510" y="0" name="H"/>
+ <anchor x="505" y="-100" name="L"/>
+ <anchor x="800" y="0" name="O"/>
+ <anchor x="1330" y="1000" name="R"/>
+ <anchor x="785" y="1100" name="U"/>
+ <outline>
+ <contour>
+ <point x="142" y="344" type="curve" smooth="yes"/>
+ <point x="142" y="114"/>
+ <point x="306" y="-25"/>
+ <point x="530" y="-25" type="curve" smooth="yes"/>
+ <point x="896" y="-25"/>
+ <point x="1138" y="314"/>
+ <point x="1138" y="648" type="curve" smooth="yes"/>
+ <point x="1138" y="879"/>
+ <point x="985" y="1020"/>
+ <point x="761" y="1020" type="curve" smooth="yes"/>
+ <point x="387" y="1020"/>
+ <point x="142" y="677"/>
+ </contour>
+ <contour>
+ <point x="721" y="862" type="curve" smooth="yes"/>
+ <point x="859" y="862"/>
+ <point x="947" y="767"/>
+ <point x="947" y="611" type="curve" smooth="yes"/>
+ <point x="947" y="391"/>
+ <point x="795" y="132"/>
+ <point x="559" y="132" type="curve" smooth="yes"/>
+ <point x="421" y="132"/>
+ <point x="333" y="226"/>
+ <point x="333" y="380" type="curve" smooth="yes"/>
+ <point x="333" y="599"/>
+ <point x="486" y="862"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetassocfeat.ufo/glyphs/L_tnS_mP_.glif b/tests/reference/ufo/psfsetassocfeat.ufo/glyphs/L_tnS_mP_.glif
new file mode 100644
index 0000000..f9e06b1
--- /dev/null
+++ b/tests/reference/ufo/psfsetassocfeat.ufo/glyphs/L_tnS_mP_.glif
@@ -0,0 +1,66 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmP" format="2">
+ <advance width="1185"/>
+ <unicode hex="0070"/>
+ <anchor x="105" y="-435" name="H"/>
+ <anchor x="405" y="-500" name="L"/>
+ <anchor x="1360" y="1000" name="R"/>
+ <anchor x="805" y="1100" name="U"/>
+ <outline>
+ <contour>
+ <point x="215" y="-480" type="line"/>
+ <point x="215" y="-388"/>
+ <point x="229" y="-282"/>
+ <point x="255" y="-175" type="curve" smooth="yes"/>
+ <point x="320" y="85" type="line"/>
+ <point x="399" y="20"/>
+ <point x="468" y="-25"/>
+ <point x="575" y="-25" type="curve" smooth="yes"/>
+ <point x="685" y="-25"/>
+ <point x="797" y="9"/>
+ <point x="895" y="85" type="curve" smooth="yes"/>
+ <point x="1063" y="215"/>
+ <point x="1185" y="438"/>
+ <point x="1185" y="680" type="curve" smooth="yes"/>
+ <point x="1185" y="878"/>
+ <point x="1101" y="1020"/>
+ <point x="920" y="1020" type="curve" smooth="yes"/>
+ <point x="757" y="1020"/>
+ <point x="559" y="842"/>
+ <point x="452" y="680" type="curve"/>
+ <point x="468" y="760"/>
+ <point x="477" y="860"/>
+ <point x="477" y="940" type="curve" smooth="yes"/>
+ <point x="477" y="962"/>
+ <point x="477" y="982"/>
+ <point x="475" y="1000" type="curve"/>
+ <point x="295" y="1000" type="line"/>
+ <point x="295" y="971" type="line" smooth="yes"/>
+ <point x="295" y="819"/>
+ <point x="273" y="625"/>
+ <point x="235" y="475" type="curve" smooth="yes"/>
+ <point x="70" y="-175" type="line" smooth="yes"/>
+ <point x="43" y="-281"/>
+ <point x="20" y="-398"/>
+ <point x="20" y="-480" type="curve"/>
+ </contour>
+ <contour>
+ <point x="407" y="432" type="line"/>
+ <point x="544" y="656"/>
+ <point x="732" y="850"/>
+ <point x="840" y="850" type="curve" smooth="yes"/>
+ <point x="939" y="850"/>
+ <point x="990" y="763"/>
+ <point x="990" y="630" type="curve" smooth="yes"/>
+ <point x="990" y="491"/>
+ <point x="926" y="322"/>
+ <point x="815" y="220" type="curve" smooth="yes"/>
+ <point x="759" y="168"/>
+ <point x="693" y="135"/>
+ <point x="615" y="135" type="curve" smooth="yes"/>
+ <point x="523" y="135"/>
+ <point x="479" y="161"/>
+ <point x="365" y="255" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetassocfeat.ufo/glyphs/L_tnS_mQ_.glif b/tests/reference/ufo/psfsetassocfeat.ufo/glyphs/L_tnS_mQ_.glif
new file mode 100644
index 0000000..58d9f87
--- /dev/null
+++ b/tests/reference/ufo/psfsetassocfeat.ufo/glyphs/L_tnS_mQ_.glif
@@ -0,0 +1,54 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmQ" format="2">
+ <advance width="1115"/>
+ <unicode hex="0071"/>
+ <anchor x="370" y="-500" name="L"/>
+ <anchor x="1320" y="1000" name="R"/>
+ <anchor x="770" y="1100" name="U"/>
+ <outline>
+ <contour>
+ <point x="843" y="-480" type="line"/>
+ <point x="843" y="-391"/>
+ <point x="858" y="-294"/>
+ <point x="885" y="-185" type="curve" smooth="yes"/>
+ <point x="1165" y="945" type="line"/>
+ <point x="1066" y="980"/>
+ <point x="946" y="1020"/>
+ <point x="825" y="1020" type="curve" smooth="yes"/>
+ <point x="675" y="1020"/>
+ <point x="550" y="977"/>
+ <point x="440" y="890" type="curve" smooth="yes"/>
+ <point x="260" y="747"/>
+ <point x="135" y="505"/>
+ <point x="135" y="285" type="curve" smooth="yes"/>
+ <point x="135" y="73"/>
+ <point x="261" y="-25"/>
+ <point x="380" y="-25" type="curve" smooth="yes"/>
+ <point x="524" y="-25"/>
+ <point x="751" y="172"/>
+ <point x="825" y="300" type="curve"/>
+ <point x="693" y="-180" type="line" smooth="yes"/>
+ <point x="662" y="-294"/>
+ <point x="648" y="-414"/>
+ <point x="648" y="-480" type="curve"/>
+ </contour>
+ <contour>
+ <point x="885" y="565" type="line"/>
+ <point x="807" y="413"/>
+ <point x="550" y="140"/>
+ <point x="455" y="140" type="curve" smooth="yes"/>
+ <point x="376" y="140"/>
+ <point x="330" y="199"/>
+ <point x="330" y="330" type="curve" smooth="yes"/>
+ <point x="330" y="481"/>
+ <point x="400" y="658"/>
+ <point x="515" y="760" type="curve" smooth="yes"/>
+ <point x="580" y="817"/>
+ <point x="658" y="855"/>
+ <point x="750" y="855" type="curve" smooth="yes"/>
+ <point x="811" y="855"/>
+ <point x="893" y="840"/>
+ <point x="947" y="817" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetassocfeat.ufo/glyphs/L_tnS_mR_.glif b/tests/reference/ufo/psfsetassocfeat.ufo/glyphs/L_tnS_mR_.glif
new file mode 100644
index 0000000..8037612
--- /dev/null
+++ b/tests/reference/ufo/psfsetassocfeat.ufo/glyphs/L_tnS_mR_.glif
@@ -0,0 +1,42 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmR" format="2">
+ <advance width="910"/>
+ <unicode hex="0072"/>
+ <anchor x="210" y="0" name="H"/>
+ <anchor x="220" y="-100" name="L"/>
+ <anchor x="670" y="1100" name="U"/>
+ <outline>
+ <contour>
+ <point x="300" y="0" type="line"/>
+ <point x="402" y="415" type="line"/>
+ <point x="502" y="602"/>
+ <point x="703" y="850"/>
+ <point x="785" y="850" type="curve" smooth="yes"/>
+ <point x="831" y="850"/>
+ <point x="855" y="801"/>
+ <point x="855" y="740" type="curve" smooth="yes"/>
+ <point x="855" y="715"/>
+ <point x="852" y="689"/>
+ <point x="845" y="660" type="curve"/>
+ <point x="1010" y="690" type="line"/>
+ <point x="1022" y="737"/>
+ <point x="1030" y="783"/>
+ <point x="1030" y="825" type="curve" smooth="yes"/>
+ <point x="1030" y="935"/>
+ <point x="986" y="1020"/>
+ <point x="865" y="1020" type="curve" smooth="yes"/>
+ <point x="735" y="1020"/>
+ <point x="575" y="867"/>
+ <point x="445" y="675" type="curve"/>
+ <point x="467" y="773"/>
+ <point x="475" y="929"/>
+ <point x="475" y="1000" type="curve"/>
+ <point x="295" y="1000" type="line"/>
+ <point x="295" y="961" type="line" smooth="yes"/>
+ <point x="295" y="833"/>
+ <point x="283" y="679"/>
+ <point x="262" y="595" type="curve" smooth="yes"/>
+ <point x="115" y="0" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetassocfeat.ufo/glyphs/L_tnS_mS_.glif b/tests/reference/ufo/psfsetassocfeat.ufo/glyphs/L_tnS_mS_.glif
new file mode 100644
index 0000000..848ddda
--- /dev/null
+++ b/tests/reference/ufo/psfsetassocfeat.ufo/glyphs/L_tnS_mS_.glif
@@ -0,0 +1,50 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmS" format="2">
+ <advance width="945"/>
+ <unicode hex="0073"/>
+ <anchor x="435" y="0" name="H"/>
+ <anchor x="440" y="-100" name="L"/>
+ <anchor x="710" y="1100" name="U"/>
+ <outline>
+ <contour>
+ <point x="990" y="941" type="line"/>
+ <point x="930" y="978"/>
+ <point x="815" y="1020"/>
+ <point x="640" y="1020" type="curve" smooth="yes"/>
+ <point x="384" y="1020"/>
+ <point x="230" y="881"/>
+ <point x="230" y="716" type="curve" smooth="yes"/>
+ <point x="230" y="614"/>
+ <point x="320" y="533"/>
+ <point x="466" y="461" type="curve" smooth="yes"/>
+ <point x="638" y="376"/>
+ <point x="700" y="333"/>
+ <point x="700" y="265" type="curve" smooth="yes"/>
+ <point x="700" y="188"/>
+ <point x="621" y="132"/>
+ <point x="532" y="132" type="curve" smooth="yes"/>
+ <point x="376" y="132"/>
+ <point x="244" y="216"/>
+ <point x="159" y="325" type="curve"/>
+ <point x="71" y="158" type="line"/>
+ <point x="160" y="60"/>
+ <point x="296" y="-25"/>
+ <point x="488" y="-25" type="curve" smooth="yes"/>
+ <point x="713" y="-25"/>
+ <point x="891" y="106"/>
+ <point x="891" y="306" type="curve" smooth="yes"/>
+ <point x="891" y="432"/>
+ <point x="774" y="515"/>
+ <point x="626" y="593" type="curve" smooth="yes"/>
+ <point x="476" y="672"/>
+ <point x="418" y="695"/>
+ <point x="418" y="753" type="curve" smooth="yes"/>
+ <point x="418" y="822"/>
+ <point x="494" y="862"/>
+ <point x="619" y="862" type="curve" smooth="yes"/>
+ <point x="743" y="862"/>
+ <point x="854" y="808"/>
+ <point x="911" y="769" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetassocfeat.ufo/glyphs/L_tnS_mT_.glif b/tests/reference/ufo/psfsetassocfeat.ufo/glyphs/L_tnS_mT_.glif
new file mode 100644
index 0000000..0eddfe9
--- /dev/null
+++ b/tests/reference/ufo/psfsetassocfeat.ufo/glyphs/L_tnS_mT_.glif
@@ -0,0 +1,45 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmT" format="2">
+ <advance width="815"/>
+ <unicode hex="0074"/>
+ <anchor x="455" y="0" name="H"/>
+ <anchor x="390" y="-100" name="L"/>
+ <anchor x="1025" y="1000" name="R"/>
+ <anchor x="605" y="1360" name="U"/>
+ <outline>
+ <contour>
+ <point x="752" y="211" type="line"/>
+ <point x="665" y="169"/>
+ <point x="593" y="134"/>
+ <point x="527" y="134" type="curve" smooth="yes"/>
+ <point x="448" y="134"/>
+ <point x="425" y="188"/>
+ <point x="425" y="247" type="curve" smooth="yes"/>
+ <point x="425" y="274"/>
+ <point x="429" y="301"/>
+ <point x="434" y="326" type="curve" smooth="yes"/>
+ <point x="470" y="519"/>
+ <point x="564" y="843"/>
+ <point x="677" y="1294" type="curve"/>
+ <point x="492" y="1294" type="line"/>
+ <point x="377" y="841"/>
+ <point x="263" y="429"/>
+ <point x="243" y="301" type="curve" smooth="yes"/>
+ <point x="238" y="269"/>
+ <point x="236" y="240"/>
+ <point x="236" y="213" type="curve" smooth="yes"/>
+ <point x="236" y="41"/>
+ <point x="330" y="-25"/>
+ <point x="465" y="-25" type="curve" smooth="yes"/>
+ <point x="535" y="-25"/>
+ <point x="634" y="-6"/>
+ <point x="740" y="52" type="curve"/>
+ </contour>
+ <contour>
+ <point x="177" y="833" type="line"/>
+ <point x="887" y="833" type="line"/>
+ <point x="923" y="975" type="line"/>
+ <point x="213" y="975" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetassocfeat.ufo/glyphs/L_tnS_mU_.glif b/tests/reference/ufo/psfsetassocfeat.ufo/glyphs/L_tnS_mU_.glif
new file mode 100644
index 0000000..0eda3d2
--- /dev/null
+++ b/tests/reference/ufo/psfsetassocfeat.ufo/glyphs/L_tnS_mU_.glif
@@ -0,0 +1,57 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmU" format="2">
+ <advance width="1175"/>
+ <unicode hex="0075"/>
+ <anchor x="465" y="0" name="H"/>
+ <anchor x="504" y="-100" name="L"/>
+ <anchor x="640" y="0" name="O"/>
+ <anchor x="1375" y="1000" name="R"/>
+ <anchor x="804" y="1100" name="U"/>
+ <outline>
+ <contour>
+ <point x="1040" y="0" type="line"/>
+ <point x="1036" y="29"/>
+ <point x="1035" y="62"/>
+ <point x="1035" y="100" type="curve" smooth="yes"/>
+ <point x="1035" y="206"/>
+ <point x="1054" y="341"/>
+ <point x="1080" y="455" type="curve" smooth="yes"/>
+ <point x="1135" y="689"/>
+ <point x="1197" y="895"/>
+ <point x="1205" y="1000" type="curve"/>
+ <point x="1010" y="1000" type="line"/>
+ <point x="1003" y="882"/>
+ <point x="971" y="769"/>
+ <point x="920" y="565" type="curve"/>
+ <point x="827" y="376"/>
+ <point x="573" y="135"/>
+ <point x="475" y="135" type="curve" smooth="yes"/>
+ <point x="409" y="135"/>
+ <point x="365" y="181"/>
+ <point x="365" y="280" type="curve" smooth="yes"/>
+ <point x="365" y="347"/>
+ <point x="407" y="500"/>
+ <point x="459" y="702" type="curve" smooth="yes"/>
+ <point x="494" y="837"/>
+ <point x="515" y="925"/>
+ <point x="520" y="1000" type="curve"/>
+ <point x="325" y="1000" type="line"/>
+ <point x="313" y="882"/>
+ <point x="295" y="809"/>
+ <point x="265" y="685" type="curve" smooth="yes"/>
+ <point x="195" y="395" type="line" smooth="yes"/>
+ <point x="179" y="330"/>
+ <point x="170" y="275"/>
+ <point x="170" y="225" type="curve" smooth="yes"/>
+ <point x="170" y="60"/>
+ <point x="257" y="-25"/>
+ <point x="410" y="-25" type="curve" smooth="yes"/>
+ <point x="551" y="-25"/>
+ <point x="745" y="118"/>
+ <point x="880" y="305" type="curve"/>
+ <point x="861" y="196"/>
+ <point x="860" y="98"/>
+ <point x="860" y="0" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetassocfeat.ufo/glyphs/L_tnS_mV_.glif b/tests/reference/ufo/psfsetassocfeat.ufo/glyphs/L_tnS_mV_.glif
new file mode 100644
index 0000000..33e91d6
--- /dev/null
+++ b/tests/reference/ufo/psfsetassocfeat.ufo/glyphs/L_tnS_mV_.glif
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmV" format="2">
+ <advance width="941"/>
+ <unicode hex="0076"/>
+ <anchor x="359" y="0" name="H"/>
+ <anchor x="350" y="-100" name="L"/>
+ <anchor x="565" y="0" name="O"/>
+ <anchor x="650" y="1100" name="U"/>
+ <outline>
+ <contour>
+ <point x="180" y="1000" type="line"/>
+ <point x="232" y="825"/>
+ <point x="256" y="602"/>
+ <point x="256" y="354" type="curve" smooth="yes"/>
+ <point x="256" y="241"/>
+ <point x="251" y="122"/>
+ <point x="241" y="0" type="curve"/>
+ <point x="441" y="0" type="line"/>
+ <point x="744" y="336"/>
+ <point x="1056" y="765"/>
+ <point x="1056" y="1000" type="curve"/>
+ <point x="856" y="1000" type="line"/>
+ <point x="856" y="769"/>
+ <point x="606" y="394"/>
+ <point x="404" y="176" type="curve"/>
+ <point x="421" y="277"/>
+ <point x="429" y="402"/>
+ <point x="429" y="526" type="curve" smooth="yes"/>
+ <point x="429" y="707"/>
+ <point x="412" y="887"/>
+ <point x="380" y="1000" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetassocfeat.ufo/glyphs/L_tnS_mW_.glif b/tests/reference/ufo/psfsetassocfeat.ufo/glyphs/L_tnS_mW_.glif
new file mode 100644
index 0000000..1daea7c
--- /dev/null
+++ b/tests/reference/ufo/psfsetassocfeat.ufo/glyphs/L_tnS_mW_.glif
@@ -0,0 +1,50 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmW" format="2">
+ <advance width="1555"/>
+ <unicode hex="0077"/>
+ <anchor x="690" y="-100" name="L"/>
+ <anchor x="990" y="1100" name="U"/>
+ <outline>
+ <contour>
+ <point x="858" y="1000" type="line"/>
+ <point x="743" y="739"/>
+ <point x="588" y="466"/>
+ <point x="388" y="181" type="curve"/>
+ <point x="417" y="339"/>
+ <point x="430" y="500"/>
+ <point x="430" y="644" type="curve" smooth="yes"/>
+ <point x="430" y="784"/>
+ <point x="418" y="908"/>
+ <point x="395" y="1000" type="curve"/>
+ <point x="195" y="1000" type="line"/>
+ <point x="234" y="873"/>
+ <point x="256" y="688"/>
+ <point x="256" y="472" type="curve" smooth="yes"/>
+ <point x="256" y="326"/>
+ <point x="246" y="166"/>
+ <point x="225" y="0" type="curve"/>
+ <point x="425" y="0" type="line"/>
+ <point x="632" y="298"/>
+ <point x="825" y="583"/>
+ <point x="896" y="765" type="curve"/>
+ <point x="920" y="478"/>
+ <point x="912" y="233"/>
+ <point x="915" y="0" type="curve"/>
+ <point x="1115" y="0" type="line"/>
+ <point x="1362" y="330"/>
+ <point x="1642" y="777"/>
+ <point x="1645" y="1000" type="curve"/>
+ <point x="1445" y="1000" type="line"/>
+ <point x="1445" y="990" type="line"/>
+ <point x="1445" y="797"/>
+ <point x="1242" y="417"/>
+ <point x="1063" y="181" type="curve"/>
+ <point x="1064" y="221"/>
+ <point x="1064" y="260"/>
+ <point x="1064" y="298" type="curve" smooth="yes"/>
+ <point x="1064" y="577"/>
+ <point x="1046" y="811"/>
+ <point x="1020" y="1000" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetassocfeat.ufo/glyphs/L_tnS_mX_.glif b/tests/reference/ufo/psfsetassocfeat.ufo/glyphs/L_tnS_mX_.glif
new file mode 100644
index 0000000..5508ff9
--- /dev/null
+++ b/tests/reference/ufo/psfsetassocfeat.ufo/glyphs/L_tnS_mX_.glif
@@ -0,0 +1,40 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmX" format="2">
+ <advance width="1009"/>
+ <unicode hex="0078"/>
+ <anchor x="840" y="0" name="H"/>
+ <anchor x="457" y="-100" name="L"/>
+ <anchor x="657" y="1100" name="U"/>
+ <outline>
+ <contour>
+ <point x="945" y="0" type="line"/>
+ <point x="765" y="133"/>
+ <point x="558" y="867"/>
+ <point x="439" y="1000" type="curve"/>
+ <point x="181" y="1000" type="line"/>
+ <point x="410" y="832"/>
+ <point x="578" y="141"/>
+ <point x="698" y="0" type="curve"/>
+ </contour>
+ <contour>
+ <point x="504" y="572" type="line"/>
+ <point x="286" y="463"/>
+ <point x="57" y="230"/>
+ <point x="30" y="0" type="curve"/>
+ <point x="230" y="0" type="line"/>
+ <point x="231" y="156"/>
+ <point x="375" y="380"/>
+ <point x="563" y="467" type="curve"/>
+ </contour>
+ <contour>
+ <point x="659" y="471" type="line"/>
+ <point x="838" y="591"/>
+ <point x="1092" y="798"/>
+ <point x="1099" y="1000" type="curve"/>
+ <point x="889" y="1000" type="line"/>
+ <point x="883" y="842"/>
+ <point x="758" y="675"/>
+ <point x="601" y="581" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetassocfeat.ufo/glyphs/L_tnS_mY_.glif b/tests/reference/ufo/psfsetassocfeat.ufo/glyphs/L_tnS_mY_.glif
new file mode 100644
index 0000000..b9000c5
--- /dev/null
+++ b/tests/reference/ufo/psfsetassocfeat.ufo/glyphs/L_tnS_mY_.glif
@@ -0,0 +1,45 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmY" format="2">
+ <advance width="976"/>
+ <unicode hex="0079"/>
+ <anchor x="710" y="-100" name="L"/>
+ <anchor x="1270" y="1000" name="R"/>
+ <anchor x="630" y="1100" name="U"/>
+ <outline>
+ <contour>
+ <point x="132" y="1000" type="line"/>
+ <point x="270" y="825"/>
+ <point x="398" y="406"/>
+ <point x="403" y="-16" type="curve"/>
+ <point x="263" y="-232"/>
+ <point x="145" y="-295"/>
+ <point x="64" y="-295" type="curve" smooth="yes"/>
+ <point x="-2" y="-295"/>
+ <point x="-69" y="-254"/>
+ <point x="-102" y="-220" type="curve"/>
+ <point x="-200" y="-377" type="line"/>
+ <point x="-141" y="-430"/>
+ <point x="-68" y="-465"/>
+ <point x="23" y="-465" type="curve" smooth="yes"/>
+ <point x="193" y="-465"/>
+ <point x="369" y="-371"/>
+ <point x="609" y="0" type="curve" smooth="yes"/>
+ <point x="877" y="414"/>
+ <point x="1056" y="808"/>
+ <point x="1056" y="964" type="curve" smooth="yes"/>
+ <point x="1056" y="978"/>
+ <point x="1055" y="990"/>
+ <point x="1052" y="1000" type="curve"/>
+ <point x="852" y="1000" type="line"/>
+ <point x="856" y="984"/>
+ <point x="858" y="967"/>
+ <point x="858" y="946" type="curve" smooth="yes"/>
+ <point x="858" y="783"/>
+ <point x="722" y="472"/>
+ <point x="548" y="189" type="curve"/>
+ <point x="548" y="484"/>
+ <point x="447" y="866"/>
+ <point x="347" y="1000" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetassocfeat.ufo/glyphs/N_onB_reakingH_yphen.glif b/tests/reference/ufo/psfsetassocfeat.ufo/glyphs/N_onB_reakingH_yphen.glif
new file mode 100644
index 0000000..e7d9c06
--- /dev/null
+++ b/tests/reference/ufo/psfsetassocfeat.ufo/glyphs/N_onB_reakingH_yphen.glif
@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="NonBreakingHyphen" format="2">
+ <advance width="840"/>
+ <unicode hex="2011"/>
+ <anchor x="645" y="1100" name="U"/>
+ <outline>
+ <component base="HyphenMinus"/>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetassocfeat.ufo/glyphs/N_umS_gn.glif b/tests/reference/ufo/psfsetassocfeat.ufo/glyphs/N_umS_gn.glif
new file mode 100644
index 0000000..b7506f7
--- /dev/null
+++ b/tests/reference/ufo/psfsetassocfeat.ufo/glyphs/N_umS_gn.glif
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="NumSgn" format="2">
+ <advance width="1180"/>
+ <unicode hex="0023"/>
+ <outline>
+ <contour>
+ <point x="739" y="1333" type="line"/>
+ <point x="91" y="98" type="line"/>
+ <point x="261" y="98" type="line"/>
+ <point x="909" y="1333" type="line"/>
+ </contour>
+ <contour>
+ <point x="80" y="465" type="line"/>
+ <point x="1171" y="465" type="line"/>
+ <point x="1208" y="612" type="line"/>
+ <point x="117" y="612" type="line"/>
+ </contour>
+ <contour>
+ <point x="234" y="843" type="line"/>
+ <point x="1325" y="843" type="line"/>
+ <point x="1361" y="990" type="line"/>
+ <point x="270" y="990" type="line"/>
+ </contour>
+ <contour>
+ <point x="1164" y="1333" type="line"/>
+ <point x="516" y="98" type="line"/>
+ <point x="686" y="98" type="line"/>
+ <point x="1334" y="1333" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetassocfeat.ufo/glyphs/P_ercentS_gn.glif b/tests/reference/ufo/psfsetassocfeat.ufo/glyphs/P_ercentS_gn.glif
new file mode 100644
index 0000000..84241ea
--- /dev/null
+++ b/tests/reference/ufo/psfsetassocfeat.ufo/glyphs/P_ercentS_gn.glif
@@ -0,0 +1,93 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="PercentSgn" format="2">
+ <advance width="1506"/>
+ <unicode hex="0025"/>
+ <outline>
+ <contour>
+ <point x="1300" y="349" type="curve" smooth="yes"/>
+ <point x="1255" y="168"/>
+ <point x="1204" y="113"/>
+ <point x="1118" y="113" type="curve" smooth="yes"/>
+ <point x="1056" y="113"/>
+ <point x="1021" y="148"/>
+ <point x="1021" y="235" type="curve" smooth="yes"/>
+ <point x="1021" y="274"/>
+ <point x="1028" y="322"/>
+ <point x="1043" y="383" type="curve" smooth="yes"/>
+ <point x="1088" y="564"/>
+ <point x="1136" y="617"/>
+ <point x="1223" y="617" type="curve" smooth="yes"/>
+ <point x="1286" y="617"/>
+ <point x="1322" y="582"/>
+ <point x="1322" y="496" type="curve" smooth="yes"/>
+ <point x="1322" y="458"/>
+ <point x="1315" y="409"/>
+ </contour>
+ <contour>
+ <point x="1468" y="361" type="curve" smooth="yes"/>
+ <point x="1483" y="419"/>
+ <point x="1489" y="470"/>
+ <point x="1489" y="515" type="curve" smooth="yes"/>
+ <point x="1489" y="677"/>
+ <point x="1400" y="755"/>
+ <point x="1263" y="755" type="curve" smooth="yes"/>
+ <point x="1089" y="755"/>
+ <point x="945" y="647"/>
+ <point x="876" y="371" type="curve" smooth="yes"/>
+ <point x="861" y="310"/>
+ <point x="854" y="256"/>
+ <point x="854" y="210" type="curve" smooth="yes"/>
+ <point x="854" y="47"/>
+ <point x="943" y="-25"/>
+ <point x="1079" y="-25" type="curve" smooth="yes"/>
+ <point x="1254" y="-25"/>
+ <point x="1396" y="72"/>
+ </contour>
+ <contour>
+ <point x="1369" y="1450" type="line"/>
+ <point x="219" y="-25" type="line"/>
+ <point x="397" y="-25" type="line"/>
+ <point x="1545" y="1450" type="line"/>
+ </contour>
+ <contour>
+ <point x="717" y="1044" type="curve" smooth="yes"/>
+ <point x="672" y="864"/>
+ <point x="621" y="809"/>
+ <point x="535" y="809" type="curve" smooth="yes"/>
+ <point x="474" y="809"/>
+ <point x="439" y="844"/>
+ <point x="439" y="930" type="curve" smooth="yes"/>
+ <point x="439" y="969"/>
+ <point x="446" y="1018"/>
+ <point x="461" y="1079" type="curve" smooth="yes"/>
+ <point x="506" y="1260"/>
+ <point x="554" y="1313"/>
+ <point x="641" y="1313" type="curve" smooth="yes"/>
+ <point x="704" y="1313"/>
+ <point x="739" y="1278"/>
+ <point x="739" y="1192" type="curve" smooth="yes"/>
+ <point x="739" y="1153"/>
+ <point x="732" y="1105"/>
+ </contour>
+ <contour>
+ <point x="886" y="1057" type="curve" smooth="yes"/>
+ <point x="900" y="1114"/>
+ <point x="907" y="1166"/>
+ <point x="907" y="1210" type="curve" smooth="yes"/>
+ <point x="907" y="1373"/>
+ <point x="817" y="1450"/>
+ <point x="680" y="1450" type="curve" smooth="yes"/>
+ <point x="506" y="1450"/>
+ <point x="362" y="1343"/>
+ <point x="293" y="1066" type="curve" smooth="yes"/>
+ <point x="278" y="1005"/>
+ <point x="271" y="952"/>
+ <point x="271" y="906" type="curve" smooth="yes"/>
+ <point x="271" y="743"/>
+ <point x="360" y="671"/>
+ <point x="497" y="671" type="curve" smooth="yes"/>
+ <point x="672" y="671"/>
+ <point x="813" y="768"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetassocfeat.ufo/glyphs/P_lusS_gn.glif b/tests/reference/ufo/psfsetassocfeat.ufo/glyphs/P_lusS_gn.glif
new file mode 100644
index 0000000..8c4577e
--- /dev/null
+++ b/tests/reference/ufo/psfsetassocfeat.ufo/glyphs/P_lusS_gn.glif
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="PlusSgn" format="2">
+ <advance width="1180"/>
+ <unicode hex="002B"/>
+ <outline>
+ <contour>
+ <point x="748" y="1156" type="line"/>
+ <point x="529" y="279" type="line"/>
+ <point x="684" y="279" type="line"/>
+ <point x="903" y="1156" type="line"/>
+ </contour>
+ <contour>
+ <point x="256" y="647" type="line"/>
+ <point x="1146" y="647" type="line"/>
+ <point x="1182" y="794" type="line"/>
+ <point x="292" y="794" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetassocfeat.ufo/glyphs/Q_stnM_rk.glif b/tests/reference/ufo/psfsetassocfeat.ufo/glyphs/Q_stnM_rk.glif
new file mode 100644
index 0000000..8b14a6c
--- /dev/null
+++ b/tests/reference/ufo/psfsetassocfeat.ufo/glyphs/Q_stnM_rk.glif
@@ -0,0 +1,49 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="QstnMrk" format="2">
+ <advance width="1030"/>
+ <unicode hex="003F"/>
+ <outline>
+ <contour>
+ <point x="419" y="1226" type="line"/>
+ <point x="514" y="1303"/>
+ <point x="615" y="1338"/>
+ <point x="685" y="1338" type="curve" smooth="yes"/>
+ <point x="800" y="1338"/>
+ <point x="858" y="1294"/>
+ <point x="858" y="1222" type="curve" smooth="yes"/>
+ <point x="858" y="1122"/>
+ <point x="713" y="1017"/>
+ <point x="654" y="960" type="curve" smooth="yes"/>
+ <point x="538" y="850"/>
+ <point x="473" y="715"/>
+ <point x="402" y="431" type="curve"/>
+ <point x="587" y="431" type="line"/>
+ <point x="656" y="707"/>
+ <point x="697" y="778"/>
+ <point x="831" y="901" type="curve" smooth="yes"/>
+ <point x="949" y="1010"/>
+ <point x="1072" y="1146"/>
+ <point x="1072" y="1272" type="curve" smooth="yes"/>
+ <point x="1072" y="1409"/>
+ <point x="947" y="1509"/>
+ <point x="746" y="1509" type="curve" smooth="yes"/>
+ <point x="631" y="1509"/>
+ <point x="500" y="1463"/>
+ <point x="419" y="1401" type="curve"/>
+ </contour>
+ <contour>
+ <point x="278" y="90" type="curve" smooth="yes"/>
+ <point x="278" y="28"/>
+ <point x="328" y="-25"/>
+ <point x="393" y="-25" type="curve" smooth="yes"/>
+ <point x="477" y="-25"/>
+ <point x="554" y="45"/>
+ <point x="554" y="125" type="curve" smooth="yes"/>
+ <point x="554" y="186"/>
+ <point x="504" y="240"/>
+ <point x="439" y="240" type="curve" smooth="yes"/>
+ <point x="355" y="240"/>
+ <point x="278" y="170"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetassocfeat.ufo/glyphs/Q_uotM_rk.glif b/tests/reference/ufo/psfsetassocfeat.ufo/glyphs/Q_uotM_rk.glif
new file mode 100644
index 0000000..4a8357b
--- /dev/null
+++ b/tests/reference/ufo/psfsetassocfeat.ufo/glyphs/Q_uotM_rk.glif
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="QuotMrk" format="2">
+ <advance width="1005"/>
+ <unicode hex="0022"/>
+ <outline>
+ <contour>
+ <point x="600" y="1024" type="line"/>
+ <point x="639" y="1162"/>
+ <point x="683" y="1312"/>
+ <point x="772" y="1553" type="curve"/>
+ <point x="567" y="1553" type="line"/>
+ <point x="538" y="1312"/>
+ <point x="505" y="1162"/>
+ <point x="475" y="1024" type="curve"/>
+ </contour>
+ <contour>
+ <point x="940" y="1024" type="line"/>
+ <point x="979" y="1162"/>
+ <point x="1023" y="1312"/>
+ <point x="1112" y="1553" type="curve"/>
+ <point x="907" y="1553" type="line"/>
+ <point x="878" y="1312"/>
+ <point x="845" y="1162"/>
+ <point x="815" y="1024" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetassocfeat.ufo/glyphs/R_everseS_olidus.glif b/tests/reference/ufo/psfsetassocfeat.ufo/glyphs/R_everseS_olidus.glif
new file mode 100644
index 0000000..f146267
--- /dev/null
+++ b/tests/reference/ufo/psfsetassocfeat.ufo/glyphs/R_everseS_olidus.glif
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="ReverseSolidus" format="2">
+ <advance width="1005"/>
+ <unicode hex="005C"/>
+ <outline>
+ <contour>
+ <point x="473" y="1538" type="line"/>
+ <point x="656" y="-123" type="line"/>
+ <point x="799" y="-93" type="line"/>
+ <point x="620" y="1568" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetassocfeat.ufo/glyphs/R_tC_urlyB_rac.glif b/tests/reference/ufo/psfsetassocfeat.ufo/glyphs/R_tC_urlyB_rac.glif
new file mode 100644
index 0000000..82df531
--- /dev/null
+++ b/tests/reference/ufo/psfsetassocfeat.ufo/glyphs/R_tC_urlyB_rac.glif
@@ -0,0 +1,50 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="RtCurlyBrac" format="2">
+ <advance width="980"/>
+ <unicode hex="007D"/>
+ <outline>
+ <contour>
+ <point x="466" y="1470" type="line"/>
+ <point x="513" y="1452"/>
+ <point x="653" y="1397"/>
+ <point x="653" y="1366" type="curve" smooth="yes"/>
+ <point x="653" y="1238"/>
+ <point x="531" y="801"/>
+ <point x="531" y="737" type="curve" smooth="yes"/>
+ <point x="531" y="701"/>
+ <point x="660" y="627"/>
+ <point x="660" y="603" type="curve" smooth="yes"/>
+ <point x="660" y="585"/>
+ <point x="496" y="511"/>
+ <point x="468" y="475" type="curve" smooth="yes"/>
+ <point x="439" y="438"/>
+ <point x="312" y="-121"/>
+ <point x="268" y="-167" type="curve" smooth="yes"/>
+ <point x="241" y="-194"/>
+ <point x="106" y="-242"/>
+ <point x="33" y="-265" type="curve"/>
+ <point x="39" y="-402" type="line"/>
+ <point x="150" y="-375"/>
+ <point x="324" y="-323"/>
+ <point x="375" y="-279" type="curve" smooth="yes"/>
+ <point x="465" y="-201"/>
+ <point x="608" y="410"/>
+ <point x="639" y="441" type="curve" smooth="yes"/>
+ <point x="675" y="476"/>
+ <point x="880" y="571"/>
+ <point x="880" y="607" type="curve" smooth="yes"/>
+ <point x="880" y="639"/>
+ <point x="719" y="740"/>
+ <point x="719" y="771" type="curve" smooth="yes"/>
+ <point x="719" y="839"/>
+ <point x="825" y="1259"/>
+ <point x="825" y="1425" type="curve" smooth="yes"/>
+ <point x="825" y="1453"/>
+ <point x="822" y="1474"/>
+ <point x="815" y="1485" type="curve" smooth="yes"/>
+ <point x="786" y="1529"/>
+ <point x="638" y="1581"/>
+ <point x="540" y="1607" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetassocfeat.ufo/glyphs/R_tP_aren.glif b/tests/reference/ufo/psfsetassocfeat.ufo/glyphs/R_tP_aren.glif
new file mode 100644
index 0000000..3950e09
--- /dev/null
+++ b/tests/reference/ufo/psfsetassocfeat.ufo/glyphs/R_tP_aren.glif
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="RtParen" format="2">
+ <advance width="775"/>
+ <unicode hex="0029"/>
+ <outline>
+ <contour>
+ <point x="467" y="1455" type="line"/>
+ <point x="578" y="1327"/>
+ <point x="628" y="1146"/>
+ <point x="628" y="946" type="curve" smooth="yes"/>
+ <point x="628" y="832"/>
+ <point x="612" y="713"/>
+ <point x="582" y="593" type="curve" smooth="yes"/>
+ <point x="497" y="252"/>
+ <point x="328" y="-8"/>
+ <point x="40" y="-260" type="curve"/>
+ <point x="99" y="-402" type="line"/>
+ <point x="444" y="-123"/>
+ <point x="673" y="194"/>
+ <point x="772" y="593" type="curve" smooth="yes"/>
+ <point x="804" y="719"/>
+ <point x="819" y="843"/>
+ <point x="819" y="959" type="curve" smooth="yes"/>
+ <point x="819" y="1236"/>
+ <point x="733" y="1472"/>
+ <point x="580" y="1607" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetassocfeat.ufo/glyphs/R_tS_qrB_rac.glif b/tests/reference/ufo/psfsetassocfeat.ufo/glyphs/R_tS_qrB_rac.glif
new file mode 100644
index 0000000..4c13a82
--- /dev/null
+++ b/tests/reference/ufo/psfsetassocfeat.ufo/glyphs/R_tS_qrB_rac.glif
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="RtSqrBrac" format="2">
+ <advance width="770"/>
+ <unicode hex="005D"/>
+ <outline>
+ <contour>
+ <point x="434" y="-402" type="line"/>
+ <point x="920" y="1568" type="line"/>
+ <point x="480" y="1568" type="line"/>
+ <point x="444" y="1421" type="line"/>
+ <point x="699" y="1421" type="line"/>
+ <point x="286" y="-255" type="line"/>
+ <point x="31" y="-255" type="line"/>
+ <point x="-6" y="-402" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetassocfeat.ufo/glyphs/S_emicolon.glif b/tests/reference/ufo/psfsetassocfeat.ufo/glyphs/S_emicolon.glif
new file mode 100644
index 0000000..be971ac
--- /dev/null
+++ b/tests/reference/ufo/psfsetassocfeat.ufo/glyphs/S_emicolon.glif
@@ -0,0 +1,38 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="Semicolon" format="2">
+ <advance width="630"/>
+ <unicode hex="003B"/>
+ <outline>
+ <contour>
+ <point x="314" y="758" type="curve" smooth="yes"/>
+ <point x="314" y="696"/>
+ <point x="365" y="642"/>
+ <point x="430" y="642" type="curve" smooth="yes"/>
+ <point x="514" y="642"/>
+ <point x="590" y="712"/>
+ <point x="590" y="792" type="curve" smooth="yes"/>
+ <point x="590" y="854"/>
+ <point x="540" y="907"/>
+ <point x="476" y="907" type="curve" smooth="yes"/>
+ <point x="393" y="907"/>
+ <point x="314" y="837"/>
+ </contour>
+ <contour>
+ <point x="137" y="49" type="line"/>
+ <point x="277" y="49" type="line"/>
+ <point x="252" y="-50"/>
+ <point x="145" y="-169"/>
+ <point x="73" y="-225" type="curve"/>
+ <point x="163" y="-265" type="line"/>
+ <point x="280" y="-175"/>
+ <point x="431" y="-28"/>
+ <point x="431" y="118" type="curve" smooth="yes"/>
+ <point x="431" y="193"/>
+ <point x="378" y="245"/>
+ <point x="311" y="245" type="curve" smooth="yes"/>
+ <point x="254" y="245"/>
+ <point x="190" y="209"/>
+ <point x="161" y="147" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetassocfeat.ufo/glyphs/S_olidus.glif b/tests/reference/ufo/psfsetassocfeat.ufo/glyphs/S_olidus.glif
new file mode 100644
index 0000000..589697b
--- /dev/null
+++ b/tests/reference/ufo/psfsetassocfeat.ufo/glyphs/S_olidus.glif
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="Solidus" format="2">
+ <advance width="980"/>
+ <unicode hex="002F"/>
+ <outline>
+ <contour>
+ <point x="1160" y="1568" type="line"/>
+ <point x="-119" y="-240" type="line"/>
+ <point x="50" y="-240" type="line"/>
+ <point x="1330" y="1568" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetassocfeat.ufo/glyphs/S_pace.glif b/tests/reference/ufo/psfsetassocfeat.ufo/glyphs/S_pace.glif
new file mode 100644
index 0000000..c49f0f2
--- /dev/null
+++ b/tests/reference/ufo/psfsetassocfeat.ufo/glyphs/S_pace.glif
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="Space" format="2">
+ <advance width="530"/>
+ <unicode hex="0020"/>
+ <outline/>
+</glyph>
diff --git a/tests/reference/ufo/psfsetassocfeat.ufo/glyphs/T_ilde.glif b/tests/reference/ufo/psfsetassocfeat.ufo/glyphs/T_ilde.glif
new file mode 100644
index 0000000..bf260b8
--- /dev/null
+++ b/tests/reference/ufo/psfsetassocfeat.ufo/glyphs/T_ilde.glif
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="Tilde" format="2">
+ <advance width="1095"/>
+ <unicode hex="007E"/>
+ <outline>
+ <contour>
+ <point x="156" y="368" type="line"/>
+ <point x="173" y="416"/>
+ <point x="215" y="456"/>
+ <point x="293" y="456" type="curve" smooth="yes"/>
+ <point x="468" y="456"/>
+ <point x="643" y="353"/>
+ <point x="873" y="353" type="curve" smooth="yes"/>
+ <point x="1032" y="353"/>
+ <point x="1137" y="472"/>
+ <point x="1169" y="598" type="curve"/>
+ <point x="1064" y="598" type="line"/>
+ <point x="1045" y="553"/>
+ <point x="1002" y="500"/>
+ <point x="919" y="500" type="curve" smooth="yes"/>
+ <point x="683" y="500"/>
+ <point x="551" y="603"/>
+ <point x="330" y="603" type="curve" smooth="yes"/>
+ <point x="184" y="603"/>
+ <point x="81" y="487"/>
+ <point x="51" y="368" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetassocfeat.ufo/glyphs/V_ertL_ine.glif b/tests/reference/ufo/psfsetassocfeat.ufo/glyphs/V_ertL_ine.glif
new file mode 100644
index 0000000..445d622
--- /dev/null
+++ b/tests/reference/ufo/psfsetassocfeat.ufo/glyphs/V_ertL_ine.glif
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="VertLine" format="2">
+ <advance width="670"/>
+ <unicode hex="007C"/>
+ <outline>
+ <contour>
+ <point x="602" y="1578" type="line"/>
+ <point x="112" y="-392" type="line"/>
+ <point x="262" y="-392" type="line"/>
+ <point x="752" y="1578" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetassocfeat.ufo/glyphs/_notdef.glif b/tests/reference/ufo/psfsetassocfeat.ufo/glyphs/_notdef.glif
new file mode 100644
index 0000000..a3e9354
--- /dev/null
+++ b/tests/reference/ufo/psfsetassocfeat.ufo/glyphs/_notdef.glif
@@ -0,0 +1,18 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name=".notdef" format="2">
+ <advance width="1400"/>
+ <outline>
+ <contour>
+ <point x="100" y="0" type="line"/>
+ <point x="1300" y="0" type="line"/>
+ <point x="1300" y="1800" type="line"/>
+ <point x="100" y="1800" type="line"/>
+ </contour>
+ <contour>
+ <point x="150" y="1750" type="line"/>
+ <point x="1250" y="1750" type="line"/>
+ <point x="1250" y="50" type="line"/>
+ <point x="150" y="50" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetassocfeat.ufo/glyphs/_null.glif b/tests/reference/ufo/psfsetassocfeat.ufo/glyphs/_null.glif
new file mode 100644
index 0000000..0b9caa6
--- /dev/null
+++ b/tests/reference/ufo/psfsetassocfeat.ufo/glyphs/_null.glif
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name=".null" format="2">
+ <outline/>
+</glyph>
diff --git a/tests/reference/ufo/psfsetassocfeat.ufo/glyphs/contents.plist b/tests/reference/ufo/psfsetassocfeat.ufo/glyphs/contents.plist
new file mode 100644
index 0000000..ad2aa41
--- /dev/null
+++ b/tests/reference/ufo/psfsetassocfeat.ufo/glyphs/contents.plist
@@ -0,0 +1,232 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+ <key>.notdef</key>
+ <string>_notdef.glif</string>
+ <key>.null</key>
+ <string>_null.glif</string>
+ <key>Ampersand</key>
+ <string>A_mpersand.glif</string>
+ <key>Apos</key>
+ <string>A_pos.glif</string>
+ <key>Asterisk</key>
+ <string>A_sterisk.glif</string>
+ <key>AtSgn</key>
+ <string>A_tS_gn.glif</string>
+ <key>CircumAccent</key>
+ <string>C_ircumA_ccent.glif</string>
+ <key>Colon</key>
+ <string>C_olon.glif</string>
+ <key>CombAcute</key>
+ <string>C_ombA_cute.glif</string>
+ <key>CombCircum</key>
+ <string>C_ombC_ircum.glif</string>
+ <key>CombDiaer</key>
+ <string>C_ombD_iaer.glif</string>
+ <key>CombGrave</key>
+ <string>C_ombG_rave.glif</string>
+ <key>CombRingAbv</key>
+ <string>C_ombR_ingA_bv.glif</string>
+ <key>CombTilde</key>
+ <string>C_ombT_ilde.glif</string>
+ <key>Comma</key>
+ <string>C_omma.glif</string>
+ <key>DigitEight</key>
+ <string>D_igitE_ight.glif</string>
+ <key>DigitFive</key>
+ <string>D_igitF_ive.glif</string>
+ <key>DigitFour</key>
+ <string>D_igitF_our.glif</string>
+ <key>DigitNine</key>
+ <string>D_igitN_ine.glif</string>
+ <key>DigitOne</key>
+ <string>D_igitO_ne.glif</string>
+ <key>DigitSeven</key>
+ <string>D_igitS_even.glif</string>
+ <key>DigitSix</key>
+ <string>D_igitS_ix.glif</string>
+ <key>DigitThree</key>
+ <string>D_igitT_hree.glif</string>
+ <key>DigitTwo</key>
+ <string>D_igitT_wo.glif</string>
+ <key>DigitZero</key>
+ <string>D_igitZ_ero.glif</string>
+ <key>DollarSgn</key>
+ <string>D_ollarS_gn.glif</string>
+ <key>DottedCirc</key>
+ <string>D_ottedC_irc.glif</string>
+ <key>EqSgn</key>
+ <string>E_qS_gn.glif</string>
+ <key>ExclamationMrk</key>
+ <string>E_xclamationM_rk.glif</string>
+ <key>FullStop</key>
+ <string>F_ullS_top.glif</string>
+ <key>GTSgn</key>
+ <string>G_T_S_gn.glif</string>
+ <key>GraveAccent</key>
+ <string>G_raveA_ccent.glif</string>
+ <key>Hyphen</key>
+ <string>H_yphen.glif</string>
+ <key>HyphenMinus</key>
+ <string>H_yphenM_inus.glif</string>
+ <key>Hyphen_Soft</key>
+ <string>H_yphen_S_oft.glif</string>
+ <key>LTSgn</key>
+ <string>L_T_S_gn.glif</string>
+ <key>LftCurlyBrac</key>
+ <string>L_ftC_urlyB_rac.glif</string>
+ <key>LftParen</key>
+ <string>L_ftP_aren.glif</string>
+ <key>LftSqrBrac</key>
+ <string>L_ftS_qrB_rac.glif</string>
+ <key>LowLine</key>
+ <string>L_owL_ine.glif</string>
+ <key>LtnCapA</key>
+ <string>L_tnC_apA_.glif</string>
+ <key>LtnCapADiaer</key>
+ <string>L_tnC_apA_D_iaer.glif</string>
+ <key>LtnCapB</key>
+ <string>L_tnC_apB_.glif</string>
+ <key>LtnCapC</key>
+ <string>L_tnC_apC_.glif</string>
+ <key>LtnCapD</key>
+ <string>L_tnC_apD_.glif</string>
+ <key>LtnCapE</key>
+ <string>L_tnC_apE_.glif</string>
+ <key>LtnCapF</key>
+ <string>L_tnC_apF_.glif</string>
+ <key>LtnCapG</key>
+ <string>L_tnC_apG_.glif</string>
+ <key>LtnCapH</key>
+ <string>L_tnC_apH_.glif</string>
+ <key>LtnCapI</key>
+ <string>L_tnC_apI_.glif</string>
+ <key>LtnCapJ</key>
+ <string>L_tnC_apJ_.glif</string>
+ <key>LtnCapK</key>
+ <string>L_tnC_apK_.glif</string>
+ <key>LtnCapL</key>
+ <string>L_tnC_apL_.glif</string>
+ <key>LtnCapM</key>
+ <string>L_tnC_apM_.glif</string>
+ <key>LtnCapN</key>
+ <string>L_tnC_apN_.glif</string>
+ <key>LtnCapO</key>
+ <string>L_tnC_apO_.glif</string>
+ <key>LtnCapP</key>
+ <string>L_tnC_apP_.glif</string>
+ <key>LtnCapQ</key>
+ <string>L_tnC_apQ_.glif</string>
+ <key>LtnCapR</key>
+ <string>L_tnC_apR_.glif</string>
+ <key>LtnCapS</key>
+ <string>L_tnC_apS_.glif</string>
+ <key>LtnCapT</key>
+ <string>L_tnC_apT_.glif</string>
+ <key>LtnCapU</key>
+ <string>L_tnC_apU_.glif</string>
+ <key>LtnCapV</key>
+ <string>L_tnC_apV_.glif</string>
+ <key>LtnCapW</key>
+ <string>L_tnC_apW_.glif</string>
+ <key>LtnCapX</key>
+ <string>L_tnC_apX_.glif</string>
+ <key>LtnCapY</key>
+ <string>L_tnC_apY_.glif</string>
+ <key>LtnSmA</key>
+ <string>L_tnS_mA_.glif</string>
+ <key>LtnSmAAcute</key>
+ <string>L_tnS_mA_A_cute.glif</string>
+ <key>LtnSmACircum</key>
+ <string>L_tnS_mA_C_ircum.glif</string>
+ <key>LtnSmADiaer</key>
+ <string>L_tnS_mA_D_iaer.glif</string>
+ <key>LtnSmAGrave</key>
+ <string>L_tnS_mA_G_rave.glif</string>
+ <key>LtnSmARingAbv</key>
+ <string>L_tnS_mA_R_ingA_bv.glif</string>
+ <key>LtnSmATilde</key>
+ <string>L_tnS_mA_T_ilde.glif</string>
+ <key>LtnSmB</key>
+ <string>L_tnS_mB_.glif</string>
+ <key>LtnSmC</key>
+ <string>L_tnS_mC_.glif</string>
+ <key>LtnSmD</key>
+ <string>L_tnS_mD_.glif</string>
+ <key>LtnSmE</key>
+ <string>L_tnS_mE_.glif</string>
+ <key>LtnSmF</key>
+ <string>L_tnS_mF_.glif</string>
+ <key>LtnSmG</key>
+ <string>L_tnS_mG_.glif</string>
+ <key>LtnSmH</key>
+ <string>L_tnS_mH_.glif</string>
+ <key>LtnSmI</key>
+ <string>L_tnS_mI_.glif</string>
+ <key>LtnSmJ</key>
+ <string>L_tnS_mJ_.glif</string>
+ <key>LtnSmK</key>
+ <string>L_tnS_mK_.glif</string>
+ <key>LtnSmL</key>
+ <string>L_tnS_mL_.glif</string>
+ <key>LtnSmM</key>
+ <string>L_tnS_mM_.glif</string>
+ <key>LtnSmN</key>
+ <string>L_tnS_mN_.glif</string>
+ <key>LtnSmO</key>
+ <string>L_tnS_mO_.glif</string>
+ <key>LtnSmP</key>
+ <string>L_tnS_mP_.glif</string>
+ <key>LtnSmQ</key>
+ <string>L_tnS_mQ_.glif</string>
+ <key>LtnSmR</key>
+ <string>L_tnS_mR_.glif</string>
+ <key>LtnSmS</key>
+ <string>L_tnS_mS_.glif</string>
+ <key>LtnSmT</key>
+ <string>L_tnS_mT_.glif</string>
+ <key>LtnSmU</key>
+ <string>L_tnS_mU_.glif</string>
+ <key>LtnSmV</key>
+ <string>L_tnS_mV_.glif</string>
+ <key>LtnSmW</key>
+ <string>L_tnS_mW_.glif</string>
+ <key>LtnSmX</key>
+ <string>L_tnS_mX_.glif</string>
+ <key>LtnSmY</key>
+ <string>L_tnS_mY_.glif</string>
+ <key>NonBreakingHyphen</key>
+ <string>N_onB_reakingH_yphen.glif</string>
+ <key>NumSgn</key>
+ <string>N_umS_gn.glif</string>
+ <key>PercentSgn</key>
+ <string>P_ercentS_gn.glif</string>
+ <key>PlusSgn</key>
+ <string>P_lusS_gn.glif</string>
+ <key>QstnMrk</key>
+ <string>Q_stnM_rk.glif</string>
+ <key>QuotMrk</key>
+ <string>Q_uotM_rk.glif</string>
+ <key>ReverseSolidus</key>
+ <string>R_everseS_olidus.glif</string>
+ <key>RtCurlyBrac</key>
+ <string>R_tC_urlyB_rac.glif</string>
+ <key>RtParen</key>
+ <string>R_tP_aren.glif</string>
+ <key>RtSqrBrac</key>
+ <string>R_tS_qrB_rac.glif</string>
+ <key>Semicolon</key>
+ <string>S_emicolon.glif</string>
+ <key>Solidus</key>
+ <string>S_olidus.glif</string>
+ <key>Space</key>
+ <string>S_pace.glif</string>
+ <key>Tilde</key>
+ <string>T_ilde.glif</string>
+ <key>VertLine</key>
+ <string>V_ertL_ine.glif</string>
+ <key>nonmarkingreturn</key>
+ <string>nonmarkingreturn.glif</string>
+</dict>
+</plist>
diff --git a/tests/reference/ufo/psfsetassocfeat.ufo/glyphs/nonmarkingreturn.glif b/tests/reference/ufo/psfsetassocfeat.ufo/glyphs/nonmarkingreturn.glif
new file mode 100644
index 0000000..9a63f06
--- /dev/null
+++ b/tests/reference/ufo/psfsetassocfeat.ufo/glyphs/nonmarkingreturn.glif
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="nonmarkingreturn" format="2">
+ <advance width="1004"/>
+ <outline/>
+</glyph>
diff --git a/tests/reference/ufo/psfsetassocfeat.ufo/layercontents.plist b/tests/reference/ufo/psfsetassocfeat.ufo/layercontents.plist
new file mode 100644
index 0000000..42b7482
--- /dev/null
+++ b/tests/reference/ufo/psfsetassocfeat.ufo/layercontents.plist
@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<array>
+ <array>
+ <string>public.default</string>
+ <string>glyphs</string>
+ </array>
+</array>
+</plist>
diff --git a/tests/reference/ufo/psfsetassocfeat.ufo/lib.plist b/tests/reference/ufo/psfsetassocfeat.ufo/lib.plist
new file mode 100644
index 0000000..43413a8
--- /dev/null
+++ b/tests/reference/ufo/psfsetassocfeat.ufo/lib.plist
@@ -0,0 +1,538 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+ <key>com.schriftgestaltung.Glyphs.fontUserData</key>
+ <dict/>
+ <key>com.schriftgestaltung.appVersion</key>
+ <string>1161</string>
+ <key>com.schriftgestaltung.customName</key>
+ <string>Italic</string>
+ <key>com.schriftgestaltung.customParameter.GSFont.DisplayStrings</key>
+ <string/>
+ <key>com.schriftgestaltung.customParameter.GSFont.disablesAutomaticAlignment</key>
+ <true/>
+ <key>com.schriftgestaltung.customParameter.GSFont.disablesLastChange</key>
+ <true/>
+ <key>com.schriftgestaltung.customParameter.GSFont.useNiceNames</key>
+ <integer>0</integer>
+ <key>com.schriftgestaltung.customParameter.GSFontMaster.customValue</key>
+ <integer>0</integer>
+ <key>com.schriftgestaltung.customParameter.GSFontMaster.customValue1</key>
+ <integer>0</integer>
+ <key>com.schriftgestaltung.customParameter.GSFontMaster.customValue2</key>
+ <integer>0</integer>
+ <key>com.schriftgestaltung.customParameter.GSFontMaster.customValue3</key>
+ <integer>0</integer>
+ <key>com.schriftgestaltung.customParameter.GSFontMaster.iconName</key>
+ <string/>
+ <key>com.schriftgestaltung.customParameter.GSFontMaster.weightValue</key>
+ <integer>400</integer>
+ <key>com.schriftgestaltung.customParameter.GSFontMaster.widthValue</key>
+ <integer>100</integer>
+ <key>com.schriftgestaltung.disablesAutomaticAlignment</key>
+ <true/>
+ <key>com.schriftgestaltung.disablesLastChange</key>
+ <true/>
+ <key>com.schriftgestaltung.fontMasterOrder</key>
+ <integer>0</integer>
+ <key>com.schriftgestaltung.glyphOrder</key>
+ <array>
+ <string>.notdef</string>
+ <string>.null</string>
+ <string>nonmarkingreturn</string>
+ <string>Space</string>
+ <string>ExclamationMrk</string>
+ <string>QuotMrk</string>
+ <string>NumSgn</string>
+ <string>DollarSgn</string>
+ <string>PercentSgn</string>
+ <string>Ampersand</string>
+ <string>Apos</string>
+ <string>LftParen</string>
+ <string>RtParen</string>
+ <string>Asterisk</string>
+ <string>PlusSgn</string>
+ <string>Comma</string>
+ <string>HyphenMinus</string>
+ <string>FullStop</string>
+ <string>Solidus</string>
+ <string>DigitZero</string>
+ <string>DigitOne</string>
+ <string>DigitTwo</string>
+ <string>DigitThree</string>
+ <string>DigitFour</string>
+ <string>DigitFive</string>
+ <string>DigitSix</string>
+ <string>DigitSeven</string>
+ <string>DigitEight</string>
+ <string>DigitNine</string>
+ <string>Colon</string>
+ <string>Semicolon</string>
+ <string>LTSgn</string>
+ <string>EqSgn</string>
+ <string>GTSgn</string>
+ <string>QstnMrk</string>
+ <string>AtSgn</string>
+ <string>LtnCapA</string>
+ <string>LtnCapA.alt</string>
+ <string>LtnCapB</string>
+ <string>LtnCapC</string>
+ <string>LtnCapD</string>
+ <string>LtnCapE</string>
+ <string>LtnCapF</string>
+ <string>LtnCapG</string>
+ <string>LtnCapH</string>
+ <string>LtnCapI</string>
+ <string>LtnCapJ</string>
+ <string>LtnCapK</string>
+ <string>LtnCapL</string>
+ <string>LtnCapM</string>
+ <string>LtnCapN</string>
+ <string>LtnCapO</string>
+ <string>LtnCapP</string>
+ <string>LtnCapQ</string>
+ <string>LtnCapR</string>
+ <string>LtnCapS</string>
+ <string>LtnCapT</string>
+ <string>LtnCapU</string>
+ <string>LtnCapV</string>
+ <string>LtnCapW</string>
+ <string>LtnCapX</string>
+ <string>LtnCapY</string>
+ <string>LftSqrBrac</string>
+ <string>ReverseSolidus</string>
+ <string>RtSqrBrac</string>
+ <string>CircumAccent</string>
+ <string>LowLine</string>
+ <string>GraveAccent</string>
+ <string>LtnSmA</string>
+ <string>LtnSmB</string>
+ <string>LtnSmC</string>
+ <string>LtnSmD</string>
+ <string>LtnSmE</string>
+ <string>LtnSmF</string>
+ <string>LtnSmG</string>
+ <string>LtnSmH</string>
+ <string>LtnSmI</string>
+ <string>LtnSmJ</string>
+ <string>LtnSmK</string>
+ <string>LtnSmL</string>
+ <string>LtnSmM</string>
+ <string>LtnSmN</string>
+ <string>LtnSmO</string>
+ <string>LtnSmP</string>
+ <string>LtnSmQ</string>
+ <string>LtnSmR</string>
+ <string>LtnSmS</string>
+ <string>LtnSmT</string>
+ <string>LtnSmU</string>
+ <string>LtnSmV</string>
+ <string>LtnSmW</string>
+ <string>LtnSmX</string>
+ <string>LtnSmY</string>
+ <string>LftCurlyBrac</string>
+ <string>VertLine</string>
+ <string>RtCurlyBrac</string>
+ <string>Tilde</string>
+ <string>LtnCapADiaer</string>
+ <string>LtnSmAAcute</string>
+ <string>LtnSmAGrave</string>
+ <string>LtnSmACircum</string>
+ <string>LtnSmADiaer</string>
+ <string>LtnSmATilde</string>
+ <string>LtnSmARingAbv</string>
+ <string>DottedCirc</string>
+ <string>Hyphen</string>
+ <string>NonBreakingHyphen</string>
+ <string>Hyphen_Soft</string>
+ <string>CombAcute</string>
+ <string>CombGrave</string>
+ <string>CombCircum</string>
+ <string>CombTilde</string>
+ <string>CombDiaer</string>
+ <string>CombRingAbv</string>
+ </array>
+ <key>com.schriftgestaltung.keyboardIncrement</key>
+ <integer>1</integer>
+ <key>com.schriftgestaltung.weight</key>
+ <string>Regular</string>
+ <key>com.schriftgestaltung.weightValue</key>
+ <integer>400</integer>
+ <key>com.schriftgestaltung.width</key>
+ <string>Regular</string>
+ <key>com.schriftgestaltung.widthValue</key>
+ <integer>100</integer>
+ <key>org.sil.lcg.toneLetters</key>
+ <dict>
+ <key>contourWidth</key>
+ <integer>480</integer>
+ <key>dotSize</key>
+ <integer>180</integer>
+ <key>dotSpacing</key>
+ <integer>200</integer>
+ <key>glyphDepth</key>
+ <integer>-25</integer>
+ <key>glyphHeight</key>
+ <integer>1600</integer>
+ <key>italicAngle</key>
+ <integer>14</integer>
+ <key>marginDotLeft</key>
+ <integer>120</integer>
+ <key>marginDotRight</key>
+ <integer>160</integer>
+ <key>marginFlatLeft</key>
+ <integer>120</integer>
+ <key>marginFlatRight</key>
+ <integer>160</integer>
+ <key>marginPointLeft</key>
+ <integer>100</integer>
+ <key>marginPointRight</key>
+ <integer>140</integer>
+ <key>strokeThickness</key>
+ <integer>120</integer>
+ </dict>
+ <key>public.glyphOrder</key>
+ <array>
+ <string>.notdef</string>
+ <string>.null</string>
+ <string>nonmarkingreturn</string>
+ <string>Space</string>
+ <string>ExclamationMrk</string>
+ <string>QuotMrk</string>
+ <string>NumSgn</string>
+ <string>DollarSgn</string>
+ <string>PercentSgn</string>
+ <string>Ampersand</string>
+ <string>Apos</string>
+ <string>LftParen</string>
+ <string>RtParen</string>
+ <string>Asterisk</string>
+ <string>PlusSgn</string>
+ <string>Comma</string>
+ <string>HyphenMinus</string>
+ <string>FullStop</string>
+ <string>Solidus</string>
+ <string>DigitZero</string>
+ <string>DigitOne</string>
+ <string>DigitTwo</string>
+ <string>DigitThree</string>
+ <string>DigitFour</string>
+ <string>DigitFive</string>
+ <string>DigitSix</string>
+ <string>DigitSeven</string>
+ <string>DigitEight</string>
+ <string>DigitNine</string>
+ <string>Colon</string>
+ <string>Semicolon</string>
+ <string>LTSgn</string>
+ <string>EqSgn</string>
+ <string>GTSgn</string>
+ <string>QstnMrk</string>
+ <string>AtSgn</string>
+ <string>LtnCapA</string>
+ <string>LtnCapA.alt</string>
+ <string>LtnCapB</string>
+ <string>LtnCapC</string>
+ <string>LtnCapD</string>
+ <string>LtnCapE</string>
+ <string>LtnCapF</string>
+ <string>LtnCapG</string>
+ <string>LtnCapH</string>
+ <string>LtnCapI</string>
+ <string>LtnCapJ</string>
+ <string>LtnCapK</string>
+ <string>LtnCapL</string>
+ <string>LtnCapM</string>
+ <string>LtnCapN</string>
+ <string>LtnCapO</string>
+ <string>LtnCapP</string>
+ <string>LtnCapQ</string>
+ <string>LtnCapR</string>
+ <string>LtnCapS</string>
+ <string>LtnCapT</string>
+ <string>LtnCapU</string>
+ <string>LtnCapV</string>
+ <string>LtnCapW</string>
+ <string>LtnCapX</string>
+ <string>LtnCapY</string>
+ <string>LftSqrBrac</string>
+ <string>ReverseSolidus</string>
+ <string>RtSqrBrac</string>
+ <string>CircumAccent</string>
+ <string>LowLine</string>
+ <string>GraveAccent</string>
+ <string>LtnSmA</string>
+ <string>LtnSmB</string>
+ <string>LtnSmC</string>
+ <string>LtnSmD</string>
+ <string>LtnSmE</string>
+ <string>LtnSmF</string>
+ <string>LtnSmG</string>
+ <string>LtnSmH</string>
+ <string>LtnSmI</string>
+ <string>LtnSmJ</string>
+ <string>LtnSmK</string>
+ <string>LtnSmL</string>
+ <string>LtnSmM</string>
+ <string>LtnSmN</string>
+ <string>LtnSmO</string>
+ <string>LtnSmP</string>
+ <string>LtnSmQ</string>
+ <string>LtnSmR</string>
+ <string>LtnSmS</string>
+ <string>LtnSmT</string>
+ <string>LtnSmU</string>
+ <string>LtnSmV</string>
+ <string>LtnSmW</string>
+ <string>LtnSmX</string>
+ <string>LtnSmY</string>
+ <string>LftCurlyBrac</string>
+ <string>VertLine</string>
+ <string>RtCurlyBrac</string>
+ <string>Tilde</string>
+ <string>LtnCapADiaer</string>
+ <string>LtnSmAAcute</string>
+ <string>LtnSmAGrave</string>
+ <string>LtnSmACircum</string>
+ <string>LtnSmADiaer</string>
+ <string>LtnSmATilde</string>
+ <string>LtnSmARingAbv</string>
+ <string>DottedCirc</string>
+ <string>Hyphen</string>
+ <string>NonBreakingHyphen</string>
+ <string>Hyphen_Soft</string>
+ <string>CombAcute</string>
+ <string>CombGrave</string>
+ <string>CombCircum</string>
+ <string>CombTilde</string>
+ <string>CombDiaer</string>
+ <string>CombRingAbv</string>
+ </array>
+ <key>public.postscriptNames</key>
+ <dict>
+ <key>Ampersand</key>
+ <string>ampersand</string>
+ <key>Apos</key>
+ <string>quotesingle</string>
+ <key>Asterisk</key>
+ <string>asterisk</string>
+ <key>AtSgn</key>
+ <string>at</string>
+ <key>CircumAccent</key>
+ <string>asciicircum</string>
+ <key>Colon</key>
+ <string>colon</string>
+ <key>CombAcute</key>
+ <string>acutecomb</string>
+ <key>CombCircum</key>
+ <string>uni0302</string>
+ <key>CombDiaer</key>
+ <string>uni0308</string>
+ <key>CombGrave</key>
+ <string>gravecomb</string>
+ <key>CombRingAbv</key>
+ <string>uni030A</string>
+ <key>CombTilde</key>
+ <string>tildecomb</string>
+ <key>Comma</key>
+ <string>comma</string>
+ <key>DigitEight</key>
+ <string>eight</string>
+ <key>DigitFive</key>
+ <string>five</string>
+ <key>DigitFour</key>
+ <string>four</string>
+ <key>DigitNine</key>
+ <string>nine</string>
+ <key>DigitOne</key>
+ <string>one</string>
+ <key>DigitSeven</key>
+ <string>seven</string>
+ <key>DigitSix</key>
+ <string>six</string>
+ <key>DigitThree</key>
+ <string>three</string>
+ <key>DigitTwo</key>
+ <string>two</string>
+ <key>DigitZero</key>
+ <string>zero</string>
+ <key>DollarSgn</key>
+ <string>dollar</string>
+ <key>DottedCirc</key>
+ <string>uni25CC</string>
+ <key>EqSgn</key>
+ <string>equal</string>
+ <key>ExclamationMrk</key>
+ <string>exclam</string>
+ <key>FullStop</key>
+ <string>period</string>
+ <key>GTSgn</key>
+ <string>greater</string>
+ <key>GraveAccent</key>
+ <string>grave</string>
+ <key>Hyphen</key>
+ <string>uni2010</string>
+ <key>HyphenMinus</key>
+ <string>hyphen</string>
+ <key>Hyphen_Soft</key>
+ <string>uni00AD</string>
+ <key>LTSgn</key>
+ <string>less</string>
+ <key>LftCurlyBrac</key>
+ <string>braceleft</string>
+ <key>LftParen</key>
+ <string>parenleft</string>
+ <key>LftSqrBrac</key>
+ <string>bracketleft</string>
+ <key>LowLine</key>
+ <string>underscore</string>
+ <key>LtnCapA</key>
+ <string>A</string>
+ <key>LtnCapA.alt</key>
+ <string>A</string>
+ <key>LtnCapADiaer</key>
+ <string>Adieresis</string>
+ <key>LtnCapB</key>
+ <string>B</string>
+ <key>LtnCapC</key>
+ <string>C</string>
+ <key>LtnCapD</key>
+ <string>D</string>
+ <key>LtnCapE</key>
+ <string>E</string>
+ <key>LtnCapF</key>
+ <string>F</string>
+ <key>LtnCapG</key>
+ <string>G</string>
+ <key>LtnCapH</key>
+ <string>H</string>
+ <key>LtnCapI</key>
+ <string>I</string>
+ <key>LtnCapJ</key>
+ <string>J</string>
+ <key>LtnCapK</key>
+ <string>K</string>
+ <key>LtnCapL</key>
+ <string>L</string>
+ <key>LtnCapM</key>
+ <string>M</string>
+ <key>LtnCapN</key>
+ <string>N</string>
+ <key>LtnCapO</key>
+ <string>O</string>
+ <key>LtnCapP</key>
+ <string>P</string>
+ <key>LtnCapQ</key>
+ <string>Q</string>
+ <key>LtnCapR</key>
+ <string>R</string>
+ <key>LtnCapS</key>
+ <string>S</string>
+ <key>LtnCapT</key>
+ <string>T</string>
+ <key>LtnCapU</key>
+ <string>U</string>
+ <key>LtnCapV</key>
+ <string>V</string>
+ <key>LtnCapW</key>
+ <string>W</string>
+ <key>LtnCapX</key>
+ <string>X</string>
+ <key>LtnCapY</key>
+ <string>Y</string>
+ <key>LtnSmA</key>
+ <string>a</string>
+ <key>LtnSmAAcute</key>
+ <string>aacute</string>
+ <key>LtnSmACircum</key>
+ <string>acircumflex</string>
+ <key>LtnSmADiaer</key>
+ <string>adieresis</string>
+ <key>LtnSmAGrave</key>
+ <string>agrave</string>
+ <key>LtnSmARingAbv</key>
+ <string>aring</string>
+ <key>LtnSmATilde</key>
+ <string>atilde</string>
+ <key>LtnSmB</key>
+ <string>b</string>
+ <key>LtnSmC</key>
+ <string>c</string>
+ <key>LtnSmD</key>
+ <string>d</string>
+ <key>LtnSmE</key>
+ <string>e</string>
+ <key>LtnSmF</key>
+ <string>f</string>
+ <key>LtnSmG</key>
+ <string>g</string>
+ <key>LtnSmH</key>
+ <string>h</string>
+ <key>LtnSmI</key>
+ <string>i</string>
+ <key>LtnSmJ</key>
+ <string>j</string>
+ <key>LtnSmK</key>
+ <string>k</string>
+ <key>LtnSmL</key>
+ <string>l</string>
+ <key>LtnSmM</key>
+ <string>m</string>
+ <key>LtnSmN</key>
+ <string>n</string>
+ <key>LtnSmO</key>
+ <string>o</string>
+ <key>LtnSmP</key>
+ <string>p</string>
+ <key>LtnSmQ</key>
+ <string>q</string>
+ <key>LtnSmR</key>
+ <string>r</string>
+ <key>LtnSmS</key>
+ <string>s</string>
+ <key>LtnSmT</key>
+ <string>t</string>
+ <key>LtnSmU</key>
+ <string>u</string>
+ <key>LtnSmV</key>
+ <string>v</string>
+ <key>LtnSmW</key>
+ <string>w</string>
+ <key>LtnSmX</key>
+ <string>x</string>
+ <key>LtnSmY</key>
+ <string>y</string>
+ <key>NonBreakingHyphen</key>
+ <string>uni2011</string>
+ <key>NumSgn</key>
+ <string>numbersign</string>
+ <key>PercentSgn</key>
+ <string>percent</string>
+ <key>PlusSgn</key>
+ <string>plus</string>
+ <key>QstnMrk</key>
+ <string>question</string>
+ <key>QuotMrk</key>
+ <string>quotedbl</string>
+ <key>ReverseSolidus</key>
+ <string>backslash</string>
+ <key>RtCurlyBrac</key>
+ <string>braceright</string>
+ <key>RtParen</key>
+ <string>parenright</string>
+ <key>RtSqrBrac</key>
+ <string>bracketright</string>
+ <key>Semicolon</key>
+ <string>semicolon</string>
+ <key>Solidus</key>
+ <string>slash</string>
+ <key>Space</key>
+ <string>space</string>
+ <key>Tilde</key>
+ <string>asciitilde</string>
+ <key>VertLine</key>
+ <string>bar</string>
+ </dict>
+</dict>
+</plist>
diff --git a/tests/reference/ufo/psfsetassocfeat.ufo/metainfo.plist b/tests/reference/ufo/psfsetassocfeat.ufo/metainfo.plist
new file mode 100644
index 0000000..aa10c5c
--- /dev/null
+++ b/tests/reference/ufo/psfsetassocfeat.ufo/metainfo.plist
@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+ <key>creator</key>
+ <string>org.sil.scripts.pysilfont</string>
+ <key>formatVersion</key>
+ <integer>3</integer>
+</dict>
+</plist>
diff --git a/tests/reference/ufo/psfsetassocuids.lg b/tests/reference/ufo/psfsetassocuids.lg
new file mode 100644
index 0000000..86af491
--- /dev/null
+++ b/tests/reference/ufo/psfsetassocuids.lg
@@ -0,0 +1,22 @@
+2021-06-29 14:42:22 Progress: Running: psfsetassocuids tests/input/font-psf-test/source/PsfTest-Bold.ufo -i tests/input/psfsetassocuids.csv -l local/testresults/ufo/psfsetassocuids.log -p loglevel=i
+2021-06-29 14:42:22 Progress: Opening file for input: tests/input/psfsetassocuids.csv
+2021-06-29 14:42:22 Progress: Reading UFO: tests/input/font-psf-test/source/PsfTest-Bold.ufo
+2021-06-29 14:42:22 Info: Processing Glyph Layer 0: public.defaultglyphs
+2021-06-29 14:42:22 Progress: Checking fontinfo.plist metadata
+2021-06-29 14:42:22 Warning: note is present - it's use is discouraged
+2021-06-29 14:42:22 Warning: openTypeOS2FamilyClass would be removed from fontinfo Old value: [0, 0]
+2021-06-29 14:42:22 Info: Types: Old - list, New - NoneType
+2021-06-29 14:42:22 Warning: openTypeOS2Selection would be added New value: [7]
+2021-06-29 14:42:22 Info: Types: Old - NoneType, New - list
+2021-06-29 14:42:22 Progress: Checking lib.plist metadata
+2021-06-29 14:42:22 Warning: com.schriftgestaltung.disablesAutomaticAlignment would be deleted - obsolete key Old value: True
+2021-06-29 14:42:22 Info: Types: Old - bool, New - NoneType
+2021-06-29 14:42:22 Warning: com.schriftgestaltung.disablesLastChange would be deleted - obsolete key Old value: True
+2021-06-29 14:42:22 Info: Types: Old - bool, New - NoneType
+2021-06-29 14:42:22 Progress: Check & fix results:- Errors: 0, Changes to make: 4, Other warnings: 1
+2021-06-29 14:42:22 Progress: See log file for details
+2021-06-29 14:42:22 Error: No glyph in font for SupThree on line 1
+2021-06-29 14:42:22 Progress: Processing font for output
+2021-06-29 14:42:22 Progress: Output UFO already exists - reading for comparison
+2021-06-29 14:42:22 Progress: Writing font to local/testresults/ufo/psfsetassocuids.ufo
+2021-06-29 14:42:22 Info: Processing glyphs directory
diff --git a/tests/reference/ufo/psfsetassocuids.ufo/fontinfo.plist b/tests/reference/ufo/psfsetassocuids.ufo/fontinfo.plist
new file mode 100644
index 0000000..2036ffe
--- /dev/null
+++ b/tests/reference/ufo/psfsetassocuids.ufo/fontinfo.plist
@@ -0,0 +1,245 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+ <key>ascender</key>
+ <integer>2100</integer>
+ <key>capHeight</key>
+ <integer>1485</integer>
+ <key>copyright</key>
+ <string>Copyright (c) 2004-2021 SIL International</string>
+ <key>descender</key>
+ <integer>-550</integer>
+ <key>familyName</key>
+ <string>Psf Test</string>
+ <key>note</key>
+ <string>Test note
+Second line
+
+Third line
+</string>
+ <key>openTypeHeadCreated</key>
+ <string>2021/01/29 10:05:06</string>
+ <key>openTypeHheaAscender</key>
+ <integer>2100</integer>
+ <key>openTypeHheaDescender</key>
+ <integer>-550</integer>
+ <key>openTypeHheaLineGap</key>
+ <integer>0</integer>
+ <key>openTypeNameDescription</key>
+ <string>Copyright (c) 2004-2021 SIL International</string>
+ <key>openTypeNameDesigner</key>
+ <string>Victor Gaultney, Annie Olsen, Julie Remington, Don Collingsworth, Eric Hays, Becca Hirsbrunner</string>
+ <key>openTypeNameDesignerURL</key>
+ <string>http://scripts.sil.org/</string>
+ <key>openTypeNameLicense</key>
+ <string>Copyright (c) 2004-2021 SIL International (http://www.sil.org/) with Reserved Font Names "Andika" and "SIL".
+
+This Font Software is licensed under the SIL Open Font License, Version 1.1. This license is copied below, and is also available with a FAQ at: http://scripts.sil.org/OFL
+
+
+-----------------------------------------------------------
+SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007
+-----------------------------------------------------------
+
+PREAMBLE
+The goals of the Open Font License (OFL) are to stimulate worldwide development of collaborative font projects, to support the font creation efforts of academic and linguistic communities, and to provide a free and open framework in which fonts may be shared and improved in partnership with others.
+
+The OFL allows the licensed fonts to be used, studied, modified and redistributed freely as long as they are not sold by themselves. The fonts, including any derivative works, can be bundled, embedded, redistributed and/or sold with any software provided that any reserved names are not used by derivative works. The fonts and derivatives, however, cannot be released under any other type of license. The requirement for fonts to remain under this license does not apply to any document created using the fonts or their derivatives.
+
+DEFINITIONS
+"Font Software" refers to the set of files released by the Copyright Holder(s) under this license and clearly marked as such. This may include source files, build scripts and documentation.
+
+"Reserved Font Name" refers to any names specified as such after the copyright statement(s).
+
+"Original Version" refers to the collection of Font Software components as distributed by the Copyright Holder(s).
+
+"Modified Version" refers to any derivative made by adding to, deleting, or substituting -- in part or in whole -- any of the components of the Original Version, by changing formats or by porting the Font Software to a new environment.
+
+"Author" refers to any designer, engineer, programmer, technical writer or other person who contributed to the Font Software.
+
+PERMISSION &amp; CONDITIONS
+Permission is hereby granted, free of charge, to any person obtaining a copy of the Font Software, to use, study, copy, merge, embed, modify, redistribute, and sell modified and unmodified copies of the Font Software, subject to the following conditions:
+
+1) Neither the Font Software nor any of its individual components, in Original or Modified Versions, may be sold by itself.
+
+2) Original or Modified Versions of the Font Software may be bundled, redistributed and/or sold with any software, provided that each copy contains the above copyright notice and this license. These can be included either as stand-alone text files, human-readable headers or in the appropriate machine-readable metadata fields within text or binary files as long as those fields can be easily viewed by the user.
+
+3) No Modified Version of the Font Software may use the Reserved Font Name(s) unless explicit written permission is granted by the corresponding Copyright Holder. This restriction only applies to the primary font name as presented to the users.
+
+4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font Software shall not be used to promote, endorse or advertise any Modified Version, except to acknowledge the contribution(s) of the Copyright Holder(s) and the Author(s) or with their explicit written permission.
+
+5) The Font Software, modified or unmodified, in part or in whole, must be distributed entirely under this license, and must not be distributed under any other license. The requirement for fonts to remain under this license does not apply to any document created using the Font Software.
+
+TERMINATION
+This license becomes null and void if any of the above conditions are not met.
+
+DISCLAIMER
+THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM OTHER DEALINGS IN THE FONT SOFTWARE.</string>
+ <key>openTypeNameLicenseURL</key>
+ <string>http://scripts.sil.org/OFL</string>
+ <key>openTypeNameManufacturer</key>
+ <string>SIL International</string>
+ <key>openTypeNameManufacturerURL</key>
+ <string>http://scripts.sil.org</string>
+ <key>openTypeNamePreferredFamilyName</key>
+ <string>Psf Test</string>
+ <key>openTypeNamePreferredSubfamilyName</key>
+ <string>Bold</string>
+ <key>openTypeNameUniqueID</key>
+ <string>SIL International: Psf Test Bold: 2022</string>
+ <key>openTypeNameVersion</key>
+ <string>Version 5.550</string>
+ <key>openTypeOS2CodePageRanges</key>
+ <array>
+ <integer>0</integer>
+ <integer>1</integer>
+ <integer>2</integer>
+ <integer>4</integer>
+ <integer>7</integer>
+ <integer>8</integer>
+ </array>
+ <key>openTypeOS2FamilyClass</key>
+ <array>
+ <integer>0</integer>
+ <integer>0</integer>
+ </array>
+ <key>openTypeOS2Panose</key>
+ <array>
+ <integer>2</integer>
+ <integer>0</integer>
+ <integer>0</integer>
+ <integer>0</integer>
+ <integer>0</integer>
+ <integer>0</integer>
+ <integer>0</integer>
+ <integer>0</integer>
+ <integer>0</integer>
+ <integer>0</integer>
+ </array>
+ <key>openTypeOS2StrikeoutPosition</key>
+ <integer>700</integer>
+ <key>openTypeOS2StrikeoutSize</key>
+ <integer>100</integer>
+ <key>openTypeOS2SubscriptXOffset</key>
+ <integer>0</integer>
+ <key>openTypeOS2SubscriptXSize</key>
+ <integer>1433</integer>
+ <key>openTypeOS2SubscriptYOffset</key>
+ <integer>286</integer>
+ <key>openTypeOS2SubscriptYSize</key>
+ <integer>1331</integer>
+ <key>openTypeOS2SuperscriptXOffset</key>
+ <integer>0</integer>
+ <key>openTypeOS2SuperscriptXSize</key>
+ <integer>1433</integer>
+ <key>openTypeOS2SuperscriptYOffset</key>
+ <integer>976</integer>
+ <key>openTypeOS2SuperscriptYSize</key>
+ <integer>1331</integer>
+ <key>openTypeOS2Type</key>
+ <array/>
+ <key>openTypeOS2TypoAscender</key>
+ <integer>2100</integer>
+ <key>openTypeOS2TypoDescender</key>
+ <integer>-550</integer>
+ <key>openTypeOS2TypoLineGap</key>
+ <integer>0</integer>
+ <key>openTypeOS2UnicodeRanges</key>
+ <array>
+ <integer>0</integer>
+ <integer>1</integer>
+ <integer>6</integer>
+ <integer>7</integer>
+ <integer>31</integer>
+ <integer>33</integer>
+ <integer>35</integer>
+ <integer>36</integer>
+ <integer>37</integer>
+ <integer>38</integer>
+ <integer>39</integer>
+ <integer>40</integer>
+ <integer>45</integer>
+ <integer>46</integer>
+ <integer>47</integer>
+ <integer>57</integer>
+ <integer>60</integer>
+ <integer>62</integer>
+ <integer>64</integer>
+ <integer>67</integer>
+ <integer>69</integer>
+ <integer>89</integer>
+ </array>
+ <key>openTypeOS2VendorID</key>
+ <string>SIL</string>
+ <key>openTypeOS2WeightClass</key>
+ <integer>700</integer>
+ <key>openTypeOS2WidthClass</key>
+ <integer>5</integer>
+ <key>openTypeOS2WinAscent</key>
+ <integer>2100</integer>
+ <key>openTypeOS2WinDescent</key>
+ <integer>550</integer>
+ <key>postscriptBlueValues</key>
+ <array>
+ <integer>-490</integer>
+ <integer>-490</integer>
+ <integer>-25</integer>
+ <integer>0</integer>
+ <integer>1020</integer>
+ <integer>1040</integer>
+ <integer>1455</integer>
+ <integer>1485</integer>
+ <integer>1600</integer>
+ <integer>1620</integer>
+ </array>
+ <key>postscriptFontName</key>
+ <string>PsfTest-Bold</string>
+ <key>postscriptFullName</key>
+ <string>Psf Test Bold</string>
+ <key>postscriptStemSnapH</key>
+ <array>
+ <integer>140</integer>
+ <integer>145</integer>
+ <integer>150</integer>
+ <integer>155</integer>
+ <integer>160</integer>
+ <integer>165</integer>
+ <integer>170</integer>
+ <integer>175</integer>
+ <integer>185</integer>
+ <integer>270</integer>
+ </array>
+ <key>postscriptStemSnapV</key>
+ <array>
+ <integer>165</integer>
+ <integer>180</integer>
+ <integer>185</integer>
+ <integer>190</integer>
+ <integer>195</integer>
+ <integer>200</integer>
+ <integer>205</integer>
+ <integer>270</integer>
+ </array>
+ <key>postscriptUnderlinePosition</key>
+ <integer>-110</integer>
+ <key>postscriptUnderlineThickness</key>
+ <integer>80</integer>
+ <key>styleMapFamilyName</key>
+ <string>Psf Test</string>
+ <key>styleMapStyleName</key>
+ <string>bold</string>
+ <key>styleName</key>
+ <string>Bold</string>
+ <key>trademark</key>
+ <string>Andika is a trademark of SIL International.</string>
+ <key>unitsPerEm</key>
+ <integer>2048</integer>
+ <key>versionMajor</key>
+ <integer>5</integer>
+ <key>versionMinor</key>
+ <integer>550</integer>
+ <key>xHeight</key>
+ <integer>1040</integer>
+</dict>
+</plist>
diff --git a/tests/reference/ufo/psfsetassocuids.ufo/glyphs/A_mpersand.glif b/tests/reference/ufo/psfsetassocuids.ufo/glyphs/A_mpersand.glif
new file mode 100644
index 0000000..f2749f2
--- /dev/null
+++ b/tests/reference/ufo/psfsetassocuids.ufo/glyphs/A_mpersand.glif
@@ -0,0 +1,61 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="Ampersand" format="2">
+ <advance width="1355"/>
+ <unicode hex="0026"/>
+ <outline>
+ <contour>
+ <point x="1060" y="600" type="line"/>
+ <point x="996" y="433"/>
+ <point x="715" y="190"/>
+ <point x="540" y="190" type="curve" smooth="yes"/>
+ <point x="425" y="190"/>
+ <point x="335" y="257"/>
+ <point x="335" y="370" type="curve" smooth="yes"/>
+ <point x="335" y="480"/>
+ <point x="411" y="547"/>
+ <point x="585" y="700" type="curve" smooth="yes"/>
+ <point x="766" y="859"/>
+ <point x="925" y="1048"/>
+ <point x="925" y="1190" type="curve" smooth="yes"/>
+ <point x="925" y="1372"/>
+ <point x="777" y="1485"/>
+ <point x="575" y="1485" type="curve" smooth="yes"/>
+ <point x="366" y="1485"/>
+ <point x="190" y="1372"/>
+ <point x="190" y="1160" type="curve" smooth="yes"/>
+ <point x="190" y="1000"/>
+ <point x="407" y="785"/>
+ <point x="590" y="540" type="curve" smooth="yes"/>
+ <point x="859" y="179"/>
+ <point x="1038" y="-25"/>
+ <point x="1090" y="-25" type="curve" smooth="yes"/>
+ <point x="1125" y="-25"/>
+ <point x="1253" y="58"/>
+ <point x="1290" y="90" type="curve"/>
+ <point x="1195" y="130"/>
+ <point x="1060" y="305"/>
+ <point x="785" y="680" type="curve" smooth="yes"/>
+ <point x="619" y="906"/>
+ <point x="420" y="1085"/>
+ <point x="420" y="1170" type="curve" smooth="yes"/>
+ <point x="420" y="1241"/>
+ <point x="483" y="1310"/>
+ <point x="560" y="1310" type="curve" smooth="yes"/>
+ <point x="640" y="1310"/>
+ <point x="695" y="1254"/>
+ <point x="695" y="1175" type="curve" smooth="yes"/>
+ <point x="695" y="1106"/>
+ <point x="628" y="1001"/>
+ <point x="455" y="840" type="curve" smooth="yes"/>
+ <point x="251" y="651"/>
+ <point x="90" y="527"/>
+ <point x="90" y="344" type="curve" smooth="yes"/>
+ <point x="90" y="121"/>
+ <point x="242" y="-25"/>
+ <point x="525" y="-25" type="curve" smooth="yes"/>
+ <point x="808" y="-25"/>
+ <point x="1117" y="264"/>
+ <point x="1195" y="425" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetassocuids.ufo/glyphs/A_pos.glif b/tests/reference/ufo/psfsetassocuids.ufo/glyphs/A_pos.glif
new file mode 100644
index 0000000..61494e8
--- /dev/null
+++ b/tests/reference/ufo/psfsetassocuids.ufo/glyphs/A_pos.glif
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="Apos" format="2">
+ <advance width="625"/>
+ <unicode hex="0027"/>
+ <outline>
+ <contour>
+ <point x="400" y="1045" type="line"/>
+ <point x="405" y="1186"/>
+ <point x="406" y="1339"/>
+ <point x="435" y="1585" type="curve"/>
+ <point x="190" y="1585" type="line"/>
+ <point x="221" y="1339"/>
+ <point x="221" y="1186"/>
+ <point x="225" y="1045" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetassocuids.ufo/glyphs/A_sterisk.glif b/tests/reference/ufo/psfsetassocuids.ufo/glyphs/A_sterisk.glif
new file mode 100644
index 0000000..ed9d25e
--- /dev/null
+++ b/tests/reference/ufo/psfsetassocuids.ufo/glyphs/A_sterisk.glif
@@ -0,0 +1,51 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="Asterisk" format="2">
+ <advance width="1040"/>
+ <unicode hex="002A"/>
+ <outline>
+ <contour>
+ <point x="827" y="1493" type="line"/>
+ <point x="747" y="1426"/>
+ <point x="679" y="1367"/>
+ <point x="594" y="1308" type="curve"/>
+ <point x="599" y="1405"/>
+ <point x="609" y="1486"/>
+ <point x="624" y="1600" type="curve"/>
+ <point x="425" y="1600" type="line"/>
+ <point x="444" y="1497"/>
+ <point x="460" y="1412"/>
+ <point x="468" y="1308" type="curve"/>
+ <point x="383" y="1360"/>
+ <point x="312" y="1408"/>
+ <point x="228" y="1476" type="curve"/>
+ <point x="126" y="1306" type="line"/>
+ <point x="231" y="1271"/>
+ <point x="331" y="1234"/>
+ <point x="412" y="1196" type="curve"/>
+ <point x="328" y="1153"/>
+ <point x="243" y="1120"/>
+ <point x="136" y="1077" type="curve"/>
+ <point x="237" y="897" type="line"/>
+ <point x="316" y="968"/>
+ <point x="382" y="1026"/>
+ <point x="466" y="1087" type="curve"/>
+ <point x="459" y="983"/>
+ <point x="449" y="896"/>
+ <point x="431" y="793" type="curve"/>
+ <point x="632" y="793" type="line"/>
+ <point x="610" y="906"/>
+ <point x="602" y="987"/>
+ <point x="593" y="1084" type="curve"/>
+ <point x="682" y="1027"/>
+ <point x="747" y="981"/>
+ <point x="830" y="914" type="curve"/>
+ <point x="936" y="1089" type="line"/>
+ <point x="827" y="1127"/>
+ <point x="743" y="1155"/>
+ <point x="651" y="1196" type="curve"/>
+ <point x="738" y="1241"/>
+ <point x="820" y="1277"/>
+ <point x="924" y="1321" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetassocuids.ufo/glyphs/A_tS_gn.glif b/tests/reference/ufo/psfsetassocuids.ufo/glyphs/A_tS_gn.glif
new file mode 100644
index 0000000..47fee96
--- /dev/null
+++ b/tests/reference/ufo/psfsetassocuids.ufo/glyphs/A_tS_gn.glif
@@ -0,0 +1,80 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="AtSgn" format="2">
+ <advance width="1742"/>
+ <unicode hex="0040"/>
+ <outline>
+ <contour>
+ <point x="1140" y="10" type="line"/>
+ <point x="1077" y="-34"/>
+ <point x="988" y="-60"/>
+ <point x="895" y="-60" type="curve" smooth="yes"/>
+ <point x="558" y="-60"/>
+ <point x="290" y="204"/>
+ <point x="290" y="605" type="curve" smooth="yes"/>
+ <point x="290" y="973"/>
+ <point x="557" y="1240"/>
+ <point x="895" y="1240" type="curve" smooth="yes"/>
+ <point x="1278" y="1240"/>
+ <point x="1460" y="992"/>
+ <point x="1460" y="670" type="curve" smooth="yes"/>
+ <point x="1460" y="452"/>
+ <point x="1363" y="335"/>
+ <point x="1305" y="335" type="curve" smooth="yes"/>
+ <point x="1256" y="335"/>
+ <point x="1220" y="430"/>
+ <point x="1220" y="650" type="curve" smooth="yes"/>
+ <point x="1220" y="980" type="line"/>
+ <point x="1133" y="1015"/>
+ <point x="986" y="1040"/>
+ <point x="905" y="1040" type="curve" smooth="yes"/>
+ <point x="741" y="1040"/>
+ <point x="618" y="961"/>
+ <point x="535" y="825" type="curve" smooth="yes"/>
+ <point x="488" y="746"/>
+ <point x="460" y="653"/>
+ <point x="460" y="530" type="curve" smooth="yes"/>
+ <point x="460" y="304"/>
+ <point x="606" y="163"/>
+ <point x="740" y="163" type="curve" smooth="yes"/>
+ <point x="867" y="163"/>
+ <point x="1013" y="331"/>
+ <point x="1065" y="455" type="curve"/>
+ <point x="1075" y="287"/>
+ <point x="1153" y="160"/>
+ <point x="1275" y="160" type="curve" smooth="yes"/>
+ <point x="1450" y="160"/>
+ <point x="1650" y="358"/>
+ <point x="1650" y="700" type="curve" smooth="yes"/>
+ <point x="1650" y="1137"/>
+ <point x="1342" y="1425"/>
+ <point x="905" y="1425" type="curve" smooth="yes"/>
+ <point x="480" y="1425"/>
+ <point x="90" y="1136"/>
+ <point x="90" y="575" type="curve" smooth="yes"/>
+ <point x="90" y="38"/>
+ <point x="479" y="-245"/>
+ <point x="880" y="-245" type="curve" smooth="yes"/>
+ <point x="1015" y="-245"/>
+ <point x="1175" y="-198"/>
+ <point x="1275" y="-128" type="curve"/>
+ </contour>
+ <contour>
+ <point x="1020" y="710" type="line"/>
+ <point x="988" y="572"/>
+ <point x="863" y="350"/>
+ <point x="773" y="350" type="curve" smooth="yes"/>
+ <point x="701" y="350"/>
+ <point x="660" y="428"/>
+ <point x="660" y="575" type="curve" smooth="yes"/>
+ <point x="660" y="652"/>
+ <point x="682" y="737"/>
+ <point x="720" y="786" type="curve" smooth="yes"/>
+ <point x="756" y="831"/>
+ <point x="807" y="855"/>
+ <point x="875" y="855" type="curve" smooth="yes"/>
+ <point x="949" y="855"/>
+ <point x="987" y="836"/>
+ <point x="1020" y="820" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetassocuids.ufo/glyphs/C_ircumA_ccent.glif b/tests/reference/ufo/psfsetassocuids.ufo/glyphs/C_ircumA_ccent.glif
new file mode 100644
index 0000000..c8db8e3
--- /dev/null
+++ b/tests/reference/ufo/psfsetassocuids.ufo/glyphs/C_ircumA_ccent.glif
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="CircumAccent" format="2">
+ <advance width="880"/>
+ <unicode hex="005E"/>
+ <anchor x="440" y="1635" name="U"/>
+ <outline>
+ <contour>
+ <point x="888" y="1200" type="line"/>
+ <point x="598" y="1600" type="line"/>
+ <point x="298" y="1600" type="line"/>
+ <point x="8" y="1200" type="line"/>
+ <point x="248" y="1200" type="line"/>
+ <point x="448" y="1430" type="line"/>
+ <point x="648" y="1200" type="line"/>
+ </contour>
+ </outline>
+ <lib>
+ <dict>
+ <key>org.sil.assocUIDs</key>
+ <array>
+ <string>003E</string>
+ </array>
+ </dict>
+ </lib>
+</glyph>
diff --git a/tests/reference/ufo/psfsetassocuids.ufo/glyphs/C_olon.glif b/tests/reference/ufo/psfsetassocuids.ufo/glyphs/C_olon.glif
new file mode 100644
index 0000000..ae4801a
--- /dev/null
+++ b/tests/reference/ufo/psfsetassocuids.ufo/glyphs/C_olon.glif
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="Colon" format="2">
+ <advance width="710"/>
+ <unicode hex="003A"/>
+ <outline>
+ <contour>
+ <point x="200" y="150" type="curve" smooth="yes"/>
+ <point x="200" y="46"/>
+ <point x="274" y="-25"/>
+ <point x="375" y="-25" type="curve" smooth="yes"/>
+ <point x="477" y="-25"/>
+ <point x="550" y="46"/>
+ <point x="550" y="150" type="curve" smooth="yes"/>
+ <point x="550" y="252"/>
+ <point x="477" y="325"/>
+ <point x="375" y="325" type="curve" smooth="yes"/>
+ <point x="274" y="325"/>
+ <point x="200" y="252"/>
+ </contour>
+ <contour>
+ <point x="200" y="750" type="curve" smooth="yes"/>
+ <point x="200" y="646"/>
+ <point x="274" y="575"/>
+ <point x="375" y="575" type="curve" smooth="yes"/>
+ <point x="477" y="575"/>
+ <point x="550" y="646"/>
+ <point x="550" y="750" type="curve" smooth="yes"/>
+ <point x="550" y="852"/>
+ <point x="477" y="925"/>
+ <point x="375" y="925" type="curve" smooth="yes"/>
+ <point x="274" y="925"/>
+ <point x="200" y="852"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetassocuids.ufo/glyphs/C_ombA_cute.glif b/tests/reference/ufo/psfsetassocuids.ufo/glyphs/C_ombA_cute.glif
new file mode 100644
index 0000000..5574223
--- /dev/null
+++ b/tests/reference/ufo/psfsetassocuids.ufo/glyphs/C_ombA_cute.glif
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="CombAcute" format="2">
+ <unicode hex="0301"/>
+ <anchor x="-600" y="1635" name="U"/>
+ <anchor x="-540" y="1100" name="_U"/>
+ <outline>
+ <contour>
+ <point x="-470" y="1600" type="line"/>
+ <point x="-760" y="1200" type="line"/>
+ <point x="-520" y="1200" type="line"/>
+ <point x="-120" y="1600" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetassocuids.ufo/glyphs/C_ombC_ircum.glif b/tests/reference/ufo/psfsetassocuids.ufo/glyphs/C_ombC_ircum.glif
new file mode 100644
index 0000000..ca30491
--- /dev/null
+++ b/tests/reference/ufo/psfsetassocuids.ufo/glyphs/C_ombC_ircum.glif
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="CombCircum" format="2">
+ <unicode hex="0302"/>
+ <anchor x="-588" y="1635" name="U"/>
+ <anchor x="-580" y="1100" name="_U"/>
+ <outline>
+ <contour>
+ <point x="-140" y="1200" type="line"/>
+ <point x="-430" y="1600" type="line"/>
+ <point x="-730" y="1600" type="line"/>
+ <point x="-1020" y="1200" type="line"/>
+ <point x="-780" y="1200" type="line"/>
+ <point x="-580" y="1430" type="line"/>
+ <point x="-380" y="1200" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetassocuids.ufo/glyphs/C_ombD_iaer.glif b/tests/reference/ufo/psfsetassocuids.ufo/glyphs/C_ombD_iaer.glif
new file mode 100644
index 0000000..5a15368
--- /dev/null
+++ b/tests/reference/ufo/psfsetassocuids.ufo/glyphs/C_ombD_iaer.glif
@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="CombDiaer" format="2">
+ <unicode hex="0308"/>
+ <anchor x="-580" y="1585" name="U"/>
+ <anchor x="-580" y="1100" name="_U"/>
+ <outline>
+ <contour>
+ <point x="-510" y="1385" type="curve" smooth="yes"/>
+ <point x="-510" y="1281"/>
+ <point x="-436" y="1210"/>
+ <point x="-335" y="1210" type="curve" smooth="yes"/>
+ <point x="-233" y="1210"/>
+ <point x="-160" y="1281"/>
+ <point x="-160" y="1385" type="curve" smooth="yes"/>
+ <point x="-160" y="1487"/>
+ <point x="-233" y="1560"/>
+ <point x="-335" y="1560" type="curve" smooth="yes"/>
+ <point x="-436" y="1560"/>
+ <point x="-510" y="1487"/>
+ </contour>
+ <contour>
+ <point x="-1000" y="1385" type="curve" smooth="yes"/>
+ <point x="-1000" y="1281"/>
+ <point x="-926" y="1210"/>
+ <point x="-825" y="1210" type="curve" smooth="yes"/>
+ <point x="-723" y="1210"/>
+ <point x="-650" y="1281"/>
+ <point x="-650" y="1385" type="curve" smooth="yes"/>
+ <point x="-650" y="1487"/>
+ <point x="-723" y="1560"/>
+ <point x="-825" y="1560" type="curve" smooth="yes"/>
+ <point x="-926" y="1560"/>
+ <point x="-1000" y="1487"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetassocuids.ufo/glyphs/C_ombG_rave.glif b/tests/reference/ufo/psfsetassocuids.ufo/glyphs/C_ombG_rave.glif
new file mode 100644
index 0000000..33bed8f
--- /dev/null
+++ b/tests/reference/ufo/psfsetassocuids.ufo/glyphs/C_ombG_rave.glif
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="CombGrave" format="2">
+ <unicode hex="0300"/>
+ <anchor x="-590" y="1635" name="U"/>
+ <anchor x="-630" y="1100" name="_U"/>
+ <outline>
+ <contour>
+ <point x="-1050" y="1600" type="line"/>
+ <point x="-650" y="1200" type="line"/>
+ <point x="-410" y="1200" type="line"/>
+ <point x="-700" y="1600" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetassocuids.ufo/glyphs/C_ombR_ingA_bv.glif b/tests/reference/ufo/psfsetassocuids.ufo/glyphs/C_ombR_ingA_bv.glif
new file mode 100644
index 0000000..7e03146
--- /dev/null
+++ b/tests/reference/ufo/psfsetassocuids.ufo/glyphs/C_ombR_ingA_bv.glif
@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="CombRingAbv" format="2">
+ <unicode hex="030A"/>
+ <anchor x="-570" y="1635" name="U"/>
+ <anchor x="-572" y="1100" name="_U"/>
+ <outline>
+ <contour>
+ <point x="-475" y="1400" type="curve" smooth="yes"/>
+ <point x="-475" y="1345"/>
+ <point x="-515" y="1305"/>
+ <point x="-570" y="1305" type="curve" smooth="yes"/>
+ <point x="-625" y="1305"/>
+ <point x="-665" y="1345"/>
+ <point x="-665" y="1400" type="curve" smooth="yes"/>
+ <point x="-665" y="1455"/>
+ <point x="-625" y="1495"/>
+ <point x="-570" y="1495" type="curve" smooth="yes"/>
+ <point x="-515" y="1495"/>
+ <point x="-475" y="1455"/>
+ </contour>
+ <contour>
+ <point x="-815" y="1400" type="curve" smooth="yes"/>
+ <point x="-815" y="1260"/>
+ <point x="-710" y="1160"/>
+ <point x="-570" y="1160" type="curve" smooth="yes"/>
+ <point x="-430" y="1160"/>
+ <point x="-325" y="1260"/>
+ <point x="-325" y="1400" type="curve" smooth="yes"/>
+ <point x="-325" y="1540"/>
+ <point x="-430" y="1640"/>
+ <point x="-570" y="1640" type="curve" smooth="yes"/>
+ <point x="-710" y="1640"/>
+ <point x="-815" y="1540"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetassocuids.ufo/glyphs/C_ombT_ilde.glif b/tests/reference/ufo/psfsetassocuids.ufo/glyphs/C_ombT_ilde.glif
new file mode 100644
index 0000000..ee23af5
--- /dev/null
+++ b/tests/reference/ufo/psfsetassocuids.ufo/glyphs/C_ombT_ilde.glif
@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="CombTilde" format="2">
+ <unicode hex="0303"/>
+ <anchor x="-580" y="1490" name="U"/>
+ <anchor x="-580" y="1100" name="_U"/>
+ <outline>
+ <contour>
+ <point x="-830" y="1190" type="line"/>
+ <point x="-824" y="1232"/>
+ <point x="-803" y="1280"/>
+ <point x="-753" y="1280" type="curve" smooth="yes"/>
+ <point x="-710" y="1280"/>
+ <point x="-653" y="1264"/>
+ <point x="-570" y="1229" type="curve" smooth="yes"/>
+ <point x="-500" y="1199"/>
+ <point x="-448" y="1180"/>
+ <point x="-386" y="1180" type="curve" smooth="yes"/>
+ <point x="-250" y="1180"/>
+ <point x="-155" y="1307"/>
+ <point x="-155" y="1480" type="curve"/>
+ <point x="-310" y="1480" type="line"/>
+ <point x="-318" y="1438"/>
+ <point x="-340" y="1390"/>
+ <point x="-387" y="1390" type="curve" smooth="yes"/>
+ <point x="-435" y="1390"/>
+ <point x="-472" y="1408"/>
+ <point x="-550" y="1437" type="curve" smooth="yes"/>
+ <point x="-629" y="1466"/>
+ <point x="-695" y="1490"/>
+ <point x="-760" y="1490" type="curve" smooth="yes"/>
+ <point x="-892" y="1490"/>
+ <point x="-985" y="1349"/>
+ <point x="-985" y="1190" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetassocuids.ufo/glyphs/C_omma.glif b/tests/reference/ufo/psfsetassocuids.ufo/glyphs/C_omma.glif
new file mode 100644
index 0000000..9d4845e
--- /dev/null
+++ b/tests/reference/ufo/psfsetassocuids.ufo/glyphs/C_omma.glif
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="Comma" format="2">
+ <advance width="665"/>
+ <unicode hex="002C"/>
+ <outline>
+ <contour>
+ <point x="185" y="50" type="line"/>
+ <point x="345" y="50" type="line"/>
+ <point x="345" y="-34"/>
+ <point x="290" y="-153"/>
+ <point x="185" y="-265" type="curve"/>
+ <point x="330" y="-335" type="line"/>
+ <point x="454" y="-228"/>
+ <point x="560" y="-49"/>
+ <point x="560" y="130" type="curve" smooth="yes"/>
+ <point x="560" y="254"/>
+ <point x="489" y="340"/>
+ <point x="375" y="340" type="curve" smooth="yes"/>
+ <point x="262" y="340"/>
+ <point x="185" y="255"/>
+ <point x="185" y="180" type="curve" smooth="yes"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetassocuids.ufo/glyphs/D_igitE_ight.glif b/tests/reference/ufo/psfsetassocuids.ufo/glyphs/D_igitE_ight.glif
new file mode 100644
index 0000000..a59fff4
--- /dev/null
+++ b/tests/reference/ufo/psfsetassocuids.ufo/glyphs/D_igitE_ight.glif
@@ -0,0 +1,63 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="DigitEight" format="2">
+ <advance width="1200"/>
+ <unicode hex="0038"/>
+ <anchor x="600" y="-100" name="L"/>
+ <anchor x="600" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="600" y="-25" type="curve" smooth="yes"/>
+ <point x="877" y="-25"/>
+ <point x="1130" y="144"/>
+ <point x="1130" y="415" type="curve" smooth="yes"/>
+ <point x="1130" y="641"/>
+ <point x="985" y="739"/>
+ <point x="875" y="795" type="curve"/>
+ <point x="953" y="841"/>
+ <point x="1060" y="923"/>
+ <point x="1060" y="1105" type="curve" smooth="yes"/>
+ <point x="1060" y="1350"/>
+ <point x="860" y="1485"/>
+ <point x="610" y="1485" type="curve" smooth="yes"/>
+ <point x="361" y="1485"/>
+ <point x="140" y="1350"/>
+ <point x="140" y="1105" type="curve" smooth="yes"/>
+ <point x="140" y="923"/>
+ <point x="252" y="838"/>
+ <point x="330" y="795" type="curve"/>
+ <point x="201" y="725"/>
+ <point x="70" y="631"/>
+ <point x="70" y="405" type="curve" smooth="yes"/>
+ <point x="70" y="134"/>
+ <point x="324" y="-25"/>
+ </contour>
+ <contour>
+ <point x="810" y="1100" type="curve" smooth="yes"/>
+ <point x="810" y="974"/>
+ <point x="733" y="895"/>
+ <point x="600" y="895" type="curve" smooth="yes"/>
+ <point x="467" y="895"/>
+ <point x="390" y="974"/>
+ <point x="390" y="1100" type="curve" smooth="yes"/>
+ <point x="390" y="1217"/>
+ <point x="477" y="1290"/>
+ <point x="600" y="1290" type="curve" smooth="yes"/>
+ <point x="743" y="1290"/>
+ <point x="810" y="1207"/>
+ </contour>
+ <contour>
+ <point x="865" y="435" type="curve" smooth="yes"/>
+ <point x="865" y="300"/>
+ <point x="768" y="185"/>
+ <point x="600" y="185" type="curve" smooth="yes"/>
+ <point x="440" y="185"/>
+ <point x="335" y="300"/>
+ <point x="335" y="435" type="curve" smooth="yes"/>
+ <point x="335" y="582"/>
+ <point x="450" y="680"/>
+ <point x="600" y="680" type="curve" smooth="yes"/>
+ <point x="748" y="680"/>
+ <point x="865" y="582"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetassocuids.ufo/glyphs/D_igitF_ive.glif b/tests/reference/ufo/psfsetassocuids.ufo/glyphs/D_igitF_ive.glif
new file mode 100644
index 0000000..102780d
--- /dev/null
+++ b/tests/reference/ufo/psfsetassocuids.ufo/glyphs/D_igitF_ive.glif
@@ -0,0 +1,44 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="DigitFive" format="2">
+ <advance width="1200"/>
+ <unicode hex="0035"/>
+ <anchor x="600" y="-100" name="L"/>
+ <anchor x="600" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="175" y="645" type="line"/>
+ <point x="299" y="693"/>
+ <point x="404" y="710"/>
+ <point x="510" y="710" type="curve" smooth="yes"/>
+ <point x="670" y="710"/>
+ <point x="810" y="632"/>
+ <point x="810" y="470" type="curve" smooth="yes"/>
+ <point x="810" y="318"/>
+ <point x="690" y="215"/>
+ <point x="530" y="215" type="curve" smooth="yes"/>
+ <point x="390" y="215"/>
+ <point x="274" y="252"/>
+ <point x="140" y="360" type="curve"/>
+ <point x="100" y="80" type="line"/>
+ <point x="225" y="2"/>
+ <point x="365" y="-25"/>
+ <point x="520" y="-25" type="curve" smooth="yes"/>
+ <point x="833" y="-25"/>
+ <point x="1090" y="163"/>
+ <point x="1090" y="475" type="curve" smooth="yes"/>
+ <point x="1090" y="752"/>
+ <point x="882" y="930"/>
+ <point x="605" y="930" type="curve" smooth="yes"/>
+ <point x="543" y="930"/>
+ <point x="468" y="911"/>
+ <point x="435" y="895" type="curve"/>
+ <point x="435" y="1215" type="line"/>
+ <point x="765" y="1215" type="line" smooth="yes"/>
+ <point x="849" y="1215"/>
+ <point x="955" y="1211"/>
+ <point x="1030" y="1195" type="curve"/>
+ <point x="1030" y="1460" type="line"/>
+ <point x="175" y="1460" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetassocuids.ufo/glyphs/D_igitF_our.glif b/tests/reference/ufo/psfsetassocuids.ufo/glyphs/D_igitF_our.glif
new file mode 100644
index 0000000..7d2cbe6
--- /dev/null
+++ b/tests/reference/ufo/psfsetassocuids.ufo/glyphs/D_igitF_our.glif
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="DigitFour" format="2">
+ <advance width="1200"/>
+ <unicode hex="0034"/>
+ <anchor x="607" y="-100" name="L"/>
+ <anchor x="607" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="1155" y="345" type="line"/>
+ <point x="1155" y="570" type="line"/>
+ <point x="995" y="570" type="line"/>
+ <point x="995" y="1460" type="line"/>
+ <point x="695" y="1460" type="line"/>
+ <point x="60" y="570" type="line"/>
+ <point x="60" y="345" type="line"/>
+ <point x="730" y="345" type="line"/>
+ <point x="730" y="0" type="line"/>
+ <point x="995" y="0" type="line"/>
+ <point x="995" y="345" type="line"/>
+ </contour>
+ <contour>
+ <point x="730" y="1145" type="line"/>
+ <point x="730" y="570" type="line"/>
+ <point x="305" y="570" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetassocuids.ufo/glyphs/D_igitN_ine.glif b/tests/reference/ufo/psfsetassocuids.ufo/glyphs/D_igitN_ine.glif
new file mode 100644
index 0000000..b1e153b
--- /dev/null
+++ b/tests/reference/ufo/psfsetassocuids.ufo/glyphs/D_igitN_ine.glif
@@ -0,0 +1,49 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="DigitNine" format="2">
+ <advance width="1200"/>
+ <unicode hex="0039"/>
+ <anchor x="600" y="-100" name="L"/>
+ <anchor x="600" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="154" y="65" type="line"/>
+ <point x="248" y="5"/>
+ <point x="364" y="-25"/>
+ <point x="492" y="-25" type="curve" smooth="yes"/>
+ <point x="967" y="-25"/>
+ <point x="1135" y="411"/>
+ <point x="1135" y="780" type="curve" smooth="yes"/>
+ <point x="1135" y="1150"/>
+ <point x="977" y="1485"/>
+ <point x="589" y="1485" type="curve" smooth="yes"/>
+ <point x="310" y="1485"/>
+ <point x="70" y="1300"/>
+ <point x="70" y="1002" type="curve" smooth="yes"/>
+ <point x="70" y="763"/>
+ <point x="272" y="576"/>
+ <point x="550" y="576" type="curve" smooth="yes"/>
+ <point x="741" y="576"/>
+ <point x="913" y="707"/>
+ <point x="1010" y="868" type="curve"/>
+ <point x="939" y="991" type="line"/>
+ <point x="865" y="877"/>
+ <point x="729" y="790"/>
+ <point x="574" y="790" type="curve" smooth="yes"/>
+ <point x="425" y="790"/>
+ <point x="326" y="890"/>
+ <point x="326" y="1036" type="curve" smooth="yes"/>
+ <point x="326" y="1153"/>
+ <point x="425" y="1250"/>
+ <point x="573" y="1250" type="curve" smooth="yes"/>
+ <point x="773" y="1250"/>
+ <point x="870" y="1102"/>
+ <point x="870" y="813" type="curve" smooth="yes"/>
+ <point x="870" y="326"/>
+ <point x="699" y="210"/>
+ <point x="502" y="210" type="curve" smooth="yes"/>
+ <point x="406" y="210"/>
+ <point x="294" y="234"/>
+ <point x="208" y="320" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetassocuids.ufo/glyphs/D_igitO_ne.glif b/tests/reference/ufo/psfsetassocuids.ufo/glyphs/D_igitO_ne.glif
new file mode 100644
index 0000000..c744b9f
--- /dev/null
+++ b/tests/reference/ufo/psfsetassocuids.ufo/glyphs/D_igitO_ne.glif
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="DigitOne" format="2">
+ <advance width="1200"/>
+ <unicode hex="0031"/>
+ <anchor x="600" y="-100" name="L"/>
+ <anchor x="600" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="1075" y="0" type="line"/>
+ <point x="1075" y="235" type="line"/>
+ <point x="767" y="235" type="line"/>
+ <point x="767" y="1460" type="line"/>
+ <point x="492" y="1460" type="line"/>
+ <point x="177" y="1278" type="line"/>
+ <point x="212" y="1018" type="line"/>
+ <point x="492" y="1170" type="line"/>
+ <point x="492" y="235" type="line"/>
+ <point x="185" y="235" type="line"/>
+ <point x="185" y="0" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetassocuids.ufo/glyphs/D_igitS_even.glif b/tests/reference/ufo/psfsetassocuids.ufo/glyphs/D_igitS_even.glif
new file mode 100644
index 0000000..63fb1c4
--- /dev/null
+++ b/tests/reference/ufo/psfsetassocuids.ufo/glyphs/D_igitS_even.glif
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="DigitSeven" format="2">
+ <advance width="1200"/>
+ <unicode hex="0037"/>
+ <anchor x="600" y="-100" name="L"/>
+ <anchor x="600" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="520" y="0" type="line"/>
+ <point x="649" y="459"/>
+ <point x="834" y="855"/>
+ <point x="1130" y="1260" type="curve"/>
+ <point x="1130" y="1460" type="line"/>
+ <point x="100" y="1460" type="line"/>
+ <point x="100" y="1195" type="line"/>
+ <point x="176" y="1211"/>
+ <point x="292" y="1215"/>
+ <point x="480" y="1215" type="curve" smooth="yes"/>
+ <point x="800" y="1215" type="line"/>
+ <point x="542" y="842"/>
+ <point x="409" y="566"/>
+ <point x="235" y="0" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetassocuids.ufo/glyphs/D_igitS_ix.glif b/tests/reference/ufo/psfsetassocuids.ufo/glyphs/D_igitS_ix.glif
new file mode 100644
index 0000000..7526cc6
--- /dev/null
+++ b/tests/reference/ufo/psfsetassocuids.ufo/glyphs/D_igitS_ix.glif
@@ -0,0 +1,49 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="DigitSix" format="2">
+ <advance width="1200"/>
+ <unicode hex="0036"/>
+ <anchor x="610" y="-100" name="L"/>
+ <anchor x="610" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="1073" y="1395" type="line"/>
+ <point x="969" y="1465"/>
+ <point x="873" y="1485"/>
+ <point x="735" y="1485" type="curve" smooth="yes"/>
+ <point x="260" y="1485"/>
+ <point x="90" y="1069"/>
+ <point x="90" y="680" type="curve" smooth="yes"/>
+ <point x="90" y="223"/>
+ <point x="297" y="-25"/>
+ <point x="652" y="-25" type="curve" smooth="yes"/>
+ <point x="955" y="-25"/>
+ <point x="1155" y="179"/>
+ <point x="1155" y="470" type="curve" smooth="yes"/>
+ <point x="1155" y="729"/>
+ <point x="963" y="925"/>
+ <point x="675" y="925" type="curve" smooth="yes"/>
+ <point x="484" y="925"/>
+ <point x="338" y="810"/>
+ <point x="225" y="655" type="curve"/>
+ <point x="290" y="540" type="line"/>
+ <point x="372" y="643"/>
+ <point x="500" y="710"/>
+ <point x="655" y="710" type="curve" smooth="yes"/>
+ <point x="814" y="710"/>
+ <point x="900" y="601"/>
+ <point x="900" y="455" type="curve" smooth="yes"/>
+ <point x="900" y="329"/>
+ <point x="803" y="210"/>
+ <point x="656" y="210" type="curve" smooth="yes"/>
+ <point x="474" y="210"/>
+ <point x="355" y="386"/>
+ <point x="355" y="645" type="curve" smooth="yes"/>
+ <point x="355" y="1132"/>
+ <point x="528" y="1250"/>
+ <point x="725" y="1250" type="curve" smooth="yes"/>
+ <point x="821" y="1250"/>
+ <point x="923" y="1226"/>
+ <point x="1009" y="1140" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetassocuids.ufo/glyphs/D_igitT_hree.glif b/tests/reference/ufo/psfsetassocuids.ufo/glyphs/D_igitT_hree.glif
new file mode 100644
index 0000000..883bd62
--- /dev/null
+++ b/tests/reference/ufo/psfsetassocuids.ufo/glyphs/D_igitT_hree.glif
@@ -0,0 +1,52 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="DigitThree" format="2">
+ <advance width="1200"/>
+ <unicode hex="0033"/>
+ <anchor x="600" y="-100" name="L"/>
+ <anchor x="600" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="390" y="885" type="line"/>
+ <point x="390" y="645" type="line"/>
+ <point x="480" y="645" type="line" smooth="yes"/>
+ <point x="706" y="645"/>
+ <point x="835" y="548"/>
+ <point x="835" y="425" type="curve" smooth="yes"/>
+ <point x="835" y="291"/>
+ <point x="708" y="210"/>
+ <point x="565" y="210" type="curve" smooth="yes"/>
+ <point x="405" y="210"/>
+ <point x="244" y="282"/>
+ <point x="135" y="405" type="curve"/>
+ <point x="100" y="130" type="line"/>
+ <point x="205" y="32"/>
+ <point x="368" y="-25"/>
+ <point x="545" y="-25" type="curve" smooth="yes"/>
+ <point x="874" y="-25"/>
+ <point x="1120" y="170"/>
+ <point x="1120" y="405" type="curve" smooth="yes"/>
+ <point x="1120" y="672"/>
+ <point x="892" y="756"/>
+ <point x="750" y="780" type="curve"/>
+ <point x="892" y="809"/>
+ <point x="1070" y="957"/>
+ <point x="1070" y="1140" type="curve" smooth="yes"/>
+ <point x="1070" y="1354"/>
+ <point x="868" y="1485"/>
+ <point x="580" y="1485" type="curve" smooth="yes"/>
+ <point x="413" y="1485"/>
+ <point x="240" y="1416"/>
+ <point x="160" y="1325" type="curve"/>
+ <point x="195" y="1095" type="line"/>
+ <point x="308" y="1211"/>
+ <point x="436" y="1250"/>
+ <point x="590" y="1250" type="curve" smooth="yes"/>
+ <point x="689" y="1250"/>
+ <point x="791" y="1193"/>
+ <point x="791" y="1102" type="curve" smooth="yes"/>
+ <point x="791" y="994"/>
+ <point x="662" y="885"/>
+ <point x="480" y="885" type="curve" smooth="yes"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetassocuids.ufo/glyphs/D_igitT_wo.glif b/tests/reference/ufo/psfsetassocuids.ufo/glyphs/D_igitT_wo.glif
new file mode 100644
index 0000000..1d73732
--- /dev/null
+++ b/tests/reference/ufo/psfsetassocuids.ufo/glyphs/D_igitT_wo.glif
@@ -0,0 +1,37 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="DigitTwo" format="2">
+ <advance width="1200"/>
+ <unicode hex="0032"/>
+ <anchor x="600" y="-100" name="L"/>
+ <anchor x="560" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="1090" y="260" type="line"/>
+ <point x="1010" y="246"/>
+ <point x="942" y="245"/>
+ <point x="745" y="245" type="curve" smooth="yes"/>
+ <point x="480" y="245" type="line"/>
+ <point x="699" y="422"/>
+ <point x="1046" y="739"/>
+ <point x="1046" y="1065" type="curve" smooth="yes"/>
+ <point x="1046" y="1323"/>
+ <point x="850" y="1485"/>
+ <point x="560" y="1485" type="curve" smooth="yes"/>
+ <point x="391" y="1485"/>
+ <point x="196" y="1402"/>
+ <point x="105" y="1290" type="curve"/>
+ <point x="170" y="1050" type="line"/>
+ <point x="259" y="1158"/>
+ <point x="412" y="1235"/>
+ <point x="535" y="1235" type="curve" smooth="yes"/>
+ <point x="688" y="1235"/>
+ <point x="758" y="1133"/>
+ <point x="758" y="1015" type="curve" smooth="yes"/>
+ <point x="758" y="758"/>
+ <point x="381" y="415"/>
+ <point x="110" y="220" type="curve"/>
+ <point x="110" y="0" type="line"/>
+ <point x="1090" y="0" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetassocuids.ufo/glyphs/D_igitZ_ero.glif b/tests/reference/ufo/psfsetassocuids.ufo/glyphs/D_igitZ_ero.glif
new file mode 100644
index 0000000..01f4532
--- /dev/null
+++ b/tests/reference/ufo/psfsetassocuids.ufo/glyphs/D_igitZ_ero.glif
@@ -0,0 +1,37 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="DigitZero" format="2">
+ <advance width="1200"/>
+ <unicode hex="0030"/>
+ <anchor x="605" y="-100" name="L"/>
+ <anchor x="605" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="850" y="715" type="curve" smooth="yes"/>
+ <point x="850" y="368"/>
+ <point x="762" y="205"/>
+ <point x="600" y="205" type="curve" smooth="yes"/>
+ <point x="432" y="205"/>
+ <point x="350" y="375"/>
+ <point x="350" y="745" type="curve" smooth="yes"/>
+ <point x="350" y="1093"/>
+ <point x="437" y="1255"/>
+ <point x="600" y="1255" type="curve" smooth="yes"/>
+ <point x="772" y="1255"/>
+ <point x="850" y="1086"/>
+ </contour>
+ <contour>
+ <point x="1135" y="740" type="curve" smooth="yes"/>
+ <point x="1135" y="1286"/>
+ <point x="950" y="1485"/>
+ <point x="610" y="1485" type="curve" smooth="yes"/>
+ <point x="291" y="1485"/>
+ <point x="65" y="1283"/>
+ <point x="65" y="720" type="curve" smooth="yes"/>
+ <point x="65" y="165"/>
+ <point x="271" y="-25"/>
+ <point x="590" y="-25" type="curve" smooth="yes"/>
+ <point x="911" y="-25"/>
+ <point x="1135" y="161"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetassocuids.ufo/glyphs/D_ollarS_gn.glif b/tests/reference/ufo/psfsetassocuids.ufo/glyphs/D_ollarS_gn.glif
new file mode 100644
index 0000000..f8b49cd
--- /dev/null
+++ b/tests/reference/ufo/psfsetassocuids.ufo/glyphs/D_ollarS_gn.glif
@@ -0,0 +1,57 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="DollarSgn" format="2">
+ <advance width="1200"/>
+ <unicode hex="0024"/>
+ <outline>
+ <contour>
+ <point x="1006" y="1316" type="line"/>
+ <point x="886" y="1374"/>
+ <point x="764" y="1389"/>
+ <point x="623" y="1389" type="curve" smooth="yes"/>
+ <point x="317" y="1389"/>
+ <point x="150" y="1203"/>
+ <point x="150" y="1017" type="curve" smooth="yes"/>
+ <point x="150" y="830"/>
+ <point x="275" y="730"/>
+ <point x="540" y="623" type="curve" smooth="yes"/>
+ <point x="802" y="517"/>
+ <point x="851" y="472"/>
+ <point x="851" y="386" type="curve" smooth="yes"/>
+ <point x="851" y="267"/>
+ <point x="744" y="211"/>
+ <point x="586" y="211" type="curve" smooth="yes"/>
+ <point x="440" y="211"/>
+ <point x="297" y="281"/>
+ <point x="195" y="383" type="curve"/>
+ <point x="123" y="124" type="line"/>
+ <point x="216" y="49"/>
+ <point x="388" y="0"/>
+ <point x="586" y="0" type="curve" smooth="yes"/>
+ <point x="847" y="0"/>
+ <point x="1086" y="147"/>
+ <point x="1086" y="414" type="curve" smooth="yes"/>
+ <point x="1086" y="633"/>
+ <point x="927" y="723"/>
+ <point x="679" y="826" type="curve" smooth="yes"/>
+ <point x="431" y="929"/>
+ <point x="385" y="969"/>
+ <point x="385" y="1040" type="curve" smooth="yes"/>
+ <point x="385" y="1132"/>
+ <point x="466" y="1188"/>
+ <point x="613" y="1188" type="curve" smooth="yes"/>
+ <point x="741" y="1188"/>
+ <point x="876" y="1154"/>
+ <point x="949" y="1077" type="curve"/>
+ </contour>
+ <contour>
+ <point x="548" y="1600" type="line"/>
+ <point x="548" y="788" type="line"/>
+ <point x="518" y="726" type="line"/>
+ <point x="518" y="-220" type="line"/>
+ <point x="688" y="-220" type="line"/>
+ <point x="688" y="668" type="line"/>
+ <point x="718" y="734" type="line"/>
+ <point x="718" y="1600" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetassocuids.ufo/glyphs/D_ottedC_irc.glif b/tests/reference/ufo/psfsetassocuids.ufo/glyphs/D_ottedC_irc.glif
new file mode 100644
index 0000000..4cf5cb4
--- /dev/null
+++ b/tests/reference/ufo/psfsetassocuids.ufo/glyphs/D_ottedC_irc.glif
@@ -0,0 +1,235 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="DottedCirc" format="2">
+ <advance width="1106"/>
+ <unicode hex="25CC"/>
+ <anchor x="553" y="0" name="H"/>
+ <anchor x="553" y="-100" name="L"/>
+ <anchor x="810" y="0" name="O"/>
+ <anchor x="553" y="1000" name="U"/>
+ <outline>
+ <contour>
+ <point x="443" y="837" type="curve" smooth="yes"/>
+ <point x="443" y="864"/>
+ <point x="423" y="885"/>
+ <point x="398" y="885" type="curve" smooth="yes"/>
+ <point x="371" y="885"/>
+ <point x="348" y="861"/>
+ <point x="348" y="837" type="curve" smooth="yes"/>
+ <point x="348" y="809"/>
+ <point x="372" y="789"/>
+ <point x="398" y="789" type="curve" smooth="yes"/>
+ <point x="425" y="789"/>
+ <point x="443" y="812"/>
+ </contour>
+ <contour>
+ <point x="758" y="79" type="curve" smooth="yes"/>
+ <point x="758" y="106"/>
+ <point x="736" y="127"/>
+ <point x="710" y="127" type="curve" smooth="yes"/>
+ <point x="685" y="127"/>
+ <point x="662" y="103"/>
+ <point x="662" y="80" type="curve" smooth="yes"/>
+ <point x="662" y="52"/>
+ <point x="686" y="31"/>
+ <point x="710" y="31" type="curve" smooth="yes"/>
+ <point x="737" y="31"/>
+ <point x="758" y="55"/>
+ </contour>
+ <contour>
+ <point x="310" y="749" type="curve" smooth="yes"/>
+ <point x="310" y="775"/>
+ <point x="288" y="796"/>
+ <point x="263" y="796" type="curve" smooth="yes"/>
+ <point x="238" y="796"/>
+ <point x="215" y="774"/>
+ <point x="215" y="747" type="curve" smooth="yes"/>
+ <point x="215" y="722"/>
+ <point x="236" y="701"/>
+ <point x="263" y="701" type="curve" smooth="yes"/>
+ <point x="291" y="701"/>
+ <point x="310" y="720"/>
+ </contour>
+ <contour>
+ <point x="891" y="168" type="curve" smooth="yes"/>
+ <point x="891" y="197"/>
+ <point x="870" y="215"/>
+ <point x="843" y="215" type="curve" smooth="yes"/>
+ <point x="817" y="215"/>
+ <point x="795" y="194"/>
+ <point x="795" y="168" type="curve" smooth="yes"/>
+ <point x="795" y="143"/>
+ <point x="816" y="121"/>
+ <point x="843" y="121" type="curve" smooth="yes"/>
+ <point x="871" y="121"/>
+ <point x="891" y="143"/>
+ </contour>
+ <contour>
+ <point x="222" y="613" type="curve" smooth="yes"/>
+ <point x="222" y="640"/>
+ <point x="199" y="663"/>
+ <point x="173" y="663" type="curve" smooth="yes"/>
+ <point x="149" y="663"/>
+ <point x="126" y="642"/>
+ <point x="126" y="615" type="curve" smooth="yes"/>
+ <point x="126" y="591"/>
+ <point x="145" y="567"/>
+ <point x="173" y="567" type="curve" smooth="yes"/>
+ <point x="197" y="567"/>
+ <point x="222" y="587"/>
+ </contour>
+ <contour>
+ <point x="980" y="301" type="curve" smooth="yes"/>
+ <point x="980" y="327"/>
+ <point x="957" y="348"/>
+ <point x="932" y="348" type="curve" smooth="yes"/>
+ <point x="908" y="348"/>
+ <point x="884" y="332"/>
+ <point x="884" y="301" type="curve" smooth="yes"/>
+ <point x="884" y="277"/>
+ <point x="902" y="254"/>
+ <point x="932" y="254" type="curve" smooth="yes"/>
+ <point x="957" y="254"/>
+ <point x="980" y="274"/>
+ </contour>
+ <contour>
+ <point x="191" y="459" type="curve" smooth="yes"/>
+ <point x="191" y="484"/>
+ <point x="168" y="505"/>
+ <point x="143" y="505" type="curve" smooth="yes"/>
+ <point x="116" y="505"/>
+ <point x="95" y="484"/>
+ <point x="95" y="458" type="curve" smooth="yes"/>
+ <point x="95" y="433"/>
+ <point x="115" y="410"/>
+ <point x="143" y="410" type="curve" smooth="yes"/>
+ <point x="167" y="410"/>
+ <point x="191" y="432"/>
+ </contour>
+ <contour>
+ <point x="1011" y="458" type="curve" smooth="yes"/>
+ <point x="1011" y="484"/>
+ <point x="990" y="506"/>
+ <point x="964" y="506" type="curve" smooth="yes"/>
+ <point x="940" y="506"/>
+ <point x="915" y="484"/>
+ <point x="915" y="457" type="curve" smooth="yes"/>
+ <point x="915" y="433"/>
+ <point x="936" y="411"/>
+ <point x="964" y="411" type="curve" smooth="yes"/>
+ <point x="990" y="411"/>
+ <point x="1011" y="433"/>
+ </contour>
+ <contour>
+ <point x="222" y="302" type="curve" smooth="yes"/>
+ <point x="222" y="328"/>
+ <point x="200" y="348"/>
+ <point x="174" y="348" type="curve" smooth="yes"/>
+ <point x="147" y="348"/>
+ <point x="126" y="326"/>
+ <point x="126" y="302" type="curve" smooth="yes"/>
+ <point x="126" y="275"/>
+ <point x="149" y="253"/>
+ <point x="174" y="253" type="curve" smooth="yes"/>
+ <point x="201" y="253"/>
+ <point x="222" y="277"/>
+ </contour>
+ <contour>
+ <point x="980" y="615" type="curve" smooth="yes"/>
+ <point x="980" y="642"/>
+ <point x="955" y="663"/>
+ <point x="931" y="663" type="curve" smooth="yes"/>
+ <point x="904" y="663"/>
+ <point x="885" y="638"/>
+ <point x="885" y="614" type="curve" smooth="yes"/>
+ <point x="885" y="588"/>
+ <point x="907" y="567"/>
+ <point x="931" y="567" type="curve" smooth="yes"/>
+ <point x="959" y="567"/>
+ <point x="980" y="591"/>
+ </contour>
+ <contour>
+ <point x="310" y="168" type="curve" smooth="yes"/>
+ <point x="310" y="195"/>
+ <point x="291" y="215"/>
+ <point x="263" y="215" type="curve" smooth="yes"/>
+ <point x="238" y="215"/>
+ <point x="215" y="190"/>
+ <point x="215" y="168" type="curve" smooth="yes"/>
+ <point x="215" y="143"/>
+ <point x="238" y="120"/>
+ <point x="263" y="120" type="curve" smooth="yes"/>
+ <point x="289" y="120"/>
+ <point x="310" y="143"/>
+ </contour>
+ <contour>
+ <point x="890" y="748" type="curve" smooth="yes"/>
+ <point x="890" y="774"/>
+ <point x="870" y="796"/>
+ <point x="843" y="796" type="curve" smooth="yes"/>
+ <point x="815" y="796"/>
+ <point x="796" y="773"/>
+ <point x="796" y="748" type="curve" smooth="yes"/>
+ <point x="796" y="724"/>
+ <point x="817" y="700"/>
+ <point x="843" y="700" type="curve" smooth="yes"/>
+ <point x="869" y="700"/>
+ <point x="890" y="722"/>
+ </contour>
+ <contour>
+ <point x="444" y="78" type="curve" smooth="yes"/>
+ <point x="444" y="102"/>
+ <point x="423" y="126"/>
+ <point x="396" y="126" type="curve" smooth="yes"/>
+ <point x="370" y="126"/>
+ <point x="348" y="102"/>
+ <point x="348" y="78" type="curve" smooth="yes"/>
+ <point x="348" y="55"/>
+ <point x="370" y="31"/>
+ <point x="396" y="31" type="curve" smooth="yes"/>
+ <point x="420" y="31"/>
+ <point x="444" y="51"/>
+ </contour>
+ <contour>
+ <point x="758" y="836" type="curve" smooth="yes"/>
+ <point x="758" y="861"/>
+ <point x="737" y="885"/>
+ <point x="710" y="885" type="curve" smooth="yes"/>
+ <point x="684" y="885"/>
+ <point x="663" y="862"/>
+ <point x="663" y="838" type="curve" smooth="yes"/>
+ <point x="663" y="814"/>
+ <point x="683" y="789"/>
+ <point x="710" y="789" type="curve" smooth="yes"/>
+ <point x="734" y="789"/>
+ <point x="758" y="809"/>
+ </contour>
+ <contour>
+ <point x="601" y="47" type="curve" smooth="yes"/>
+ <point x="601" y="73"/>
+ <point x="579" y="95"/>
+ <point x="553" y="95" type="curve" smooth="yes"/>
+ <point x="527" y="95"/>
+ <point x="506" y="73"/>
+ <point x="506" y="47" type="curve" smooth="yes"/>
+ <point x="506" y="21"/>
+ <point x="527" y="0"/>
+ <point x="553" y="0" type="curve" smooth="yes"/>
+ <point x="579" y="0"/>
+ <point x="601" y="21"/>
+ </contour>
+ <contour>
+ <point x="601" y="868" type="curve" smooth="yes"/>
+ <point x="601" y="894"/>
+ <point x="579" y="916"/>
+ <point x="553" y="916" type="curve" smooth="yes"/>
+ <point x="527" y="916"/>
+ <point x="506" y="894"/>
+ <point x="506" y="868" type="curve" smooth="yes"/>
+ <point x="506" y="842"/>
+ <point x="527" y="821"/>
+ <point x="553" y="821" type="curve" smooth="yes"/>
+ <point x="579" y="821"/>
+ <point x="601" y="842"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetassocuids.ufo/glyphs/E_qS_gn.glif b/tests/reference/ufo/psfsetassocuids.ufo/glyphs/E_qS_gn.glif
new file mode 100644
index 0000000..9eeb2ef
--- /dev/null
+++ b/tests/reference/ufo/psfsetassocuids.ufo/glyphs/E_qS_gn.glif
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="EqSgn" format="2">
+ <advance width="1200"/>
+ <unicode hex="003D"/>
+ <outline>
+ <contour>
+ <point x="120" y="440" type="line"/>
+ <point x="1080" y="440" type="line"/>
+ <point x="1080" y="650" type="line"/>
+ <point x="120" y="650" type="line"/>
+ </contour>
+ <contour>
+ <point x="120" y="810" type="line"/>
+ <point x="1080" y="810" type="line"/>
+ <point x="1080" y="1020" type="line"/>
+ <point x="120" y="1020" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetassocuids.ufo/glyphs/E_xclamationM_rk.glif b/tests/reference/ufo/psfsetassocuids.ufo/glyphs/E_xclamationM_rk.glif
new file mode 100644
index 0000000..cfdf1a6
--- /dev/null
+++ b/tests/reference/ufo/psfsetassocuids.ufo/glyphs/E_xclamationM_rk.glif
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="ExclamationMrk" format="2">
+ <advance width="780"/>
+ <unicode hex="0021"/>
+ <outline>
+ <contour>
+ <point x="530" y="500" type="line"/>
+ <point x="536" y="790"/>
+ <point x="531" y="1076"/>
+ <point x="570" y="1510" type="curve"/>
+ <point x="235" y="1510" type="line"/>
+ <point x="273" y="1076"/>
+ <point x="268" y="790"/>
+ <point x="275" y="500" type="curve"/>
+ </contour>
+ <contour>
+ <point x="230" y="150" type="curve" smooth="yes"/>
+ <point x="230" y="46"/>
+ <point x="304" y="-25"/>
+ <point x="405" y="-25" type="curve" smooth="yes"/>
+ <point x="507" y="-25"/>
+ <point x="580" y="46"/>
+ <point x="580" y="150" type="curve" smooth="yes"/>
+ <point x="580" y="252"/>
+ <point x="507" y="325"/>
+ <point x="405" y="325" type="curve" smooth="yes"/>
+ <point x="304" y="325"/>
+ <point x="230" y="252"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetassocuids.ufo/glyphs/F_ullS_top.glif b/tests/reference/ufo/psfsetassocuids.ufo/glyphs/F_ullS_top.glif
new file mode 100644
index 0000000..b05d598
--- /dev/null
+++ b/tests/reference/ufo/psfsetassocuids.ufo/glyphs/F_ullS_top.glif
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="FullStop" format="2">
+ <advance width="710"/>
+ <unicode hex="002E"/>
+ <outline>
+ <contour>
+ <point x="200" y="150" type="curve" smooth="yes"/>
+ <point x="200" y="46"/>
+ <point x="274" y="-25"/>
+ <point x="375" y="-25" type="curve" smooth="yes"/>
+ <point x="477" y="-25"/>
+ <point x="550" y="46"/>
+ <point x="550" y="150" type="curve" smooth="yes"/>
+ <point x="550" y="252"/>
+ <point x="477" y="325"/>
+ <point x="375" y="325" type="curve" smooth="yes"/>
+ <point x="274" y="325"/>
+ <point x="200" y="252"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetassocuids.ufo/glyphs/G_T_S_gn.glif b/tests/reference/ufo/psfsetassocuids.ufo/glyphs/G_T_S_gn.glif
new file mode 100644
index 0000000..650e4d2
--- /dev/null
+++ b/tests/reference/ufo/psfsetassocuids.ufo/glyphs/G_T_S_gn.glif
@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="GTSgn" format="2">
+ <advance width="1200"/>
+ <unicode hex="003E"/>
+ <outline>
+ <contour>
+ <point x="130" y="245" type="line"/>
+ <point x="1090" y="635" type="line"/>
+ <point x="1090" y="825" type="line"/>
+ <point x="130" y="1215" type="line"/>
+ <point x="130" y="985" type="line"/>
+ <point x="810" y="730" type="line"/>
+ <point x="130" y="475" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetassocuids.ufo/glyphs/G_raveA_ccent.glif b/tests/reference/ufo/psfsetassocuids.ufo/glyphs/G_raveA_ccent.glif
new file mode 100644
index 0000000..83a5f21
--- /dev/null
+++ b/tests/reference/ufo/psfsetassocuids.ufo/glyphs/G_raveA_ccent.glif
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="GraveAccent" format="2">
+ <advance width="640"/>
+ <unicode hex="0060"/>
+ <anchor x="500" y="1635" name="U"/>
+ <outline>
+ <contour>
+ <point x="0" y="1600" type="line"/>
+ <point x="400" y="1200" type="line"/>
+ <point x="640" y="1200" type="line"/>
+ <point x="350" y="1600" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetassocuids.ufo/glyphs/H_yphen.glif b/tests/reference/ufo/psfsetassocuids.ufo/glyphs/H_yphen.glif
new file mode 100644
index 0000000..d79c70a
--- /dev/null
+++ b/tests/reference/ufo/psfsetassocuids.ufo/glyphs/H_yphen.glif
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="Hyphen" format="2">
+ <advance width="880"/>
+ <unicode hex="2010"/>
+ <anchor x="440" y="1100" name="U"/>
+ <outline>
+ <contour>
+ <point x="70" y="525" type="line"/>
+ <point x="810" y="525" type="line"/>
+ <point x="810" y="735" type="line"/>
+ <point x="70" y="735" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetassocuids.ufo/glyphs/H_yphenM_inus.glif b/tests/reference/ufo/psfsetassocuids.ufo/glyphs/H_yphenM_inus.glif
new file mode 100644
index 0000000..b88bdd4
--- /dev/null
+++ b/tests/reference/ufo/psfsetassocuids.ufo/glyphs/H_yphenM_inus.glif
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="HyphenMinus" format="2">
+ <advance width="895"/>
+ <unicode hex="002D"/>
+ <anchor x="450" y="1100" name="U"/>
+ <outline>
+ <contour>
+ <point x="80" y="525" type="line"/>
+ <point x="815" y="525" type="line"/>
+ <point x="815" y="735" type="line"/>
+ <point x="80" y="735" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetassocuids.ufo/glyphs/H_yphen_S_oft.glif b/tests/reference/ufo/psfsetassocuids.ufo/glyphs/H_yphen_S_oft.glif
new file mode 100644
index 0000000..916f8cf
--- /dev/null
+++ b/tests/reference/ufo/psfsetassocuids.ufo/glyphs/H_yphen_S_oft.glif
@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="Hyphen_Soft" format="2">
+ <advance width="895"/>
+ <unicode hex="00AD"/>
+ <anchor x="450" y="1100" name="U"/>
+ <outline>
+ <component base="HyphenMinus"/>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetassocuids.ufo/glyphs/L_T_S_gn.glif b/tests/reference/ufo/psfsetassocuids.ufo/glyphs/L_T_S_gn.glif
new file mode 100644
index 0000000..ab92cf3
--- /dev/null
+++ b/tests/reference/ufo/psfsetassocuids.ufo/glyphs/L_T_S_gn.glif
@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LTSgn" format="2">
+ <advance width="1200"/>
+ <unicode hex="003C"/>
+ <outline>
+ <contour>
+ <point x="1070" y="475" type="line"/>
+ <point x="390" y="730" type="line"/>
+ <point x="1070" y="985" type="line"/>
+ <point x="1070" y="1215" type="line"/>
+ <point x="110" y="825" type="line"/>
+ <point x="110" y="635" type="line"/>
+ <point x="1070" y="245" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetassocuids.ufo/glyphs/L_ftC_urlyB_rac.glif b/tests/reference/ufo/psfsetassocuids.ufo/glyphs/L_ftC_urlyB_rac.glif
new file mode 100644
index 0000000..2370b56
--- /dev/null
+++ b/tests/reference/ufo/psfsetassocuids.ufo/glyphs/L_ftC_urlyB_rac.glif
@@ -0,0 +1,47 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LftCurlyBrac" format="2">
+ <advance width="1040"/>
+ <unicode hex="007B"/>
+ <outline>
+ <contour>
+ <point x="895" y="-179" type="line"/>
+ <point x="828" y="-160"/>
+ <point x="704" y="-122"/>
+ <point x="685" y="-100" type="curve" smooth="yes"/>
+ <point x="650" y="-60"/>
+ <point x="663" y="411"/>
+ <point x="645" y="445" type="curve" smooth="yes"/>
+ <point x="621" y="491"/>
+ <point x="483" y="580"/>
+ <point x="483" y="615" type="curve" smooth="yes"/>
+ <point x="483" y="650"/>
+ <point x="620" y="740"/>
+ <point x="643" y="785" type="curve" smooth="yes"/>
+ <point x="661" y="820"/>
+ <point x="650" y="1289"/>
+ <point x="685" y="1330" type="curve" smooth="yes"/>
+ <point x="702" y="1351"/>
+ <point x="807" y="1390"/>
+ <point x="870" y="1409" type="curve"/>
+ <point x="820" y="1640" type="line"/>
+ <point x="692" y="1613"/>
+ <point x="502" y="1562"/>
+ <point x="455" y="1515" type="curve" smooth="yes"/>
+ <point x="381" y="1442"/>
+ <point x="392" y="852"/>
+ <point x="370" y="820" type="curve" smooth="yes"/>
+ <point x="340" y="777"/>
+ <point x="170" y="670"/>
+ <point x="170" y="615" type="curve" smooth="yes"/>
+ <point x="170" y="560"/>
+ <point x="340" y="453"/>
+ <point x="370" y="410" type="curve" smooth="yes"/>
+ <point x="392" y="378"/>
+ <point x="380" y="-213"/>
+ <point x="455" y="-285" type="curve" smooth="yes"/>
+ <point x="505" y="-333"/>
+ <point x="709" y="-383"/>
+ <point x="845" y="-410" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetassocuids.ufo/glyphs/L_ftP_aren.glif b/tests/reference/ufo/psfsetassocuids.ufo/glyphs/L_ftP_aren.glif
new file mode 100644
index 0000000..99e1982
--- /dev/null
+++ b/tests/reference/ufo/psfsetassocuids.ufo/glyphs/L_ftP_aren.glif
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LftParen" format="2">
+ <advance width="860"/>
+ <unicode hex="0028"/>
+ <outline>
+ <contour>
+ <point x="555" y="1640" type="line"/>
+ <point x="290" y="1444"/>
+ <point x="115" y="1062"/>
+ <point x="115" y="625" type="curve" smooth="yes"/>
+ <point x="115" y="218"/>
+ <point x="260" y="-125"/>
+ <point x="535" y="-410" type="curve"/>
+ <point x="686" y="-240" type="line"/>
+ <point x="462" y="11"/>
+ <point x="376" y="335"/>
+ <point x="376" y="635" type="curve" smooth="yes"/>
+ <point x="376" y="938"/>
+ <point x="466" y="1261"/>
+ <point x="676" y="1455" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetassocuids.ufo/glyphs/L_ftS_qrB_rac.glif b/tests/reference/ufo/psfsetassocuids.ufo/glyphs/L_ftS_qrB_rac.glif
new file mode 100644
index 0000000..dcf019b
--- /dev/null
+++ b/tests/reference/ufo/psfsetassocuids.ufo/glyphs/L_ftS_qrB_rac.glif
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LftSqrBrac" format="2">
+ <advance width="850"/>
+ <unicode hex="005B"/>
+ <outline>
+ <contour>
+ <point x="710" y="-410" type="line"/>
+ <point x="710" y="-200" type="line"/>
+ <point x="470" y="-200" type="line"/>
+ <point x="470" y="1390" type="line"/>
+ <point x="710" y="1390" type="line"/>
+ <point x="710" y="1600" type="line"/>
+ <point x="190" y="1600" type="line"/>
+ <point x="190" y="-410" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetassocuids.ufo/glyphs/L_owL_ine.glif b/tests/reference/ufo/psfsetassocuids.ufo/glyphs/L_owL_ine.glif
new file mode 100644
index 0000000..225c4ce
--- /dev/null
+++ b/tests/reference/ufo/psfsetassocuids.ufo/glyphs/L_owL_ine.glif
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LowLine" format="2">
+ <advance width="1274"/>
+ <unicode hex="005F"/>
+ <outline>
+ <contour>
+ <point x="0" y="-350" type="line"/>
+ <point x="1274" y="-350" type="line"/>
+ <point x="1274" y="-140" type="line"/>
+ <point x="0" y="-140" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetassocuids.ufo/glyphs/L_tnC_apA_.alt.glif b/tests/reference/ufo/psfsetassocuids.ufo/glyphs/L_tnC_apA_.alt.glif
new file mode 100644
index 0000000..cf1b900
--- /dev/null
+++ b/tests/reference/ufo/psfsetassocuids.ufo/glyphs/L_tnC_apA_.alt.glif
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnCapA.alt" format="2">
+ <advance width="1485"/>
+ <anchor x="1275" y="0" name="H"/>
+ <anchor x="732" y="-100" name="L"/>
+ <anchor x="1495" y="0" name="O"/>
+ <anchor x="732" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="1115" y="0" type="line"/>
+ <point x="1408" y="0" type="line"/>
+ <point x="1373" y="80"/>
+ <point x="1341" y="168"/>
+ <point x="1278" y="355" type="curve" smooth="yes"/>
+ <point x="908" y="1460" type="line"/>
+ <point x="552" y="1460" type="line"/>
+ <point x="182" y="355" type="line" smooth="yes"/>
+ <point x="119" y="166"/>
+ <point x="88" y="81"/>
+ <point x="52" y="0" type="curve"/>
+ <point x="350" y="0" type="line"/>
+ <point x="460" y="355" type="line"/>
+ <point x="1004" y="355" type="line"/>
+ </contour>
+ <contour>
+ <point x="730" y="1228" type="line"/>
+ <point x="936" y="570" type="line"/>
+ <point x="526" y="570" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetassocuids.ufo/glyphs/L_tnC_apA_.glif b/tests/reference/ufo/psfsetassocuids.ufo/glyphs/L_tnC_apA_.glif
new file mode 100644
index 0000000..9fa1f45
--- /dev/null
+++ b/tests/reference/ufo/psfsetassocuids.ufo/glyphs/L_tnC_apA_.glif
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnCapA" format="2">
+ <advance width="1485"/>
+ <unicode hex="0041"/>
+ <anchor x="1275" y="0" name="H"/>
+ <anchor x="732" y="-100" name="L"/>
+ <anchor x="1495" y="0" name="O"/>
+ <anchor x="732" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="1115" y="0" type="line"/>
+ <point x="1408" y="0" type="line"/>
+ <point x="1373" y="80"/>
+ <point x="1341" y="168"/>
+ <point x="1278" y="355" type="curve" smooth="yes"/>
+ <point x="908" y="1460" type="line"/>
+ <point x="552" y="1460" type="line"/>
+ <point x="182" y="355" type="line" smooth="yes"/>
+ <point x="119" y="166"/>
+ <point x="88" y="81"/>
+ <point x="52" y="0" type="curve"/>
+ <point x="350" y="0" type="line"/>
+ <point x="460" y="355" type="line"/>
+ <point x="1004" y="355" type="line"/>
+ </contour>
+ <contour>
+ <point x="730" y="1228" type="line"/>
+ <point x="936" y="570" type="line"/>
+ <point x="526" y="570" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetassocuids.ufo/glyphs/L_tnC_apA_D_iaer.glif b/tests/reference/ufo/psfsetassocuids.ufo/glyphs/L_tnC_apA_D_iaer.glif
new file mode 100644
index 0000000..79101d0
--- /dev/null
+++ b/tests/reference/ufo/psfsetassocuids.ufo/glyphs/L_tnC_apA_D_iaer.glif
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnCapADiaer" format="2">
+ <advance width="1485"/>
+ <unicode hex="00C4"/>
+ <anchor x="1275" y="0" name="H"/>
+ <anchor x="732" y="-100" name="L"/>
+ <anchor x="1495" y="0" name="O"/>
+ <anchor x="732" y="2015" name="U"/>
+ <outline>
+ <component base="LtnCapA"/>
+ <component base="CombDiaer" xOffset="1312" yOffset="430"/>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetassocuids.ufo/glyphs/L_tnC_apB_.glif b/tests/reference/ufo/psfsetassocuids.ufo/glyphs/L_tnC_apB_.glif
new file mode 100644
index 0000000..df49e47
--- /dev/null
+++ b/tests/reference/ufo/psfsetassocuids.ufo/glyphs/L_tnC_apB_.glif
@@ -0,0 +1,62 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnCapB" format="2">
+ <advance width="1385"/>
+ <unicode hex="0042"/>
+ <anchor x="670" y="-100" name="L"/>
+ <anchor x="670" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="450" y="1248" type="line"/>
+ <point x="487" y="1250"/>
+ <point x="562" y="1253"/>
+ <point x="631" y="1253" type="curve" smooth="yes"/>
+ <point x="818" y="1253"/>
+ <point x="897" y="1196"/>
+ <point x="897" y="1077" type="curve" smooth="yes"/>
+ <point x="897" y="951"/>
+ <point x="794" y="875"/>
+ <point x="605" y="875" type="curve" smooth="yes"/>
+ <point x="450" y="875" type="line"/>
+ </contour>
+ <contour>
+ <point x="1245" y="430" type="curve" smooth="yes"/>
+ <point x="1245" y="672"/>
+ <point x="1084" y="760"/>
+ <point x="935" y="800" type="curve"/>
+ <point x="1065" y="850"/>
+ <point x="1170" y="947"/>
+ <point x="1170" y="1110" type="curve" smooth="yes"/>
+ <point x="1170" y="1378"/>
+ <point x="937" y="1470"/>
+ <point x="615" y="1470" type="curve" smooth="yes"/>
+ <point x="422" y="1470"/>
+ <point x="248" y="1466"/>
+ <point x="150" y="1460" type="curve"/>
+ <point x="165" y="1380"/>
+ <point x="165" y="1196"/>
+ <point x="165" y="1000" type="curve" smooth="yes"/>
+ <point x="165" y="455" type="line" smooth="yes"/>
+ <point x="165" y="257"/>
+ <point x="165" y="80"/>
+ <point x="150" y="0" type="curve"/>
+ <point x="150" y="0"/>
+ <point x="401" y="-10"/>
+ <point x="631" y="-10" type="curve" smooth="yes"/>
+ <point x="1055" y="-10"/>
+ <point x="1245" y="181"/>
+ </contour>
+ <contour>
+ <point x="450" y="658" type="line"/>
+ <point x="643" y="658" type="line" smooth="yes"/>
+ <point x="853" y="658"/>
+ <point x="972" y="587"/>
+ <point x="972" y="450" type="curve" smooth="yes"/>
+ <point x="972" y="269"/>
+ <point x="826" y="215"/>
+ <point x="652" y="215" type="curve" smooth="yes"/>
+ <point x="552" y="215"/>
+ <point x="483" y="218"/>
+ <point x="450" y="220" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetassocuids.ufo/glyphs/L_tnC_apC_.glif b/tests/reference/ufo/psfsetassocuids.ufo/glyphs/L_tnC_apC_.glif
new file mode 100644
index 0000000..78c5238
--- /dev/null
+++ b/tests/reference/ufo/psfsetassocuids.ufo/glyphs/L_tnC_apC_.glif
@@ -0,0 +1,38 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnCapC" format="2">
+ <advance width="1385"/>
+ <unicode hex="0043"/>
+ <anchor x="745" y="0" name="H"/>
+ <anchor x="745" y="-100" name="L"/>
+ <anchor x="745" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="1215" y="405" type="line"/>
+ <point x="1105" y="293"/>
+ <point x="940" y="220"/>
+ <point x="790" y="220" type="curve" smooth="yes"/>
+ <point x="531" y="220"/>
+ <point x="375" y="413"/>
+ <point x="375" y="735" type="curve" smooth="yes"/>
+ <point x="375" y="1074"/>
+ <point x="557" y="1245"/>
+ <point x="800" y="1245" type="curve" smooth="yes"/>
+ <point x="931" y="1245"/>
+ <point x="1053" y="1205"/>
+ <point x="1180" y="1105" type="curve"/>
+ <point x="1250" y="1345" type="line"/>
+ <point x="1106" y="1449"/>
+ <point x="969" y="1485"/>
+ <point x="785" y="1485" type="curve" smooth="yes"/>
+ <point x="413" y="1485"/>
+ <point x="90" y="1225"/>
+ <point x="90" y="710" type="curve" smooth="yes"/>
+ <point x="90" y="260"/>
+ <point x="341" y="-25"/>
+ <point x="755" y="-25" type="curve" smooth="yes"/>
+ <point x="926" y="-25"/>
+ <point x="1142" y="42"/>
+ <point x="1265" y="140" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetassocuids.ufo/glyphs/L_tnC_apD_.glif b/tests/reference/ufo/psfsetassocuids.ufo/glyphs/L_tnC_apD_.glif
new file mode 100644
index 0000000..4dd3b9c
--- /dev/null
+++ b/tests/reference/ufo/psfsetassocuids.ufo/glyphs/L_tnC_apD_.glif
@@ -0,0 +1,45 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnCapD" format="2">
+ <advance width="1485"/>
+ <unicode hex="0044"/>
+ <anchor x="800" y="-100" name="L"/>
+ <anchor x="800" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="165" y="455" type="line"/>
+ <point x="164" y="257"/>
+ <point x="165" y="80"/>
+ <point x="150" y="0" type="curve"/>
+ <point x="150" y="0"/>
+ <point x="474" y="-10"/>
+ <point x="609" y="-10" type="curve" smooth="yes"/>
+ <point x="919" y="-10"/>
+ <point x="1370" y="145"/>
+ <point x="1370" y="740" type="curve" smooth="yes"/>
+ <point x="1370" y="1374"/>
+ <point x="906" y="1470"/>
+ <point x="630" y="1470" type="curve" smooth="yes"/>
+ <point x="487" y="1470"/>
+ <point x="239" y="1466"/>
+ <point x="150" y="1460" type="curve"/>
+ <point x="165" y="1380"/>
+ <point x="165" y="1196"/>
+ <point x="165" y="1000" type="curve" smooth="yes"/>
+ </contour>
+ <contour>
+ <point x="450" y="1241" type="line"/>
+ <point x="492" y="1243"/>
+ <point x="582" y="1246"/>
+ <point x="637" y="1246" type="curve" smooth="yes"/>
+ <point x="897" y="1246"/>
+ <point x="1078" y="1118"/>
+ <point x="1078" y="720" type="curve" smooth="yes"/>
+ <point x="1078" y="357"/>
+ <point x="856" y="221"/>
+ <point x="633" y="221" type="curve" smooth="yes"/>
+ <point x="554" y="221"/>
+ <point x="489" y="227"/>
+ <point x="450" y="231" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetassocuids.ufo/glyphs/L_tnC_apE_.glif b/tests/reference/ufo/psfsetassocuids.ufo/glyphs/L_tnC_apE_.glif
new file mode 100644
index 0000000..9572dfd
--- /dev/null
+++ b/tests/reference/ufo/psfsetassocuids.ufo/glyphs/L_tnC_apE_.glif
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnCapE" format="2">
+ <advance width="1212"/>
+ <unicode hex="0045"/>
+ <anchor x="610" y="0" name="H"/>
+ <anchor x="610" y="-100" name="L"/>
+ <anchor x="1004" y="0" name="O"/>
+ <anchor x="1247" y="1200" name="R"/>
+ <anchor x="610" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="450" y="875" type="line"/>
+ <point x="450" y="1230" type="line"/>
+ <point x="1072" y="1230" type="line"/>
+ <point x="1072" y="1460" type="line"/>
+ <point x="150" y="1460" type="line"/>
+ <point x="165" y="1380"/>
+ <point x="165" y="1222"/>
+ <point x="165" y="1025" type="curve" smooth="yes"/>
+ <point x="165" y="435" type="line" smooth="yes"/>
+ <point x="165" y="238"/>
+ <point x="165" y="80"/>
+ <point x="150" y="0" type="curve"/>
+ <point x="1102" y="0" type="line"/>
+ <point x="1102" y="245" type="line"/>
+ <point x="1024" y="231"/>
+ <point x="899" y="230"/>
+ <point x="708" y="230" type="curve" smooth="yes"/>
+ <point x="450" y="230" type="line"/>
+ <point x="450" y="650" type="line"/>
+ <point x="997" y="650" type="line"/>
+ <point x="997" y="875" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetassocuids.ufo/glyphs/L_tnC_apF_.glif b/tests/reference/ufo/psfsetassocuids.ufo/glyphs/L_tnC_apF_.glif
new file mode 100644
index 0000000..9f4f14b
--- /dev/null
+++ b/tests/reference/ufo/psfsetassocuids.ufo/glyphs/L_tnC_apF_.glif
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnCapF" format="2">
+ <advance width="1200"/>
+ <unicode hex="0046"/>
+ <anchor x="630" y="-100" name="L"/>
+ <anchor x="630" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="450" y="860" type="line"/>
+ <point x="450" y="1230" type="line"/>
+ <point x="1090" y="1230" type="line"/>
+ <point x="1090" y="1460" type="line"/>
+ <point x="150" y="1460" type="line"/>
+ <point x="165" y="1380"/>
+ <point x="165" y="1217"/>
+ <point x="165" y="1020" type="curve" smooth="yes"/>
+ <point x="165" y="435" type="line" smooth="yes"/>
+ <point x="165" y="238"/>
+ <point x="165" y="80"/>
+ <point x="150" y="0" type="curve"/>
+ <point x="465" y="0" type="line"/>
+ <point x="450" y="73"/>
+ <point x="450" y="222"/>
+ <point x="450" y="408" type="curve" smooth="yes"/>
+ <point x="450" y="635" type="line"/>
+ <point x="1005" y="635" type="line"/>
+ <point x="1005" y="860" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetassocuids.ufo/glyphs/L_tnC_apG_.glif b/tests/reference/ufo/psfsetassocuids.ufo/glyphs/L_tnC_apG_.glif
new file mode 100644
index 0000000..8358b8a
--- /dev/null
+++ b/tests/reference/ufo/psfsetassocuids.ufo/glyphs/L_tnC_apG_.glif
@@ -0,0 +1,42 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnCapG" format="2">
+ <advance width="1472"/>
+ <unicode hex="0047"/>
+ <anchor x="807" y="0" name="H"/>
+ <anchor x="807" y="-100" name="L"/>
+ <anchor x="807" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="1337" y="785" type="line"/>
+ <point x="767" y="785" type="line"/>
+ <point x="767" y="560" type="line"/>
+ <point x="1082" y="560" type="line"/>
+ <point x="1082" y="294" type="line"/>
+ <point x="966" y="236"/>
+ <point x="883" y="220"/>
+ <point x="769" y="220" type="curve" smooth="yes"/>
+ <point x="532" y="220"/>
+ <point x="375" y="420"/>
+ <point x="375" y="745" type="curve" smooth="yes"/>
+ <point x="375" y="1048"/>
+ <point x="545" y="1245"/>
+ <point x="810" y="1245" type="curve" smooth="yes"/>
+ <point x="953" y="1245"/>
+ <point x="1097" y="1205"/>
+ <point x="1236" y="1107" type="curve"/>
+ <point x="1322" y="1345" type="line"/>
+ <point x="1137" y="1462"/>
+ <point x="989" y="1485"/>
+ <point x="818" y="1485" type="curve" smooth="yes"/>
+ <point x="403" y="1485"/>
+ <point x="90" y="1199"/>
+ <point x="90" y="720" type="curve" smooth="yes"/>
+ <point x="90" y="241"/>
+ <point x="377" y="-25"/>
+ <point x="777" y="-25" type="curve" smooth="yes"/>
+ <point x="960" y="-25"/>
+ <point x="1120" y="11"/>
+ <point x="1337" y="155" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetassocuids.ufo/glyphs/L_tnC_apH_.glif b/tests/reference/ufo/psfsetassocuids.ufo/glyphs/L_tnC_apH_.glif
new file mode 100644
index 0000000..2e2e5e6
--- /dev/null
+++ b/tests/reference/ufo/psfsetassocuids.ufo/glyphs/L_tnC_apH_.glif
@@ -0,0 +1,40 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnCapH" format="2">
+ <advance width="1515"/>
+ <unicode hex="0048"/>
+ <anchor x="305" y="0" name="H"/>
+ <anchor x="745" y="-100" name="L"/>
+ <anchor x="745" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="1040" y="1460" type="line"/>
+ <point x="1040" y="860" type="line"/>
+ <point x="450" y="860" type="line"/>
+ <point x="450" y="1460" type="line"/>
+ <point x="150" y="1460" type="line"/>
+ <point x="165" y="1380"/>
+ <point x="165" y="1227"/>
+ <point x="165" y="1030" type="curve" smooth="yes"/>
+ <point x="165" y="430" type="line" smooth="yes"/>
+ <point x="165" y="233"/>
+ <point x="165" y="80"/>
+ <point x="150" y="0" type="curve"/>
+ <point x="150" y="0"/>
+ <point x="450" y="0"/>
+ <point x="450" y="0" type="curve"/>
+ <point x="450" y="635" type="line"/>
+ <point x="1040" y="635" type="line"/>
+ <point x="1040" y="0" type="line"/>
+ <point x="1040" y="0"/>
+ <point x="1340" y="0"/>
+ <point x="1340" y="0" type="curve"/>
+ <point x="1325" y="80"/>
+ <point x="1325" y="233"/>
+ <point x="1325" y="430" type="curve" smooth="yes"/>
+ <point x="1325" y="1030" type="line" smooth="yes"/>
+ <point x="1325" y="1227"/>
+ <point x="1325" y="1380"/>
+ <point x="1340" y="1460" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetassocuids.ufo/glyphs/L_tnC_apI_.glif b/tests/reference/ufo/psfsetassocuids.ufo/glyphs/L_tnC_apI_.glif
new file mode 100644
index 0000000..388486b
--- /dev/null
+++ b/tests/reference/ufo/psfsetassocuids.ufo/glyphs/L_tnC_apI_.glif
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnCapI" format="2">
+ <advance width="1045"/>
+ <unicode hex="0049"/>
+ <anchor x="520" y="0" name="H"/>
+ <anchor x="516" y="-100" name="L"/>
+ <anchor x="712" y="0" name="O"/>
+ <anchor x="1014" y="1200" name="R"/>
+ <anchor x="520" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="130" y="1460" type="line"/>
+ <point x="130" y="1255" type="line"/>
+ <point x="370" y="1255" type="line"/>
+ <point x="370" y="205" type="line"/>
+ <point x="130" y="205" type="line"/>
+ <point x="130" y="0" type="line"/>
+ <point x="895" y="0" type="line"/>
+ <point x="895" y="205" type="line"/>
+ <point x="655" y="205" type="line"/>
+ <point x="655" y="1255" type="line"/>
+ <point x="895" y="1255" type="line"/>
+ <point x="895" y="1460" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetassocuids.ufo/glyphs/L_tnC_apJ_.glif b/tests/reference/ufo/psfsetassocuids.ufo/glyphs/L_tnC_apJ_.glif
new file mode 100644
index 0000000..8ee9ce3
--- /dev/null
+++ b/tests/reference/ufo/psfsetassocuids.ufo/glyphs/L_tnC_apJ_.glif
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnCapJ" format="2">
+ <advance width="1030"/>
+ <unicode hex="004A"/>
+ <anchor x="415" y="-100" name="L"/>
+ <anchor x="705" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="555" y="1460" type="line"/>
+ <point x="568" y="1354"/>
+ <point x="570" y="1175"/>
+ <point x="570" y="980" type="curve" smooth="yes"/>
+ <point x="570" y="558" type="line" smooth="yes"/>
+ <point x="570" y="383"/>
+ <point x="540" y="227"/>
+ <point x="365" y="227" type="curve" smooth="yes"/>
+ <point x="264" y="227"/>
+ <point x="153" y="270"/>
+ <point x="79" y="347" type="curve"/>
+ <point x="30" y="90" type="line"/>
+ <point x="109" y="9"/>
+ <point x="258" y="-25"/>
+ <point x="363" y="-25" type="curve" smooth="yes"/>
+ <point x="658" y="-25"/>
+ <point x="855" y="129"/>
+ <point x="855" y="535" type="curve" smooth="yes"/>
+ <point x="855" y="618"/>
+ <point x="855" y="1460"/>
+ <point x="855" y="1460" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetassocuids.ufo/glyphs/L_tnC_apK_.glif b/tests/reference/ufo/psfsetassocuids.ufo/glyphs/L_tnC_apK_.glif
new file mode 100644
index 0000000..abb6ff7
--- /dev/null
+++ b/tests/reference/ufo/psfsetassocuids.ufo/glyphs/L_tnC_apK_.glif
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnCapK" format="2">
+ <advance width="1430"/>
+ <unicode hex="004B"/>
+ <anchor x="320" y="0" name="H"/>
+ <anchor x="740" y="-100" name="L"/>
+ <anchor x="725" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="944" y="1460" type="line"/>
+ <point x="371" y="732" type="line"/>
+ <point x="579" y="676" type="line"/>
+ <point x="1280" y="1460" type="line"/>
+ </contour>
+ <contour>
+ <point x="389" y="731" type="line"/>
+ <point x="990" y="0" type="line"/>
+ <point x="1360" y="0" type="line"/>
+ <point x="614" y="829" type="line"/>
+ </contour>
+ <contour>
+ <point x="450" y="1460" type="line"/>
+ <point x="150" y="1460" type="line"/>
+ <point x="165" y="1380"/>
+ <point x="165" y="1222"/>
+ <point x="165" y="1025" type="curve" smooth="yes"/>
+ <point x="165" y="435" type="line" smooth="yes"/>
+ <point x="165" y="238"/>
+ <point x="165" y="80"/>
+ <point x="150" y="0" type="curve"/>
+ <point x="450" y="0" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetassocuids.ufo/glyphs/L_tnC_apL_.glif b/tests/reference/ufo/psfsetassocuids.ufo/glyphs/L_tnC_apL_.glif
new file mode 100644
index 0000000..e1c1e2e
--- /dev/null
+++ b/tests/reference/ufo/psfsetassocuids.ufo/glyphs/L_tnC_apL_.glif
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnCapL" format="2">
+ <advance width="1130"/>
+ <unicode hex="004C"/>
+ <anchor x="620" y="0" name="H"/>
+ <anchor x="620" y="-100" name="L"/>
+ <anchor x="650" y="1200" name="R"/>
+ <anchor x="620" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="450" y="230" type="line"/>
+ <point x="450" y="1460" type="line"/>
+ <point x="150" y="1460" type="line"/>
+ <point x="165" y="1380"/>
+ <point x="165" y="1222"/>
+ <point x="165" y="1025" type="curve" smooth="yes"/>
+ <point x="165" y="435" type="line" smooth="yes"/>
+ <point x="165" y="238"/>
+ <point x="165" y="80"/>
+ <point x="150" y="0" type="curve"/>
+ <point x="1085" y="0" type="line"/>
+ <point x="1085" y="245" type="line"/>
+ <point x="1008" y="231"/>
+ <point x="855" y="230"/>
+ <point x="666" y="230" type="curve" smooth="yes"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetassocuids.ufo/glyphs/L_tnC_apM_.glif b/tests/reference/ufo/psfsetassocuids.ufo/glyphs/L_tnC_apM_.glif
new file mode 100644
index 0000000..8da241e
--- /dev/null
+++ b/tests/reference/ufo/psfsetassocuids.ufo/glyphs/L_tnC_apM_.glif
@@ -0,0 +1,38 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnCapM" format="2">
+ <advance width="1855"/>
+ <unicode hex="004D"/>
+ <anchor x="915" y="-100" name="L"/>
+ <anchor x="915" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="917" y="275" type="line"/>
+ <point x="575" y="1460" type="line"/>
+ <point x="315" y="1460" type="line"/>
+ <point x="436" y="1170" type="line"/>
+ <point x="770" y="0" type="line"/>
+ <point x="1065" y="0" type="line"/>
+ <point x="1397" y="1170" type="line"/>
+ <point x="1517" y="1460" type="line"/>
+ <point x="1260" y="1460" type="line"/>
+ </contour>
+ <contour>
+ <point x="220" y="1460" type="line"/>
+ <point x="220" y="1460"/>
+ <point x="176" y="198"/>
+ <point x="150" y="0" type="curve"/>
+ <point x="420" y="0" type="line"/>
+ <point x="449" y="1205" type="line"/>
+ <point x="485" y="1460" type="line"/>
+ </contour>
+ <contour>
+ <point x="1680" y="0" type="line"/>
+ <point x="1651" y="198"/>
+ <point x="1610" y="1460"/>
+ <point x="1610" y="1460" type="curve"/>
+ <point x="1340" y="1460" type="line"/>
+ <point x="1385" y="1205" type="line"/>
+ <point x="1410" y="0" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetassocuids.ufo/glyphs/L_tnC_apN_.glif b/tests/reference/ufo/psfsetassocuids.ufo/glyphs/L_tnC_apN_.glif
new file mode 100644
index 0000000..aa2b5c4
--- /dev/null
+++ b/tests/reference/ufo/psfsetassocuids.ufo/glyphs/L_tnC_apN_.glif
@@ -0,0 +1,37 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnCapN" format="2">
+ <advance width="1545"/>
+ <unicode hex="004E"/>
+ <anchor x="1240" y="0" name="H"/>
+ <anchor x="765" y="-100" name="L"/>
+ <anchor x="765" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="223" y="1310" type="line"/>
+ <point x="1095" y="0" type="line"/>
+ <point x="1297" y="150" type="line"/>
+ <point x="425" y="1460" type="line"/>
+ </contour>
+ <contour>
+ <point x="1095" y="0" type="line"/>
+ <point x="1355" y="0" type="line"/>
+ <point x="1355" y="1025" type="line" smooth="yes"/>
+ <point x="1355" y="1222"/>
+ <point x="1356" y="1380"/>
+ <point x="1370" y="1460" type="curve"/>
+ <point x="1095" y="1460" type="line"/>
+ </contour>
+ <contour>
+ <point x="425" y="1460" type="line"/>
+ <point x="150" y="1460" type="line"/>
+ <point x="165" y="1380"/>
+ <point x="165" y="1222"/>
+ <point x="165" y="1025" type="curve" smooth="yes"/>
+ <point x="165" y="435" type="line" smooth="yes"/>
+ <point x="165" y="238"/>
+ <point x="165" y="80"/>
+ <point x="150" y="0" type="curve"/>
+ <point x="425" y="0" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetassocuids.ufo/glyphs/L_tnC_apO_.glif b/tests/reference/ufo/psfsetassocuids.ufo/glyphs/L_tnC_apO_.glif
new file mode 100644
index 0000000..10479ad
--- /dev/null
+++ b/tests/reference/ufo/psfsetassocuids.ufo/glyphs/L_tnC_apO_.glif
@@ -0,0 +1,40 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnCapO" format="2">
+ <advance width="1500"/>
+ <unicode hex="004F"/>
+ <anchor x="740" y="0" name="H"/>
+ <anchor x="740" y="-100" name="L"/>
+ <anchor x="976" y="0" name="O"/>
+ <anchor x="1480" y="1200" name="R"/>
+ <anchor x="740" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="1100" y="715" type="curve" smooth="yes"/>
+ <point x="1100" y="404"/>
+ <point x="940" y="220"/>
+ <point x="740" y="220" type="curve" smooth="yes"/>
+ <point x="524" y="220"/>
+ <point x="375" y="423"/>
+ <point x="375" y="745" type="curve" smooth="yes"/>
+ <point x="375" y="1048"/>
+ <point x="529" y="1240"/>
+ <point x="740" y="1240" type="curve" smooth="yes"/>
+ <point x="951" y="1240"/>
+ <point x="1100" y="1041"/>
+ </contour>
+ <contour>
+ <point x="1385" y="740" type="curve" smooth="yes"/>
+ <point x="1385" y="1219"/>
+ <point x="1091" y="1485"/>
+ <point x="750" y="1485" type="curve" smooth="yes"/>
+ <point x="404" y="1485"/>
+ <point x="90" y="1199"/>
+ <point x="90" y="720" type="curve" smooth="yes"/>
+ <point x="90" y="241"/>
+ <point x="385" y="-25"/>
+ <point x="730" y="-25" type="curve" smooth="yes"/>
+ <point x="1072" y="-25"/>
+ <point x="1385" y="260"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetassocuids.ufo/glyphs/L_tnC_apP_.glif b/tests/reference/ufo/psfsetassocuids.ufo/glyphs/L_tnC_apP_.glif
new file mode 100644
index 0000000..18e9ee0
--- /dev/null
+++ b/tests/reference/ufo/psfsetassocuids.ufo/glyphs/L_tnC_apP_.glif
@@ -0,0 +1,50 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnCapP" format="2">
+ <advance width="1275"/>
+ <unicode hex="0050"/>
+ <anchor x="685" y="-100" name="L"/>
+ <anchor x="685" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="450" y="523" type="line"/>
+ <point x="515" y="516"/>
+ <point x="575" y="513"/>
+ <point x="648" y="513" type="curve" smooth="yes"/>
+ <point x="977" y="513"/>
+ <point x="1200" y="702"/>
+ <point x="1200" y="1010" type="curve" smooth="yes"/>
+ <point x="1200" y="1316"/>
+ <point x="981" y="1470"/>
+ <point x="658" y="1470" type="curve" smooth="yes"/>
+ <point x="445" y="1470"/>
+ <point x="150" y="1460"/>
+ <point x="150" y="1460" type="curve"/>
+ <point x="165" y="1380"/>
+ <point x="165" y="1196"/>
+ <point x="165" y="1000" type="curve" smooth="yes"/>
+ <point x="165" y="435" type="line" smooth="yes"/>
+ <point x="165" y="238"/>
+ <point x="165" y="80"/>
+ <point x="150" y="0" type="curve"/>
+ <point x="465" y="0" type="line"/>
+ <point x="451" y="78"/>
+ <point x="450" y="237"/>
+ <point x="450" y="435" type="curve" smooth="yes"/>
+ </contour>
+ <contour>
+ <point x="450" y="1240" type="line"/>
+ <point x="506" y="1243"/>
+ <point x="544" y="1245"/>
+ <point x="622" y="1245" type="curve" smooth="yes"/>
+ <point x="833" y="1245"/>
+ <point x="915" y="1145"/>
+ <point x="915" y="1000" type="curve" smooth="yes"/>
+ <point x="915" y="820"/>
+ <point x="811" y="730"/>
+ <point x="618" y="730" type="curve" smooth="yes"/>
+ <point x="556" y="730"/>
+ <point x="493" y="733"/>
+ <point x="450" y="740" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetassocuids.ufo/glyphs/L_tnC_apQ_.glif b/tests/reference/ufo/psfsetassocuids.ufo/glyphs/L_tnC_apQ_.glif
new file mode 100644
index 0000000..433087c
--- /dev/null
+++ b/tests/reference/ufo/psfsetassocuids.ufo/glyphs/L_tnC_apQ_.glif
@@ -0,0 +1,49 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnCapQ" format="2">
+ <advance width="1545"/>
+ <unicode hex="0051"/>
+ <anchor x="747" y="-270" name="L"/>
+ <anchor x="747" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="1385" y="740" type="curve" smooth="yes"/>
+ <point x="1385" y="1219"/>
+ <point x="1091" y="1485"/>
+ <point x="750" y="1485" type="curve" smooth="yes"/>
+ <point x="404" y="1485"/>
+ <point x="90" y="1199"/>
+ <point x="90" y="720" type="curve" smooth="yes"/>
+ <point x="90" y="241"/>
+ <point x="385" y="-25"/>
+ <point x="730" y="-25" type="curve" smooth="yes"/>
+ <point x="807" y="-25"/>
+ <point x="840" y="-23"/>
+ <point x="889" y="-15" type="curve"/>
+ <point x="958" y="-15"/>
+ <point x="1266" y="-228"/>
+ <point x="1350" y="-228" type="curve" smooth="yes"/>
+ <point x="1424" y="-228"/>
+ <point x="1502" y="-68"/>
+ <point x="1535" y="-15" type="curve"/>
+ <point x="1394" y="1"/>
+ <point x="1277" y="68"/>
+ <point x="1146" y="142" type="curve"/>
+ <point x="1294" y="283"/>
+ <point x="1385" y="471"/>
+ </contour>
+ <contour>
+ <point x="1100" y="715" type="curve" smooth="yes"/>
+ <point x="1100" y="404"/>
+ <point x="943" y="220"/>
+ <point x="740" y="220" type="curve" smooth="yes"/>
+ <point x="524" y="220"/>
+ <point x="375" y="423"/>
+ <point x="375" y="745" type="curve" smooth="yes"/>
+ <point x="375" y="1048"/>
+ <point x="529" y="1240"/>
+ <point x="740" y="1240" type="curve" smooth="yes"/>
+ <point x="951" y="1240"/>
+ <point x="1100" y="1041"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetassocuids.ufo/glyphs/L_tnC_apR_.glif b/tests/reference/ufo/psfsetassocuids.ufo/glyphs/L_tnC_apR_.glif
new file mode 100644
index 0000000..6103056
--- /dev/null
+++ b/tests/reference/ufo/psfsetassocuids.ufo/glyphs/L_tnC_apR_.glif
@@ -0,0 +1,55 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnCapR" format="2">
+ <advance width="1380"/>
+ <unicode hex="0052"/>
+ <anchor x="690" y="0" name="H"/>
+ <anchor x="690" y="-100" name="L"/>
+ <anchor x="660" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="450" y="585" type="line"/>
+ <point x="625" y="585" type="line" smooth="yes"/>
+ <point x="910" y="585"/>
+ <point x="1175" y="723"/>
+ <point x="1175" y="1040" type="curve" smooth="yes"/>
+ <point x="1175" y="1329"/>
+ <point x="961" y="1470"/>
+ <point x="650" y="1470" type="curve" smooth="yes"/>
+ <point x="416" y="1470"/>
+ <point x="150" y="1460"/>
+ <point x="150" y="1460" type="curve"/>
+ <point x="165" y="1380"/>
+ <point x="165" y="1196"/>
+ <point x="165" y="1000" type="curve" smooth="yes"/>
+ <point x="165" y="435" type="line" smooth="yes"/>
+ <point x="165" y="238"/>
+ <point x="165" y="80"/>
+ <point x="150" y="0" type="curve"/>
+ <point x="465" y="0" type="line"/>
+ <point x="451" y="78"/>
+ <point x="450" y="238"/>
+ <point x="450" y="435" type="curve" smooth="yes"/>
+ </contour>
+ <contour>
+ <point x="450" y="1240" type="line"/>
+ <point x="503" y="1243"/>
+ <point x="537" y="1245"/>
+ <point x="615" y="1245" type="curve" smooth="yes"/>
+ <point x="792" y="1245"/>
+ <point x="890" y="1186"/>
+ <point x="890" y="1035" type="curve" smooth="yes"/>
+ <point x="890" y="859"/>
+ <point x="780" y="800"/>
+ <point x="605" y="800" type="curve" smooth="yes"/>
+ <point x="450" y="800" type="line"/>
+ </contour>
+ <contour>
+ <point x="556" y="635" type="line"/>
+ <point x="975" y="0" type="line"/>
+ <point x="1330" y="0" type="line"/>
+ <point x="1263" y="73"/>
+ <point x="827" y="687"/>
+ <point x="827" y="687" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetassocuids.ufo/glyphs/L_tnC_apS_.glif b/tests/reference/ufo/psfsetassocuids.ufo/glyphs/L_tnC_apS_.glif
new file mode 100644
index 0000000..486ff77
--- /dev/null
+++ b/tests/reference/ufo/psfsetassocuids.ufo/glyphs/L_tnC_apS_.glif
@@ -0,0 +1,50 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnCapS" format="2">
+ <advance width="1243"/>
+ <unicode hex="0053"/>
+ <anchor x="616" y="0" name="H"/>
+ <anchor x="616" y="-100" name="L"/>
+ <anchor x="616" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="1075" y="1395" type="line"/>
+ <point x="932" y="1458"/>
+ <point x="810" y="1485"/>
+ <point x="640" y="1485" type="curve" smooth="yes"/>
+ <point x="280" y="1485"/>
+ <point x="130" y="1239"/>
+ <point x="130" y="1060" type="curve" smooth="yes"/>
+ <point x="130" y="882"/>
+ <point x="196" y="754"/>
+ <point x="510" y="655" type="curve" smooth="yes"/>
+ <point x="800" y="563"/>
+ <point x="851" y="504"/>
+ <point x="851" y="420" type="curve" smooth="yes"/>
+ <point x="851" y="293"/>
+ <point x="730" y="220"/>
+ <point x="600" y="220" type="curve" smooth="yes"/>
+ <point x="439" y="220"/>
+ <point x="283" y="270"/>
+ <point x="140" y="385" type="curve"/>
+ <point x="90" y="110" type="line"/>
+ <point x="201" y="31"/>
+ <point x="391" y="-25"/>
+ <point x="600" y="-25" type="curve" smooth="yes"/>
+ <point x="895" y="-25"/>
+ <point x="1138" y="169"/>
+ <point x="1138" y="455" type="curve" smooth="yes"/>
+ <point x="1138" y="666"/>
+ <point x="994" y="787"/>
+ <point x="727" y="870" type="curve" smooth="yes"/>
+ <point x="464" y="952"/>
+ <point x="416" y="994"/>
+ <point x="416" y="1080" type="curve" smooth="yes"/>
+ <point x="416" y="1162"/>
+ <point x="506" y="1245"/>
+ <point x="630" y="1245" type="curve" smooth="yes"/>
+ <point x="771" y="1245"/>
+ <point x="873" y="1209"/>
+ <point x="1030" y="1130" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetassocuids.ufo/glyphs/L_tnC_apT_.glif b/tests/reference/ufo/psfsetassocuids.ufo/glyphs/L_tnC_apT_.glif
new file mode 100644
index 0000000..5f87c10
--- /dev/null
+++ b/tests/reference/ufo/psfsetassocuids.ufo/glyphs/L_tnC_apT_.glif
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnCapT" format="2">
+ <advance width="1275"/>
+ <unicode hex="0054"/>
+ <anchor x="632" y="0" name="H"/>
+ <anchor x="632" y="-100" name="L"/>
+ <anchor x="632" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="45" y="1460" type="line"/>
+ <point x="45" y="1210" type="line"/>
+ <point x="117" y="1227"/>
+ <point x="196" y="1230"/>
+ <point x="276" y="1230" type="curve" smooth="yes"/>
+ <point x="488" y="1230" type="line"/>
+ <point x="488" y="413" type="line" smooth="yes"/>
+ <point x="488" y="226"/>
+ <point x="485" y="76"/>
+ <point x="468" y="0" type="curve"/>
+ <point x="793" y="0" type="line"/>
+ <point x="776" y="76"/>
+ <point x="773" y="226"/>
+ <point x="773" y="413" type="curve" smooth="yes"/>
+ <point x="773" y="1230" type="line"/>
+ <point x="989" y="1230" type="line" smooth="yes"/>
+ <point x="1070" y="1230"/>
+ <point x="1148" y="1227"/>
+ <point x="1220" y="1210" type="curve"/>
+ <point x="1220" y="1460" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetassocuids.ufo/glyphs/L_tnC_apU_.glif b/tests/reference/ufo/psfsetassocuids.ufo/glyphs/L_tnC_apU_.glif
new file mode 100644
index 0000000..343e0f2
--- /dev/null
+++ b/tests/reference/ufo/psfsetassocuids.ufo/glyphs/L_tnC_apU_.glif
@@ -0,0 +1,46 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnCapU" format="2">
+ <advance width="1490"/>
+ <unicode hex="0055"/>
+ <anchor x="732" y="0" name="H"/>
+ <anchor x="732" y="-100" name="L"/>
+ <anchor x="950" y="0" name="O"/>
+ <anchor x="1480" y="1200" name="R"/>
+ <anchor x="732" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="1015" y="1460" type="line"/>
+ <point x="1015" y="560" type="line" smooth="yes"/>
+ <point x="1015" y="344"/>
+ <point x="952" y="204"/>
+ <point x="735" y="204" type="curve" smooth="yes"/>
+ <point x="513" y="204"/>
+ <point x="450" y="344"/>
+ <point x="450" y="560" type="curve" smooth="yes"/>
+ <point x="450" y="1460" type="line"/>
+ <point x="150" y="1460" type="line"/>
+ <point x="164" y="1380"/>
+ <point x="165" y="1222"/>
+ <point x="165" y="1025" type="curve" smooth="yes"/>
+ <point x="165" y="515" type="line" smooth="yes"/>
+ <point x="165" y="190"/>
+ <point x="356" y="-25"/>
+ <point x="735" y="-25" type="curve" smooth="yes"/>
+ <point x="1110" y="-25"/>
+ <point x="1300" y="190"/>
+ <point x="1300" y="515" type="curve" smooth="yes"/>
+ <point x="1300" y="1025" type="line" smooth="yes"/>
+ <point x="1300" y="1232"/>
+ <point x="1302" y="1380"/>
+ <point x="1315" y="1460" type="curve"/>
+ </contour>
+ </outline>
+ <lib>
+ <dict>
+ <key>org.sil.assocUIDs</key>
+ <array>
+ <string>00fA</string>
+ </array>
+ </dict>
+ </lib>
+</glyph>
diff --git a/tests/reference/ufo/psfsetassocuids.ufo/glyphs/L_tnC_apV_.glif b/tests/reference/ufo/psfsetassocuids.ufo/glyphs/L_tnC_apV_.glif
new file mode 100644
index 0000000..3468784
--- /dev/null
+++ b/tests/reference/ufo/psfsetassocuids.ufo/glyphs/L_tnC_apV_.glif
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnCapV" format="2">
+ <advance width="1465"/>
+ <unicode hex="0056"/>
+ <anchor x="730" y="0" name="H"/>
+ <anchor x="722" y="-100" name="L"/>
+ <anchor x="930" y="0" name="O"/>
+ <anchor x="722" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="1115" y="1460" type="line"/>
+ <point x="722" y="260" type="line"/>
+ <point x="330" y="1460" type="line"/>
+ <point x="25" y="1460" type="line"/>
+ <point x="58" y="1378"/>
+ <point x="96" y="1288"/>
+ <point x="165" y="1095" type="curve" smooth="yes"/>
+ <point x="555" y="0" type="line"/>
+ <point x="890" y="0" type="line"/>
+ <point x="1280" y="1095" type="line" smooth="yes"/>
+ <point x="1348" y="1289"/>
+ <point x="1384" y="1378"/>
+ <point x="1420" y="1460" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetassocuids.ufo/glyphs/L_tnC_apW_.glif b/tests/reference/ufo/psfsetassocuids.ufo/glyphs/L_tnC_apW_.glif
new file mode 100644
index 0000000..98329a0
--- /dev/null
+++ b/tests/reference/ufo/psfsetassocuids.ufo/glyphs/L_tnC_apW_.glif
@@ -0,0 +1,45 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnCapW" format="2">
+ <advance width="2135"/>
+ <unicode hex="0057"/>
+ <anchor x="1052" y="-100" name="L"/>
+ <anchor x="1052" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="1490" y="0" type="line"/>
+ <point x="1655" y="0" type="line"/>
+ <point x="1965" y="1095" type="line" smooth="yes"/>
+ <point x="2020" y="1289"/>
+ <point x="2048" y="1378"/>
+ <point x="2080" y="1460" type="curve"/>
+ <point x="1770" y="1460" type="line"/>
+ <point x="1470" y="130" type="line"/>
+ </contour>
+ <contour>
+ <point x="1180" y="1460" type="line"/>
+ <point x="920" y="1460" type="line"/>
+ <point x="995" y="1305" type="line"/>
+ <point x="1340" y="0" type="line"/>
+ <point x="1510" y="0" type="line"/>
+ <point x="1530" y="130" type="line"/>
+ </contour>
+ <contour>
+ <point x="600" y="0" type="line"/>
+ <point x="765" y="0" type="line"/>
+ <point x="1105" y="1305" type="line"/>
+ <point x="1180" y="1460" type="line"/>
+ <point x="920" y="1460" type="line"/>
+ <point x="580" y="130" type="line"/>
+ </contour>
+ <contour>
+ <point x="340" y="1460" type="line"/>
+ <point x="30" y="1460" type="line"/>
+ <point x="61" y="1381"/>
+ <point x="92" y="1286"/>
+ <point x="145" y="1095" type="curve" smooth="yes"/>
+ <point x="450" y="0" type="line"/>
+ <point x="620" y="0" type="line"/>
+ <point x="640" y="130" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetassocuids.ufo/glyphs/L_tnC_apX_.glif b/tests/reference/ufo/psfsetassocuids.ufo/glyphs/L_tnC_apX_.glif
new file mode 100644
index 0000000..17126dd
--- /dev/null
+++ b/tests/reference/ufo/psfsetassocuids.ufo/glyphs/L_tnC_apX_.glif
@@ -0,0 +1,39 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnCapX" format="2">
+ <advance width="1365"/>
+ <unicode hex="0058"/>
+ <anchor x="670" y="-100" name="L"/>
+ <anchor x="670" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="990" y="0" type="line"/>
+ <point x="1310" y="0" type="line"/>
+ <point x="1249" y="82"/>
+ <point x="1211" y="125"/>
+ <point x="1083" y="336" type="curve" smooth="yes"/>
+ <point x="400" y="1460" type="line"/>
+ <point x="75" y="1460" type="line"/>
+ <point x="139" y="1376"/>
+ <point x="189" y="1317"/>
+ <point x="315" y="1110" type="curve"/>
+ </contour>
+ <contour>
+ <point x="605" y="947" type="line"/>
+ <point x="255" y="340" type="line" smooth="yes"/>
+ <point x="133" y="128"/>
+ <point x="93" y="86"/>
+ <point x="30" y="0" type="curve"/>
+ <point x="350" y="0" type="line"/>
+ <point x="700" y="609" type="line"/>
+ </contour>
+ <contour>
+ <point x="750" y="609" type="line"/>
+ <point x="1040" y="1110" type="line" smooth="yes"/>
+ <point x="1153" y="1306"/>
+ <point x="1211" y="1383"/>
+ <point x="1275" y="1460" type="curve"/>
+ <point x="950" y="1460" type="line"/>
+ <point x="655" y="947" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetassocuids.ufo/glyphs/L_tnC_apY_.glif b/tests/reference/ufo/psfsetassocuids.ufo/glyphs/L_tnC_apY_.glif
new file mode 100644
index 0000000..a7a345d
--- /dev/null
+++ b/tests/reference/ufo/psfsetassocuids.ufo/glyphs/L_tnC_apY_.glif
@@ -0,0 +1,39 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnCapY" format="2">
+ <advance width="1364"/>
+ <unicode hex="0059"/>
+ <anchor x="672" y="-100" name="L"/>
+ <anchor x="672" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="575" y="560" type="line"/>
+ <point x="782" y="675" type="line"/>
+ <point x="357" y="1460" type="line"/>
+ <point x="25" y="1460" type="line"/>
+ <point x="137" y="1311"/>
+ <point x="203" y="1197"/>
+ <point x="280" y="1065" type="curve" smooth="yes"/>
+ </contour>
+ <contour>
+ <point x="770" y="560" type="line"/>
+ <point x="1069" y="1065" type="line" smooth="yes"/>
+ <point x="1145" y="1195"/>
+ <point x="1201" y="1291"/>
+ <point x="1319" y="1460" type="curve"/>
+ <point x="997" y="1460" type="line"/>
+ <point x="577" y="675" type="line"/>
+ </contour>
+ <contour>
+ <point x="530" y="695" type="line"/>
+ <point x="530" y="435" type="line" smooth="yes"/>
+ <point x="530" y="238"/>
+ <point x="530" y="80"/>
+ <point x="515" y="0" type="curve"/>
+ <point x="830" y="0" type="line"/>
+ <point x="815" y="80"/>
+ <point x="815" y="238"/>
+ <point x="815" y="435" type="curve" smooth="yes"/>
+ <point x="815" y="695" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetassocuids.ufo/glyphs/L_tnS_mA_.glif b/tests/reference/ufo/psfsetassocuids.ufo/glyphs/L_tnS_mA_.glif
new file mode 100644
index 0000000..7885750
--- /dev/null
+++ b/tests/reference/ufo/psfsetassocuids.ufo/glyphs/L_tnS_mA_.glif
@@ -0,0 +1,76 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmA" format="2">
+ <advance width="1205"/>
+ <unicode hex="0061"/>
+ <note>
+
+
+
+
+ GlyphNote A
+
+
+
+
+ </note>
+ <anchor x="985" y="0" name="H"/>
+ <anchor x="610" y="-100" name="L"/>
+ <anchor x="1185" y="0" name="O"/>
+ <anchor x="1145" y="1000" name="R"/>
+ <anchor x="610" y="1100" name="U"/>
+ <outline>
+ <contour>
+ <point x="1120" y="0" type="line"/>
+ <point x="1078" y="112"/>
+ <point x="1050" y="226"/>
+ <point x="1050" y="370" type="curve"/>
+ <point x="1050" y="760" type="line"/>
+ <point x="1050" y="919"/>
+ <point x="877" y="1040"/>
+ <point x="615" y="1040" type="curve" smooth="yes"/>
+ <point x="446" y="1040"/>
+ <point x="330" y="994"/>
+ <point x="216" y="950" type="curve"/>
+ <point x="210" y="868"/>
+ <point x="207" y="735"/>
+ <point x="206" y="691" type="curve"/>
+ <point x="323" y="773"/>
+ <point x="424" y="816"/>
+ <point x="530" y="816" type="curve" smooth="yes"/>
+ <point x="680" y="816"/>
+ <point x="770" y="785"/>
+ <point x="770" y="710" type="curve" smooth="yes"/>
+ <point x="770" y="660" type="line"/>
+ <point x="729" y="659"/>
+ <point x="569" y="649"/>
+ <point x="500" y="642" type="curve" smooth="yes"/>
+ <point x="191" y="612"/>
+ <point x="100" y="438"/>
+ <point x="100" y="285" type="curve" smooth="yes"/>
+ <point x="100" y="121"/>
+ <point x="245" y="-25"/>
+ <point x="445" y="-25" type="curve" smooth="yes"/>
+ <point x="562" y="-25"/>
+ <point x="688" y="23"/>
+ <point x="800" y="135" type="curve"/>
+ <point x="814" y="79"/>
+ <point x="838" y="28"/>
+ <point x="850" y="0" type="curve"/>
+ </contour>
+ <contour>
+ <point x="770" y="355" type="line"/>
+ <point x="674" y="225"/>
+ <point x="600" y="205"/>
+ <point x="518" y="205" type="curve" smooth="yes"/>
+ <point x="436" y="205"/>
+ <point x="380" y="256"/>
+ <point x="380" y="320" type="curve" smooth="yes"/>
+ <point x="380" y="386"/>
+ <point x="422" y="442"/>
+ <point x="560" y="457" type="curve" smooth="yes"/>
+ <point x="611" y="463"/>
+ <point x="730" y="474"/>
+ <point x="770" y="475" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetassocuids.ufo/glyphs/L_tnS_mA_A_cute.glif b/tests/reference/ufo/psfsetassocuids.ufo/glyphs/L_tnS_mA_A_cute.glif
new file mode 100644
index 0000000..f1c66a5
--- /dev/null
+++ b/tests/reference/ufo/psfsetassocuids.ufo/glyphs/L_tnS_mA_A_cute.glif
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmAAcute" format="2">
+ <advance width="1205"/>
+ <unicode hex="00E1"/>
+ <anchor x="985" y="0" name="H"/>
+ <anchor x="610" y="-100" name="L"/>
+ <anchor x="1185" y="0" name="O"/>
+ <anchor x="1145" y="1000" name="R"/>
+ <anchor x="550" y="1635" name="U"/>
+ <outline>
+ <component base="LtnSmA"/>
+ <component base="CombAcute" xOffset="1150"/>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetassocuids.ufo/glyphs/L_tnS_mA_C_ircum.glif b/tests/reference/ufo/psfsetassocuids.ufo/glyphs/L_tnS_mA_C_ircum.glif
new file mode 100644
index 0000000..218d694
--- /dev/null
+++ b/tests/reference/ufo/psfsetassocuids.ufo/glyphs/L_tnS_mA_C_ircum.glif
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmACircum" format="2">
+ <advance width="1205"/>
+ <unicode hex="00E2"/>
+ <anchor x="985" y="0" name="H"/>
+ <anchor x="610" y="-100" name="L"/>
+ <anchor x="1185" y="0" name="O"/>
+ <anchor x="1145" y="1000" name="R"/>
+ <anchor x="602" y="1635" name="U"/>
+ <outline>
+ <component base="LtnSmA"/>
+ <component base="CombCircum" xOffset="1190"/>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetassocuids.ufo/glyphs/L_tnS_mA_D_iaer.glif b/tests/reference/ufo/psfsetassocuids.ufo/glyphs/L_tnS_mA_D_iaer.glif
new file mode 100644
index 0000000..bb0ea2c
--- /dev/null
+++ b/tests/reference/ufo/psfsetassocuids.ufo/glyphs/L_tnS_mA_D_iaer.glif
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmADiaer" format="2">
+ <advance width="1205"/>
+ <unicode hex="00E4"/>
+ <anchor x="985" y="0" name="H"/>
+ <anchor x="610" y="-100" name="L"/>
+ <anchor x="1185" y="0" name="O"/>
+ <anchor x="1145" y="1000" name="R"/>
+ <anchor x="610" y="1585" name="U"/>
+ <outline>
+ <component base="LtnSmA"/>
+ <component base="CombDiaer" xOffset="1190"/>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetassocuids.ufo/glyphs/L_tnS_mA_G_rave.glif b/tests/reference/ufo/psfsetassocuids.ufo/glyphs/L_tnS_mA_G_rave.glif
new file mode 100644
index 0000000..3153364
--- /dev/null
+++ b/tests/reference/ufo/psfsetassocuids.ufo/glyphs/L_tnS_mA_G_rave.glif
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmAGrave" format="2">
+ <advance width="1205"/>
+ <unicode hex="00E0"/>
+ <anchor x="985" y="0" name="H"/>
+ <anchor x="610" y="-100" name="L"/>
+ <anchor x="1185" y="0" name="O"/>
+ <anchor x="1145" y="1000" name="R"/>
+ <anchor x="650" y="1635" name="U"/>
+ <outline>
+ <component base="LtnSmA"/>
+ <component base="CombGrave" xOffset="1240"/>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetassocuids.ufo/glyphs/L_tnS_mA_R_ingA_bv.glif b/tests/reference/ufo/psfsetassocuids.ufo/glyphs/L_tnS_mA_R_ingA_bv.glif
new file mode 100644
index 0000000..3b8da5a
--- /dev/null
+++ b/tests/reference/ufo/psfsetassocuids.ufo/glyphs/L_tnS_mA_R_ingA_bv.glif
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmARingAbv" format="2">
+ <advance width="1205"/>
+ <unicode hex="00E5"/>
+ <anchor x="985" y="0" name="H"/>
+ <anchor x="610" y="-100" name="L"/>
+ <anchor x="1185" y="0" name="O"/>
+ <anchor x="1145" y="1000" name="R"/>
+ <anchor x="612" y="1635" name="U"/>
+ <outline>
+ <component base="LtnSmA"/>
+ <component base="CombRingAbv" xOffset="1182"/>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetassocuids.ufo/glyphs/L_tnS_mA_T_ilde.glif b/tests/reference/ufo/psfsetassocuids.ufo/glyphs/L_tnS_mA_T_ilde.glif
new file mode 100644
index 0000000..b3a8515
--- /dev/null
+++ b/tests/reference/ufo/psfsetassocuids.ufo/glyphs/L_tnS_mA_T_ilde.glif
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmATilde" format="2">
+ <advance width="1205"/>
+ <unicode hex="00E3"/>
+ <anchor x="985" y="0" name="H"/>
+ <anchor x="610" y="-100" name="L"/>
+ <anchor x="1185" y="0" name="O"/>
+ <anchor x="1145" y="1000" name="R"/>
+ <anchor x="610" y="1490" name="U"/>
+ <outline>
+ <component base="LtnSmA"/>
+ <component base="CombTilde" xOffset="1190"/>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetassocuids.ufo/glyphs/L_tnS_mB_.glif b/tests/reference/ufo/psfsetassocuids.ufo/glyphs/L_tnS_mB_.glif
new file mode 100644
index 0000000..6cc6671
--- /dev/null
+++ b/tests/reference/ufo/psfsetassocuids.ufo/glyphs/L_tnS_mB_.glif
@@ -0,0 +1,50 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmB" format="2">
+ <advance width="1215"/>
+ <unicode hex="0062"/>
+ <anchor x="610" y="0" name="H"/>
+ <anchor x="610" y="-100" name="L"/>
+ <anchor x="1215" y="1000" name="R"/>
+ <anchor x="610" y="1635" name="U"/>
+ <outline>
+ <contour>
+ <point x="120" y="1600" type="line"/>
+ <point x="135" y="1488"/>
+ <point x="135" y="1273"/>
+ <point x="135" y="1130" type="curve" smooth="yes"/>
+ <point x="135" y="936"/>
+ <point x="135" y="228"/>
+ <point x="135" y="65" type="curve"/>
+ <point x="286" y="26"/>
+ <point x="457" y="-25"/>
+ <point x="650" y="-25" type="curve" smooth="yes"/>
+ <point x="939" y="-25"/>
+ <point x="1125" y="197"/>
+ <point x="1125" y="540" type="curve" smooth="yes"/>
+ <point x="1125" y="832"/>
+ <point x="986" y="1040"/>
+ <point x="789" y="1040" type="curve" smooth="yes"/>
+ <point x="626" y="1040"/>
+ <point x="505" y="956"/>
+ <point x="415" y="845" type="curve"/>
+ <point x="415" y="934"/>
+ <point x="415" y="1600"/>
+ <point x="415" y="1600" type="curve"/>
+ </contour>
+ <contour>
+ <point x="415" y="585" type="line"/>
+ <point x="471" y="709"/>
+ <point x="580" y="795"/>
+ <point x="683" y="795" type="curve" smooth="yes"/>
+ <point x="793" y="795"/>
+ <point x="855" y="684"/>
+ <point x="855" y="505" type="curve" smooth="yes"/>
+ <point x="855" y="317"/>
+ <point x="750" y="190"/>
+ <point x="605" y="190" type="curve" smooth="yes"/>
+ <point x="538" y="190"/>
+ <point x="492" y="204"/>
+ <point x="415" y="240" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetassocuids.ufo/glyphs/L_tnS_mC_.glif b/tests/reference/ufo/psfsetassocuids.ufo/glyphs/L_tnS_mC_.glif
new file mode 100644
index 0000000..19a8a6d
--- /dev/null
+++ b/tests/reference/ufo/psfsetassocuids.ufo/glyphs/L_tnS_mC_.glif
@@ -0,0 +1,39 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmC" format="2">
+ <advance width="1022"/>
+ <unicode hex="0063"/>
+ <anchor x="555" y="0" name="H"/>
+ <anchor x="575" y="-100" name="L"/>
+ <anchor x="1020" y="1000" name="R"/>
+ <anchor x="575" y="1100" name="U"/>
+ <outline>
+ <contour>
+ <point x="922" y="969" type="line"/>
+ <point x="849" y="1007"/>
+ <point x="744" y="1040"/>
+ <point x="612" y="1040" type="curve" smooth="yes"/>
+ <point x="295" y="1040"/>
+ <point x="90" y="802"/>
+ <point x="90" y="490" type="curve" smooth="yes"/>
+ <point x="90" y="161"/>
+ <point x="309" y="-25"/>
+ <point x="578" y="-25" type="curve" smooth="yes"/>
+ <point x="727" y="-25"/>
+ <point x="831" y="8"/>
+ <point x="932" y="70" type="curve"/>
+ <point x="902" y="314" type="line"/>
+ <point x="815" y="245"/>
+ <point x="737" y="205"/>
+ <point x="617" y="205" type="curve" smooth="yes"/>
+ <point x="467" y="205"/>
+ <point x="370" y="324"/>
+ <point x="370" y="500" type="curve" smooth="yes"/>
+ <point x="370" y="694"/>
+ <point x="478" y="810"/>
+ <point x="617" y="810" type="curve" smooth="yes"/>
+ <point x="720" y="810"/>
+ <point x="788" y="779"/>
+ <point x="878" y="717" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetassocuids.ufo/glyphs/L_tnS_mD_.glif b/tests/reference/ufo/psfsetassocuids.ufo/glyphs/L_tnS_mD_.glif
new file mode 100644
index 0000000..fc1cc76
--- /dev/null
+++ b/tests/reference/ufo/psfsetassocuids.ufo/glyphs/L_tnS_mD_.glif
@@ -0,0 +1,53 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmD" format="2">
+ <advance width="1265"/>
+ <unicode hex="0064"/>
+ <anchor x="595" y="0" name="H"/>
+ <anchor x="595" y="-100" name="L"/>
+ <anchor x="1285" y="1000" name="R"/>
+ <anchor x="610" y="1635" name="U"/>
+ <outline>
+ <contour>
+ <point x="1115" y="1600" type="line"/>
+ <point x="810" y="1600" type="line"/>
+ <point x="829" y="1516"/>
+ <point x="835" y="1395"/>
+ <point x="835" y="1235" type="curve" smooth="yes"/>
+ <point x="835" y="955" type="line"/>
+ <point x="763" y="999"/>
+ <point x="669" y="1040"/>
+ <point x="590" y="1040" type="curve" smooth="yes"/>
+ <point x="319" y="1040"/>
+ <point x="100" y="814"/>
+ <point x="100" y="460" type="curve" smooth="yes"/>
+ <point x="100" y="167"/>
+ <point x="268" y="-25"/>
+ <point x="515" y="-25" type="curve" smooth="yes"/>
+ <point x="654" y="-25"/>
+ <point x="770" y="47"/>
+ <point x="860" y="175" type="curve"/>
+ <point x="877" y="105"/>
+ <point x="900" y="32"/>
+ <point x="915" y="0" type="curve"/>
+ <point x="1190" y="0" type="line"/>
+ <point x="1147" y="112"/>
+ <point x="1115" y="278"/>
+ <point x="1115" y="530" type="curve" smooth="yes"/>
+ </contour>
+ <contour>
+ <point x="835" y="400" type="line"/>
+ <point x="787" y="300"/>
+ <point x="676" y="200"/>
+ <point x="570" y="200" type="curve" smooth="yes"/>
+ <point x="443" y="200"/>
+ <point x="380" y="300"/>
+ <point x="380" y="490" type="curve" smooth="yes"/>
+ <point x="380" y="685"/>
+ <point x="485" y="800"/>
+ <point x="590" y="800" type="curve" smooth="yes"/>
+ <point x="683" y="800"/>
+ <point x="743" y="783"/>
+ <point x="835" y="738" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetassocuids.ufo/glyphs/L_tnS_mE_.glif b/tests/reference/ufo/psfsetassocuids.ufo/glyphs/L_tnS_mE_.glif
new file mode 100644
index 0000000..5c67455
--- /dev/null
+++ b/tests/reference/ufo/psfsetassocuids.ufo/glyphs/L_tnS_mE_.glif
@@ -0,0 +1,45 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmE" format="2">
+ <advance width="1110"/>
+ <unicode hex="0065"/>
+ <anchor x="569" y="0" name="H"/>
+ <anchor x="589" y="-100" name="L"/>
+ <anchor x="900" y="0" name="O"/>
+ <anchor x="1130" y="1000" name="R"/>
+ <anchor x="537" y="1100" name="U"/>
+ <outline>
+ <contour>
+ <point x="1010" y="450" type="line"/>
+ <point x="1010" y="469"/>
+ <point x="1009" y="513"/>
+ <point x="1009" y="532" type="curve" smooth="yes"/>
+ <point x="1009" y="782"/>
+ <point x="924" y="1040"/>
+ <point x="589" y="1040" type="curve" smooth="yes"/>
+ <point x="281" y="1040"/>
+ <point x="90" y="826"/>
+ <point x="90" y="495" type="curve" smooth="yes"/>
+ <point x="90" y="155"/>
+ <point x="324" y="-25"/>
+ <point x="589" y="-25" type="curve" smooth="yes"/>
+ <point x="745" y="-25"/>
+ <point x="871" y="2"/>
+ <point x="1015" y="75" type="curve"/>
+ <point x="994" y="306" type="line"/>
+ <point x="870" y="232"/>
+ <point x="745" y="205"/>
+ <point x="614" y="205" type="curve" smooth="yes"/>
+ <point x="448" y="205"/>
+ <point x="362" y="293"/>
+ <point x="362" y="505" type="curve" smooth="yes"/>
+ <point x="362" y="739"/>
+ <point x="431" y="830"/>
+ <point x="575" y="830" type="curve" smooth="yes"/>
+ <point x="693" y="830"/>
+ <point x="755" y="770"/>
+ <point x="755" y="630" type="curve"/>
+ <point x="242" y="630" type="line"/>
+ <point x="242" y="450" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetassocuids.ufo/glyphs/L_tnS_mF_.glif b/tests/reference/ufo/psfsetassocuids.ufo/glyphs/L_tnS_mF_.glif
new file mode 100644
index 0000000..8a5996d
--- /dev/null
+++ b/tests/reference/ufo/psfsetassocuids.ufo/glyphs/L_tnS_mF_.glif
@@ -0,0 +1,39 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmF" format="2">
+ <advance width="800"/>
+ <unicode hex="0066"/>
+ <anchor x="380" y="0" name="H"/>
+ <anchor x="400" y="-100" name="L"/>
+ <anchor x="600" y="1635" name="U"/>
+ <outline>
+ <contour>
+ <point x="30" y="805" type="line"/>
+ <point x="230" y="805" type="line"/>
+ <point x="230" y="0" type="line"/>
+ <point x="540" y="0" type="line"/>
+ <point x="518" y="105"/>
+ <point x="510" y="300"/>
+ <point x="510" y="494" type="curve" smooth="yes"/>
+ <point x="510" y="805" type="line"/>
+ <point x="765" y="805" type="line"/>
+ <point x="765" y="1005" type="line"/>
+ <point x="510" y="1005" type="line"/>
+ <point x="510" y="1159" type="line" smooth="yes"/>
+ <point x="510" y="1322"/>
+ <point x="552" y="1387"/>
+ <point x="648" y="1387" type="curve" smooth="yes"/>
+ <point x="697" y="1387"/>
+ <point x="765" y="1362"/>
+ <point x="808" y="1322" type="curve"/>
+ <point x="865" y="1550" type="line"/>
+ <point x="806" y="1588"/>
+ <point x="699" y="1620"/>
+ <point x="625" y="1620" type="curve" smooth="yes"/>
+ <point x="378" y="1620"/>
+ <point x="230" y="1470"/>
+ <point x="230" y="1170" type="curve" smooth="yes"/>
+ <point x="230" y="1005" type="line"/>
+ <point x="30" y="1005" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetassocuids.ufo/glyphs/L_tnS_mG_.glif b/tests/reference/ufo/psfsetassocuids.ufo/glyphs/L_tnS_mG_.glif
new file mode 100644
index 0000000..871e4e9
--- /dev/null
+++ b/tests/reference/ufo/psfsetassocuids.ufo/glyphs/L_tnS_mG_.glif
@@ -0,0 +1,91 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmG" format="2">
+ <advance width="1170"/>
+ <unicode hex="0067"/>
+ <anchor x="597" y="-465" name="H"/>
+ <anchor x="597" y="-535" name="L"/>
+ <anchor x="1187" y="1000" name="R"/>
+ <anchor x="567" y="1100" name="U"/>
+ <outline>
+ <contour>
+ <point x="352" y="395" type="line"/>
+ <point x="256" y="357"/>
+ <point x="202" y="275"/>
+ <point x="202" y="215" type="curve" smooth="yes"/>
+ <point x="202" y="113"/>
+ <point x="280" y="12"/>
+ <point x="547" y="-23" type="curve" smooth="yes"/>
+ <point x="797" y="-50"/>
+ <point x="870" y="-99"/>
+ <point x="870" y="-170" type="curve" smooth="yes"/>
+ <point x="870" y="-229"/>
+ <point x="748" y="-302"/>
+ <point x="602" y="-302" type="curve" smooth="yes"/>
+ <point x="418" y="-302"/>
+ <point x="330" y="-235"/>
+ <point x="330" y="-180" type="curve" smooth="yes"/>
+ <point x="330" y="-121"/>
+ <point x="357" y="-56"/>
+ <point x="562" y="20" type="curve"/>
+ <point x="554" y="49"/>
+ <point x="322" y="75"/>
+ <point x="322" y="75" type="curve"/>
+ <point x="138" y="2"/>
+ <point x="50" y="-89"/>
+ <point x="50" y="-200" type="curve" smooth="yes"/>
+ <point x="50" y="-409"/>
+ <point x="341" y="-505"/>
+ <point x="587" y="-505" type="curve" smooth="yes"/>
+ <point x="843" y="-505"/>
+ <point x="1150" y="-375"/>
+ <point x="1150" y="-160" type="curve" smooth="yes"/>
+ <point x="1150" y="13"/>
+ <point x="1049" y="125"/>
+ <point x="752" y="165" type="curve" smooth="yes"/>
+ <point x="497" y="191"/>
+ <point x="433" y="216"/>
+ <point x="433" y="255" type="curve" smooth="yes"/>
+ <point x="433" y="285"/>
+ <point x="472" y="322"/>
+ <point x="588" y="350" type="curve"/>
+ </contour>
+ <contour>
+ <point x="1102" y="1040" type="line"/>
+ <point x="1003" y="1033"/>
+ <point x="871" y="997"/>
+ <point x="782" y="940" type="curve"/>
+ <point x="847" y="770" type="line"/>
+ <point x="939" y="808"/>
+ <point x="1019" y="823"/>
+ <point x="1092" y="825" type="curve"/>
+ </contour>
+ <contour>
+ <point x="122" y="670" type="curve" smooth="yes"/>
+ <point x="122" y="455"/>
+ <point x="316" y="305"/>
+ <point x="567" y="305" type="curve" smooth="yes"/>
+ <point x="820" y="305"/>
+ <point x="1012" y="465"/>
+ <point x="1012" y="680" type="curve" smooth="yes"/>
+ <point x="1012" y="884"/>
+ <point x="820" y="1040"/>
+ <point x="567" y="1040" type="curve" smooth="yes"/>
+ <point x="316" y="1040"/>
+ <point x="122" y="874"/>
+ </contour>
+ <contour>
+ <point x="377" y="680" type="curve" smooth="yes"/>
+ <point x="377" y="770"/>
+ <point x="457" y="847"/>
+ <point x="567" y="847" type="curve" smooth="yes"/>
+ <point x="678" y="847"/>
+ <point x="757" y="770"/>
+ <point x="757" y="680" type="curve" smooth="yes"/>
+ <point x="757" y="578"/>
+ <point x="678" y="501"/>
+ <point x="567" y="501" type="curve" smooth="yes"/>
+ <point x="457" y="501"/>
+ <point x="377" y="578"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetassocuids.ufo/glyphs/L_tnS_mH_.glif b/tests/reference/ufo/psfsetassocuids.ufo/glyphs/L_tnS_mH_.glif
new file mode 100644
index 0000000..15fc451
--- /dev/null
+++ b/tests/reference/ufo/psfsetassocuids.ufo/glyphs/L_tnS_mH_.glif
@@ -0,0 +1,43 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmH" format="2">
+ <advance width="1235"/>
+ <unicode hex="0068"/>
+ <anchor x="280" y="0" name="H"/>
+ <anchor x="620" y="-100" name="L"/>
+ <anchor x="620" y="1635" name="U"/>
+ <outline>
+ <contour>
+ <point x="415" y="580" type="line"/>
+ <point x="450" y="683"/>
+ <point x="560" y="795"/>
+ <point x="675" y="795" type="curve" smooth="yes"/>
+ <point x="782" y="795"/>
+ <point x="830" y="744"/>
+ <point x="830" y="550" type="curve" smooth="yes"/>
+ <point x="830" y="413"/>
+ <point x="830" y="0"/>
+ <point x="830" y="0" type="curve"/>
+ <point x="1110" y="0" type="line"/>
+ <point x="1110" y="0"/>
+ <point x="1110" y="459"/>
+ <point x="1110" y="625" type="curve" smooth="yes"/>
+ <point x="1110" y="900"/>
+ <point x="1008" y="1040"/>
+ <point x="805" y="1040" type="curve" smooth="yes"/>
+ <point x="662" y="1040"/>
+ <point x="513" y="976"/>
+ <point x="415" y="850" type="curve"/>
+ <point x="415" y="894"/>
+ <point x="415" y="1600"/>
+ <point x="415" y="1600" type="curve"/>
+ <point x="120" y="1600" type="line"/>
+ <point x="135" y="1514"/>
+ <point x="135" y="1345"/>
+ <point x="135" y="1130" type="curve" smooth="yes"/>
+ <point x="135" y="935"/>
+ <point x="135" y="0"/>
+ <point x="135" y="0" type="curve"/>
+ <point x="415" y="0" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetassocuids.ufo/glyphs/L_tnS_mI_.glif b/tests/reference/ufo/psfsetassocuids.ufo/glyphs/L_tnS_mI_.glif
new file mode 100644
index 0000000..05022d4
--- /dev/null
+++ b/tests/reference/ufo/psfsetassocuids.ufo/glyphs/L_tnS_mI_.glif
@@ -0,0 +1,42 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmI" format="2">
+ <advance width="640"/>
+ <unicode hex="0069"/>
+ <anchor x="320" y="0" name="H"/>
+ <anchor x="320" y="-100" name="L"/>
+ <anchor x="580" y="0" name="O"/>
+ <anchor x="640" y="1000" name="R"/>
+ <anchor x="320" y="1100" name="U"/>
+ <outline>
+ <contour>
+ <point x="165" y="1020" type="line"/>
+ <point x="178" y="915"/>
+ <point x="180" y="725"/>
+ <point x="180" y="530" type="curve" smooth="yes"/>
+ <point x="180" y="336"/>
+ <point x="180" y="0"/>
+ <point x="180" y="0" type="curve"/>
+ <point x="480" y="0" type="line"/>
+ <point x="467" y="107"/>
+ <point x="460" y="346"/>
+ <point x="460" y="475" type="curve" smooth="yes"/>
+ <point x="460" y="558"/>
+ <point x="460" y="1020"/>
+ <point x="460" y="1020" type="curve"/>
+ </contour>
+ <contour>
+ <point x="145" y="1385" type="curve" smooth="yes"/>
+ <point x="145" y="1281"/>
+ <point x="219" y="1210"/>
+ <point x="320" y="1210" type="curve" smooth="yes"/>
+ <point x="422" y="1210"/>
+ <point x="495" y="1281"/>
+ <point x="495" y="1385" type="curve" smooth="yes"/>
+ <point x="495" y="1487"/>
+ <point x="422" y="1560"/>
+ <point x="320" y="1560" type="curve" smooth="yes"/>
+ <point x="219" y="1560"/>
+ <point x="145" y="1487"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetassocuids.ufo/glyphs/L_tnS_mJ_.glif b/tests/reference/ufo/psfsetassocuids.ufo/glyphs/L_tnS_mJ_.glif
new file mode 100644
index 0000000..6e044af
--- /dev/null
+++ b/tests/reference/ufo/psfsetassocuids.ufo/glyphs/L_tnS_mJ_.glif
@@ -0,0 +1,44 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmJ" format="2">
+ <advance width="670"/>
+ <unicode hex="006A"/>
+ <anchor x="140" y="-500" name="L"/>
+ <anchor x="355" y="1100" name="U"/>
+ <outline>
+ <contour>
+ <point x="185" y="1385" type="curve" smooth="yes"/>
+ <point x="185" y="1281"/>
+ <point x="259" y="1210"/>
+ <point x="360" y="1210" type="curve" smooth="yes"/>
+ <point x="462" y="1210"/>
+ <point x="535" y="1281"/>
+ <point x="535" y="1385" type="curve" smooth="yes"/>
+ <point x="535" y="1487"/>
+ <point x="462" y="1560"/>
+ <point x="360" y="1560" type="curve" smooth="yes"/>
+ <point x="259" y="1560"/>
+ <point x="185" y="1487"/>
+ </contour>
+ <contour>
+ <point x="500" y="1020" type="line"/>
+ <point x="205" y="1020" type="line"/>
+ <point x="218" y="915"/>
+ <point x="220" y="725"/>
+ <point x="220" y="530" type="curve"/>
+ <point x="220" y="20" type="line"/>
+ <point x="220" y="-150"/>
+ <point x="165" y="-232"/>
+ <point x="48" y="-232" type="curve" smooth="yes"/>
+ <point x="-20" y="-232"/>
+ <point x="-101" y="-195"/>
+ <point x="-145" y="-152" type="curve"/>
+ <point x="-190" y="-389" type="line"/>
+ <point x="-148" y="-421"/>
+ <point x="-37" y="-470"/>
+ <point x="56" y="-470" type="curve" smooth="yes"/>
+ <point x="306" y="-470"/>
+ <point x="500" y="-348"/>
+ <point x="500" y="25" type="curve" smooth="yes"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetassocuids.ufo/glyphs/L_tnS_mK_.glif b/tests/reference/ufo/psfsetassocuids.ufo/glyphs/L_tnS_mK_.glif
new file mode 100644
index 0000000..529f7dd
--- /dev/null
+++ b/tests/reference/ufo/psfsetassocuids.ufo/glyphs/L_tnS_mK_.glif
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmK" format="2">
+ <advance width="1138"/>
+ <unicode hex="006B"/>
+ <anchor x="940" y="0" name="H"/>
+ <anchor x="585" y="-100" name="L"/>
+ <anchor x="1140" y="1000" name="R"/>
+ <anchor x="595" y="1635" name="U"/>
+ <outline>
+ <contour>
+ <point x="415" y="0" type="line"/>
+ <point x="415" y="1600" type="line"/>
+ <point x="120" y="1600" type="line"/>
+ <point x="135" y="1514"/>
+ <point x="135" y="1345"/>
+ <point x="135" y="1130" type="curve" smooth="yes"/>
+ <point x="135" y="934"/>
+ <point x="135" y="0"/>
+ <point x="135" y="0" type="curve"/>
+ </contour>
+ <contour>
+ <point x="723" y="1020" type="line"/>
+ <point x="353" y="570" type="line"/>
+ <point x="572" y="528" type="line"/>
+ <point x="1098" y="1020" type="line"/>
+ </contour>
+ <contour>
+ <point x="350" y="570" type="line"/>
+ <point x="761" y="0" type="line"/>
+ <point x="1128" y="0" type="line"/>
+ <point x="540" y="664" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetassocuids.ufo/glyphs/L_tnS_mL_.glif b/tests/reference/ufo/psfsetassocuids.ufo/glyphs/L_tnS_mL_.glif
new file mode 100644
index 0000000..0b21294
--- /dev/null
+++ b/tests/reference/ufo/psfsetassocuids.ufo/glyphs/L_tnS_mL_.glif
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmL" format="2">
+ <advance width="640"/>
+ <unicode hex="006C"/>
+ <anchor x="335" y="0" name="H"/>
+ <anchor x="335" y="-100" name="L"/>
+ <anchor x="660" y="1000" name="R"/>
+ <anchor x="320" y="1635" name="U"/>
+ <outline>
+ <contour>
+ <point x="460" y="1600" type="line"/>
+ <point x="160" y="1600" type="line"/>
+ <point x="173" y="1485"/>
+ <point x="180" y="1324"/>
+ <point x="180" y="1130" type="curve" smooth="yes"/>
+ <point x="180" y="0" type="line"/>
+ <point x="480" y="0" type="line"/>
+ <point x="467" y="109"/>
+ <point x="460" y="346"/>
+ <point x="460" y="475" type="curve" smooth="yes"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetassocuids.ufo/glyphs/L_tnS_mM_.glif b/tests/reference/ufo/psfsetassocuids.ufo/glyphs/L_tnS_mM_.glif
new file mode 100644
index 0000000..eace489
--- /dev/null
+++ b/tests/reference/ufo/psfsetassocuids.ufo/glyphs/L_tnS_mM_.glif
@@ -0,0 +1,52 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmM" format="2">
+ <advance width="1760"/>
+ <unicode hex="006D"/>
+ <anchor x="890" y="0" name="H"/>
+ <anchor x="890" y="-100" name="L"/>
+ <anchor x="890" y="1100" name="U"/>
+ <outline>
+ <contour>
+ <point x="115" y="1020" type="line"/>
+ <point x="136" y="951"/>
+ <point x="165" y="811"/>
+ <point x="165" y="615" type="curve" smooth="yes"/>
+ <point x="165" y="0" type="line"/>
+ <point x="445" y="0" type="line"/>
+ <point x="445" y="640" type="line"/>
+ <point x="484" y="731"/>
+ <point x="560" y="795"/>
+ <point x="635" y="795" type="curve" smooth="yes"/>
+ <point x="723" y="795"/>
+ <point x="750" y="759"/>
+ <point x="750" y="570" type="curve" smooth="yes"/>
+ <point x="750" y="0" type="line"/>
+ <point x="1030" y="0" type="line"/>
+ <point x="1030" y="660" type="line"/>
+ <point x="1073" y="742"/>
+ <point x="1147" y="795"/>
+ <point x="1220" y="795" type="curve" smooth="yes"/>
+ <point x="1310" y="795"/>
+ <point x="1335" y="751"/>
+ <point x="1335" y="550" type="curve" smooth="yes"/>
+ <point x="1335" y="0" type="line"/>
+ <point x="1615" y="0" type="line"/>
+ <point x="1615" y="660" type="line" smooth="yes"/>
+ <point x="1615" y="907"/>
+ <point x="1548" y="1040"/>
+ <point x="1345" y="1040" type="curve" smooth="yes"/>
+ <point x="1240" y="1040"/>
+ <point x="1131" y="1007"/>
+ <point x="1006" y="872" type="curve"/>
+ <point x="973" y="960"/>
+ <point x="891" y="1040"/>
+ <point x="760" y="1040" type="curve" smooth="yes"/>
+ <point x="644" y="1040"/>
+ <point x="544" y="1008"/>
+ <point x="422" y="875" type="curve"/>
+ <point x="412" y="920"/>
+ <point x="397" y="981"/>
+ <point x="375" y="1020" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetassocuids.ufo/glyphs/L_tnS_mN_.glif b/tests/reference/ufo/psfsetassocuids.ufo/glyphs/L_tnS_mN_.glif
new file mode 100644
index 0000000..f7abb6f
--- /dev/null
+++ b/tests/reference/ufo/psfsetassocuids.ufo/glyphs/L_tnS_mN_.glif
@@ -0,0 +1,43 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmN" format="2">
+ <advance width="1245"/>
+ <unicode hex="006E"/>
+ <anchor x="620" y="0" name="H"/>
+ <anchor x="620" y="-100" name="L"/>
+ <anchor x="620" y="1100" name="U"/>
+ <outline>
+ <contour>
+ <point x="1120" y="0" type="line"/>
+ <point x="1120" y="0"/>
+ <point x="1120" y="459"/>
+ <point x="1120" y="625" type="curve" smooth="yes"/>
+ <point x="1120" y="900"/>
+ <point x="998" y="1040"/>
+ <point x="795" y="1040" type="curve" smooth="yes"/>
+ <point x="654" y="1040"/>
+ <point x="537" y="980"/>
+ <point x="410" y="835" type="curve"/>
+ <point x="403" y="881"/>
+ <point x="385" y="980"/>
+ <point x="370" y="1020" type="curve"/>
+ <point x="95" y="1020" type="line"/>
+ <point x="117" y="951"/>
+ <point x="145" y="811"/>
+ <point x="145" y="615" type="curve" smooth="yes"/>
+ <point x="145" y="420"/>
+ <point x="145" y="0"/>
+ <point x="145" y="0" type="curve"/>
+ <point x="425" y="0" type="line"/>
+ <point x="425" y="580" type="line"/>
+ <point x="460" y="683"/>
+ <point x="570" y="795"/>
+ <point x="685" y="795" type="curve" smooth="yes"/>
+ <point x="792" y="795"/>
+ <point x="840" y="734"/>
+ <point x="840" y="550" type="curve" smooth="yes"/>
+ <point x="840" y="413"/>
+ <point x="840" y="0"/>
+ <point x="840" y="0" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetassocuids.ufo/glyphs/L_tnS_mO_.glif b/tests/reference/ufo/psfsetassocuids.ufo/glyphs/L_tnS_mO_.glif
new file mode 100644
index 0000000..063c297
--- /dev/null
+++ b/tests/reference/ufo/psfsetassocuids.ufo/glyphs/L_tnS_mO_.glif
@@ -0,0 +1,40 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmO" format="2">
+ <advance width="1160"/>
+ <unicode hex="006F"/>
+ <anchor x="578" y="0" name="H"/>
+ <anchor x="580" y="-100" name="L"/>
+ <anchor x="790" y="0" name="O"/>
+ <anchor x="1160" y="1000" name="R"/>
+ <anchor x="580" y="1100" name="U"/>
+ <outline>
+ <contour>
+ <point x="90" y="507" type="curve" smooth="yes"/>
+ <point x="90" y="163"/>
+ <point x="288" y="-25"/>
+ <point x="570" y="-25" type="curve" smooth="yes"/>
+ <point x="840" y="-25"/>
+ <point x="1070" y="163"/>
+ <point x="1070" y="507" type="curve" smooth="yes"/>
+ <point x="1070" y="851"/>
+ <point x="873" y="1040"/>
+ <point x="590" y="1040" type="curve" smooth="yes"/>
+ <point x="320" y="1040"/>
+ <point x="90" y="851"/>
+ </contour>
+ <contour>
+ <point x="370" y="507" type="curve" smooth="yes"/>
+ <point x="370" y="699"/>
+ <point x="451" y="815"/>
+ <point x="580" y="815" type="curve" smooth="yes"/>
+ <point x="717" y="815"/>
+ <point x="790" y="699"/>
+ <point x="790" y="507" type="curve" smooth="yes"/>
+ <point x="790" y="316"/>
+ <point x="709" y="200"/>
+ <point x="580" y="200" type="curve" smooth="yes"/>
+ <point x="443" y="200"/>
+ <point x="370" y="316"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetassocuids.ufo/glyphs/L_tnS_mP_.glif b/tests/reference/ufo/psfsetassocuids.ufo/glyphs/L_tnS_mP_.glif
new file mode 100644
index 0000000..4fe224b
--- /dev/null
+++ b/tests/reference/ufo/psfsetassocuids.ufo/glyphs/L_tnS_mP_.glif
@@ -0,0 +1,59 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmP" format="2">
+ <advance width="1235"/>
+ <unicode hex="0070"/>
+ <anchor x="290" y="-435" name="H"/>
+ <anchor x="640" y="-500" name="L"/>
+ <anchor x="1235" y="1000" name="R"/>
+ <anchor x="640" y="1100" name="U"/>
+ <outline>
+ <contour>
+ <point x="450" y="-490" type="line"/>
+ <point x="433" y="-405"/>
+ <point x="425" y="-310"/>
+ <point x="425" y="-150" type="curve" smooth="yes"/>
+ <point x="425" y="-71"/>
+ <point x="425" y="-41"/>
+ <point x="425" y="65" type="curve"/>
+ <point x="518" y="10"/>
+ <point x="594" y="-25"/>
+ <point x="699" y="-25" type="curve" smooth="yes"/>
+ <point x="945" y="-25"/>
+ <point x="1145" y="193"/>
+ <point x="1145" y="535" type="curve" smooth="yes"/>
+ <point x="1145" y="828"/>
+ <point x="996" y="1040"/>
+ <point x="773" y="1040" type="curve" smooth="yes"/>
+ <point x="628" y="1040"/>
+ <point x="502" y="962"/>
+ <point x="410" y="850" type="curve"/>
+ <point x="401" y="932"/>
+ <point x="385" y="990"/>
+ <point x="370" y="1020" type="curve"/>
+ <point x="95" y="1020" type="line"/>
+ <point x="140" y="907"/>
+ <point x="145" y="734"/>
+ <point x="145" y="485" type="curve" smooth="yes"/>
+ <point x="145" y="291"/>
+ <point x="145" y="-345"/>
+ <point x="145" y="-490" type="curve"/>
+ </contour>
+ <contour>
+ <point x="633" y="206" type="curve" smooth="yes"/>
+ <point x="564" y="206"/>
+ <point x="527" y="225"/>
+ <point x="425" y="300" type="curve"/>
+ <point x="425" y="390"/>
+ <point x="425" y="507"/>
+ <point x="425" y="585" type="curve"/>
+ <point x="482" y="726"/>
+ <point x="583" y="802"/>
+ <point x="672" y="802" type="curve" smooth="yes"/>
+ <point x="793" y="802"/>
+ <point x="865" y="686"/>
+ <point x="865" y="505" type="curve" smooth="yes"/>
+ <point x="865" y="320"/>
+ <point x="755" y="206"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetassocuids.ufo/glyphs/L_tnS_mQ_.glif b/tests/reference/ufo/psfsetassocuids.ufo/glyphs/L_tnS_mQ_.glif
new file mode 100644
index 0000000..9727ad7
--- /dev/null
+++ b/tests/reference/ufo/psfsetassocuids.ufo/glyphs/L_tnS_mQ_.glif
@@ -0,0 +1,47 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmQ" format="2">
+ <advance width="1210"/>
+ <unicode hex="0071"/>
+ <anchor x="600" y="-500" name="L"/>
+ <anchor x="1210" y="1000" name="R"/>
+ <anchor x="600" y="1100" name="U"/>
+ <outline>
+ <contour>
+ <point x="790" y="-490" type="line"/>
+ <point x="1095" y="-490" type="line"/>
+ <point x="1078" y="-405"/>
+ <point x="1070" y="-310"/>
+ <point x="1070" y="-150" type="curve" smooth="yes"/>
+ <point x="1070" y="-26"/>
+ <point x="1070" y="965"/>
+ <point x="1070" y="965" type="curve"/>
+ <point x="934" y="1001"/>
+ <point x="773" y="1040"/>
+ <point x="620" y="1040" type="curve" smooth="yes"/>
+ <point x="255" y="1040"/>
+ <point x="100" y="742"/>
+ <point x="100" y="435" type="curve" smooth="yes"/>
+ <point x="100" y="117"/>
+ <point x="316" y="-25"/>
+ <point x="500" y="-25" type="curve" smooth="yes"/>
+ <point x="593" y="-25"/>
+ <point x="686" y="14"/>
+ <point x="790" y="120" type="curve"/>
+ </contour>
+ <contour>
+ <point x="790" y="368" type="line"/>
+ <point x="727" y="258"/>
+ <point x="650" y="203"/>
+ <point x="580" y="203" type="curve" smooth="yes"/>
+ <point x="475" y="203"/>
+ <point x="380" y="287"/>
+ <point x="380" y="485" type="curve" smooth="yes"/>
+ <point x="380" y="641"/>
+ <point x="456" y="802"/>
+ <point x="655" y="802" type="curve" smooth="yes"/>
+ <point x="696" y="802"/>
+ <point x="749" y="789"/>
+ <point x="790" y="770" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetassocuids.ufo/glyphs/L_tnS_mR_.glif b/tests/reference/ufo/psfsetassocuids.ufo/glyphs/L_tnS_mR_.glif
new file mode 100644
index 0000000..8a81116
--- /dev/null
+++ b/tests/reference/ufo/psfsetassocuids.ufo/glyphs/L_tnS_mR_.glif
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmR" format="2">
+ <advance width="995"/>
+ <unicode hex="0072"/>
+ <anchor x="285" y="0" name="H"/>
+ <anchor x="275" y="-100" name="L"/>
+ <anchor x="550" y="1100" name="U"/>
+ <outline>
+ <contour>
+ <point x="425" y="0" type="line"/>
+ <point x="425" y="530" type="line"/>
+ <point x="460" y="654"/>
+ <point x="570" y="781"/>
+ <point x="637" y="781" type="curve" smooth="yes"/>
+ <point x="722" y="781"/>
+ <point x="755" y="721"/>
+ <point x="762" y="630" type="curve"/>
+ <point x="985" y="665" type="line"/>
+ <point x="985" y="868"/>
+ <point x="913" y="1040"/>
+ <point x="725" y="1040" type="curve" smooth="yes"/>
+ <point x="634" y="1040"/>
+ <point x="507" y="964"/>
+ <point x="410" y="825" type="curve"/>
+ <point x="403" y="873"/>
+ <point x="385" y="978"/>
+ <point x="370" y="1020" type="curve"/>
+ <point x="95" y="1020" type="line"/>
+ <point x="117" y="951"/>
+ <point x="145" y="811"/>
+ <point x="145" y="615" type="curve" smooth="yes"/>
+ <point x="145" y="0" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetassocuids.ufo/glyphs/L_tnS_mS_.glif b/tests/reference/ufo/psfsetassocuids.ufo/glyphs/L_tnS_mS_.glif
new file mode 100644
index 0000000..06b1a9a
--- /dev/null
+++ b/tests/reference/ufo/psfsetassocuids.ufo/glyphs/L_tnS_mS_.glif
@@ -0,0 +1,50 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmS" format="2">
+ <advance width="1035"/>
+ <unicode hex="0073"/>
+ <anchor x="515" y="0" name="H"/>
+ <anchor x="515" y="-100" name="L"/>
+ <anchor x="530" y="1100" name="U"/>
+ <outline>
+ <contour>
+ <point x="905" y="960" type="line"/>
+ <point x="827" y="998"/>
+ <point x="708" y="1040"/>
+ <point x="545" y="1040" type="curve" smooth="yes"/>
+ <point x="202" y="1040"/>
+ <point x="110" y="818"/>
+ <point x="110" y="720" type="curve" smooth="yes"/>
+ <point x="110" y="594"/>
+ <point x="171" y="491"/>
+ <point x="455" y="432" type="curve" smooth="yes"/>
+ <point x="646" y="390"/>
+ <point x="690" y="348"/>
+ <point x="690" y="290" type="curve" smooth="yes"/>
+ <point x="690" y="243"/>
+ <point x="624" y="199"/>
+ <point x="530" y="199" type="curve" smooth="yes"/>
+ <point x="413" y="199"/>
+ <point x="254" y="253"/>
+ <point x="155" y="334" type="curve"/>
+ <point x="100" y="90" type="line"/>
+ <point x="187" y="28"/>
+ <point x="346" y="-25"/>
+ <point x="525" y="-25" type="curve" smooth="yes"/>
+ <point x="768" y="-25"/>
+ <point x="960" y="123"/>
+ <point x="960" y="315" type="curve" smooth="yes"/>
+ <point x="960" y="504"/>
+ <point x="788" y="583"/>
+ <point x="580" y="625" type="curve" smooth="yes"/>
+ <point x="405" y="659"/>
+ <point x="380" y="681"/>
+ <point x="380" y="730" type="curve" smooth="yes"/>
+ <point x="380" y="770"/>
+ <point x="418" y="816"/>
+ <point x="535" y="816" type="curve" smooth="yes"/>
+ <point x="674" y="816"/>
+ <point x="791" y="760"/>
+ <point x="866" y="721" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetassocuids.ufo/glyphs/L_tnS_mT_.glif b/tests/reference/ufo/psfsetassocuids.ufo/glyphs/L_tnS_mT_.glif
new file mode 100644
index 0000000..d4123c7
--- /dev/null
+++ b/tests/reference/ufo/psfsetassocuids.ufo/glyphs/L_tnS_mT_.glif
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmT" format="2">
+ <advance width="885"/>
+ <unicode hex="0074"/>
+ <anchor x="530" y="0" name="H"/>
+ <anchor x="530" y="-100" name="L"/>
+ <anchor x="885" y="1000" name="R"/>
+ <anchor x="360" y="1360" name="U"/>
+ <outline>
+ <contour>
+ <point x="220" y="270" type="line"/>
+ <point x="220" y="39"/>
+ <point x="374" y="-25"/>
+ <point x="563" y="-25" type="curve" smooth="yes"/>
+ <point x="635" y="-25"/>
+ <point x="725" y="-3"/>
+ <point x="820" y="57" type="curve"/>
+ <point x="820" y="281" type="line"/>
+ <point x="741" y="232"/>
+ <point x="678" y="206"/>
+ <point x="627" y="206" type="curve" smooth="yes"/>
+ <point x="537" y="206"/>
+ <point x="500" y="235"/>
+ <point x="500" y="462" type="curve" smooth="yes"/>
+ <point x="500" y="1320" type="line"/>
+ <point x="220" y="1320" type="line"/>
+ </contour>
+ <contour>
+ <point x="805" y="805" type="line"/>
+ <point x="805" y="1005" type="line"/>
+ <point x="30" y="1005" type="line"/>
+ <point x="30" y="805" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetassocuids.ufo/glyphs/L_tnS_mU_.glif b/tests/reference/ufo/psfsetassocuids.ufo/glyphs/L_tnS_mU_.glif
new file mode 100644
index 0000000..5b8d434
--- /dev/null
+++ b/tests/reference/ufo/psfsetassocuids.ufo/glyphs/L_tnS_mU_.glif
@@ -0,0 +1,51 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmU" format="2">
+ <advance width="1245"/>
+ <unicode hex="0075"/>
+ <anchor x="515" y="0" name="H"/>
+ <anchor x="615" y="-100" name="L"/>
+ <anchor x="690" y="0" name="O"/>
+ <anchor x="1258" y="1000" name="R"/>
+ <anchor x="615" y="1100" name="U"/>
+ <outline>
+ <contour>
+ <point x="1160" y="0" type="line"/>
+ <point x="1118" y="112"/>
+ <point x="1095" y="256"/>
+ <point x="1095" y="450" type="curve" smooth="yes"/>
+ <point x="1095" y="646"/>
+ <point x="1095" y="1020"/>
+ <point x="1095" y="1020" type="curve"/>
+ <point x="795" y="1020" type="line"/>
+ <point x="813" y="898"/>
+ <point x="815" y="832"/>
+ <point x="815" y="700" type="curve" smooth="yes"/>
+ <point x="815" y="418" type="line"/>
+ <point x="774" y="326"/>
+ <point x="651" y="206"/>
+ <point x="560" y="206" type="curve" smooth="yes"/>
+ <point x="458" y="206"/>
+ <point x="425" y="284"/>
+ <point x="425" y="465" type="curve" smooth="yes"/>
+ <point x="425" y="603"/>
+ <point x="425" y="1020"/>
+ <point x="425" y="1020" type="curve"/>
+ <point x="125" y="1020" type="line"/>
+ <point x="143" y="900"/>
+ <point x="145" y="827"/>
+ <point x="145" y="700" type="curve" smooth="yes"/>
+ <point x="145" y="681"/>
+ <point x="145" y="424"/>
+ <point x="145" y="405" type="curve" smooth="yes"/>
+ <point x="145" y="120"/>
+ <point x="250" y="-25"/>
+ <point x="458" y="-25" type="curve" smooth="yes"/>
+ <point x="595" y="-25"/>
+ <point x="722" y="48"/>
+ <point x="840" y="185" type="curve"/>
+ <point x="850" y="116"/>
+ <point x="876" y="43"/>
+ <point x="895" y="0" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetassocuids.ufo/glyphs/L_tnS_mV_.glif b/tests/reference/ufo/psfsetassocuids.ufo/glyphs/L_tnS_mV_.glif
new file mode 100644
index 0000000..daf1468
--- /dev/null
+++ b/tests/reference/ufo/psfsetassocuids.ufo/glyphs/L_tnS_mV_.glif
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmV" format="2">
+ <advance width="1104"/>
+ <unicode hex="0076"/>
+ <anchor x="565" y="0" name="H"/>
+ <anchor x="565" y="-100" name="L"/>
+ <anchor x="750" y="0" name="O"/>
+ <anchor x="565" y="1100" name="U"/>
+ <outline>
+ <contour>
+ <point x="786" y="1020" type="line"/>
+ <point x="556" y="290" type="line"/>
+ <point x="322" y="1020" type="line"/>
+ <point x="10" y="1020" type="line"/>
+ <point x="65" y="905"/>
+ <point x="133" y="746"/>
+ <point x="165" y="665" type="curve" smooth="yes"/>
+ <point x="227" y="510"/>
+ <point x="430" y="0"/>
+ <point x="430" y="0" type="curve"/>
+ <point x="674" y="0" type="line"/>
+ <point x="674" y="0"/>
+ <point x="886" y="536"/>
+ <point x="939" y="665" type="curve" smooth="yes"/>
+ <point x="972" y="744"/>
+ <point x="1037" y="905"/>
+ <point x="1094" y="1020" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetassocuids.ufo/glyphs/L_tnS_mW_.glif b/tests/reference/ufo/psfsetassocuids.ufo/glyphs/L_tnS_mW_.glif
new file mode 100644
index 0000000..1ca1ec4
--- /dev/null
+++ b/tests/reference/ufo/psfsetassocuids.ufo/glyphs/L_tnS_mW_.glif
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmW" format="2">
+ <advance width="1570"/>
+ <unicode hex="0077"/>
+ <anchor x="785" y="-100" name="L"/>
+ <anchor x="785" y="1100" name="U"/>
+ <outline>
+ <contour>
+ <point x="665" y="1020" type="line"/>
+ <point x="480" y="285" type="line"/>
+ <point x="323" y="1020" type="line"/>
+ <point x="35" y="1020" type="line"/>
+ <point x="82" y="867"/>
+ <point x="110" y="771"/>
+ <point x="140" y="665" type="curve" smooth="yes"/>
+ <point x="325" y="0" type="line"/>
+ <point x="615" y="0" type="line"/>
+ <point x="785" y="695" type="line"/>
+ <point x="955" y="0" type="line"/>
+ <point x="1245" y="0" type="line"/>
+ <point x="1430" y="665" type="line" smooth="yes"/>
+ <point x="1464" y="785"/>
+ <point x="1488" y="868"/>
+ <point x="1535" y="1020" type="curve"/>
+ <point x="1247" y="1020" type="line"/>
+ <point x="1090" y="285" type="line"/>
+ <point x="905" y="1020" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetassocuids.ufo/glyphs/L_tnS_mX_.glif b/tests/reference/ufo/psfsetassocuids.ufo/glyphs/L_tnS_mX_.glif
new file mode 100644
index 0000000..971c129
--- /dev/null
+++ b/tests/reference/ufo/psfsetassocuids.ufo/glyphs/L_tnS_mX_.glif
@@ -0,0 +1,40 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmX" format="2">
+ <advance width="1185"/>
+ <unicode hex="0078"/>
+ <anchor x="960" y="0" name="H"/>
+ <anchor x="590" y="-100" name="L"/>
+ <anchor x="615" y="1100" name="U"/>
+ <outline>
+ <contour>
+ <point x="815" y="0" type="line"/>
+ <point x="1145" y="0" type="line"/>
+ <point x="1037" y="129"/>
+ <point x="989" y="190"/>
+ <point x="930" y="270" type="curve" smooth="yes"/>
+ <point x="380" y="1020" type="line"/>
+ <point x="50" y="1020" type="line"/>
+ <point x="158" y="887"/>
+ <point x="192" y="842"/>
+ <point x="260" y="750" type="curve" smooth="yes"/>
+ </contour>
+ <contour>
+ <point x="499" y="616" type="line"/>
+ <point x="245" y="270" type="line" smooth="yes"/>
+ <point x="195" y="201"/>
+ <point x="150" y="143"/>
+ <point x="40" y="0" type="curve"/>
+ <point x="345" y="0" type="line"/>
+ <point x="584" y="359" type="line"/>
+ </contour>
+ <contour>
+ <point x="675" y="405" type="line"/>
+ <point x="925" y="750" type="line" smooth="yes"/>
+ <point x="980" y="826"/>
+ <point x="1027" y="886"/>
+ <point x="1130" y="1020" type="curve"/>
+ <point x="825" y="1020" type="line"/>
+ <point x="595" y="668" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetassocuids.ufo/glyphs/L_tnS_mY_.glif b/tests/reference/ufo/psfsetassocuids.ufo/glyphs/L_tnS_mY_.glif
new file mode 100644
index 0000000..ea8d25e
--- /dev/null
+++ b/tests/reference/ufo/psfsetassocuids.ufo/glyphs/L_tnS_mY_.glif
@@ -0,0 +1,39 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmY" format="2">
+ <advance width="1100"/>
+ <unicode hex="0079"/>
+ <anchor x="845" y="-100" name="L"/>
+ <anchor x="1155" y="1000" name="R"/>
+ <anchor x="565" y="1100" name="U"/>
+ <outline>
+ <contour>
+ <point x="945" y="665" type="line" smooth="yes"/>
+ <point x="978" y="758"/>
+ <point x="1021" y="865"/>
+ <point x="1090" y="1020" type="curve"/>
+ <point x="777" y="1020" type="line"/>
+ <point x="777" y="1020"/>
+ <point x="646" y="549"/>
+ <point x="573" y="293" type="curve"/>
+ <point x="333" y="1020" type="line"/>
+ <point x="20" y="1020" type="line"/>
+ <point x="97" y="864"/>
+ <point x="144" y="757"/>
+ <point x="180" y="665" type="curve" smooth="yes"/>
+ <point x="445" y="-18" type="line"/>
+ <point x="366" y="-209"/>
+ <point x="304" y="-242"/>
+ <point x="245" y="-242" type="curve" smooth="yes"/>
+ <point x="179" y="-242"/>
+ <point x="102" y="-202"/>
+ <point x="60" y="-167" type="curve"/>
+ <point x="-10" y="-385" type="line"/>
+ <point x="63" y="-439"/>
+ <point x="154" y="-470"/>
+ <point x="245" y="-470" type="curve" smooth="yes"/>
+ <point x="427" y="-470"/>
+ <point x="565" y="-387"/>
+ <point x="705" y="0" type="curve" smooth="yes"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetassocuids.ufo/glyphs/N_onB_reakingH_yphen.glif b/tests/reference/ufo/psfsetassocuids.ufo/glyphs/N_onB_reakingH_yphen.glif
new file mode 100644
index 0000000..7dc67c0
--- /dev/null
+++ b/tests/reference/ufo/psfsetassocuids.ufo/glyphs/N_onB_reakingH_yphen.glif
@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="NonBreakingHyphen" format="2">
+ <advance width="895"/>
+ <unicode hex="2011"/>
+ <anchor x="450" y="1100" name="U"/>
+ <outline>
+ <component base="HyphenMinus"/>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetassocuids.ufo/glyphs/N_umS_gn.glif b/tests/reference/ufo/psfsetassocuids.ufo/glyphs/N_umS_gn.glif
new file mode 100644
index 0000000..54b82cb
--- /dev/null
+++ b/tests/reference/ufo/psfsetassocuids.ufo/glyphs/N_umS_gn.glif
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="NumSgn" format="2">
+ <advance width="1200"/>
+ <unicode hex="0023"/>
+ <outline>
+ <contour>
+ <point x="412" y="1360" type="line"/>
+ <point x="52" y="100" type="line"/>
+ <point x="272" y="100" type="line"/>
+ <point x="632" y="1360" type="line"/>
+ </contour>
+ <contour>
+ <point x="10" y="425" type="line"/>
+ <point x="1101" y="425" type="line"/>
+ <point x="1101" y="635" type="line"/>
+ <point x="10" y="635" type="line"/>
+ </contour>
+ <contour>
+ <point x="69" y="850" type="line"/>
+ <point x="1160" y="850" type="line"/>
+ <point x="1160" y="1060" type="line"/>
+ <point x="69" y="1060" type="line"/>
+ </contour>
+ <contour>
+ <point x="887" y="1360" type="line"/>
+ <point x="527" y="100" type="line"/>
+ <point x="747" y="100" type="line"/>
+ <point x="1107" y="1360" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetassocuids.ufo/glyphs/P_ercentS_gn.glif b/tests/reference/ufo/psfsetassocuids.ufo/glyphs/P_ercentS_gn.glif
new file mode 100644
index 0000000..5017543
--- /dev/null
+++ b/tests/reference/ufo/psfsetassocuids.ufo/glyphs/P_ercentS_gn.glif
@@ -0,0 +1,69 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="PercentSgn" format="2">
+ <advance width="1565"/>
+ <unicode hex="0025"/>
+ <outline>
+ <contour>
+ <point x="1073" y="1480" type="line"/>
+ <point x="291" y="-25" type="line"/>
+ <point x="499" y="-25" type="line"/>
+ <point x="1279" y="1480" type="line"/>
+ </contour>
+ <contour>
+ <point x="511" y="1076" type="curve" smooth="yes"/>
+ <point x="511" y="892"/>
+ <point x="470" y="815"/>
+ <point x="394" y="815" type="curve" smooth="yes"/>
+ <point x="315" y="815"/>
+ <point x="279" y="891"/>
+ <point x="279" y="1091" type="curve" smooth="yes"/>
+ <point x="279" y="1275"/>
+ <point x="317" y="1350"/>
+ <point x="394" y="1350" type="curve" smooth="yes"/>
+ <point x="475" y="1350"/>
+ <point x="511" y="1276"/>
+ </contour>
+ <contour>
+ <point x="721" y="1089" type="curve" smooth="yes"/>
+ <point x="721" y="1362"/>
+ <point x="584" y="1480"/>
+ <point x="399" y="1480" type="curve" smooth="yes"/>
+ <point x="215" y="1480"/>
+ <point x="69" y="1360"/>
+ <point x="69" y="1078" type="curve" smooth="yes"/>
+ <point x="69" y="796"/>
+ <point x="205" y="685"/>
+ <point x="390" y="685" type="curve" smooth="yes"/>
+ <point x="575" y="685"/>
+ <point x="721" y="794"/>
+ </contour>
+ <contour>
+ <point x="1286" y="366" type="curve" smooth="yes"/>
+ <point x="1286" y="182"/>
+ <point x="1245" y="105"/>
+ <point x="1169" y="105" type="curve" smooth="yes"/>
+ <point x="1090" y="105"/>
+ <point x="1054" y="181"/>
+ <point x="1054" y="381" type="curve" smooth="yes"/>
+ <point x="1054" y="565"/>
+ <point x="1092" y="640"/>
+ <point x="1169" y="640" type="curve" smooth="yes"/>
+ <point x="1250" y="640"/>
+ <point x="1286" y="566"/>
+ </contour>
+ <contour>
+ <point x="1496" y="379" type="curve" smooth="yes"/>
+ <point x="1496" y="652"/>
+ <point x="1359" y="770"/>
+ <point x="1174" y="770" type="curve" smooth="yes"/>
+ <point x="990" y="770"/>
+ <point x="844" y="650"/>
+ <point x="844" y="368" type="curve" smooth="yes"/>
+ <point x="844" y="86"/>
+ <point x="980" y="-25"/>
+ <point x="1165" y="-25" type="curve" smooth="yes"/>
+ <point x="1350" y="-25"/>
+ <point x="1496" y="84"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetassocuids.ufo/glyphs/P_lusS_gn.glif b/tests/reference/ufo/psfsetassocuids.ufo/glyphs/P_lusS_gn.glif
new file mode 100644
index 0000000..a1a4c93
--- /dev/null
+++ b/tests/reference/ufo/psfsetassocuids.ufo/glyphs/P_lusS_gn.glif
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="PlusSgn" format="2">
+ <advance width="1200"/>
+ <unicode hex="002B"/>
+ <outline>
+ <contour>
+ <point x="495" y="1180" type="line"/>
+ <point x="495" y="285" type="line"/>
+ <point x="705" y="285" type="line"/>
+ <point x="705" y="1180" type="line"/>
+ </contour>
+ <contour>
+ <point x="155" y="630" type="line"/>
+ <point x="1045" y="630" type="line"/>
+ <point x="1045" y="840" type="line"/>
+ <point x="155" y="840" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetassocuids.ufo/glyphs/Q_stnM_rk.glif b/tests/reference/ufo/psfsetassocuids.ufo/glyphs/Q_stnM_rk.glif
new file mode 100644
index 0000000..c9bbb28
--- /dev/null
+++ b/tests/reference/ufo/psfsetassocuids.ufo/glyphs/Q_stnM_rk.glif
@@ -0,0 +1,49 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="QstnMrk" format="2">
+ <advance width="1090"/>
+ <unicode hex="003F"/>
+ <outline>
+ <contour>
+ <point x="640" y="500" type="line"/>
+ <point x="640" y="671"/>
+ <point x="668" y="805"/>
+ <point x="767" y="956" type="curve" smooth="yes"/>
+ <point x="837" y="1063"/>
+ <point x="900" y="1117"/>
+ <point x="900" y="1220" type="curve" smooth="yes"/>
+ <point x="900" y="1402"/>
+ <point x="757" y="1540"/>
+ <point x="500" y="1540" type="curve" smooth="yes"/>
+ <point x="355" y="1540"/>
+ <point x="206" y="1470"/>
+ <point x="140" y="1407" type="curve"/>
+ <point x="185" y="1168" type="line"/>
+ <point x="261" y="1247"/>
+ <point x="372" y="1295"/>
+ <point x="472" y="1295" type="curve" smooth="yes"/>
+ <point x="569" y="1295"/>
+ <point x="615" y="1249"/>
+ <point x="615" y="1190" type="curve" smooth="yes"/>
+ <point x="615" y="1139"/>
+ <point x="565" y="1096"/>
+ <point x="495" y="980" type="curve" smooth="yes"/>
+ <point x="434" y="879"/>
+ <point x="375" y="710"/>
+ <point x="375" y="500" type="curve"/>
+ </contour>
+ <contour>
+ <point x="335" y="150" type="curve" smooth="yes"/>
+ <point x="335" y="46"/>
+ <point x="409" y="-25"/>
+ <point x="510" y="-25" type="curve" smooth="yes"/>
+ <point x="612" y="-25"/>
+ <point x="685" y="46"/>
+ <point x="685" y="150" type="curve" smooth="yes"/>
+ <point x="685" y="252"/>
+ <point x="612" y="325"/>
+ <point x="510" y="325" type="curve" smooth="yes"/>
+ <point x="409" y="325"/>
+ <point x="335" y="252"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetassocuids.ufo/glyphs/Q_uotM_rk.glif b/tests/reference/ufo/psfsetassocuids.ufo/glyphs/Q_uotM_rk.glif
new file mode 100644
index 0000000..794a655
--- /dev/null
+++ b/tests/reference/ufo/psfsetassocuids.ufo/glyphs/Q_uotM_rk.glif
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="QuotMrk" format="2">
+ <advance width="1085"/>
+ <unicode hex="0022"/>
+ <outline>
+ <contour>
+ <point x="450" y="1045" type="line"/>
+ <point x="455" y="1186"/>
+ <point x="456" y="1339"/>
+ <point x="485" y="1585" type="curve"/>
+ <point x="240" y="1585" type="line"/>
+ <point x="271" y="1339"/>
+ <point x="271" y="1186"/>
+ <point x="275" y="1045" type="curve"/>
+ </contour>
+ <contour>
+ <point x="810" y="1045" type="line"/>
+ <point x="815" y="1186"/>
+ <point x="816" y="1339"/>
+ <point x="845" y="1585" type="curve"/>
+ <point x="600" y="1585" type="line"/>
+ <point x="631" y="1339"/>
+ <point x="631" y="1186"/>
+ <point x="635" y="1045" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetassocuids.ufo/glyphs/R_everseS_olidus.glif b/tests/reference/ufo/psfsetassocuids.ufo/glyphs/R_everseS_olidus.glif
new file mode 100644
index 0000000..799c999
--- /dev/null
+++ b/tests/reference/ufo/psfsetassocuids.ufo/glyphs/R_everseS_olidus.glif
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="ReverseSolidus" format="2">
+ <advance width="1080"/>
+ <unicode hex="005C"/>
+ <outline>
+ <contour>
+ <point x="10" y="1600" type="line"/>
+ <point x="840" y="-245" type="line"/>
+ <point x="1070" y="-245" type="line"/>
+ <point x="240" y="1600" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetassocuids.ufo/glyphs/R_tC_urlyB_rac.glif b/tests/reference/ufo/psfsetassocuids.ufo/glyphs/R_tC_urlyB_rac.glif
new file mode 100644
index 0000000..48383fb
--- /dev/null
+++ b/tests/reference/ufo/psfsetassocuids.ufo/glyphs/R_tC_urlyB_rac.glif
@@ -0,0 +1,47 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="RtCurlyBrac" format="2">
+ <advance width="1040"/>
+ <unicode hex="007D"/>
+ <outline>
+ <contour>
+ <point x="180" y="-410" type="line"/>
+ <point x="316" y="-383"/>
+ <point x="520" y="-333"/>
+ <point x="570" y="-285" type="curve" smooth="yes"/>
+ <point x="645" y="-213"/>
+ <point x="633" y="378"/>
+ <point x="655" y="410" type="curve" smooth="yes"/>
+ <point x="685" y="453"/>
+ <point x="855" y="560"/>
+ <point x="855" y="615" type="curve" smooth="yes"/>
+ <point x="855" y="670"/>
+ <point x="685" y="777"/>
+ <point x="655" y="820" type="curve" smooth="yes"/>
+ <point x="633" y="852"/>
+ <point x="644" y="1442"/>
+ <point x="570" y="1515" type="curve" smooth="yes"/>
+ <point x="523" y="1562"/>
+ <point x="333" y="1613"/>
+ <point x="205" y="1640" type="curve"/>
+ <point x="155" y="1409" type="line"/>
+ <point x="218" y="1390"/>
+ <point x="323" y="1351"/>
+ <point x="340" y="1330" type="curve" smooth="yes"/>
+ <point x="375" y="1289"/>
+ <point x="364" y="820"/>
+ <point x="382" y="785" type="curve" smooth="yes"/>
+ <point x="405" y="740"/>
+ <point x="542" y="650"/>
+ <point x="542" y="615" type="curve" smooth="yes"/>
+ <point x="542" y="580"/>
+ <point x="404" y="491"/>
+ <point x="380" y="445" type="curve" smooth="yes"/>
+ <point x="362" y="411"/>
+ <point x="375" y="-60"/>
+ <point x="340" y="-100" type="curve" smooth="yes"/>
+ <point x="321" y="-122"/>
+ <point x="197" y="-160"/>
+ <point x="130" y="-179" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetassocuids.ufo/glyphs/R_tP_aren.glif b/tests/reference/ufo/psfsetassocuids.ufo/glyphs/R_tP_aren.glif
new file mode 100644
index 0000000..ae49fca
--- /dev/null
+++ b/tests/reference/ufo/psfsetassocuids.ufo/glyphs/R_tP_aren.glif
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="RtParen" format="2">
+ <advance width="860"/>
+ <unicode hex="0029"/>
+ <outline>
+ <contour>
+ <point x="185" y="1455" type="line"/>
+ <point x="395" y="1261"/>
+ <point x="485" y="938"/>
+ <point x="485" y="635" type="curve" smooth="yes"/>
+ <point x="485" y="335"/>
+ <point x="399" y="11"/>
+ <point x="175" y="-240" type="curve"/>
+ <point x="326" y="-410" type="line"/>
+ <point x="601" y="-125"/>
+ <point x="746" y="218"/>
+ <point x="746" y="625" type="curve" smooth="yes"/>
+ <point x="746" y="1062"/>
+ <point x="571" y="1444"/>
+ <point x="306" y="1640" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetassocuids.ufo/glyphs/R_tS_qrB_rac.glif b/tests/reference/ufo/psfsetassocuids.ufo/glyphs/R_tS_qrB_rac.glif
new file mode 100644
index 0000000..325e575
--- /dev/null
+++ b/tests/reference/ufo/psfsetassocuids.ufo/glyphs/R_tS_qrB_rac.glif
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="RtSqrBrac" format="2">
+ <advance width="850"/>
+ <unicode hex="005D"/>
+ <outline>
+ <contour>
+ <point x="660" y="-410" type="line"/>
+ <point x="660" y="1600" type="line"/>
+ <point x="140" y="1600" type="line"/>
+ <point x="140" y="1390" type="line"/>
+ <point x="380" y="1390" type="line"/>
+ <point x="380" y="-200" type="line"/>
+ <point x="140" y="-200" type="line"/>
+ <point x="140" y="-410" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetassocuids.ufo/glyphs/S_emicolon.glif b/tests/reference/ufo/psfsetassocuids.ufo/glyphs/S_emicolon.glif
new file mode 100644
index 0000000..ae95657
--- /dev/null
+++ b/tests/reference/ufo/psfsetassocuids.ufo/glyphs/S_emicolon.glif
@@ -0,0 +1,38 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="Semicolon" format="2">
+ <advance width="710"/>
+ <unicode hex="003B"/>
+ <outline>
+ <contour>
+ <point x="200" y="750" type="curve" smooth="yes"/>
+ <point x="200" y="646"/>
+ <point x="274" y="575"/>
+ <point x="375" y="575" type="curve" smooth="yes"/>
+ <point x="477" y="575"/>
+ <point x="550" y="646"/>
+ <point x="550" y="750" type="curve" smooth="yes"/>
+ <point x="550" y="852"/>
+ <point x="477" y="925"/>
+ <point x="375" y="925" type="curve" smooth="yes"/>
+ <point x="274" y="925"/>
+ <point x="200" y="852"/>
+ </contour>
+ <contour>
+ <point x="185" y="50" type="line"/>
+ <point x="345" y="50" type="line"/>
+ <point x="345" y="-34"/>
+ <point x="290" y="-153"/>
+ <point x="185" y="-265" type="curve"/>
+ <point x="330" y="-335" type="line"/>
+ <point x="454" y="-228"/>
+ <point x="560" y="-49"/>
+ <point x="560" y="130" type="curve" smooth="yes"/>
+ <point x="560" y="254"/>
+ <point x="489" y="340"/>
+ <point x="375" y="340" type="curve" smooth="yes"/>
+ <point x="262" y="340"/>
+ <point x="185" y="255"/>
+ <point x="185" y="180" type="curve" smooth="yes"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetassocuids.ufo/glyphs/S_olidus.glif b/tests/reference/ufo/psfsetassocuids.ufo/glyphs/S_olidus.glif
new file mode 100644
index 0000000..1e33c05
--- /dev/null
+++ b/tests/reference/ufo/psfsetassocuids.ufo/glyphs/S_olidus.glif
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="Solidus" format="2">
+ <advance width="1080"/>
+ <unicode hex="002F"/>
+ <outline>
+ <contour>
+ <point x="840" y="1600" type="line"/>
+ <point x="10" y="-245" type="line"/>
+ <point x="240" y="-245" type="line"/>
+ <point x="1070" y="1600" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetassocuids.ufo/glyphs/S_pace.glif b/tests/reference/ufo/psfsetassocuids.ufo/glyphs/S_pace.glif
new file mode 100644
index 0000000..ef0bed7
--- /dev/null
+++ b/tests/reference/ufo/psfsetassocuids.ufo/glyphs/S_pace.glif
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="Space" format="2">
+ <advance width="550"/>
+ <unicode hex="0020"/>
+ <outline/>
+</glyph>
diff --git a/tests/reference/ufo/psfsetassocuids.ufo/glyphs/T_ilde.glif b/tests/reference/ufo/psfsetassocuids.ufo/glyphs/T_ilde.glif
new file mode 100644
index 0000000..ec9fc73
--- /dev/null
+++ b/tests/reference/ufo/psfsetassocuids.ufo/glyphs/T_ilde.glif
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="Tilde" format="2">
+ <advance width="1115"/>
+ <unicode hex="007E"/>
+ <outline>
+ <contour>
+ <point x="165" y="345" type="line"/>
+ <point x="170" y="394"/>
+ <point x="202" y="435"/>
+ <point x="280" y="435" type="curve" smooth="yes"/>
+ <point x="435" y="435"/>
+ <point x="615" y="330"/>
+ <point x="825" y="330" type="curve" smooth="yes"/>
+ <point x="984" y="330"/>
+ <point x="1080" y="512"/>
+ <point x="1080" y="640" type="curve"/>
+ <point x="935" y="640" type="line"/>
+ <point x="928" y="594"/>
+ <point x="898" y="540"/>
+ <point x="815" y="540" type="curve" smooth="yes"/>
+ <point x="599" y="540"/>
+ <point x="461" y="645"/>
+ <point x="260" y="645" type="curve" smooth="yes"/>
+ <point x="104" y="645"/>
+ <point x="20" y="467"/>
+ <point x="20" y="345" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetassocuids.ufo/glyphs/V_ertL_ine.glif b/tests/reference/ufo/psfsetassocuids.ufo/glyphs/V_ertL_ine.glif
new file mode 100644
index 0000000..d7caa84
--- /dev/null
+++ b/tests/reference/ufo/psfsetassocuids.ufo/glyphs/V_ertL_ine.glif
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="VertLine" format="2">
+ <advance width="690"/>
+ <unicode hex="007C"/>
+ <outline>
+ <contour>
+ <point x="240" y="1600" type="line"/>
+ <point x="240" y="-390" type="line"/>
+ <point x="450" y="-390" type="line"/>
+ <point x="450" y="1600" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetassocuids.ufo/glyphs/_notdef.glif b/tests/reference/ufo/psfsetassocuids.ufo/glyphs/_notdef.glif
new file mode 100644
index 0000000..a3e9354
--- /dev/null
+++ b/tests/reference/ufo/psfsetassocuids.ufo/glyphs/_notdef.glif
@@ -0,0 +1,18 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name=".notdef" format="2">
+ <advance width="1400"/>
+ <outline>
+ <contour>
+ <point x="100" y="0" type="line"/>
+ <point x="1300" y="0" type="line"/>
+ <point x="1300" y="1800" type="line"/>
+ <point x="100" y="1800" type="line"/>
+ </contour>
+ <contour>
+ <point x="150" y="1750" type="line"/>
+ <point x="1250" y="1750" type="line"/>
+ <point x="1250" y="50" type="line"/>
+ <point x="150" y="50" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetassocuids.ufo/glyphs/_null.glif b/tests/reference/ufo/psfsetassocuids.ufo/glyphs/_null.glif
new file mode 100644
index 0000000..0b9caa6
--- /dev/null
+++ b/tests/reference/ufo/psfsetassocuids.ufo/glyphs/_null.glif
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name=".null" format="2">
+ <outline/>
+</glyph>
diff --git a/tests/reference/ufo/psfsetassocuids.ufo/glyphs/contents.plist b/tests/reference/ufo/psfsetassocuids.ufo/glyphs/contents.plist
new file mode 100644
index 0000000..de3c0b3
--- /dev/null
+++ b/tests/reference/ufo/psfsetassocuids.ufo/glyphs/contents.plist
@@ -0,0 +1,234 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+ <key>.notdef</key>
+ <string>_notdef.glif</string>
+ <key>.null</key>
+ <string>_null.glif</string>
+ <key>Ampersand</key>
+ <string>A_mpersand.glif</string>
+ <key>Apos</key>
+ <string>A_pos.glif</string>
+ <key>Asterisk</key>
+ <string>A_sterisk.glif</string>
+ <key>AtSgn</key>
+ <string>A_tS_gn.glif</string>
+ <key>CircumAccent</key>
+ <string>C_ircumA_ccent.glif</string>
+ <key>Colon</key>
+ <string>C_olon.glif</string>
+ <key>CombAcute</key>
+ <string>C_ombA_cute.glif</string>
+ <key>CombCircum</key>
+ <string>C_ombC_ircum.glif</string>
+ <key>CombDiaer</key>
+ <string>C_ombD_iaer.glif</string>
+ <key>CombGrave</key>
+ <string>C_ombG_rave.glif</string>
+ <key>CombRingAbv</key>
+ <string>C_ombR_ingA_bv.glif</string>
+ <key>CombTilde</key>
+ <string>C_ombT_ilde.glif</string>
+ <key>Comma</key>
+ <string>C_omma.glif</string>
+ <key>DigitEight</key>
+ <string>D_igitE_ight.glif</string>
+ <key>DigitFive</key>
+ <string>D_igitF_ive.glif</string>
+ <key>DigitFour</key>
+ <string>D_igitF_our.glif</string>
+ <key>DigitNine</key>
+ <string>D_igitN_ine.glif</string>
+ <key>DigitOne</key>
+ <string>D_igitO_ne.glif</string>
+ <key>DigitSeven</key>
+ <string>D_igitS_even.glif</string>
+ <key>DigitSix</key>
+ <string>D_igitS_ix.glif</string>
+ <key>DigitThree</key>
+ <string>D_igitT_hree.glif</string>
+ <key>DigitTwo</key>
+ <string>D_igitT_wo.glif</string>
+ <key>DigitZero</key>
+ <string>D_igitZ_ero.glif</string>
+ <key>DollarSgn</key>
+ <string>D_ollarS_gn.glif</string>
+ <key>DottedCirc</key>
+ <string>D_ottedC_irc.glif</string>
+ <key>EqSgn</key>
+ <string>E_qS_gn.glif</string>
+ <key>ExclamationMrk</key>
+ <string>E_xclamationM_rk.glif</string>
+ <key>FullStop</key>
+ <string>F_ullS_top.glif</string>
+ <key>GTSgn</key>
+ <string>G_T_S_gn.glif</string>
+ <key>GraveAccent</key>
+ <string>G_raveA_ccent.glif</string>
+ <key>Hyphen</key>
+ <string>H_yphen.glif</string>
+ <key>HyphenMinus</key>
+ <string>H_yphenM_inus.glif</string>
+ <key>Hyphen_Soft</key>
+ <string>H_yphen_S_oft.glif</string>
+ <key>LTSgn</key>
+ <string>L_T_S_gn.glif</string>
+ <key>LftCurlyBrac</key>
+ <string>L_ftC_urlyB_rac.glif</string>
+ <key>LftParen</key>
+ <string>L_ftP_aren.glif</string>
+ <key>LftSqrBrac</key>
+ <string>L_ftS_qrB_rac.glif</string>
+ <key>LowLine</key>
+ <string>L_owL_ine.glif</string>
+ <key>LtnCapA</key>
+ <string>L_tnC_apA_.glif</string>
+ <key>LtnCapA.alt</key>
+ <string>L_tnC_apA_.alt.glif</string>
+ <key>LtnCapADiaer</key>
+ <string>L_tnC_apA_D_iaer.glif</string>
+ <key>LtnCapB</key>
+ <string>L_tnC_apB_.glif</string>
+ <key>LtnCapC</key>
+ <string>L_tnC_apC_.glif</string>
+ <key>LtnCapD</key>
+ <string>L_tnC_apD_.glif</string>
+ <key>LtnCapE</key>
+ <string>L_tnC_apE_.glif</string>
+ <key>LtnCapF</key>
+ <string>L_tnC_apF_.glif</string>
+ <key>LtnCapG</key>
+ <string>L_tnC_apG_.glif</string>
+ <key>LtnCapH</key>
+ <string>L_tnC_apH_.glif</string>
+ <key>LtnCapI</key>
+ <string>L_tnC_apI_.glif</string>
+ <key>LtnCapJ</key>
+ <string>L_tnC_apJ_.glif</string>
+ <key>LtnCapK</key>
+ <string>L_tnC_apK_.glif</string>
+ <key>LtnCapL</key>
+ <string>L_tnC_apL_.glif</string>
+ <key>LtnCapM</key>
+ <string>L_tnC_apM_.glif</string>
+ <key>LtnCapN</key>
+ <string>L_tnC_apN_.glif</string>
+ <key>LtnCapO</key>
+ <string>L_tnC_apO_.glif</string>
+ <key>LtnCapP</key>
+ <string>L_tnC_apP_.glif</string>
+ <key>LtnCapQ</key>
+ <string>L_tnC_apQ_.glif</string>
+ <key>LtnCapR</key>
+ <string>L_tnC_apR_.glif</string>
+ <key>LtnCapS</key>
+ <string>L_tnC_apS_.glif</string>
+ <key>LtnCapT</key>
+ <string>L_tnC_apT_.glif</string>
+ <key>LtnCapU</key>
+ <string>L_tnC_apU_.glif</string>
+ <key>LtnCapV</key>
+ <string>L_tnC_apV_.glif</string>
+ <key>LtnCapW</key>
+ <string>L_tnC_apW_.glif</string>
+ <key>LtnCapX</key>
+ <string>L_tnC_apX_.glif</string>
+ <key>LtnCapY</key>
+ <string>L_tnC_apY_.glif</string>
+ <key>LtnSmA</key>
+ <string>L_tnS_mA_.glif</string>
+ <key>LtnSmAAcute</key>
+ <string>L_tnS_mA_A_cute.glif</string>
+ <key>LtnSmACircum</key>
+ <string>L_tnS_mA_C_ircum.glif</string>
+ <key>LtnSmADiaer</key>
+ <string>L_tnS_mA_D_iaer.glif</string>
+ <key>LtnSmAGrave</key>
+ <string>L_tnS_mA_G_rave.glif</string>
+ <key>LtnSmARingAbv</key>
+ <string>L_tnS_mA_R_ingA_bv.glif</string>
+ <key>LtnSmATilde</key>
+ <string>L_tnS_mA_T_ilde.glif</string>
+ <key>LtnSmB</key>
+ <string>L_tnS_mB_.glif</string>
+ <key>LtnSmC</key>
+ <string>L_tnS_mC_.glif</string>
+ <key>LtnSmD</key>
+ <string>L_tnS_mD_.glif</string>
+ <key>LtnSmE</key>
+ <string>L_tnS_mE_.glif</string>
+ <key>LtnSmF</key>
+ <string>L_tnS_mF_.glif</string>
+ <key>LtnSmG</key>
+ <string>L_tnS_mG_.glif</string>
+ <key>LtnSmH</key>
+ <string>L_tnS_mH_.glif</string>
+ <key>LtnSmI</key>
+ <string>L_tnS_mI_.glif</string>
+ <key>LtnSmJ</key>
+ <string>L_tnS_mJ_.glif</string>
+ <key>LtnSmK</key>
+ <string>L_tnS_mK_.glif</string>
+ <key>LtnSmL</key>
+ <string>L_tnS_mL_.glif</string>
+ <key>LtnSmM</key>
+ <string>L_tnS_mM_.glif</string>
+ <key>LtnSmN</key>
+ <string>L_tnS_mN_.glif</string>
+ <key>LtnSmO</key>
+ <string>L_tnS_mO_.glif</string>
+ <key>LtnSmP</key>
+ <string>L_tnS_mP_.glif</string>
+ <key>LtnSmQ</key>
+ <string>L_tnS_mQ_.glif</string>
+ <key>LtnSmR</key>
+ <string>L_tnS_mR_.glif</string>
+ <key>LtnSmS</key>
+ <string>L_tnS_mS_.glif</string>
+ <key>LtnSmT</key>
+ <string>L_tnS_mT_.glif</string>
+ <key>LtnSmU</key>
+ <string>L_tnS_mU_.glif</string>
+ <key>LtnSmV</key>
+ <string>L_tnS_mV_.glif</string>
+ <key>LtnSmW</key>
+ <string>L_tnS_mW_.glif</string>
+ <key>LtnSmX</key>
+ <string>L_tnS_mX_.glif</string>
+ <key>LtnSmY</key>
+ <string>L_tnS_mY_.glif</string>
+ <key>NonBreakingHyphen</key>
+ <string>N_onB_reakingH_yphen.glif</string>
+ <key>NumSgn</key>
+ <string>N_umS_gn.glif</string>
+ <key>PercentSgn</key>
+ <string>P_ercentS_gn.glif</string>
+ <key>PlusSgn</key>
+ <string>P_lusS_gn.glif</string>
+ <key>QstnMrk</key>
+ <string>Q_stnM_rk.glif</string>
+ <key>QuotMrk</key>
+ <string>Q_uotM_rk.glif</string>
+ <key>ReverseSolidus</key>
+ <string>R_everseS_olidus.glif</string>
+ <key>RtCurlyBrac</key>
+ <string>R_tC_urlyB_rac.glif</string>
+ <key>RtParen</key>
+ <string>R_tP_aren.glif</string>
+ <key>RtSqrBrac</key>
+ <string>R_tS_qrB_rac.glif</string>
+ <key>Semicolon</key>
+ <string>S_emicolon.glif</string>
+ <key>Solidus</key>
+ <string>S_olidus.glif</string>
+ <key>Space</key>
+ <string>S_pace.glif</string>
+ <key>Tilde</key>
+ <string>T_ilde.glif</string>
+ <key>VertLine</key>
+ <string>V_ertL_ine.glif</string>
+ <key>nonmarkingreturn</key>
+ <string>nonmarkingreturn.glif</string>
+</dict>
+</plist>
diff --git a/tests/reference/ufo/psfsetassocuids.ufo/glyphs/nonmarkingreturn.glif b/tests/reference/ufo/psfsetassocuids.ufo/glyphs/nonmarkingreturn.glif
new file mode 100644
index 0000000..ee41448
--- /dev/null
+++ b/tests/reference/ufo/psfsetassocuids.ufo/glyphs/nonmarkingreturn.glif
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="nonmarkingreturn" format="2">
+ <advance width="1024"/>
+ <outline/>
+</glyph>
diff --git a/tests/reference/ufo/psfsetassocuids.ufo/layercontents.plist b/tests/reference/ufo/psfsetassocuids.ufo/layercontents.plist
new file mode 100644
index 0000000..42b7482
--- /dev/null
+++ b/tests/reference/ufo/psfsetassocuids.ufo/layercontents.plist
@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<array>
+ <array>
+ <string>public.default</string>
+ <string>glyphs</string>
+ </array>
+</array>
+</plist>
diff --git a/tests/reference/ufo/psfsetassocuids.ufo/lib.plist b/tests/reference/ufo/psfsetassocuids.ufo/lib.plist
new file mode 100644
index 0000000..4fe2e05
--- /dev/null
+++ b/tests/reference/ufo/psfsetassocuids.ufo/lib.plist
@@ -0,0 +1,535 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+ <key>com.schriftgestaltung.Glyphs.fontUserData</key>
+ <dict/>
+ <key>com.schriftgestaltung.appVersion</key>
+ <string>1161</string>
+ <key>com.schriftgestaltung.customParameter.GSFont.DisplayStrings</key>
+ <string/>
+ <key>com.schriftgestaltung.customParameter.GSFont.disablesAutomaticAlignment</key>
+ <true/>
+ <key>com.schriftgestaltung.customParameter.GSFont.disablesLastChange</key>
+ <true/>
+ <key>com.schriftgestaltung.customParameter.GSFont.useNiceNames</key>
+ <integer>0</integer>
+ <key>com.schriftgestaltung.customParameter.GSFontMaster.customValue</key>
+ <integer>0</integer>
+ <key>com.schriftgestaltung.customParameter.GSFontMaster.customValue1</key>
+ <integer>0</integer>
+ <key>com.schriftgestaltung.customParameter.GSFontMaster.customValue2</key>
+ <integer>0</integer>
+ <key>com.schriftgestaltung.customParameter.GSFontMaster.customValue3</key>
+ <integer>0</integer>
+ <key>com.schriftgestaltung.customParameter.GSFontMaster.iconName</key>
+ <string/>
+ <key>com.schriftgestaltung.customParameter.GSFontMaster.weightValue</key>
+ <integer>700</integer>
+ <key>com.schriftgestaltung.customParameter.GSFontMaster.widthValue</key>
+ <integer>100</integer>
+ <key>com.schriftgestaltung.disablesAutomaticAlignment</key>
+ <true/>
+ <key>com.schriftgestaltung.disablesLastChange</key>
+ <true/>
+ <key>com.schriftgestaltung.fontMasterOrder</key>
+ <integer>1</integer>
+ <key>com.schriftgestaltung.glyphOrder</key>
+ <array>
+ <string>.notdef</string>
+ <string>.null</string>
+ <string>nonmarkingreturn</string>
+ <string>Space</string>
+ <string>ExclamationMrk</string>
+ <string>QuotMrk</string>
+ <string>NumSgn</string>
+ <string>DollarSgn</string>
+ <string>PercentSgn</string>
+ <string>Ampersand</string>
+ <string>Apos</string>
+ <string>LftParen</string>
+ <string>RtParen</string>
+ <string>Asterisk</string>
+ <string>PlusSgn</string>
+ <string>Comma</string>
+ <string>HyphenMinus</string>
+ <string>FullStop</string>
+ <string>Solidus</string>
+ <string>DigitOne</string>
+ <string>DigitTwo</string>
+ <string>DigitThree</string>
+ <string>DigitFour</string>
+ <string>DigitFive</string>
+ <string>DigitSix</string>
+ <string>DigitSeven</string>
+ <string>DigitEight</string>
+ <string>DigitNine</string>
+ <string>Colon</string>
+ <string>Semicolon</string>
+ <string>LTSgn</string>
+ <string>EqSgn</string>
+ <string>GTSgn</string>
+ <string>QstnMrk</string>
+ <string>AtSgn</string>
+ <string>LtnCapA</string>
+ <string>LtnCapA.alt</string>
+ <string>LtnCapB</string>
+ <string>LtnCapC</string>
+ <string>LtnCapD</string>
+ <string>LtnCapE</string>
+ <string>LtnCapF</string>
+ <string>LtnCapG</string>
+ <string>LtnCapH</string>
+ <string>LtnCapI</string>
+ <string>LtnCapJ</string>
+ <string>LtnCapK</string>
+ <string>LtnCapL</string>
+ <string>LtnCapM</string>
+ <string>LtnCapN</string>
+ <string>LtnCapO</string>
+ <string>LtnCapP</string>
+ <string>LtnCapQ</string>
+ <string>LtnCapR</string>
+ <string>LtnCapS</string>
+ <string>LtnCapT</string>
+ <string>LtnCapU</string>
+ <string>LtnCapV</string>
+ <string>LtnCapW</string>
+ <string>LtnCapX</string>
+ <string>LtnCapY</string>
+ <string>LftSqrBrac</string>
+ <string>ReverseSolidus</string>
+ <string>RtSqrBrac</string>
+ <string>CircumAccent</string>
+ <string>LowLine</string>
+ <string>GraveAccent</string>
+ <string>LtnSmA</string>
+ <string>LtnSmB</string>
+ <string>LtnSmC</string>
+ <string>LtnSmD</string>
+ <string>LtnSmE</string>
+ <string>LtnSmF</string>
+ <string>LtnSmG</string>
+ <string>LtnSmH</string>
+ <string>LtnSmI</string>
+ <string>LtnSmJ</string>
+ <string>LtnSmK</string>
+ <string>LtnSmL</string>
+ <string>LtnSmM</string>
+ <string>LtnSmN</string>
+ <string>LtnSmO</string>
+ <string>LtnSmP</string>
+ <string>LtnSmQ</string>
+ <string>LtnSmR</string>
+ <string>LtnSmS</string>
+ <string>LtnSmT</string>
+ <string>LtnSmU</string>
+ <string>LtnSmV</string>
+ <string>LtnSmW</string>
+ <string>LtnSmX</string>
+ <string>LtnSmY</string>
+ <string>LftCurlyBrac</string>
+ <string>VertLine</string>
+ <string>RtCurlyBrac</string>
+ <string>Tilde</string>
+ <string>LtnCapADiaer</string>
+ <string>LtnSmAAcute</string>
+ <string>LtnSmAGrave</string>
+ <string>LtnSmACircum</string>
+ <string>LtnSmADiaer</string>
+ <string>LtnSmATilde</string>
+ <string>LtnSmARingAbv</string>
+ <string>DottedCirc</string>
+ <string>Hyphen</string>
+ <string>NonBreakingHyphen</string>
+ <string>Hyphen_Soft</string>
+ <string>CombAcute</string>
+ <string>CombGrave</string>
+ <string>CombCircum</string>
+ <string>CombTilde</string>
+ <string>CombDiaer</string>
+ <string>CombRingAbv</string>
+ </array>
+ <key>com.schriftgestaltung.keyboardIncrement</key>
+ <integer>1</integer>
+ <key>com.schriftgestaltung.weight</key>
+ <string>Bold</string>
+ <key>com.schriftgestaltung.weightValue</key>
+ <integer>700</integer>
+ <key>com.schriftgestaltung.width</key>
+ <string>Regular</string>
+ <key>com.schriftgestaltung.widthValue</key>
+ <integer>100</integer>
+ <key>org.sil.lcg.toneLetters</key>
+ <dict>
+ <key>contourWidth</key>
+ <integer>540</integer>
+ <key>dotSize</key>
+ <integer>280</integer>
+ <key>dotSpacing</key>
+ <integer>200</integer>
+ <key>glyphDepth</key>
+ <integer>-25</integer>
+ <key>glyphHeight</key>
+ <integer>1600</integer>
+ <key>italicAngle</key>
+ <integer>0</integer>
+ <key>marginDotLeft</key>
+ <integer>100</integer>
+ <key>marginDotRight</key>
+ <integer>140</integer>
+ <key>marginFlatLeft</key>
+ <integer>100</integer>
+ <key>marginFlatRight</key>
+ <integer>140</integer>
+ <key>marginPointLeft</key>
+ <integer>80</integer>
+ <key>marginPointRight</key>
+ <integer>120</integer>
+ <key>strokeThickness</key>
+ <integer>200</integer>
+ </dict>
+ <key>public.glyphOrder</key>
+ <array>
+ <string>.notdef</string>
+ <string>.null</string>
+ <string>nonmarkingreturn</string>
+ <string>Space</string>
+ <string>ExclamationMrk</string>
+ <string>QuotMrk</string>
+ <string>NumSgn</string>
+ <string>DollarSgn</string>
+ <string>PercentSgn</string>
+ <string>Ampersand</string>
+ <string>Apos</string>
+ <string>LftParen</string>
+ <string>RtParen</string>
+ <string>Asterisk</string>
+ <string>PlusSgn</string>
+ <string>Comma</string>
+ <string>HyphenMinus</string>
+ <string>FullStop</string>
+ <string>Solidus</string>
+ <string>DigitZero</string>
+ <string>DigitOne</string>
+ <string>DigitTwo</string>
+ <string>DigitThree</string>
+ <string>DigitFour</string>
+ <string>DigitFive</string>
+ <string>DigitSix</string>
+ <string>DigitSeven</string>
+ <string>DigitEight</string>
+ <string>DigitNine</string>
+ <string>Colon</string>
+ <string>Semicolon</string>
+ <string>LTSgn</string>
+ <string>EqSgn</string>
+ <string>GTSgn</string>
+ <string>QstnMrk</string>
+ <string>AtSgn</string>
+ <string>LtnCapA</string>
+ <string>LtnCapA.alt</string>
+ <string>LtnCapB</string>
+ <string>LtnCapC</string>
+ <string>LtnCapD</string>
+ <string>LtnCapE</string>
+ <string>LtnCapF</string>
+ <string>LtnCapG</string>
+ <string>LtnCapH</string>
+ <string>LtnCapI</string>
+ <string>LtnCapJ</string>
+ <string>LtnCapK</string>
+ <string>LtnCapL</string>
+ <string>LtnCapM</string>
+ <string>LtnCapN</string>
+ <string>LtnCapO</string>
+ <string>LtnCapP</string>
+ <string>LtnCapQ</string>
+ <string>LtnCapR</string>
+ <string>LtnCapS</string>
+ <string>LtnCapT</string>
+ <string>LtnCapU</string>
+ <string>LtnCapV</string>
+ <string>LtnCapW</string>
+ <string>LtnCapX</string>
+ <string>LtnCapY</string>
+ <string>LftSqrBrac</string>
+ <string>ReverseSolidus</string>
+ <string>RtSqrBrac</string>
+ <string>CircumAccent</string>
+ <string>LowLine</string>
+ <string>GraveAccent</string>
+ <string>LtnSmA</string>
+ <string>LtnSmB</string>
+ <string>LtnSmC</string>
+ <string>LtnSmD</string>
+ <string>LtnSmE</string>
+ <string>LtnSmF</string>
+ <string>LtnSmG</string>
+ <string>LtnSmH</string>
+ <string>LtnSmI</string>
+ <string>LtnSmJ</string>
+ <string>LtnSmK</string>
+ <string>LtnSmL</string>
+ <string>LtnSmM</string>
+ <string>LtnSmN</string>
+ <string>LtnSmO</string>
+ <string>LtnSmP</string>
+ <string>LtnSmQ</string>
+ <string>LtnSmR</string>
+ <string>LtnSmS</string>
+ <string>LtnSmT</string>
+ <string>LtnSmU</string>
+ <string>LtnSmV</string>
+ <string>LtnSmW</string>
+ <string>LtnSmX</string>
+ <string>LtnSmY</string>
+ <string>LftCurlyBrac</string>
+ <string>VertLine</string>
+ <string>RtCurlyBrac</string>
+ <string>Tilde</string>
+ <string>LtnCapADiaer</string>
+ <string>LtnSmAAcute</string>
+ <string>LtnSmAGrave</string>
+ <string>LtnSmACircum</string>
+ <string>LtnSmADiaer</string>
+ <string>LtnSmATilde</string>
+ <string>LtnSmARingAbv</string>
+ <string>DottedCirc</string>
+ <string>Hyphen</string>
+ <string>NonBreakingHyphen</string>
+ <string>Hyphen_Soft</string>
+ <string>CombAcute</string>
+ <string>CombGrave</string>
+ <string>CombCircum</string>
+ <string>CombTilde</string>
+ <string>CombDiaer</string>
+ <string>CombRingAbv</string>
+ </array>
+ <key>public.postscriptNames</key>
+ <dict>
+ <key>Ampersand</key>
+ <string>ampersand</string>
+ <key>Apos</key>
+ <string>quotesingle</string>
+ <key>Asterisk</key>
+ <string>asterisk</string>
+ <key>AtSgn</key>
+ <string>at</string>
+ <key>CircumAccent</key>
+ <string>asciicircum</string>
+ <key>Colon</key>
+ <string>colon</string>
+ <key>CombAcute</key>
+ <string>acutecomb</string>
+ <key>CombCircum</key>
+ <string>uni0302</string>
+ <key>CombDiaer</key>
+ <string>uni0308</string>
+ <key>CombGrave</key>
+ <string>gravecomb</string>
+ <key>CombRingAbv</key>
+ <string>uni030A</string>
+ <key>CombTilde</key>
+ <string>tildecomb</string>
+ <key>Comma</key>
+ <string>comma</string>
+ <key>DigitEight</key>
+ <string>eight</string>
+ <key>DigitFive</key>
+ <string>five</string>
+ <key>DigitFour</key>
+ <string>four</string>
+ <key>DigitNine</key>
+ <string>nine</string>
+ <key>DigitOne</key>
+ <string>one</string>
+ <key>DigitSeven</key>
+ <string>seven</string>
+ <key>DigitSix</key>
+ <string>six</string>
+ <key>DigitThree</key>
+ <string>three</string>
+ <key>DigitTwo</key>
+ <string>two</string>
+ <key>DigitZero</key>
+ <string>zero</string>
+ <key>DollarSgn</key>
+ <string>dollar</string>
+ <key>DottedCirc</key>
+ <string>uni25CC</string>
+ <key>EqSgn</key>
+ <string>equal</string>
+ <key>ExclamationMrk</key>
+ <string>exclam</string>
+ <key>FullStop</key>
+ <string>period</string>
+ <key>GTSgn</key>
+ <string>greater</string>
+ <key>GraveAccent</key>
+ <string>grave</string>
+ <key>Hyphen</key>
+ <string>uni2010</string>
+ <key>HyphenMinus</key>
+ <string>hyphen</string>
+ <key>Hyphen_Soft</key>
+ <string>uni00AD</string>
+ <key>LTSgn</key>
+ <string>less</string>
+ <key>LftCurlyBrac</key>
+ <string>braceleft</string>
+ <key>LftParen</key>
+ <string>parenleft</string>
+ <key>LftSqrBrac</key>
+ <string>bracketleft</string>
+ <key>LowLine</key>
+ <string>underscore</string>
+ <key>LtnCapA</key>
+ <string>A</string>
+ <key>LtnCapA.alt</key>
+ <string>A</string>
+ <key>LtnCapADiaer</key>
+ <string>Adieresis</string>
+ <key>LtnCapB</key>
+ <string>B</string>
+ <key>LtnCapC</key>
+ <string>C</string>
+ <key>LtnCapD</key>
+ <string>D</string>
+ <key>LtnCapE</key>
+ <string>E</string>
+ <key>LtnCapF</key>
+ <string>F</string>
+ <key>LtnCapG</key>
+ <string>G</string>
+ <key>LtnCapH</key>
+ <string>H</string>
+ <key>LtnCapI</key>
+ <string>I</string>
+ <key>LtnCapJ</key>
+ <string>J</string>
+ <key>LtnCapK</key>
+ <string>K</string>
+ <key>LtnCapL</key>
+ <string>L</string>
+ <key>LtnCapM</key>
+ <string>M</string>
+ <key>LtnCapN</key>
+ <string>N</string>
+ <key>LtnCapO</key>
+ <string>O</string>
+ <key>LtnCapP</key>
+ <string>P</string>
+ <key>LtnCapQ</key>
+ <string>Q</string>
+ <key>LtnCapR</key>
+ <string>R</string>
+ <key>LtnCapS</key>
+ <string>S</string>
+ <key>LtnCapT</key>
+ <string>T</string>
+ <key>LtnCapU</key>
+ <string>U</string>
+ <key>LtnCapV</key>
+ <string>V</string>
+ <key>LtnCapW</key>
+ <string>W</string>
+ <key>LtnCapX</key>
+ <string>X</string>
+ <key>LtnCapY</key>
+ <string>Y</string>
+ <key>LtnSmA</key>
+ <string>a</string>
+ <key>LtnSmAAcute</key>
+ <string>aacute</string>
+ <key>LtnSmACircum</key>
+ <string>acircumflex</string>
+ <key>LtnSmADiaer</key>
+ <string>adieresis</string>
+ <key>LtnSmAGrave</key>
+ <string>agrave</string>
+ <key>LtnSmARingAbv</key>
+ <string>aring</string>
+ <key>LtnSmATilde</key>
+ <string>atilde</string>
+ <key>LtnSmB</key>
+ <string>b</string>
+ <key>LtnSmC</key>
+ <string>c</string>
+ <key>LtnSmD</key>
+ <string>d</string>
+ <key>LtnSmE</key>
+ <string>e</string>
+ <key>LtnSmF</key>
+ <string>f</string>
+ <key>LtnSmG</key>
+ <string>g</string>
+ <key>LtnSmH</key>
+ <string>h</string>
+ <key>LtnSmI</key>
+ <string>i</string>
+ <key>LtnSmJ</key>
+ <string>j</string>
+ <key>LtnSmK</key>
+ <string>k</string>
+ <key>LtnSmL</key>
+ <string>l</string>
+ <key>LtnSmM</key>
+ <string>m</string>
+ <key>LtnSmN</key>
+ <string>n</string>
+ <key>LtnSmO</key>
+ <string>o</string>
+ <key>LtnSmP</key>
+ <string>p</string>
+ <key>LtnSmQ</key>
+ <string>q</string>
+ <key>LtnSmR</key>
+ <string>r</string>
+ <key>LtnSmS</key>
+ <string>s</string>
+ <key>LtnSmT</key>
+ <string>t</string>
+ <key>LtnSmU</key>
+ <string>u</string>
+ <key>LtnSmV</key>
+ <string>v</string>
+ <key>LtnSmW</key>
+ <string>w</string>
+ <key>LtnSmX</key>
+ <string>x</string>
+ <key>LtnSmY</key>
+ <string>y</string>
+ <key>NonBreakingHyphen</key>
+ <string>uni2011</string>
+ <key>NumSgn</key>
+ <string>numbersign</string>
+ <key>PercentSgn</key>
+ <string>percent</string>
+ <key>PlusSgn</key>
+ <string>plus</string>
+ <key>QstnMrk</key>
+ <string>question</string>
+ <key>QuotMrk</key>
+ <string>quotedbl</string>
+ <key>ReverseSolidus</key>
+ <string>backslash</string>
+ <key>RtCurlyBrac</key>
+ <string>braceright</string>
+ <key>RtParen</key>
+ <string>parenright</string>
+ <key>RtSqrBrac</key>
+ <string>bracketright</string>
+ <key>Semicolon</key>
+ <string>semicolon</string>
+ <key>Solidus</key>
+ <string>slash</string>
+ <key>Space</key>
+ <string>space</string>
+ <key>Tilde</key>
+ <string>asciitilde</string>
+ <key>VertLine</key>
+ <string>bar</string>
+ </dict>
+</dict>
+</plist>
diff --git a/tests/reference/ufo/psfsetassocuids.ufo/metainfo.plist b/tests/reference/ufo/psfsetassocuids.ufo/metainfo.plist
new file mode 100644
index 0000000..aa10c5c
--- /dev/null
+++ b/tests/reference/ufo/psfsetassocuids.ufo/metainfo.plist
@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+ <key>creator</key>
+ <string>org.sil.scripts.pysilfont</string>
+ <key>formatVersion</key>
+ <integer>3</integer>
+</dict>
+</plist>
diff --git a/tests/reference/ufo/psfsetglyphorder.lg b/tests/reference/ufo/psfsetglyphorder.lg
new file mode 100644
index 0000000..d2af751
--- /dev/null
+++ b/tests/reference/ufo/psfsetglyphorder.lg
@@ -0,0 +1,158 @@
+2021-06-29 14:42:22 Progress: Running: psfsetglyphorder tests/input/font-psf-test/source/PsfTest-Italic.ufo -i tests/input/glyph_data.csv -l local/testresults/ufo/psfsetglyphorder.log -p loglevel=i
+2021-06-29 14:42:22 Progress: Opening file for input: tests/input/glyph_data.csv
+2021-06-29 14:42:22 Progress: Reading UFO: tests/input/font-psf-test/source/PsfTest-Italic.ufo
+2021-06-29 14:42:22 Info: Processing Glyph Layer 0: public.defaultglyphs
+2021-06-29 14:42:22 Progress: Checking fontinfo.plist metadata
+2021-06-29 14:42:22 Warning: openTypeOS2FamilyClass would be removed from fontinfo Old value: [0, 0]
+2021-06-29 14:42:22 Info: Types: Old - list, New - NoneType
+2021-06-29 14:42:22 Warning: year would be removed from fontinfo Old value: 2021
+2021-06-29 14:42:22 Info: Types: Old - int, New - NoneType
+2021-06-29 14:42:22 Warning: capHeight would be updated Old value: 1485.3, new value: 1485
+2021-06-29 14:42:22 Info: Types: Old - float, New - int
+2021-06-29 14:42:22 Warning: styleMapFamilyName would be uppdated Old value: Psf test, new value: Psf Test
+2021-06-29 14:42:22 Info: Types: Old - string, New - string
+2021-06-29 14:42:22 Warning: openTypeOS2TypoLineGap would be updated Old value: 1, new value: 0
+2021-06-29 14:42:22 Info: Types: Old - int, New - int
+2021-06-29 14:42:22 Warning: openTypeOS2Selection would be added New value: [7]
+2021-06-29 14:42:22 Info: Types: Old - NoneType, New - list
+2021-06-29 14:42:22 Warning: openTypeNamePreferredFamilyName would be updated Old value: Psf Testing, new value: Psf Test
+2021-06-29 14:42:22 Info: Types: Old - string, New - string
+2021-06-29 14:42:22 Progress: Checking lib.plist metadata
+2021-06-29 14:42:22 Warning: com.schriftgestaltung.disablesAutomaticAlignment would be deleted - obsolete key Old value: True
+2021-06-29 14:42:22 Info: Types: Old - bool, New - NoneType
+2021-06-29 14:42:22 Warning: com.schriftgestaltung.disablesLastChange would be deleted - obsolete key Old value: True
+2021-06-29 14:42:22 Info: Types: Old - bool, New - NoneType
+2021-06-29 14:42:22 Progress: Check & fix results:- Errors: 0, Changes to make: 9, Other warnings: 0
+2021-06-29 14:42:22 Progress: See log file for details
+2021-06-29 14:42:22 Info: No glyph in font for LtnSmEAcute
+2021-06-29 14:42:22 Info: No glyph in font for LtnSmIAcute
+2021-06-29 14:42:22 Info: No glyph in font for LtnSmOAcute
+2021-06-29 14:42:22 Info: No glyph in font for LtnSmUAcute
+2021-06-29 14:42:22 Info: No glyph in font for Bullet
+2021-06-29 14:42:22 Info: No glyph in font for AcuteAccent
+2021-06-29 14:42:22 Info: No glyph in font for LtnCapEAcute
+2021-06-29 14:42:22 Info: No glyph in font for LtnCapAAcute
+2021-06-29 14:42:22 Info: No glyph in font for LtnCapIAcute
+2021-06-29 14:42:22 Info: No glyph in font for LtnCapOAcute
+2021-06-29 14:42:22 Info: No glyph in font for LtnCapUAcute
+2021-06-29 14:42:22 Info: No glyph in font for ModCircumAccent
+2021-06-29 14:42:22 Info: No glyph in font for DblAcuteAccent
+2021-06-29 14:42:22 Info: No glyph in font for LtnSmYAcute
+2021-06-29 14:42:22 Info: No glyph in font for LtnCapYAcute
+2021-06-29 14:42:22 Info: No glyph in font for SupOne
+2021-06-29 14:42:22 Info: No glyph in font for SupThree
+2021-06-29 14:42:22 Info: No glyph in font for VulgFracOneHalf
+2021-06-29 14:42:22 Info: No glyph in font for VulgFracOneQuarter
+2021-06-29 14:42:22 Info: No glyph in font for VulgFracThreeQuarters
+2021-06-29 14:42:22 Info: No glyph in font for BulletOperator
+2021-06-29 14:42:22 Info: No entry in input file for font glyph .notdef
+2021-06-29 14:42:22 Info: No entry in input file for font glyph .null
+2021-06-29 14:42:22 Info: No entry in input file for font glyph Ampersand
+2021-06-29 14:42:22 Info: No entry in input file for font glyph Apos
+2021-06-29 14:42:22 Info: No entry in input file for font glyph Asterisk
+2021-06-29 14:42:22 Info: No entry in input file for font glyph AtSgn
+2021-06-29 14:42:22 Info: No entry in input file for font glyph Colon
+2021-06-29 14:42:22 Info: No entry in input file for font glyph CombCircum
+2021-06-29 14:42:22 Info: No entry in input file for font glyph CombDiaer
+2021-06-29 14:42:22 Info: No entry in input file for font glyph CombGrave
+2021-06-29 14:42:22 Info: No entry in input file for font glyph CombRingAbv
+2021-06-29 14:42:22 Info: No entry in input file for font glyph CombTilde
+2021-06-29 14:42:22 Info: No entry in input file for font glyph Comma
+2021-06-29 14:42:22 Info: No entry in input file for font glyph DigitEight
+2021-06-29 14:42:22 Info: No entry in input file for font glyph DigitFive
+2021-06-29 14:42:22 Info: No entry in input file for font glyph DigitFour
+2021-06-29 14:42:22 Info: No entry in input file for font glyph DigitNine
+2021-06-29 14:42:22 Info: No entry in input file for font glyph DigitOne
+2021-06-29 14:42:22 Info: No entry in input file for font glyph DigitSeven
+2021-06-29 14:42:22 Info: No entry in input file for font glyph DigitSix
+2021-06-29 14:42:22 Info: No entry in input file for font glyph DigitThree
+2021-06-29 14:42:22 Info: No entry in input file for font glyph DigitTwo
+2021-06-29 14:42:22 Info: No entry in input file for font glyph DigitZero
+2021-06-29 14:42:22 Info: No entry in input file for font glyph DollarSgn
+2021-06-29 14:42:22 Info: No entry in input file for font glyph DottedCirc
+2021-06-29 14:42:22 Info: No entry in input file for font glyph EqSgn
+2021-06-29 14:42:22 Info: No entry in input file for font glyph ExclamationMrk
+2021-06-29 14:42:22 Info: No entry in input file for font glyph FullStop
+2021-06-29 14:42:22 Info: No entry in input file for font glyph GTSgn
+2021-06-29 14:42:22 Info: No entry in input file for font glyph GraveAccent
+2021-06-29 14:42:22 Info: No entry in input file for font glyph Hyphen
+2021-06-29 14:42:22 Info: No entry in input file for font glyph Hyphen_Soft
+2021-06-29 14:42:22 Info: No entry in input file for font glyph LTSgn
+2021-06-29 14:42:22 Info: No entry in input file for font glyph LftCurlyBrac
+2021-06-29 14:42:22 Info: No entry in input file for font glyph LftParen
+2021-06-29 14:42:22 Info: No entry in input file for font glyph LftSqrBrac
+2021-06-29 14:42:22 Info: No entry in input file for font glyph LowLine
+2021-06-29 14:42:22 Info: No entry in input file for font glyph LtnCapA
+2021-06-29 14:42:22 Info: No entry in input file for font glyph LtnCapADiaer
+2021-06-29 14:42:22 Info: No entry in input file for font glyph LtnCapB
+2021-06-29 14:42:22 Info: No entry in input file for font glyph LtnCapC
+2021-06-29 14:42:22 Info: No entry in input file for font glyph LtnCapD
+2021-06-29 14:42:22 Info: No entry in input file for font glyph LtnCapE
+2021-06-29 14:42:22 Info: No entry in input file for font glyph LtnCapF
+2021-06-29 14:42:22 Info: No entry in input file for font glyph LtnCapG
+2021-06-29 14:42:22 Info: No entry in input file for font glyph LtnCapH
+2021-06-29 14:42:22 Info: No entry in input file for font glyph LtnCapI
+2021-06-29 14:42:22 Info: No entry in input file for font glyph LtnCapJ
+2021-06-29 14:42:22 Info: No entry in input file for font glyph LtnCapK
+2021-06-29 14:42:22 Info: No entry in input file for font glyph LtnCapL
+2021-06-29 14:42:22 Info: No entry in input file for font glyph LtnCapM
+2021-06-29 14:42:22 Info: No entry in input file for font glyph LtnCapN
+2021-06-29 14:42:22 Info: No entry in input file for font glyph LtnCapO
+2021-06-29 14:42:22 Info: No entry in input file for font glyph LtnCapP
+2021-06-29 14:42:22 Info: No entry in input file for font glyph LtnCapQ
+2021-06-29 14:42:22 Info: No entry in input file for font glyph LtnCapR
+2021-06-29 14:42:22 Info: No entry in input file for font glyph LtnCapS
+2021-06-29 14:42:22 Info: No entry in input file for font glyph LtnCapT
+2021-06-29 14:42:22 Info: No entry in input file for font glyph LtnCapU
+2021-06-29 14:42:22 Info: No entry in input file for font glyph LtnCapV
+2021-06-29 14:42:22 Info: No entry in input file for font glyph LtnCapW
+2021-06-29 14:42:22 Info: No entry in input file for font glyph LtnCapX
+2021-06-29 14:42:22 Info: No entry in input file for font glyph LtnCapY
+2021-06-29 14:42:22 Info: No entry in input file for font glyph LtnSmA
+2021-06-29 14:42:22 Info: No entry in input file for font glyph LtnSmACircum
+2021-06-29 14:42:22 Info: No entry in input file for font glyph LtnSmADiaer
+2021-06-29 14:42:22 Info: No entry in input file for font glyph LtnSmAGrave
+2021-06-29 14:42:22 Info: No entry in input file for font glyph LtnSmARingAbv
+2021-06-29 14:42:22 Info: No entry in input file for font glyph LtnSmATilde
+2021-06-29 14:42:22 Info: No entry in input file for font glyph LtnSmB
+2021-06-29 14:42:22 Info: No entry in input file for font glyph LtnSmC
+2021-06-29 14:42:22 Info: No entry in input file for font glyph LtnSmD
+2021-06-29 14:42:22 Info: No entry in input file for font glyph LtnSmE
+2021-06-29 14:42:22 Info: No entry in input file for font glyph LtnSmF
+2021-06-29 14:42:22 Info: No entry in input file for font glyph LtnSmG
+2021-06-29 14:42:22 Info: No entry in input file for font glyph LtnSmH
+2021-06-29 14:42:22 Info: No entry in input file for font glyph LtnSmI
+2021-06-29 14:42:22 Info: No entry in input file for font glyph LtnSmJ
+2021-06-29 14:42:22 Info: No entry in input file for font glyph LtnSmK
+2021-06-29 14:42:22 Info: No entry in input file for font glyph LtnSmL
+2021-06-29 14:42:22 Info: No entry in input file for font glyph LtnSmM
+2021-06-29 14:42:22 Info: No entry in input file for font glyph LtnSmN
+2021-06-29 14:42:22 Info: No entry in input file for font glyph LtnSmO
+2021-06-29 14:42:22 Info: No entry in input file for font glyph LtnSmP
+2021-06-29 14:42:22 Info: No entry in input file for font glyph LtnSmQ
+2021-06-29 14:42:22 Info: No entry in input file for font glyph LtnSmR
+2021-06-29 14:42:22 Info: No entry in input file for font glyph LtnSmS
+2021-06-29 14:42:22 Info: No entry in input file for font glyph LtnSmT
+2021-06-29 14:42:22 Info: No entry in input file for font glyph LtnSmU
+2021-06-29 14:42:22 Info: No entry in input file for font glyph LtnSmV
+2021-06-29 14:42:22 Info: No entry in input file for font glyph LtnSmW
+2021-06-29 14:42:22 Info: No entry in input file for font glyph LtnSmX
+2021-06-29 14:42:22 Info: No entry in input file for font glyph LtnSmY
+2021-06-29 14:42:22 Info: No entry in input file for font glyph NonBreakingHyphen
+2021-06-29 14:42:22 Info: No entry in input file for font glyph NumSgn
+2021-06-29 14:42:22 Info: No entry in input file for font glyph PercentSgn
+2021-06-29 14:42:22 Info: No entry in input file for font glyph PlusSgn
+2021-06-29 14:42:22 Info: No entry in input file for font glyph QstnMrk
+2021-06-29 14:42:22 Info: No entry in input file for font glyph QuotMrk
+2021-06-29 14:42:22 Info: No entry in input file for font glyph RtCurlyBrac
+2021-06-29 14:42:22 Info: No entry in input file for font glyph RtParen
+2021-06-29 14:42:22 Info: No entry in input file for font glyph RtSqrBrac
+2021-06-29 14:42:22 Info: No entry in input file for font glyph Semicolon
+2021-06-29 14:42:22 Info: No entry in input file for font glyph Solidus
+2021-06-29 14:42:22 Info: No entry in input file for font glyph Space
+2021-06-29 14:42:22 Info: No entry in input file for font glyph Tilde
+2021-06-29 14:42:22 Info: No entry in input file for font glyph VertLine
+2021-06-29 14:42:22 Progress: Processing font for output
+2021-06-29 14:42:22 Progress: Output UFO already exists - reading for comparison
+2021-06-29 14:42:22 Progress: Writing font to local/testresults/ufo/psfsetglyphorder.ufo
+2021-06-29 14:42:22 Info: Processing glyphs directory
diff --git a/tests/reference/ufo/psfsetglyphorder.ufo/fontinfo.plist b/tests/reference/ufo/psfsetglyphorder.ufo/fontinfo.plist
new file mode 100644
index 0000000..44ce162
--- /dev/null
+++ b/tests/reference/ufo/psfsetglyphorder.ufo/fontinfo.plist
@@ -0,0 +1,243 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+ <key>ascender</key>
+ <integer>2100</integer>
+ <key>capHeight</key>
+ <real>1485.3</real>
+ <key>copyright</key>
+ <string>Copyright (c) 2004-2021 SIL International</string>
+ <key>descender</key>
+ <integer>-550</integer>
+ <key>familyName</key>
+ <string>Psf Test</string>
+ <key>italicAngle</key>
+ <integer>-14</integer>
+ <key>openTypeHeadCreated</key>
+ <string>2021/01/29 10:05:07</string>
+ <key>openTypeHheaAscender</key>
+ <integer>2100</integer>
+ <key>openTypeHheaDescender</key>
+ <integer>-550</integer>
+ <key>openTypeHheaLineGap</key>
+ <integer>0</integer>
+ <key>openTypeNameDescription</key>
+ <string>Copyright (c) 2004-2021 SIL International</string>
+ <key>openTypeNameDesigner</key>
+ <string>Victor Gaultney, Annie Olsen, Julie Remington, Don Collingsworth, Eric Hays, Becca Hirsbrunner</string>
+ <key>openTypeNameDesignerURL</key>
+ <string>http://scripts.sil.org/</string>
+ <key>openTypeNameLicense</key>
+ <string>Copyright (c) 2004-2021 SIL International (http://www.sil.org/) with Reserved Font Names "Andika" and "SIL".
+
+This Font Software is licensed under the SIL Open Font License, Version 1.1. This license is copied below, and is also available with a FAQ at: http://scripts.sil.org/OFL
+
+
+-----------------------------------------------------------
+SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007
+-----------------------------------------------------------
+
+PREAMBLE
+The goals of the Open Font License (OFL) are to stimulate worldwide development of collaborative font projects, to support the font creation efforts of academic and linguistic communities, and to provide a free and open framework in which fonts may be shared and improved in partnership with others.
+
+The OFL allows the licensed fonts to be used, studied, modified and redistributed freely as long as they are not sold by themselves. The fonts, including any derivative works, can be bundled, embedded, redistributed and/or sold with any software provided that any reserved names are not used by derivative works. The fonts and derivatives, however, cannot be released under any other type of license. The requirement for fonts to remain under this license does not apply to any document created using the fonts or their derivatives.
+
+DEFINITIONS
+"Font Software" refers to the set of files released by the Copyright Holder(s) under this license and clearly marked as such. This may include source files, build scripts and documentation.
+
+"Reserved Font Name" refers to any names specified as such after the copyright statement(s).
+
+"Original Version" refers to the collection of Font Software components as distributed by the Copyright Holder(s).
+
+"Modified Version" refers to any derivative made by adding to, deleting, or substituting -- in part or in whole -- any of the components of the Original Version, by changing formats or by porting the Font Software to a new environment.
+
+"Author" refers to any designer, engineer, programmer, technical writer or other person who contributed to the Font Software.
+
+PERMISSION &amp; CONDITIONS
+Permission is hereby granted, free of charge, to any person obtaining a copy of the Font Software, to use, study, copy, merge, embed, modify, redistribute, and sell modified and unmodified copies of the Font Software, subject to the following conditions:
+
+1) Neither the Font Software nor any of its individual components, in Original or Modified Versions, may be sold by itself.
+
+2) Original or Modified Versions of the Font Software may be bundled, redistributed and/or sold with any software, provided that each copy contains the above copyright notice and this license. These can be included either as stand-alone text files, human-readable headers or in the appropriate machine-readable metadata fields within text or binary files as long as those fields can be easily viewed by the user.
+
+3) No Modified Version of the Font Software may use the Reserved Font Name(s) unless explicit written permission is granted by the corresponding Copyright Holder. This restriction only applies to the primary font name as presented to the users.
+
+4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font Software shall not be used to promote, endorse or advertise any Modified Version, except to acknowledge the contribution(s) of the Copyright Holder(s) and the Author(s) or with their explicit written permission.
+
+5) The Font Software, modified or unmodified, in part or in whole, must be distributed entirely under this license, and must not be distributed under any other license. The requirement for fonts to remain under this license does not apply to any document created using the Font Software.
+
+TERMINATION
+This license becomes null and void if any of the above conditions are not met.
+
+DISCLAIMER
+THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM OTHER DEALINGS IN THE FONT SOFTWARE.</string>
+ <key>openTypeNameLicenseURL</key>
+ <string>http://scripts.sil.org/OFL</string>
+ <key>openTypeNameManufacturer</key>
+ <string>SIL International</string>
+ <key>openTypeNameManufacturerURL</key>
+ <string>http://scripts.sil.org</string>
+ <key>openTypeNamePreferredFamilyName</key>
+ <string>Psf Testing</string>
+ <key>openTypeNamePreferredSubfamilyName</key>
+ <string>Italic</string>
+ <key>openTypeNameUniqueID</key>
+ <string>SIL International: Psf Test Italic: 2022</string>
+ <key>openTypeNameVersion</key>
+ <string>Version 5.550</string>
+ <key>openTypeOS2CodePageRanges</key>
+ <array>
+ <integer>0</integer>
+ <integer>1</integer>
+ <integer>2</integer>
+ <integer>4</integer>
+ <integer>7</integer>
+ <integer>8</integer>
+ </array>
+ <key>openTypeOS2FamilyClass</key>
+ <array>
+ <integer>0</integer>
+ <integer>0</integer>
+ </array>
+ <key>openTypeOS2Panose</key>
+ <array>
+ <integer>2</integer>
+ <integer>0</integer>
+ <integer>0</integer>
+ <integer>0</integer>
+ <integer>0</integer>
+ <integer>0</integer>
+ <integer>0</integer>
+ <integer>0</integer>
+ <integer>0</integer>
+ <integer>0</integer>
+ </array>
+ <key>openTypeOS2StrikeoutPosition</key>
+ <integer>700</integer>
+ <key>openTypeOS2StrikeoutSize</key>
+ <integer>100</integer>
+ <key>openTypeOS2SubscriptXOffset</key>
+ <integer>0</integer>
+ <key>openTypeOS2SubscriptXSize</key>
+ <integer>1433</integer>
+ <key>openTypeOS2SubscriptYOffset</key>
+ <integer>286</integer>
+ <key>openTypeOS2SubscriptYSize</key>
+ <integer>1331</integer>
+ <key>openTypeOS2SuperscriptXOffset</key>
+ <integer>0</integer>
+ <key>openTypeOS2SuperscriptXSize</key>
+ <integer>1433</integer>
+ <key>openTypeOS2SuperscriptYOffset</key>
+ <integer>976</integer>
+ <key>openTypeOS2SuperscriptYSize</key>
+ <integer>1331</integer>
+ <key>openTypeOS2Type</key>
+ <array/>
+ <key>openTypeOS2TypoAscender</key>
+ <integer>2100</integer>
+ <key>openTypeOS2TypoDescender</key>
+ <integer>-550</integer>
+ <key>openTypeOS2TypoLineGap</key>
+ <integer>1</integer>
+ <key>openTypeOS2UnicodeRanges</key>
+ <array>
+ <integer>0</integer>
+ <integer>1</integer>
+ <integer>6</integer>
+ <integer>7</integer>
+ <integer>31</integer>
+ <integer>33</integer>
+ <integer>35</integer>
+ <integer>36</integer>
+ <integer>37</integer>
+ <integer>38</integer>
+ <integer>39</integer>
+ <integer>40</integer>
+ <integer>45</integer>
+ <integer>46</integer>
+ <integer>47</integer>
+ <integer>57</integer>
+ <integer>60</integer>
+ <integer>62</integer>
+ <integer>64</integer>
+ <integer>67</integer>
+ <integer>69</integer>
+ <integer>89</integer>
+ </array>
+ <key>openTypeOS2VendorID</key>
+ <string>SIL</string>
+ <key>openTypeOS2WeightClass</key>
+ <integer>400</integer>
+ <key>openTypeOS2WidthClass</key>
+ <integer>5</integer>
+ <key>openTypeOS2WinAscent</key>
+ <integer>2100</integer>
+ <key>openTypeOS2WinDescent</key>
+ <integer>550</integer>
+ <key>postscriptBlueValues</key>
+ <array>
+ <integer>-490</integer>
+ <integer>-490</integer>
+ <integer>-25</integer>
+ <integer>0</integer>
+ <integer>1020</integer>
+ <integer>1040</integer>
+ <integer>1455</integer>
+ <integer>1485</integer>
+ <integer>1600</integer>
+ <integer>1620</integer>
+ </array>
+ <key>postscriptFontName</key>
+ <string>PsfTest-Italic</string>
+ <key>postscriptFullName</key>
+ <string>Psf Test Italic</string>
+ <key>postscriptStemSnapH</key>
+ <array>
+ <integer>140</integer>
+ <integer>145</integer>
+ <integer>150</integer>
+ <integer>155</integer>
+ <integer>160</integer>
+ <integer>165</integer>
+ <integer>170</integer>
+ <integer>175</integer>
+ <integer>185</integer>
+ <integer>270</integer>
+ </array>
+ <key>postscriptStemSnapV</key>
+ <array>
+ <integer>165</integer>
+ <integer>180</integer>
+ <integer>185</integer>
+ <integer>190</integer>
+ <integer>195</integer>
+ <integer>200</integer>
+ <integer>205</integer>
+ <integer>270</integer>
+ </array>
+ <key>postscriptUnderlinePosition</key>
+ <integer>-110</integer>
+ <key>postscriptUnderlineThickness</key>
+ <integer>80</integer>
+ <key>styleMapFamilyName</key>
+ <string>Psf test</string>
+ <key>styleMapStyleName</key>
+ <string>italic</string>
+ <key>styleName</key>
+ <string>Italic</string>
+ <key>trademark</key>
+ <string>Andika is a trademark of SIL International.</string>
+ <key>unitsPerEm</key>
+ <integer>2048</integer>
+ <key>versionMajor</key>
+ <integer>5</integer>
+ <key>versionMinor</key>
+ <integer>550</integer>
+ <key>xHeight</key>
+ <integer>1040</integer>
+ <key>year</key>
+ <integer>2021</integer>
+</dict>
+</plist>
diff --git a/tests/reference/ufo/psfsetglyphorder.ufo/glyphs/A_mpersand.glif b/tests/reference/ufo/psfsetglyphorder.ufo/glyphs/A_mpersand.glif
new file mode 100644
index 0000000..689cb3e
--- /dev/null
+++ b/tests/reference/ufo/psfsetglyphorder.ufo/glyphs/A_mpersand.glif
@@ -0,0 +1,61 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="Ampersand" format="2">
+ <advance width="1202"/>
+ <unicode hex="0026"/>
+ <outline>
+ <contour>
+ <point x="1054" y="559" type="line"/>
+ <point x="949" y="395"/>
+ <point x="616" y="147"/>
+ <point x="441" y="147" type="curve" smooth="yes"/>
+ <point x="318" y="147"/>
+ <point x="256" y="224"/>
+ <point x="256" y="314" type="curve" smooth="yes"/>
+ <point x="256" y="453"/>
+ <point x="369" y="575"/>
+ <point x="590" y="725" type="curve" smooth="yes"/>
+ <point x="836" y="892"/>
+ <point x="1022" y="1067"/>
+ <point x="1022" y="1223" type="curve" smooth="yes"/>
+ <point x="1022" y="1363"/>
+ <point x="894" y="1455"/>
+ <point x="762" y="1455" type="curve" smooth="yes"/>
+ <point x="504" y="1455"/>
+ <point x="378" y="1328"/>
+ <point x="378" y="1114" type="curve" smooth="yes"/>
+ <point x="378" y="953"/>
+ <point x="514" y="771"/>
+ <point x="614" y="559" type="curve" smooth="yes"/>
+ <point x="783" y="198"/>
+ <point x="906" y="-25"/>
+ <point x="958" y="-25" type="curve" smooth="yes"/>
+ <point x="993" y="-25"/>
+ <point x="1087" y="37"/>
+ <point x="1132" y="69" type="curve"/>
+ <point x="1046" y="108"/>
+ <point x="926" y="291"/>
+ <point x="756" y="666" type="curve" smooth="yes"/>
+ <point x="665" y="866"/>
+ <point x="544" y="1029"/>
+ <point x="544" y="1149" type="curve" smooth="yes"/>
+ <point x="544" y="1252"/>
+ <point x="632" y="1323"/>
+ <point x="724" y="1323" type="curve" smooth="yes"/>
+ <point x="794" y="1323"/>
+ <point x="858" y="1266"/>
+ <point x="858" y="1193" type="curve" smooth="yes"/>
+ <point x="858" y="1107"/>
+ <point x="743" y="1004"/>
+ <point x="492" y="826" type="curve" smooth="yes"/>
+ <point x="182" y="606"/>
+ <point x="73" y="439"/>
+ <point x="73" y="288" type="curve" smooth="yes"/>
+ <point x="73" y="113"/>
+ <point x="195" y="-25"/>
+ <point x="383" y="-25" type="curve" smooth="yes"/>
+ <point x="656" y="-25"/>
+ <point x="1009" y="269"/>
+ <point x="1126" y="426" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetglyphorder.ufo/glyphs/A_pos.glif b/tests/reference/ufo/psfsetglyphorder.ufo/glyphs/A_pos.glif
new file mode 100644
index 0000000..deb1650
--- /dev/null
+++ b/tests/reference/ufo/psfsetglyphorder.ufo/glyphs/A_pos.glif
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="Apos" format="2">
+ <advance width="585"/>
+ <unicode hex="0027"/>
+ <outline>
+ <contour>
+ <point x="560" y="1024" type="line"/>
+ <point x="599" y="1162"/>
+ <point x="643" y="1312"/>
+ <point x="732" y="1553" type="curve"/>
+ <point x="527" y="1553" type="line"/>
+ <point x="498" y="1312"/>
+ <point x="465" y="1162"/>
+ <point x="435" y="1024" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetglyphorder.ufo/glyphs/A_sterisk.glif b/tests/reference/ufo/psfsetglyphorder.ufo/glyphs/A_sterisk.glif
new file mode 100644
index 0000000..3027a5d
--- /dev/null
+++ b/tests/reference/ufo/psfsetglyphorder.ufo/glyphs/A_sterisk.glif
@@ -0,0 +1,51 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="Asterisk" format="2">
+ <advance width="1008"/>
+ <unicode hex="002A"/>
+ <outline>
+ <contour>
+ <point x="745" y="1568" type="line"/>
+ <point x="733" y="1438"/>
+ <point x="725" y="1359"/>
+ <point x="707" y="1274" type="curve"/>
+ <point x="644" y="1317"/>
+ <point x="587" y="1359"/>
+ <point x="498" y="1436" type="curve"/>
+ <point x="392" y="1313" type="line"/>
+ <point x="505" y="1264"/>
+ <point x="575" y="1236"/>
+ <point x="643" y="1196" type="curve"/>
+ <point x="556" y="1153"/>
+ <point x="474" y="1117"/>
+ <point x="340" y="1063" type="curve"/>
+ <point x="379" y="941" type="line"/>
+ <point x="504" y="1021"/>
+ <point x="584" y="1072"/>
+ <point x="668" y="1117" type="curve"/>
+ <point x="645" y="1034"/>
+ <point x="619" y="954"/>
+ <point x="575" y="823" type="curve"/>
+ <point x="715" y="823" type="line"/>
+ <point x="727" y="954"/>
+ <point x="741" y="1031"/>
+ <point x="758" y="1117" type="curve"/>
+ <point x="821" y="1073"/>
+ <point x="878" y="1032"/>
+ <point x="968" y="956" type="curve"/>
+ <point x="1073" y="1078" type="line"/>
+ <point x="959" y="1126"/>
+ <point x="890" y="1155"/>
+ <point x="823" y="1196" type="curve"/>
+ <point x="909" y="1236"/>
+ <point x="990" y="1273"/>
+ <point x="1126" y="1328" type="curve"/>
+ <point x="1086" y="1450" type="line"/>
+ <point x="961" y="1368"/>
+ <point x="883" y="1321"/>
+ <point x="797" y="1274" type="curve"/>
+ <point x="819" y="1359"/>
+ <point x="845" y="1438"/>
+ <point x="890" y="1568" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetglyphorder.ufo/glyphs/A_tS_gn.glif b/tests/reference/ufo/psfsetglyphorder.ufo/glyphs/A_tS_gn.glif
new file mode 100644
index 0000000..2cd2542
--- /dev/null
+++ b/tests/reference/ufo/psfsetglyphorder.ufo/glyphs/A_tS_gn.glif
@@ -0,0 +1,104 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="AtSgn" format="2">
+ <advance width="1682"/>
+ <unicode hex="0040"/>
+ <outline>
+ <contour>
+ <point x="1082" y="-10" type="line"/>
+ <point x="980" y="-69"/>
+ <point x="889" y="-93"/>
+ <point x="796" y="-93" type="curve" smooth="yes"/>
+ <point x="507" y="-93"/>
+ <point x="301" y="104"/>
+ <point x="301" y="414" type="curve" smooth="yes"/>
+ <point x="301" y="476"/>
+ <point x="309" y="543"/>
+ <point x="327" y="613" type="curve" smooth="yes"/>
+ <point x="425" y="1003"/>
+ <point x="782" y="1245"/>
+ <point x="1110" y="1245" type="curve" smooth="yes"/>
+ <point x="1433" y="1245"/>
+ <point x="1590" y="1060"/>
+ <point x="1590" y="813" type="curve" smooth="yes"/>
+ <point x="1590" y="760"/>
+ <point x="1582" y="705"/>
+ <point x="1568" y="647" type="curve" smooth="yes"/>
+ <point x="1510" y="413"/>
+ <point x="1365" y="309"/>
+ <point x="1297" y="309" type="curve" smooth="yes"/>
+ <point x="1261" y="309"/>
+ <point x="1238" y="344"/>
+ <point x="1238" y="420" type="curve" smooth="yes"/>
+ <point x="1238" y="468"/>
+ <point x="1247" y="533"/>
+ <point x="1268" y="617" type="curve" smooth="yes"/>
+ <point x="1354" y="960" type="line"/>
+ <point x="1276" y="995"/>
+ <point x="1155" y="1019"/>
+ <point x="1074" y="1019" type="curve" smooth="yes"/>
+ <point x="910" y="1019"/>
+ <point x="790" y="962"/>
+ <point x="673" y="828" type="curve" smooth="yes"/>
+ <point x="607" y="751"/>
+ <point x="554" y="650"/>
+ <point x="524" y="529" type="curve" smooth="yes"/>
+ <point x="514" y="488"/>
+ <point x="509" y="450"/>
+ <point x="509" y="416" type="curve" smooth="yes"/>
+ <point x="509" y="259"/>
+ <point x="609" y="179"/>
+ <point x="719" y="179" type="curve" smooth="yes"/>
+ <point x="836" y="179"/>
+ <point x="1017" y="359"/>
+ <point x="1099" y="480" type="curve"/>
+ <point x="1093" y="446"/>
+ <point x="1089" y="413"/>
+ <point x="1089" y="382" type="curve" smooth="yes"/>
+ <point x="1089" y="264"/>
+ <point x="1136" y="176"/>
+ <point x="1233" y="176" type="curve" smooth="yes"/>
+ <point x="1408" y="176"/>
+ <point x="1635" y="331"/>
+ <point x="1716" y="656" type="curve" smooth="yes"/>
+ <point x="1732" y="722"/>
+ <point x="1740" y="784"/>
+ <point x="1740" y="843" type="curve" smooth="yes"/>
+ <point x="1740" y="1161"/>
+ <point x="1513" y="1377"/>
+ <point x="1153" y="1377" type="curve" smooth="yes"/>
+ <point x="738" y="1377"/>
+ <point x="310" y="1143"/>
+ <point x="175" y="603" type="curve" smooth="yes"/>
+ <point x="155" y="522"/>
+ <point x="145" y="446"/>
+ <point x="145" y="375" type="curve" smooth="yes"/>
+ <point x="145" y="-5"/>
+ <point x="417" y="-230"/>
+ <point x="747" y="-230" type="curve" smooth="yes"/>
+ <point x="882" y="-230"/>
+ <point x="1044" y="-184"/>
+ <point x="1161" y="-116" type="curve"/>
+ </contour>
+ <contour>
+ <point x="1141" y="706" type="line"/>
+ <point x="1075" y="570"/>
+ <point x="856" y="314"/>
+ <point x="766" y="314" type="curve" smooth="yes"/>
+ <point x="712" y="314"/>
+ <point x="669" y="362"/>
+ <point x="669" y="459" type="curve" smooth="yes"/>
+ <point x="669" y="491"/>
+ <point x="674" y="530"/>
+ <point x="685" y="573" type="curve" smooth="yes"/>
+ <point x="704" y="649"/>
+ <point x="739" y="726"/>
+ <point x="780" y="774" type="curve" smooth="yes"/>
+ <point x="859" y="868"/>
+ <point x="943" y="887"/>
+ <point x="1011" y="887" type="curve" smooth="yes"/>
+ <point x="1085" y="887"/>
+ <point x="1148" y="868"/>
+ <point x="1177" y="853" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetglyphorder.ufo/glyphs/C_ircumA_ccent.glif b/tests/reference/ufo/psfsetglyphorder.ufo/glyphs/C_ircumA_ccent.glif
new file mode 100644
index 0000000..91ab811
--- /dev/null
+++ b/tests/reference/ufo/psfsetglyphorder.ufo/glyphs/C_ircumA_ccent.glif
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="CircumAccent" format="2">
+ <advance width="830"/>
+ <unicode hex="005E"/>
+ <anchor x="705" y="1635" name="U"/>
+ <outline>
+ <contour>
+ <point x="316" y="1147" type="line"/>
+ <point x="660" y="1421" type="line"/>
+ <point x="866" y="1147" type="line"/>
+ <point x="1015" y="1147" type="line"/>
+ <point x="761" y="1568" type="line"/>
+ <point x="591" y="1568" type="line"/>
+ <point x="166" y="1147" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetglyphorder.ufo/glyphs/C_olon.glif b/tests/reference/ufo/psfsetglyphorder.ufo/glyphs/C_olon.glif
new file mode 100644
index 0000000..bcccfc2
--- /dev/null
+++ b/tests/reference/ufo/psfsetglyphorder.ufo/glyphs/C_olon.glif
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="Colon" format="2">
+ <advance width="620"/>
+ <unicode hex="003A"/>
+ <outline>
+ <contour>
+ <point x="314" y="758" type="curve" smooth="yes"/>
+ <point x="314" y="696"/>
+ <point x="365" y="642"/>
+ <point x="430" y="642" type="curve" smooth="yes"/>
+ <point x="514" y="642"/>
+ <point x="590" y="712"/>
+ <point x="590" y="792" type="curve" smooth="yes"/>
+ <point x="590" y="854"/>
+ <point x="540" y="907"/>
+ <point x="476" y="907" type="curve" smooth="yes"/>
+ <point x="393" y="907"/>
+ <point x="314" y="837"/>
+ </contour>
+ <contour>
+ <point x="148" y="90" type="curve" smooth="yes"/>
+ <point x="148" y="28"/>
+ <point x="198" y="-25"/>
+ <point x="263" y="-25" type="curve" smooth="yes"/>
+ <point x="347" y="-25"/>
+ <point x="424" y="45"/>
+ <point x="424" y="125" type="curve" smooth="yes"/>
+ <point x="424" y="186"/>
+ <point x="374" y="240"/>
+ <point x="309" y="240" type="curve" smooth="yes"/>
+ <point x="225" y="240"/>
+ <point x="148" y="170"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetglyphorder.ufo/glyphs/C_ombA_cute.glif b/tests/reference/ufo/psfsetglyphorder.ufo/glyphs/C_ombA_cute.glif
new file mode 100644
index 0000000..a7607fe
--- /dev/null
+++ b/tests/reference/ufo/psfsetglyphorder.ufo/glyphs/C_ombA_cute.glif
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="CombAcute" format="2">
+ <unicode hex="0301"/>
+ <anchor x="-221" y="1635" name="U"/>
+ <anchor x="-355" y="1100" name="_U"/>
+ <outline>
+ <contour>
+ <point x="-99" y="1568" type="line"/>
+ <point x="-524" y="1147" type="line"/>
+ <point x="-354" y="1147" type="line"/>
+ <point x="150" y="1568" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetglyphorder.ufo/glyphs/C_ombC_ircum.glif b/tests/reference/ufo/psfsetglyphorder.ufo/glyphs/C_ombC_ircum.glif
new file mode 100644
index 0000000..6614f85
--- /dev/null
+++ b/tests/reference/ufo/psfsetglyphorder.ufo/glyphs/C_ombC_ircum.glif
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="CombCircum" format="2">
+ <unicode hex="0302"/>
+ <anchor x="-221" y="1635" name="U"/>
+ <anchor x="-320" y="1100" name="_U"/>
+ <outline>
+ <contour>
+ <point x="-619" y="1147" type="line"/>
+ <point x="-275" y="1421" type="line"/>
+ <point x="-69" y="1147" type="line"/>
+ <point x="80" y="1147" type="line"/>
+ <point x="-174" y="1568" type="line"/>
+ <point x="-344" y="1568" type="line"/>
+ <point x="-769" y="1147" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetglyphorder.ufo/glyphs/C_ombD_iaer.glif b/tests/reference/ufo/psfsetglyphorder.ufo/glyphs/C_ombD_iaer.glif
new file mode 100644
index 0000000..d6b35b7
--- /dev/null
+++ b/tests/reference/ufo/psfsetglyphorder.ufo/glyphs/C_ombD_iaer.glif
@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="CombDiaer" format="2">
+ <unicode hex="0308"/>
+ <anchor x="-253" y="1505" name="U"/>
+ <anchor x="-350" y="1100" name="_U"/>
+ <outline>
+ <contour>
+ <point x="39" y="1338" type="curve" smooth="yes"/>
+ <point x="39" y="1399"/>
+ <point x="-7" y="1450"/>
+ <point x="-72" y="1450" type="curve" smooth="yes"/>
+ <point x="-167" y="1450"/>
+ <point x="-229" y="1372"/>
+ <point x="-229" y="1299" type="curve" smooth="yes"/>
+ <point x="-229" y="1238"/>
+ <point x="-182" y="1186"/>
+ <point x="-118" y="1186" type="curve" smooth="yes"/>
+ <point x="-33" y="1186"/>
+ <point x="39" y="1259"/>
+ </contour>
+ <contour>
+ <point x="-381" y="1338" type="curve" smooth="yes"/>
+ <point x="-381" y="1399"/>
+ <point x="-427" y="1450"/>
+ <point x="-492" y="1450" type="curve" smooth="yes"/>
+ <point x="-587" y="1450"/>
+ <point x="-649" y="1372"/>
+ <point x="-649" y="1299" type="curve" smooth="yes"/>
+ <point x="-649" y="1238"/>
+ <point x="-602" y="1186"/>
+ <point x="-538" y="1186" type="curve" smooth="yes"/>
+ <point x="-453" y="1186"/>
+ <point x="-381" y="1259"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetglyphorder.ufo/glyphs/C_ombG_rave.glif b/tests/reference/ufo/psfsetglyphorder.ufo/glyphs/C_ombG_rave.glif
new file mode 100644
index 0000000..8869bb9
--- /dev/null
+++ b/tests/reference/ufo/psfsetglyphorder.ufo/glyphs/C_ombG_rave.glif
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="CombGrave" format="2">
+ <unicode hex="0300"/>
+ <anchor x="-201" y="1635" name="U"/>
+ <anchor x="-335" y="1100" name="_U"/>
+ <outline>
+ <contour>
+ <point x="-619" y="1568" type="line"/>
+ <point x="-284" y="1147" type="line"/>
+ <point x="-134" y="1147" type="line"/>
+ <point x="-409" y="1568" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetglyphorder.ufo/glyphs/C_ombR_ingA_bv.glif b/tests/reference/ufo/psfsetglyphorder.ufo/glyphs/C_ombR_ingA_bv.glif
new file mode 100644
index 0000000..38232a0
--- /dev/null
+++ b/tests/reference/ufo/psfsetglyphorder.ufo/glyphs/C_ombR_ingA_bv.glif
@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="CombRingAbv" format="2">
+ <unicode hex="030A"/>
+ <anchor x="-221" y="1635" name="U"/>
+ <anchor x="-385" y="1100" name="_U"/>
+ <outline>
+ <contour>
+ <point x="-377" y="1259" type="curve" smooth="yes"/>
+ <point x="-427" y="1259"/>
+ <point x="-456" y="1287"/>
+ <point x="-456" y="1329" type="curve" smooth="yes"/>
+ <point x="-456" y="1400"/>
+ <point x="-393" y="1455"/>
+ <point x="-328" y="1455" type="curve" smooth="yes"/>
+ <point x="-278" y="1455"/>
+ <point x="-248" y="1428"/>
+ <point x="-248" y="1385" type="curve" smooth="yes"/>
+ <point x="-248" y="1314"/>
+ <point x="-312" y="1259"/>
+ </contour>
+ <contour>
+ <point x="-573" y="1320" type="curve" smooth="yes"/>
+ <point x="-573" y="1224"/>
+ <point x="-498" y="1147"/>
+ <point x="-395" y="1147" type="curve" smooth="yes"/>
+ <point x="-257" y="1147"/>
+ <point x="-131" y="1263"/>
+ <point x="-131" y="1394" type="curve" smooth="yes"/>
+ <point x="-131" y="1491"/>
+ <point x="-206" y="1568"/>
+ <point x="-310" y="1568" type="curve" smooth="yes"/>
+ <point x="-448" y="1568"/>
+ <point x="-573" y="1451"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetglyphorder.ufo/glyphs/C_ombT_ilde.glif b/tests/reference/ufo/psfsetglyphorder.ufo/glyphs/C_ombT_ilde.glif
new file mode 100644
index 0000000..f79322e
--- /dev/null
+++ b/tests/reference/ufo/psfsetglyphorder.ufo/glyphs/C_ombT_ilde.glif
@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="CombTilde" format="2">
+ <unicode hex="0303"/>
+ <anchor x="-290" y="1475" name="U"/>
+ <anchor x="-385" y="1100" name="_U"/>
+ <outline>
+ <contour>
+ <point x="-646" y="1181" type="line"/>
+ <point x="-629" y="1229"/>
+ <point x="-589" y="1269"/>
+ <point x="-540" y="1269" type="curve" smooth="yes"/>
+ <point x="-503" y="1269"/>
+ <point x="-466" y="1253"/>
+ <point x="-398" y="1218" type="curve" smooth="yes"/>
+ <point x="-344" y="1190"/>
+ <point x="-296" y="1171"/>
+ <point x="-243" y="1171" type="curve" smooth="yes"/>
+ <point x="-120" y="1171"/>
+ <point x="-15" y="1286"/>
+ <point x="16" y="1411" type="curve"/>
+ <point x="-89" y="1411" type="line"/>
+ <point x="-107" y="1366"/>
+ <point x="-147" y="1323"/>
+ <point x="-194" y="1323" type="curve" smooth="yes"/>
+ <point x="-236" y="1323"/>
+ <point x="-273" y="1342"/>
+ <point x="-338" y="1370" type="curve" smooth="yes"/>
+ <point x="-401" y="1397"/>
+ <point x="-442" y="1421"/>
+ <point x="-498" y="1421" type="curve" smooth="yes"/>
+ <point x="-617" y="1421"/>
+ <point x="-721" y="1300"/>
+ <point x="-751" y="1181" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetglyphorder.ufo/glyphs/C_omma.glif b/tests/reference/ufo/psfsetglyphorder.ufo/glyphs/C_omma.glif
new file mode 100644
index 0000000..eaff517
--- /dev/null
+++ b/tests/reference/ufo/psfsetglyphorder.ufo/glyphs/C_omma.glif
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="Comma" format="2">
+ <advance width="630"/>
+ <unicode hex="002C"/>
+ <outline>
+ <contour>
+ <point x="137" y="49" type="line"/>
+ <point x="277" y="49" type="line"/>
+ <point x="252" y="-50"/>
+ <point x="145" y="-169"/>
+ <point x="73" y="-225" type="curve"/>
+ <point x="163" y="-265" type="line"/>
+ <point x="280" y="-175"/>
+ <point x="431" y="-28"/>
+ <point x="431" y="118" type="curve" smooth="yes"/>
+ <point x="431" y="193"/>
+ <point x="378" y="245"/>
+ <point x="311" y="245" type="curve" smooth="yes"/>
+ <point x="254" y="245"/>
+ <point x="190" y="209"/>
+ <point x="161" y="147" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetglyphorder.ufo/glyphs/D_igitE_ight.glif b/tests/reference/ufo/psfsetglyphorder.ufo/glyphs/D_igitE_ight.glif
new file mode 100644
index 0000000..262f860
--- /dev/null
+++ b/tests/reference/ufo/psfsetglyphorder.ufo/glyphs/D_igitE_ight.glif
@@ -0,0 +1,63 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="DigitEight" format="2">
+ <advance width="1180"/>
+ <unicode hex="0038"/>
+ <anchor x="515" y="-100" name="L"/>
+ <anchor x="922" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="542" y="-25" type="curve" smooth="yes"/>
+ <point x="839" y="-25"/>
+ <point x="1160" y="170"/>
+ <point x="1160" y="475" type="curve" smooth="yes"/>
+ <point x="1160" y="626"/>
+ <point x="1068" y="733"/>
+ <point x="988" y="779" type="curve"/>
+ <point x="1155" y="860"/>
+ <point x="1270" y="970"/>
+ <point x="1270" y="1151" type="curve" smooth="yes"/>
+ <point x="1270" y="1340"/>
+ <point x="1102" y="1455"/>
+ <point x="901" y="1455" type="curve" smooth="yes"/>
+ <point x="620" y="1455"/>
+ <point x="348" y="1292"/>
+ <point x="348" y="1018" type="curve" smooth="yes"/>
+ <point x="348" y="891"/>
+ <point x="427" y="814"/>
+ <point x="483" y="779" type="curve"/>
+ <point x="297" y="706"/>
+ <point x="115" y="549"/>
+ <point x="115" y="325" type="curve" smooth="yes"/>
+ <point x="115" y="111"/>
+ <point x="317" y="-25"/>
+ </contour>
+ <contour>
+ <point x="750" y="848" type="curve" smooth="yes"/>
+ <point x="628" y="848"/>
+ <point x="541" y="917"/>
+ <point x="541" y="1029" type="curve" smooth="yes"/>
+ <point x="541" y="1205"/>
+ <point x="704" y="1299"/>
+ <point x="862" y="1299" type="curve" smooth="yes"/>
+ <point x="985" y="1299"/>
+ <point x="1076" y="1235"/>
+ <point x="1076" y="1128" type="curve" smooth="yes"/>
+ <point x="1076" y="955"/>
+ <point x="907" y="848"/>
+ </contour>
+ <contour>
+ <point x="564" y="142" type="curve" smooth="yes"/>
+ <point x="413" y="142"/>
+ <point x="322" y="225"/>
+ <point x="322" y="350" type="curve" smooth="yes"/>
+ <point x="322" y="557"/>
+ <point x="520" y="696"/>
+ <point x="712" y="696" type="curve" smooth="yes"/>
+ <point x="864" y="696"/>
+ <point x="961" y="602"/>
+ <point x="961" y="476" type="curve" smooth="yes"/>
+ <point x="961" y="266"/>
+ <point x="753" y="142"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetglyphorder.ufo/glyphs/D_igitF_ive.glif b/tests/reference/ufo/psfsetglyphorder.ufo/glyphs/D_igitF_ive.glif
new file mode 100644
index 0000000..a224838
--- /dev/null
+++ b/tests/reference/ufo/psfsetglyphorder.ufo/glyphs/D_igitF_ive.glif
@@ -0,0 +1,44 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="DigitFive" format="2">
+ <advance width="1180"/>
+ <unicode hex="0035"/>
+ <anchor x="515" y="-100" name="L"/>
+ <anchor x="922" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="1296" y="1431" type="line"/>
+ <point x="491" y="1431" type="line"/>
+ <point x="302" y="671" type="line"/>
+ <point x="438" y="718"/>
+ <point x="537" y="735"/>
+ <point x="643" y="735" type="curve" smooth="yes"/>
+ <point x="784" y="735"/>
+ <point x="933" y="660"/>
+ <point x="933" y="508" type="curve" smooth="yes"/>
+ <point x="933" y="273"/>
+ <point x="710" y="152"/>
+ <point x="497" y="152" type="curve" smooth="yes"/>
+ <point x="357" y="152"/>
+ <point x="263" y="195"/>
+ <point x="170" y="284" type="curve"/>
+ <point x="89" y="78" type="line"/>
+ <point x="195" y="2"/>
+ <point x="326" y="-25"/>
+ <point x="481" y="-25" type="curve" smooth="yes"/>
+ <point x="807" y="-25"/>
+ <point x="1129" y="190"/>
+ <point x="1129" y="546" type="curve" smooth="yes"/>
+ <point x="1129" y="757"/>
+ <point x="951" y="911"/>
+ <point x="702" y="911" type="curve" smooth="yes"/>
+ <point x="629" y="911"/>
+ <point x="576" y="906"/>
+ <point x="544" y="902" type="curve"/>
+ <point x="635" y="1264" type="line"/>
+ <point x="1020" y="1264" type="line" smooth="yes"/>
+ <point x="1104" y="1264"/>
+ <point x="1179" y="1260"/>
+ <point x="1250" y="1245" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetglyphorder.ufo/glyphs/D_igitF_our.glif b/tests/reference/ufo/psfsetglyphorder.ufo/glyphs/D_igitF_our.glif
new file mode 100644
index 0000000..eeccb48
--- /dev/null
+++ b/tests/reference/ufo/psfsetglyphorder.ufo/glyphs/D_igitF_our.glif
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="DigitFour" format="2">
+ <advance width="1180"/>
+ <unicode hex="0034"/>
+ <anchor x="522" y="-100" name="L"/>
+ <anchor x="929" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="1161" y="387" type="line"/>
+ <point x="1199" y="539" type="line"/>
+ <point x="1009" y="539" type="line"/>
+ <point x="1236" y="1450" type="line"/>
+ <point x="1026" y="1450" type="line"/>
+ <point x="144" y="539" type="line"/>
+ <point x="106" y="387" type="line"/>
+ <point x="781" y="387" type="line"/>
+ <point x="685" y="0" type="line"/>
+ <point x="875" y="0" type="line"/>
+ <point x="971" y="387" type="line"/>
+ </contour>
+ <contour>
+ <point x="985" y="1205" type="line"/>
+ <point x="819" y="539" type="line"/>
+ <point x="337" y="539" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetglyphorder.ufo/glyphs/D_igitN_ine.glif b/tests/reference/ufo/psfsetglyphorder.ufo/glyphs/D_igitN_ine.glif
new file mode 100644
index 0000000..191cd79
--- /dev/null
+++ b/tests/reference/ufo/psfsetglyphorder.ufo/glyphs/D_igitN_ine.glif
@@ -0,0 +1,49 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="DigitNine" format="2">
+ <advance width="1180"/>
+ <unicode hex="0039"/>
+ <anchor x="515" y="-100" name="L"/>
+ <anchor x="922" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="157" y="94" type="line"/>
+ <point x="208" y="29"/>
+ <point x="355" y="-25"/>
+ <point x="473" y="-25" type="curve" smooth="yes"/>
+ <point x="999" y="-25"/>
+ <point x="1267" y="520"/>
+ <point x="1267" y="982" type="curve" smooth="yes"/>
+ <point x="1267" y="1248"/>
+ <point x="1127" y="1455"/>
+ <point x="866" y="1455" type="curve" smooth="yes"/>
+ <point x="596" y="1455"/>
+ <point x="303" y="1269"/>
+ <point x="303" y="932" type="curve" smooth="yes"/>
+ <point x="303" y="761"/>
+ <point x="425" y="574"/>
+ <point x="661" y="574" type="curve" smooth="yes"/>
+ <point x="852" y="574"/>
+ <point x="1036" y="683"/>
+ <point x="1172" y="840" type="curve"/>
+ <point x="1121" y="922" type="line"/>
+ <point x="1019" y="810"/>
+ <point x="872" y="745"/>
+ <point x="717" y="745" type="curve" smooth="yes"/>
+ <point x="584" y="745"/>
+ <point x="498" y="833"/>
+ <point x="498" y="956" type="curve" smooth="yes"/>
+ <point x="498" y="1146"/>
+ <point x="638" y="1284"/>
+ <point x="821" y="1284" type="curve" smooth="yes"/>
+ <point x="998" y="1284"/>
+ <point x="1073" y="1119"/>
+ <point x="1073" y="956" type="curve" smooth="yes"/>
+ <point x="1073" y="455"/>
+ <point x="760" y="147"/>
+ <point x="496" y="147" type="curve" smooth="yes"/>
+ <point x="410" y="147"/>
+ <point x="298" y="209"/>
+ <point x="249" y="285" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetglyphorder.ufo/glyphs/D_igitO_ne.glif b/tests/reference/ufo/psfsetglyphorder.ufo/glyphs/D_igitO_ne.glif
new file mode 100644
index 0000000..a639774
--- /dev/null
+++ b/tests/reference/ufo/psfsetglyphorder.ufo/glyphs/D_igitO_ne.glif
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="DigitOne" format="2">
+ <advance width="1180"/>
+ <unicode hex="0031"/>
+ <anchor x="515" y="-100" name="L"/>
+ <anchor x="922" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="1021" y="167" type="line"/>
+ <point x="706" y="167" type="line"/>
+ <point x="1026" y="1450" type="line"/>
+ <point x="856" y="1450" type="line"/>
+ <point x="459" y="1243" type="line"/>
+ <point x="440" y="1066" type="line"/>
+ <point x="782" y="1235" type="line"/>
+ <point x="516" y="167" type="line"/>
+ <point x="201" y="167" type="line"/>
+ <point x="160" y="0" type="line"/>
+ <point x="980" y="0" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetglyphorder.ufo/glyphs/D_igitS_even.glif b/tests/reference/ufo/psfsetglyphorder.ufo/glyphs/D_igitS_even.glif
new file mode 100644
index 0000000..68c6ef6
--- /dev/null
+++ b/tests/reference/ufo/psfsetglyphorder.ufo/glyphs/D_igitS_even.glif
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="DigitSeven" format="2">
+ <advance width="1180"/>
+ <unicode hex="0037"/>
+ <anchor x="515" y="-100" name="L"/>
+ <anchor x="922" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="420" y="0" type="line"/>
+ <point x="661" y="450"/>
+ <point x="972" y="877"/>
+ <point x="1367" y="1274" type="curve"/>
+ <point x="1406" y="1431" type="line"/>
+ <point x="386" y="1431" type="line"/>
+ <point x="341" y="1245" type="line"/>
+ <point x="421" y="1260"/>
+ <point x="538" y="1264"/>
+ <point x="726" y="1264" type="curve" smooth="yes"/>
+ <point x="1126" y="1264" type="line"/>
+ <point x="774" y="889"/>
+ <point x="517" y="555"/>
+ <point x="215" y="0" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetglyphorder.ufo/glyphs/D_igitS_ix.glif b/tests/reference/ufo/psfsetglyphorder.ufo/glyphs/D_igitS_ix.glif
new file mode 100644
index 0000000..b6be793
--- /dev/null
+++ b/tests/reference/ufo/psfsetglyphorder.ufo/glyphs/D_igitS_ix.glif
@@ -0,0 +1,49 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="DigitSix" format="2">
+ <advance width="1180"/>
+ <unicode hex="0036"/>
+ <anchor x="515" y="-100" name="L"/>
+ <anchor x="922" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="1313" y="1347" type="line"/>
+ <point x="1248" y="1418"/>
+ <point x="1135" y="1455"/>
+ <point x="1017" y="1455" type="curve" smooth="yes"/>
+ <point x="481" y="1454"/>
+ <point x="208" y="915"/>
+ <point x="208" y="475" type="curve" smooth="yes"/>
+ <point x="208" y="167"/>
+ <point x="392" y="-25"/>
+ <point x="623" y="-25" type="curve" smooth="yes"/>
+ <point x="947" y="-25"/>
+ <point x="1183" y="169"/>
+ <point x="1183" y="517" type="curve" smooth="yes"/>
+ <point x="1183" y="709"/>
+ <point x="1029" y="887"/>
+ <point x="793" y="887" type="curve" smooth="yes"/>
+ <point x="636" y="887"/>
+ <point x="432" y="784"/>
+ <point x="317" y="633" type="curve"/>
+ <point x="364" y="559" type="line"/>
+ <point x="471" y="660"/>
+ <point x="596" y="716"/>
+ <point x="751" y="716" type="curve" smooth="yes"/>
+ <point x="898" y="716"/>
+ <point x="987" y="614"/>
+ <point x="987" y="454" type="curve" smooth="yes"/>
+ <point x="987" y="263"/>
+ <point x="816" y="147"/>
+ <point x="656" y="147" type="curve" smooth="yes"/>
+ <point x="491" y="147"/>
+ <point x="403" y="284"/>
+ <point x="403" y="472" type="curve" smooth="yes"/>
+ <point x="403" y="962"/>
+ <point x="664" y="1284"/>
+ <point x="985" y="1284" type="curve" smooth="yes"/>
+ <point x="1081" y="1284"/>
+ <point x="1174" y="1235"/>
+ <point x="1222" y="1156" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetglyphorder.ufo/glyphs/D_igitT_hree.glif b/tests/reference/ufo/psfsetglyphorder.ufo/glyphs/D_igitT_hree.glif
new file mode 100644
index 0000000..e01df2c
--- /dev/null
+++ b/tests/reference/ufo/psfsetglyphorder.ufo/glyphs/D_igitT_hree.glif
@@ -0,0 +1,52 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="DigitThree" format="2">
+ <advance width="1180"/>
+ <unicode hex="0033"/>
+ <anchor x="515" y="-100" name="L"/>
+ <anchor x="922" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="562" y="853" type="line"/>
+ <point x="521" y="686" type="line"/>
+ <point x="591" y="686" type="line" smooth="yes"/>
+ <point x="802" y="686"/>
+ <point x="944" y="606"/>
+ <point x="944" y="476" type="curve" smooth="yes"/>
+ <point x="944" y="268"/>
+ <point x="738" y="147"/>
+ <point x="551" y="147" type="curve" smooth="yes"/>
+ <point x="371" y="147"/>
+ <point x="260" y="227"/>
+ <point x="181" y="348" type="curve"/>
+ <point x="104" y="137" type="line"/>
+ <point x="185" y="41"/>
+ <point x="341" y="-25"/>
+ <point x="518" y="-25" type="curve" smooth="yes"/>
+ <point x="815" y="-25"/>
+ <point x="1141" y="168"/>
+ <point x="1141" y="475" type="curve" smooth="yes"/>
+ <point x="1141" y="670"/>
+ <point x="973" y="763"/>
+ <point x="855" y="784" type="curve"/>
+ <point x="1046" y="827"/>
+ <point x="1266" y="955"/>
+ <point x="1266" y="1163" type="curve" smooth="yes"/>
+ <point x="1266" y="1338"/>
+ <point x="1073" y="1455"/>
+ <point x="852" y="1455" type="curve" smooth="yes"/>
+ <point x="685" y="1455"/>
+ <point x="536" y="1388"/>
+ <point x="433" y="1299" type="curve"/>
+ <point x="427" y="1132" type="line"/>
+ <point x="568" y="1246"/>
+ <point x="696" y="1284"/>
+ <point x="850" y="1284" type="curve" smooth="yes"/>
+ <point x="957" y="1284"/>
+ <point x="1068" y="1236"/>
+ <point x="1068" y="1137" type="curve" smooth="yes"/>
+ <point x="1068" y="949"/>
+ <point x="781" y="853"/>
+ <point x="632" y="853" type="curve" smooth="yes"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetglyphorder.ufo/glyphs/D_igitT_wo.glif b/tests/reference/ufo/psfsetglyphorder.ufo/glyphs/D_igitT_wo.glif
new file mode 100644
index 0000000..d1bbb54
--- /dev/null
+++ b/tests/reference/ufo/psfsetglyphorder.ufo/glyphs/D_igitT_wo.glif
@@ -0,0 +1,37 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="DigitTwo" format="2">
+ <advance width="1180"/>
+ <unicode hex="0032"/>
+ <anchor x="515" y="-100" name="L"/>
+ <anchor x="882" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="1063" y="176" type="line"/>
+ <point x="980" y="163"/>
+ <point x="822" y="162"/>
+ <point x="625" y="162" type="curve" smooth="yes"/>
+ <point x="370" y="162" type="line"/>
+ <point x="783" y="393"/>
+ <point x="1210" y="830"/>
+ <point x="1210" y="1098" type="curve" smooth="yes"/>
+ <point x="1210" y="1296"/>
+ <point x="1075" y="1455"/>
+ <point x="842" y="1455" type="curve" smooth="yes"/>
+ <point x="673" y="1455"/>
+ <point x="488" y="1374"/>
+ <point x="380" y="1264" type="curve"/>
+ <point x="388" y="1098" type="line"/>
+ <point x="503" y="1203"/>
+ <point x="660" y="1279"/>
+ <point x="783" y="1279" type="curve" smooth="yes"/>
+ <point x="915" y="1279"/>
+ <point x="1003" y="1199"/>
+ <point x="1003" y="1063" type="curve" smooth="yes"/>
+ <point x="1003" y="848"/>
+ <point x="506" y="386"/>
+ <point x="101" y="167" type="curve"/>
+ <point x="60" y="0" type="line"/>
+ <point x="1020" y="0" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetglyphorder.ufo/glyphs/D_igitZ_ero.glif b/tests/reference/ufo/psfsetglyphorder.ufo/glyphs/D_igitZ_ero.glif
new file mode 100644
index 0000000..5d1bf0e
--- /dev/null
+++ b/tests/reference/ufo/psfsetglyphorder.ufo/glyphs/D_igitZ_ero.glif
@@ -0,0 +1,49 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="DigitZero" format="2">
+ <advance width="1180"/>
+ <unicode hex="0030"/>
+ <anchor x="520" y="-100" name="L"/>
+ <anchor x="927" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="1024" y="711" type="curve" smooth="yes"/>
+ <point x="925" y="312"/>
+ <point x="747" y="142"/>
+ <point x="565" y="142" type="curve" smooth="yes"/>
+ <point x="432" y="142"/>
+ <point x="360" y="218"/>
+ <point x="360" y="383" type="curve" smooth="yes"/>
+ <point x="360" y="468"/>
+ <point x="377" y="579"/>
+ <point x="412" y="720" type="curve" smooth="yes"/>
+ <point x="512" y="1120"/>
+ <point x="678" y="1289"/>
+ <point x="871" y="1289" type="curve" smooth="yes"/>
+ <point x="1006" y="1289"/>
+ <point x="1077" y="1223"/>
+ <point x="1077" y="1051" type="curve" smooth="yes"/>
+ <point x="1077" y="966"/>
+ <point x="1060" y="854"/>
+ </contour>
+ <contour>
+ <point x="1230" y="715" type="curve" smooth="yes"/>
+ <point x="1262" y="841"/>
+ <point x="1276" y="949"/>
+ <point x="1276" y="1040" type="curve" smooth="yes"/>
+ <point x="1276" y="1335"/>
+ <point x="1124" y="1455"/>
+ <point x="902" y="1455" type="curve" smooth="yes"/>
+ <point x="613" y="1455"/>
+ <point x="344" y="1267"/>
+ <point x="206" y="716" type="curve" smooth="yes"/>
+ <point x="173" y="584"/>
+ <point x="158" y="474"/>
+ <point x="158" y="381" type="curve" smooth="yes"/>
+ <point x="158" y="104"/>
+ <point x="313" y="-25"/>
+ <point x="533" y="-25" type="curve" smooth="yes"/>
+ <point x="804" y="-25"/>
+ <point x="1086" y="138"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetglyphorder.ufo/glyphs/D_ollarS_gn.glif b/tests/reference/ufo/psfsetglyphorder.ufo/glyphs/D_ollarS_gn.glif
new file mode 100644
index 0000000..5c2db20
--- /dev/null
+++ b/tests/reference/ufo/psfsetglyphorder.ufo/glyphs/D_ollarS_gn.glif
@@ -0,0 +1,53 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="DollarSgn" format="2">
+ <advance width="1180"/>
+ <unicode hex="0024"/>
+ <outline>
+ <contour>
+ <point x="1225" y="1280" type="line"/>
+ <point x="1119" y="1337"/>
+ <point x="1023" y="1361"/>
+ <point x="882" y="1361" type="curve" smooth="yes"/>
+ <point x="513" y="1361"/>
+ <point x="354" y="1182"/>
+ <point x="354" y="992" type="curve" smooth="yes"/>
+ <point x="354" y="837"/>
+ <point x="446" y="771"/>
+ <point x="639" y="650" type="curve" smooth="yes"/>
+ <point x="844" y="521"/>
+ <point x="919" y="439"/>
+ <point x="919" y="357" type="curve" smooth="yes"/>
+ <point x="919" y="244"/>
+ <point x="826" y="158"/>
+ <point x="635" y="158" type="curve" smooth="yes"/>
+ <point x="469" y="158"/>
+ <point x="314" y="266"/>
+ <point x="251" y="347" type="curve"/>
+ <point x="163" y="162" type="line"/>
+ <point x="304" y="58"/>
+ <point x="453" y="0"/>
+ <point x="606" y="0" type="curve" smooth="yes"/>
+ <point x="872" y="0"/>
+ <point x="1102" y="119"/>
+ <point x="1102" y="381" type="curve" smooth="yes"/>
+ <point x="1102" y="528"/>
+ <point x="981" y="657"/>
+ <point x="801" y="771" type="curve" smooth="yes"/>
+ <point x="610" y="892"/>
+ <point x="535" y="943"/>
+ <point x="535" y="1024" type="curve" smooth="yes"/>
+ <point x="535" y="1116"/>
+ <point x="657" y="1203"/>
+ <point x="832" y="1203" type="curve" smooth="yes"/>
+ <point x="950" y="1203"/>
+ <point x="1031" y="1176"/>
+ <point x="1144" y="1104" type="curve"/>
+ </contour>
+ <contour>
+ <point x="878" y="1568" type="line"/>
+ <point x="434" y="-216" type="line"/>
+ <point x="574" y="-216" type="line"/>
+ <point x="1018" y="1568" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetglyphorder.ufo/glyphs/D_ottedC_irc.glif b/tests/reference/ufo/psfsetglyphorder.ufo/glyphs/D_ottedC_irc.glif
new file mode 100644
index 0000000..2cdf8fd
--- /dev/null
+++ b/tests/reference/ufo/psfsetglyphorder.ufo/glyphs/D_ottedC_irc.glif
@@ -0,0 +1,235 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="DottedCirc" format="2">
+ <advance width="1086"/>
+ <unicode hex="25CC"/>
+ <anchor x="493" y="0" name="H"/>
+ <anchor x="468" y="-100" name="L"/>
+ <anchor x="750" y="0" name="O"/>
+ <anchor x="743" y="1000" name="U"/>
+ <outline>
+ <contour>
+ <point x="588" y="834" type="curve" smooth="yes"/>
+ <point x="588" y="858"/>
+ <point x="571" y="867"/>
+ <point x="553" y="867" type="curve" smooth="yes"/>
+ <point x="521" y="867"/>
+ <point x="491" y="837"/>
+ <point x="491" y="809" type="curve" smooth="yes"/>
+ <point x="491" y="788"/>
+ <point x="508" y="773"/>
+ <point x="530" y="773" type="curve" smooth="yes"/>
+ <point x="564" y="773"/>
+ <point x="588" y="805"/>
+ </contour>
+ <contour>
+ <point x="677" y="124" type="curve" smooth="yes"/>
+ <point x="647" y="124"/>
+ <point x="620" y="93"/>
+ <point x="620" y="67" type="curve" smooth="yes"/>
+ <point x="620" y="46"/>
+ <point x="636" y="30"/>
+ <point x="657" y="30" type="curve" smooth="yes"/>
+ <point x="687" y="30"/>
+ <point x="718" y="60"/>
+ <point x="718" y="86" type="curve" smooth="yes"/>
+ <point x="718" y="109"/>
+ <point x="700" y="124"/>
+ </contour>
+ <contour>
+ <point x="396" y="780" type="curve" smooth="yes"/>
+ <point x="369" y="780"/>
+ <point x="336" y="753"/>
+ <point x="336" y="722" type="curve" smooth="yes"/>
+ <point x="336" y="702"/>
+ <point x="351" y="687"/>
+ <point x="374" y="687" type="curve" smooth="yes"/>
+ <point x="403" y="687"/>
+ <point x="434" y="711"/>
+ <point x="434" y="744" type="curve" smooth="yes"/>
+ <point x="434" y="764"/>
+ <point x="414" y="780"/>
+ </contour>
+ <contour>
+ <point x="873" y="175" type="curve" smooth="yes"/>
+ <point x="872" y="199"/>
+ <point x="854" y="211"/>
+ <point x="833" y="211" type="curve" smooth="yes"/>
+ <point x="803" y="211"/>
+ <point x="774" y="183"/>
+ <point x="774" y="153" type="curve" smooth="yes"/>
+ <point x="774" y="133"/>
+ <point x="789" y="119"/>
+ <point x="812" y="119" type="curve" smooth="yes"/>
+ <point x="843" y="119"/>
+ <point x="873" y="146"/>
+ </contour>
+ <contour>
+ <point x="313" y="612" type="curve" smooth="yes"/>
+ <point x="312" y="633"/>
+ <point x="296" y="650"/>
+ <point x="275" y="650" type="curve" smooth="yes"/>
+ <point x="247" y="650"/>
+ <point x="215" y="623"/>
+ <point x="215" y="592" type="curve" smooth="yes"/>
+ <point x="215" y="573"/>
+ <point x="227" y="556"/>
+ <point x="251" y="556" type="curve" smooth="yes"/>
+ <point x="278" y="556"/>
+ <point x="313" y="581"/>
+ </contour>
+ <contour>
+ <point x="994" y="306" type="curve" smooth="yes"/>
+ <point x="993" y="327"/>
+ <point x="978" y="341"/>
+ <point x="958" y="341" type="curve" smooth="yes"/>
+ <point x="933" y="341"/>
+ <point x="896" y="321"/>
+ <point x="896" y="284" type="curve" smooth="yes"/>
+ <point x="896" y="265"/>
+ <point x="909" y="249"/>
+ <point x="934" y="249" type="curve" smooth="yes"/>
+ <point x="963" y="249"/>
+ <point x="994" y="275"/>
+ </contour>
+ <contour>
+ <point x="205" y="495" type="curve" smooth="yes"/>
+ <point x="175" y="495"/>
+ <point x="145" y="468"/>
+ <point x="145" y="438" type="curve" smooth="yes"/>
+ <point x="145" y="418"/>
+ <point x="159" y="402"/>
+ <point x="183" y="402" type="curve" smooth="yes"/>
+ <point x="208" y="402"/>
+ <point x="244" y="428"/>
+ <point x="244" y="459" type="curve" smooth="yes"/>
+ <point x="244" y="479"/>
+ <point x="227" y="495"/>
+ </contour>
+ <contour>
+ <point x="1026" y="496" type="curve" smooth="yes"/>
+ <point x="999" y="496"/>
+ <point x="965" y="469"/>
+ <point x="965" y="438" type="curve" smooth="yes"/>
+ <point x="965" y="418"/>
+ <point x="979" y="403"/>
+ <point x="1004" y="403" type="curve" smooth="yes"/>
+ <point x="1033" y="403"/>
+ <point x="1064" y="431"/>
+ <point x="1064" y="460" type="curve" smooth="yes"/>
+ <point x="1064" y="480"/>
+ <point x="1048" y="496"/>
+ </contour>
+ <contour>
+ <point x="237" y="307" type="curve" smooth="yes"/>
+ <point x="237" y="327"/>
+ <point x="221" y="341"/>
+ <point x="199" y="341" type="curve" smooth="yes"/>
+ <point x="169" y="341"/>
+ <point x="138" y="314"/>
+ <point x="138" y="285" type="curve" smooth="yes"/>
+ <point x="138" y="263"/>
+ <point x="153" y="248"/>
+ <point x="175" y="248" type="curve" smooth="yes"/>
+ <point x="206" y="248"/>
+ <point x="237" y="278"/>
+ </contour>
+ <contour>
+ <point x="1071" y="613" type="curve" smooth="yes"/>
+ <point x="1071" y="634"/>
+ <point x="1055" y="650"/>
+ <point x="1034" y="650" type="curve" smooth="yes"/>
+ <point x="1003" y="650"/>
+ <point x="973" y="619"/>
+ <point x="973" y="590" type="curve" smooth="yes"/>
+ <point x="973" y="570"/>
+ <point x="989" y="556"/>
+ <point x="1009" y="556" type="curve" smooth="yes"/>
+ <point x="1041" y="556"/>
+ <point x="1071" y="585"/>
+ </contour>
+ <contour>
+ <point x="292" y="177" type="curve" smooth="yes"/>
+ <point x="292" y="197"/>
+ <point x="277" y="211"/>
+ <point x="253" y="211" type="curve" smooth="yes"/>
+ <point x="224" y="211"/>
+ <point x="194" y="181"/>
+ <point x="194" y="154" type="curve" smooth="yes"/>
+ <point x="194" y="134"/>
+ <point x="211" y="118"/>
+ <point x="232" y="118" type="curve" smooth="yes"/>
+ <point x="262" y="118"/>
+ <point x="292" y="148"/>
+ </contour>
+ <contour>
+ <point x="917" y="724" type="curve" smooth="yes"/>
+ <point x="917" y="704"/>
+ <point x="931" y="686"/>
+ <point x="954" y="686" type="curve" smooth="yes"/>
+ <point x="984" y="686"/>
+ <point x="1014" y="716"/>
+ <point x="1014" y="745" type="curve" smooth="yes"/>
+ <point x="1014" y="765"/>
+ <point x="1000" y="780"/>
+ <point x="977" y="780" type="curve" smooth="yes"/>
+ <point x="947" y="780"/>
+ <point x="917" y="753"/>
+ </contour>
+ <contour>
+ <point x="403" y="87" type="curve" smooth="yes"/>
+ <point x="403" y="107"/>
+ <point x="390" y="123"/>
+ <point x="367" y="123" type="curve" smooth="yes"/>
+ <point x="339" y="123"/>
+ <point x="305" y="96"/>
+ <point x="305" y="68" type="curve" smooth="yes"/>
+ <point x="305" y="49"/>
+ <point x="320" y="30"/>
+ <point x="343" y="30" type="curve" smooth="yes"/>
+ <point x="371" y="30"/>
+ <point x="403" y="56"/>
+ </contour>
+ <contour>
+ <point x="806" y="810" type="curve" smooth="yes"/>
+ <point x="806" y="791"/>
+ <point x="819" y="773"/>
+ <point x="842" y="773" type="curve" smooth="yes"/>
+ <point x="869" y="773"/>
+ <point x="903" y="799"/>
+ <point x="903" y="830" type="curve" smooth="yes"/>
+ <point x="903" y="850"/>
+ <point x="889" y="867"/>
+ <point x="866" y="867" type="curve" smooth="yes"/>
+ <point x="836" y="867"/>
+ <point x="806" y="839"/>
+ </contour>
+ <contour>
+ <point x="553" y="57" type="curve" smooth="yes"/>
+ <point x="553" y="78"/>
+ <point x="538" y="93"/>
+ <point x="516" y="93" type="curve" smooth="yes"/>
+ <point x="485" y="93"/>
+ <point x="456" y="65"/>
+ <point x="456" y="36" type="curve" smooth="yes"/>
+ <point x="456" y="16"/>
+ <point x="471" y="0"/>
+ <point x="493" y="0" type="curve" smooth="yes"/>
+ <point x="523" y="0"/>
+ <point x="553" y="27"/>
+ </contour>
+ <contour>
+ <point x="656" y="839" type="curve" smooth="yes"/>
+ <point x="656" y="819"/>
+ <point x="671" y="805"/>
+ <point x="693" y="805" type="curve" smooth="yes"/>
+ <point x="721" y="805"/>
+ <point x="754" y="830"/>
+ <point x="754" y="861" type="curve" smooth="yes"/>
+ <point x="754" y="882"/>
+ <point x="738" y="898"/>
+ <point x="716" y="898" type="curve" smooth="yes"/>
+ <point x="685" y="898"/>
+ <point x="656" y="868"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetglyphorder.ufo/glyphs/E_qS_gn.glif b/tests/reference/ufo/psfsetglyphorder.ufo/glyphs/E_qS_gn.glif
new file mode 100644
index 0000000..3d756e8
--- /dev/null
+++ b/tests/reference/ufo/psfsetglyphorder.ufo/glyphs/E_qS_gn.glif
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="EqSgn" format="2">
+ <advance width="1180"/>
+ <unicode hex="003D"/>
+ <outline>
+ <contour>
+ <point x="177" y="470" type="line"/>
+ <point x="1137" y="470" type="line"/>
+ <point x="1173" y="617" type="line"/>
+ <point x="213" y="617" type="line"/>
+ </contour>
+ <contour>
+ <point x="262" y="813" type="line"/>
+ <point x="1222" y="813" type="line"/>
+ <point x="1259" y="960" type="line"/>
+ <point x="299" y="960" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetglyphorder.ufo/glyphs/E_xclamationM_rk.glif b/tests/reference/ufo/psfsetglyphorder.ufo/glyphs/E_xclamationM_rk.glif
new file mode 100644
index 0000000..a1c14d9
--- /dev/null
+++ b/tests/reference/ufo/psfsetglyphorder.ufo/glyphs/E_xclamationM_rk.glif
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="ExclamationMrk" format="2">
+ <advance width="744"/>
+ <unicode hex="0021"/>
+ <outline>
+ <contour>
+ <point x="497" y="431" type="line"/>
+ <point x="574" y="715"/>
+ <point x="653" y="1054"/>
+ <point x="799" y="1480" type="curve"/>
+ <point x="544" y="1480" type="line"/>
+ <point x="475" y="1054"/>
+ <point x="386" y="715"/>
+ <point x="322" y="431" type="curve"/>
+ </contour>
+ <contour>
+ <point x="188" y="90" type="curve" smooth="yes"/>
+ <point x="188" y="28"/>
+ <point x="238" y="-25"/>
+ <point x="303" y="-25" type="curve" smooth="yes"/>
+ <point x="387" y="-25"/>
+ <point x="464" y="45"/>
+ <point x="464" y="125" type="curve" smooth="yes"/>
+ <point x="464" y="186"/>
+ <point x="414" y="240"/>
+ <point x="349" y="240" type="curve" smooth="yes"/>
+ <point x="265" y="240"/>
+ <point x="188" y="170"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetglyphorder.ufo/glyphs/F_ullS_top.glif b/tests/reference/ufo/psfsetglyphorder.ufo/glyphs/F_ullS_top.glif
new file mode 100644
index 0000000..a6c4d08
--- /dev/null
+++ b/tests/reference/ufo/psfsetglyphorder.ufo/glyphs/F_ullS_top.glif
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="FullStop" format="2">
+ <advance width="620"/>
+ <unicode hex="002E"/>
+ <outline>
+ <contour>
+ <point x="148" y="90" type="curve" smooth="yes"/>
+ <point x="148" y="28"/>
+ <point x="198" y="-25"/>
+ <point x="263" y="-25" type="curve" smooth="yes"/>
+ <point x="347" y="-25"/>
+ <point x="424" y="45"/>
+ <point x="424" y="125" type="curve" smooth="yes"/>
+ <point x="424" y="186"/>
+ <point x="374" y="240"/>
+ <point x="309" y="240" type="curve" smooth="yes"/>
+ <point x="225" y="240"/>
+ <point x="148" y="170"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetglyphorder.ufo/glyphs/G_T_S_gn.glif b/tests/reference/ufo/psfsetglyphorder.ufo/glyphs/G_T_S_gn.glif
new file mode 100644
index 0000000..12da8b3
--- /dev/null
+++ b/tests/reference/ufo/psfsetglyphorder.ufo/glyphs/G_T_S_gn.glif
@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="GTSgn" format="2">
+ <advance width="1180"/>
+ <unicode hex="003E"/>
+ <outline>
+ <contour>
+ <point x="312" y="1014" type="line"/>
+ <point x="1028" y="725" type="line"/>
+ <point x="163" y="417" type="line"/>
+ <point x="119" y="240" type="line"/>
+ <point x="1197" y="632" type="line"/>
+ <point x="1239" y="799" type="line"/>
+ <point x="356" y="1191" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetglyphorder.ufo/glyphs/G_raveA_ccent.glif b/tests/reference/ufo/psfsetglyphorder.ufo/glyphs/G_raveA_ccent.glif
new file mode 100644
index 0000000..48adfc4
--- /dev/null
+++ b/tests/reference/ufo/psfsetglyphorder.ufo/glyphs/G_raveA_ccent.glif
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="GraveAccent" format="2">
+ <advance width="560"/>
+ <unicode hex="0060"/>
+ <anchor x="738" y="1635" name="U"/>
+ <outline>
+ <contour>
+ <point x="261" y="1568" type="line"/>
+ <point x="596" y="1147" type="line"/>
+ <point x="746" y="1147" type="line"/>
+ <point x="471" y="1568" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetglyphorder.ufo/glyphs/H_yphen.glif b/tests/reference/ufo/psfsetglyphorder.ufo/glyphs/H_yphen.glif
new file mode 100644
index 0000000..ae8cad5
--- /dev/null
+++ b/tests/reference/ufo/psfsetglyphorder.ufo/glyphs/H_yphen.glif
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="Hyphen" format="2">
+ <advance width="840"/>
+ <unicode hex="2010"/>
+ <anchor x="645" y="1100" name="U"/>
+ <outline>
+ <contour>
+ <point x="155" y="544" type="line"/>
+ <point x="855" y="544" type="line"/>
+ <point x="892" y="691" type="line"/>
+ <point x="192" y="691" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetglyphorder.ufo/glyphs/H_yphenM_inus.glif b/tests/reference/ufo/psfsetglyphorder.ufo/glyphs/H_yphenM_inus.glif
new file mode 100644
index 0000000..155b460
--- /dev/null
+++ b/tests/reference/ufo/psfsetglyphorder.ufo/glyphs/H_yphenM_inus.glif
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="HyphenMinus" format="2">
+ <advance width="840"/>
+ <unicode hex="002D"/>
+ <anchor x="645" y="1100" name="U"/>
+ <outline>
+ <contour>
+ <point x="155" y="544" type="line"/>
+ <point x="855" y="544" type="line"/>
+ <point x="892" y="691" type="line"/>
+ <point x="192" y="691" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetglyphorder.ufo/glyphs/H_yphen_S_oft.glif b/tests/reference/ufo/psfsetglyphorder.ufo/glyphs/H_yphen_S_oft.glif
new file mode 100644
index 0000000..0c7b834
--- /dev/null
+++ b/tests/reference/ufo/psfsetglyphorder.ufo/glyphs/H_yphen_S_oft.glif
@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="Hyphen_Soft" format="2">
+ <advance width="840"/>
+ <unicode hex="00AD"/>
+ <anchor x="645" y="1100" name="U"/>
+ <outline>
+ <component base="HyphenMinus"/>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetglyphorder.ufo/glyphs/L_T_S_gn.glif b/tests/reference/ufo/psfsetglyphorder.ufo/glyphs/L_T_S_gn.glif
new file mode 100644
index 0000000..3c857a5
--- /dev/null
+++ b/tests/reference/ufo/psfsetglyphorder.ufo/glyphs/L_T_S_gn.glif
@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LTSgn" format="2">
+ <advance width="1180"/>
+ <unicode hex="003C"/>
+ <outline>
+ <contour>
+ <point x="1123" y="417" type="line"/>
+ <point x="408" y="705" type="line"/>
+ <point x="1272" y="1014" type="line"/>
+ <point x="1316" y="1191" type="line"/>
+ <point x="239" y="799" type="line"/>
+ <point x="197" y="632" type="line"/>
+ <point x="1079" y="240" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetglyphorder.ufo/glyphs/L_ftC_urlyB_rac.glif b/tests/reference/ufo/psfsetglyphorder.ufo/glyphs/L_ftC_urlyB_rac.glif
new file mode 100644
index 0000000..4f8c90c
--- /dev/null
+++ b/tests/reference/ufo/psfsetglyphorder.ufo/glyphs/L_ftC_urlyB_rac.glif
@@ -0,0 +1,50 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LftCurlyBrac" format="2">
+ <advance width="980"/>
+ <unicode hex="007B"/>
+ <outline>
+ <contour>
+ <point x="713" y="-265" type="line"/>
+ <point x="660" y="-250"/>
+ <point x="526" y="-188"/>
+ <point x="526" y="-158" type="curve" smooth="yes"/>
+ <point x="526" y="-59"/>
+ <point x="649" y="404"/>
+ <point x="649" y="469" type="curve" smooth="yes"/>
+ <point x="649" y="509"/>
+ <point x="520" y="577"/>
+ <point x="520" y="602" type="curve" smooth="yes"/>
+ <point x="520" y="620"/>
+ <point x="688" y="700"/>
+ <point x="712" y="730" type="curve" smooth="yes"/>
+ <point x="741" y="767"/>
+ <point x="867" y="1326"/>
+ <point x="912" y="1372" type="curve" smooth="yes"/>
+ <point x="938" y="1399"/>
+ <point x="1073" y="1447"/>
+ <point x="1146" y="1470" type="curve"/>
+ <point x="1140" y="1607" type="line"/>
+ <point x="1030" y="1581"/>
+ <point x="856" y="1529"/>
+ <point x="805" y="1485" type="curve" smooth="yes"/>
+ <point x="714" y="1406"/>
+ <point x="572" y="796"/>
+ <point x="540" y="764" type="curve" smooth="yes"/>
+ <point x="504" y="729"/>
+ <point x="300" y="633"/>
+ <point x="300" y="601" type="curve" smooth="yes"/>
+ <point x="300" y="560"/>
+ <point x="460" y="468"/>
+ <point x="460" y="432" type="curve" smooth="yes"/>
+ <point x="460" y="362"/>
+ <point x="355" y="-53"/>
+ <point x="355" y="-219" type="curve" smooth="yes"/>
+ <point x="355" y="-247"/>
+ <point x="358" y="-268"/>
+ <point x="365" y="-279" type="curve" smooth="yes"/>
+ <point x="394" y="-323"/>
+ <point x="542" y="-375"/>
+ <point x="639" y="-402" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetglyphorder.ufo/glyphs/L_ftP_aren.glif b/tests/reference/ufo/psfsetglyphorder.ufo/glyphs/L_ftP_aren.glif
new file mode 100644
index 0000000..bc65fc1
--- /dev/null
+++ b/tests/reference/ufo/psfsetglyphorder.ufo/glyphs/L_ftP_aren.glif
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LftParen" format="2">
+ <advance width="775"/>
+ <unicode hex="0028"/>
+ <outline>
+ <contour>
+ <point x="895" y="1607" type="line"/>
+ <point x="582" y="1415"/>
+ <point x="314" y="1061"/>
+ <point x="207" y="633" type="curve" smooth="yes"/>
+ <point x="176" y="508"/>
+ <point x="161" y="386"/>
+ <point x="161" y="270" type="curve" smooth="yes"/>
+ <point x="161" y="17"/>
+ <point x="233" y="-211"/>
+ <point x="374" y="-402" type="curve"/>
+ <point x="505" y="-260" type="line"/>
+ <point x="397" y="-102"/>
+ <point x="348" y="75"/>
+ <point x="348" y="270" type="curve" smooth="yes"/>
+ <point x="348" y="385"/>
+ <point x="365" y="506"/>
+ <point x="397" y="633" type="curve" smooth="yes"/>
+ <point x="484" y="982"/>
+ <point x="647" y="1254"/>
+ <point x="932" y="1455" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetglyphorder.ufo/glyphs/L_ftS_qrB_rac.glif b/tests/reference/ufo/psfsetglyphorder.ufo/glyphs/L_ftS_qrB_rac.glif
new file mode 100644
index 0000000..6d064d1
--- /dev/null
+++ b/tests/reference/ufo/psfsetglyphorder.ufo/glyphs/L_ftS_qrB_rac.glif
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LftSqrBrac" format="2">
+ <advance width="770"/>
+ <unicode hex="005B"/>
+ <outline>
+ <contour>
+ <point x="484" y="-402" type="line"/>
+ <point x="521" y="-255" type="line"/>
+ <point x="266" y="-255" type="line"/>
+ <point x="679" y="1421" type="line"/>
+ <point x="934" y="1421" type="line"/>
+ <point x="970" y="1568" type="line"/>
+ <point x="530" y="1568" type="line"/>
+ <point x="44" y="-402" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetglyphorder.ufo/glyphs/L_owL_ine.glif b/tests/reference/ufo/psfsetglyphorder.ufo/glyphs/L_owL_ine.glif
new file mode 100644
index 0000000..879d36b
--- /dev/null
+++ b/tests/reference/ufo/psfsetglyphorder.ufo/glyphs/L_owL_ine.glif
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LowLine" format="2">
+ <advance width="1254"/>
+ <unicode hex="005F"/>
+ <outline>
+ <contour>
+ <point x="-138" y="-314" type="line"/>
+ <point x="1135" y="-314" type="line"/>
+ <point x="1172" y="-167" type="line"/>
+ <point x="-101" y="-167" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetglyphorder.ufo/glyphs/L_tnC_apA_.glif b/tests/reference/ufo/psfsetglyphorder.ufo/glyphs/L_tnC_apA_.glif
new file mode 100644
index 0000000..3a14b0e
--- /dev/null
+++ b/tests/reference/ufo/psfsetglyphorder.ufo/glyphs/L_tnC_apA_.glif
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnCapA" format="2">
+ <advance width="1395"/>
+ <unicode hex="0041"/>
+ <anchor x="1170" y="0" name="H"/>
+ <anchor x="602" y="-100" name="L"/>
+ <anchor x="1390" y="0" name="O"/>
+ <anchor x="1009" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="1080" y="0" type="line"/>
+ <point x="1275" y="0" type="line"/>
+ <point x="1259" y="78"/>
+ <point x="1243" y="166"/>
+ <point x="1221" y="348" type="curve" smooth="yes"/>
+ <point x="1091" y="1431" type="line"/>
+ <point x="876" y="1431" type="line"/>
+ <point x="206" y="348" type="line" smooth="yes"/>
+ <point x="93" y="165"/>
+ <point x="35" y="79"/>
+ <point x="-20" y="0" type="curve"/>
+ <point x="195" y="0" type="line"/>
+ <point x="422" y="377" type="line"/>
+ <point x="1038" y="377" type="line"/>
+ </contour>
+ <contour>
+ <point x="944" y="1240" type="line"/>
+ <point x="1022" y="529" type="line"/>
+ <point x="514" y="529" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetglyphorder.ufo/glyphs/L_tnC_apA_D_iaer.glif b/tests/reference/ufo/psfsetglyphorder.ufo/glyphs/L_tnC_apA_D_iaer.glif
new file mode 100644
index 0000000..6c3502c
--- /dev/null
+++ b/tests/reference/ufo/psfsetglyphorder.ufo/glyphs/L_tnC_apA_D_iaer.glif
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnCapADiaer" format="2">
+ <advance width="1395"/>
+ <unicode hex="00C4"/>
+ <anchor x="1170" y="0" name="H"/>
+ <anchor x="602" y="-100" name="L"/>
+ <anchor x="1390" y="0" name="O"/>
+ <anchor x="1106" y="1935" name="U"/>
+ <outline>
+ <component base="LtnCapA"/>
+ <component base="CombDiaer" xOffset="1359" yOffset="430"/>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetglyphorder.ufo/glyphs/L_tnC_apB_.glif b/tests/reference/ufo/psfsetglyphorder.ufo/glyphs/L_tnC_apB_.glif
new file mode 100644
index 0000000..5445f93
--- /dev/null
+++ b/tests/reference/ufo/psfsetglyphorder.ufo/glyphs/L_tnC_apB_.glif
@@ -0,0 +1,62 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnCapB" format="2">
+ <advance width="1271"/>
+ <unicode hex="0042"/>
+ <anchor x="530" y="-100" name="L"/>
+ <anchor x="937" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="625" y="1284" type="line"/>
+ <point x="667" y="1286"/>
+ <point x="733" y="1289"/>
+ <point x="811" y="1289" type="curve" smooth="yes"/>
+ <point x="993" y="1289"/>
+ <point x="1080" y="1230"/>
+ <point x="1080" y="1105" type="curve" smooth="yes"/>
+ <point x="1080" y="932"/>
+ <point x="931" y="838"/>
+ <point x="698" y="838" type="curve" smooth="yes"/>
+ <point x="513" y="838" type="line"/>
+ </contour>
+ <contour>
+ <point x="226" y="446" type="line"/>
+ <point x="178" y="252"/>
+ <point x="134" y="78"/>
+ <point x="100" y="0" type="curve"/>
+ <point x="151" y="-5"/>
+ <point x="359" y="-10"/>
+ <point x="562" y="-10" type="curve" smooth="yes"/>
+ <point x="960" y="-10"/>
+ <point x="1201" y="149"/>
+ <point x="1201" y="453" type="curve" smooth="yes"/>
+ <point x="1201" y="644"/>
+ <point x="1067" y="736"/>
+ <point x="955" y="764" type="curve"/>
+ <point x="1155" y="819"/>
+ <point x="1283" y="941"/>
+ <point x="1283" y="1140" type="curve" smooth="yes"/>
+ <point x="1283" y="1310"/>
+ <point x="1136" y="1441"/>
+ <point x="869" y="1441" type="curve" smooth="yes"/>
+ <point x="700" y="1441"/>
+ <point x="546" y="1437"/>
+ <point x="456" y="1431" type="curve"/>
+ <point x="452" y="1352"/>
+ <point x="407" y="1172"/>
+ <point x="359" y="980" type="curve" smooth="yes"/>
+ </contour>
+ <contour>
+ <point x="476" y="686" type="line"/>
+ <point x="721" y="686" type="line" smooth="yes"/>
+ <point x="892" y="686"/>
+ <point x="1011" y="598"/>
+ <point x="1011" y="450" type="curve" smooth="yes"/>
+ <point x="1011" y="218"/>
+ <point x="806" y="147"/>
+ <point x="586" y="147" type="curve" smooth="yes"/>
+ <point x="474" y="147"/>
+ <point x="379" y="150"/>
+ <point x="342" y="152" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetglyphorder.ufo/glyphs/L_tnC_apC_.glif b/tests/reference/ufo/psfsetglyphorder.ufo/glyphs/L_tnC_apC_.glif
new file mode 100644
index 0000000..c2e4948
--- /dev/null
+++ b/tests/reference/ufo/psfsetglyphorder.ufo/glyphs/L_tnC_apC_.glif
@@ -0,0 +1,38 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnCapC" format="2">
+ <advance width="1341"/>
+ <unicode hex="0043"/>
+ <anchor x="690" y="0" name="H"/>
+ <anchor x="665" y="-100" name="L"/>
+ <anchor x="1072" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="1237" y="318" type="line"/>
+ <point x="1115" y="222"/>
+ <point x="934" y="147"/>
+ <point x="752" y="147" type="curve" smooth="yes"/>
+ <point x="537" y="147"/>
+ <point x="385" y="304"/>
+ <point x="385" y="532" type="curve" smooth="yes"/>
+ <point x="385" y="964"/>
+ <point x="704" y="1289"/>
+ <point x="1037" y="1289" type="curve" smooth="yes"/>
+ <point x="1168" y="1289"/>
+ <point x="1310" y="1235"/>
+ <point x="1385" y="1132" type="curve"/>
+ <point x="1489" y="1308" type="line"/>
+ <point x="1388" y="1408"/>
+ <point x="1201" y="1455"/>
+ <point x="1058" y="1455" type="curve" smooth="yes"/>
+ <point x="645" y="1455"/>
+ <point x="185" y="1093"/>
+ <point x="185" y="513" type="curve" smooth="yes"/>
+ <point x="185" y="202"/>
+ <point x="381" y="-25"/>
+ <point x="709" y="-25" type="curve" smooth="yes"/>
+ <point x="896" y="-25"/>
+ <point x="1087" y="21"/>
+ <point x="1230" y="127" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetglyphorder.ufo/glyphs/L_tnC_apD_.glif b/tests/reference/ufo/psfsetglyphorder.ufo/glyphs/L_tnC_apD_.glif
new file mode 100644
index 0000000..3b93811
--- /dev/null
+++ b/tests/reference/ufo/psfsetglyphorder.ufo/glyphs/L_tnC_apD_.glif
@@ -0,0 +1,51 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnCapD" format="2">
+ <advance width="1421"/>
+ <unicode hex="0044"/>
+ <anchor x="630" y="-100" name="L"/>
+ <anchor x="1037" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="226" y="446" type="line"/>
+ <point x="176" y="252"/>
+ <point x="134" y="78"/>
+ <point x="100" y="0" type="curve"/>
+ <point x="100" y="0"/>
+ <point x="414" y="-10"/>
+ <point x="542" y="-10" type="curve" smooth="yes"/>
+ <point x="985" y="-10"/>
+ <point x="1299" y="181"/>
+ <point x="1415" y="648" type="curve" smooth="yes"/>
+ <point x="1437" y="738"/>
+ <point x="1447" y="819"/>
+ <point x="1447" y="891" type="curve" smooth="yes"/>
+ <point x="1447" y="1279"/>
+ <point x="1188" y="1441"/>
+ <point x="894" y="1441" type="curve" smooth="yes"/>
+ <point x="759" y="1441"/>
+ <point x="543" y="1437"/>
+ <point x="456" y="1431" type="curve"/>
+ <point x="452" y="1352"/>
+ <point x="407" y="1172"/>
+ <point x="359" y="980" type="curve" smooth="yes"/>
+ </contour>
+ <contour>
+ <point x="623" y="1279" type="line"/>
+ <point x="674" y="1281"/>
+ <point x="764" y="1284"/>
+ <point x="830" y="1284" type="curve" smooth="yes"/>
+ <point x="1105" y="1284"/>
+ <point x="1246" y="1140"/>
+ <point x="1246" y="850" type="curve" smooth="yes"/>
+ <point x="1246" y="784"/>
+ <point x="1236" y="710"/>
+ <point x="1216" y="629" type="curve" smooth="yes"/>
+ <point x="1134" y="300"/>
+ <point x="925" y="152"/>
+ <point x="572" y="152" type="curve" smooth="yes"/>
+ <point x="477" y="152"/>
+ <point x="391" y="158"/>
+ <point x="345" y="162" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetglyphorder.ufo/glyphs/L_tnC_apE_.glif b/tests/reference/ufo/psfsetglyphorder.ufo/glyphs/L_tnC_apE_.glif
new file mode 100644
index 0000000..8b5f8b9
--- /dev/null
+++ b/tests/reference/ufo/psfsetglyphorder.ufo/glyphs/L_tnC_apE_.glif
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnCapE" format="2">
+ <advance width="1140"/>
+ <unicode hex="0045"/>
+ <anchor x="540" y="0" name="H"/>
+ <anchor x="515" y="-100" name="L"/>
+ <anchor x="857" y="0" name="O"/>
+ <anchor x="1400" y="1200" name="R"/>
+ <anchor x="922" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="511" y="828" type="line"/>
+ <point x="621" y="1269" type="line"/>
+ <point x="1266" y="1269" type="line"/>
+ <point x="1306" y="1431" type="line"/>
+ <point x="456" y="1431" type="line"/>
+ <point x="452" y="1352"/>
+ <point x="413" y="1197"/>
+ <point x="365" y="1005" type="curve" smooth="yes"/>
+ <point x="221" y="426" type="line" smooth="yes"/>
+ <point x="173" y="233"/>
+ <point x="134" y="78"/>
+ <point x="100" y="0" type="curve"/>
+ <point x="980" y="0" type="line"/>
+ <point x="1023" y="176" type="line"/>
+ <point x="940" y="163"/>
+ <point x="806" y="162"/>
+ <point x="609" y="162" type="curve" smooth="yes"/>
+ <point x="345" y="162" type="line"/>
+ <point x="472" y="671" type="line"/>
+ <point x="1042" y="671" type="line"/>
+ <point x="1081" y="828" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetglyphorder.ufo/glyphs/L_tnC_apF_.glif b/tests/reference/ufo/psfsetglyphorder.ufo/glyphs/L_tnC_apF_.glif
new file mode 100644
index 0000000..cbc1726
--- /dev/null
+++ b/tests/reference/ufo/psfsetglyphorder.ufo/glyphs/L_tnC_apF_.glif
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnCapF" format="2">
+ <advance width="1130"/>
+ <unicode hex="0046"/>
+ <anchor x="510" y="-100" name="L"/>
+ <anchor x="917" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="508" y="818" type="line"/>
+ <point x="621" y="1269" type="line"/>
+ <point x="1286" y="1269" type="line"/>
+ <point x="1326" y="1431" type="line"/>
+ <point x="456" y="1431" type="line"/>
+ <point x="452" y="1352"/>
+ <point x="412" y="1193"/>
+ <point x="364" y="1000" type="curve" smooth="yes"/>
+ <point x="221" y="426" type="line" smooth="yes"/>
+ <point x="173" y="233"/>
+ <point x="134" y="78"/>
+ <point x="100" y="0" type="curve"/>
+ <point x="320" y="0" type="line"/>
+ <point x="323" y="76"/>
+ <point x="362" y="232"/>
+ <point x="411" y="426" type="curve" smooth="yes"/>
+ <point x="470" y="662" type="line"/>
+ <point x="1050" y="662" type="line"/>
+ <point x="1088" y="818" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetglyphorder.ufo/glyphs/L_tnC_apG_.glif b/tests/reference/ufo/psfsetglyphorder.ufo/glyphs/L_tnC_apG_.glif
new file mode 100644
index 0000000..c39b75a
--- /dev/null
+++ b/tests/reference/ufo/psfsetglyphorder.ufo/glyphs/L_tnC_apG_.glif
@@ -0,0 +1,48 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnCapG" format="2">
+ <advance width="1406"/>
+ <unicode hex="0047"/>
+ <anchor x="685" y="0" name="H"/>
+ <anchor x="660" y="-100" name="L"/>
+ <anchor x="1067" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="1403" y="710" type="line"/>
+ <point x="863" y="710" type="line"/>
+ <point x="822" y="548" type="line"/>
+ <point x="1172" y="548" type="line"/>
+ <point x="1090" y="220" type="line"/>
+ <point x="1012" y="176"/>
+ <point x="858" y="147"/>
+ <point x="739" y="147" type="curve" smooth="yes"/>
+ <point x="520" y="147"/>
+ <point x="384" y="272"/>
+ <point x="384" y="493" type="curve" smooth="yes"/>
+ <point x="384" y="560"/>
+ <point x="394" y="636"/>
+ <point x="415" y="720" type="curve" smooth="yes"/>
+ <point x="500" y="1062"/>
+ <point x="747" y="1289"/>
+ <point x="1052" y="1289" type="curve" smooth="yes"/>
+ <point x="1195" y="1289"/>
+ <point x="1335" y="1233"/>
+ <point x="1425" y="1122" type="curve"/>
+ <point x="1534" y="1298" type="line"/>
+ <point x="1409" y="1405"/>
+ <point x="1235" y="1455"/>
+ <point x="1063" y="1455" type="curve" smooth="yes"/>
+ <point x="680" y="1455"/>
+ <point x="334" y="1195"/>
+ <point x="217" y="726" type="curve" smooth="yes"/>
+ <point x="195" y="639"/>
+ <point x="185" y="559"/>
+ <point x="185" y="486" type="curve" smooth="yes"/>
+ <point x="185" y="162"/>
+ <point x="406" y="-25"/>
+ <point x="714" y="-25" type="curve" smooth="yes"/>
+ <point x="907" y="-25"/>
+ <point x="1149" y="50"/>
+ <point x="1258" y="132" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetglyphorder.ufo/glyphs/L_tnC_apH_.glif b/tests/reference/ufo/psfsetglyphorder.ufo/glyphs/L_tnC_apH_.glif
new file mode 100644
index 0000000..f454288
--- /dev/null
+++ b/tests/reference/ufo/psfsetglyphorder.ufo/glyphs/L_tnC_apH_.glif
@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnCapH" format="2">
+ <advance width="1455"/>
+ <unicode hex="0048"/>
+ <anchor x="225" y="0" name="H"/>
+ <anchor x="640" y="-100" name="L"/>
+ <anchor x="1047" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="1230" y="0" type="line"/>
+ <point x="1234" y="78"/>
+ <point x="1273" y="233"/>
+ <point x="1321" y="426" type="curve" smooth="yes"/>
+ <point x="1465" y="1005" type="line" smooth="yes"/>
+ <point x="1513" y="1198"/>
+ <point x="1552" y="1352"/>
+ <point x="1586" y="1431" type="curve"/>
+ <point x="1381" y="1431" type="line"/>
+ <point x="1228" y="818" type="line"/>
+ <point x="508" y="818" type="line"/>
+ <point x="661" y="1431" type="line"/>
+ <point x="456" y="1431" type="line"/>
+ <point x="452" y="1352"/>
+ <point x="413" y="1197"/>
+ <point x="365" y="1005" type="curve" smooth="yes"/>
+ <point x="221" y="426" type="line" smooth="yes"/>
+ <point x="173" y="233"/>
+ <point x="134" y="78"/>
+ <point x="100" y="0" type="curve"/>
+ <point x="305" y="0" type="line"/>
+ <point x="470" y="662" type="line"/>
+ <point x="1190" y="662" type="line"/>
+ <point x="1025" y="0" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetglyphorder.ufo/glyphs/L_tnC_apI_.glif b/tests/reference/ufo/psfsetglyphorder.ufo/glyphs/L_tnC_apI_.glif
new file mode 100644
index 0000000..78b151c
--- /dev/null
+++ b/tests/reference/ufo/psfsetglyphorder.ufo/glyphs/L_tnC_apI_.glif
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnCapI" format="2">
+ <advance width="955"/>
+ <unicode hex="0049"/>
+ <anchor x="417" y="0" name="H"/>
+ <anchor x="392" y="-100" name="L"/>
+ <anchor x="613" y="0" name="O"/>
+ <anchor x="1215" y="1200" name="R"/>
+ <anchor x="799" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="436" y="1431" type="line"/>
+ <point x="401" y="1289" type="line"/>
+ <point x="641" y="1289" type="line"/>
+ <point x="355" y="142" type="line"/>
+ <point x="115" y="142" type="line"/>
+ <point x="80" y="0" type="line"/>
+ <point x="755" y="0" type="line"/>
+ <point x="790" y="142" type="line"/>
+ <point x="545" y="142" type="line"/>
+ <point x="831" y="1289" type="line"/>
+ <point x="1076" y="1289" type="line"/>
+ <point x="1111" y="1431" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetglyphorder.ufo/glyphs/L_tnC_apJ_.glif b/tests/reference/ufo/psfsetglyphorder.ufo/glyphs/L_tnC_apJ_.glif
new file mode 100644
index 0000000..417d1f8
--- /dev/null
+++ b/tests/reference/ufo/psfsetglyphorder.ufo/glyphs/L_tnC_apJ_.glif
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnCapJ" format="2">
+ <advance width="996"/>
+ <unicode hex="004A"/>
+ <anchor x="325" y="-100" name="L"/>
+ <anchor x="997" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="871" y="1431" type="line"/>
+ <point x="858" y="1327"/>
+ <point x="817" y="1151"/>
+ <point x="769" y="960" type="curve" smooth="yes"/>
+ <point x="648" y="475" type="line" smooth="yes"/>
+ <point x="592" y="251"/>
+ <point x="484" y="152"/>
+ <point x="337" y="152" type="curve" smooth="yes"/>
+ <point x="245" y="152"/>
+ <point x="145" y="224"/>
+ <point x="97" y="299" type="curve"/>
+ <point x="6" y="118" type="line"/>
+ <point x="58" y="39"/>
+ <point x="193" y="-25"/>
+ <point x="298" y="-25" type="curve" smooth="yes"/>
+ <point x="555" y="-25"/>
+ <point x="749" y="117"/>
+ <point x="850" y="524" type="curve" smooth="yes"/>
+ <point x="1076" y="1431" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetglyphorder.ufo/glyphs/L_tnC_apK_.glif b/tests/reference/ufo/psfsetglyphorder.ufo/glyphs/L_tnC_apK_.glif
new file mode 100644
index 0000000..8e54a6d
--- /dev/null
+++ b/tests/reference/ufo/psfsetglyphorder.ufo/glyphs/L_tnC_apK_.glif
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnCapK" format="2">
+ <advance width="1261"/>
+ <unicode hex="004B"/>
+ <anchor x="210" y="0" name="H"/>
+ <anchor x="610" y="-100" name="L"/>
+ <anchor x="972" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="1221" y="1431" type="line"/>
+ <point x="406" y="689" type="line"/>
+ <point x="547" y="730" type="line"/>
+ <point x="660" y="725" type="line"/>
+ <point x="1461" y="1431" type="line"/>
+ </contour>
+ <contour>
+ <point x="1170" y="0" type="line"/>
+ <point x="615" y="823" type="line"/>
+ <point x="469" y="720" type="line"/>
+ <point x="925" y="0" type="line"/>
+ </contour>
+ <contour>
+ <point x="661" y="1431" type="line"/>
+ <point x="456" y="1431" type="line"/>
+ <point x="452" y="1352"/>
+ <point x="413" y="1197"/>
+ <point x="365" y="1005" type="curve" smooth="yes"/>
+ <point x="221" y="426" type="line" smooth="yes"/>
+ <point x="173" y="233"/>
+ <point x="134" y="78"/>
+ <point x="100" y="0" type="curve"/>
+ <point x="305" y="0" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetglyphorder.ufo/glyphs/L_tnC_apL_.glif b/tests/reference/ufo/psfsetglyphorder.ufo/glyphs/L_tnC_apL_.glif
new file mode 100644
index 0000000..d2eb932
--- /dev/null
+++ b/tests/reference/ufo/psfsetglyphorder.ufo/glyphs/L_tnC_apL_.glif
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnCapL" format="2">
+ <advance width="1060"/>
+ <unicode hex="004C"/>
+ <anchor x="532" y="0" name="H"/>
+ <anchor x="507" y="-100" name="L"/>
+ <anchor x="780" y="1200" name="R"/>
+ <anchor x="914" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="345" y="162" type="line"/>
+ <point x="661" y="1431" type="line"/>
+ <point x="456" y="1431" type="line"/>
+ <point x="452" y="1352"/>
+ <point x="413" y="1197"/>
+ <point x="365" y="1005" type="curve" smooth="yes"/>
+ <point x="221" y="426" type="line" smooth="yes"/>
+ <point x="173" y="233"/>
+ <point x="134" y="78"/>
+ <point x="100" y="0" type="curve"/>
+ <point x="965" y="0" type="line"/>
+ <point x="1008" y="176" type="line"/>
+ <point x="925" y="163"/>
+ <point x="766" y="162"/>
+ <point x="569" y="162" type="curve" smooth="yes"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetglyphorder.ufo/glyphs/L_tnC_apM_.glif b/tests/reference/ufo/psfsetglyphorder.ufo/glyphs/L_tnC_apM_.glif
new file mode 100644
index 0000000..7c3c824
--- /dev/null
+++ b/tests/reference/ufo/psfsetglyphorder.ufo/glyphs/L_tnC_apM_.glif
@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnCapM" format="2">
+ <advance width="1785"/>
+ <unicode hex="004D"/>
+ <anchor x="800" y="-100" name="L"/>
+ <anchor x="1207" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="880" y="201" type="line"/>
+ <point x="751" y="1431" type="line"/>
+ <point x="591" y="1431" type="line"/>
+ <point x="740" y="0" type="line"/>
+ <point x="935" y="0" type="line"/>
+ <point x="1793" y="1431" type="line"/>
+ <point x="1616" y="1431" type="line"/>
+ </contour>
+ <contour>
+ <point x="536" y="1431" type="line"/>
+ <point x="536" y="1431"/>
+ <point x="184" y="194"/>
+ <point x="110" y="0" type="curve"/>
+ <point x="295" y="0" type="line"/>
+ <point x="621" y="1181" type="line"/>
+ <point x="711" y="1431" type="line"/>
+ </contour>
+ <contour>
+ <point x="1560" y="0" type="line"/>
+ <point x="1579" y="194"/>
+ <point x="1846" y="1431"/>
+ <point x="1846" y="1431" type="curve"/>
+ <point x="1671" y="1431" type="line"/>
+ <point x="1641" y="1181" type="line"/>
+ <point x="1375" y="0" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetglyphorder.ufo/glyphs/L_tnC_apN_.glif b/tests/reference/ufo/psfsetglyphorder.ufo/glyphs/L_tnC_apN_.glif
new file mode 100644
index 0000000..7306669
--- /dev/null
+++ b/tests/reference/ufo/psfsetglyphorder.ufo/glyphs/L_tnC_apN_.glif
@@ -0,0 +1,37 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnCapN" format="2">
+ <advance width="1480"/>
+ <unicode hex="004E"/>
+ <anchor x="1170" y="0" name="H"/>
+ <anchor x="652" y="-100" name="L"/>
+ <anchor x="1059" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="491" y="1328" type="line"/>
+ <point x="1075" y="0" type="line"/>
+ <point x="1219" y="98" type="line"/>
+ <point x="636" y="1431" type="line"/>
+ </contour>
+ <contour>
+ <point x="1075" y="0" type="line"/>
+ <point x="1250" y="0" type="line"/>
+ <point x="1500" y="1005" type="line" smooth="yes"/>
+ <point x="1548" y="1198"/>
+ <point x="1588" y="1352"/>
+ <point x="1621" y="1431" type="curve"/>
+ <point x="1431" y="1431" type="line"/>
+ </contour>
+ <contour>
+ <point x="636" y="1431" type="line"/>
+ <point x="446" y="1431" type="line"/>
+ <point x="442" y="1352"/>
+ <point x="403" y="1197"/>
+ <point x="355" y="1005" type="curve" smooth="yes"/>
+ <point x="211" y="426" type="line" smooth="yes"/>
+ <point x="163" y="233"/>
+ <point x="124" y="78"/>
+ <point x="90" y="0" type="curve"/>
+ <point x="280" y="0" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetglyphorder.ufo/glyphs/L_tnC_apO_.glif b/tests/reference/ufo/psfsetglyphorder.ufo/glyphs/L_tnC_apO_.glif
new file mode 100644
index 0000000..19c4886
--- /dev/null
+++ b/tests/reference/ufo/psfsetglyphorder.ufo/glyphs/L_tnC_apO_.glif
@@ -0,0 +1,40 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnCapO" format="2">
+ <advance width="1447"/>
+ <unicode hex="004F"/>
+ <anchor x="657" y="0" name="H"/>
+ <anchor x="632" y="-100" name="L"/>
+ <anchor x="896" y="0" name="O"/>
+ <anchor x="1700" y="1200" name="R"/>
+ <anchor x="1039" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="719" y="147" type="curve" smooth="yes"/>
+ <point x="514" y="147"/>
+ <point x="386" y="300"/>
+ <point x="386" y="541" type="curve" smooth="yes"/>
+ <point x="386" y="871"/>
+ <point x="606" y="1284"/>
+ <point x="963" y="1284" type="curve" smooth="yes"/>
+ <point x="1164" y="1284"/>
+ <point x="1291" y="1133"/>
+ <point x="1291" y="892" type="curve" smooth="yes"/>
+ <point x="1291" y="563"/>
+ <point x="1077" y="147"/>
+ </contour>
+ <contour>
+ <point x="1492" y="931" type="curve" smooth="yes"/>
+ <point x="1492" y="1263"/>
+ <point x="1278" y="1455"/>
+ <point x="1015" y="1455" type="curve" smooth="yes"/>
+ <point x="599" y="1455"/>
+ <point x="185" y="1036"/>
+ <point x="185" y="500" type="curve" smooth="yes"/>
+ <point x="185" y="167"/>
+ <point x="400" y="-25"/>
+ <point x="666" y="-25" type="curve" smooth="yes"/>
+ <point x="1078" y="-25"/>
+ <point x="1492" y="395"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetglyphorder.ufo/glyphs/L_tnC_apP_.glif b/tests/reference/ufo/psfsetglyphorder.ufo/glyphs/L_tnC_apP_.glif
new file mode 100644
index 0000000..5b51a57
--- /dev/null
+++ b/tests/reference/ufo/psfsetglyphorder.ufo/glyphs/L_tnC_apP_.glif
@@ -0,0 +1,50 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnCapP" format="2">
+ <advance width="1190"/>
+ <unicode hex="0050"/>
+ <anchor x="552" y="-100" name="L"/>
+ <anchor x="959" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="443" y="554" type="line"/>
+ <point x="506" y="547"/>
+ <point x="597" y="544"/>
+ <point x="670" y="544" type="curve" smooth="yes"/>
+ <point x="1058" y="544"/>
+ <point x="1321" y="733"/>
+ <point x="1321" y="1084" type="curve" smooth="yes"/>
+ <point x="1321" y="1302"/>
+ <point x="1141" y="1441"/>
+ <point x="864" y="1441" type="curve" smooth="yes"/>
+ <point x="651" y="1441"/>
+ <point x="456" y="1431"/>
+ <point x="456" y="1431" type="curve"/>
+ <point x="452" y="1352"/>
+ <point x="407" y="1172"/>
+ <point x="359" y="980" type="curve"/>
+ <point x="221" y="426" type="line" smooth="yes"/>
+ <point x="173" y="233"/>
+ <point x="134" y="78"/>
+ <point x="100" y="0" type="curve"/>
+ <point x="320" y="0" type="line"/>
+ <point x="324" y="76"/>
+ <point x="362" y="232"/>
+ <point x="411" y="426" type="curve" smooth="yes"/>
+ </contour>
+ <contour>
+ <point x="623" y="1279" type="line"/>
+ <point x="692" y="1282"/>
+ <point x="721" y="1284"/>
+ <point x="815" y="1284" type="curve" smooth="yes"/>
+ <point x="1036" y="1284"/>
+ <point x="1121" y="1172"/>
+ <point x="1121" y="1048" type="curve" smooth="yes"/>
+ <point x="1121" y="845"/>
+ <point x="968" y="696"/>
+ <point x="693" y="696" type="curve" smooth="yes"/>
+ <point x="618" y="696"/>
+ <point x="542" y="698"/>
+ <point x="481" y="706" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetglyphorder.ufo/glyphs/L_tnC_apQ_.glif b/tests/reference/ufo/psfsetglyphorder.ufo/glyphs/L_tnC_apQ_.glif
new file mode 100644
index 0000000..3dcbc8d
--- /dev/null
+++ b/tests/reference/ufo/psfsetglyphorder.ufo/glyphs/L_tnC_apQ_.glif
@@ -0,0 +1,52 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnCapQ" format="2">
+ <advance width="1459"/>
+ <unicode hex="0051"/>
+ <anchor x="589" y="-270" name="L"/>
+ <anchor x="1039" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="1495" y="939" type="curve" smooth="yes"/>
+ <point x="1495" y="1266"/>
+ <point x="1306" y="1455"/>
+ <point x="1026" y="1455" type="curve" smooth="yes"/>
+ <point x="703" y="1455"/>
+ <point x="332" y="1195"/>
+ <point x="215" y="726" type="curve" smooth="yes"/>
+ <point x="194" y="642"/>
+ <point x="185" y="564"/>
+ <point x="185" y="492" type="curve" smooth="yes"/>
+ <point x="185" y="165"/>
+ <point x="388" y="-25"/>
+ <point x="652" y="-25" type="curve" smooth="yes"/>
+ <point x="714" y="-25"/>
+ <point x="781" y="-17"/>
+ <point x="829" y="0" type="curve"/>
+ <point x="898" y="0"/>
+ <point x="1133" y="-186"/>
+ <point x="1217" y="-186" type="curve" smooth="yes"/>
+ <point x="1271" y="-186"/>
+ <point x="1355" y="-79"/>
+ <point x="1388" y="-44" type="curve"/>
+ <point x="1258" y="-27"/>
+ <point x="1155" y="27"/>
+ <point x="1049" y="103" type="curve"/>
+ <point x="1253" y="217"/>
+ <point x="1495" y="528"/>
+ </contour>
+ <contour>
+ <point x="690" y="147" type="curve" smooth="yes"/>
+ <point x="492" y="147"/>
+ <point x="384" y="284"/>
+ <point x="384" y="508" type="curve" smooth="yes"/>
+ <point x="384" y="856"/>
+ <point x="609" y="1284"/>
+ <point x="994" y="1284" type="curve" smooth="yes"/>
+ <point x="1188" y="1284"/>
+ <point x="1295" y="1149"/>
+ <point x="1295" y="925" type="curve" smooth="yes"/>
+ <point x="1295" y="490"/>
+ <point x="985" y="147"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetglyphorder.ufo/glyphs/L_tnC_apR_.glif b/tests/reference/ufo/psfsetglyphorder.ufo/glyphs/L_tnC_apR_.glif
new file mode 100644
index 0000000..c8f8186
--- /dev/null
+++ b/tests/reference/ufo/psfsetglyphorder.ufo/glyphs/L_tnC_apR_.glif
@@ -0,0 +1,55 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnCapR" format="2">
+ <advance width="1295"/>
+ <unicode hex="0052"/>
+ <anchor x="590" y="0" name="H"/>
+ <anchor x="525" y="-100" name="L"/>
+ <anchor x="932" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="457" y="613" type="line"/>
+ <point x="712" y="613" type="line" smooth="yes"/>
+ <point x="1010" y="613"/>
+ <point x="1303" y="784"/>
+ <point x="1303" y="1114" type="curve" smooth="yes"/>
+ <point x="1303" y="1326"/>
+ <point x="1114" y="1441"/>
+ <point x="844" y="1441" type="curve" smooth="yes"/>
+ <point x="610" y="1441"/>
+ <point x="456" y="1431"/>
+ <point x="456" y="1431" type="curve"/>
+ <point x="452" y="1352"/>
+ <point x="407" y="1172"/>
+ <point x="359" y="980" type="curve" smooth="yes"/>
+ <point x="221" y="426" type="line"/>
+ <point x="173" y="233"/>
+ <point x="134" y="78"/>
+ <point x="100" y="0" type="curve"/>
+ <point x="320" y="0" type="line"/>
+ <point x="324" y="76"/>
+ <point x="363" y="233"/>
+ <point x="411" y="426" type="curve"/>
+ </contour>
+ <contour>
+ <point x="623" y="1279" type="line"/>
+ <point x="677" y="1281"/>
+ <point x="725" y="1284"/>
+ <point x="795" y="1284" type="curve" smooth="yes"/>
+ <point x="1003" y="1284"/>
+ <point x="1104" y="1203"/>
+ <point x="1104" y="1076" type="curve" smooth="yes"/>
+ <point x="1104" y="856"/>
+ <point x="921" y="764"/>
+ <point x="685" y="764" type="curve" smooth="yes"/>
+ <point x="495" y="764" type="line"/>
+ </contour>
+ <contour>
+ <point x="656" y="622" type="line"/>
+ <point x="930" y="0" type="line"/>
+ <point x="1185" y="0" type="line"/>
+ <point x="1122" y="89"/>
+ <point x="864" y="602"/>
+ <point x="828" y="676" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetglyphorder.ufo/glyphs/L_tnC_apS_.glif b/tests/reference/ufo/psfsetglyphorder.ufo/glyphs/L_tnC_apS_.glif
new file mode 100644
index 0000000..01e9f47
--- /dev/null
+++ b/tests/reference/ufo/psfsetglyphorder.ufo/glyphs/L_tnC_apS_.glif
@@ -0,0 +1,50 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnCapS" format="2">
+ <advance width="1155"/>
+ <unicode hex="0053"/>
+ <anchor x="520" y="0" name="H"/>
+ <anchor x="495" y="-100" name="L"/>
+ <anchor x="902" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="1260" y="1347" type="line"/>
+ <point x="1146" y="1419"/>
+ <point x="1021" y="1455"/>
+ <point x="867" y="1455" type="curve" smooth="yes"/>
+ <point x="549" y="1455"/>
+ <point x="320" y="1303"/>
+ <point x="320" y="1040" type="curve" smooth="yes"/>
+ <point x="320" y="901"/>
+ <point x="438" y="794"/>
+ <point x="622" y="691" type="curve" smooth="yes"/>
+ <point x="877" y="549"/>
+ <point x="914" y="461"/>
+ <point x="914" y="378" type="curve" smooth="yes"/>
+ <point x="914" y="256"/>
+ <point x="792" y="147"/>
+ <point x="621" y="147" type="curve" smooth="yes"/>
+ <point x="473" y="147"/>
+ <point x="278" y="235"/>
+ <point x="161" y="378" type="curve"/>
+ <point x="65" y="187" type="line"/>
+ <point x="178" y="73"/>
+ <point x="365" y="-25"/>
+ <point x="558" y="-25" type="curve" smooth="yes"/>
+ <point x="852" y="-25"/>
+ <point x="1114" y="115"/>
+ <point x="1114" y="414" type="curve" smooth="yes"/>
+ <point x="1114" y="526"/>
+ <point x="1057" y="679"/>
+ <point x="800" y="828" type="curve" smooth="yes"/>
+ <point x="597" y="946"/>
+ <point x="510" y="1005"/>
+ <point x="510" y="1079" type="curve" smooth="yes"/>
+ <point x="510" y="1210"/>
+ <point x="659" y="1284"/>
+ <point x="845" y="1284" type="curve" smooth="yes"/>
+ <point x="959" y="1284"/>
+ <point x="1075" y="1240"/>
+ <point x="1173" y="1156" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetglyphorder.ufo/glyphs/L_tnC_apT_.glif b/tests/reference/ufo/psfsetglyphorder.ufo/glyphs/L_tnC_apT_.glif
new file mode 100644
index 0000000..0eeece4
--- /dev/null
+++ b/tests/reference/ufo/psfsetglyphorder.ufo/glyphs/L_tnC_apT_.glif
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnCapT" format="2">
+ <advance width="1245"/>
+ <unicode hex="0054"/>
+ <anchor x="562" y="0" name="H"/>
+ <anchor x="562" y="-100" name="L"/>
+ <anchor x="944" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="341" y="1431" type="line"/>
+ <point x="296" y="1250" type="line"/>
+ <point x="380" y="1266"/>
+ <point x="457" y="1269"/>
+ <point x="546" y="1269" type="curve" smooth="yes"/>
+ <point x="781" y="1269" type="line"/>
+ <point x="571" y="426" type="line" smooth="yes"/>
+ <point x="523" y="233"/>
+ <point x="481" y="78"/>
+ <point x="445" y="0" type="curve"/>
+ <point x="675" y="0" type="line"/>
+ <point x="677" y="78"/>
+ <point x="713" y="233"/>
+ <point x="761" y="426" type="curve" smooth="yes"/>
+ <point x="971" y="1269" type="line"/>
+ <point x="1211" y="1269" type="line" smooth="yes"/>
+ <point x="1301" y="1269"/>
+ <point x="1375" y="1266"/>
+ <point x="1451" y="1250" type="curve"/>
+ <point x="1496" y="1431" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetglyphorder.ufo/glyphs/L_tnC_apU_.glif b/tests/reference/ufo/psfsetglyphorder.ufo/glyphs/L_tnC_apU_.glif
new file mode 100644
index 0000000..9576e20
--- /dev/null
+++ b/tests/reference/ufo/psfsetglyphorder.ufo/glyphs/L_tnC_apU_.glif
@@ -0,0 +1,44 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnCapU" format="2">
+ <advance width="1420"/>
+ <unicode hex="0055"/>
+ <anchor x="647" y="0" name="H"/>
+ <anchor x="622" y="-100" name="L"/>
+ <anchor x="865" y="0" name="O"/>
+ <anchor x="1640" y="1200" name="R"/>
+ <anchor x="1029" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="1346" y="1431" type="line"/>
+ <point x="1126" y="549" type="line" smooth="yes"/>
+ <point x="1055" y="264"/>
+ <point x="916" y="132"/>
+ <point x="682" y="132" type="curve" smooth="yes"/>
+ <point x="485" y="132"/>
+ <point x="421" y="244"/>
+ <point x="421" y="391" type="curve" smooth="yes"/>
+ <point x="421" y="451"/>
+ <point x="431" y="516"/>
+ <point x="448" y="582" type="curve" smooth="yes"/>
+ <point x="661" y="1431" type="line"/>
+ <point x="456" y="1431" type="line"/>
+ <point x="451" y="1352"/>
+ <point x="414" y="1198"/>
+ <point x="365" y="1005" type="curve" smooth="yes"/>
+ <point x="251" y="552" type="line" smooth="yes"/>
+ <point x="236" y="493"/>
+ <point x="228" y="435"/>
+ <point x="228" y="379" type="curve" smooth="yes"/>
+ <point x="228" y="157"/>
+ <point x="351" y="-25"/>
+ <point x="643" y="-25" type="curve" smooth="yes"/>
+ <point x="1020" y="-25"/>
+ <point x="1223" y="177"/>
+ <point x="1299" y="480" type="curve" smooth="yes"/>
+ <point x="1430" y="1005" type="line" smooth="yes"/>
+ <point x="1480" y="1207"/>
+ <point x="1519" y="1352"/>
+ <point x="1551" y="1431" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetglyphorder.ufo/glyphs/L_tnC_apV_.glif b/tests/reference/ufo/psfsetglyphorder.ufo/glyphs/L_tnC_apV_.glif
new file mode 100644
index 0000000..2bf8b96
--- /dev/null
+++ b/tests/reference/ufo/psfsetglyphorder.ufo/glyphs/L_tnC_apV_.glif
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnCapV" format="2">
+ <advance width="1345"/>
+ <unicode hex="0056"/>
+ <anchor x="620" y="0" name="H"/>
+ <anchor x="587" y="-100" name="L"/>
+ <anchor x="820" y="0" name="O"/>
+ <anchor x="994" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="1381" y="1431" type="line"/>
+ <point x="654" y="191" type="line"/>
+ <point x="536" y="1431" type="line"/>
+ <point x="331" y="1431" type="line"/>
+ <point x="344" y="1350"/>
+ <point x="355" y="1262"/>
+ <point x="377" y="1073" type="curve" smooth="yes"/>
+ <point x="500" y="0" type="line"/>
+ <point x="725" y="0" type="line"/>
+ <point x="1377" y="1073" type="line" smooth="yes"/>
+ <point x="1492" y="1263"/>
+ <point x="1550" y="1350"/>
+ <point x="1606" y="1431" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetglyphorder.ufo/glyphs/L_tnC_apW_.glif b/tests/reference/ufo/psfsetglyphorder.ufo/glyphs/L_tnC_apW_.glif
new file mode 100644
index 0000000..553ea17
--- /dev/null
+++ b/tests/reference/ufo/psfsetglyphorder.ufo/glyphs/L_tnC_apW_.glif
@@ -0,0 +1,44 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnCapW" format="2">
+ <advance width="2060"/>
+ <unicode hex="0057"/>
+ <anchor x="942" y="-100" name="L"/>
+ <anchor x="1349" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="1535" y="0" type="line"/>
+ <point x="2107" y="1073" type="line" smooth="yes"/>
+ <point x="2208" y="1263"/>
+ <point x="2259" y="1350"/>
+ <point x="2311" y="1431" type="curve"/>
+ <point x="2081" y="1431" type="line"/>
+ <point x="1431" y="127" type="line"/>
+ <point x="1420" y="0" type="line"/>
+ </contour>
+ <contour>
+ <point x="1310" y="0" type="line"/>
+ <point x="1420" y="0" type="line"/>
+ <point x="1461" y="127" type="line"/>
+ <point x="1406" y="1431" type="line"/>
+ <point x="1231" y="1431" type="line"/>
+ <point x="1248" y="1279" type="line"/>
+ </contour>
+ <contour>
+ <point x="625" y="0" type="line"/>
+ <point x="1406" y="1431" type="line"/>
+ <point x="1221" y="1431" type="line"/>
+ <point x="521" y="127" type="line"/>
+ <point x="521" y="0" type="line"/>
+ </contour>
+ <contour>
+ <point x="546" y="1431" type="line"/>
+ <point x="336" y="1431" type="line"/>
+ <point x="348" y="1353"/>
+ <point x="355" y="1260"/>
+ <point x="362" y="1073" type="curve" smooth="yes"/>
+ <point x="400" y="0" type="line"/>
+ <point x="521" y="0" type="line"/>
+ <point x="551" y="127" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetglyphorder.ufo/glyphs/L_tnC_apX_.glif b/tests/reference/ufo/psfsetglyphorder.ufo/glyphs/L_tnC_apX_.glif
new file mode 100644
index 0000000..2da5787
--- /dev/null
+++ b/tests/reference/ufo/psfsetglyphorder.ufo/glyphs/L_tnC_apX_.glif
@@ -0,0 +1,39 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnCapX" format="2">
+ <advance width="1305"/>
+ <unicode hex="0058"/>
+ <anchor x="565" y="-100" name="L"/>
+ <anchor x="972" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="970" y="0" type="line"/>
+ <point x="1190" y="0" type="line"/>
+ <point x="1148" y="80"/>
+ <point x="1125" y="124"/>
+ <point x="1045" y="329" type="curve" smooth="yes"/>
+ <point x="611" y="1431" type="line"/>
+ <point x="386" y="1431" type="line"/>
+ <point x="430" y="1348"/>
+ <point x="462" y="1289"/>
+ <point x="541" y="1088" type="curve" smooth="yes"/>
+ </contour>
+ <contour>
+ <point x="752" y="872" type="line"/>
+ <point x="278" y="333" type="line" smooth="yes"/>
+ <point x="98" y="129"/>
+ <point x="53" y="84"/>
+ <point x="-30" y="0" type="curve"/>
+ <point x="210" y="0" type="line"/>
+ <point x="750" y="622" type="line"/>
+ </contour>
+ <contour>
+ <point x="765" y="622" type="line"/>
+ <point x="1183" y="1088" type="line" smooth="yes"/>
+ <point x="1360" y="1285"/>
+ <point x="1425" y="1355"/>
+ <point x="1506" y="1431" type="curve"/>
+ <point x="1261" y="1431" type="line"/>
+ <point x="767" y="872" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetglyphorder.ufo/glyphs/L_tnC_apY_.glif b/tests/reference/ufo/psfsetglyphorder.ufo/glyphs/L_tnC_apY_.glif
new file mode 100644
index 0000000..9ec65ef
--- /dev/null
+++ b/tests/reference/ufo/psfsetglyphorder.ufo/glyphs/L_tnC_apY_.glif
@@ -0,0 +1,39 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnCapY" format="2">
+ <advance width="1300"/>
+ <unicode hex="0059"/>
+ <anchor x="565" y="-100" name="L"/>
+ <anchor x="972" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="331" y="1431" type="line"/>
+ <point x="407" y="1285"/>
+ <point x="446" y="1173"/>
+ <point x="490" y="1044" type="curve"/>
+ <point x="661" y="549" type="line"/>
+ <point x="829" y="661" type="line"/>
+ <point x="551" y="1431" type="line"/>
+ </contour>
+ <contour>
+ <point x="1321" y="1431" type="line"/>
+ <point x="684" y="661" type="line"/>
+ <point x="796" y="549" type="line"/>
+ <point x="1215" y="1044" type="line" smooth="yes"/>
+ <point x="1322" y="1171"/>
+ <point x="1402" y="1265"/>
+ <point x="1561" y="1431" type="curve"/>
+ </contour>
+ <contour>
+ <point x="700" y="0" type="line"/>
+ <point x="704" y="78"/>
+ <point x="743" y="233"/>
+ <point x="791" y="426" type="curve" smooth="yes"/>
+ <point x="854" y="681" type="line"/>
+ <point x="664" y="681" type="line"/>
+ <point x="601" y="426" type="line" smooth="yes"/>
+ <point x="553" y="233"/>
+ <point x="514" y="78"/>
+ <point x="480" y="0" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetglyphorder.ufo/glyphs/L_tnS_mA_.glif b/tests/reference/ufo/psfsetglyphorder.ufo/glyphs/L_tnS_mA_.glif
new file mode 100644
index 0000000..586e494
--- /dev/null
+++ b/tests/reference/ufo/psfsetglyphorder.ufo/glyphs/L_tnS_mA_.glif
@@ -0,0 +1,77 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmA" format="2">
+ <advance width="1107"/>
+ <unicode hex="0061"/>
+ <anchor x="860" y="0" name="H"/>
+ <anchor x="455" y="-100" name="L"/>
+ <anchor x="1065" y="0" name="O"/>
+ <anchor x="1310" y="1000" name="R"/>
+ <anchor x="755" y="1100" name="U"/>
+ <outline>
+ <contour>
+ <point x="972" y="0" type="line"/>
+ <point x="965" y="48"/>
+ <point x="960" y="98"/>
+ <point x="960" y="149" type="curve" smooth="yes"/>
+ <point x="960" y="214"/>
+ <point x="967" y="284"/>
+ <point x="987" y="363" type="curve"/>
+ <point x="1077" y="726" type="line"/>
+ <point x="1081" y="744"/>
+ <point x="1084" y="762"/>
+ <point x="1084" y="779" type="curve" smooth="yes"/>
+ <point x="1084" y="912"/>
+ <point x="955" y="1019"/>
+ <point x="751" y="1019" type="curve" smooth="yes"/>
+ <point x="599" y="1019"/>
+ <point x="502" y="974"/>
+ <point x="389" y="931" type="curve"/>
+ <point x="373" y="889"/>
+ <point x="343" y="783"/>
+ <point x="331" y="740" type="curve"/>
+ <point x="468" y="820"/>
+ <point x="560" y="862"/>
+ <point x="666" y="862" type="curve" smooth="yes"/>
+ <point x="798" y="862"/>
+ <point x="885" y="810"/>
+ <point x="885" y="718" type="curve" smooth="yes"/>
+ <point x="885" y="705"/>
+ <point x="884" y="691"/>
+ <point x="880" y="677" type="curve" smooth="yes"/>
+ <point x="867" y="622" type="line"/>
+ <point x="825" y="619"/>
+ <point x="661" y="605"/>
+ <point x="591" y="598" type="curve" smooth="yes"/>
+ <point x="282" y="568"/>
+ <point x="102" y="415"/>
+ <point x="102" y="233" type="curve" smooth="yes"/>
+ <point x="102" y="103"/>
+ <point x="223" y="-25"/>
+ <point x="390" y="-25" type="curve" smooth="yes"/>
+ <point x="514" y="-25"/>
+ <point x="674" y="47"/>
+ <point x="779" y="152" type="curve"/>
+ <point x="779" y="89"/>
+ <point x="787" y="31"/>
+ <point x="792" y="0" type="curve"/>
+ </contour>
+ <contour>
+ <point x="791" y="319" type="line"/>
+ <point x="674" y="191"/>
+ <point x="553" y="137"/>
+ <point x="451" y="137" type="curve" smooth="yes"/>
+ <point x="355" y="137"/>
+ <point x="290" y="192"/>
+ <point x="290" y="264" type="curve" smooth="yes"/>
+ <point x="290" y="274"/>
+ <point x="291" y="285"/>
+ <point x="294" y="296" type="curve" smooth="yes"/>
+ <point x="315" y="380"/>
+ <point x="432" y="450"/>
+ <point x="566" y="461" type="curve" smooth="yes"/>
+ <point x="631" y="466"/>
+ <point x="782" y="483"/>
+ <point x="832" y="485" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetglyphorder.ufo/glyphs/L_tnS_mA_A_cute.glif b/tests/reference/ufo/psfsetglyphorder.ufo/glyphs/L_tnS_mA_A_cute.glif
new file mode 100644
index 0000000..198d6db
--- /dev/null
+++ b/tests/reference/ufo/psfsetglyphorder.ufo/glyphs/L_tnS_mA_A_cute.glif
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmAAcute" format="2">
+ <advance width="1107"/>
+ <unicode hex="00E1"/>
+ <anchor x="860" y="0" name="H"/>
+ <anchor x="455" y="-100" name="L"/>
+ <anchor x="1065" y="0" name="O"/>
+ <anchor x="1310" y="1000" name="R"/>
+ <anchor x="889" y="1635" name="U"/>
+ <outline>
+ <component base="LtnSmA"/>
+ <component base="CombAcute" xOffset="1110"/>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetglyphorder.ufo/glyphs/L_tnS_mA_C_ircum.glif b/tests/reference/ufo/psfsetglyphorder.ufo/glyphs/L_tnS_mA_C_ircum.glif
new file mode 100644
index 0000000..f5cfb16
--- /dev/null
+++ b/tests/reference/ufo/psfsetglyphorder.ufo/glyphs/L_tnS_mA_C_ircum.glif
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmACircum" format="2">
+ <advance width="1107"/>
+ <unicode hex="00E2"/>
+ <anchor x="860" y="0" name="H"/>
+ <anchor x="455" y="-100" name="L"/>
+ <anchor x="1065" y="0" name="O"/>
+ <anchor x="1310" y="1000" name="R"/>
+ <anchor x="854" y="1635" name="U"/>
+ <outline>
+ <component base="LtnSmA"/>
+ <component base="CombCircum" xOffset="1075"/>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetglyphorder.ufo/glyphs/L_tnS_mA_D_iaer.glif b/tests/reference/ufo/psfsetglyphorder.ufo/glyphs/L_tnS_mA_D_iaer.glif
new file mode 100644
index 0000000..6f05301
--- /dev/null
+++ b/tests/reference/ufo/psfsetglyphorder.ufo/glyphs/L_tnS_mA_D_iaer.glif
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmADiaer" format="2">
+ <advance width="1107"/>
+ <unicode hex="00E4"/>
+ <anchor x="860" y="0" name="H"/>
+ <anchor x="455" y="-100" name="L"/>
+ <anchor x="1065" y="0" name="O"/>
+ <anchor x="1310" y="1000" name="R"/>
+ <anchor x="852" y="1505" name="U"/>
+ <outline>
+ <component base="LtnSmA"/>
+ <component base="CombDiaer" xOffset="1105"/>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetglyphorder.ufo/glyphs/L_tnS_mA_G_rave.glif b/tests/reference/ufo/psfsetglyphorder.ufo/glyphs/L_tnS_mA_G_rave.glif
new file mode 100644
index 0000000..9048920
--- /dev/null
+++ b/tests/reference/ufo/psfsetglyphorder.ufo/glyphs/L_tnS_mA_G_rave.glif
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmAGrave" format="2">
+ <advance width="1107"/>
+ <unicode hex="00E0"/>
+ <anchor x="860" y="0" name="H"/>
+ <anchor x="455" y="-100" name="L"/>
+ <anchor x="1065" y="0" name="O"/>
+ <anchor x="1310" y="1000" name="R"/>
+ <anchor x="889" y="1635" name="U"/>
+ <outline>
+ <component base="LtnSmA"/>
+ <component base="CombGrave" xOffset="1090"/>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetglyphorder.ufo/glyphs/L_tnS_mA_R_ingA_bv.glif b/tests/reference/ufo/psfsetglyphorder.ufo/glyphs/L_tnS_mA_R_ingA_bv.glif
new file mode 100644
index 0000000..8ada58f
--- /dev/null
+++ b/tests/reference/ufo/psfsetglyphorder.ufo/glyphs/L_tnS_mA_R_ingA_bv.glif
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmARingAbv" format="2">
+ <advance width="1107"/>
+ <unicode hex="00E5"/>
+ <anchor x="860" y="0" name="H"/>
+ <anchor x="455" y="-100" name="L"/>
+ <anchor x="1065" y="0" name="O"/>
+ <anchor x="1310" y="1000" name="R"/>
+ <anchor x="919" y="1635" name="U"/>
+ <outline>
+ <component base="LtnSmA"/>
+ <component base="CombRingAbv" xOffset="1140"/>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetglyphorder.ufo/glyphs/L_tnS_mA_T_ilde.glif b/tests/reference/ufo/psfsetglyphorder.ufo/glyphs/L_tnS_mA_T_ilde.glif
new file mode 100644
index 0000000..c29348b
--- /dev/null
+++ b/tests/reference/ufo/psfsetglyphorder.ufo/glyphs/L_tnS_mA_T_ilde.glif
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmATilde" format="2">
+ <advance width="1107"/>
+ <unicode hex="00E3"/>
+ <anchor x="860" y="0" name="H"/>
+ <anchor x="455" y="-100" name="L"/>
+ <anchor x="1065" y="0" name="O"/>
+ <anchor x="1310" y="1000" name="R"/>
+ <anchor x="850" y="1475" name="U"/>
+ <outline>
+ <component base="LtnSmA"/>
+ <component base="CombTilde" xOffset="1140"/>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetglyphorder.ufo/glyphs/L_tnS_mB_.glif b/tests/reference/ufo/psfsetglyphorder.ufo/glyphs/L_tnS_mB_.glif
new file mode 100644
index 0000000..b3a3696
--- /dev/null
+++ b/tests/reference/ufo/psfsetglyphorder.ufo/glyphs/L_tnS_mB_.glif
@@ -0,0 +1,55 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmB" format="2">
+ <advance width="1144"/>
+ <unicode hex="0062"/>
+ <anchor x="530" y="0" name="H"/>
+ <anchor x="505" y="-100" name="L"/>
+ <anchor x="1345" y="1000" name="R"/>
+ <anchor x="938" y="1635" name="U"/>
+ <outline>
+ <contour>
+ <point x="437" y="1570" type="line"/>
+ <point x="437" y="1456"/>
+ <point x="402" y="1246"/>
+ <point x="367" y="1105" type="curve" smooth="yes"/>
+ <point x="110" y="85" type="line"/>
+ <point x="198" y="44"/>
+ <point x="355" y="-25"/>
+ <point x="517" y="-25" type="curve" smooth="yes"/>
+ <point x="675" y="-25"/>
+ <point x="795" y="24"/>
+ <point x="907" y="125" type="curve" smooth="yes"/>
+ <point x="1050" y="255"/>
+ <point x="1162" y="466"/>
+ <point x="1162" y="695" type="curve" smooth="yes"/>
+ <point x="1162" y="930"/>
+ <point x="1046" y="1020"/>
+ <point x="907" y="1020" type="curve" smooth="yes"/>
+ <point x="754" y="1020"/>
+ <point x="584" y="878"/>
+ <point x="456" y="719" type="curve"/>
+ <point x="552" y="1105" type="line" smooth="yes"/>
+ <point x="600" y="1296"/>
+ <point x="627" y="1508"/>
+ <point x="627" y="1570" type="curve"/>
+ </contour>
+ <contour>
+ <point x="382" y="429" type="line"/>
+ <point x="485" y="617"/>
+ <point x="708" y="850"/>
+ <point x="822" y="850" type="curve" smooth="yes"/>
+ <point x="913" y="850"/>
+ <point x="972" y="784"/>
+ <point x="972" y="635" type="curve" smooth="yes"/>
+ <point x="972" y="469"/>
+ <point x="909" y="336"/>
+ <point x="822" y="250" type="curve" smooth="yes"/>
+ <point x="741" y="169"/>
+ <point x="638" y="125"/>
+ <point x="552" y="125" type="curve" smooth="yes"/>
+ <point x="466" y="125"/>
+ <point x="376" y="167"/>
+ <point x="325" y="200" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetglyphorder.ufo/glyphs/L_tnS_mC_.glif b/tests/reference/ufo/psfsetglyphorder.ufo/glyphs/L_tnS_mC_.glif
new file mode 100644
index 0000000..f54fbe9
--- /dev/null
+++ b/tests/reference/ufo/psfsetglyphorder.ufo/glyphs/L_tnS_mC_.glif
@@ -0,0 +1,39 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmC" format="2">
+ <advance width="989"/>
+ <unicode hex="0063"/>
+ <anchor x="520" y="0" name="H"/>
+ <anchor x="495" y="-100" name="L"/>
+ <anchor x="1210" y="1000" name="R"/>
+ <anchor x="785" y="1100" name="U"/>
+ <outline>
+ <contour>
+ <point x="917" y="255" type="line"/>
+ <point x="811" y="179"/>
+ <point x="703" y="137"/>
+ <point x="583" y="137" type="curve" smooth="yes"/>
+ <point x="427" y="137"/>
+ <point x="331" y="239"/>
+ <point x="331" y="406" type="curve" smooth="yes"/>
+ <point x="331" y="619"/>
+ <point x="499" y="858"/>
+ <point x="742" y="858" type="curve" smooth="yes"/>
+ <point x="845" y="858"/>
+ <point x="924" y="824"/>
+ <point x="998" y="760" type="curve"/>
+ <point x="1077" y="936" type="line"/>
+ <point x="1016" y="985"/>
+ <point x="902" y="1020"/>
+ <point x="789" y="1020" type="curve" smooth="yes"/>
+ <point x="420" y="1020"/>
+ <point x="139" y="737"/>
+ <point x="139" y="381" type="curve" smooth="yes"/>
+ <point x="139" y="130"/>
+ <point x="309" y="-25"/>
+ <point x="532" y="-25" type="curve" smooth="yes"/>
+ <point x="682" y="-25"/>
+ <point x="785" y="9"/>
+ <point x="904" y="83" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetglyphorder.ufo/glyphs/L_tnS_mD_.glif b/tests/reference/ufo/psfsetglyphorder.ufo/glyphs/L_tnS_mD_.glif
new file mode 100644
index 0000000..4ea9ea1
--- /dev/null
+++ b/tests/reference/ufo/psfsetglyphorder.ufo/glyphs/L_tnS_mD_.glif
@@ -0,0 +1,65 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmD" format="2">
+ <advance width="1197"/>
+ <unicode hex="0064"/>
+ <anchor x="545" y="0" name="H"/>
+ <anchor x="520" y="-100" name="L"/>
+ <anchor x="1380" y="1000" name="R"/>
+ <anchor x="953" y="1635" name="U"/>
+ <outline>
+ <contour>
+ <point x="1144" y="1570" type="line"/>
+ <point x="1144" y="1456"/>
+ <point x="1114" y="1327"/>
+ <point x="1079" y="1175" type="curve" smooth="yes"/>
+ <point x="1024" y="935" type="line"/>
+ <point x="957" y="978"/>
+ <point x="854" y="1020"/>
+ <point x="759" y="1020" type="curve" smooth="yes"/>
+ <point x="650" y="1020"/>
+ <point x="534" y="979"/>
+ <point x="429" y="895" type="curve" smooth="yes"/>
+ <point x="262" y="761"/>
+ <point x="139" y="532"/>
+ <point x="139" y="288" type="curve" smooth="yes"/>
+ <point x="139" y="94"/>
+ <point x="250" y="-25"/>
+ <point x="424" y="-25" type="curve" smooth="yes"/>
+ <point x="563" y="-25"/>
+ <point x="791" y="141"/>
+ <point x="899" y="305" type="curve"/>
+ <point x="875" y="196"/>
+ <point x="869" y="93"/>
+ <point x="869" y="0" type="curve"/>
+ <point x="1052" y="0" type="line"/>
+ <point x="1048" y="23"/>
+ <point x="1047" y="53"/>
+ <point x="1047" y="90" type="curve" smooth="yes"/>
+ <point x="1047" y="190"/>
+ <point x="1063" y="340"/>
+ <point x="1107" y="520" type="curve" smooth="yes"/>
+ <point x="1267" y="1175" type="line" smooth="yes"/>
+ <point x="1310" y="1351"/>
+ <point x="1337" y="1475"/>
+ <point x="1337" y="1570" type="curve"/>
+ </contour>
+ <contour>
+ <point x="930" y="545" type="line"/>
+ <point x="846" y="370"/>
+ <point x="592" y="130"/>
+ <point x="479" y="130" type="curve" smooth="yes"/>
+ <point x="374" y="130"/>
+ <point x="330" y="195"/>
+ <point x="330" y="316" type="curve" smooth="yes"/>
+ <point x="330" y="460"/>
+ <point x="397" y="649"/>
+ <point x="509" y="760" type="curve" smooth="yes"/>
+ <point x="572" y="822"/>
+ <point x="643" y="855"/>
+ <point x="734" y="855" type="curve" smooth="yes"/>
+ <point x="835" y="855"/>
+ <point x="898" y="832"/>
+ <point x="984" y="780" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetglyphorder.ufo/glyphs/L_tnS_mE_.glif b/tests/reference/ufo/psfsetglyphorder.ufo/glyphs/L_tnS_mE_.glif
new file mode 100644
index 0000000..a3a6490
--- /dev/null
+++ b/tests/reference/ufo/psfsetglyphorder.ufo/glyphs/L_tnS_mE_.glif
@@ -0,0 +1,52 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmE" format="2">
+ <advance width="1042"/>
+ <unicode hex="0065"/>
+ <anchor x="485" y="0" name="H"/>
+ <anchor x="484" y="-100" name="L"/>
+ <anchor x="840" y="0" name="O"/>
+ <anchor x="1285" y="1000" name="R"/>
+ <anchor x="784" y="1100" name="U"/>
+ <outline>
+ <contour>
+ <point x="967" y="270" type="line"/>
+ <point x="854" y="189"/>
+ <point x="700" y="135"/>
+ <point x="567" y="135" type="curve" smooth="yes"/>
+ <point x="386" y="135"/>
+ <point x="317" y="263"/>
+ <point x="317" y="420" type="curve" smooth="yes"/>
+ <point x="317" y="686"/>
+ <point x="522" y="872"/>
+ <point x="720" y="872" type="curve" smooth="yes"/>
+ <point x="813" y="872"/>
+ <point x="883" y="823"/>
+ <point x="883" y="753" type="curve" smooth="yes"/>
+ <point x="883" y="660"/>
+ <point x="766" y="590"/>
+ <point x="539" y="590" type="curve" smooth="yes"/>
+ <point x="468" y="590"/>
+ <point x="382" y="596"/>
+ <point x="279" y="610" type="curve"/>
+ <point x="279" y="477" type="line"/>
+ <point x="391" y="461"/>
+ <point x="487" y="453"/>
+ <point x="569" y="453" type="curve" smooth="yes"/>
+ <point x="931" y="453"/>
+ <point x="1077" y="609"/>
+ <point x="1077" y="791" type="curve" smooth="yes"/>
+ <point x="1077" y="899"/>
+ <point x="986" y="1020"/>
+ <point x="772" y="1020" type="curve" smooth="yes"/>
+ <point x="399" y="1020"/>
+ <point x="137" y="710"/>
+ <point x="137" y="380" type="curve" smooth="yes"/>
+ <point x="137" y="147"/>
+ <point x="258" y="-25"/>
+ <point x="523" y="-25" type="curve" smooth="yes"/>
+ <point x="689" y="-25"/>
+ <point x="849" y="26"/>
+ <point x="955" y="83" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetglyphorder.ufo/glyphs/L_tnS_mF_.glif b/tests/reference/ufo/psfsetglyphorder.ufo/glyphs/L_tnS_mF_.glif
new file mode 100644
index 0000000..ede52a9
--- /dev/null
+++ b/tests/reference/ufo/psfsetglyphorder.ufo/glyphs/L_tnS_mF_.glif
@@ -0,0 +1,44 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmF" format="2">
+ <advance width="756"/>
+ <unicode hex="0066"/>
+ <anchor x="290" y="0" name="H"/>
+ <anchor x="315" y="-100" name="L"/>
+ <anchor x="908" y="1635" name="U"/>
+ <outline>
+ <contour>
+ <point x="180" y="833" type="line"/>
+ <point x="835" y="833" type="line"/>
+ <point x="871" y="975" type="line"/>
+ <point x="216" y="975" type="line"/>
+ </contour>
+ <contour>
+ <point x="1106" y="1519" type="line"/>
+ <point x="1062" y="1555"/>
+ <point x="981" y="1588"/>
+ <point x="903" y="1588" type="curve" smooth="yes"/>
+ <point x="687" y="1588"/>
+ <point x="533" y="1478"/>
+ <point x="448" y="1147" type="curve" smooth="yes"/>
+ <point x="403" y="972"/>
+ <point x="244" y="334"/>
+ <point x="223" y="0" type="curve"/>
+ <point x="436" y="0" type="line"/>
+ <point x="430" y="28"/>
+ <point x="427" y="66"/>
+ <point x="427" y="110" type="curve" smooth="yes"/>
+ <point x="427" y="213"/>
+ <point x="447" y="351"/>
+ <point x="476" y="484" type="curve" smooth="yes"/>
+ <point x="510" y="641"/>
+ <point x="558" y="846"/>
+ <point x="641" y="1186" type="curve" smooth="yes"/>
+ <point x="682" y="1353"/>
+ <point x="758" y="1421"/>
+ <point x="862" y="1421" type="curve" smooth="yes"/>
+ <point x="920" y="1421"/>
+ <point x="988" y="1392"/>
+ <point x="1022" y="1362" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetglyphorder.ufo/glyphs/L_tnS_mG_.glif b/tests/reference/ufo/psfsetglyphorder.ufo/glyphs/L_tnS_mG_.glif
new file mode 100644
index 0000000..8931f8d
--- /dev/null
+++ b/tests/reference/ufo/psfsetglyphorder.ufo/glyphs/L_tnS_mG_.glif
@@ -0,0 +1,100 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmG" format="2">
+ <advance width="1075"/>
+ <unicode hex="0067"/>
+ <anchor x="368" y="-465" name="H"/>
+ <anchor x="351" y="-535" name="L"/>
+ <anchor x="1285" y="1000" name="R"/>
+ <anchor x="730" y="1100" name="U"/>
+ <outline>
+ <contour>
+ <point x="360" y="389" type="line"/>
+ <point x="277" y="352"/>
+ <point x="168" y="266"/>
+ <point x="168" y="176" type="curve" smooth="yes"/>
+ <point x="168" y="96"/>
+ <point x="246" y="33"/>
+ <point x="483" y="-5" type="curve" smooth="yes"/>
+ <point x="707" y="-41"/>
+ <point x="781" y="-94"/>
+ <point x="781" y="-151" type="curve" smooth="yes"/>
+ <point x="781" y="-256"/>
+ <point x="580" y="-353"/>
+ <point x="411" y="-353" type="curve" smooth="yes"/>
+ <point x="202" y="-353"/>
+ <point x="104" y="-271"/>
+ <point x="104" y="-196" type="curve" smooth="yes"/>
+ <point x="104" y="-189"/>
+ <point x="104" y="-183"/>
+ <point x="106" y="-176" type="curve" smooth="yes"/>
+ <point x="120" y="-119"/>
+ <point x="170" y="-55"/>
+ <point x="409" y="20" type="curve"/>
+ <point x="410" y="48"/>
+ <point x="248" y="73"/>
+ <point x="248" y="73" type="curve"/>
+ <point x="53" y="12"/>
+ <point x="-51" y="-77"/>
+ <point x="-78" y="-186" type="curve" smooth="yes"/>
+ <point x="-82" y="-201"/>
+ <point x="-84" y="-217"/>
+ <point x="-84" y="-231" type="curve" smooth="yes"/>
+ <point x="-84" y="-396"/>
+ <point x="158" y="-495"/>
+ <point x="371" y="-495" type="curve" smooth="yes"/>
+ <point x="632" y="-495"/>
+ <point x="972" y="-360"/>
+ <point x="972" y="-125" type="curve" smooth="yes"/>
+ <point x="972" y="0"/>
+ <point x="849" y="90"/>
+ <point x="619" y="127" type="curve" smooth="yes"/>
+ <point x="403" y="162"/>
+ <point x="341" y="184"/>
+ <point x="341" y="218" type="curve" smooth="yes"/>
+ <point x="341" y="263"/>
+ <point x="447" y="325"/>
+ <point x="522" y="342" type="curve"/>
+ </contour>
+ <contour>
+ <point x="1244" y="1019" type="line"/>
+ <point x="1143" y="1012"/>
+ <point x="1002" y="977"/>
+ <point x="899" y="921" type="curve"/>
+ <point x="936" y="809" type="line"/>
+ <point x="1037" y="846"/>
+ <point x="1121" y="860"/>
+ <point x="1194" y="862" type="curve"/>
+ </contour>
+ <contour>
+ <point x="212" y="613" type="curve" smooth="yes"/>
+ <point x="212" y="449"/>
+ <point x="356" y="319"/>
+ <point x="554" y="319" type="curve" smooth="yes"/>
+ <point x="791" y="319"/>
+ <point x="1030" y="495"/>
+ <point x="1030" y="729" type="curve" smooth="yes"/>
+ <point x="1030" y="894"/>
+ <point x="887" y="1019"/>
+ <point x="689" y="1019" type="curve" smooth="yes"/>
+ <point x="441" y="1019"/>
+ <point x="212" y="847"/>
+ </contour>
+ <contour>
+ <point x="857" y="704" type="curve" smooth="yes"/>
+ <point x="857" y="555"/>
+ <point x="712" y="456"/>
+ <point x="578" y="456" type="curve" smooth="yes"/>
+ <point x="463" y="456"/>
+ <point x="385" y="530"/>
+ <point x="385" y="628" type="curve" smooth="yes"/>
+ <point x="385" y="643"/>
+ <point x="387" y="660"/>
+ <point x="391" y="676" type="curve" smooth="yes"/>
+ <point x="421" y="797"/>
+ <point x="530" y="877"/>
+ <point x="663" y="877" type="curve" smooth="yes"/>
+ <point x="779" y="877"/>
+ <point x="857" y="802"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetglyphorder.ufo/glyphs/L_tnS_mH_.glif b/tests/reference/ufo/psfsetglyphorder.ufo/glyphs/L_tnS_mH_.glif
new file mode 100644
index 0000000..08afbac
--- /dev/null
+++ b/tests/reference/ufo/psfsetglyphorder.ufo/glyphs/L_tnS_mH_.glif
@@ -0,0 +1,54 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmH" format="2">
+ <advance width="1185"/>
+ <unicode hex="0068"/>
+ <anchor x="190" y="0" name="H"/>
+ <anchor x="550" y="-100" name="L"/>
+ <anchor x="933" y="1635" name="U"/>
+ <outline>
+ <contour>
+ <point x="1055" y="0" type="line"/>
+ <point x="1047" y="30"/>
+ <point x="1043" y="65"/>
+ <point x="1043" y="102" type="curve" smooth="yes"/>
+ <point x="1043" y="143"/>
+ <point x="1048" y="188"/>
+ <point x="1055" y="238" type="curve" smooth="yes"/>
+ <point x="1069" y="327"/>
+ <point x="1170" y="636"/>
+ <point x="1170" y="745" type="curve" smooth="yes"/>
+ <point x="1170" y="917"/>
+ <point x="1095" y="1020"/>
+ <point x="930" y="1020" type="curve" smooth="yes"/>
+ <point x="760" y="1020"/>
+ <point x="591" y="877"/>
+ <point x="475" y="723" type="curve"/>
+ <point x="571" y="1105" type="line" smooth="yes"/>
+ <point x="609" y="1259"/>
+ <point x="645" y="1482"/>
+ <point x="645" y="1570" type="curve"/>
+ <point x="455" y="1570" type="line"/>
+ <point x="455" y="1456"/>
+ <point x="423" y="1257"/>
+ <point x="385" y="1105" type="curve" smooth="yes"/>
+ <point x="110" y="0" type="line"/>
+ <point x="295" y="0" type="line"/>
+ <point x="397" y="408" type="line"/>
+ <point x="492" y="612"/>
+ <point x="717" y="850"/>
+ <point x="840" y="850" type="curve" smooth="yes"/>
+ <point x="937" y="850"/>
+ <point x="970" y="798"/>
+ <point x="970" y="680" type="curve" smooth="yes"/>
+ <point x="970" y="592"/>
+ <point x="886" y="319"/>
+ <point x="872" y="203" type="curve" smooth="yes"/>
+ <point x="867" y="158"/>
+ <point x="864" y="115"/>
+ <point x="864" y="77" type="curve" smooth="yes"/>
+ <point x="864" y="48"/>
+ <point x="866" y="21"/>
+ <point x="870" y="0" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetglyphorder.ufo/glyphs/L_tnS_mI_.glif b/tests/reference/ufo/psfsetglyphorder.ufo/glyphs/L_tnS_mI_.glif
new file mode 100644
index 0000000..65ed550
--- /dev/null
+++ b/tests/reference/ufo/psfsetglyphorder.ufo/glyphs/L_tnS_mI_.glif
@@ -0,0 +1,50 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmI" format="2">
+ <advance width="554"/>
+ <unicode hex="0069"/>
+ <anchor x="235" y="0" name="H"/>
+ <anchor x="250" y="-100" name="L"/>
+ <anchor x="455" y="0" name="O"/>
+ <anchor x="745" y="1000" name="R"/>
+ <anchor x="472" y="1100" name="U"/>
+ <outline>
+ <contour>
+ <point x="361" y="1297" type="curve" smooth="yes"/>
+ <point x="361" y="1237"/>
+ <point x="404" y="1186"/>
+ <point x="467" y="1186" type="curve" smooth="yes"/>
+ <point x="552" y="1186"/>
+ <point x="624" y="1259"/>
+ <point x="624" y="1338" type="curve" smooth="yes"/>
+ <point x="624" y="1399"/>
+ <point x="578" y="1450"/>
+ <point x="513" y="1450" type="curve" smooth="yes"/>
+ <point x="428" y="1450"/>
+ <point x="361" y="1375"/>
+ </contour>
+ <contour>
+ <point x="335" y="1000" type="line"/>
+ <point x="335" y="886"/>
+ <point x="286" y="688"/>
+ <point x="246" y="537" type="curve" smooth="yes"/>
+ <point x="207" y="388" type="line" smooth="yes"/>
+ <point x="180" y="284"/>
+ <point x="165" y="172"/>
+ <point x="165" y="87" type="curve" smooth="yes"/>
+ <point x="165" y="53"/>
+ <point x="167" y="24"/>
+ <point x="172" y="0" type="curve"/>
+ <point x="372" y="0" type="line"/>
+ <point x="365" y="37"/>
+ <point x="360" y="85"/>
+ <point x="360" y="136" type="curve" smooth="yes"/>
+ <point x="360" y="208"/>
+ <point x="368" y="287"/>
+ <point x="386" y="357" type="curve" smooth="yes"/>
+ <point x="431" y="536" type="line" smooth="yes"/>
+ <point x="476" y="712"/>
+ <point x="525" y="912"/>
+ <point x="525" y="1000" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetglyphorder.ufo/glyphs/L_tnS_mJ_.glif b/tests/reference/ufo/psfsetglyphorder.ufo/glyphs/L_tnS_mJ_.glif
new file mode 100644
index 0000000..e9e18b8
--- /dev/null
+++ b/tests/reference/ufo/psfsetglyphorder.ufo/glyphs/L_tnS_mJ_.glif
@@ -0,0 +1,45 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmJ" format="2">
+ <advance width="602"/>
+ <unicode hex="006A"/>
+ <anchor x="-60" y="-500" name="L"/>
+ <anchor x="510" y="1100" name="U"/>
+ <outline>
+ <contour>
+ <point x="370" y="1000" type="line"/>
+ <point x="370" y="856"/>
+ <point x="288" y="374"/>
+ <point x="214" y="77" type="curve" smooth="yes"/>
+ <point x="152" y="-173"/>
+ <point x="29" y="-295"/>
+ <point x="-77" y="-295" type="curve" smooth="yes"/>
+ <point x="-133" y="-295"/>
+ <point x="-217" y="-264"/>
+ <point x="-253" y="-229" type="curve"/>
+ <point x="-328" y="-397" type="line"/>
+ <point x="-278" y="-437"/>
+ <point x="-170" y="-465"/>
+ <point x="-114" y="-465" type="curve" smooth="yes"/>
+ <point x="103" y="-465"/>
+ <point x="303" y="-314"/>
+ <point x="396" y="66" type="curve" smooth="yes"/>
+ <point x="455" y="307"/>
+ <point x="560" y="872"/>
+ <point x="560" y="1000" type="curve"/>
+ </contour>
+ <contour>
+ <point x="397" y="1297" type="curve" smooth="yes"/>
+ <point x="397" y="1237"/>
+ <point x="440" y="1186"/>
+ <point x="503" y="1186" type="curve" smooth="yes"/>
+ <point x="588" y="1186"/>
+ <point x="660" y="1259"/>
+ <point x="660" y="1338" type="curve" smooth="yes"/>
+ <point x="660" y="1399"/>
+ <point x="614" y="1450"/>
+ <point x="549" y="1450" type="curve" smooth="yes"/>
+ <point x="464" y="1450"/>
+ <point x="397" y="1375"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetglyphorder.ufo/glyphs/L_tnS_mK_.glif b/tests/reference/ufo/psfsetglyphorder.ufo/glyphs/L_tnS_mK_.glif
new file mode 100644
index 0000000..28fbc71
--- /dev/null
+++ b/tests/reference/ufo/psfsetglyphorder.ufo/glyphs/L_tnS_mK_.glif
@@ -0,0 +1,50 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmK" format="2">
+ <advance width="1059"/>
+ <unicode hex="006B"/>
+ <anchor x="840" y="0" name="H"/>
+ <anchor x="537" y="-100" name="L"/>
+ <anchor x="1225" y="1000" name="R"/>
+ <anchor x="920" y="1635" name="U"/>
+ <outline>
+ <contour>
+ <point x="295" y="0" type="line"/>
+ <point x="570" y="1105" type="line" smooth="yes"/>
+ <point x="614" y="1280"/>
+ <point x="645" y="1482"/>
+ <point x="645" y="1570" type="curve"/>
+ <point x="455" y="1570" type="line"/>
+ <point x="455" y="1456"/>
+ <point x="424" y="1259"/>
+ <point x="386" y="1107" type="curve" smooth="yes"/>
+ <point x="338" y="915"/>
+ <point x="110" y="0"/>
+ <point x="110" y="0" type="curve"/>
+ </contour>
+ <contour>
+ <point x="909" y="1000" type="line"/>
+ <point x="885" y="863"/>
+ <point x="654" y="700"/>
+ <point x="379" y="539" type="curve"/>
+ <point x="386" y="540"/>
+ <point x="393" y="540"/>
+ <point x="400" y="540" type="curve" smooth="yes"/>
+ <point x="467" y="540"/>
+ <point x="559" y="514"/>
+ <point x="559" y="514" type="curve"/>
+ <point x="902" y="702"/>
+ <point x="1134" y="884"/>
+ <point x="1134" y="1000" type="curve"/>
+ </contour>
+ <contour>
+ <point x="1010" y="0" type="line"/>
+ <point x="863" y="238"/>
+ <point x="718" y="600"/>
+ <point x="527" y="600" type="curve"/>
+ <point x="385" y="529" type="line"/>
+ <point x="540" y="529"/>
+ <point x="667" y="246"/>
+ <point x="775" y="0" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetglyphorder.ufo/glyphs/L_tnS_mL_.glif b/tests/reference/ufo/psfsetglyphorder.ufo/glyphs/L_tnS_mL_.glif
new file mode 100644
index 0000000..06d68fd
--- /dev/null
+++ b/tests/reference/ufo/psfsetglyphorder.ufo/glyphs/L_tnS_mL_.glif
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmL" format="2">
+ <advance width="575"/>
+ <unicode hex="006C"/>
+ <anchor x="230" y="0" name="H"/>
+ <anchor x="255" y="-100" name="L"/>
+ <anchor x="740" y="1000" name="R"/>
+ <anchor x="630" y="1635" name="U"/>
+ <outline>
+ <contour>
+ <point x="465" y="1570" type="line"/>
+ <point x="465" y="1456"/>
+ <point x="434" y="1259"/>
+ <point x="396" y="1107" type="curve" smooth="yes"/>
+ <point x="241" y="489" type="line" smooth="yes"/>
+ <point x="204" y="343"/>
+ <point x="186" y="220"/>
+ <point x="186" y="104" type="curve" smooth="yes"/>
+ <point x="186" y="69"/>
+ <point x="188" y="34"/>
+ <point x="191" y="0" type="curve"/>
+ <point x="391" y="0" type="line"/>
+ <point x="386" y="32"/>
+ <point x="384" y="70"/>
+ <point x="384" y="112" type="curve" smooth="yes"/>
+ <point x="384" y="230"/>
+ <point x="402" y="380"/>
+ <point x="436" y="517" type="curve" smooth="yes"/>
+ <point x="580" y="1105" type="line" smooth="yes"/>
+ <point x="623" y="1280"/>
+ <point x="655" y="1482"/>
+ <point x="655" y="1570" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetglyphorder.ufo/glyphs/L_tnS_mM_.glif b/tests/reference/ufo/psfsetglyphorder.ufo/glyphs/L_tnS_mM_.glif
new file mode 100644
index 0000000..a6b80db
--- /dev/null
+++ b/tests/reference/ufo/psfsetglyphorder.ufo/glyphs/L_tnS_mM_.glif
@@ -0,0 +1,80 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmM" format="2">
+ <advance width="1680"/>
+ <unicode hex="006D"/>
+ <anchor x="805" y="0" name="H"/>
+ <anchor x="780" y="-100" name="L"/>
+ <anchor x="1080" y="1100" name="U"/>
+ <outline>
+ <contour>
+ <point x="1520" y="0" type="line"/>
+ <point x="1512" y="30"/>
+ <point x="1510" y="65"/>
+ <point x="1510" y="102" type="curve" smooth="yes"/>
+ <point x="1510" y="143"/>
+ <point x="1515" y="188"/>
+ <point x="1522" y="238" type="curve" smooth="yes"/>
+ <point x="1536" y="327"/>
+ <point x="1655" y="691"/>
+ <point x="1655" y="800" type="curve" smooth="yes"/>
+ <point x="1655" y="930"/>
+ <point x="1594" y="1020"/>
+ <point x="1445" y="1020" type="curve" smooth="yes"/>
+ <point x="1292" y="1020"/>
+ <point x="1124" y="867"/>
+ <point x="1026" y="680" type="curve"/>
+ <point x="1030" y="704"/>
+ <point x="1045" y="778"/>
+ <point x="1045" y="800" type="curve" smooth="yes"/>
+ <point x="1045" y="932"/>
+ <point x="982" y="1020"/>
+ <point x="860" y="1020" type="curve" smooth="yes"/>
+ <point x="717" y="1020"/>
+ <point x="563" y="879"/>
+ <point x="446" y="680" type="curve"/>
+ <point x="466" y="753"/>
+ <point x="476" y="880"/>
+ <point x="476" y="961" type="curve" smooth="yes"/>
+ <point x="476" y="976"/>
+ <point x="476" y="989"/>
+ <point x="475" y="1000" type="curve"/>
+ <point x="295" y="1000" type="line"/>
+ <point x="296" y="983"/>
+ <point x="296" y="964"/>
+ <point x="296" y="945" type="curve" smooth="yes"/>
+ <point x="296" y="825"/>
+ <point x="283" y="680"/>
+ <point x="262" y="595" type="curve" smooth="yes"/>
+ <point x="115" y="0" type="line"/>
+ <point x="300" y="0" type="line"/>
+ <point x="389" y="359" type="line"/>
+ <point x="475" y="573"/>
+ <point x="685" y="850"/>
+ <point x="775" y="850" type="curve" smooth="yes"/>
+ <point x="833" y="850"/>
+ <point x="865" y="813"/>
+ <point x="865" y="720" type="curve" smooth="yes"/>
+ <point x="865" y="679"/>
+ <point x="846" y="583"/>
+ <point x="822" y="486" type="curve" smooth="yes"/>
+ <point x="700" y="0" type="line"/>
+ <point x="885" y="0" type="line"/>
+ <point x="974" y="359" type="line"/>
+ <point x="1032" y="531"/>
+ <point x="1242" y="850"/>
+ <point x="1357" y="850" type="curve" smooth="yes"/>
+ <point x="1425" y="850"/>
+ <point x="1457" y="813"/>
+ <point x="1457" y="720" type="curve" smooth="yes"/>
+ <point x="1457" y="632"/>
+ <point x="1349" y="319"/>
+ <point x="1335" y="203" type="curve" smooth="yes"/>
+ <point x="1330" y="158"/>
+ <point x="1327" y="115"/>
+ <point x="1327" y="77" type="curve" smooth="yes"/>
+ <point x="1327" y="48"/>
+ <point x="1331" y="21"/>
+ <point x="1335" y="0" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetglyphorder.ufo/glyphs/L_tnS_mN_.glif b/tests/reference/ufo/psfsetglyphorder.ufo/glyphs/L_tnS_mN_.glif
new file mode 100644
index 0000000..1f38f20
--- /dev/null
+++ b/tests/reference/ufo/psfsetglyphorder.ufo/glyphs/L_tnS_mN_.glif
@@ -0,0 +1,57 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmN" format="2">
+ <advance width="1195"/>
+ <unicode hex="006E"/>
+ <anchor x="540" y="0" name="H"/>
+ <anchor x="565" y="-100" name="L"/>
+ <anchor x="815" y="1100" name="U"/>
+ <outline>
+ <contour>
+ <point x="1060" y="0" type="line"/>
+ <point x="1052" y="30"/>
+ <point x="1050" y="65"/>
+ <point x="1050" y="102" type="curve" smooth="yes"/>
+ <point x="1050" y="143"/>
+ <point x="1055" y="188"/>
+ <point x="1062" y="238" type="curve" smooth="yes"/>
+ <point x="1075" y="327"/>
+ <point x="1175" y="636"/>
+ <point x="1175" y="745" type="curve" smooth="yes"/>
+ <point x="1175" y="917"/>
+ <point x="1100" y="1020"/>
+ <point x="935" y="1020" type="curve" smooth="yes"/>
+ <point x="755" y="1020"/>
+ <point x="581" y="870"/>
+ <point x="445" y="672" type="curve"/>
+ <point x="463" y="740"/>
+ <point x="477" y="873"/>
+ <point x="477" y="957" type="curve" smooth="yes"/>
+ <point x="477" y="973"/>
+ <point x="476" y="988"/>
+ <point x="475" y="1000" type="curve"/>
+ <point x="295" y="1000" type="line"/>
+ <point x="295" y="961" type="line" smooth="yes"/>
+ <point x="295" y="833"/>
+ <point x="283" y="679"/>
+ <point x="262" y="595" type="curve" smooth="yes"/>
+ <point x="115" y="0" type="line"/>
+ <point x="300" y="0" type="line"/>
+ <point x="392" y="370" type="line"/>
+ <point x="478" y="573"/>
+ <point x="708" y="850"/>
+ <point x="835" y="850" type="curve" smooth="yes"/>
+ <point x="927" y="850"/>
+ <point x="975" y="798"/>
+ <point x="975" y="680" type="curve" smooth="yes"/>
+ <point x="975" y="592"/>
+ <point x="888" y="319"/>
+ <point x="875" y="203" type="curve" smooth="yes"/>
+ <point x="870" y="158"/>
+ <point x="867" y="115"/>
+ <point x="867" y="77" type="curve" smooth="yes"/>
+ <point x="867" y="48"/>
+ <point x="871" y="21"/>
+ <point x="875" y="0" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetglyphorder.ufo/glyphs/L_tnS_mO_.glif b/tests/reference/ufo/psfsetglyphorder.ufo/glyphs/L_tnS_mO_.glif
new file mode 100644
index 0000000..bec7b9e
--- /dev/null
+++ b/tests/reference/ufo/psfsetglyphorder.ufo/glyphs/L_tnS_mO_.glif
@@ -0,0 +1,40 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmO" format="2">
+ <advance width="1133"/>
+ <unicode hex="006F"/>
+ <anchor x="510" y="0" name="H"/>
+ <anchor x="505" y="-100" name="L"/>
+ <anchor x="800" y="0" name="O"/>
+ <anchor x="1330" y="1000" name="R"/>
+ <anchor x="785" y="1100" name="U"/>
+ <outline>
+ <contour>
+ <point x="142" y="344" type="curve" smooth="yes"/>
+ <point x="142" y="114"/>
+ <point x="306" y="-25"/>
+ <point x="530" y="-25" type="curve" smooth="yes"/>
+ <point x="896" y="-25"/>
+ <point x="1138" y="314"/>
+ <point x="1138" y="648" type="curve" smooth="yes"/>
+ <point x="1138" y="879"/>
+ <point x="985" y="1020"/>
+ <point x="761" y="1020" type="curve" smooth="yes"/>
+ <point x="387" y="1020"/>
+ <point x="142" y="677"/>
+ </contour>
+ <contour>
+ <point x="721" y="862" type="curve" smooth="yes"/>
+ <point x="859" y="862"/>
+ <point x="947" y="767"/>
+ <point x="947" y="611" type="curve" smooth="yes"/>
+ <point x="947" y="391"/>
+ <point x="795" y="132"/>
+ <point x="559" y="132" type="curve" smooth="yes"/>
+ <point x="421" y="132"/>
+ <point x="333" y="226"/>
+ <point x="333" y="380" type="curve" smooth="yes"/>
+ <point x="333" y="599"/>
+ <point x="486" y="862"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetglyphorder.ufo/glyphs/L_tnS_mP_.glif b/tests/reference/ufo/psfsetglyphorder.ufo/glyphs/L_tnS_mP_.glif
new file mode 100644
index 0000000..f9e06b1
--- /dev/null
+++ b/tests/reference/ufo/psfsetglyphorder.ufo/glyphs/L_tnS_mP_.glif
@@ -0,0 +1,66 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmP" format="2">
+ <advance width="1185"/>
+ <unicode hex="0070"/>
+ <anchor x="105" y="-435" name="H"/>
+ <anchor x="405" y="-500" name="L"/>
+ <anchor x="1360" y="1000" name="R"/>
+ <anchor x="805" y="1100" name="U"/>
+ <outline>
+ <contour>
+ <point x="215" y="-480" type="line"/>
+ <point x="215" y="-388"/>
+ <point x="229" y="-282"/>
+ <point x="255" y="-175" type="curve" smooth="yes"/>
+ <point x="320" y="85" type="line"/>
+ <point x="399" y="20"/>
+ <point x="468" y="-25"/>
+ <point x="575" y="-25" type="curve" smooth="yes"/>
+ <point x="685" y="-25"/>
+ <point x="797" y="9"/>
+ <point x="895" y="85" type="curve" smooth="yes"/>
+ <point x="1063" y="215"/>
+ <point x="1185" y="438"/>
+ <point x="1185" y="680" type="curve" smooth="yes"/>
+ <point x="1185" y="878"/>
+ <point x="1101" y="1020"/>
+ <point x="920" y="1020" type="curve" smooth="yes"/>
+ <point x="757" y="1020"/>
+ <point x="559" y="842"/>
+ <point x="452" y="680" type="curve"/>
+ <point x="468" y="760"/>
+ <point x="477" y="860"/>
+ <point x="477" y="940" type="curve" smooth="yes"/>
+ <point x="477" y="962"/>
+ <point x="477" y="982"/>
+ <point x="475" y="1000" type="curve"/>
+ <point x="295" y="1000" type="line"/>
+ <point x="295" y="971" type="line" smooth="yes"/>
+ <point x="295" y="819"/>
+ <point x="273" y="625"/>
+ <point x="235" y="475" type="curve" smooth="yes"/>
+ <point x="70" y="-175" type="line" smooth="yes"/>
+ <point x="43" y="-281"/>
+ <point x="20" y="-398"/>
+ <point x="20" y="-480" type="curve"/>
+ </contour>
+ <contour>
+ <point x="407" y="432" type="line"/>
+ <point x="544" y="656"/>
+ <point x="732" y="850"/>
+ <point x="840" y="850" type="curve" smooth="yes"/>
+ <point x="939" y="850"/>
+ <point x="990" y="763"/>
+ <point x="990" y="630" type="curve" smooth="yes"/>
+ <point x="990" y="491"/>
+ <point x="926" y="322"/>
+ <point x="815" y="220" type="curve" smooth="yes"/>
+ <point x="759" y="168"/>
+ <point x="693" y="135"/>
+ <point x="615" y="135" type="curve" smooth="yes"/>
+ <point x="523" y="135"/>
+ <point x="479" y="161"/>
+ <point x="365" y="255" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetglyphorder.ufo/glyphs/L_tnS_mQ_.glif b/tests/reference/ufo/psfsetglyphorder.ufo/glyphs/L_tnS_mQ_.glif
new file mode 100644
index 0000000..58d9f87
--- /dev/null
+++ b/tests/reference/ufo/psfsetglyphorder.ufo/glyphs/L_tnS_mQ_.glif
@@ -0,0 +1,54 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmQ" format="2">
+ <advance width="1115"/>
+ <unicode hex="0071"/>
+ <anchor x="370" y="-500" name="L"/>
+ <anchor x="1320" y="1000" name="R"/>
+ <anchor x="770" y="1100" name="U"/>
+ <outline>
+ <contour>
+ <point x="843" y="-480" type="line"/>
+ <point x="843" y="-391"/>
+ <point x="858" y="-294"/>
+ <point x="885" y="-185" type="curve" smooth="yes"/>
+ <point x="1165" y="945" type="line"/>
+ <point x="1066" y="980"/>
+ <point x="946" y="1020"/>
+ <point x="825" y="1020" type="curve" smooth="yes"/>
+ <point x="675" y="1020"/>
+ <point x="550" y="977"/>
+ <point x="440" y="890" type="curve" smooth="yes"/>
+ <point x="260" y="747"/>
+ <point x="135" y="505"/>
+ <point x="135" y="285" type="curve" smooth="yes"/>
+ <point x="135" y="73"/>
+ <point x="261" y="-25"/>
+ <point x="380" y="-25" type="curve" smooth="yes"/>
+ <point x="524" y="-25"/>
+ <point x="751" y="172"/>
+ <point x="825" y="300" type="curve"/>
+ <point x="693" y="-180" type="line" smooth="yes"/>
+ <point x="662" y="-294"/>
+ <point x="648" y="-414"/>
+ <point x="648" y="-480" type="curve"/>
+ </contour>
+ <contour>
+ <point x="885" y="565" type="line"/>
+ <point x="807" y="413"/>
+ <point x="550" y="140"/>
+ <point x="455" y="140" type="curve" smooth="yes"/>
+ <point x="376" y="140"/>
+ <point x="330" y="199"/>
+ <point x="330" y="330" type="curve" smooth="yes"/>
+ <point x="330" y="481"/>
+ <point x="400" y="658"/>
+ <point x="515" y="760" type="curve" smooth="yes"/>
+ <point x="580" y="817"/>
+ <point x="658" y="855"/>
+ <point x="750" y="855" type="curve" smooth="yes"/>
+ <point x="811" y="855"/>
+ <point x="893" y="840"/>
+ <point x="947" y="817" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetglyphorder.ufo/glyphs/L_tnS_mR_.glif b/tests/reference/ufo/psfsetglyphorder.ufo/glyphs/L_tnS_mR_.glif
new file mode 100644
index 0000000..8037612
--- /dev/null
+++ b/tests/reference/ufo/psfsetglyphorder.ufo/glyphs/L_tnS_mR_.glif
@@ -0,0 +1,42 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmR" format="2">
+ <advance width="910"/>
+ <unicode hex="0072"/>
+ <anchor x="210" y="0" name="H"/>
+ <anchor x="220" y="-100" name="L"/>
+ <anchor x="670" y="1100" name="U"/>
+ <outline>
+ <contour>
+ <point x="300" y="0" type="line"/>
+ <point x="402" y="415" type="line"/>
+ <point x="502" y="602"/>
+ <point x="703" y="850"/>
+ <point x="785" y="850" type="curve" smooth="yes"/>
+ <point x="831" y="850"/>
+ <point x="855" y="801"/>
+ <point x="855" y="740" type="curve" smooth="yes"/>
+ <point x="855" y="715"/>
+ <point x="852" y="689"/>
+ <point x="845" y="660" type="curve"/>
+ <point x="1010" y="690" type="line"/>
+ <point x="1022" y="737"/>
+ <point x="1030" y="783"/>
+ <point x="1030" y="825" type="curve" smooth="yes"/>
+ <point x="1030" y="935"/>
+ <point x="986" y="1020"/>
+ <point x="865" y="1020" type="curve" smooth="yes"/>
+ <point x="735" y="1020"/>
+ <point x="575" y="867"/>
+ <point x="445" y="675" type="curve"/>
+ <point x="467" y="773"/>
+ <point x="475" y="929"/>
+ <point x="475" y="1000" type="curve"/>
+ <point x="295" y="1000" type="line"/>
+ <point x="295" y="961" type="line" smooth="yes"/>
+ <point x="295" y="833"/>
+ <point x="283" y="679"/>
+ <point x="262" y="595" type="curve" smooth="yes"/>
+ <point x="115" y="0" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetglyphorder.ufo/glyphs/L_tnS_mS_.glif b/tests/reference/ufo/psfsetglyphorder.ufo/glyphs/L_tnS_mS_.glif
new file mode 100644
index 0000000..848ddda
--- /dev/null
+++ b/tests/reference/ufo/psfsetglyphorder.ufo/glyphs/L_tnS_mS_.glif
@@ -0,0 +1,50 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmS" format="2">
+ <advance width="945"/>
+ <unicode hex="0073"/>
+ <anchor x="435" y="0" name="H"/>
+ <anchor x="440" y="-100" name="L"/>
+ <anchor x="710" y="1100" name="U"/>
+ <outline>
+ <contour>
+ <point x="990" y="941" type="line"/>
+ <point x="930" y="978"/>
+ <point x="815" y="1020"/>
+ <point x="640" y="1020" type="curve" smooth="yes"/>
+ <point x="384" y="1020"/>
+ <point x="230" y="881"/>
+ <point x="230" y="716" type="curve" smooth="yes"/>
+ <point x="230" y="614"/>
+ <point x="320" y="533"/>
+ <point x="466" y="461" type="curve" smooth="yes"/>
+ <point x="638" y="376"/>
+ <point x="700" y="333"/>
+ <point x="700" y="265" type="curve" smooth="yes"/>
+ <point x="700" y="188"/>
+ <point x="621" y="132"/>
+ <point x="532" y="132" type="curve" smooth="yes"/>
+ <point x="376" y="132"/>
+ <point x="244" y="216"/>
+ <point x="159" y="325" type="curve"/>
+ <point x="71" y="158" type="line"/>
+ <point x="160" y="60"/>
+ <point x="296" y="-25"/>
+ <point x="488" y="-25" type="curve" smooth="yes"/>
+ <point x="713" y="-25"/>
+ <point x="891" y="106"/>
+ <point x="891" y="306" type="curve" smooth="yes"/>
+ <point x="891" y="432"/>
+ <point x="774" y="515"/>
+ <point x="626" y="593" type="curve" smooth="yes"/>
+ <point x="476" y="672"/>
+ <point x="418" y="695"/>
+ <point x="418" y="753" type="curve" smooth="yes"/>
+ <point x="418" y="822"/>
+ <point x="494" y="862"/>
+ <point x="619" y="862" type="curve" smooth="yes"/>
+ <point x="743" y="862"/>
+ <point x="854" y="808"/>
+ <point x="911" y="769" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetglyphorder.ufo/glyphs/L_tnS_mT_.glif b/tests/reference/ufo/psfsetglyphorder.ufo/glyphs/L_tnS_mT_.glif
new file mode 100644
index 0000000..0eddfe9
--- /dev/null
+++ b/tests/reference/ufo/psfsetglyphorder.ufo/glyphs/L_tnS_mT_.glif
@@ -0,0 +1,45 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmT" format="2">
+ <advance width="815"/>
+ <unicode hex="0074"/>
+ <anchor x="455" y="0" name="H"/>
+ <anchor x="390" y="-100" name="L"/>
+ <anchor x="1025" y="1000" name="R"/>
+ <anchor x="605" y="1360" name="U"/>
+ <outline>
+ <contour>
+ <point x="752" y="211" type="line"/>
+ <point x="665" y="169"/>
+ <point x="593" y="134"/>
+ <point x="527" y="134" type="curve" smooth="yes"/>
+ <point x="448" y="134"/>
+ <point x="425" y="188"/>
+ <point x="425" y="247" type="curve" smooth="yes"/>
+ <point x="425" y="274"/>
+ <point x="429" y="301"/>
+ <point x="434" y="326" type="curve" smooth="yes"/>
+ <point x="470" y="519"/>
+ <point x="564" y="843"/>
+ <point x="677" y="1294" type="curve"/>
+ <point x="492" y="1294" type="line"/>
+ <point x="377" y="841"/>
+ <point x="263" y="429"/>
+ <point x="243" y="301" type="curve" smooth="yes"/>
+ <point x="238" y="269"/>
+ <point x="236" y="240"/>
+ <point x="236" y="213" type="curve" smooth="yes"/>
+ <point x="236" y="41"/>
+ <point x="330" y="-25"/>
+ <point x="465" y="-25" type="curve" smooth="yes"/>
+ <point x="535" y="-25"/>
+ <point x="634" y="-6"/>
+ <point x="740" y="52" type="curve"/>
+ </contour>
+ <contour>
+ <point x="177" y="833" type="line"/>
+ <point x="887" y="833" type="line"/>
+ <point x="923" y="975" type="line"/>
+ <point x="213" y="975" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetglyphorder.ufo/glyphs/L_tnS_mU_.glif b/tests/reference/ufo/psfsetglyphorder.ufo/glyphs/L_tnS_mU_.glif
new file mode 100644
index 0000000..0eda3d2
--- /dev/null
+++ b/tests/reference/ufo/psfsetglyphorder.ufo/glyphs/L_tnS_mU_.glif
@@ -0,0 +1,57 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmU" format="2">
+ <advance width="1175"/>
+ <unicode hex="0075"/>
+ <anchor x="465" y="0" name="H"/>
+ <anchor x="504" y="-100" name="L"/>
+ <anchor x="640" y="0" name="O"/>
+ <anchor x="1375" y="1000" name="R"/>
+ <anchor x="804" y="1100" name="U"/>
+ <outline>
+ <contour>
+ <point x="1040" y="0" type="line"/>
+ <point x="1036" y="29"/>
+ <point x="1035" y="62"/>
+ <point x="1035" y="100" type="curve" smooth="yes"/>
+ <point x="1035" y="206"/>
+ <point x="1054" y="341"/>
+ <point x="1080" y="455" type="curve" smooth="yes"/>
+ <point x="1135" y="689"/>
+ <point x="1197" y="895"/>
+ <point x="1205" y="1000" type="curve"/>
+ <point x="1010" y="1000" type="line"/>
+ <point x="1003" y="882"/>
+ <point x="971" y="769"/>
+ <point x="920" y="565" type="curve"/>
+ <point x="827" y="376"/>
+ <point x="573" y="135"/>
+ <point x="475" y="135" type="curve" smooth="yes"/>
+ <point x="409" y="135"/>
+ <point x="365" y="181"/>
+ <point x="365" y="280" type="curve" smooth="yes"/>
+ <point x="365" y="347"/>
+ <point x="407" y="500"/>
+ <point x="459" y="702" type="curve" smooth="yes"/>
+ <point x="494" y="837"/>
+ <point x="515" y="925"/>
+ <point x="520" y="1000" type="curve"/>
+ <point x="325" y="1000" type="line"/>
+ <point x="313" y="882"/>
+ <point x="295" y="809"/>
+ <point x="265" y="685" type="curve" smooth="yes"/>
+ <point x="195" y="395" type="line" smooth="yes"/>
+ <point x="179" y="330"/>
+ <point x="170" y="275"/>
+ <point x="170" y="225" type="curve" smooth="yes"/>
+ <point x="170" y="60"/>
+ <point x="257" y="-25"/>
+ <point x="410" y="-25" type="curve" smooth="yes"/>
+ <point x="551" y="-25"/>
+ <point x="745" y="118"/>
+ <point x="880" y="305" type="curve"/>
+ <point x="861" y="196"/>
+ <point x="860" y="98"/>
+ <point x="860" y="0" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetglyphorder.ufo/glyphs/L_tnS_mV_.glif b/tests/reference/ufo/psfsetglyphorder.ufo/glyphs/L_tnS_mV_.glif
new file mode 100644
index 0000000..33e91d6
--- /dev/null
+++ b/tests/reference/ufo/psfsetglyphorder.ufo/glyphs/L_tnS_mV_.glif
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmV" format="2">
+ <advance width="941"/>
+ <unicode hex="0076"/>
+ <anchor x="359" y="0" name="H"/>
+ <anchor x="350" y="-100" name="L"/>
+ <anchor x="565" y="0" name="O"/>
+ <anchor x="650" y="1100" name="U"/>
+ <outline>
+ <contour>
+ <point x="180" y="1000" type="line"/>
+ <point x="232" y="825"/>
+ <point x="256" y="602"/>
+ <point x="256" y="354" type="curve" smooth="yes"/>
+ <point x="256" y="241"/>
+ <point x="251" y="122"/>
+ <point x="241" y="0" type="curve"/>
+ <point x="441" y="0" type="line"/>
+ <point x="744" y="336"/>
+ <point x="1056" y="765"/>
+ <point x="1056" y="1000" type="curve"/>
+ <point x="856" y="1000" type="line"/>
+ <point x="856" y="769"/>
+ <point x="606" y="394"/>
+ <point x="404" y="176" type="curve"/>
+ <point x="421" y="277"/>
+ <point x="429" y="402"/>
+ <point x="429" y="526" type="curve" smooth="yes"/>
+ <point x="429" y="707"/>
+ <point x="412" y="887"/>
+ <point x="380" y="1000" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetglyphorder.ufo/glyphs/L_tnS_mW_.glif b/tests/reference/ufo/psfsetglyphorder.ufo/glyphs/L_tnS_mW_.glif
new file mode 100644
index 0000000..1daea7c
--- /dev/null
+++ b/tests/reference/ufo/psfsetglyphorder.ufo/glyphs/L_tnS_mW_.glif
@@ -0,0 +1,50 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmW" format="2">
+ <advance width="1555"/>
+ <unicode hex="0077"/>
+ <anchor x="690" y="-100" name="L"/>
+ <anchor x="990" y="1100" name="U"/>
+ <outline>
+ <contour>
+ <point x="858" y="1000" type="line"/>
+ <point x="743" y="739"/>
+ <point x="588" y="466"/>
+ <point x="388" y="181" type="curve"/>
+ <point x="417" y="339"/>
+ <point x="430" y="500"/>
+ <point x="430" y="644" type="curve" smooth="yes"/>
+ <point x="430" y="784"/>
+ <point x="418" y="908"/>
+ <point x="395" y="1000" type="curve"/>
+ <point x="195" y="1000" type="line"/>
+ <point x="234" y="873"/>
+ <point x="256" y="688"/>
+ <point x="256" y="472" type="curve" smooth="yes"/>
+ <point x="256" y="326"/>
+ <point x="246" y="166"/>
+ <point x="225" y="0" type="curve"/>
+ <point x="425" y="0" type="line"/>
+ <point x="632" y="298"/>
+ <point x="825" y="583"/>
+ <point x="896" y="765" type="curve"/>
+ <point x="920" y="478"/>
+ <point x="912" y="233"/>
+ <point x="915" y="0" type="curve"/>
+ <point x="1115" y="0" type="line"/>
+ <point x="1362" y="330"/>
+ <point x="1642" y="777"/>
+ <point x="1645" y="1000" type="curve"/>
+ <point x="1445" y="1000" type="line"/>
+ <point x="1445" y="990" type="line"/>
+ <point x="1445" y="797"/>
+ <point x="1242" y="417"/>
+ <point x="1063" y="181" type="curve"/>
+ <point x="1064" y="221"/>
+ <point x="1064" y="260"/>
+ <point x="1064" y="298" type="curve" smooth="yes"/>
+ <point x="1064" y="577"/>
+ <point x="1046" y="811"/>
+ <point x="1020" y="1000" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetglyphorder.ufo/glyphs/L_tnS_mX_.glif b/tests/reference/ufo/psfsetglyphorder.ufo/glyphs/L_tnS_mX_.glif
new file mode 100644
index 0000000..5508ff9
--- /dev/null
+++ b/tests/reference/ufo/psfsetglyphorder.ufo/glyphs/L_tnS_mX_.glif
@@ -0,0 +1,40 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmX" format="2">
+ <advance width="1009"/>
+ <unicode hex="0078"/>
+ <anchor x="840" y="0" name="H"/>
+ <anchor x="457" y="-100" name="L"/>
+ <anchor x="657" y="1100" name="U"/>
+ <outline>
+ <contour>
+ <point x="945" y="0" type="line"/>
+ <point x="765" y="133"/>
+ <point x="558" y="867"/>
+ <point x="439" y="1000" type="curve"/>
+ <point x="181" y="1000" type="line"/>
+ <point x="410" y="832"/>
+ <point x="578" y="141"/>
+ <point x="698" y="0" type="curve"/>
+ </contour>
+ <contour>
+ <point x="504" y="572" type="line"/>
+ <point x="286" y="463"/>
+ <point x="57" y="230"/>
+ <point x="30" y="0" type="curve"/>
+ <point x="230" y="0" type="line"/>
+ <point x="231" y="156"/>
+ <point x="375" y="380"/>
+ <point x="563" y="467" type="curve"/>
+ </contour>
+ <contour>
+ <point x="659" y="471" type="line"/>
+ <point x="838" y="591"/>
+ <point x="1092" y="798"/>
+ <point x="1099" y="1000" type="curve"/>
+ <point x="889" y="1000" type="line"/>
+ <point x="883" y="842"/>
+ <point x="758" y="675"/>
+ <point x="601" y="581" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetglyphorder.ufo/glyphs/L_tnS_mY_.glif b/tests/reference/ufo/psfsetglyphorder.ufo/glyphs/L_tnS_mY_.glif
new file mode 100644
index 0000000..b9000c5
--- /dev/null
+++ b/tests/reference/ufo/psfsetglyphorder.ufo/glyphs/L_tnS_mY_.glif
@@ -0,0 +1,45 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmY" format="2">
+ <advance width="976"/>
+ <unicode hex="0079"/>
+ <anchor x="710" y="-100" name="L"/>
+ <anchor x="1270" y="1000" name="R"/>
+ <anchor x="630" y="1100" name="U"/>
+ <outline>
+ <contour>
+ <point x="132" y="1000" type="line"/>
+ <point x="270" y="825"/>
+ <point x="398" y="406"/>
+ <point x="403" y="-16" type="curve"/>
+ <point x="263" y="-232"/>
+ <point x="145" y="-295"/>
+ <point x="64" y="-295" type="curve" smooth="yes"/>
+ <point x="-2" y="-295"/>
+ <point x="-69" y="-254"/>
+ <point x="-102" y="-220" type="curve"/>
+ <point x="-200" y="-377" type="line"/>
+ <point x="-141" y="-430"/>
+ <point x="-68" y="-465"/>
+ <point x="23" y="-465" type="curve" smooth="yes"/>
+ <point x="193" y="-465"/>
+ <point x="369" y="-371"/>
+ <point x="609" y="0" type="curve" smooth="yes"/>
+ <point x="877" y="414"/>
+ <point x="1056" y="808"/>
+ <point x="1056" y="964" type="curve" smooth="yes"/>
+ <point x="1056" y="978"/>
+ <point x="1055" y="990"/>
+ <point x="1052" y="1000" type="curve"/>
+ <point x="852" y="1000" type="line"/>
+ <point x="856" y="984"/>
+ <point x="858" y="967"/>
+ <point x="858" y="946" type="curve" smooth="yes"/>
+ <point x="858" y="783"/>
+ <point x="722" y="472"/>
+ <point x="548" y="189" type="curve"/>
+ <point x="548" y="484"/>
+ <point x="447" y="866"/>
+ <point x="347" y="1000" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetglyphorder.ufo/glyphs/N_onB_reakingH_yphen.glif b/tests/reference/ufo/psfsetglyphorder.ufo/glyphs/N_onB_reakingH_yphen.glif
new file mode 100644
index 0000000..e7d9c06
--- /dev/null
+++ b/tests/reference/ufo/psfsetglyphorder.ufo/glyphs/N_onB_reakingH_yphen.glif
@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="NonBreakingHyphen" format="2">
+ <advance width="840"/>
+ <unicode hex="2011"/>
+ <anchor x="645" y="1100" name="U"/>
+ <outline>
+ <component base="HyphenMinus"/>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetglyphorder.ufo/glyphs/N_umS_gn.glif b/tests/reference/ufo/psfsetglyphorder.ufo/glyphs/N_umS_gn.glif
new file mode 100644
index 0000000..b7506f7
--- /dev/null
+++ b/tests/reference/ufo/psfsetglyphorder.ufo/glyphs/N_umS_gn.glif
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="NumSgn" format="2">
+ <advance width="1180"/>
+ <unicode hex="0023"/>
+ <outline>
+ <contour>
+ <point x="739" y="1333" type="line"/>
+ <point x="91" y="98" type="line"/>
+ <point x="261" y="98" type="line"/>
+ <point x="909" y="1333" type="line"/>
+ </contour>
+ <contour>
+ <point x="80" y="465" type="line"/>
+ <point x="1171" y="465" type="line"/>
+ <point x="1208" y="612" type="line"/>
+ <point x="117" y="612" type="line"/>
+ </contour>
+ <contour>
+ <point x="234" y="843" type="line"/>
+ <point x="1325" y="843" type="line"/>
+ <point x="1361" y="990" type="line"/>
+ <point x="270" y="990" type="line"/>
+ </contour>
+ <contour>
+ <point x="1164" y="1333" type="line"/>
+ <point x="516" y="98" type="line"/>
+ <point x="686" y="98" type="line"/>
+ <point x="1334" y="1333" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetglyphorder.ufo/glyphs/P_ercentS_gn.glif b/tests/reference/ufo/psfsetglyphorder.ufo/glyphs/P_ercentS_gn.glif
new file mode 100644
index 0000000..84241ea
--- /dev/null
+++ b/tests/reference/ufo/psfsetglyphorder.ufo/glyphs/P_ercentS_gn.glif
@@ -0,0 +1,93 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="PercentSgn" format="2">
+ <advance width="1506"/>
+ <unicode hex="0025"/>
+ <outline>
+ <contour>
+ <point x="1300" y="349" type="curve" smooth="yes"/>
+ <point x="1255" y="168"/>
+ <point x="1204" y="113"/>
+ <point x="1118" y="113" type="curve" smooth="yes"/>
+ <point x="1056" y="113"/>
+ <point x="1021" y="148"/>
+ <point x="1021" y="235" type="curve" smooth="yes"/>
+ <point x="1021" y="274"/>
+ <point x="1028" y="322"/>
+ <point x="1043" y="383" type="curve" smooth="yes"/>
+ <point x="1088" y="564"/>
+ <point x="1136" y="617"/>
+ <point x="1223" y="617" type="curve" smooth="yes"/>
+ <point x="1286" y="617"/>
+ <point x="1322" y="582"/>
+ <point x="1322" y="496" type="curve" smooth="yes"/>
+ <point x="1322" y="458"/>
+ <point x="1315" y="409"/>
+ </contour>
+ <contour>
+ <point x="1468" y="361" type="curve" smooth="yes"/>
+ <point x="1483" y="419"/>
+ <point x="1489" y="470"/>
+ <point x="1489" y="515" type="curve" smooth="yes"/>
+ <point x="1489" y="677"/>
+ <point x="1400" y="755"/>
+ <point x="1263" y="755" type="curve" smooth="yes"/>
+ <point x="1089" y="755"/>
+ <point x="945" y="647"/>
+ <point x="876" y="371" type="curve" smooth="yes"/>
+ <point x="861" y="310"/>
+ <point x="854" y="256"/>
+ <point x="854" y="210" type="curve" smooth="yes"/>
+ <point x="854" y="47"/>
+ <point x="943" y="-25"/>
+ <point x="1079" y="-25" type="curve" smooth="yes"/>
+ <point x="1254" y="-25"/>
+ <point x="1396" y="72"/>
+ </contour>
+ <contour>
+ <point x="1369" y="1450" type="line"/>
+ <point x="219" y="-25" type="line"/>
+ <point x="397" y="-25" type="line"/>
+ <point x="1545" y="1450" type="line"/>
+ </contour>
+ <contour>
+ <point x="717" y="1044" type="curve" smooth="yes"/>
+ <point x="672" y="864"/>
+ <point x="621" y="809"/>
+ <point x="535" y="809" type="curve" smooth="yes"/>
+ <point x="474" y="809"/>
+ <point x="439" y="844"/>
+ <point x="439" y="930" type="curve" smooth="yes"/>
+ <point x="439" y="969"/>
+ <point x="446" y="1018"/>
+ <point x="461" y="1079" type="curve" smooth="yes"/>
+ <point x="506" y="1260"/>
+ <point x="554" y="1313"/>
+ <point x="641" y="1313" type="curve" smooth="yes"/>
+ <point x="704" y="1313"/>
+ <point x="739" y="1278"/>
+ <point x="739" y="1192" type="curve" smooth="yes"/>
+ <point x="739" y="1153"/>
+ <point x="732" y="1105"/>
+ </contour>
+ <contour>
+ <point x="886" y="1057" type="curve" smooth="yes"/>
+ <point x="900" y="1114"/>
+ <point x="907" y="1166"/>
+ <point x="907" y="1210" type="curve" smooth="yes"/>
+ <point x="907" y="1373"/>
+ <point x="817" y="1450"/>
+ <point x="680" y="1450" type="curve" smooth="yes"/>
+ <point x="506" y="1450"/>
+ <point x="362" y="1343"/>
+ <point x="293" y="1066" type="curve" smooth="yes"/>
+ <point x="278" y="1005"/>
+ <point x="271" y="952"/>
+ <point x="271" y="906" type="curve" smooth="yes"/>
+ <point x="271" y="743"/>
+ <point x="360" y="671"/>
+ <point x="497" y="671" type="curve" smooth="yes"/>
+ <point x="672" y="671"/>
+ <point x="813" y="768"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetglyphorder.ufo/glyphs/P_lusS_gn.glif b/tests/reference/ufo/psfsetglyphorder.ufo/glyphs/P_lusS_gn.glif
new file mode 100644
index 0000000..8c4577e
--- /dev/null
+++ b/tests/reference/ufo/psfsetglyphorder.ufo/glyphs/P_lusS_gn.glif
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="PlusSgn" format="2">
+ <advance width="1180"/>
+ <unicode hex="002B"/>
+ <outline>
+ <contour>
+ <point x="748" y="1156" type="line"/>
+ <point x="529" y="279" type="line"/>
+ <point x="684" y="279" type="line"/>
+ <point x="903" y="1156" type="line"/>
+ </contour>
+ <contour>
+ <point x="256" y="647" type="line"/>
+ <point x="1146" y="647" type="line"/>
+ <point x="1182" y="794" type="line"/>
+ <point x="292" y="794" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetglyphorder.ufo/glyphs/Q_stnM_rk.glif b/tests/reference/ufo/psfsetglyphorder.ufo/glyphs/Q_stnM_rk.glif
new file mode 100644
index 0000000..8b14a6c
--- /dev/null
+++ b/tests/reference/ufo/psfsetglyphorder.ufo/glyphs/Q_stnM_rk.glif
@@ -0,0 +1,49 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="QstnMrk" format="2">
+ <advance width="1030"/>
+ <unicode hex="003F"/>
+ <outline>
+ <contour>
+ <point x="419" y="1226" type="line"/>
+ <point x="514" y="1303"/>
+ <point x="615" y="1338"/>
+ <point x="685" y="1338" type="curve" smooth="yes"/>
+ <point x="800" y="1338"/>
+ <point x="858" y="1294"/>
+ <point x="858" y="1222" type="curve" smooth="yes"/>
+ <point x="858" y="1122"/>
+ <point x="713" y="1017"/>
+ <point x="654" y="960" type="curve" smooth="yes"/>
+ <point x="538" y="850"/>
+ <point x="473" y="715"/>
+ <point x="402" y="431" type="curve"/>
+ <point x="587" y="431" type="line"/>
+ <point x="656" y="707"/>
+ <point x="697" y="778"/>
+ <point x="831" y="901" type="curve" smooth="yes"/>
+ <point x="949" y="1010"/>
+ <point x="1072" y="1146"/>
+ <point x="1072" y="1272" type="curve" smooth="yes"/>
+ <point x="1072" y="1409"/>
+ <point x="947" y="1509"/>
+ <point x="746" y="1509" type="curve" smooth="yes"/>
+ <point x="631" y="1509"/>
+ <point x="500" y="1463"/>
+ <point x="419" y="1401" type="curve"/>
+ </contour>
+ <contour>
+ <point x="278" y="90" type="curve" smooth="yes"/>
+ <point x="278" y="28"/>
+ <point x="328" y="-25"/>
+ <point x="393" y="-25" type="curve" smooth="yes"/>
+ <point x="477" y="-25"/>
+ <point x="554" y="45"/>
+ <point x="554" y="125" type="curve" smooth="yes"/>
+ <point x="554" y="186"/>
+ <point x="504" y="240"/>
+ <point x="439" y="240" type="curve" smooth="yes"/>
+ <point x="355" y="240"/>
+ <point x="278" y="170"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetglyphorder.ufo/glyphs/Q_uotM_rk.glif b/tests/reference/ufo/psfsetglyphorder.ufo/glyphs/Q_uotM_rk.glif
new file mode 100644
index 0000000..4a8357b
--- /dev/null
+++ b/tests/reference/ufo/psfsetglyphorder.ufo/glyphs/Q_uotM_rk.glif
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="QuotMrk" format="2">
+ <advance width="1005"/>
+ <unicode hex="0022"/>
+ <outline>
+ <contour>
+ <point x="600" y="1024" type="line"/>
+ <point x="639" y="1162"/>
+ <point x="683" y="1312"/>
+ <point x="772" y="1553" type="curve"/>
+ <point x="567" y="1553" type="line"/>
+ <point x="538" y="1312"/>
+ <point x="505" y="1162"/>
+ <point x="475" y="1024" type="curve"/>
+ </contour>
+ <contour>
+ <point x="940" y="1024" type="line"/>
+ <point x="979" y="1162"/>
+ <point x="1023" y="1312"/>
+ <point x="1112" y="1553" type="curve"/>
+ <point x="907" y="1553" type="line"/>
+ <point x="878" y="1312"/>
+ <point x="845" y="1162"/>
+ <point x="815" y="1024" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetglyphorder.ufo/glyphs/R_everseS_olidus.glif b/tests/reference/ufo/psfsetglyphorder.ufo/glyphs/R_everseS_olidus.glif
new file mode 100644
index 0000000..f146267
--- /dev/null
+++ b/tests/reference/ufo/psfsetglyphorder.ufo/glyphs/R_everseS_olidus.glif
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="ReverseSolidus" format="2">
+ <advance width="1005"/>
+ <unicode hex="005C"/>
+ <outline>
+ <contour>
+ <point x="473" y="1538" type="line"/>
+ <point x="656" y="-123" type="line"/>
+ <point x="799" y="-93" type="line"/>
+ <point x="620" y="1568" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetglyphorder.ufo/glyphs/R_tC_urlyB_rac.glif b/tests/reference/ufo/psfsetglyphorder.ufo/glyphs/R_tC_urlyB_rac.glif
new file mode 100644
index 0000000..82df531
--- /dev/null
+++ b/tests/reference/ufo/psfsetglyphorder.ufo/glyphs/R_tC_urlyB_rac.glif
@@ -0,0 +1,50 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="RtCurlyBrac" format="2">
+ <advance width="980"/>
+ <unicode hex="007D"/>
+ <outline>
+ <contour>
+ <point x="466" y="1470" type="line"/>
+ <point x="513" y="1452"/>
+ <point x="653" y="1397"/>
+ <point x="653" y="1366" type="curve" smooth="yes"/>
+ <point x="653" y="1238"/>
+ <point x="531" y="801"/>
+ <point x="531" y="737" type="curve" smooth="yes"/>
+ <point x="531" y="701"/>
+ <point x="660" y="627"/>
+ <point x="660" y="603" type="curve" smooth="yes"/>
+ <point x="660" y="585"/>
+ <point x="496" y="511"/>
+ <point x="468" y="475" type="curve" smooth="yes"/>
+ <point x="439" y="438"/>
+ <point x="312" y="-121"/>
+ <point x="268" y="-167" type="curve" smooth="yes"/>
+ <point x="241" y="-194"/>
+ <point x="106" y="-242"/>
+ <point x="33" y="-265" type="curve"/>
+ <point x="39" y="-402" type="line"/>
+ <point x="150" y="-375"/>
+ <point x="324" y="-323"/>
+ <point x="375" y="-279" type="curve" smooth="yes"/>
+ <point x="465" y="-201"/>
+ <point x="608" y="410"/>
+ <point x="639" y="441" type="curve" smooth="yes"/>
+ <point x="675" y="476"/>
+ <point x="880" y="571"/>
+ <point x="880" y="607" type="curve" smooth="yes"/>
+ <point x="880" y="639"/>
+ <point x="719" y="740"/>
+ <point x="719" y="771" type="curve" smooth="yes"/>
+ <point x="719" y="839"/>
+ <point x="825" y="1259"/>
+ <point x="825" y="1425" type="curve" smooth="yes"/>
+ <point x="825" y="1453"/>
+ <point x="822" y="1474"/>
+ <point x="815" y="1485" type="curve" smooth="yes"/>
+ <point x="786" y="1529"/>
+ <point x="638" y="1581"/>
+ <point x="540" y="1607" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetglyphorder.ufo/glyphs/R_tP_aren.glif b/tests/reference/ufo/psfsetglyphorder.ufo/glyphs/R_tP_aren.glif
new file mode 100644
index 0000000..3950e09
--- /dev/null
+++ b/tests/reference/ufo/psfsetglyphorder.ufo/glyphs/R_tP_aren.glif
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="RtParen" format="2">
+ <advance width="775"/>
+ <unicode hex="0029"/>
+ <outline>
+ <contour>
+ <point x="467" y="1455" type="line"/>
+ <point x="578" y="1327"/>
+ <point x="628" y="1146"/>
+ <point x="628" y="946" type="curve" smooth="yes"/>
+ <point x="628" y="832"/>
+ <point x="612" y="713"/>
+ <point x="582" y="593" type="curve" smooth="yes"/>
+ <point x="497" y="252"/>
+ <point x="328" y="-8"/>
+ <point x="40" y="-260" type="curve"/>
+ <point x="99" y="-402" type="line"/>
+ <point x="444" y="-123"/>
+ <point x="673" y="194"/>
+ <point x="772" y="593" type="curve" smooth="yes"/>
+ <point x="804" y="719"/>
+ <point x="819" y="843"/>
+ <point x="819" y="959" type="curve" smooth="yes"/>
+ <point x="819" y="1236"/>
+ <point x="733" y="1472"/>
+ <point x="580" y="1607" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetglyphorder.ufo/glyphs/R_tS_qrB_rac.glif b/tests/reference/ufo/psfsetglyphorder.ufo/glyphs/R_tS_qrB_rac.glif
new file mode 100644
index 0000000..4c13a82
--- /dev/null
+++ b/tests/reference/ufo/psfsetglyphorder.ufo/glyphs/R_tS_qrB_rac.glif
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="RtSqrBrac" format="2">
+ <advance width="770"/>
+ <unicode hex="005D"/>
+ <outline>
+ <contour>
+ <point x="434" y="-402" type="line"/>
+ <point x="920" y="1568" type="line"/>
+ <point x="480" y="1568" type="line"/>
+ <point x="444" y="1421" type="line"/>
+ <point x="699" y="1421" type="line"/>
+ <point x="286" y="-255" type="line"/>
+ <point x="31" y="-255" type="line"/>
+ <point x="-6" y="-402" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetglyphorder.ufo/glyphs/S_emicolon.glif b/tests/reference/ufo/psfsetglyphorder.ufo/glyphs/S_emicolon.glif
new file mode 100644
index 0000000..be971ac
--- /dev/null
+++ b/tests/reference/ufo/psfsetglyphorder.ufo/glyphs/S_emicolon.glif
@@ -0,0 +1,38 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="Semicolon" format="2">
+ <advance width="630"/>
+ <unicode hex="003B"/>
+ <outline>
+ <contour>
+ <point x="314" y="758" type="curve" smooth="yes"/>
+ <point x="314" y="696"/>
+ <point x="365" y="642"/>
+ <point x="430" y="642" type="curve" smooth="yes"/>
+ <point x="514" y="642"/>
+ <point x="590" y="712"/>
+ <point x="590" y="792" type="curve" smooth="yes"/>
+ <point x="590" y="854"/>
+ <point x="540" y="907"/>
+ <point x="476" y="907" type="curve" smooth="yes"/>
+ <point x="393" y="907"/>
+ <point x="314" y="837"/>
+ </contour>
+ <contour>
+ <point x="137" y="49" type="line"/>
+ <point x="277" y="49" type="line"/>
+ <point x="252" y="-50"/>
+ <point x="145" y="-169"/>
+ <point x="73" y="-225" type="curve"/>
+ <point x="163" y="-265" type="line"/>
+ <point x="280" y="-175"/>
+ <point x="431" y="-28"/>
+ <point x="431" y="118" type="curve" smooth="yes"/>
+ <point x="431" y="193"/>
+ <point x="378" y="245"/>
+ <point x="311" y="245" type="curve" smooth="yes"/>
+ <point x="254" y="245"/>
+ <point x="190" y="209"/>
+ <point x="161" y="147" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetglyphorder.ufo/glyphs/S_olidus.glif b/tests/reference/ufo/psfsetglyphorder.ufo/glyphs/S_olidus.glif
new file mode 100644
index 0000000..589697b
--- /dev/null
+++ b/tests/reference/ufo/psfsetglyphorder.ufo/glyphs/S_olidus.glif
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="Solidus" format="2">
+ <advance width="980"/>
+ <unicode hex="002F"/>
+ <outline>
+ <contour>
+ <point x="1160" y="1568" type="line"/>
+ <point x="-119" y="-240" type="line"/>
+ <point x="50" y="-240" type="line"/>
+ <point x="1330" y="1568" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetglyphorder.ufo/glyphs/S_pace.glif b/tests/reference/ufo/psfsetglyphorder.ufo/glyphs/S_pace.glif
new file mode 100644
index 0000000..c49f0f2
--- /dev/null
+++ b/tests/reference/ufo/psfsetglyphorder.ufo/glyphs/S_pace.glif
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="Space" format="2">
+ <advance width="530"/>
+ <unicode hex="0020"/>
+ <outline/>
+</glyph>
diff --git a/tests/reference/ufo/psfsetglyphorder.ufo/glyphs/T_ilde.glif b/tests/reference/ufo/psfsetglyphorder.ufo/glyphs/T_ilde.glif
new file mode 100644
index 0000000..bf260b8
--- /dev/null
+++ b/tests/reference/ufo/psfsetglyphorder.ufo/glyphs/T_ilde.glif
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="Tilde" format="2">
+ <advance width="1095"/>
+ <unicode hex="007E"/>
+ <outline>
+ <contour>
+ <point x="156" y="368" type="line"/>
+ <point x="173" y="416"/>
+ <point x="215" y="456"/>
+ <point x="293" y="456" type="curve" smooth="yes"/>
+ <point x="468" y="456"/>
+ <point x="643" y="353"/>
+ <point x="873" y="353" type="curve" smooth="yes"/>
+ <point x="1032" y="353"/>
+ <point x="1137" y="472"/>
+ <point x="1169" y="598" type="curve"/>
+ <point x="1064" y="598" type="line"/>
+ <point x="1045" y="553"/>
+ <point x="1002" y="500"/>
+ <point x="919" y="500" type="curve" smooth="yes"/>
+ <point x="683" y="500"/>
+ <point x="551" y="603"/>
+ <point x="330" y="603" type="curve" smooth="yes"/>
+ <point x="184" y="603"/>
+ <point x="81" y="487"/>
+ <point x="51" y="368" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetglyphorder.ufo/glyphs/V_ertL_ine.glif b/tests/reference/ufo/psfsetglyphorder.ufo/glyphs/V_ertL_ine.glif
new file mode 100644
index 0000000..445d622
--- /dev/null
+++ b/tests/reference/ufo/psfsetglyphorder.ufo/glyphs/V_ertL_ine.glif
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="VertLine" format="2">
+ <advance width="670"/>
+ <unicode hex="007C"/>
+ <outline>
+ <contour>
+ <point x="602" y="1578" type="line"/>
+ <point x="112" y="-392" type="line"/>
+ <point x="262" y="-392" type="line"/>
+ <point x="752" y="1578" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetglyphorder.ufo/glyphs/_notdef.glif b/tests/reference/ufo/psfsetglyphorder.ufo/glyphs/_notdef.glif
new file mode 100644
index 0000000..a3e9354
--- /dev/null
+++ b/tests/reference/ufo/psfsetglyphorder.ufo/glyphs/_notdef.glif
@@ -0,0 +1,18 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name=".notdef" format="2">
+ <advance width="1400"/>
+ <outline>
+ <contour>
+ <point x="100" y="0" type="line"/>
+ <point x="1300" y="0" type="line"/>
+ <point x="1300" y="1800" type="line"/>
+ <point x="100" y="1800" type="line"/>
+ </contour>
+ <contour>
+ <point x="150" y="1750" type="line"/>
+ <point x="1250" y="1750" type="line"/>
+ <point x="1250" y="50" type="line"/>
+ <point x="150" y="50" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetglyphorder.ufo/glyphs/_null.glif b/tests/reference/ufo/psfsetglyphorder.ufo/glyphs/_null.glif
new file mode 100644
index 0000000..0b9caa6
--- /dev/null
+++ b/tests/reference/ufo/psfsetglyphorder.ufo/glyphs/_null.glif
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name=".null" format="2">
+ <outline/>
+</glyph>
diff --git a/tests/reference/ufo/psfsetglyphorder.ufo/glyphs/contents.plist b/tests/reference/ufo/psfsetglyphorder.ufo/glyphs/contents.plist
new file mode 100644
index 0000000..ad2aa41
--- /dev/null
+++ b/tests/reference/ufo/psfsetglyphorder.ufo/glyphs/contents.plist
@@ -0,0 +1,232 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+ <key>.notdef</key>
+ <string>_notdef.glif</string>
+ <key>.null</key>
+ <string>_null.glif</string>
+ <key>Ampersand</key>
+ <string>A_mpersand.glif</string>
+ <key>Apos</key>
+ <string>A_pos.glif</string>
+ <key>Asterisk</key>
+ <string>A_sterisk.glif</string>
+ <key>AtSgn</key>
+ <string>A_tS_gn.glif</string>
+ <key>CircumAccent</key>
+ <string>C_ircumA_ccent.glif</string>
+ <key>Colon</key>
+ <string>C_olon.glif</string>
+ <key>CombAcute</key>
+ <string>C_ombA_cute.glif</string>
+ <key>CombCircum</key>
+ <string>C_ombC_ircum.glif</string>
+ <key>CombDiaer</key>
+ <string>C_ombD_iaer.glif</string>
+ <key>CombGrave</key>
+ <string>C_ombG_rave.glif</string>
+ <key>CombRingAbv</key>
+ <string>C_ombR_ingA_bv.glif</string>
+ <key>CombTilde</key>
+ <string>C_ombT_ilde.glif</string>
+ <key>Comma</key>
+ <string>C_omma.glif</string>
+ <key>DigitEight</key>
+ <string>D_igitE_ight.glif</string>
+ <key>DigitFive</key>
+ <string>D_igitF_ive.glif</string>
+ <key>DigitFour</key>
+ <string>D_igitF_our.glif</string>
+ <key>DigitNine</key>
+ <string>D_igitN_ine.glif</string>
+ <key>DigitOne</key>
+ <string>D_igitO_ne.glif</string>
+ <key>DigitSeven</key>
+ <string>D_igitS_even.glif</string>
+ <key>DigitSix</key>
+ <string>D_igitS_ix.glif</string>
+ <key>DigitThree</key>
+ <string>D_igitT_hree.glif</string>
+ <key>DigitTwo</key>
+ <string>D_igitT_wo.glif</string>
+ <key>DigitZero</key>
+ <string>D_igitZ_ero.glif</string>
+ <key>DollarSgn</key>
+ <string>D_ollarS_gn.glif</string>
+ <key>DottedCirc</key>
+ <string>D_ottedC_irc.glif</string>
+ <key>EqSgn</key>
+ <string>E_qS_gn.glif</string>
+ <key>ExclamationMrk</key>
+ <string>E_xclamationM_rk.glif</string>
+ <key>FullStop</key>
+ <string>F_ullS_top.glif</string>
+ <key>GTSgn</key>
+ <string>G_T_S_gn.glif</string>
+ <key>GraveAccent</key>
+ <string>G_raveA_ccent.glif</string>
+ <key>Hyphen</key>
+ <string>H_yphen.glif</string>
+ <key>HyphenMinus</key>
+ <string>H_yphenM_inus.glif</string>
+ <key>Hyphen_Soft</key>
+ <string>H_yphen_S_oft.glif</string>
+ <key>LTSgn</key>
+ <string>L_T_S_gn.glif</string>
+ <key>LftCurlyBrac</key>
+ <string>L_ftC_urlyB_rac.glif</string>
+ <key>LftParen</key>
+ <string>L_ftP_aren.glif</string>
+ <key>LftSqrBrac</key>
+ <string>L_ftS_qrB_rac.glif</string>
+ <key>LowLine</key>
+ <string>L_owL_ine.glif</string>
+ <key>LtnCapA</key>
+ <string>L_tnC_apA_.glif</string>
+ <key>LtnCapADiaer</key>
+ <string>L_tnC_apA_D_iaer.glif</string>
+ <key>LtnCapB</key>
+ <string>L_tnC_apB_.glif</string>
+ <key>LtnCapC</key>
+ <string>L_tnC_apC_.glif</string>
+ <key>LtnCapD</key>
+ <string>L_tnC_apD_.glif</string>
+ <key>LtnCapE</key>
+ <string>L_tnC_apE_.glif</string>
+ <key>LtnCapF</key>
+ <string>L_tnC_apF_.glif</string>
+ <key>LtnCapG</key>
+ <string>L_tnC_apG_.glif</string>
+ <key>LtnCapH</key>
+ <string>L_tnC_apH_.glif</string>
+ <key>LtnCapI</key>
+ <string>L_tnC_apI_.glif</string>
+ <key>LtnCapJ</key>
+ <string>L_tnC_apJ_.glif</string>
+ <key>LtnCapK</key>
+ <string>L_tnC_apK_.glif</string>
+ <key>LtnCapL</key>
+ <string>L_tnC_apL_.glif</string>
+ <key>LtnCapM</key>
+ <string>L_tnC_apM_.glif</string>
+ <key>LtnCapN</key>
+ <string>L_tnC_apN_.glif</string>
+ <key>LtnCapO</key>
+ <string>L_tnC_apO_.glif</string>
+ <key>LtnCapP</key>
+ <string>L_tnC_apP_.glif</string>
+ <key>LtnCapQ</key>
+ <string>L_tnC_apQ_.glif</string>
+ <key>LtnCapR</key>
+ <string>L_tnC_apR_.glif</string>
+ <key>LtnCapS</key>
+ <string>L_tnC_apS_.glif</string>
+ <key>LtnCapT</key>
+ <string>L_tnC_apT_.glif</string>
+ <key>LtnCapU</key>
+ <string>L_tnC_apU_.glif</string>
+ <key>LtnCapV</key>
+ <string>L_tnC_apV_.glif</string>
+ <key>LtnCapW</key>
+ <string>L_tnC_apW_.glif</string>
+ <key>LtnCapX</key>
+ <string>L_tnC_apX_.glif</string>
+ <key>LtnCapY</key>
+ <string>L_tnC_apY_.glif</string>
+ <key>LtnSmA</key>
+ <string>L_tnS_mA_.glif</string>
+ <key>LtnSmAAcute</key>
+ <string>L_tnS_mA_A_cute.glif</string>
+ <key>LtnSmACircum</key>
+ <string>L_tnS_mA_C_ircum.glif</string>
+ <key>LtnSmADiaer</key>
+ <string>L_tnS_mA_D_iaer.glif</string>
+ <key>LtnSmAGrave</key>
+ <string>L_tnS_mA_G_rave.glif</string>
+ <key>LtnSmARingAbv</key>
+ <string>L_tnS_mA_R_ingA_bv.glif</string>
+ <key>LtnSmATilde</key>
+ <string>L_tnS_mA_T_ilde.glif</string>
+ <key>LtnSmB</key>
+ <string>L_tnS_mB_.glif</string>
+ <key>LtnSmC</key>
+ <string>L_tnS_mC_.glif</string>
+ <key>LtnSmD</key>
+ <string>L_tnS_mD_.glif</string>
+ <key>LtnSmE</key>
+ <string>L_tnS_mE_.glif</string>
+ <key>LtnSmF</key>
+ <string>L_tnS_mF_.glif</string>
+ <key>LtnSmG</key>
+ <string>L_tnS_mG_.glif</string>
+ <key>LtnSmH</key>
+ <string>L_tnS_mH_.glif</string>
+ <key>LtnSmI</key>
+ <string>L_tnS_mI_.glif</string>
+ <key>LtnSmJ</key>
+ <string>L_tnS_mJ_.glif</string>
+ <key>LtnSmK</key>
+ <string>L_tnS_mK_.glif</string>
+ <key>LtnSmL</key>
+ <string>L_tnS_mL_.glif</string>
+ <key>LtnSmM</key>
+ <string>L_tnS_mM_.glif</string>
+ <key>LtnSmN</key>
+ <string>L_tnS_mN_.glif</string>
+ <key>LtnSmO</key>
+ <string>L_tnS_mO_.glif</string>
+ <key>LtnSmP</key>
+ <string>L_tnS_mP_.glif</string>
+ <key>LtnSmQ</key>
+ <string>L_tnS_mQ_.glif</string>
+ <key>LtnSmR</key>
+ <string>L_tnS_mR_.glif</string>
+ <key>LtnSmS</key>
+ <string>L_tnS_mS_.glif</string>
+ <key>LtnSmT</key>
+ <string>L_tnS_mT_.glif</string>
+ <key>LtnSmU</key>
+ <string>L_tnS_mU_.glif</string>
+ <key>LtnSmV</key>
+ <string>L_tnS_mV_.glif</string>
+ <key>LtnSmW</key>
+ <string>L_tnS_mW_.glif</string>
+ <key>LtnSmX</key>
+ <string>L_tnS_mX_.glif</string>
+ <key>LtnSmY</key>
+ <string>L_tnS_mY_.glif</string>
+ <key>NonBreakingHyphen</key>
+ <string>N_onB_reakingH_yphen.glif</string>
+ <key>NumSgn</key>
+ <string>N_umS_gn.glif</string>
+ <key>PercentSgn</key>
+ <string>P_ercentS_gn.glif</string>
+ <key>PlusSgn</key>
+ <string>P_lusS_gn.glif</string>
+ <key>QstnMrk</key>
+ <string>Q_stnM_rk.glif</string>
+ <key>QuotMrk</key>
+ <string>Q_uotM_rk.glif</string>
+ <key>ReverseSolidus</key>
+ <string>R_everseS_olidus.glif</string>
+ <key>RtCurlyBrac</key>
+ <string>R_tC_urlyB_rac.glif</string>
+ <key>RtParen</key>
+ <string>R_tP_aren.glif</string>
+ <key>RtSqrBrac</key>
+ <string>R_tS_qrB_rac.glif</string>
+ <key>Semicolon</key>
+ <string>S_emicolon.glif</string>
+ <key>Solidus</key>
+ <string>S_olidus.glif</string>
+ <key>Space</key>
+ <string>S_pace.glif</string>
+ <key>Tilde</key>
+ <string>T_ilde.glif</string>
+ <key>VertLine</key>
+ <string>V_ertL_ine.glif</string>
+ <key>nonmarkingreturn</key>
+ <string>nonmarkingreturn.glif</string>
+</dict>
+</plist>
diff --git a/tests/reference/ufo/psfsetglyphorder.ufo/glyphs/nonmarkingreturn.glif b/tests/reference/ufo/psfsetglyphorder.ufo/glyphs/nonmarkingreturn.glif
new file mode 100644
index 0000000..9a63f06
--- /dev/null
+++ b/tests/reference/ufo/psfsetglyphorder.ufo/glyphs/nonmarkingreturn.glif
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="nonmarkingreturn" format="2">
+ <advance width="1004"/>
+ <outline/>
+</glyph>
diff --git a/tests/reference/ufo/psfsetglyphorder.ufo/layercontents.plist b/tests/reference/ufo/psfsetglyphorder.ufo/layercontents.plist
new file mode 100644
index 0000000..42b7482
--- /dev/null
+++ b/tests/reference/ufo/psfsetglyphorder.ufo/layercontents.plist
@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<array>
+ <array>
+ <string>public.default</string>
+ <string>glyphs</string>
+ </array>
+</array>
+</plist>
diff --git a/tests/reference/ufo/psfsetglyphorder.ufo/lib.plist b/tests/reference/ufo/psfsetglyphorder.ufo/lib.plist
new file mode 100644
index 0000000..65224e2
--- /dev/null
+++ b/tests/reference/ufo/psfsetglyphorder.ufo/lib.plist
@@ -0,0 +1,451 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+ <key>com.schriftgestaltung.Glyphs.fontUserData</key>
+ <dict/>
+ <key>com.schriftgestaltung.appVersion</key>
+ <string>1161</string>
+ <key>com.schriftgestaltung.customName</key>
+ <string>Italic</string>
+ <key>com.schriftgestaltung.customParameter.GSFont.DisplayStrings</key>
+ <string/>
+ <key>com.schriftgestaltung.customParameter.GSFont.disablesAutomaticAlignment</key>
+ <true/>
+ <key>com.schriftgestaltung.customParameter.GSFont.disablesLastChange</key>
+ <true/>
+ <key>com.schriftgestaltung.customParameter.GSFont.useNiceNames</key>
+ <integer>0</integer>
+ <key>com.schriftgestaltung.customParameter.GSFontMaster.customValue</key>
+ <integer>0</integer>
+ <key>com.schriftgestaltung.customParameter.GSFontMaster.customValue1</key>
+ <integer>0</integer>
+ <key>com.schriftgestaltung.customParameter.GSFontMaster.customValue2</key>
+ <integer>0</integer>
+ <key>com.schriftgestaltung.customParameter.GSFontMaster.customValue3</key>
+ <integer>0</integer>
+ <key>com.schriftgestaltung.customParameter.GSFontMaster.iconName</key>
+ <string/>
+ <key>com.schriftgestaltung.customParameter.GSFontMaster.weightValue</key>
+ <integer>400</integer>
+ <key>com.schriftgestaltung.customParameter.GSFontMaster.widthValue</key>
+ <integer>100</integer>
+ <key>com.schriftgestaltung.disablesAutomaticAlignment</key>
+ <true/>
+ <key>com.schriftgestaltung.disablesLastChange</key>
+ <true/>
+ <key>com.schriftgestaltung.fontMasterOrder</key>
+ <integer>0</integer>
+ <key>com.schriftgestaltung.glyphOrder</key>
+ <array>
+ <string>.notdef</string>
+ <string>.null</string>
+ <string>nonmarkingreturn</string>
+ <string>Space</string>
+ <string>ExclamationMrk</string>
+ <string>QuotMrk</string>
+ <string>NumSgn</string>
+ <string>DollarSgn</string>
+ <string>PercentSgn</string>
+ <string>Ampersand</string>
+ <string>Apos</string>
+ <string>LftParen</string>
+ <string>RtParen</string>
+ <string>Asterisk</string>
+ <string>PlusSgn</string>
+ <string>Comma</string>
+ <string>HyphenMinus</string>
+ <string>FullStop</string>
+ <string>Solidus</string>
+ <string>DigitZero</string>
+ <string>DigitOne</string>
+ <string>DigitTwo</string>
+ <string>DigitThree</string>
+ <string>DigitFour</string>
+ <string>DigitFive</string>
+ <string>DigitSix</string>
+ <string>DigitSeven</string>
+ <string>DigitEight</string>
+ <string>DigitNine</string>
+ <string>Colon</string>
+ <string>Semicolon</string>
+ <string>LTSgn</string>
+ <string>EqSgn</string>
+ <string>GTSgn</string>
+ <string>QstnMrk</string>
+ <string>AtSgn</string>
+ <string>LtnCapA</string>
+ <string>LtnCapA.alt</string>
+ <string>LtnCapB</string>
+ <string>LtnCapC</string>
+ <string>LtnCapD</string>
+ <string>LtnCapE</string>
+ <string>LtnCapF</string>
+ <string>LtnCapG</string>
+ <string>LtnCapH</string>
+ <string>LtnCapI</string>
+ <string>LtnCapJ</string>
+ <string>LtnCapK</string>
+ <string>LtnCapL</string>
+ <string>LtnCapM</string>
+ <string>LtnCapN</string>
+ <string>LtnCapO</string>
+ <string>LtnCapP</string>
+ <string>LtnCapQ</string>
+ <string>LtnCapR</string>
+ <string>LtnCapS</string>
+ <string>LtnCapT</string>
+ <string>LtnCapU</string>
+ <string>LtnCapV</string>
+ <string>LtnCapW</string>
+ <string>LtnCapX</string>
+ <string>LtnCapY</string>
+ <string>LftSqrBrac</string>
+ <string>ReverseSolidus</string>
+ <string>RtSqrBrac</string>
+ <string>CircumAccent</string>
+ <string>LowLine</string>
+ <string>GraveAccent</string>
+ <string>LtnSmA</string>
+ <string>LtnSmB</string>
+ <string>LtnSmC</string>
+ <string>LtnSmD</string>
+ <string>LtnSmE</string>
+ <string>LtnSmF</string>
+ <string>LtnSmG</string>
+ <string>LtnSmH</string>
+ <string>LtnSmI</string>
+ <string>LtnSmJ</string>
+ <string>LtnSmK</string>
+ <string>LtnSmL</string>
+ <string>LtnSmM</string>
+ <string>LtnSmN</string>
+ <string>LtnSmO</string>
+ <string>LtnSmP</string>
+ <string>LtnSmQ</string>
+ <string>LtnSmR</string>
+ <string>LtnSmS</string>
+ <string>LtnSmT</string>
+ <string>LtnSmU</string>
+ <string>LtnSmV</string>
+ <string>LtnSmW</string>
+ <string>LtnSmX</string>
+ <string>LtnSmY</string>
+ <string>LftCurlyBrac</string>
+ <string>VertLine</string>
+ <string>RtCurlyBrac</string>
+ <string>Tilde</string>
+ <string>LtnCapADiaer</string>
+ <string>LtnSmAAcute</string>
+ <string>LtnSmAGrave</string>
+ <string>LtnSmACircum</string>
+ <string>LtnSmADiaer</string>
+ <string>LtnSmATilde</string>
+ <string>LtnSmARingAbv</string>
+ <string>DottedCirc</string>
+ <string>Hyphen</string>
+ <string>NonBreakingHyphen</string>
+ <string>Hyphen_Soft</string>
+ <string>CombAcute</string>
+ <string>CombGrave</string>
+ <string>CombCircum</string>
+ <string>CombTilde</string>
+ <string>CombDiaer</string>
+ <string>CombRingAbv</string>
+ </array>
+ <key>com.schriftgestaltung.keyboardIncrement</key>
+ <integer>1</integer>
+ <key>com.schriftgestaltung.weight</key>
+ <string>Regular</string>
+ <key>com.schriftgestaltung.weightValue</key>
+ <integer>400</integer>
+ <key>com.schriftgestaltung.width</key>
+ <string>Regular</string>
+ <key>com.schriftgestaltung.widthValue</key>
+ <integer>100</integer>
+ <key>org.sil.lcg.toneLetters</key>
+ <dict>
+ <key>contourWidth</key>
+ <integer>480</integer>
+ <key>dotSize</key>
+ <integer>180</integer>
+ <key>dotSpacing</key>
+ <integer>200</integer>
+ <key>glyphDepth</key>
+ <integer>-25</integer>
+ <key>glyphHeight</key>
+ <integer>1600</integer>
+ <key>italicAngle</key>
+ <integer>14</integer>
+ <key>marginDotLeft</key>
+ <integer>120</integer>
+ <key>marginDotRight</key>
+ <integer>160</integer>
+ <key>marginFlatLeft</key>
+ <integer>120</integer>
+ <key>marginFlatRight</key>
+ <integer>160</integer>
+ <key>marginPointLeft</key>
+ <integer>100</integer>
+ <key>marginPointRight</key>
+ <integer>140</integer>
+ <key>strokeThickness</key>
+ <integer>120</integer>
+ </dict>
+ <key>public.glyphOrder</key>
+ <array>
+ <string>nonmarkingreturn</string>
+ <string>HyphenMinus</string>
+ <string>ReverseSolidus</string>
+ <string>CircumAccent</string>
+ <string>LtnSmAAcute</string>
+ <string>LtnSmEAcute</string>
+ <string>LtnSmIAcute</string>
+ <string>LtnSmOAcute</string>
+ <string>LtnSmUAcute</string>
+ <string>Bullet</string>
+ <string>AcuteAccent</string>
+ <string>LtnCapEAcute</string>
+ <string>LtnCapAAcute</string>
+ <string>LtnCapIAcute</string>
+ <string>LtnCapOAcute</string>
+ <string>LtnCapUAcute</string>
+ <string>ModCircumAccent</string>
+ <string>DblAcuteAccent</string>
+ <string>LtnSmYAcute</string>
+ <string>LtnCapYAcute</string>
+ <string>SupOne</string>
+ <string>SupThree</string>
+ <string>VulgFracOneHalf</string>
+ <string>VulgFracOneQuarter</string>
+ <string>VulgFracThreeQuarters</string>
+ <string>BulletOperator</string>
+ <string>CombAcute</string>
+ </array>
+ <key>public.postscriptNames</key>
+ <dict>
+ <key>Ampersand</key>
+ <string>ampersand</string>
+ <key>Apos</key>
+ <string>quotesingle</string>
+ <key>Asterisk</key>
+ <string>asterisk</string>
+ <key>AtSgn</key>
+ <string>at</string>
+ <key>CircumAccent</key>
+ <string>asciicircum</string>
+ <key>Colon</key>
+ <string>colon</string>
+ <key>CombAcute</key>
+ <string>acutecomb</string>
+ <key>CombCircum</key>
+ <string>uni0302</string>
+ <key>CombDiaer</key>
+ <string>uni0308</string>
+ <key>CombGrave</key>
+ <string>gravecomb</string>
+ <key>CombRingAbv</key>
+ <string>uni030A</string>
+ <key>CombTilde</key>
+ <string>tildecomb</string>
+ <key>Comma</key>
+ <string>comma</string>
+ <key>DigitEight</key>
+ <string>eight</string>
+ <key>DigitFive</key>
+ <string>five</string>
+ <key>DigitFour</key>
+ <string>four</string>
+ <key>DigitNine</key>
+ <string>nine</string>
+ <key>DigitOne</key>
+ <string>one</string>
+ <key>DigitSeven</key>
+ <string>seven</string>
+ <key>DigitSix</key>
+ <string>six</string>
+ <key>DigitThree</key>
+ <string>three</string>
+ <key>DigitTwo</key>
+ <string>two</string>
+ <key>DigitZero</key>
+ <string>zero</string>
+ <key>DollarSgn</key>
+ <string>dollar</string>
+ <key>DottedCirc</key>
+ <string>uni25CC</string>
+ <key>EqSgn</key>
+ <string>equal</string>
+ <key>ExclamationMrk</key>
+ <string>exclam</string>
+ <key>FullStop</key>
+ <string>period</string>
+ <key>GTSgn</key>
+ <string>greater</string>
+ <key>GraveAccent</key>
+ <string>grave</string>
+ <key>Hyphen</key>
+ <string>uni2010</string>
+ <key>HyphenMinus</key>
+ <string>hyphen</string>
+ <key>Hyphen_Soft</key>
+ <string>uni00AD</string>
+ <key>LTSgn</key>
+ <string>less</string>
+ <key>LftCurlyBrac</key>
+ <string>braceleft</string>
+ <key>LftParen</key>
+ <string>parenleft</string>
+ <key>LftSqrBrac</key>
+ <string>bracketleft</string>
+ <key>LowLine</key>
+ <string>underscore</string>
+ <key>LtnCapA</key>
+ <string>A</string>
+ <key>LtnCapA.alt</key>
+ <string>A</string>
+ <key>LtnCapADiaer</key>
+ <string>Adieresis</string>
+ <key>LtnCapB</key>
+ <string>B</string>
+ <key>LtnCapC</key>
+ <string>C</string>
+ <key>LtnCapD</key>
+ <string>D</string>
+ <key>LtnCapE</key>
+ <string>E</string>
+ <key>LtnCapF</key>
+ <string>F</string>
+ <key>LtnCapG</key>
+ <string>G</string>
+ <key>LtnCapH</key>
+ <string>H</string>
+ <key>LtnCapI</key>
+ <string>I</string>
+ <key>LtnCapJ</key>
+ <string>J</string>
+ <key>LtnCapK</key>
+ <string>K</string>
+ <key>LtnCapL</key>
+ <string>L</string>
+ <key>LtnCapM</key>
+ <string>M</string>
+ <key>LtnCapN</key>
+ <string>N</string>
+ <key>LtnCapO</key>
+ <string>O</string>
+ <key>LtnCapP</key>
+ <string>P</string>
+ <key>LtnCapQ</key>
+ <string>Q</string>
+ <key>LtnCapR</key>
+ <string>R</string>
+ <key>LtnCapS</key>
+ <string>S</string>
+ <key>LtnCapT</key>
+ <string>T</string>
+ <key>LtnCapU</key>
+ <string>U</string>
+ <key>LtnCapV</key>
+ <string>V</string>
+ <key>LtnCapW</key>
+ <string>W</string>
+ <key>LtnCapX</key>
+ <string>X</string>
+ <key>LtnCapY</key>
+ <string>Y</string>
+ <key>LtnSmA</key>
+ <string>a</string>
+ <key>LtnSmAAcute</key>
+ <string>aacute</string>
+ <key>LtnSmACircum</key>
+ <string>acircumflex</string>
+ <key>LtnSmADiaer</key>
+ <string>adieresis</string>
+ <key>LtnSmAGrave</key>
+ <string>agrave</string>
+ <key>LtnSmARingAbv</key>
+ <string>aring</string>
+ <key>LtnSmATilde</key>
+ <string>atilde</string>
+ <key>LtnSmB</key>
+ <string>b</string>
+ <key>LtnSmC</key>
+ <string>c</string>
+ <key>LtnSmD</key>
+ <string>d</string>
+ <key>LtnSmE</key>
+ <string>e</string>
+ <key>LtnSmF</key>
+ <string>f</string>
+ <key>LtnSmG</key>
+ <string>g</string>
+ <key>LtnSmH</key>
+ <string>h</string>
+ <key>LtnSmI</key>
+ <string>i</string>
+ <key>LtnSmJ</key>
+ <string>j</string>
+ <key>LtnSmK</key>
+ <string>k</string>
+ <key>LtnSmL</key>
+ <string>l</string>
+ <key>LtnSmM</key>
+ <string>m</string>
+ <key>LtnSmN</key>
+ <string>n</string>
+ <key>LtnSmO</key>
+ <string>o</string>
+ <key>LtnSmP</key>
+ <string>p</string>
+ <key>LtnSmQ</key>
+ <string>q</string>
+ <key>LtnSmR</key>
+ <string>r</string>
+ <key>LtnSmS</key>
+ <string>s</string>
+ <key>LtnSmT</key>
+ <string>t</string>
+ <key>LtnSmU</key>
+ <string>u</string>
+ <key>LtnSmV</key>
+ <string>v</string>
+ <key>LtnSmW</key>
+ <string>w</string>
+ <key>LtnSmX</key>
+ <string>x</string>
+ <key>LtnSmY</key>
+ <string>y</string>
+ <key>NonBreakingHyphen</key>
+ <string>uni2011</string>
+ <key>NumSgn</key>
+ <string>numbersign</string>
+ <key>PercentSgn</key>
+ <string>percent</string>
+ <key>PlusSgn</key>
+ <string>plus</string>
+ <key>QstnMrk</key>
+ <string>question</string>
+ <key>QuotMrk</key>
+ <string>quotedbl</string>
+ <key>ReverseSolidus</key>
+ <string>backslash</string>
+ <key>RtCurlyBrac</key>
+ <string>braceright</string>
+ <key>RtParen</key>
+ <string>parenright</string>
+ <key>RtSqrBrac</key>
+ <string>bracketright</string>
+ <key>Semicolon</key>
+ <string>semicolon</string>
+ <key>Solidus</key>
+ <string>slash</string>
+ <key>Space</key>
+ <string>space</string>
+ <key>Tilde</key>
+ <string>asciitilde</string>
+ <key>VertLine</key>
+ <string>bar</string>
+ </dict>
+</dict>
+</plist>
diff --git a/tests/reference/ufo/psfsetglyphorder.ufo/metainfo.plist b/tests/reference/ufo/psfsetglyphorder.ufo/metainfo.plist
new file mode 100644
index 0000000..aa10c5c
--- /dev/null
+++ b/tests/reference/ufo/psfsetglyphorder.ufo/metainfo.plist
@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+ <key>creator</key>
+ <string>org.sil.scripts.pysilfont</string>
+ <key>formatVersion</key>
+ <integer>3</integer>
+</dict>
+</plist>
diff --git a/tests/reference/ufo/psfsetkeys.lg b/tests/reference/ufo/psfsetkeys.lg
new file mode 100644
index 0000000..9013f01
--- /dev/null
+++ b/tests/reference/ufo/psfsetkeys.lg
@@ -0,0 +1,27 @@
+2021-06-29 14:42:22 Progress: Running: psfsetkeys tests/input/font-psf-test/source/PsfTest-BoldItalic.ufo -k org.sil.newkey -v newvalue -l local/testresults/ufo/psfsetkeys.log -p loglevel=i -p checkfix=fix
+2021-06-29 14:42:22 Progress: Reading UFO: tests/input/font-psf-test/source/PsfTest-BoldItalic.ufo
+2021-06-29 14:42:22 Info: Processing Glyph Layer 0: public.defaultglyphs
+2021-06-29 14:42:22 Progress: Checking fontinfo.plist metadata
+2021-06-29 14:42:22 Warning: macintoshFONDName removed from fontinfo. Old value: My Test
+2021-06-29 14:42:22 Info: Types: Old - string, New - NoneType
+2021-06-29 14:42:22 Warning: openTypeOS2FamilyClass removed from fontinfo. Old value: [0, 0]
+2021-06-29 14:42:22 Info: Types: Old - list, New - NoneType
+2021-06-29 14:42:22 Warning: postscriptFamilyBlues removed from fontinfo. Old value: []
+2021-06-29 14:42:22 Info: Types: Old - list, New - NoneType
+2021-06-29 14:42:22 Warning: openTypeOS2Selection added New value: [7]
+2021-06-29 14:42:22 Info: Types: Old - NoneType, New - list
+2021-06-29 14:42:22 Warning: openTypeHheaAscender updated Old value: 2200, new value: 2100
+2021-06-29 14:42:22 Info: Types: Old - int, New - int
+2021-06-29 14:42:22 Progress: Checking lib.plist metadata
+2021-06-29 14:42:22 Warning: com.schriftgestaltung.disablesAutomaticAlignment deleted - obsolete key Old value: True
+2021-06-29 14:42:22 Info: Types: Old - bool, New - NoneType
+2021-06-29 14:42:22 Warning: com.schriftgestaltung.disablesLastChange deleted - obsolete key Old value: True
+2021-06-29 14:42:22 Info: Types: Old - bool, New - NoneType
+2021-06-29 14:42:22 Progress: Check & fix results:- Errors: 0, Changes made: 7, Other warnings: 0
+2021-06-29 14:42:22 Progress: See log file for details
+2021-06-29 14:42:22 Info: Adding keys to fontinfo
+2021-06-29 14:42:22 Info: org.sil.newkey added, value: newvalue
+2021-06-29 14:42:22 Progress: Processing font for output
+2021-06-29 14:42:22 Progress: Output UFO already exists - reading for comparison
+2021-06-29 14:42:22 Progress: Writing font to local/testresults/ufo/psfsetkeys.ufo
+2021-06-29 14:42:22 Info: Processing glyphs directory
diff --git a/tests/reference/ufo/psfsetkeys.ufo/fontinfo.plist b/tests/reference/ufo/psfsetkeys.ufo/fontinfo.plist
new file mode 100644
index 0000000..6d494b6
--- /dev/null
+++ b/tests/reference/ufo/psfsetkeys.ufo/fontinfo.plist
@@ -0,0 +1,242 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+ <key>ascender</key>
+ <integer>2100</integer>
+ <key>capHeight</key>
+ <integer>1485</integer>
+ <key>copyright</key>
+ <string>Copyright (c) 2004-2021 SIL International</string>
+ <key>descender</key>
+ <integer>-550</integer>
+ <key>familyName</key>
+ <string>Psf Test</string>
+ <key>italicAngle</key>
+ <integer>-14</integer>
+ <key>openTypeHeadCreated</key>
+ <string>2021/06/29 14:43:52</string>
+ <key>openTypeHheaAscender</key>
+ <integer>2100</integer>
+ <key>openTypeHheaDescender</key>
+ <integer>-550</integer>
+ <key>openTypeHheaLineGap</key>
+ <integer>0</integer>
+ <key>openTypeNameDescription</key>
+ <string>Copyright (c) 2004-2021 SIL International</string>
+ <key>openTypeNameDesigner</key>
+ <string>Victor Gaultney, Annie Olsen, Julie Remington, Don Collingsworth, Eric Hays, Becca Hirsbrunner</string>
+ <key>openTypeNameDesignerURL</key>
+ <string>http://scripts.sil.org/</string>
+ <key>openTypeNameLicense</key>
+ <string>Copyright (c) 2004-2021 SIL International (http://www.sil.org/) with Reserved Font Names "Andika" and "SIL".
+
+This Font Software is licensed under the SIL Open Font License, Version 1.1. This license is copied below, and is also available with a FAQ at: http://scripts.sil.org/OFL
+
+
+-----------------------------------------------------------
+SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007
+-----------------------------------------------------------
+
+PREAMBLE
+The goals of the Open Font License (OFL) are to stimulate worldwide development of collaborative font projects, to support the font creation efforts of academic and linguistic communities, and to provide a free and open framework in which fonts may be shared and improved in partnership with others.
+
+The OFL allows the licensed fonts to be used, studied, modified and redistributed freely as long as they are not sold by themselves. The fonts, including any derivative works, can be bundled, embedded, redistributed and/or sold with any software provided that any reserved names are not used by derivative works. The fonts and derivatives, however, cannot be released under any other type of license. The requirement for fonts to remain under this license does not apply to any document created using the fonts or their derivatives.
+
+DEFINITIONS
+"Font Software" refers to the set of files released by the Copyright Holder(s) under this license and clearly marked as such. This may include source files, build scripts and documentation.
+
+"Reserved Font Name" refers to any names specified as such after the copyright statement(s).
+
+"Original Version" refers to the collection of Font Software components as distributed by the Copyright Holder(s).
+
+"Modified Version" refers to any derivative made by adding to, deleting, or substituting -- in part or in whole -- any of the components of the Original Version, by changing formats or by porting the Font Software to a new environment.
+
+"Author" refers to any designer, engineer, programmer, technical writer or other person who contributed to the Font Software.
+
+PERMISSION &amp; CONDITIONS
+Permission is hereby granted, free of charge, to any person obtaining a copy of the Font Software, to use, study, copy, merge, embed, modify, redistribute, and sell modified and unmodified copies of the Font Software, subject to the following conditions:
+
+1) Neither the Font Software nor any of its individual components, in Original or Modified Versions, may be sold by itself.
+
+2) Original or Modified Versions of the Font Software may be bundled, redistributed and/or sold with any software, provided that each copy contains the above copyright notice and this license. These can be included either as stand-alone text files, human-readable headers or in the appropriate machine-readable metadata fields within text or binary files as long as those fields can be easily viewed by the user.
+
+3) No Modified Version of the Font Software may use the Reserved Font Name(s) unless explicit written permission is granted by the corresponding Copyright Holder. This restriction only applies to the primary font name as presented to the users.
+
+4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font Software shall not be used to promote, endorse or advertise any Modified Version, except to acknowledge the contribution(s) of the Copyright Holder(s) and the Author(s) or with their explicit written permission.
+
+5) The Font Software, modified or unmodified, in part or in whole, must be distributed entirely under this license, and must not be distributed under any other license. The requirement for fonts to remain under this license does not apply to any document created using the Font Software.
+
+TERMINATION
+This license becomes null and void if any of the above conditions are not met.
+
+DISCLAIMER
+THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM OTHER DEALINGS IN THE FONT SOFTWARE.</string>
+ <key>openTypeNameLicenseURL</key>
+ <string>http://scripts.sil.org/OFL</string>
+ <key>openTypeNameManufacturer</key>
+ <string>SIL International</string>
+ <key>openTypeNameManufacturerURL</key>
+ <string>http://scripts.sil.org</string>
+ <key>openTypeNamePreferredFamilyName</key>
+ <string>Psf Test</string>
+ <key>openTypeNamePreferredSubfamilyName</key>
+ <string>Bold Italic</string>
+ <key>openTypeNameUniqueID</key>
+ <string>SIL International: Psf Test Bold Italic: 2022</string>
+ <key>openTypeNameVersion</key>
+ <string>Version 5.550</string>
+ <key>openTypeOS2CodePageRanges</key>
+ <array>
+ <integer>0</integer>
+ <integer>1</integer>
+ <integer>2</integer>
+ <integer>4</integer>
+ <integer>7</integer>
+ <integer>8</integer>
+ </array>
+ <key>openTypeOS2Panose</key>
+ <array>
+ <integer>2</integer>
+ <integer>0</integer>
+ <integer>0</integer>
+ <integer>0</integer>
+ <integer>0</integer>
+ <integer>0</integer>
+ <integer>0</integer>
+ <integer>0</integer>
+ <integer>0</integer>
+ <integer>0</integer>
+ </array>
+ <key>openTypeOS2Selection</key>
+ <array>
+ <integer>7</integer>
+ </array>
+ <key>openTypeOS2StrikeoutPosition</key>
+ <integer>700</integer>
+ <key>openTypeOS2StrikeoutSize</key>
+ <integer>100</integer>
+ <key>openTypeOS2SubscriptXOffset</key>
+ <integer>0</integer>
+ <key>openTypeOS2SubscriptXSize</key>
+ <integer>1433</integer>
+ <key>openTypeOS2SubscriptYOffset</key>
+ <integer>286</integer>
+ <key>openTypeOS2SubscriptYSize</key>
+ <integer>1331</integer>
+ <key>openTypeOS2SuperscriptXOffset</key>
+ <integer>0</integer>
+ <key>openTypeOS2SuperscriptXSize</key>
+ <integer>1433</integer>
+ <key>openTypeOS2SuperscriptYOffset</key>
+ <integer>976</integer>
+ <key>openTypeOS2SuperscriptYSize</key>
+ <integer>1331</integer>
+ <key>openTypeOS2Type</key>
+ <array/>
+ <key>openTypeOS2TypoAscender</key>
+ <integer>2100</integer>
+ <key>openTypeOS2TypoDescender</key>
+ <integer>-550</integer>
+ <key>openTypeOS2TypoLineGap</key>
+ <integer>0</integer>
+ <key>openTypeOS2UnicodeRanges</key>
+ <array>
+ <integer>0</integer>
+ <integer>1</integer>
+ <integer>6</integer>
+ <integer>7</integer>
+ <integer>31</integer>
+ <integer>33</integer>
+ <integer>35</integer>
+ <integer>36</integer>
+ <integer>37</integer>
+ <integer>38</integer>
+ <integer>39</integer>
+ <integer>40</integer>
+ <integer>45</integer>
+ <integer>46</integer>
+ <integer>47</integer>
+ <integer>57</integer>
+ <integer>60</integer>
+ <integer>62</integer>
+ <integer>64</integer>
+ <integer>67</integer>
+ <integer>69</integer>
+ <integer>89</integer>
+ </array>
+ <key>openTypeOS2VendorID</key>
+ <string>SIL</string>
+ <key>openTypeOS2WeightClass</key>
+ <integer>700</integer>
+ <key>openTypeOS2WidthClass</key>
+ <integer>5</integer>
+ <key>openTypeOS2WinAscent</key>
+ <integer>2100</integer>
+ <key>openTypeOS2WinDescent</key>
+ <integer>550</integer>
+ <key>org.sil.newkey</key>
+ <string>newvalue</string>
+ <key>postscriptBlueValues</key>
+ <array>
+ <integer>-490</integer>
+ <integer>-490</integer>
+ <integer>-25</integer>
+ <integer>0</integer>
+ <integer>1020</integer>
+ <integer>1040</integer>
+ <integer>1455</integer>
+ <integer>1485</integer>
+ <integer>1600</integer>
+ <integer>1620</integer>
+ </array>
+ <key>postscriptFontName</key>
+ <string>PsfTest-BoldItalic</string>
+ <key>postscriptFullName</key>
+ <string>Psf Test Bold Italic</string>
+ <key>postscriptStemSnapH</key>
+ <array>
+ <integer>140</integer>
+ <integer>145</integer>
+ <integer>150</integer>
+ <integer>155</integer>
+ <integer>160</integer>
+ <integer>165</integer>
+ <integer>170</integer>
+ <integer>175</integer>
+ <integer>185</integer>
+ <integer>270</integer>
+ </array>
+ <key>postscriptStemSnapV</key>
+ <array>
+ <integer>165</integer>
+ <integer>180</integer>
+ <integer>185</integer>
+ <integer>190</integer>
+ <integer>195</integer>
+ <integer>200</integer>
+ <integer>205</integer>
+ <integer>270</integer>
+ </array>
+ <key>postscriptUnderlinePosition</key>
+ <integer>-110</integer>
+ <key>postscriptUnderlineThickness</key>
+ <integer>80</integer>
+ <key>styleMapFamilyName</key>
+ <string>Psf Test</string>
+ <key>styleMapStyleName</key>
+ <string>bold italic</string>
+ <key>styleName</key>
+ <string>Bold Italic</string>
+ <key>trademark</key>
+ <string>Andika is a trademark of SIL International.</string>
+ <key>unitsPerEm</key>
+ <integer>2048</integer>
+ <key>versionMajor</key>
+ <integer>5</integer>
+ <key>versionMinor</key>
+ <integer>550</integer>
+ <key>xHeight</key>
+ <integer>1040</integer>
+</dict>
+</plist>
diff --git a/tests/reference/ufo/psfsetkeys.ufo/glyphs/A_mpersand.glif b/tests/reference/ufo/psfsetkeys.ufo/glyphs/A_mpersand.glif
new file mode 100644
index 0000000..f3fb1c7
--- /dev/null
+++ b/tests/reference/ufo/psfsetkeys.ufo/glyphs/A_mpersand.glif
@@ -0,0 +1,61 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="Ampersand" format="2">
+ <advance width="1333"/>
+ <unicode hex="0026"/>
+ <outline>
+ <contour>
+ <point x="1146" y="594" type="line"/>
+ <point x="1040" y="429"/>
+ <point x="712" y="198"/>
+ <point x="537" y="198" type="curve" smooth="yes"/>
+ <point x="437" y="198"/>
+ <point x="363" y="257"/>
+ <point x="363" y="345" type="curve" smooth="yes"/>
+ <point x="363" y="490"/>
+ <point x="474" y="535"/>
+ <point x="695" y="693" type="curve" smooth="yes"/>
+ <point x="940" y="868"/>
+ <point x="1160" y="1032"/>
+ <point x="1160" y="1213" type="curve" smooth="yes"/>
+ <point x="1160" y="1361"/>
+ <point x="1026" y="1470"/>
+ <point x="849" y="1470" type="curve" smooth="yes"/>
+ <point x="637" y="1470"/>
+ <point x="414" y="1364"/>
+ <point x="414" y="1124" type="curve" smooth="yes"/>
+ <point x="414" y="968"/>
+ <point x="552" y="751"/>
+ <point x="661" y="535" type="curve" smooth="yes"/>
+ <point x="842" y="177"/>
+ <point x="969" y="-25"/>
+ <point x="1021" y="-25" type="curve" smooth="yes"/>
+ <point x="1056" y="-25"/>
+ <point x="1205" y="57"/>
+ <point x="1250" y="89" type="curve"/>
+ <point x="1165" y="129"/>
+ <point x="1073" y="302"/>
+ <point x="890" y="673" type="curve" smooth="yes"/>
+ <point x="788" y="881"/>
+ <point x="651" y="1063"/>
+ <point x="651" y="1163" type="curve" smooth="yes"/>
+ <point x="651" y="1245"/>
+ <point x="729" y="1307"/>
+ <point x="803" y="1307" type="curve" smooth="yes"/>
+ <point x="873" y="1307"/>
+ <point x="926" y="1250"/>
+ <point x="926" y="1184" type="curve" smooth="yes"/>
+ <point x="926" y="1081"/>
+ <point x="821" y="997"/>
+ <point x="600" y="832" type="curve" smooth="yes"/>
+ <point x="392" y="677"/>
+ <point x="108" y="540"/>
+ <point x="108" y="268" type="curve" smooth="yes"/>
+ <point x="108" y="98"/>
+ <point x="229" y="-25"/>
+ <point x="466" y="-25" type="curve" smooth="yes"/>
+ <point x="749" y="-25"/>
+ <point x="1120" y="261"/>
+ <point x="1237" y="421" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetkeys.ufo/glyphs/A_pos.glif b/tests/reference/ufo/psfsetkeys.ufo/glyphs/A_pos.glif
new file mode 100644
index 0000000..68b000e
--- /dev/null
+++ b/tests/reference/ufo/psfsetkeys.ufo/glyphs/A_pos.glif
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="Apos" format="2">
+ <advance width="605"/>
+ <unicode hex="0027"/>
+ <outline>
+ <contour>
+ <point x="598" y="1035" type="line"/>
+ <point x="637" y="1174"/>
+ <point x="676" y="1326"/>
+ <point x="766" y="1569" type="curve"/>
+ <point x="521" y="1569" type="line"/>
+ <point x="491" y="1326"/>
+ <point x="453" y="1174"/>
+ <point x="423" y="1035" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetkeys.ufo/glyphs/A_sterisk.glif b/tests/reference/ufo/psfsetkeys.ufo/glyphs/A_sterisk.glif
new file mode 100644
index 0000000..a36131c
--- /dev/null
+++ b/tests/reference/ufo/psfsetkeys.ufo/glyphs/A_sterisk.glif
@@ -0,0 +1,51 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="Asterisk" format="2">
+ <advance width="1020"/>
+ <unicode hex="002A"/>
+ <outline>
+ <contour>
+ <point x="1135" y="1478" type="line"/>
+ <point x="1039" y="1412"/>
+ <point x="956" y="1353"/>
+ <point x="856" y="1295" type="curve"/>
+ <point x="885" y="1391"/>
+ <point x="915" y="1471"/>
+ <point x="958" y="1584" type="curve"/>
+ <point x="759" y="1584" type="line"/>
+ <point x="753" y="1482"/>
+ <point x="748" y="1398"/>
+ <point x="730" y="1295" type="curve"/>
+ <point x="658" y="1346"/>
+ <point x="599" y="1394"/>
+ <point x="532" y="1461" type="curve"/>
+ <point x="388" y="1293" type="line"/>
+ <point x="484" y="1258"/>
+ <point x="575" y="1222"/>
+ <point x="647" y="1184" type="curve"/>
+ <point x="552" y="1141"/>
+ <point x="459" y="1109"/>
+ <point x="341" y="1066" type="curve"/>
+ <point x="398" y="888" type="line"/>
+ <point x="494" y="958"/>
+ <point x="575" y="1016"/>
+ <point x="674" y="1076" type="curve"/>
+ <point x="641" y="973"/>
+ <point x="610" y="887"/>
+ <point x="566" y="785" type="curve"/>
+ <point x="767" y="785" type="line"/>
+ <point x="773" y="897"/>
+ <point x="785" y="977"/>
+ <point x="800" y="1073" type="curve"/>
+ <point x="875" y="1017"/>
+ <point x="929" y="971"/>
+ <point x="995" y="905" type="curve"/>
+ <point x="1144" y="1078" type="line"/>
+ <point x="1045" y="1116"/>
+ <point x="967" y="1143"/>
+ <point x="886" y="1184" type="curve"/>
+ <point x="984" y="1229"/>
+ <point x="1075" y="1264"/>
+ <point x="1190" y="1308" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetkeys.ufo/glyphs/A_tS_gn.glif b/tests/reference/ufo/psfsetkeys.ufo/glyphs/A_tS_gn.glif
new file mode 100644
index 0000000..e2233cf
--- /dev/null
+++ b/tests/reference/ufo/psfsetkeys.ufo/glyphs/A_tS_gn.glif
@@ -0,0 +1,104 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="AtSgn" format="2">
+ <advance width="1693"/>
+ <unicode hex="0040"/>
+ <outline>
+ <contour>
+ <point x="1082" y="10" type="line"/>
+ <point x="1008" y="-34"/>
+ <point x="933" y="-59"/>
+ <point x="840" y="-59" type="curve" smooth="yes"/>
+ <point x="540" y="-59"/>
+ <point x="362" y="143"/>
+ <point x="362" y="434" type="curve" smooth="yes"/>
+ <point x="362" y="498"/>
+ <point x="371" y="567"/>
+ <point x="389" y="639" type="curve" smooth="yes"/>
+ <point x="480" y="1003"/>
+ <point x="783" y="1228"/>
+ <point x="1121" y="1228" type="curve" smooth="yes"/>
+ <point x="1424" y="1228"/>
+ <point x="1581" y="1069"/>
+ <point x="1581" y="813" type="curve" smooth="yes"/>
+ <point x="1581" y="753"/>
+ <point x="1572" y="688"/>
+ <point x="1555" y="619" type="curve" smooth="yes"/>
+ <point x="1506" y="418"/>
+ <point x="1400" y="331"/>
+ <point x="1340" y="331" type="curve" smooth="yes"/>
+ <point x="1307" y="331"/>
+ <point x="1287" y="362"/>
+ <point x="1287" y="432" type="curve" smooth="yes"/>
+ <point x="1287" y="482"/>
+ <point x="1297" y="551"/>
+ <point x="1320" y="643" type="curve" smooth="yes"/>
+ <point x="1401" y="970" type="line"/>
+ <point x="1323" y="1005"/>
+ <point x="1182" y="1030"/>
+ <point x="1101" y="1030" type="curve" smooth="yes"/>
+ <point x="937" y="1030"/>
+ <point x="822" y="974"/>
+ <point x="710" y="862" type="curve" smooth="yes"/>
+ <point x="637" y="789"/>
+ <point x="569" y="677"/>
+ <point x="539" y="556" type="curve" smooth="yes"/>
+ <point x="529" y="518"/>
+ <point x="525" y="481"/>
+ <point x="525" y="447" type="curve" smooth="yes"/>
+ <point x="525" y="279"/>
+ <point x="629" y="161"/>
+ <point x="740" y="161" type="curve" smooth="yes"/>
+ <point x="867" y="161"/>
+ <point x="1034" y="328"/>
+ <point x="1117" y="450" type="curve"/>
+ <point x="1112" y="422"/>
+ <point x="1110" y="394"/>
+ <point x="1110" y="367" type="curve" smooth="yes"/>
+ <point x="1110" y="252"/>
+ <point x="1157" y="155"/>
+ <point x="1291" y="155" type="curve" smooth="yes"/>
+ <point x="1454" y="155"/>
+ <point x="1674" y="332"/>
+ <point x="1752" y="646" type="curve" smooth="yes"/>
+ <point x="1768" y="710"/>
+ <point x="1775" y="771"/>
+ <point x="1775" y="829" type="curve" smooth="yes"/>
+ <point x="1775" y="1169"/>
+ <point x="1520" y="1411"/>
+ <point x="1156" y="1411" type="curve" smooth="yes"/>
+ <point x="731" y="1411"/>
+ <point x="322" y="1180"/>
+ <point x="183" y="624" type="curve" smooth="yes"/>
+ <point x="163" y="544"/>
+ <point x="154" y="469"/>
+ <point x="154" y="398" type="curve" smooth="yes"/>
+ <point x="154" y="-1"/>
+ <point x="448" y="-243"/>
+ <point x="789" y="-243" type="curve" smooth="yes"/>
+ <point x="924" y="-243"/>
+ <point x="1076" y="-206"/>
+ <point x="1193" y="-137" type="curve"/>
+ </contour>
+ <contour>
+ <point x="1135" y="703" type="line"/>
+ <point x="1069" y="566"/>
+ <point x="899" y="346"/>
+ <point x="809" y="346" type="curve" smooth="yes"/>
+ <point x="757" y="346"/>
+ <point x="726" y="386"/>
+ <point x="726" y="463" type="curve" smooth="yes"/>
+ <point x="726" y="493"/>
+ <point x="731" y="528"/>
+ <point x="741" y="569" type="curve" smooth="yes"/>
+ <point x="760" y="645"/>
+ <point x="803" y="731"/>
+ <point x="853" y="778" type="curve" smooth="yes"/>
+ <point x="901" y="824"/>
+ <point x="957" y="846"/>
+ <point x="1025" y="846" type="curve" smooth="yes"/>
+ <point x="1099" y="846"/>
+ <point x="1133" y="828"/>
+ <point x="1162" y="812" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetkeys.ufo/glyphs/C_ircumA_ccent.glif b/tests/reference/ufo/psfsetkeys.ufo/glyphs/C_ircumA_ccent.glif
new file mode 100644
index 0000000..b60b998
--- /dev/null
+++ b/tests/reference/ufo/psfsetkeys.ufo/glyphs/C_ircumA_ccent.glif
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="CircumAccent" format="2">
+ <advance width="860"/>
+ <unicode hex="005E"/>
+ <anchor x="788" y="1635" name="U"/>
+ <outline>
+ <contour>
+ <point x="1056" y="1188" type="line"/>
+ <point x="845" y="1584" type="line"/>
+ <point x="545" y="1584" type="line"/>
+ <point x="177" y="1188" type="line"/>
+ <point x="417" y="1188" type="line"/>
+ <point x="674" y="1416" type="line"/>
+ <point x="817" y="1188" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetkeys.ufo/glyphs/C_olon.glif b/tests/reference/ufo/psfsetkeys.ufo/glyphs/C_olon.glif
new file mode 100644
index 0000000..37f30d8
--- /dev/null
+++ b/tests/reference/ufo/psfsetkeys.ufo/glyphs/C_olon.glif
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="Colon" format="2">
+ <advance width="690"/>
+ <unicode hex="003A"/>
+ <outline>
+ <contour>
+ <point x="171" y="116" type="curve" smooth="yes"/>
+ <point x="171" y="35"/>
+ <point x="232" y="-25"/>
+ <point x="318" y="-25" type="curve" smooth="yes"/>
+ <point x="436" y="-25"/>
+ <point x="531" y="71"/>
+ <point x="531" y="181" type="curve" smooth="yes"/>
+ <point x="531" y="261"/>
+ <point x="472" y="322"/>
+ <point x="385" y="322" type="curve" smooth="yes"/>
+ <point x="268" y="322"/>
+ <point x="171" y="226"/>
+ </contour>
+ <contour>
+ <point x="319" y="710" type="curve" smooth="yes"/>
+ <point x="319" y="629"/>
+ <point x="380" y="569"/>
+ <point x="466" y="569" type="curve" smooth="yes"/>
+ <point x="584" y="569"/>
+ <point x="679" y="665"/>
+ <point x="679" y="775" type="curve" smooth="yes"/>
+ <point x="679" y="855"/>
+ <point x="620" y="916"/>
+ <point x="533" y="916" type="curve" smooth="yes"/>
+ <point x="416" y="916"/>
+ <point x="319" y="820"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetkeys.ufo/glyphs/C_ombA_cute.glif b/tests/reference/ufo/psfsetkeys.ufo/glyphs/C_ombA_cute.glif
new file mode 100644
index 0000000..f3ea065
--- /dev/null
+++ b/tests/reference/ufo/psfsetkeys.ufo/glyphs/C_ombA_cute.glif
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="CombAcute" format="2">
+ <unicode hex="0301"/>
+ <anchor x="-251" y="1635" name="U"/>
+ <anchor x="-325" y="1100" name="_U"/>
+ <outline>
+ <contour>
+ <point x="-165" y="1584" type="line"/>
+ <point x="-523" y="1188" type="line"/>
+ <point x="-283" y="1188" type="line"/>
+ <point x="204" y="1584" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetkeys.ufo/glyphs/C_ombC_ircum.glif b/tests/reference/ufo/psfsetkeys.ufo/glyphs/C_ombC_ircum.glif
new file mode 100644
index 0000000..9dc18ac
--- /dev/null
+++ b/tests/reference/ufo/psfsetkeys.ufo/glyphs/C_ombC_ircum.glif
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="CombCircum" format="2">
+ <unicode hex="0302"/>
+ <anchor x="-239" y="1635" name="U"/>
+ <anchor x="-330" y="1100" name="_U"/>
+ <outline>
+ <contour>
+ <point x="88" y="1188" type="line"/>
+ <point x="-123" y="1584" type="line"/>
+ <point x="-423" y="1584" type="line"/>
+ <point x="-791" y="1188" type="line"/>
+ <point x="-551" y="1188" type="line"/>
+ <point x="-294" y="1416" type="line"/>
+ <point x="-151" y="1188" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetkeys.ufo/glyphs/C_ombD_iaer.glif b/tests/reference/ufo/psfsetkeys.ufo/glyphs/C_ombD_iaer.glif
new file mode 100644
index 0000000..490587d
--- /dev/null
+++ b/tests/reference/ufo/psfsetkeys.ufo/glyphs/C_ombD_iaer.glif
@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="CombDiaer" format="2">
+ <unicode hex="0308"/>
+ <anchor x="-243" y="1585" name="U"/>
+ <anchor x="-365" y="1100" name="_U"/>
+ <outline>
+ <contour>
+ <point x="-233" y="1338" type="curve" smooth="yes"/>
+ <point x="-233" y="1256"/>
+ <point x="-172" y="1198"/>
+ <point x="-86" y="1198" type="curve" smooth="yes"/>
+ <point x="32" y="1198"/>
+ <point x="126" y="1294"/>
+ <point x="126" y="1404" type="curve" smooth="yes"/>
+ <point x="126" y="1484"/>
+ <point x="66" y="1544"/>
+ <point x="-21" y="1544" type="curve" smooth="yes"/>
+ <point x="-139" y="1544"/>
+ <point x="-233" y="1447"/>
+ </contour>
+ <contour>
+ <point x="-723" y="1338" type="curve" smooth="yes"/>
+ <point x="-723" y="1256"/>
+ <point x="-662" y="1198"/>
+ <point x="-576" y="1198" type="curve" smooth="yes"/>
+ <point x="-457" y="1198"/>
+ <point x="-363" y="1293"/>
+ <point x="-363" y="1404" type="curve" smooth="yes"/>
+ <point x="-363" y="1484"/>
+ <point x="-423" y="1544"/>
+ <point x="-510" y="1544" type="curve" smooth="yes"/>
+ <point x="-628" y="1544"/>
+ <point x="-723" y="1448"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetkeys.ufo/glyphs/C_ombG_rave.glif b/tests/reference/ufo/psfsetkeys.ufo/glyphs/C_ombG_rave.glif
new file mode 100644
index 0000000..49617c2
--- /dev/null
+++ b/tests/reference/ufo/psfsetkeys.ufo/glyphs/C_ombG_rave.glif
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="CombGrave" format="2">
+ <unicode hex="0300"/>
+ <anchor x="-241" y="1635" name="U"/>
+ <anchor x="-415" y="1100" name="_U"/>
+ <outline>
+ <contour>
+ <point x="-725" y="1584" type="line"/>
+ <point x="-403" y="1188" type="line"/>
+ <point x="-173" y="1188" type="line"/>
+ <point x="-395" y="1584" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetkeys.ufo/glyphs/C_ombR_ingA_bv.glif b/tests/reference/ufo/psfsetkeys.ufo/glyphs/C_ombR_ingA_bv.glif
new file mode 100644
index 0000000..27f9832
--- /dev/null
+++ b/tests/reference/ufo/psfsetkeys.ufo/glyphs/C_ombR_ingA_bv.glif
@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="CombRingAbv" format="2">
+ <unicode hex="030A"/>
+ <anchor x="-221" y="1635" name="U"/>
+ <anchor x="-357" y="1100" name="_U"/>
+ <outline>
+ <contour>
+ <point x="-358" y="1292" type="curve" smooth="yes"/>
+ <point x="-406" y="1292"/>
+ <point x="-442" y="1330"/>
+ <point x="-442" y="1375" type="curve" smooth="yes"/>
+ <point x="-442" y="1440"/>
+ <point x="-385" y="1480"/>
+ <point x="-331" y="1480" type="curve" smooth="yes"/>
+ <point x="-283" y="1480"/>
+ <point x="-247" y="1443"/>
+ <point x="-247" y="1398" type="curve" smooth="yes"/>
+ <point x="-247" y="1335"/>
+ <point x="-301" y="1292"/>
+ </contour>
+ <contour>
+ <point x="-598" y="1348" type="curve" smooth="yes"/>
+ <point x="-598" y="1238"/>
+ <point x="-504" y="1148"/>
+ <point x="-384" y="1148" type="curve" smooth="yes"/>
+ <point x="-223" y="1148"/>
+ <point x="-92" y="1271"/>
+ <point x="-92" y="1424" type="curve" smooth="yes"/>
+ <point x="-92" y="1534"/>
+ <point x="-186" y="1624"/>
+ <point x="-306" y="1624" type="curve" smooth="yes"/>
+ <point x="-467" y="1624"/>
+ <point x="-598" y="1501"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetkeys.ufo/glyphs/C_ombT_ilde.glif b/tests/reference/ufo/psfsetkeys.ufo/glyphs/C_ombT_ilde.glif
new file mode 100644
index 0000000..1aa1b62
--- /dev/null
+++ b/tests/reference/ufo/psfsetkeys.ufo/glyphs/C_ombT_ilde.glif
@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="CombTilde" format="2">
+ <unicode hex="0303"/>
+ <anchor x="-355" y="1490" name="U"/>
+ <anchor x="-390" y="1100" name="_U"/>
+ <outline>
+ <contour>
+ <point x="-687" y="1178" type="line"/>
+ <point x="-673" y="1232"/>
+ <point x="-628" y="1271"/>
+ <point x="-584" y="1271" type="curve" smooth="yes"/>
+ <point x="-546" y="1271"/>
+ <point x="-498" y="1247"/>
+ <point x="-437" y="1217" type="curve" smooth="yes"/>
+ <point x="-375" y="1187"/>
+ <point x="-327" y="1168"/>
+ <point x="-265" y="1168" type="curve" smooth="yes"/>
+ <point x="-129" y="1168"/>
+ <point x="-13" y="1294"/>
+ <point x="30" y="1465" type="curve"/>
+ <point x="-125" y="1465" type="line"/>
+ <point x="-138" y="1415"/>
+ <point x="-190" y="1373"/>
+ <point x="-235" y="1373" type="curve" smooth="yes"/>
+ <point x="-272" y="1373"/>
+ <point x="-306" y="1399"/>
+ <point x="-366" y="1423" type="curve" smooth="yes"/>
+ <point x="-438" y="1452"/>
+ <point x="-498" y="1475"/>
+ <point x="-563" y="1475" type="curve" smooth="yes"/>
+ <point x="-695" y="1475"/>
+ <point x="-802" y="1336"/>
+ <point x="-842" y="1178" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetkeys.ufo/glyphs/C_omma.glif b/tests/reference/ufo/psfsetkeys.ufo/glyphs/C_omma.glif
new file mode 100644
index 0000000..4105316
--- /dev/null
+++ b/tests/reference/ufo/psfsetkeys.ufo/glyphs/C_omma.glif
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="Comma" format="2">
+ <advance width="645"/>
+ <unicode hex="002C"/>
+ <outline>
+ <contour>
+ <point x="137" y="49" type="line"/>
+ <point x="297" y="49" type="line"/>
+ <point x="276" y="-34"/>
+ <point x="192" y="-151"/>
+ <point x="59" y="-262" type="curve"/>
+ <point x="187" y="-332" type="line"/>
+ <point x="337" y="-222"/>
+ <point x="539" y="-11"/>
+ <point x="539" y="165" type="curve" smooth="yes"/>
+ <point x="539" y="262"/>
+ <point x="495" y="337"/>
+ <point x="379" y="337" type="curve" smooth="yes"/>
+ <point x="266" y="337"/>
+ <point x="187" y="252"/>
+ <point x="169" y="178" type="curve" smooth="yes"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetkeys.ufo/glyphs/D_igitE_ight.glif b/tests/reference/ufo/psfsetkeys.ufo/glyphs/D_igitE_ight.glif
new file mode 100644
index 0000000..9272dc9
--- /dev/null
+++ b/tests/reference/ufo/psfsetkeys.ufo/glyphs/D_igitE_ight.glif
@@ -0,0 +1,63 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="DigitEight" format="2">
+ <advance width="1180"/>
+ <unicode hex="0038"/>
+ <anchor x="515" y="-100" name="L"/>
+ <anchor x="922" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="543" y="-25" type="curve" smooth="yes"/>
+ <point x="860" y="-25"/>
+ <point x="1182" y="176"/>
+ <point x="1182" y="498" type="curve" smooth="yes"/>
+ <point x="1182" y="642"/>
+ <point x="1090" y="742"/>
+ <point x="1011" y="787" type="curve"/>
+ <point x="1159" y="866"/>
+ <point x="1279" y="994"/>
+ <point x="1279" y="1163" type="curve" smooth="yes"/>
+ <point x="1279" y="1342"/>
+ <point x="1123" y="1470"/>
+ <point x="906" y="1470" type="curve" smooth="yes"/>
+ <point x="632" y="1470"/>
+ <point x="349" y="1310"/>
+ <point x="349" y="1028" type="curve" smooth="yes"/>
+ <point x="349" y="904"/>
+ <point x="412" y="821"/>
+ <point x="466" y="787" type="curve"/>
+ <point x="270" y="703"/>
+ <point x="108" y="563"/>
+ <point x="108" y="341" type="curve" smooth="yes"/>
+ <point x="108" y="123"/>
+ <point x="301" y="-25"/>
+ </contour>
+ <contour>
+ <point x="760" y="886" type="curve" smooth="yes"/>
+ <point x="651" y="886"/>
+ <point x="593" y="939"/>
+ <point x="593" y="1038" type="curve" smooth="yes"/>
+ <point x="593" y="1175"/>
+ <point x="721" y="1277"/>
+ <point x="858" y="1277" type="curve" smooth="yes"/>
+ <point x="976" y="1277"/>
+ <point x="1028" y="1221"/>
+ <point x="1028" y="1127" type="curve" smooth="yes"/>
+ <point x="1028" y="993"/>
+ <point x="898" y="886"/>
+ </contour>
+ <contour>
+ <point x="595" y="183" type="curve" smooth="yes"/>
+ <point x="458" y="183"/>
+ <point x="375" y="267"/>
+ <point x="375" y="384" type="curve" smooth="yes"/>
+ <point x="375" y="549"/>
+ <point x="549" y="673"/>
+ <point x="707" y="673" type="curve" smooth="yes"/>
+ <point x="833" y="673"/>
+ <point x="920" y="602"/>
+ <point x="920" y="477" type="curve" smooth="yes"/>
+ <point x="920" y="317"/>
+ <point x="759" y="183"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetkeys.ufo/glyphs/D_igitF_ive.glif b/tests/reference/ufo/psfsetkeys.ufo/glyphs/D_igitF_ive.glif
new file mode 100644
index 0000000..1c4dd99
--- /dev/null
+++ b/tests/reference/ufo/psfsetkeys.ufo/glyphs/D_igitF_ive.glif
@@ -0,0 +1,44 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="DigitFive" format="2">
+ <advance width="1180"/>
+ <unicode hex="0035"/>
+ <anchor x="515" y="-100" name="L"/>
+ <anchor x="922" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="1330" y="1445" type="line"/>
+ <point x="475" y="1445" type="line"/>
+ <point x="274" y="639" type="line"/>
+ <point x="410" y="686"/>
+ <point x="519" y="703"/>
+ <point x="625" y="703" type="curve" smooth="yes"/>
+ <point x="763" y="703"/>
+ <point x="867" y="630"/>
+ <point x="867" y="507" type="curve" smooth="yes"/>
+ <point x="867" y="318"/>
+ <point x="680" y="213"/>
+ <point x="503" y="213" type="curve" smooth="yes"/>
+ <point x="363" y="213"/>
+ <point x="255" y="260"/>
+ <point x="168" y="356" type="curve"/>
+ <point x="59" y="79" type="line"/>
+ <point x="165" y="2"/>
+ <point x="308" y="-25"/>
+ <point x="483" y="-25" type="curve" smooth="yes"/>
+ <point x="841" y="-25"/>
+ <point x="1155" y="204"/>
+ <point x="1155" y="564" type="curve" smooth="yes"/>
+ <point x="1155" y="774"/>
+ <point x="1007" y="921"/>
+ <point x="774" y="921" type="curve" smooth="yes"/>
+ <point x="712" y="921"/>
+ <point x="632" y="902"/>
+ <point x="595" y="886" type="curve"/>
+ <point x="674" y="1203" type="line"/>
+ <point x="1004" y="1203" type="line" smooth="yes"/>
+ <point x="1088" y="1203"/>
+ <point x="1193" y="1199"/>
+ <point x="1264" y="1183" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetkeys.ufo/glyphs/D_igitF_our.glif b/tests/reference/ufo/psfsetkeys.ufo/glyphs/D_igitF_our.glif
new file mode 100644
index 0000000..617709f
--- /dev/null
+++ b/tests/reference/ufo/psfsetkeys.ufo/glyphs/D_igitF_our.glif
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="DigitFour" format="2">
+ <advance width="1180"/>
+ <unicode hex="0034"/>
+ <anchor x="522" y="-100" name="L"/>
+ <anchor x="929" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="1180" y="342" type="line"/>
+ <point x="1235" y="564" type="line"/>
+ <point x="1075" y="564" type="line"/>
+ <point x="1295" y="1445" type="line"/>
+ <point x="945" y="1445" type="line"/>
+ <point x="120" y="564" type="line"/>
+ <point x="65" y="342" type="line"/>
+ <point x="755" y="342" type="line"/>
+ <point x="670" y="0" type="line"/>
+ <point x="935" y="0" type="line"/>
+ <point x="1020" y="342" type="line"/>
+ </contour>
+ <contour>
+ <point x="954" y="1143" type="line"/>
+ <point x="810" y="564" type="line"/>
+ <point x="385" y="564" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetkeys.ufo/glyphs/D_igitN_ine.glif b/tests/reference/ufo/psfsetkeys.ufo/glyphs/D_igitN_ine.glif
new file mode 100644
index 0000000..85e36a0
--- /dev/null
+++ b/tests/reference/ufo/psfsetkeys.ufo/glyphs/D_igitN_ine.glif
@@ -0,0 +1,49 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="DigitNine" format="2">
+ <advance width="1180"/>
+ <unicode hex="0039"/>
+ <anchor x="515" y="-100" name="L"/>
+ <anchor x="922" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="119" y="84" type="line"/>
+ <point x="199" y="25"/>
+ <point x="327" y="-25"/>
+ <point x="455" y="-25" type="curve" smooth="yes"/>
+ <point x="979" y="-25"/>
+ <point x="1289" y="533"/>
+ <point x="1289" y="979" type="curve" smooth="yes"/>
+ <point x="1289" y="1248"/>
+ <point x="1164" y="1470"/>
+ <point x="833" y="1470" type="curve" smooth="yes"/>
+ <point x="554" y="1470"/>
+ <point x="255" y="1239"/>
+ <point x="255" y="932" type="curve" smooth="yes"/>
+ <point x="255" y="736"/>
+ <point x="399" y="570"/>
+ <point x="644" y="570" type="curve" smooth="yes"/>
+ <point x="833" y="570"/>
+ <point x="1027" y="700"/>
+ <point x="1164" y="859" type="curve"/>
+ <point x="1123" y="981" type="line"/>
+ <point x="1021" y="868"/>
+ <point x="863" y="782"/>
+ <point x="728" y="782" type="curve" smooth="yes"/>
+ <point x="589" y="782"/>
+ <point x="519" y="845"/>
+ <point x="519" y="955" type="curve" smooth="yes"/>
+ <point x="519" y="1133"/>
+ <point x="653" y="1237"/>
+ <point x="801" y="1237" type="curve" smooth="yes"/>
+ <point x="951" y="1237"/>
+ <point x="1029" y="1136"/>
+ <point x="1029" y="965" type="curve" smooth="yes"/>
+ <point x="1029" y="476"/>
+ <point x="710" y="208"/>
+ <point x="513" y="208" type="curve" smooth="yes"/>
+ <point x="417" y="208"/>
+ <point x="301" y="252"/>
+ <point x="237" y="337" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetkeys.ufo/glyphs/D_igitO_ne.glif b/tests/reference/ufo/psfsetkeys.ufo/glyphs/D_igitO_ne.glif
new file mode 100644
index 0000000..df3633d
--- /dev/null
+++ b/tests/reference/ufo/psfsetkeys.ufo/glyphs/D_igitO_ne.glif
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="DigitOne" format="2">
+ <advance width="1180"/>
+ <unicode hex="0031"/>
+ <anchor x="515" y="-100" name="L"/>
+ <anchor x="922" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="490" y="233" type="line"/>
+ <point x="183" y="233" type="line"/>
+ <point x="125" y="0" type="line"/>
+ <point x="1015" y="0" type="line"/>
+ <point x="1073" y="233" type="line"/>
+ <point x="765" y="233" type="line"/>
+ <point x="1067" y="1445" type="line"/>
+ <point x="792" y="1445" type="line"/>
+ <point x="432" y="1265" type="line"/>
+ <point x="403" y="1008" type="line"/>
+ <point x="720" y="1158" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetkeys.ufo/glyphs/D_igitS_even.glif b/tests/reference/ufo/psfsetkeys.ufo/glyphs/D_igitS_even.glif
new file mode 100644
index 0000000..23ac13b
--- /dev/null
+++ b/tests/reference/ufo/psfsetkeys.ufo/glyphs/D_igitS_even.glif
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="DigitSeven" format="2">
+ <advance width="1180"/>
+ <unicode hex="0037"/>
+ <anchor x="515" y="-100" name="L"/>
+ <anchor x="922" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="480" y="0" type="line"/>
+ <point x="722" y="454"/>
+ <point x="1004" y="846"/>
+ <point x="1400" y="1247" type="curve"/>
+ <point x="1450" y="1445" type="line"/>
+ <point x="390" y="1445" type="line"/>
+ <point x="324" y="1178" type="line"/>
+ <point x="404" y="1194"/>
+ <point x="521" y="1198"/>
+ <point x="709" y="1198" type="curve" smooth="yes"/>
+ <point x="1039" y="1198" type="line"/>
+ <point x="689" y="829"/>
+ <point x="488" y="560"/>
+ <point x="175" y="0" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetkeys.ufo/glyphs/D_igitS_ix.glif b/tests/reference/ufo/psfsetkeys.ufo/glyphs/D_igitS_ix.glif
new file mode 100644
index 0000000..5fad278
--- /dev/null
+++ b/tests/reference/ufo/psfsetkeys.ufo/glyphs/D_igitS_ix.glif
@@ -0,0 +1,49 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="DigitSix" format="2">
+ <advance width="1180"/>
+ <unicode hex="0036"/>
+ <anchor x="525" y="-100" name="L"/>
+ <anchor x="932" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="1347" y="1371" type="line"/>
+ <point x="1260" y="1440"/>
+ <point x="1149" y="1470"/>
+ <point x="1011" y="1470" type="curve" smooth="yes"/>
+ <point x="493" y="1470"/>
+ <point x="181" y="971"/>
+ <point x="181" y="500" type="curve" smooth="yes"/>
+ <point x="181" y="188"/>
+ <point x="368" y="-25"/>
+ <point x="635" y="-25" type="curve" smooth="yes"/>
+ <point x="954" y="-25"/>
+ <point x="1207" y="192"/>
+ <point x="1207" y="498" type="curve" smooth="yes"/>
+ <point x="1207" y="714"/>
+ <point x="1058" y="916"/>
+ <point x="813" y="916" type="curve" smooth="yes"/>
+ <point x="622" y="916"/>
+ <point x="477" y="802"/>
+ <point x="326" y="648" type="curve"/>
+ <point x="363" y="525" type="line"/>
+ <point x="470" y="637"/>
+ <point x="595" y="703"/>
+ <point x="750" y="703" type="curve" smooth="yes"/>
+ <point x="882" y="703"/>
+ <point x="954" y="586"/>
+ <point x="954" y="466" type="curve" smooth="yes"/>
+ <point x="954" y="325"/>
+ <point x="828" y="208"/>
+ <point x="677" y="208" type="curve" smooth="yes"/>
+ <point x="526" y="208"/>
+ <point x="447" y="350"/>
+ <point x="447" y="533" type="curve" smooth="yes"/>
+ <point x="447" y="978"/>
+ <point x="738" y="1237"/>
+ <point x="953" y="1237" type="curve" smooth="yes"/>
+ <point x="1049" y="1237"/>
+ <point x="1155" y="1204"/>
+ <point x="1220" y="1119" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetkeys.ufo/glyphs/D_igitT_hree.glif b/tests/reference/ufo/psfsetkeys.ufo/glyphs/D_igitT_hree.glif
new file mode 100644
index 0000000..5be951b
--- /dev/null
+++ b/tests/reference/ufo/psfsetkeys.ufo/glyphs/D_igitT_hree.glif
@@ -0,0 +1,52 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="DigitThree" format="2">
+ <advance width="1180"/>
+ <unicode hex="0033"/>
+ <anchor x="515" y="-100" name="L"/>
+ <anchor x="922" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="548" y="876" type="line"/>
+ <point x="489" y="639" type="line"/>
+ <point x="579" y="639" type="line" smooth="yes"/>
+ <point x="778" y="639"/>
+ <point x="880" y="555"/>
+ <point x="880" y="452" type="curve" smooth="yes"/>
+ <point x="880" y="295"/>
+ <point x="726" y="208"/>
+ <point x="576" y="208" type="curve" smooth="yes"/>
+ <point x="386" y="208"/>
+ <point x="253" y="279"/>
+ <point x="174" y="401" type="curve"/>
+ <point x="72" y="129" type="line"/>
+ <point x="162" y="32"/>
+ <point x="321" y="-25"/>
+ <point x="518" y="-25" type="curve" smooth="yes"/>
+ <point x="867" y="-25"/>
+ <point x="1163" y="169"/>
+ <point x="1163" y="471" type="curve" smooth="yes"/>
+ <point x="1163" y="644"/>
+ <point x="999" y="751"/>
+ <point x="882" y="772" type="curve"/>
+ <point x="1076" y="817"/>
+ <point x="1296" y="963"/>
+ <point x="1296" y="1172" type="curve" smooth="yes"/>
+ <point x="1296" y="1348"/>
+ <point x="1112" y="1470"/>
+ <point x="856" y="1470" type="curve" smooth="yes"/>
+ <point x="689" y="1470"/>
+ <point x="529" y="1402"/>
+ <point x="427" y="1312" type="curve"/>
+ <point x="405" y="1084" type="line"/>
+ <point x="546" y="1199"/>
+ <point x="664" y="1237"/>
+ <point x="818" y="1237" type="curve" smooth="yes"/>
+ <point x="928" y="1237"/>
+ <point x="1001" y="1178"/>
+ <point x="1001" y="1100" type="curve" smooth="yes"/>
+ <point x="1001" y="975"/>
+ <point x="819" y="876"/>
+ <point x="638" y="876" type="curve" smooth="yes"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetkeys.ufo/glyphs/D_igitT_wo.glif b/tests/reference/ufo/psfsetkeys.ufo/glyphs/D_igitT_wo.glif
new file mode 100644
index 0000000..001d438
--- /dev/null
+++ b/tests/reference/ufo/psfsetkeys.ufo/glyphs/D_igitT_wo.glif
@@ -0,0 +1,37 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="DigitTwo" format="2">
+ <advance width="1180"/>
+ <unicode hex="0032"/>
+ <anchor x="515" y="-100" name="L"/>
+ <anchor x="882" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="1094" y="257" type="line"/>
+ <point x="1010" y="244"/>
+ <point x="942" y="243"/>
+ <point x="745" y="243" type="curve" smooth="yes"/>
+ <point x="480" y="243" type="line"/>
+ <point x="875" y="492"/>
+ <point x="1255" y="786"/>
+ <point x="1255" y="1125" type="curve" smooth="yes"/>
+ <point x="1255" y="1324"/>
+ <point x="1106" y="1470"/>
+ <point x="846" y="1470" type="curve" smooth="yes"/>
+ <point x="667" y="1470"/>
+ <point x="472" y="1388"/>
+ <point x="363" y="1277" type="curve"/>
+ <point x="374" y="1039" type="line"/>
+ <point x="489" y="1146"/>
+ <point x="646" y="1223"/>
+ <point x="762" y="1223" type="curve" smooth="yes"/>
+ <point x="890" y="1223"/>
+ <point x="949" y="1138"/>
+ <point x="949" y="1040" type="curve" smooth="yes"/>
+ <point x="949" y="805"/>
+ <point x="500" y="440"/>
+ <point x="104" y="218" type="curve"/>
+ <point x="50" y="0" type="line"/>
+ <point x="1030" y="0" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetkeys.ufo/glyphs/D_igitZ_ero.glif b/tests/reference/ufo/psfsetkeys.ufo/glyphs/D_igitZ_ero.glif
new file mode 100644
index 0000000..895a8e4
--- /dev/null
+++ b/tests/reference/ufo/psfsetkeys.ufo/glyphs/D_igitZ_ero.glif
@@ -0,0 +1,49 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="DigitZero" format="2">
+ <advance width="1180"/>
+ <unicode hex="0030"/>
+ <anchor x="520" y="-100" name="L"/>
+ <anchor x="927" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="959" y="683" type="curve" smooth="yes"/>
+ <point x="873" y="339"/>
+ <point x="762" y="203"/>
+ <point x="600" y="203" type="curve" smooth="yes"/>
+ <point x="469" y="203"/>
+ <point x="432" y="294"/>
+ <point x="432" y="454" type="curve" smooth="yes"/>
+ <point x="432" y="537"/>
+ <point x="447" y="630"/>
+ <point x="478" y="755" type="curve" smooth="yes"/>
+ <point x="564" y="1099"/>
+ <point x="676" y="1242"/>
+ <point x="839" y="1242" type="curve" smooth="yes"/>
+ <point x="971" y="1242"/>
+ <point x="1010" y="1140"/>
+ <point x="1010" y="992" type="curve" smooth="yes"/>
+ <point x="1010" y="907"/>
+ <point x="991" y="811"/>
+ </contour>
+ <contour>
+ <point x="1246" y="689" type="curve" smooth="yes"/>
+ <point x="1281" y="828"/>
+ <point x="1298" y="927"/>
+ <point x="1298" y="1028" type="curve" smooth="yes"/>
+ <point x="1298" y="1317"/>
+ <point x="1158" y="1470"/>
+ <point x="906" y="1470" type="curve" smooth="yes"/>
+ <point x="587" y="1470"/>
+ <point x="329" y="1302"/>
+ <point x="190" y="745" type="curve" smooth="yes"/>
+ <point x="157" y="611"/>
+ <point x="141" y="516"/>
+ <point x="141" y="420" type="curve" smooth="yes"/>
+ <point x="141" y="131"/>
+ <point x="292" y="-25"/>
+ <point x="533" y="-25" type="curve" smooth="yes"/>
+ <point x="854" y="-25"/>
+ <point x="1103" y="115"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetkeys.ufo/glyphs/D_ollarS_gn.glif b/tests/reference/ufo/psfsetkeys.ufo/glyphs/D_ollarS_gn.glif
new file mode 100644
index 0000000..0b8bdfc
--- /dev/null
+++ b/tests/reference/ufo/psfsetkeys.ufo/glyphs/D_ollarS_gn.glif
@@ -0,0 +1,57 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="DollarSgn" format="2">
+ <advance width="1180"/>
+ <unicode hex="0024"/>
+ <outline>
+ <contour>
+ <point x="879" y="1584" type="line"/>
+ <point x="679" y="780" type="line"/>
+ <point x="634" y="719" type="line"/>
+ <point x="400" y="-218" type="line"/>
+ <point x="576" y="-218" type="line"/>
+ <point x="795" y="661" type="line"/>
+ <point x="842" y="727" type="line"/>
+ <point x="1055" y="1584" type="line"/>
+ </contour>
+ <contour>
+ <point x="1250" y="1303" type="line"/>
+ <point x="1145" y="1355"/>
+ <point x="1026" y="1375"/>
+ <point x="885" y="1375" type="curve" smooth="yes"/>
+ <point x="537" y="1375"/>
+ <point x="345" y="1216"/>
+ <point x="345" y="984" type="curve" smooth="yes"/>
+ <point x="345" y="841"/>
+ <point x="441" y="726"/>
+ <point x="638" y="622" type="curve" smooth="yes"/>
+ <point x="832" y="519"/>
+ <point x="881" y="451"/>
+ <point x="881" y="381" type="curve" smooth="yes"/>
+ <point x="881" y="274"/>
+ <point x="817" y="209"/>
+ <point x="613" y="209" type="curve" smooth="yes"/>
+ <point x="462" y="209"/>
+ <point x="336" y="298"/>
+ <point x="259" y="389" type="curve"/>
+ <point x="133" y="143" type="line"/>
+ <point x="243" y="56"/>
+ <point x="378" y="0"/>
+ <point x="566" y="0" type="curve" smooth="yes"/>
+ <point x="879" y="0"/>
+ <point x="1120" y="142"/>
+ <point x="1120" y="396" type="curve" smooth="yes"/>
+ <point x="1120" y="562"/>
+ <point x="1028" y="682"/>
+ <point x="817" y="803" type="curve" smooth="yes"/>
+ <point x="635" y="908"/>
+ <point x="592" y="958"/>
+ <point x="592" y="1016" type="curve" smooth="yes"/>
+ <point x="592" y="1113"/>
+ <point x="649" y="1176"/>
+ <point x="826" y="1176" type="curve" smooth="yes"/>
+ <point x="954" y="1176"/>
+ <point x="1048" y="1135"/>
+ <point x="1134" y="1066" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetkeys.ufo/glyphs/D_ottedC_irc.glif b/tests/reference/ufo/psfsetkeys.ufo/glyphs/D_ottedC_irc.glif
new file mode 100644
index 0000000..f7581b6
--- /dev/null
+++ b/tests/reference/ufo/psfsetkeys.ufo/glyphs/D_ottedC_irc.glif
@@ -0,0 +1,235 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="DottedCirc" format="2">
+ <advance width="1086"/>
+ <unicode hex="25CC"/>
+ <anchor x="493" y="0" name="H"/>
+ <anchor x="545" y="-100" name="L"/>
+ <anchor x="750" y="0" name="O"/>
+ <anchor x="645" y="1000" name="U"/>
+ <outline>
+ <contour>
+ <point x="443" y="837" type="curve" smooth="yes"/>
+ <point x="443" y="864"/>
+ <point x="423" y="885"/>
+ <point x="398" y="885" type="curve" smooth="yes"/>
+ <point x="371" y="885"/>
+ <point x="348" y="861"/>
+ <point x="348" y="837" type="curve" smooth="yes"/>
+ <point x="348" y="809"/>
+ <point x="372" y="789"/>
+ <point x="398" y="789" type="curve" smooth="yes"/>
+ <point x="425" y="789"/>
+ <point x="443" y="812"/>
+ </contour>
+ <contour>
+ <point x="758" y="79" type="curve" smooth="yes"/>
+ <point x="758" y="106"/>
+ <point x="736" y="127"/>
+ <point x="710" y="127" type="curve" smooth="yes"/>
+ <point x="685" y="127"/>
+ <point x="662" y="103"/>
+ <point x="662" y="80" type="curve" smooth="yes"/>
+ <point x="662" y="52"/>
+ <point x="686" y="31"/>
+ <point x="710" y="31" type="curve" smooth="yes"/>
+ <point x="737" y="31"/>
+ <point x="758" y="55"/>
+ </contour>
+ <contour>
+ <point x="310" y="749" type="curve" smooth="yes"/>
+ <point x="310" y="775"/>
+ <point x="288" y="796"/>
+ <point x="263" y="796" type="curve" smooth="yes"/>
+ <point x="238" y="796"/>
+ <point x="215" y="774"/>
+ <point x="215" y="747" type="curve" smooth="yes"/>
+ <point x="215" y="722"/>
+ <point x="236" y="701"/>
+ <point x="263" y="701" type="curve" smooth="yes"/>
+ <point x="291" y="701"/>
+ <point x="310" y="720"/>
+ </contour>
+ <contour>
+ <point x="891" y="168" type="curve" smooth="yes"/>
+ <point x="891" y="197"/>
+ <point x="870" y="215"/>
+ <point x="843" y="215" type="curve" smooth="yes"/>
+ <point x="817" y="215"/>
+ <point x="795" y="194"/>
+ <point x="795" y="168" type="curve" smooth="yes"/>
+ <point x="795" y="143"/>
+ <point x="816" y="121"/>
+ <point x="843" y="121" type="curve" smooth="yes"/>
+ <point x="871" y="121"/>
+ <point x="891" y="143"/>
+ </contour>
+ <contour>
+ <point x="222" y="613" type="curve" smooth="yes"/>
+ <point x="222" y="640"/>
+ <point x="199" y="663"/>
+ <point x="173" y="663" type="curve" smooth="yes"/>
+ <point x="149" y="663"/>
+ <point x="126" y="642"/>
+ <point x="126" y="615" type="curve" smooth="yes"/>
+ <point x="126" y="591"/>
+ <point x="145" y="567"/>
+ <point x="173" y="567" type="curve" smooth="yes"/>
+ <point x="197" y="567"/>
+ <point x="222" y="587"/>
+ </contour>
+ <contour>
+ <point x="980" y="301" type="curve" smooth="yes"/>
+ <point x="980" y="327"/>
+ <point x="957" y="348"/>
+ <point x="932" y="348" type="curve" smooth="yes"/>
+ <point x="908" y="348"/>
+ <point x="884" y="332"/>
+ <point x="884" y="301" type="curve" smooth="yes"/>
+ <point x="884" y="277"/>
+ <point x="902" y="254"/>
+ <point x="932" y="254" type="curve" smooth="yes"/>
+ <point x="957" y="254"/>
+ <point x="980" y="274"/>
+ </contour>
+ <contour>
+ <point x="191" y="459" type="curve" smooth="yes"/>
+ <point x="191" y="484"/>
+ <point x="168" y="505"/>
+ <point x="143" y="505" type="curve" smooth="yes"/>
+ <point x="116" y="505"/>
+ <point x="95" y="484"/>
+ <point x="95" y="458" type="curve" smooth="yes"/>
+ <point x="95" y="433"/>
+ <point x="115" y="410"/>
+ <point x="143" y="410" type="curve" smooth="yes"/>
+ <point x="167" y="410"/>
+ <point x="191" y="432"/>
+ </contour>
+ <contour>
+ <point x="1011" y="458" type="curve" smooth="yes"/>
+ <point x="1011" y="484"/>
+ <point x="990" y="506"/>
+ <point x="964" y="506" type="curve" smooth="yes"/>
+ <point x="940" y="506"/>
+ <point x="915" y="484"/>
+ <point x="915" y="457" type="curve" smooth="yes"/>
+ <point x="915" y="433"/>
+ <point x="936" y="411"/>
+ <point x="964" y="411" type="curve" smooth="yes"/>
+ <point x="990" y="411"/>
+ <point x="1011" y="433"/>
+ </contour>
+ <contour>
+ <point x="222" y="302" type="curve" smooth="yes"/>
+ <point x="222" y="328"/>
+ <point x="200" y="348"/>
+ <point x="174" y="348" type="curve" smooth="yes"/>
+ <point x="147" y="348"/>
+ <point x="126" y="326"/>
+ <point x="126" y="302" type="curve" smooth="yes"/>
+ <point x="126" y="275"/>
+ <point x="149" y="253"/>
+ <point x="174" y="253" type="curve" smooth="yes"/>
+ <point x="201" y="253"/>
+ <point x="222" y="277"/>
+ </contour>
+ <contour>
+ <point x="980" y="615" type="curve" smooth="yes"/>
+ <point x="980" y="642"/>
+ <point x="955" y="663"/>
+ <point x="931" y="663" type="curve" smooth="yes"/>
+ <point x="904" y="663"/>
+ <point x="885" y="638"/>
+ <point x="885" y="614" type="curve" smooth="yes"/>
+ <point x="885" y="588"/>
+ <point x="907" y="567"/>
+ <point x="931" y="567" type="curve" smooth="yes"/>
+ <point x="959" y="567"/>
+ <point x="980" y="591"/>
+ </contour>
+ <contour>
+ <point x="310" y="168" type="curve" smooth="yes"/>
+ <point x="310" y="195"/>
+ <point x="291" y="215"/>
+ <point x="263" y="215" type="curve" smooth="yes"/>
+ <point x="238" y="215"/>
+ <point x="215" y="190"/>
+ <point x="215" y="168" type="curve" smooth="yes"/>
+ <point x="215" y="143"/>
+ <point x="238" y="120"/>
+ <point x="263" y="120" type="curve" smooth="yes"/>
+ <point x="289" y="120"/>
+ <point x="310" y="143"/>
+ </contour>
+ <contour>
+ <point x="890" y="748" type="curve" smooth="yes"/>
+ <point x="890" y="774"/>
+ <point x="870" y="796"/>
+ <point x="843" y="796" type="curve" smooth="yes"/>
+ <point x="815" y="796"/>
+ <point x="796" y="773"/>
+ <point x="796" y="748" type="curve" smooth="yes"/>
+ <point x="796" y="724"/>
+ <point x="817" y="700"/>
+ <point x="843" y="700" type="curve" smooth="yes"/>
+ <point x="869" y="700"/>
+ <point x="890" y="722"/>
+ </contour>
+ <contour>
+ <point x="444" y="78" type="curve" smooth="yes"/>
+ <point x="444" y="102"/>
+ <point x="423" y="126"/>
+ <point x="396" y="126" type="curve" smooth="yes"/>
+ <point x="370" y="126"/>
+ <point x="348" y="102"/>
+ <point x="348" y="78" type="curve" smooth="yes"/>
+ <point x="348" y="55"/>
+ <point x="370" y="31"/>
+ <point x="396" y="31" type="curve" smooth="yes"/>
+ <point x="420" y="31"/>
+ <point x="444" y="51"/>
+ </contour>
+ <contour>
+ <point x="758" y="836" type="curve" smooth="yes"/>
+ <point x="758" y="861"/>
+ <point x="737" y="885"/>
+ <point x="710" y="885" type="curve" smooth="yes"/>
+ <point x="684" y="885"/>
+ <point x="663" y="862"/>
+ <point x="663" y="838" type="curve" smooth="yes"/>
+ <point x="663" y="814"/>
+ <point x="683" y="789"/>
+ <point x="710" y="789" type="curve" smooth="yes"/>
+ <point x="734" y="789"/>
+ <point x="758" y="809"/>
+ </contour>
+ <contour>
+ <point x="601" y="47" type="curve" smooth="yes"/>
+ <point x="601" y="73"/>
+ <point x="579" y="95"/>
+ <point x="553" y="95" type="curve" smooth="yes"/>
+ <point x="527" y="95"/>
+ <point x="506" y="73"/>
+ <point x="506" y="47" type="curve" smooth="yes"/>
+ <point x="506" y="21"/>
+ <point x="527" y="0"/>
+ <point x="553" y="0" type="curve" smooth="yes"/>
+ <point x="579" y="0"/>
+ <point x="601" y="21"/>
+ </contour>
+ <contour>
+ <point x="601" y="868" type="curve" smooth="yes"/>
+ <point x="601" y="894"/>
+ <point x="579" y="916"/>
+ <point x="553" y="916" type="curve" smooth="yes"/>
+ <point x="527" y="916"/>
+ <point x="506" y="894"/>
+ <point x="506" y="868" type="curve" smooth="yes"/>
+ <point x="506" y="842"/>
+ <point x="527" y="821"/>
+ <point x="553" y="821" type="curve" smooth="yes"/>
+ <point x="579" y="821"/>
+ <point x="601" y="842"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetkeys.ufo/glyphs/E_qS_gn.glif b/tests/reference/ufo/psfsetkeys.ufo/glyphs/E_qS_gn.glif
new file mode 100644
index 0000000..0461eab
--- /dev/null
+++ b/tests/reference/ufo/psfsetkeys.ufo/glyphs/E_qS_gn.glif
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="EqSgn" format="2">
+ <advance width="1180"/>
+ <unicode hex="003D"/>
+ <outline>
+ <contour>
+ <point x="168" y="436" type="line"/>
+ <point x="1128" y="436" type="line"/>
+ <point x="1180" y="643" type="line"/>
+ <point x="220" y="643" type="line"/>
+ </contour>
+ <contour>
+ <point x="259" y="802" type="line"/>
+ <point x="1219" y="802" type="line"/>
+ <point x="1271" y="1010" type="line"/>
+ <point x="311" y="1010" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetkeys.ufo/glyphs/E_xclamationM_rk.glif b/tests/reference/ufo/psfsetkeys.ufo/glyphs/E_xclamationM_rk.glif
new file mode 100644
index 0000000..167f45e
--- /dev/null
+++ b/tests/reference/ufo/psfsetkeys.ufo/glyphs/E_xclamationM_rk.glif
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="ExclamationMrk" format="2">
+ <advance width="760"/>
+ <unicode hex="0021"/>
+ <outline>
+ <contour>
+ <point x="593" y="495" type="line"/>
+ <point x="670" y="782"/>
+ <point x="736" y="1065"/>
+ <point x="882" y="1495" type="curve"/>
+ <point x="547" y="1495" type="line"/>
+ <point x="478" y="1065"/>
+ <point x="402" y="782"/>
+ <point x="338" y="495" type="curve"/>
+ </contour>
+ <contour>
+ <point x="201" y="116" type="curve" smooth="yes"/>
+ <point x="201" y="35"/>
+ <point x="262" y="-25"/>
+ <point x="348" y="-25" type="curve" smooth="yes"/>
+ <point x="466" y="-25"/>
+ <point x="561" y="71"/>
+ <point x="561" y="181" type="curve" smooth="yes"/>
+ <point x="561" y="261"/>
+ <point x="502" y="322"/>
+ <point x="415" y="322" type="curve" smooth="yes"/>
+ <point x="298" y="322"/>
+ <point x="201" y="226"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetkeys.ufo/glyphs/F_ullS_top.glif b/tests/reference/ufo/psfsetkeys.ufo/glyphs/F_ullS_top.glif
new file mode 100644
index 0000000..cfedcd4
--- /dev/null
+++ b/tests/reference/ufo/psfsetkeys.ufo/glyphs/F_ullS_top.glif
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="FullStop" format="2">
+ <advance width="690"/>
+ <unicode hex="002E"/>
+ <outline>
+ <contour>
+ <point x="171" y="116" type="curve" smooth="yes"/>
+ <point x="171" y="35"/>
+ <point x="232" y="-25"/>
+ <point x="318" y="-25" type="curve" smooth="yes"/>
+ <point x="436" y="-25"/>
+ <point x="531" y="71"/>
+ <point x="531" y="181" type="curve" smooth="yes"/>
+ <point x="531" y="261"/>
+ <point x="472" y="322"/>
+ <point x="385" y="322" type="curve" smooth="yes"/>
+ <point x="268" y="322"/>
+ <point x="171" y="226"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetkeys.ufo/glyphs/G_T_S_gn.glif b/tests/reference/ufo/psfsetkeys.ufo/glyphs/G_T_S_gn.glif
new file mode 100644
index 0000000..6dab866
--- /dev/null
+++ b/tests/reference/ufo/psfsetkeys.ufo/glyphs/G_T_S_gn.glif
@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="GTSgn" format="2">
+ <advance width="1180"/>
+ <unicode hex="003E"/>
+ <outline>
+ <contour>
+ <point x="130" y="243" type="line"/>
+ <point x="1186" y="629" type="line"/>
+ <point x="1233" y="817" type="line"/>
+ <point x="369" y="1203" type="line"/>
+ <point x="313" y="975" type="line"/>
+ <point x="930" y="733" type="line"/>
+ <point x="187" y="470" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetkeys.ufo/glyphs/G_raveA_ccent.glif b/tests/reference/ufo/psfsetkeys.ufo/glyphs/G_raveA_ccent.glif
new file mode 100644
index 0000000..f745b6a
--- /dev/null
+++ b/tests/reference/ufo/psfsetkeys.ufo/glyphs/G_raveA_ccent.glif
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="GraveAccent" format="2">
+ <advance width="620"/>
+ <unicode hex="0060"/>
+ <anchor x="848" y="1635" name="U"/>
+ <outline>
+ <contour>
+ <point x="265" y="1584" type="line"/>
+ <point x="587" y="1188" type="line"/>
+ <point x="817" y="1188" type="line"/>
+ <point x="595" y="1584" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetkeys.ufo/glyphs/H_yphen.glif b/tests/reference/ufo/psfsetkeys.ufo/glyphs/H_yphen.glif
new file mode 100644
index 0000000..810f855
--- /dev/null
+++ b/tests/reference/ufo/psfsetkeys.ufo/glyphs/H_yphen.glif
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="Hyphen" format="2">
+ <advance width="860"/>
+ <unicode hex="2010"/>
+ <anchor x="655" y="1100" name="U"/>
+ <outline>
+ <contour>
+ <point x="139" y="520" type="line"/>
+ <point x="879" y="520" type="line"/>
+ <point x="931" y="728" type="line"/>
+ <point x="191" y="728" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetkeys.ufo/glyphs/H_yphenM_inus.glif b/tests/reference/ufo/psfsetkeys.ufo/glyphs/H_yphenM_inus.glif
new file mode 100644
index 0000000..d8ce949
--- /dev/null
+++ b/tests/reference/ufo/psfsetkeys.ufo/glyphs/H_yphenM_inus.glif
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="HyphenMinus" format="2">
+ <advance width="875"/>
+ <unicode hex="002D"/>
+ <anchor x="665" y="1100" name="U"/>
+ <outline>
+ <contour>
+ <point x="149" y="520" type="line"/>
+ <point x="884" y="520" type="line"/>
+ <point x="936" y="728" type="line"/>
+ <point x="201" y="728" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetkeys.ufo/glyphs/H_yphen_S_oft.glif b/tests/reference/ufo/psfsetkeys.ufo/glyphs/H_yphen_S_oft.glif
new file mode 100644
index 0000000..2f651fa
--- /dev/null
+++ b/tests/reference/ufo/psfsetkeys.ufo/glyphs/H_yphen_S_oft.glif
@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="Hyphen_Soft" format="2">
+ <advance width="875"/>
+ <unicode hex="00AD"/>
+ <anchor x="665" y="1100" name="U"/>
+ <outline>
+ <component base="HyphenMinus"/>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetkeys.ufo/glyphs/L_T_S_gn.glif b/tests/reference/ufo/psfsetkeys.ufo/glyphs/L_T_S_gn.glif
new file mode 100644
index 0000000..b2883d3
--- /dev/null
+++ b/tests/reference/ufo/psfsetkeys.ufo/glyphs/L_T_S_gn.glif
@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LTSgn" format="2">
+ <advance width="1180"/>
+ <unicode hex="003C"/>
+ <outline>
+ <contour>
+ <point x="1127" y="470" type="line"/>
+ <point x="510" y="713" type="line"/>
+ <point x="1253" y="975" type="line"/>
+ <point x="1309" y="1203" type="line"/>
+ <point x="253" y="817" type="line"/>
+ <point x="206" y="629" type="line"/>
+ <point x="1070" y="243" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetkeys.ufo/glyphs/L_ftC_urlyB_rac.glif b/tests/reference/ufo/psfsetkeys.ufo/glyphs/L_ftC_urlyB_rac.glif
new file mode 100644
index 0000000..c92f889
--- /dev/null
+++ b/tests/reference/ufo/psfsetkeys.ufo/glyphs/L_ftC_urlyB_rac.glif
@@ -0,0 +1,50 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LftCurlyBrac" format="2">
+ <advance width="1020"/>
+ <unicode hex="007B"/>
+ <outline>
+ <contour>
+ <point x="790" y="-177" type="line"/>
+ <point x="717" y="-149"/>
+ <point x="597" y="-129"/>
+ <point x="597" y="-79" type="curve" smooth="yes"/>
+ <point x="597" y="16"/>
+ <point x="695" y="378"/>
+ <point x="695" y="435" type="curve" smooth="yes"/>
+ <point x="695" y="476"/>
+ <point x="574" y="568"/>
+ <point x="574" y="605" type="curve" smooth="yes"/>
+ <point x="574" y="644"/>
+ <point x="742" y="733"/>
+ <point x="776" y="777" type="curve" smooth="yes"/>
+ <point x="803" y="812"/>
+ <point x="908" y="1276"/>
+ <point x="953" y="1317" type="curve" smooth="yes"/>
+ <point x="975" y="1337"/>
+ <point x="1090" y="1376"/>
+ <point x="1157" y="1395" type="curve"/>
+ <point x="1165" y="1624" type="line"/>
+ <point x="1031" y="1597"/>
+ <point x="827" y="1546"/>
+ <point x="768" y="1500" type="curve" smooth="yes"/>
+ <point x="677" y="1428"/>
+ <point x="542" y="843"/>
+ <point x="512" y="812" type="curve" smooth="yes"/>
+ <point x="472" y="770"/>
+ <point x="260" y="659"/>
+ <point x="260" y="601" type="curve" smooth="yes"/>
+ <point x="260" y="540"/>
+ <point x="412" y="434"/>
+ <point x="412" y="399" type="curve" smooth="yes"/>
+ <point x="412" y="337"/>
+ <point x="311" y="-52"/>
+ <point x="311" y="-216" type="curve" smooth="yes"/>
+ <point x="311" y="-248"/>
+ <point x="315" y="-271"/>
+ <point x="324" y="-282" type="curve" smooth="yes"/>
+ <point x="362" y="-330"/>
+ <point x="554" y="-379"/>
+ <point x="683" y="-406" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetkeys.ufo/glyphs/L_ftP_aren.glif b/tests/reference/ufo/psfsetkeys.ufo/glyphs/L_ftP_aren.glif
new file mode 100644
index 0000000..42e4531
--- /dev/null
+++ b/tests/reference/ufo/psfsetkeys.ufo/glyphs/L_ftP_aren.glif
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LftParen" format="2">
+ <advance width="840"/>
+ <unicode hex="0028"/>
+ <outline>
+ <contour>
+ <point x="899" y="1624" type="line"/>
+ <point x="586" y="1430"/>
+ <point x="317" y="1081"/>
+ <point x="209" y="649" type="curve" smooth="yes"/>
+ <point x="177" y="521"/>
+ <point x="161" y="397"/>
+ <point x="161" y="277" type="curve" smooth="yes"/>
+ <point x="161" y="20"/>
+ <point x="234" y="-214"/>
+ <point x="373" y="-406" type="curve"/>
+ <point x="565" y="-198" type="line"/>
+ <point x="479" y="-42"/>
+ <point x="436" y="130"/>
+ <point x="436" y="315" type="curve" smooth="yes"/>
+ <point x="436" y="422"/>
+ <point x="450" y="534"/>
+ <point x="479" y="649" type="curve" smooth="yes"/>
+ <point x="559" y="972"/>
+ <point x="715" y="1216"/>
+ <point x="966" y="1411" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetkeys.ufo/glyphs/L_ftS_qrB_rac.glif b/tests/reference/ufo/psfsetkeys.ufo/glyphs/L_ftS_qrB_rac.glif
new file mode 100644
index 0000000..db76a2d
--- /dev/null
+++ b/tests/reference/ufo/psfsetkeys.ufo/glyphs/L_ftS_qrB_rac.glif
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LftSqrBrac" format="2">
+ <advance width="830"/>
+ <unicode hex="005B"/>
+ <outline>
+ <contour>
+ <point x="553" y="-406" type="line"/>
+ <point x="605" y="-198" type="line"/>
+ <point x="365" y="-198" type="line"/>
+ <point x="753" y="1376" type="line"/>
+ <point x="993" y="1376" type="line"/>
+ <point x="1044" y="1584" type="line"/>
+ <point x="524" y="1584" type="line"/>
+ <point x="33" y="-406" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetkeys.ufo/glyphs/L_owL_ine.glif b/tests/reference/ufo/psfsetkeys.ufo/glyphs/L_owL_ine.glif
new file mode 100644
index 0000000..de8a991
--- /dev/null
+++ b/tests/reference/ufo/psfsetkeys.ufo/glyphs/L_owL_ine.glif
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LowLine" format="2">
+ <advance width="1254"/>
+ <unicode hex="005F"/>
+ <outline>
+ <contour>
+ <point x="-146" y="-347" type="line"/>
+ <point x="1127" y="-347" type="line"/>
+ <point x="1179" y="-139" type="line"/>
+ <point x="-94" y="-139" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetkeys.ufo/glyphs/L_tnC_apA_.glif b/tests/reference/ufo/psfsetkeys.ufo/glyphs/L_tnC_apA_.glif
new file mode 100644
index 0000000..592502c
--- /dev/null
+++ b/tests/reference/ufo/psfsetkeys.ufo/glyphs/L_tnC_apA_.glif
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnCapA" format="2">
+ <advance width="1465"/>
+ <unicode hex="0041"/>
+ <anchor x="1215" y="0" name="H"/>
+ <anchor x="647" y="-100" name="L"/>
+ <anchor x="1435" y="0" name="O"/>
+ <anchor x="1054" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="1055" y="0" type="line"/>
+ <point x="1338" y="0" type="line"/>
+ <point x="1322" y="79"/>
+ <point x="1312" y="166"/>
+ <point x="1295" y="351" type="curve" smooth="yes"/>
+ <point x="1198" y="1445" type="line"/>
+ <point x="842" y="1445" type="line"/>
+ <point x="199" y="351" type="line" smooth="yes"/>
+ <point x="89" y="164"/>
+ <point x="37" y="80"/>
+ <point x="-18" y="0" type="curve"/>
+ <point x="290" y="0" type="line"/>
+ <point x="487" y="351" type="line"/>
+ <point x="1031" y="351" type="line"/>
+ </contour>
+ <contour>
+ <point x="973" y="1216" type="line"/>
+ <point x="1016" y="564" type="line"/>
+ <point x="606" y="564" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetkeys.ufo/glyphs/L_tnC_apA_D_iaer.glif b/tests/reference/ufo/psfsetkeys.ufo/glyphs/L_tnC_apA_D_iaer.glif
new file mode 100644
index 0000000..17600b4
--- /dev/null
+++ b/tests/reference/ufo/psfsetkeys.ufo/glyphs/L_tnC_apA_D_iaer.glif
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnCapADiaer" format="2">
+ <advance width="1465"/>
+ <unicode hex="00C4"/>
+ <anchor x="1215" y="0" name="H"/>
+ <anchor x="647" y="-100" name="L"/>
+ <anchor x="1435" y="0" name="O"/>
+ <anchor x="1176" y="2015" name="U"/>
+ <outline>
+ <component base="LtnCapA"/>
+ <component base="CombDiaer" xOffset="1419" yOffset="430"/>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetkeys.ufo/glyphs/L_tnC_apB_.glif b/tests/reference/ufo/psfsetkeys.ufo/glyphs/L_tnC_apB_.glif
new file mode 100644
index 0000000..2b14150
--- /dev/null
+++ b/tests/reference/ufo/psfsetkeys.ufo/glyphs/L_tnC_apB_.glif
@@ -0,0 +1,62 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnCapB" format="2">
+ <advance width="1367"/>
+ <unicode hex="0042"/>
+ <anchor x="585" y="-100" name="L"/>
+ <anchor x="992" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="698" y="1236" type="line"/>
+ <point x="735" y="1237"/>
+ <point x="791" y="1240"/>
+ <point x="860" y="1240" type="curve" smooth="yes"/>
+ <point x="1021" y="1240"/>
+ <point x="1101" y="1179"/>
+ <point x="1101" y="1087" type="curve" smooth="yes"/>
+ <point x="1101" y="932"/>
+ <point x="962" y="866"/>
+ <point x="770" y="866" type="curve" smooth="yes"/>
+ <point x="605" y="866" type="line"/>
+ </contour>
+ <contour>
+ <point x="217" y="450" type="line"/>
+ <point x="168" y="254"/>
+ <point x="124" y="79"/>
+ <point x="90" y="0" type="curve"/>
+ <point x="161" y="-3"/>
+ <point x="368" y="-10"/>
+ <point x="598" y="-10" type="curve" smooth="yes"/>
+ <point x="1055" y="-10"/>
+ <point x="1298" y="206"/>
+ <point x="1298" y="508" type="curve" smooth="yes"/>
+ <point x="1298" y="673"/>
+ <point x="1188" y="759"/>
+ <point x="1072" y="792" type="curve"/>
+ <point x="1254" y="848"/>
+ <point x="1388" y="956"/>
+ <point x="1388" y="1155" type="curve" smooth="yes"/>
+ <point x="1388" y="1359"/>
+ <point x="1181" y="1455"/>
+ <point x="897" y="1455" type="curve" smooth="yes"/>
+ <point x="704" y="1455"/>
+ <point x="549" y="1451"/>
+ <point x="450" y="1445" type="curve"/>
+ <point x="445" y="1366"/>
+ <point x="399" y="1182"/>
+ <point x="351" y="990" type="curve" smooth="yes"/>
+ </contour>
+ <contour>
+ <point x="552" y="651" type="line"/>
+ <point x="745" y="651" type="line" smooth="yes"/>
+ <point x="927" y="651"/>
+ <point x="1019" y="577"/>
+ <point x="1019" y="468" type="curve" smooth="yes"/>
+ <point x="1019" y="295"/>
+ <point x="879" y="213"/>
+ <point x="675" y="213" type="curve" smooth="yes"/>
+ <point x="575" y="213"/>
+ <point x="476" y="216"/>
+ <point x="444" y="218" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetkeys.ufo/glyphs/L_tnC_apC_.glif b/tests/reference/ufo/psfsetkeys.ufo/glyphs/L_tnC_apC_.glif
new file mode 100644
index 0000000..569eba9
--- /dev/null
+++ b/tests/reference/ufo/psfsetkeys.ufo/glyphs/L_tnC_apC_.glif
@@ -0,0 +1,38 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnCapC" format="2">
+ <advance width="1357"/>
+ <unicode hex="0043"/>
+ <anchor x="685" y="0" name="H"/>
+ <anchor x="660" y="-100" name="L"/>
+ <anchor x="1067" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="1286" y="391" type="line"/>
+ <point x="1149" y="280"/>
+ <point x="966" y="218"/>
+ <point x="816" y="218" type="curve" smooth="yes"/>
+ <point x="594" y="218"/>
+ <point x="472" y="349"/>
+ <point x="472" y="588" type="curve" smooth="yes"/>
+ <point x="472" y="922"/>
+ <point x="690" y="1230"/>
+ <point x="1039" y="1230" type="curve" smooth="yes"/>
+ <point x="1170" y="1230"/>
+ <point x="1298" y="1188"/>
+ <point x="1385" y="1093" type="curve"/>
+ <point x="1515" y="1331" type="line"/>
+ <point x="1408" y="1418"/>
+ <point x="1247" y="1470"/>
+ <point x="1073" y="1470" type="curve" smooth="yes"/>
+ <point x="545" y="1470"/>
+ <point x="191" y="1032"/>
+ <point x="191" y="544" type="curve" smooth="yes"/>
+ <point x="191" y="210"/>
+ <point x="404" y="-25"/>
+ <point x="750" y="-25" type="curve" smooth="yes"/>
+ <point x="921" y="-25"/>
+ <point x="1124" y="27"/>
+ <point x="1271" y="124" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetkeys.ufo/glyphs/L_tnC_apD_.glif b/tests/reference/ufo/psfsetkeys.ufo/glyphs/L_tnC_apD_.glif
new file mode 100644
index 0000000..093d346
--- /dev/null
+++ b/tests/reference/ufo/psfsetkeys.ufo/glyphs/L_tnC_apD_.glif
@@ -0,0 +1,51 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnCapD" format="2">
+ <advance width="1465"/>
+ <unicode hex="0044"/>
+ <anchor x="690" y="-100" name="L"/>
+ <anchor x="1122" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="217" y="450" type="line" smooth="yes"/>
+ <point x="167" y="251"/>
+ <point x="124" y="79"/>
+ <point x="90" y="0" type="curve"/>
+ <point x="90" y="0"/>
+ <point x="431" y="-10"/>
+ <point x="566" y="-10" type="curve" smooth="yes"/>
+ <point x="1036" y="-10"/>
+ <point x="1361" y="195"/>
+ <point x="1471" y="648" type="curve" smooth="yes"/>
+ <point x="1494" y="742"/>
+ <point x="1505" y="827"/>
+ <point x="1505" y="902" type="curve" smooth="yes"/>
+ <point x="1505" y="1325"/>
+ <point x="1172" y="1455"/>
+ <point x="912" y="1455" type="curve" smooth="yes"/>
+ <point x="769" y="1455"/>
+ <point x="540" y="1451"/>
+ <point x="450" y="1445" type="curve"/>
+ <point x="445" y="1371"/>
+ <point x="404" y="1205"/>
+ <point x="359" y="1024" type="curve" smooth="yes"/>
+ </contour>
+ <contour>
+ <point x="696" y="1229" type="line"/>
+ <point x="738" y="1231"/>
+ <point x="809" y="1234"/>
+ <point x="864" y="1234" type="curve" smooth="yes"/>
+ <point x="1077" y="1234"/>
+ <point x="1212" y="1104"/>
+ <point x="1212" y="871" type="curve" smooth="yes"/>
+ <point x="1212" y="805"/>
+ <point x="1201" y="731"/>
+ <point x="1181" y="647" type="curve" smooth="yes"/>
+ <point x="1108" y="346"/>
+ <point x="930" y="219"/>
+ <point x="647" y="219" type="curve" smooth="yes"/>
+ <point x="568" y="219"/>
+ <point x="485" y="225"/>
+ <point x="447" y="229" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetkeys.ufo/glyphs/L_tnC_apE_.glif b/tests/reference/ufo/psfsetkeys.ufo/glyphs/L_tnC_apE_.glif
new file mode 100644
index 0000000..8e7a0a1
--- /dev/null
+++ b/tests/reference/ufo/psfsetkeys.ufo/glyphs/L_tnC_apE_.glif
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnCapE" format="2">
+ <advance width="1192"/>
+ <unicode hex="0045"/>
+ <anchor x="550" y="0" name="H"/>
+ <anchor x="525" y="-100" name="L"/>
+ <anchor x="944" y="0" name="O"/>
+ <anchor x="1487" y="1200" name="R"/>
+ <anchor x="932" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="605" y="866" type="line"/>
+ <point x="693" y="1217" type="line"/>
+ <point x="1315" y="1217" type="line"/>
+ <point x="1372" y="1445" type="line"/>
+ <point x="450" y="1445" type="line"/>
+ <point x="444" y="1366"/>
+ <point x="406" y="1210"/>
+ <point x="358" y="1015" type="curve" smooth="yes"/>
+ <point x="212" y="431" type="line" smooth="yes"/>
+ <point x="163" y="236"/>
+ <point x="123" y="79"/>
+ <point x="90" y="0" type="curve"/>
+ <point x="1042" y="0" type="line"/>
+ <point x="1102" y="243" type="line"/>
+ <point x="1021" y="229"/>
+ <point x="895" y="228"/>
+ <point x="704" y="228" type="curve" smooth="yes"/>
+ <point x="446" y="228" type="line"/>
+ <point x="550" y="644" type="line"/>
+ <point x="1097" y="644" type="line"/>
+ <point x="1152" y="866" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetkeys.ufo/glyphs/L_tnC_apF_.glif b/tests/reference/ufo/psfsetkeys.ufo/glyphs/L_tnC_apF_.glif
new file mode 100644
index 0000000..df3370c
--- /dev/null
+++ b/tests/reference/ufo/psfsetkeys.ufo/glyphs/L_tnC_apF_.glif
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnCapF" format="2">
+ <advance width="1180"/>
+ <unicode hex="0046"/>
+ <anchor x="545" y="-100" name="L"/>
+ <anchor x="952" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="602" y="851" type="line"/>
+ <point x="693" y="1217" type="line"/>
+ <point x="1333" y="1217" type="line"/>
+ <point x="1390" y="1445" type="line"/>
+ <point x="450" y="1445" type="line"/>
+ <point x="445" y="1366"/>
+ <point x="405" y="1205"/>
+ <point x="356" y="1010" type="curve" smooth="yes"/>
+ <point x="212" y="431" type="line" smooth="yes"/>
+ <point x="163" y="236"/>
+ <point x="123" y="79"/>
+ <point x="90" y="0" type="curve"/>
+ <point x="405" y="0" type="line"/>
+ <point x="407" y="72"/>
+ <point x="444" y="220"/>
+ <point x="490" y="404" type="curve" smooth="yes"/>
+ <point x="546" y="629" type="line"/>
+ <point x="1101" y="629" type="line"/>
+ <point x="1157" y="851" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetkeys.ufo/glyphs/L_tnC_apG_.glif b/tests/reference/ufo/psfsetkeys.ufo/glyphs/L_tnC_apG_.glif
new file mode 100644
index 0000000..7d36953
--- /dev/null
+++ b/tests/reference/ufo/psfsetkeys.ufo/glyphs/L_tnC_apG_.glif
@@ -0,0 +1,48 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnCapG" format="2">
+ <advance width="1452"/>
+ <unicode hex="0047"/>
+ <anchor x="747" y="0" name="H"/>
+ <anchor x="722" y="-100" name="L"/>
+ <anchor x="1129" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="1480" y="767" type="line"/>
+ <point x="910" y="767" type="line"/>
+ <point x="855" y="544" type="line"/>
+ <point x="1170" y="544" type="line"/>
+ <point x="1104" y="271" type="line"/>
+ <point x="1015" y="231"/>
+ <point x="916" y="218"/>
+ <point x="805" y="218" type="curve" smooth="yes"/>
+ <point x="593" y="218"/>
+ <point x="475" y="352"/>
+ <point x="475" y="567" type="curve" smooth="yes"/>
+ <point x="475" y="633"/>
+ <point x="484" y="708"/>
+ <point x="505" y="789" type="curve" smooth="yes"/>
+ <point x="581" y="1079"/>
+ <point x="802" y="1230"/>
+ <point x="1067" y="1230" type="curve" smooth="yes"/>
+ <point x="1220" y="1230"/>
+ <point x="1334" y="1193"/>
+ <point x="1449" y="1096" type="curve"/>
+ <point x="1594" y="1332" type="line"/>
+ <point x="1447" y="1437"/>
+ <point x="1275" y="1470"/>
+ <point x="1094" y="1470" type="curve" smooth="yes"/>
+ <point x="709" y="1470"/>
+ <point x="345" y="1257"/>
+ <point x="227" y="783" type="curve" smooth="yes"/>
+ <point x="205" y="694"/>
+ <point x="194" y="611"/>
+ <point x="194" y="534" type="curve" smooth="yes"/>
+ <point x="194" y="176"/>
+ <point x="419" y="-25"/>
+ <point x="768" y="-25" type="curve" smooth="yes"/>
+ <point x="940" y="-25"/>
+ <point x="1105" y="10"/>
+ <point x="1325" y="133" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetkeys.ufo/glyphs/L_tnC_apH_.glif b/tests/reference/ufo/psfsetkeys.ufo/glyphs/L_tnC_apH_.glif
new file mode 100644
index 0000000..a49f5fb
--- /dev/null
+++ b/tests/reference/ufo/psfsetkeys.ufo/glyphs/L_tnC_apH_.glif
@@ -0,0 +1,40 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnCapH" format="2">
+ <advance width="1495"/>
+ <unicode hex="0048"/>
+ <anchor x="245" y="0" name="H"/>
+ <anchor x="660" y="-100" name="L"/>
+ <anchor x="1067" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="1340" y="1445" type="line"/>
+ <point x="1192" y="851" type="line"/>
+ <point x="602" y="851" type="line"/>
+ <point x="750" y="1445" type="line"/>
+ <point x="450" y="1445" type="line"/>
+ <point x="445" y="1366"/>
+ <point x="408" y="1215"/>
+ <point x="359" y="1020" type="curve" smooth="yes"/>
+ <point x="211" y="426" type="line" smooth="yes"/>
+ <point x="162" y="231"/>
+ <point x="124" y="79"/>
+ <point x="90" y="0" type="curve"/>
+ <point x="90" y="0"/>
+ <point x="390" y="0"/>
+ <point x="390" y="0" type="curve"/>
+ <point x="546" y="629" type="line"/>
+ <point x="1136" y="629" type="line"/>
+ <point x="980" y="0" type="line"/>
+ <point x="980" y="0"/>
+ <point x="1280" y="0"/>
+ <point x="1280" y="0" type="curve"/>
+ <point x="1284" y="79"/>
+ <point x="1322" y="231"/>
+ <point x="1371" y="426" type="curve" smooth="yes"/>
+ <point x="1519" y="1020" type="line" smooth="yes"/>
+ <point x="1567" y="1215"/>
+ <point x="1605" y="1366"/>
+ <point x="1640" y="1445" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetkeys.ufo/glyphs/L_tnC_apI_.glif b/tests/reference/ufo/psfsetkeys.ufo/glyphs/L_tnC_apI_.glif
new file mode 100644
index 0000000..fc059de
--- /dev/null
+++ b/tests/reference/ufo/psfsetkeys.ufo/glyphs/L_tnC_apI_.glif
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnCapI" format="2">
+ <advance width="1025"/>
+ <unicode hex="0049"/>
+ <anchor x="460" y="0" name="H"/>
+ <anchor x="431" y="-100" name="L"/>
+ <anchor x="652" y="0" name="O"/>
+ <anchor x="1254" y="1200" name="R"/>
+ <anchor x="842" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="430" y="1445" type="line"/>
+ <point x="379" y="1242" type="line"/>
+ <point x="619" y="1242" type="line"/>
+ <point x="360" y="203" type="line"/>
+ <point x="120" y="203" type="line"/>
+ <point x="70" y="0" type="line"/>
+ <point x="835" y="0" type="line"/>
+ <point x="885" y="203" type="line"/>
+ <point x="645" y="203" type="line"/>
+ <point x="904" y="1242" type="line"/>
+ <point x="1144" y="1242" type="line"/>
+ <point x="1195" y="1445" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetkeys.ufo/glyphs/L_tnC_apJ_.glif b/tests/reference/ufo/psfsetkeys.ufo/glyphs/L_tnC_apJ_.glif
new file mode 100644
index 0000000..6a3a604
--- /dev/null
+++ b/tests/reference/ufo/psfsetkeys.ufo/glyphs/L_tnC_apJ_.glif
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnCapJ" format="2">
+ <advance width="1010"/>
+ <unicode hex="004A"/>
+ <anchor x="330" y="-100" name="L"/>
+ <anchor x="1027" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="855" y="1445" type="line"/>
+ <point x="842" y="1340"/>
+ <point x="799" y="1163"/>
+ <point x="751" y="970" type="curve" smooth="yes"/>
+ <point x="647" y="552" type="line" smooth="yes"/>
+ <point x="602" y="370"/>
+ <point x="516" y="225"/>
+ <point x="341" y="225" type="curve" smooth="yes"/>
+ <point x="260" y="225"/>
+ <point x="159" y="267"/>
+ <point x="104" y="344" type="curve"/>
+ <point x="-8" y="89" type="line"/>
+ <point x="51" y="19"/>
+ <point x="191" y="-25"/>
+ <point x="326" y="-25" type="curve" smooth="yes"/>
+ <point x="611" y="-25"/>
+ <point x="826" y="128"/>
+ <point x="927" y="530" type="curve" smooth="yes"/>
+ <point x="947" y="612"/>
+ <point x="1155" y="1445"/>
+ <point x="1155" y="1445" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetkeys.ufo/glyphs/L_tnC_apK_.glif b/tests/reference/ufo/psfsetkeys.ufo/glyphs/L_tnC_apK_.glif
new file mode 100644
index 0000000..44d4d68
--- /dev/null
+++ b/tests/reference/ufo/psfsetkeys.ufo/glyphs/L_tnC_apK_.glif
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnCapK" format="2">
+ <advance width="1410"/>
+ <unicode hex="004B"/>
+ <anchor x="260" y="0" name="H"/>
+ <anchor x="655" y="-100" name="L"/>
+ <anchor x="1047" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="750" y="1445" type="line"/>
+ <point x="450" y="1445" type="line"/>
+ <point x="444" y="1366"/>
+ <point x="406" y="1210"/>
+ <point x="358" y="1015" type="curve" smooth="yes"/>
+ <point x="212" y="431" type="line" smooth="yes"/>
+ <point x="163" y="236"/>
+ <point x="123" y="79"/>
+ <point x="90" y="0" type="curve"/>
+ <point x="390" y="0" type="line"/>
+ </contour>
+ <contour>
+ <point x="1244" y="1445" type="line"/>
+ <point x="461" y="697" type="line"/>
+ <point x="634" y="738" type="line"/>
+ <point x="758" y="724" type="line"/>
+ <point x="1580" y="1445" type="line"/>
+ </contour>
+ <contour>
+ <point x="509" y="724" type="line"/>
+ <point x="950" y="0" type="line"/>
+ <point x="1300" y="0" type="line"/>
+ <point x="738" y="801" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetkeys.ufo/glyphs/L_tnC_apL_.glif b/tests/reference/ufo/psfsetkeys.ufo/glyphs/L_tnC_apL_.glif
new file mode 100644
index 0000000..f8d6959
--- /dev/null
+++ b/tests/reference/ufo/psfsetkeys.ufo/glyphs/L_tnC_apL_.glif
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnCapL" format="2">
+ <advance width="1110"/>
+ <unicode hex="004C"/>
+ <anchor x="560" y="0" name="H"/>
+ <anchor x="535" y="-100" name="L"/>
+ <anchor x="890" y="1200" name="R"/>
+ <anchor x="942" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="446" y="228" type="line"/>
+ <point x="750" y="1445" type="line"/>
+ <point x="450" y="1445" type="line"/>
+ <point x="444" y="1366"/>
+ <point x="406" y="1210"/>
+ <point x="358" y="1015" type="curve" smooth="yes"/>
+ <point x="212" y="431" type="line" smooth="yes"/>
+ <point x="163" y="236"/>
+ <point x="123" y="79"/>
+ <point x="90" y="0" type="curve"/>
+ <point x="1025" y="0" type="line"/>
+ <point x="1085" y="243" type="line"/>
+ <point x="1005" y="229"/>
+ <point x="851" y="228"/>
+ <point x="662" y="228" type="curve" smooth="yes"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetkeys.ufo/glyphs/L_tnC_apM_.glif b/tests/reference/ufo/psfsetkeys.ufo/glyphs/L_tnC_apM_.glif
new file mode 100644
index 0000000..67d1463
--- /dev/null
+++ b/tests/reference/ufo/psfsetkeys.ufo/glyphs/L_tnC_apM_.glif
@@ -0,0 +1,38 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnCapM" format="2">
+ <advance width="1835"/>
+ <unicode hex="004D"/>
+ <anchor x="830" y="-100" name="L"/>
+ <anchor x="1237" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="919" y="272" type="line"/>
+ <point x="865" y="1445" type="line"/>
+ <point x="615" y="1445" type="line"/>
+ <point x="664" y="1158" type="line"/>
+ <point x="710" y="0" type="line"/>
+ <point x="1005" y="0" type="line"/>
+ <point x="1625" y="1158" type="line"/>
+ <point x="1817" y="1445" type="line"/>
+ <point x="1550" y="1445" type="line"/>
+ </contour>
+ <contour>
+ <point x="520" y="1445" type="line"/>
+ <point x="520" y="1445"/>
+ <point x="164" y="196"/>
+ <point x="90" y="0" type="curve"/>
+ <point x="360" y="0" type="line"/>
+ <point x="686" y="1193" type="line"/>
+ <point x="785" y="1445" type="line"/>
+ </contour>
+ <contour>
+ <point x="1630" y="0" type="line"/>
+ <point x="1649" y="196"/>
+ <point x="1910" y="1445"/>
+ <point x="1910" y="1445" type="curve"/>
+ <point x="1640" y="1445" type="line"/>
+ <point x="1622" y="1193" type="line"/>
+ <point x="1360" y="0" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetkeys.ufo/glyphs/L_tnC_apN_.glif b/tests/reference/ufo/psfsetkeys.ufo/glyphs/L_tnC_apN_.glif
new file mode 100644
index 0000000..838490a
--- /dev/null
+++ b/tests/reference/ufo/psfsetkeys.ufo/glyphs/L_tnC_apN_.glif
@@ -0,0 +1,37 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnCapN" format="2">
+ <advance width="1525"/>
+ <unicode hex="004E"/>
+ <anchor x="1180" y="0" name="H"/>
+ <anchor x="680" y="-100" name="L"/>
+ <anchor x="1087" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="506" y="1297" type="line"/>
+ <point x="1035" y="0" type="line"/>
+ <point x="1253" y="148" type="line"/>
+ <point x="725" y="1445" type="line"/>
+ </contour>
+ <contour>
+ <point x="1035" y="0" type="line"/>
+ <point x="1305" y="0" type="line"/>
+ <point x="1558" y="1015" type="line" smooth="yes"/>
+ <point x="1606" y="1210"/>
+ <point x="1646" y="1366"/>
+ <point x="1680" y="1445" type="curve"/>
+ <point x="1395" y="1445" type="line"/>
+ </contour>
+ <contour>
+ <point x="725" y="1445" type="line"/>
+ <point x="440" y="1445" type="line"/>
+ <point x="434" y="1366"/>
+ <point x="396" y="1210"/>
+ <point x="348" y="1015" type="curve" smooth="yes"/>
+ <point x="202" y="431" type="line" smooth="yes"/>
+ <point x="153" y="236"/>
+ <point x="113" y="79"/>
+ <point x="80" y="0" type="curve"/>
+ <point x="365" y="0" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetkeys.ufo/glyphs/L_tnC_apO_.glif b/tests/reference/ufo/psfsetkeys.ufo/glyphs/L_tnC_apO_.glif
new file mode 100644
index 0000000..4410e20
--- /dev/null
+++ b/tests/reference/ufo/psfsetkeys.ufo/glyphs/L_tnC_apO_.glif
@@ -0,0 +1,40 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnCapO" format="2">
+ <advance width="1480"/>
+ <unicode hex="004F"/>
+ <anchor x="680" y="0" name="H"/>
+ <anchor x="655" y="-100" name="L"/>
+ <anchor x="916" y="0" name="O"/>
+ <anchor x="1720" y="1200" name="R"/>
+ <anchor x="1062" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="754" y="218" type="curve" smooth="yes"/>
+ <point x="580" y="218"/>
+ <point x="471" y="345"/>
+ <point x="471" y="568" type="curve" smooth="yes"/>
+ <point x="471" y="922"/>
+ <point x="664" y="1228"/>
+ <point x="966" y="1228" type="curve" smooth="yes"/>
+ <point x="1134" y="1228"/>
+ <point x="1237" y="1106"/>
+ <point x="1237" y="891" type="curve" smooth="yes"/>
+ <point x="1237" y="540"/>
+ <point x="1060" y="218"/>
+ </contour>
+ <contour>
+ <point x="1519" y="911" type="curve" smooth="yes"/>
+ <point x="1519" y="1249"/>
+ <point x="1350" y="1470"/>
+ <point x="1026" y="1470" type="curve" smooth="yes"/>
+ <point x="510" y="1470"/>
+ <point x="191" y="1010"/>
+ <point x="191" y="539" type="curve" smooth="yes"/>
+ <point x="191" y="199"/>
+ <point x="401" y="-25"/>
+ <point x="693" y="-25" type="curve" smooth="yes"/>
+ <point x="1121" y="-25"/>
+ <point x="1519" y="337"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetkeys.ufo/glyphs/L_tnC_apP_.glif b/tests/reference/ufo/psfsetkeys.ufo/glyphs/L_tnC_apP_.glif
new file mode 100644
index 0000000..b0d40c0
--- /dev/null
+++ b/tests/reference/ufo/psfsetkeys.ufo/glyphs/L_tnC_apP_.glif
@@ -0,0 +1,50 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnCapP" format="2">
+ <advance width="1255"/>
+ <unicode hex="0050"/>
+ <anchor x="600" y="-100" name="L"/>
+ <anchor x="970" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="519" y="518" type="line"/>
+ <point x="582" y="511"/>
+ <point x="661" y="508"/>
+ <point x="734" y="508" type="curve" smooth="yes"/>
+ <point x="1118" y="508"/>
+ <point x="1393" y="718"/>
+ <point x="1393" y="1076" type="curve" smooth="yes"/>
+ <point x="1393" y="1306"/>
+ <point x="1215" y="1455"/>
+ <point x="940" y="1455" type="curve" smooth="yes"/>
+ <point x="727" y="1455"/>
+ <point x="450" y="1445"/>
+ <point x="450" y="1445" type="curve"/>
+ <point x="445" y="1366"/>
+ <point x="400" y="1184"/>
+ <point x="351" y="990" type="curve" smooth="yes"/>
+ <point x="212" y="431" type="line" smooth="yes"/>
+ <point x="164" y="237"/>
+ <point x="124" y="79"/>
+ <point x="90" y="0" type="curve"/>
+ <point x="405" y="0" type="line"/>
+ <point x="410" y="77"/>
+ <point x="448" y="235"/>
+ <point x="497" y="431" type="curve" smooth="yes"/>
+ </contour>
+ <contour>
+ <point x="696" y="1228" type="line"/>
+ <point x="752" y="1231"/>
+ <point x="781" y="1233"/>
+ <point x="849" y="1233" type="curve" smooth="yes"/>
+ <point x="1020" y="1233"/>
+ <point x="1103" y="1135"/>
+ <point x="1103" y="1020" type="curve" smooth="yes"/>
+ <point x="1103" y="827"/>
+ <point x="965" y="723"/>
+ <point x="758" y="723" type="curve" smooth="yes"/>
+ <point x="696" y="723"/>
+ <point x="614" y="726"/>
+ <point x="572" y="733" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetkeys.ufo/glyphs/L_tnC_apQ_.glif b/tests/reference/ufo/psfsetkeys.ufo/glyphs/L_tnC_apQ_.glif
new file mode 100644
index 0000000..7013e5f
--- /dev/null
+++ b/tests/reference/ufo/psfsetkeys.ufo/glyphs/L_tnC_apQ_.glif
@@ -0,0 +1,52 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnCapQ" format="2">
+ <advance width="1488"/>
+ <unicode hex="0051"/>
+ <anchor x="619" y="-270" name="L"/>
+ <anchor x="1069" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="1527" y="922" type="curve" smooth="yes"/>
+ <point x="1527" y="1259"/>
+ <point x="1324" y="1470"/>
+ <point x="1029" y="1470" type="curve" smooth="yes"/>
+ <point x="663" y="1470"/>
+ <point x="339" y="1229"/>
+ <point x="221" y="755" type="curve" smooth="yes"/>
+ <point x="201" y="673"/>
+ <point x="191" y="597"/>
+ <point x="191" y="526" type="curve" smooth="yes"/>
+ <point x="191" y="185"/>
+ <point x="410" y="-25"/>
+ <point x="696" y="-25" type="curve" smooth="yes"/>
+ <point x="743" y="-25"/>
+ <point x="787" y="-23"/>
+ <point x="838" y="-15" type="curve"/>
+ <point x="907" y="-15"/>
+ <point x="1162" y="-221"/>
+ <point x="1246" y="-221" type="curve" smooth="yes"/>
+ <point x="1310" y="-221"/>
+ <point x="1422" y="-74"/>
+ <point x="1468" y="-22" type="curve"/>
+ <point x="1331" y="-6"/>
+ <point x="1227" y="60"/>
+ <point x="1115" y="134" type="curve"/>
+ <point x="1312" y="242"/>
+ <point x="1527" y="566"/>
+ </contour>
+ <contour>
+ <point x="757" y="218" type="curve" smooth="yes"/>
+ <point x="563" y="218"/>
+ <point x="471" y="355"/>
+ <point x="471" y="558" type="curve" smooth="yes"/>
+ <point x="471" y="912"/>
+ <point x="677" y="1228"/>
+ <point x="969" y="1228" type="curve" smooth="yes"/>
+ <point x="1147" y="1228"/>
+ <point x="1246" y="1106"/>
+ <point x="1246" y="891" type="curve" smooth="yes"/>
+ <point x="1246" y="560"/>
+ <point x="1053" y="218"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetkeys.ufo/glyphs/L_tnC_apR_.glif b/tests/reference/ufo/psfsetkeys.ufo/glyphs/L_tnC_apR_.glif
new file mode 100644
index 0000000..9133fd2
--- /dev/null
+++ b/tests/reference/ufo/psfsetkeys.ufo/glyphs/L_tnC_apR_.glif
@@ -0,0 +1,55 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnCapR" format="2">
+ <advance width="1360"/>
+ <unicode hex="0052"/>
+ <anchor x="630" y="0" name="H"/>
+ <anchor x="605" y="-100" name="L"/>
+ <anchor x="982" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="534" y="579" type="line"/>
+ <point x="749" y="579" type="line" smooth="yes"/>
+ <point x="1071" y="579"/>
+ <point x="1378" y="761"/>
+ <point x="1378" y="1117" type="curve" smooth="yes"/>
+ <point x="1378" y="1332"/>
+ <point x="1199" y="1455"/>
+ <point x="932" y="1455" type="curve" smooth="yes"/>
+ <point x="698" y="1455"/>
+ <point x="450" y="1445"/>
+ <point x="450" y="1445" type="curve"/>
+ <point x="445" y="1366"/>
+ <point x="400" y="1184"/>
+ <point x="351" y="990" type="curve" smooth="yes"/>
+ <point x="212" y="431" type="line"/>
+ <point x="164" y="236"/>
+ <point x="124" y="79"/>
+ <point x="90" y="0" type="curve"/>
+ <point x="405" y="0" type="line"/>
+ <point x="410" y="77"/>
+ <point x="448" y="236"/>
+ <point x="497" y="431" type="curve"/>
+ </contour>
+ <contour>
+ <point x="696" y="1228" type="line"/>
+ <point x="749" y="1231"/>
+ <point x="764" y="1233"/>
+ <point x="842" y="1233" type="curve" smooth="yes"/>
+ <point x="995" y="1233"/>
+ <point x="1089" y="1167"/>
+ <point x="1089" y="1060" type="curve" smooth="yes"/>
+ <point x="1089" y="899"/>
+ <point x="956" y="792"/>
+ <point x="782" y="792" type="curve" smooth="yes"/>
+ <point x="587" y="792" type="line"/>
+ </contour>
+ <contour>
+ <point x="652" y="629" type="line"/>
+ <point x="915" y="0" type="line"/>
+ <point x="1270" y="0" type="line"/>
+ <point x="1220" y="72"/>
+ <point x="962" y="623"/>
+ <point x="936" y="680" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetkeys.ufo/glyphs/L_tnC_apS_.glif b/tests/reference/ufo/psfsetkeys.ufo/glyphs/L_tnC_apS_.glif
new file mode 100644
index 0000000..79fe933
--- /dev/null
+++ b/tests/reference/ufo/psfsetkeys.ufo/glyphs/L_tnC_apS_.glif
@@ -0,0 +1,50 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnCapS" format="2">
+ <advance width="1223"/>
+ <unicode hex="0053"/>
+ <anchor x="556" y="0" name="H"/>
+ <anchor x="531" y="-100" name="L"/>
+ <anchor x="938" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="1339" y="1361" type="line"/>
+ <point x="1232" y="1430"/>
+ <point x="1086" y="1470"/>
+ <point x="916" y="1470" type="curve" smooth="yes"/>
+ <point x="600" y="1470"/>
+ <point x="332" y="1333"/>
+ <point x="332" y="1053" type="curve" smooth="yes"/>
+ <point x="332" y="889"/>
+ <point x="413" y="800"/>
+ <point x="621" y="658" type="curve" smooth="yes"/>
+ <point x="829" y="516"/>
+ <point x="885" y="448"/>
+ <point x="885" y="374" type="curve" smooth="yes"/>
+ <point x="885" y="276"/>
+ <point x="772" y="218"/>
+ <point x="624" y="218" type="curve" smooth="yes"/>
+ <point x="463" y="218"/>
+ <point x="270" y="340"/>
+ <point x="184" y="461" type="curve"/>
+ <point x="67" y="189" type="line"/>
+ <point x="147" y="91"/>
+ <point x="394" y="-25"/>
+ <point x="573" y="-25" type="curve" smooth="yes"/>
+ <point x="923" y="-25"/>
+ <point x="1182" y="124"/>
+ <point x="1182" y="419" type="curve" smooth="yes"/>
+ <point x="1182" y="584"/>
+ <point x="1077" y="682"/>
+ <point x="881" y="831" type="curve" smooth="yes"/>
+ <point x="728" y="947"/>
+ <point x="628" y="1010"/>
+ <point x="628" y="1082" type="curve" smooth="yes"/>
+ <point x="628" y="1198"/>
+ <point x="790" y="1230"/>
+ <point x="877" y="1230" type="curve" smooth="yes"/>
+ <point x="1018" y="1230"/>
+ <point x="1119" y="1189"/>
+ <point x="1228" y="1099" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetkeys.ufo/glyphs/L_tnC_apT_.glif b/tests/reference/ufo/psfsetkeys.ufo/glyphs/L_tnC_apT_.glif
new file mode 100644
index 0000000..b7aa4cd
--- /dev/null
+++ b/tests/reference/ufo/psfsetkeys.ufo/glyphs/L_tnC_apT_.glif
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnCapT" format="2">
+ <advance width="1255"/>
+ <unicode hex="0054"/>
+ <anchor x="572" y="0" name="H"/>
+ <anchor x="547" y="-100" name="L"/>
+ <anchor x="954" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="345" y="1445" type="line"/>
+ <point x="283" y="1198" type="line"/>
+ <point x="359" y="1215"/>
+ <point x="439" y="1218"/>
+ <point x="519" y="1218" type="curve" smooth="yes"/>
+ <point x="731" y="1218" type="line"/>
+ <point x="529" y="409" type="line" smooth="yes"/>
+ <point x="483" y="224"/>
+ <point x="443" y="75"/>
+ <point x="408" y="0" type="curve"/>
+ <point x="733" y="0" type="line"/>
+ <point x="734" y="75"/>
+ <point x="768" y="224"/>
+ <point x="814" y="409" type="curve" smooth="yes"/>
+ <point x="1016" y="1218" type="line"/>
+ <point x="1232" y="1218" type="line" smooth="yes"/>
+ <point x="1313" y="1218"/>
+ <point x="1390" y="1215"/>
+ <point x="1458" y="1198" type="curve"/>
+ <point x="1520" y="1445" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetkeys.ufo/glyphs/L_tnC_apU_.glif b/tests/reference/ufo/psfsetkeys.ufo/glyphs/L_tnC_apU_.glif
new file mode 100644
index 0000000..a01a283
--- /dev/null
+++ b/tests/reference/ufo/psfsetkeys.ufo/glyphs/L_tnC_apU_.glif
@@ -0,0 +1,44 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnCapU" format="2">
+ <advance width="1470"/>
+ <unicode hex="0055"/>
+ <anchor x="672" y="0" name="H"/>
+ <anchor x="647" y="-100" name="L"/>
+ <anchor x="890" y="0" name="O"/>
+ <anchor x="1720" y="1200" name="R"/>
+ <anchor x="1054" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="1315" y="1445" type="line"/>
+ <point x="1093" y="554" type="line" smooth="yes"/>
+ <point x="1040" y="341"/>
+ <point x="952" y="202"/>
+ <point x="735" y="202" type="curve" smooth="yes"/>
+ <point x="572" y="202"/>
+ <point x="515" y="305"/>
+ <point x="515" y="435" type="curve" smooth="yes"/>
+ <point x="515" y="482"/>
+ <point x="523" y="533"/>
+ <point x="535" y="583" type="curve" smooth="yes"/>
+ <point x="750" y="1445" type="line"/>
+ <point x="450" y="1445" type="line"/>
+ <point x="444" y="1366"/>
+ <point x="406" y="1210"/>
+ <point x="358" y="1015" type="curve" smooth="yes"/>
+ <point x="249" y="570" type="line" smooth="yes"/>
+ <point x="235" y="512"/>
+ <point x="228" y="457"/>
+ <point x="228" y="404" type="curve" smooth="yes"/>
+ <point x="228" y="155"/>
+ <point x="385" y="-25"/>
+ <point x="698" y="-25" type="curve" smooth="yes"/>
+ <point x="1063" y="-25"/>
+ <point x="1275" y="148"/>
+ <point x="1356" y="470" type="curve" smooth="yes"/>
+ <point x="1493" y="1015" type="line" smooth="yes"/>
+ <point x="1544" y="1220"/>
+ <point x="1582" y="1366"/>
+ <point x="1615" y="1445" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetkeys.ufo/glyphs/L_tnC_apV_.glif b/tests/reference/ufo/psfsetkeys.ufo/glyphs/L_tnC_apV_.glif
new file mode 100644
index 0000000..07a71af
--- /dev/null
+++ b/tests/reference/ufo/psfsetkeys.ufo/glyphs/L_tnC_apV_.glif
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnCapV" format="2">
+ <advance width="1445"/>
+ <unicode hex="0056"/>
+ <anchor x="670" y="0" name="H"/>
+ <anchor x="637" y="-100" name="L"/>
+ <anchor x="870" y="0" name="O"/>
+ <anchor x="1044" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="1405" y="1445" type="line"/>
+ <point x="721" y="257" type="line"/>
+ <point x="620" y="1445" type="line"/>
+ <point x="325" y="1445" type="line"/>
+ <point x="339" y="1364"/>
+ <point x="354" y="1275"/>
+ <point x="375" y="1084" type="curve" smooth="yes"/>
+ <point x="495" y="0" type="line"/>
+ <point x="830" y="0" type="line"/>
+ <point x="1490" y="1084" type="line" smooth="yes"/>
+ <point x="1606" y="1276"/>
+ <point x="1664" y="1364"/>
+ <point x="1720" y="1445" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetkeys.ufo/glyphs/L_tnC_apW_.glif b/tests/reference/ufo/psfsetkeys.ufo/glyphs/L_tnC_apW_.glif
new file mode 100644
index 0000000..f0e3607
--- /dev/null
+++ b/tests/reference/ufo/psfsetkeys.ufo/glyphs/L_tnC_apW_.glif
@@ -0,0 +1,45 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnCapW" format="2">
+ <advance width="2115"/>
+ <unicode hex="0057"/>
+ <anchor x="967" y="-100" name="L"/>
+ <anchor x="1374" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="1430" y="0" type="line"/>
+ <point x="1595" y="0" type="line"/>
+ <point x="2165" y="1084" type="line" smooth="yes"/>
+ <point x="2266" y="1277"/>
+ <point x="2318" y="1364"/>
+ <point x="2370" y="1445" type="curve"/>
+ <point x="2050" y="1445" type="line"/>
+ <point x="1432" y="129" type="line"/>
+ </contour>
+ <contour>
+ <point x="1470" y="1445" type="line"/>
+ <point x="1220" y="1445" type="line"/>
+ <point x="1257" y="1292" type="line"/>
+ <point x="1280" y="0" type="line"/>
+ <point x="1450" y="0" type="line"/>
+ <point x="1492" y="129" type="line"/>
+ </contour>
+ <contour>
+ <point x="540" y="0" type="line"/>
+ <point x="705" y="0" type="line"/>
+ <point x="1367" y="1292" type="line"/>
+ <point x="1470" y="1445" type="line"/>
+ <point x="1210" y="1445" type="line"/>
+ <point x="542" y="129" type="line"/>
+ </contour>
+ <contour>
+ <point x="630" y="1445" type="line"/>
+ <point x="330" y="1445" type="line"/>
+ <point x="341" y="1367"/>
+ <point x="349" y="1273"/>
+ <point x="355" y="1084" type="curve" smooth="yes"/>
+ <point x="390" y="0" type="line"/>
+ <point x="560" y="0" type="line"/>
+ <point x="602" y="129" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetkeys.ufo/glyphs/L_tnC_apX_.glif b/tests/reference/ufo/psfsetkeys.ufo/glyphs/L_tnC_apX_.glif
new file mode 100644
index 0000000..633303c
--- /dev/null
+++ b/tests/reference/ufo/psfsetkeys.ufo/glyphs/L_tnC_apX_.glif
@@ -0,0 +1,39 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnCapX" format="2">
+ <advance width="1345"/>
+ <unicode hex="0058"/>
+ <anchor x="585" y="-100" name="L"/>
+ <anchor x="992" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="930" y="0" type="line"/>
+ <point x="1240" y="0" type="line"/>
+ <point x="1199" y="81"/>
+ <point x="1172" y="125"/>
+ <point x="1096" y="333" type="curve" smooth="yes"/>
+ <point x="690" y="1445" type="line"/>
+ <point x="375" y="1445" type="line"/>
+ <point x="418" y="1362"/>
+ <point x="454" y="1304"/>
+ <point x="529" y="1099" type="curve" smooth="yes"/>
+ </contour>
+ <contour>
+ <point x="768" y="938" type="line"/>
+ <point x="269" y="337" type="line" smooth="yes"/>
+ <point x="94" y="126"/>
+ <point x="44" y="85"/>
+ <point x="-40" y="0" type="curve"/>
+ <point x="290" y="0" type="line"/>
+ <point x="790" y="603" type="line"/>
+ </contour>
+ <contour>
+ <point x="830" y="603" type="line"/>
+ <point x="1251" y="1099" type="line" smooth="yes"/>
+ <point x="1423" y="1302"/>
+ <point x="1492" y="1369"/>
+ <point x="1575" y="1445" type="curve"/>
+ <point x="1240" y="1445" type="line"/>
+ <point x="808" y="938" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetkeys.ufo/glyphs/L_tnC_apY_.glif b/tests/reference/ufo/psfsetkeys.ufo/glyphs/L_tnC_apY_.glif
new file mode 100644
index 0000000..49af854
--- /dev/null
+++ b/tests/reference/ufo/psfsetkeys.ufo/glyphs/L_tnC_apY_.glif
@@ -0,0 +1,39 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnCapY" format="2">
+ <advance width="1344"/>
+ <unicode hex="0059"/>
+ <anchor x="587" y="-100" name="L"/>
+ <anchor x="994" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="325" y="1445" type="line"/>
+ <point x="400" y="1298"/>
+ <point x="438" y="1185"/>
+ <point x="482" y="1054" type="curve" smooth="yes"/>
+ <point x="653" y="554" type="line"/>
+ <point x="868" y="668" type="line"/>
+ <point x="637" y="1445" type="line"/>
+ </contour>
+ <contour>
+ <point x="1282" y="1445" type="line"/>
+ <point x="668" y="668" type="line"/>
+ <point x="848" y="554" type="line"/>
+ <point x="1271" y="1054" type="line" smooth="yes"/>
+ <point x="1379" y="1183"/>
+ <point x="1459" y="1278"/>
+ <point x="1619" y="1445" type="curve"/>
+ </contour>
+ <contour>
+ <point x="770" y="0" type="line"/>
+ <point x="774" y="79"/>
+ <point x="813" y="236"/>
+ <point x="862" y="431" type="curve" smooth="yes"/>
+ <point x="926" y="688" type="line"/>
+ <point x="641" y="688" type="line"/>
+ <point x="577" y="431" type="line" smooth="yes"/>
+ <point x="528" y="236"/>
+ <point x="488" y="79"/>
+ <point x="455" y="0" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetkeys.ufo/glyphs/L_tnS_mA_.glif b/tests/reference/ufo/psfsetkeys.ufo/glyphs/L_tnS_mA_.glif
new file mode 100644
index 0000000..0208140
--- /dev/null
+++ b/tests/reference/ufo/psfsetkeys.ufo/glyphs/L_tnS_mA_.glif
@@ -0,0 +1,79 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmA" format="2">
+ <advance width="1185"/>
+ <unicode hex="0061"/>
+ <anchor x="925" y="0" name="H"/>
+ <anchor x="525" y="-100" name="L"/>
+ <anchor x="1125" y="0" name="O"/>
+ <anchor x="1335" y="1000" name="R"/>
+ <anchor x="825" y="1100" name="U"/>
+ <outline>
+ <contour>
+ <point x="1060" y="0" type="line"/>
+ <point x="1054" y="44"/>
+ <point x="1051" y="87"/>
+ <point x="1051" y="133" type="curve" smooth="yes"/>
+ <point x="1051" y="204"/>
+ <point x="1059" y="280"/>
+ <point x="1081" y="366" type="curve"/>
+ <point x="1128" y="557"/>
+ <point x="1156" y="665"/>
+ <point x="1170" y="722" type="curve"/>
+ <point x="1174" y="738"/>
+ <point x="1176" y="754"/>
+ <point x="1176" y="770" type="curve" smooth="yes"/>
+ <point x="1176" y="909"/>
+ <point x="1026" y="1030"/>
+ <point x="791" y="1030" type="curve" smooth="yes"/>
+ <point x="632" y="1030"/>
+ <point x="514" y="994"/>
+ <point x="389" y="940" type="curve"/>
+ <point x="363" y="859"/>
+ <point x="327" y="728"/>
+ <point x="315" y="684" type="curve"/>
+ <point x="452" y="765"/>
+ <point x="565" y="808"/>
+ <point x="673" y="808" type="curve" smooth="yes"/>
+ <point x="809" y="808"/>
+ <point x="885" y="760"/>
+ <point x="885" y="709" type="curve" smooth="yes"/>
+ <point x="885" y="705"/>
+ <point x="884" y="700"/>
+ <point x="883" y="696" type="curve" smooth="yes"/>
+ <point x="872" y="653" type="line"/>
+ <point x="831" y="652"/>
+ <point x="669" y="643"/>
+ <point x="598" y="636" type="curve" smooth="yes"/>
+ <point x="367" y="614"/>
+ <point x="109" y="474"/>
+ <point x="109" y="236" type="curve" smooth="yes"/>
+ <point x="109" y="97"/>
+ <point x="215" y="-25"/>
+ <point x="388" y="-25" type="curve" smooth="yes"/>
+ <point x="505" y="-25"/>
+ <point x="633" y="23"/>
+ <point x="773" y="134" type="curve"/>
+ <point x="773" y="78"/>
+ <point x="784" y="28"/>
+ <point x="790" y="0" type="curve"/>
+ </contour>
+ <contour>
+ <point x="797" y="351" type="line"/>
+ <point x="669" y="223"/>
+ <point x="590" y="203"/>
+ <point x="508" y="203" type="curve" smooth="yes"/>
+ <point x="438" y="203"/>
+ <point x="398" y="246"/>
+ <point x="398" y="299" type="curve" smooth="yes"/>
+ <point x="398" y="308"/>
+ <point x="399" y="317"/>
+ <point x="401" y="326" type="curve" smooth="yes"/>
+ <point x="417" y="391"/>
+ <point x="471" y="438"/>
+ <point x="612" y="452" type="curve" smooth="yes"/>
+ <point x="665" y="458"/>
+ <point x="786" y="469"/>
+ <point x="827" y="470" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetkeys.ufo/glyphs/L_tnS_mA_A_cute.glif b/tests/reference/ufo/psfsetkeys.ufo/glyphs/L_tnS_mA_A_cute.glif
new file mode 100644
index 0000000..a91e18b
--- /dev/null
+++ b/tests/reference/ufo/psfsetkeys.ufo/glyphs/L_tnS_mA_A_cute.glif
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmAAcute" format="2">
+ <advance width="1185"/>
+ <unicode hex="00E1"/>
+ <anchor x="925" y="0" name="H"/>
+ <anchor x="525" y="-100" name="L"/>
+ <anchor x="1125" y="0" name="O"/>
+ <anchor x="1335" y="1000" name="R"/>
+ <anchor x="899" y="1635" name="U"/>
+ <outline>
+ <component base="LtnSmA"/>
+ <component base="CombAcute" xOffset="1150"/>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetkeys.ufo/glyphs/L_tnS_mA_C_ircum.glif b/tests/reference/ufo/psfsetkeys.ufo/glyphs/L_tnS_mA_C_ircum.glif
new file mode 100644
index 0000000..c17afb1
--- /dev/null
+++ b/tests/reference/ufo/psfsetkeys.ufo/glyphs/L_tnS_mA_C_ircum.glif
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmACircum" format="2">
+ <advance width="1185"/>
+ <unicode hex="00E2"/>
+ <anchor x="925" y="0" name="H"/>
+ <anchor x="525" y="-100" name="L"/>
+ <anchor x="1125" y="0" name="O"/>
+ <anchor x="1335" y="1000" name="R"/>
+ <anchor x="916" y="1635" name="U"/>
+ <outline>
+ <component base="LtnSmA"/>
+ <component base="CombCircum" xOffset="1155"/>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetkeys.ufo/glyphs/L_tnS_mA_D_iaer.glif b/tests/reference/ufo/psfsetkeys.ufo/glyphs/L_tnS_mA_D_iaer.glif
new file mode 100644
index 0000000..af45db4
--- /dev/null
+++ b/tests/reference/ufo/psfsetkeys.ufo/glyphs/L_tnS_mA_D_iaer.glif
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmADiaer" format="2">
+ <advance width="1185"/>
+ <unicode hex="00E4"/>
+ <anchor x="925" y="0" name="H"/>
+ <anchor x="525" y="-100" name="L"/>
+ <anchor x="1125" y="0" name="O"/>
+ <anchor x="1335" y="1000" name="R"/>
+ <anchor x="947" y="1585" name="U"/>
+ <outline>
+ <component base="LtnSmA"/>
+ <component base="CombDiaer" xOffset="1190"/>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetkeys.ufo/glyphs/L_tnS_mA_G_rave.glif b/tests/reference/ufo/psfsetkeys.ufo/glyphs/L_tnS_mA_G_rave.glif
new file mode 100644
index 0000000..2374c69
--- /dev/null
+++ b/tests/reference/ufo/psfsetkeys.ufo/glyphs/L_tnS_mA_G_rave.glif
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmAGrave" format="2">
+ <advance width="1185"/>
+ <unicode hex="00E0"/>
+ <anchor x="925" y="0" name="H"/>
+ <anchor x="525" y="-100" name="L"/>
+ <anchor x="1125" y="0" name="O"/>
+ <anchor x="1335" y="1000" name="R"/>
+ <anchor x="999" y="1635" name="U"/>
+ <outline>
+ <component base="LtnSmA"/>
+ <component base="CombGrave" xOffset="1240"/>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetkeys.ufo/glyphs/L_tnS_mA_R_ingA_bv.glif b/tests/reference/ufo/psfsetkeys.ufo/glyphs/L_tnS_mA_R_ingA_bv.glif
new file mode 100644
index 0000000..f8a7dcc
--- /dev/null
+++ b/tests/reference/ufo/psfsetkeys.ufo/glyphs/L_tnS_mA_R_ingA_bv.glif
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmARingAbv" format="2">
+ <advance width="1185"/>
+ <unicode hex="00E5"/>
+ <anchor x="925" y="0" name="H"/>
+ <anchor x="525" y="-100" name="L"/>
+ <anchor x="1125" y="0" name="O"/>
+ <anchor x="1335" y="1000" name="R"/>
+ <anchor x="961" y="1635" name="U"/>
+ <outline>
+ <component base="LtnSmA"/>
+ <component base="CombRingAbv" xOffset="1182"/>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetkeys.ufo/glyphs/L_tnS_mA_T_ilde.glif b/tests/reference/ufo/psfsetkeys.ufo/glyphs/L_tnS_mA_T_ilde.glif
new file mode 100644
index 0000000..4a46027
--- /dev/null
+++ b/tests/reference/ufo/psfsetkeys.ufo/glyphs/L_tnS_mA_T_ilde.glif
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmATilde" format="2">
+ <advance width="1185"/>
+ <unicode hex="00E3"/>
+ <anchor x="925" y="0" name="H"/>
+ <anchor x="525" y="-100" name="L"/>
+ <anchor x="1125" y="0" name="O"/>
+ <anchor x="1335" y="1000" name="R"/>
+ <anchor x="860" y="1490" name="U"/>
+ <outline>
+ <component base="LtnSmA"/>
+ <component base="CombTilde" xOffset="1215"/>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetkeys.ufo/glyphs/L_tnS_mB_.glif b/tests/reference/ufo/psfsetkeys.ufo/glyphs/L_tnS_mB_.glif
new file mode 100644
index 0000000..92bd16b
--- /dev/null
+++ b/tests/reference/ufo/psfsetkeys.ufo/glyphs/L_tnS_mB_.glif
@@ -0,0 +1,55 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmB" format="2">
+ <advance width="1229"/>
+ <unicode hex="0062"/>
+ <anchor x="550" y="0" name="H"/>
+ <anchor x="525" y="-100" name="L"/>
+ <anchor x="1405" y="1000" name="R"/>
+ <anchor x="958" y="1635" name="U"/>
+ <outline>
+ <contour>
+ <point x="482" y="432" type="line"/>
+ <point x="576" y="610"/>
+ <point x="726" y="787"/>
+ <point x="829" y="787" type="curve" smooth="yes"/>
+ <point x="911" y="787"/>
+ <point x="946" y="705"/>
+ <point x="946" y="590" type="curve" smooth="yes"/>
+ <point x="946" y="465"/>
+ <point x="897" y="350"/>
+ <point x="823" y="275" type="curve" smooth="yes"/>
+ <point x="769" y="221"/>
+ <point x="703" y="188"/>
+ <point x="631" y="188" type="curve" smooth="yes"/>
+ <point x="564" y="188"/>
+ <point x="502" y="202"/>
+ <point x="434" y="238" type="curve"/>
+ </contour>
+ <contour>
+ <point x="445" y="1585" type="line"/>
+ <point x="445" y="1439"/>
+ <point x="404" y="1242"/>
+ <point x="367" y="1095" type="curve" smooth="yes"/>
+ <point x="110" y="64" type="line"/>
+ <point x="252" y="16"/>
+ <point x="400" y="-25"/>
+ <point x="593" y="-25" type="curve" smooth="yes"/>
+ <point x="727" y="-25"/>
+ <point x="845" y="19"/>
+ <point x="942" y="91" type="curve" smooth="yes"/>
+ <point x="1122" y="224"/>
+ <point x="1229" y="453"/>
+ <point x="1229" y="672" type="curve" smooth="yes"/>
+ <point x="1229" y="906"/>
+ <point x="1138" y="1030"/>
+ <point x="985" y="1030" type="curve" smooth="yes"/>
+ <point x="822" y="1030"/>
+ <point x="684" y="906"/>
+ <point x="562" y="756" type="curve"/>
+ <point x="646" y="1095" type="line" smooth="yes"/>
+ <point x="686" y="1255"/>
+ <point x="725" y="1474"/>
+ <point x="725" y="1585" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetkeys.ufo/glyphs/L_tnS_mC_.glif b/tests/reference/ufo/psfsetkeys.ufo/glyphs/L_tnS_mC_.glif
new file mode 100644
index 0000000..62c096c
--- /dev/null
+++ b/tests/reference/ufo/psfsetkeys.ufo/glyphs/L_tnS_mC_.glif
@@ -0,0 +1,39 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmC" format="2">
+ <advance width="1019"/>
+ <unicode hex="0063"/>
+ <anchor x="495" y="0" name="H"/>
+ <anchor x="490" y="-100" name="L"/>
+ <anchor x="1210" y="1000" name="R"/>
+ <anchor x="790" y="1100" name="U"/>
+ <outline>
+ <contour>
+ <point x="1099" y="959" type="line"/>
+ <point x="1035" y="997"/>
+ <point x="928" y="1030"/>
+ <point x="796" y="1030" type="curve" smooth="yes"/>
+ <point x="446" y="1030"/>
+ <point x="150" y="774"/>
+ <point x="150" y="386" type="curve" smooth="yes"/>
+ <point x="150" y="137"/>
+ <point x="341" y="-25"/>
+ <point x="569" y="-25" type="curve" smooth="yes"/>
+ <point x="718" y="-25"/>
+ <point x="835" y="11"/>
+ <point x="927" y="69" type="curve"/>
+ <point x="937" y="311" type="line"/>
+ <point x="840" y="238"/>
+ <point x="755" y="203"/>
+ <point x="625" y="203" type="curve" smooth="yes"/>
+ <point x="494" y="203"/>
+ <point x="417" y="302"/>
+ <point x="417" y="416" type="curve" smooth="yes"/>
+ <point x="417" y="661"/>
+ <point x="588" y="802"/>
+ <point x="754" y="802" type="curve" smooth="yes"/>
+ <point x="857" y="802"/>
+ <point x="918" y="781"/>
+ <point x="993" y="720" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetkeys.ufo/glyphs/L_tnS_mD_.glif b/tests/reference/ufo/psfsetkeys.ufo/glyphs/L_tnS_mD_.glif
new file mode 100644
index 0000000..fa38d37
--- /dev/null
+++ b/tests/reference/ufo/psfsetkeys.ufo/glyphs/L_tnS_mD_.glif
@@ -0,0 +1,65 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmD" format="2">
+ <advance width="1265"/>
+ <unicode hex="0064"/>
+ <anchor x="535" y="0" name="H"/>
+ <anchor x="540" y="-100" name="L"/>
+ <anchor x="1475" y="1000" name="R"/>
+ <anchor x="958" y="1635" name="U"/>
+ <outline>
+ <contour>
+ <point x="913" y="558" type="line"/>
+ <point x="861" y="438"/>
+ <point x="666" y="200"/>
+ <point x="560" y="200" type="curve" smooth="yes"/>
+ <point x="470" y="200"/>
+ <point x="427" y="263"/>
+ <point x="427" y="367" type="curve" smooth="yes"/>
+ <point x="427" y="480"/>
+ <point x="469" y="626"/>
+ <point x="554" y="714" type="curve" smooth="yes"/>
+ <point x="599" y="761"/>
+ <point x="657" y="792"/>
+ <point x="727" y="792" type="curve" smooth="yes"/>
+ <point x="820" y="792"/>
+ <point x="876" y="775"/>
+ <point x="957" y="731" type="curve"/>
+ </contour>
+ <contour>
+ <point x="1144" y="1585" type="line"/>
+ <point x="1144" y="1471"/>
+ <point x="1116" y="1327"/>
+ <point x="1079" y="1175" type="curve" smooth="yes"/>
+ <point x="1020" y="935" type="line"/>
+ <point x="949" y="989"/>
+ <point x="845" y="1030"/>
+ <point x="756" y="1030" type="curve" smooth="yes"/>
+ <point x="630" y="1030"/>
+ <point x="518" y="987"/>
+ <point x="426" y="917" type="curve" smooth="yes"/>
+ <point x="250" y="784"/>
+ <point x="145" y="553"/>
+ <point x="145" y="341" type="curve" smooth="yes"/>
+ <point x="145" y="130"/>
+ <point x="258" y="-25"/>
+ <point x="448" y="-25" type="curve" smooth="yes"/>
+ <point x="597" y="-25"/>
+ <point x="785" y="145"/>
+ <point x="867" y="267" type="curve"/>
+ <point x="855" y="181"/>
+ <point x="855" y="72"/>
+ <point x="855" y="0" type="curve"/>
+ <point x="1130" y="0" type="line"/>
+ <point x="1126" y="23"/>
+ <point x="1125" y="63"/>
+ <point x="1125" y="100" type="curve" smooth="yes"/>
+ <point x="1125" y="200"/>
+ <point x="1142" y="340"/>
+ <point x="1185" y="520" type="curve" smooth="yes"/>
+ <point x="1345" y="1190" type="line" smooth="yes"/>
+ <point x="1387" y="1366"/>
+ <point x="1415" y="1490"/>
+ <point x="1415" y="1585" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetkeys.ufo/glyphs/L_tnS_mE_.glif b/tests/reference/ufo/psfsetkeys.ufo/glyphs/L_tnS_mE_.glif
new file mode 100644
index 0000000..49f5856
--- /dev/null
+++ b/tests/reference/ufo/psfsetkeys.ufo/glyphs/L_tnS_mE_.glif
@@ -0,0 +1,52 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmE" format="2">
+ <advance width="1087"/>
+ <unicode hex="0065"/>
+ <anchor x="509" y="0" name="H"/>
+ <anchor x="555" y="-100" name="L"/>
+ <anchor x="840" y="0" name="O"/>
+ <anchor x="1320" y="1000" name="R"/>
+ <anchor x="752" y="1100" name="U"/>
+ <outline>
+ <contour>
+ <point x="1013" y="303" type="line"/>
+ <point x="871" y="230"/>
+ <point x="739" y="198"/>
+ <point x="608" y="198" type="curve" smooth="yes"/>
+ <point x="459" y="198"/>
+ <point x="401" y="297"/>
+ <point x="401" y="428" type="curve" smooth="yes"/>
+ <point x="401" y="683"/>
+ <point x="552" y="822"/>
+ <point x="713" y="822" type="curve" smooth="yes"/>
+ <point x="811" y="822"/>
+ <point x="869" y="782"/>
+ <point x="869" y="720" type="curve" smooth="yes"/>
+ <point x="869" y="635"/>
+ <point x="777" y="580"/>
+ <point x="533" y="580" type="curve" smooth="yes"/>
+ <point x="461" y="580"/>
+ <point x="385" y="589"/>
+ <point x="283" y="610" type="curve"/>
+ <point x="283" y="437" type="line"/>
+ <point x="353" y="422"/>
+ <point x="487" y="413"/>
+ <point x="569" y="413" type="curve" smooth="yes"/>
+ <point x="935" y="413"/>
+ <point x="1125" y="583"/>
+ <point x="1125" y="774" type="curve" smooth="yes"/>
+ <point x="1125" y="922"/>
+ <point x="993" y="1030"/>
+ <point x="769" y="1030" type="curve" smooth="yes"/>
+ <point x="435" y="1030"/>
+ <point x="148" y="775"/>
+ <point x="148" y="388" type="curve" smooth="yes"/>
+ <point x="148" y="135"/>
+ <point x="332" y="-25"/>
+ <point x="556" y="-25" type="curve" smooth="yes"/>
+ <point x="712" y="-25"/>
+ <point x="835" y="2"/>
+ <point x="997" y="74" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetkeys.ufo/glyphs/L_tnS_mF_.glif b/tests/reference/ufo/psfsetkeys.ufo/glyphs/L_tnS_mF_.glif
new file mode 100644
index 0000000..fd86bf3
--- /dev/null
+++ b/tests/reference/ufo/psfsetkeys.ufo/glyphs/L_tnS_mF_.glif
@@ -0,0 +1,44 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmF" format="2">
+ <advance width="859"/>
+ <unicode hex="0066"/>
+ <anchor x="320" y="0" name="H"/>
+ <anchor x="400" y="-100" name="L"/>
+ <anchor x="948" y="1635" name="U"/>
+ <outline>
+ <contour>
+ <point x="180" y="797" type="line"/>
+ <point x="915" y="797" type="line"/>
+ <point x="965" y="995" type="line"/>
+ <point x="230" y="995" type="line"/>
+ </contour>
+ <contour>
+ <point x="1189" y="1534" type="line"/>
+ <point x="1139" y="1572"/>
+ <point x="1040" y="1604"/>
+ <point x="966" y="1604" type="curve" smooth="yes"/>
+ <point x="719" y="1604"/>
+ <point x="535" y="1455"/>
+ <point x="460" y="1158" type="curve" smooth="yes"/>
+ <point x="416" y="983"/>
+ <point x="253" y="334"/>
+ <point x="232" y="0" type="curve"/>
+ <point x="542" y="0" type="line"/>
+ <point x="536" y="28"/>
+ <point x="533" y="66"/>
+ <point x="533" y="110" type="curve" smooth="yes"/>
+ <point x="533" y="213"/>
+ <point x="550" y="356"/>
+ <point x="581" y="489" type="curve" smooth="yes"/>
+ <point x="649" y="784"/>
+ <point x="682" y="926"/>
+ <point x="735" y="1147" type="curve" smooth="yes"/>
+ <point x="774" y="1309"/>
+ <point x="836" y="1373"/>
+ <point x="932" y="1373" type="curve" smooth="yes"/>
+ <point x="981" y="1373"/>
+ <point x="1043" y="1348"/>
+ <point x="1076" y="1309" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetkeys.ufo/glyphs/L_tnS_mG_.glif b/tests/reference/ufo/psfsetkeys.ufo/glyphs/L_tnS_mG_.glif
new file mode 100644
index 0000000..c651c04
--- /dev/null
+++ b/tests/reference/ufo/psfsetkeys.ufo/glyphs/L_tnS_mG_.glif
@@ -0,0 +1,91 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmG" format="2">
+ <advance width="1120"/>
+ <unicode hex="0067"/>
+ <anchor x="420" y="-465" name="H"/>
+ <anchor x="403" y="-535" name="L"/>
+ <anchor x="1360" y="1000" name="R"/>
+ <anchor x="782" y="1100" name="U"/>
+ <outline>
+ <contour>
+ <point x="1027" y="-117" type="curve" smooth="yes"/>
+ <point x="1027" y="8"/>
+ <point x="938" y="114"/>
+ <point x="702" y="163" type="curve" smooth="yes"/>
+ <point x="473" y="210"/>
+ <point x="402" y="217"/>
+ <point x="402" y="249" type="curve" smooth="yes"/>
+ <point x="402" y="279"/>
+ <point x="493" y="321"/>
+ <point x="584" y="346" type="curve"/>
+ <point x="359" y="391" type="line"/>
+ <point x="263" y="354"/>
+ <point x="161" y="283"/>
+ <point x="161" y="188" type="curve" smooth="yes"/>
+ <point x="161" y="101"/>
+ <point x="230" y="4"/>
+ <point x="451" y="-23" type="curve" smooth="yes"/>
+ <point x="669" y="-50"/>
+ <point x="740" y="-97"/>
+ <point x="740" y="-157" type="curve" smooth="yes"/>
+ <point x="740" y="-245"/>
+ <point x="591" y="-299"/>
+ <point x="457" y="-299" type="curve" smooth="yes"/>
+ <point x="286" y="-299"/>
+ <point x="197" y="-233"/>
+ <point x="197" y="-180" type="curve" smooth="yes"/>
+ <point x="197" y="-74"/>
+ <point x="405" y="-4"/>
+ <point x="476" y="20" type="curve"/>
+ <point x="476" y="49"/>
+ <point x="250" y="74"/>
+ <point x="250" y="74" type="curve"/>
+ <point x="103" y="20"/>
+ <point x="-91" y="-65"/>
+ <point x="-91" y="-233" type="curve" smooth="yes"/>
+ <point x="-91" y="-409"/>
+ <point x="166" y="-500"/>
+ <point x="392" y="-500" type="curve" smooth="yes"/>
+ <point x="690" y="-500"/>
+ <point x="1027" y="-380"/>
+ </contour>
+ <contour>
+ <point x="1268" y="1030" type="line"/>
+ <point x="1168" y="1023"/>
+ <point x="1027" y="987"/>
+ <point x="924" y="931" type="curve"/>
+ <point x="946" y="762" type="line"/>
+ <point x="1048" y="800"/>
+ <point x="1132" y="815"/>
+ <point x="1205" y="817" type="curve"/>
+ </contour>
+ <contour>
+ <point x="198" y="627" type="curve" smooth="yes"/>
+ <point x="198" y="450"/>
+ <point x="353" y="302"/>
+ <point x="572" y="302" type="curve" smooth="yes"/>
+ <point x="824" y="302"/>
+ <point x="1087" y="444"/>
+ <point x="1087" y="702" type="curve" smooth="yes"/>
+ <point x="1087" y="874"/>
+ <point x="955" y="1030"/>
+ <point x="703" y="1030" type="curve" smooth="yes"/>
+ <point x="454" y="1030"/>
+ <point x="198" y="881"/>
+ </contour>
+ <contour>
+ <point x="663" y="829" type="curve" smooth="yes"/>
+ <point x="761" y="829"/>
+ <point x="842" y="762"/>
+ <point x="842" y="675" type="curve" smooth="yes"/>
+ <point x="842" y="559"/>
+ <point x="733" y="496"/>
+ <point x="620" y="496" type="curve" smooth="yes"/>
+ <point x="524" y="496"/>
+ <point x="450" y="569"/>
+ <point x="450" y="653" type="curve" smooth="yes"/>
+ <point x="450" y="769"/>
+ <point x="560" y="829"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetkeys.ufo/glyphs/L_tnS_mH_.glif b/tests/reference/ufo/psfsetkeys.ufo/glyphs/L_tnS_mH_.glif
new file mode 100644
index 0000000..7160c61
--- /dev/null
+++ b/tests/reference/ufo/psfsetkeys.ufo/glyphs/L_tnS_mH_.glif
@@ -0,0 +1,54 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmH" format="2">
+ <advance width="1273"/>
+ <unicode hex="0068"/>
+ <anchor x="220" y="0" name="H"/>
+ <anchor x="635" y="-100" name="L"/>
+ <anchor x="968" y="1635" name="U"/>
+ <outline>
+ <contour>
+ <point x="1140" y="0" type="line"/>
+ <point x="1135" y="29"/>
+ <point x="1129" y="60"/>
+ <point x="1129" y="90" type="curve" smooth="yes"/>
+ <point x="1129" y="135"/>
+ <point x="1134" y="170"/>
+ <point x="1141" y="215" type="curve" smooth="yes"/>
+ <point x="1171" y="400"/>
+ <point x="1253" y="590"/>
+ <point x="1253" y="725" type="curve" smooth="yes"/>
+ <point x="1253" y="900"/>
+ <point x="1183" y="1030"/>
+ <point x="990" y="1030" type="curve" smooth="yes"/>
+ <point x="849" y="1030"/>
+ <point x="694" y="902"/>
+ <point x="566" y="740" type="curve"/>
+ <point x="656" y="1095" type="line" smooth="yes"/>
+ <point x="696" y="1255"/>
+ <point x="735" y="1474"/>
+ <point x="735" y="1585" type="curve"/>
+ <point x="455" y="1585" type="line"/>
+ <point x="455" y="1439"/>
+ <point x="413" y="1242"/>
+ <point x="377" y="1095" type="curve" smooth="yes"/>
+ <point x="105" y="0" type="line"/>
+ <point x="385" y="0" type="line"/>
+ <point x="485" y="400" type="line"/>
+ <point x="580" y="596"/>
+ <point x="745" y="787"/>
+ <point x="850" y="787" type="curve" smooth="yes"/>
+ <point x="937" y="787"/>
+ <point x="953" y="722"/>
+ <point x="953" y="625" type="curve" smooth="yes"/>
+ <point x="953" y="529"/>
+ <point x="889" y="374"/>
+ <point x="863" y="213" type="curve" smooth="yes"/>
+ <point x="857" y="174"/>
+ <point x="853" y="134"/>
+ <point x="853" y="95" type="curve" smooth="yes"/>
+ <point x="853" y="63"/>
+ <point x="854" y="31"/>
+ <point x="860" y="0" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetkeys.ufo/glyphs/L_tnS_mI_.glif b/tests/reference/ufo/psfsetkeys.ufo/glyphs/L_tnS_mI_.glif
new file mode 100644
index 0000000..c19769e
--- /dev/null
+++ b/tests/reference/ufo/psfsetkeys.ufo/glyphs/L_tnS_mI_.glif
@@ -0,0 +1,50 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmI" format="2">
+ <advance width="625"/>
+ <unicode hex="0069"/>
+ <anchor x="260" y="0" name="H"/>
+ <anchor x="335" y="-100" name="L"/>
+ <anchor x="520" y="0" name="O"/>
+ <anchor x="830" y="1000" name="R"/>
+ <anchor x="535" y="1100" name="U"/>
+ <outline>
+ <contour>
+ <point x="341" y="1010" type="line"/>
+ <point x="341" y="877"/>
+ <point x="290" y="698"/>
+ <point x="252" y="547" type="curve" smooth="yes"/>
+ <point x="213" y="390" type="line" smooth="yes"/>
+ <point x="193" y="309"/>
+ <point x="170" y="191"/>
+ <point x="170" y="88" type="curve" smooth="yes"/>
+ <point x="170" y="57"/>
+ <point x="172" y="27"/>
+ <point x="177" y="0" type="curve"/>
+ <point x="472" y="0" type="line"/>
+ <point x="463" y="39"/>
+ <point x="459" y="82"/>
+ <point x="459" y="126" type="curve" smooth="yes"/>
+ <point x="459" y="217"/>
+ <point x="475" y="310"/>
+ <point x="486" y="358" type="curve" smooth="yes"/>
+ <point x="531" y="546" type="line" smooth="yes"/>
+ <point x="572" y="719"/>
+ <point x="621" y="875"/>
+ <point x="625" y="1010" type="curve"/>
+ </contour>
+ <contour>
+ <point x="404" y="1341" type="curve" smooth="yes"/>
+ <point x="404" y="1259"/>
+ <point x="462" y="1197"/>
+ <point x="548" y="1197" type="curve" smooth="yes"/>
+ <point x="668" y="1197"/>
+ <point x="759" y="1292"/>
+ <point x="759" y="1403" type="curve" smooth="yes"/>
+ <point x="759" y="1483"/>
+ <point x="701" y="1544"/>
+ <point x="614" y="1544" type="curve" smooth="yes"/>
+ <point x="496" y="1544"/>
+ <point x="404" y="1451"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetkeys.ufo/glyphs/L_tnS_mJ_.glif b/tests/reference/ufo/psfsetkeys.ufo/glyphs/L_tnS_mJ_.glif
new file mode 100644
index 0000000..a454f7a
--- /dev/null
+++ b/tests/reference/ufo/psfsetkeys.ufo/glyphs/L_tnS_mJ_.glif
@@ -0,0 +1,45 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmJ" format="2">
+ <advance width="695"/>
+ <unicode hex="006A"/>
+ <anchor x="-45" y="-500" name="L"/>
+ <anchor x="565" y="1100" name="U"/>
+ <outline>
+ <contour>
+ <point x="361" y="1010" type="line"/>
+ <point x="361" y="866"/>
+ <point x="284" y="395"/>
+ <point x="205" y="87" type="curve" smooth="yes"/>
+ <point x="148" y="-136"/>
+ <point x="54" y="-221"/>
+ <point x="-56" y="-221" type="curve" smooth="yes"/>
+ <point x="-137" y="-221"/>
+ <point x="-217" y="-187"/>
+ <point x="-252" y="-150" type="curve"/>
+ <point x="-355" y="-385" type="line"/>
+ <point x="-321" y="-417"/>
+ <point x="-172" y="-465"/>
+ <point x="-79" y="-465" type="curve" smooth="yes"/>
+ <point x="170" y="-465"/>
+ <point x="388" y="-295"/>
+ <point x="481" y="75" type="curve" smooth="yes"/>
+ <point x="501" y="157"/>
+ <point x="646" y="882"/>
+ <point x="646" y="1010" type="curve"/>
+ </contour>
+ <contour>
+ <point x="395" y="1341" type="curve" smooth="yes"/>
+ <point x="395" y="1259"/>
+ <point x="453" y="1197"/>
+ <point x="539" y="1197" type="curve" smooth="yes"/>
+ <point x="659" y="1197"/>
+ <point x="750" y="1292"/>
+ <point x="750" y="1403" type="curve" smooth="yes"/>
+ <point x="750" y="1483"/>
+ <point x="692" y="1544"/>
+ <point x="605" y="1544" type="curve" smooth="yes"/>
+ <point x="487" y="1544"/>
+ <point x="395" y="1451"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetkeys.ufo/glyphs/L_tnS_mK_.glif b/tests/reference/ufo/psfsetkeys.ufo/glyphs/L_tnS_mK_.glif
new file mode 100644
index 0000000..ed9d720
--- /dev/null
+++ b/tests/reference/ufo/psfsetkeys.ufo/glyphs/L_tnS_mK_.glif
@@ -0,0 +1,45 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmK" format="2">
+ <advance width="1209"/>
+ <unicode hex="006B"/>
+ <anchor x="880" y="0" name="H"/>
+ <anchor x="600" y="-100" name="L"/>
+ <anchor x="1330" y="1000" name="R"/>
+ <anchor x="943" y="1635" name="U"/>
+ <outline>
+ <contour>
+ <point x="964" y="1010" type="line"/>
+ <point x="920" y="864"/>
+ <point x="682" y="702"/>
+ <point x="483" y="576" type="curve"/>
+ <point x="676" y="518" type="line"/>
+ <point x="915" y="662"/>
+ <point x="1289" y="867"/>
+ <point x="1289" y="1010" type="curve"/>
+ </contour>
+ <contour>
+ <point x="1168" y="0" type="line"/>
+ <point x="992" y="302"/>
+ <point x="856" y="620"/>
+ <point x="633" y="620" type="curve"/>
+ <point x="442" y="529" type="line"/>
+ <point x="606" y="529"/>
+ <point x="722" y="252"/>
+ <point x="831" y="0" type="curve"/>
+ </contour>
+ <contour>
+ <point x="394" y="0" type="line"/>
+ <point x="669" y="1105" type="line" smooth="yes"/>
+ <point x="713" y="1280"/>
+ <point x="744" y="1497"/>
+ <point x="744" y="1585" type="curve"/>
+ <point x="462" y="1585" type="line"/>
+ <point x="462" y="1471"/>
+ <point x="431" y="1274"/>
+ <point x="393" y="1122" type="curve" smooth="yes"/>
+ <point x="345" y="928"/>
+ <point x="115" y="0"/>
+ <point x="115" y="0" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetkeys.ufo/glyphs/L_tnS_mL_.glif b/tests/reference/ufo/psfsetkeys.ufo/glyphs/L_tnS_mL_.glif
new file mode 100644
index 0000000..3ecb48c
--- /dev/null
+++ b/tests/reference/ufo/psfsetkeys.ufo/glyphs/L_tnS_mL_.glif
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmL" format="2">
+ <advance width="641"/>
+ <unicode hex="006C"/>
+ <anchor x="275" y="0" name="H"/>
+ <anchor x="350" y="-100" name="L"/>
+ <anchor x="850" y="1000" name="R"/>
+ <anchor x="630" y="1635" name="U"/>
+ <outline>
+ <contour>
+ <point x="461" y="1585" type="line"/>
+ <point x="461" y="1439"/>
+ <point x="420" y="1242"/>
+ <point x="383" y="1095" type="curve" smooth="yes"/>
+ <point x="232" y="488" type="line" smooth="yes"/>
+ <point x="208" y="394"/>
+ <point x="175" y="269"/>
+ <point x="175" y="116" type="curve" smooth="yes"/>
+ <point x="175" y="89"/>
+ <point x="178" y="30"/>
+ <point x="180" y="0" type="curve"/>
+ <point x="470" y="0" type="line"/>
+ <point x="464" y="39"/>
+ <point x="461" y="80"/>
+ <point x="461" y="121" type="curve" smooth="yes"/>
+ <point x="461" y="277"/>
+ <point x="498" y="434"/>
+ <point x="518" y="515" type="curve" smooth="yes"/>
+ <point x="662" y="1095" type="line" smooth="yes"/>
+ <point x="702" y="1255"/>
+ <point x="741" y="1474"/>
+ <point x="741" y="1585" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetkeys.ufo/glyphs/L_tnS_mM_.glif b/tests/reference/ufo/psfsetkeys.ufo/glyphs/L_tnS_mM_.glif
new file mode 100644
index 0000000..6f5967a
--- /dev/null
+++ b/tests/reference/ufo/psfsetkeys.ufo/glyphs/L_tnS_mM_.glif
@@ -0,0 +1,80 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmM" format="2">
+ <advance width="1770"/>
+ <unicode hex="006D"/>
+ <anchor x="830" y="0" name="H"/>
+ <anchor x="805" y="-100" name="L"/>
+ <anchor x="1105" y="1100" name="U"/>
+ <outline>
+ <contour>
+ <point x="1609" y="0" type="line"/>
+ <point x="1604" y="29"/>
+ <point x="1602" y="60"/>
+ <point x="1602" y="90" type="curve" smooth="yes"/>
+ <point x="1602" y="136"/>
+ <point x="1606" y="181"/>
+ <point x="1613" y="228" type="curve" smooth="yes"/>
+ <point x="1628" y="333"/>
+ <point x="1747" y="670"/>
+ <point x="1747" y="822" type="curve" smooth="yes"/>
+ <point x="1747" y="958"/>
+ <point x="1681" y="1030"/>
+ <point x="1547" y="1030" type="curve" smooth="yes"/>
+ <point x="1391" y="1030"/>
+ <point x="1227" y="876"/>
+ <point x="1120" y="705" type="curve"/>
+ <point x="1125" y="738"/>
+ <point x="1127" y="769"/>
+ <point x="1127" y="798" type="curve" smooth="yes"/>
+ <point x="1127" y="944"/>
+ <point x="1067" y="1030"/>
+ <point x="941" y="1030" type="curve" smooth="yes"/>
+ <point x="815" y="1030"/>
+ <point x="664" y="911"/>
+ <point x="537" y="715" type="curve"/>
+ <point x="553" y="840"/>
+ <point x="556" y="911"/>
+ <point x="556" y="955" type="curve" smooth="yes"/>
+ <point x="556" y="981"/>
+ <point x="554" y="998"/>
+ <point x="551" y="1010" type="curve"/>
+ <point x="291" y="1010" type="line"/>
+ <point x="293" y="999"/>
+ <point x="294" y="975"/>
+ <point x="294" y="942" type="curve" smooth="yes"/>
+ <point x="294" y="855"/>
+ <point x="286" y="710"/>
+ <point x="261" y="609" type="curve" smooth="yes"/>
+ <point x="110" y="0" type="line"/>
+ <point x="390" y="0" type="line"/>
+ <point x="479" y="370" type="line"/>
+ <point x="541" y="552"/>
+ <point x="711" y="787"/>
+ <point x="791" y="787" type="curve" smooth="yes"/>
+ <point x="843" y="787"/>
+ <point x="857" y="741"/>
+ <point x="857" y="688" type="curve" smooth="yes"/>
+ <point x="857" y="625"/>
+ <point x="832" y="535"/>
+ <point x="819" y="483" type="curve" smooth="yes"/>
+ <point x="695" y="0" type="line"/>
+ <point x="975" y="0" type="line"/>
+ <point x="1067" y="370" type="line"/>
+ <point x="1139" y="556"/>
+ <point x="1300" y="787"/>
+ <point x="1381" y="787" type="curve" smooth="yes"/>
+ <point x="1434" y="787"/>
+ <point x="1450" y="762"/>
+ <point x="1450" y="706" type="curve" smooth="yes"/>
+ <point x="1450" y="592"/>
+ <point x="1350" y="331"/>
+ <point x="1330" y="205" type="curve" smooth="yes"/>
+ <point x="1324" y="168"/>
+ <point x="1321" y="132"/>
+ <point x="1321" y="95" type="curve" smooth="yes"/>
+ <point x="1321" y="63"/>
+ <point x="1323" y="31"/>
+ <point x="1329" y="0" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetkeys.ufo/glyphs/L_tnS_mN_.glif b/tests/reference/ufo/psfsetkeys.ufo/glyphs/L_tnS_mN_.glif
new file mode 100644
index 0000000..009224e
--- /dev/null
+++ b/tests/reference/ufo/psfsetkeys.ufo/glyphs/L_tnS_mN_.glif
@@ -0,0 +1,57 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmN" format="2">
+ <advance width="1281"/>
+ <unicode hex="006E"/>
+ <anchor x="560" y="0" name="H"/>
+ <anchor x="635" y="-100" name="L"/>
+ <anchor x="835" y="1100" name="U"/>
+ <outline>
+ <contour>
+ <point x="1145" y="0" type="line"/>
+ <point x="1140" y="29"/>
+ <point x="1138" y="60"/>
+ <point x="1138" y="90" type="curve" smooth="yes"/>
+ <point x="1138" y="136"/>
+ <point x="1141" y="182"/>
+ <point x="1149" y="228" type="curve" smooth="yes"/>
+ <point x="1173" y="366"/>
+ <point x="1258" y="591"/>
+ <point x="1258" y="725" type="curve" smooth="yes"/>
+ <point x="1258" y="890"/>
+ <point x="1188" y="1030"/>
+ <point x="995" y="1030" type="curve" smooth="yes"/>
+ <point x="844" y="1030"/>
+ <point x="685" y="903"/>
+ <point x="546" y="715" type="curve"/>
+ <point x="555" y="771"/>
+ <point x="569" y="875"/>
+ <point x="569" y="933" type="curve" smooth="yes"/>
+ <point x="569" y="962"/>
+ <point x="568" y="988"/>
+ <point x="565" y="1010" type="curve"/>
+ <point x="290" y="1010" type="line"/>
+ <point x="290" y="962" type="line" smooth="yes"/>
+ <point x="290" y="859"/>
+ <point x="280" y="685"/>
+ <point x="261" y="609" type="curve" smooth="yes"/>
+ <point x="110" y="0" type="line"/>
+ <point x="388" y="0" type="line"/>
+ <point x="490" y="405" type="line"/>
+ <point x="569" y="569"/>
+ <point x="740" y="787"/>
+ <point x="835" y="787" type="curve" smooth="yes"/>
+ <point x="922" y="787"/>
+ <point x="958" y="732"/>
+ <point x="958" y="625" type="curve" smooth="yes"/>
+ <point x="958" y="527"/>
+ <point x="891" y="369"/>
+ <point x="866" y="205" type="curve" smooth="yes"/>
+ <point x="860" y="168"/>
+ <point x="857" y="132"/>
+ <point x="857" y="95" type="curve" smooth="yes"/>
+ <point x="857" y="63"/>
+ <point x="859" y="31"/>
+ <point x="865" y="0" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetkeys.ufo/glyphs/L_tnS_mO_.glif b/tests/reference/ufo/psfsetkeys.ufo/glyphs/L_tnS_mO_.glif
new file mode 100644
index 0000000..d21fb58
--- /dev/null
+++ b/tests/reference/ufo/psfsetkeys.ufo/glyphs/L_tnS_mO_.glif
@@ -0,0 +1,40 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmO" format="2">
+ <advance width="1139"/>
+ <unicode hex="006F"/>
+ <anchor x="518" y="0" name="H"/>
+ <anchor x="530" y="-100" name="L"/>
+ <anchor x="730" y="0" name="O"/>
+ <anchor x="1350" y="1000" name="R"/>
+ <anchor x="795" y="1100" name="U"/>
+ <outline>
+ <contour>
+ <point x="140" y="370" type="curve" smooth="yes"/>
+ <point x="140" y="128"/>
+ <point x="289" y="-25"/>
+ <point x="520" y="-25" type="curve" smooth="yes"/>
+ <point x="906" y="-25"/>
+ <point x="1144" y="295"/>
+ <point x="1144" y="641" type="curve" smooth="yes"/>
+ <point x="1144" y="880"/>
+ <point x="1003" y="1030"/>
+ <point x="773" y="1030" type="curve" smooth="yes"/>
+ <point x="390" y="1030"/>
+ <point x="140" y="718"/>
+ </contour>
+ <contour>
+ <point x="718" y="807" type="curve" smooth="yes"/>
+ <point x="826" y="807"/>
+ <point x="879" y="737"/>
+ <point x="879" y="612" type="curve" smooth="yes"/>
+ <point x="879" y="413"/>
+ <point x="764" y="198"/>
+ <point x="566" y="198" type="curve" smooth="yes"/>
+ <point x="464" y="198"/>
+ <point x="404" y="264"/>
+ <point x="404" y="385" type="curve" smooth="yes"/>
+ <point x="404" y="570"/>
+ <point x="512" y="807"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetkeys.ufo/glyphs/L_tnS_mP_.glif b/tests/reference/ufo/psfsetkeys.ufo/glyphs/L_tnS_mP_.glif
new file mode 100644
index 0000000..55c6e8b
--- /dev/null
+++ b/tests/reference/ufo/psfsetkeys.ufo/glyphs/L_tnS_mP_.glif
@@ -0,0 +1,66 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmP" format="2">
+ <advance width="1272"/>
+ <unicode hex="0070"/>
+ <anchor x="121" y="-435" name="H"/>
+ <anchor x="555" y="-500" name="L"/>
+ <anchor x="1425" y="1000" name="R"/>
+ <anchor x="855" y="1100" name="U"/>
+ <outline>
+ <contour>
+ <point x="523" y="500" type="line"/>
+ <point x="605" y="650"/>
+ <point x="765" y="794"/>
+ <point x="854" y="794" type="curve" smooth="yes"/>
+ <point x="932" y="794"/>
+ <point x="975" y="719"/>
+ <point x="975" y="609" type="curve" smooth="yes"/>
+ <point x="975" y="478"/>
+ <point x="924" y="334"/>
+ <point x="823" y="258" type="curve" smooth="yes"/>
+ <point x="778" y="224"/>
+ <point x="723" y="204"/>
+ <point x="658" y="204" type="curve" smooth="yes"/>
+ <point x="589" y="204"/>
+ <point x="517" y="243"/>
+ <point x="473" y="297" type="curve"/>
+ </contour>
+ <contour>
+ <point x="300" y="1010" type="line"/>
+ <point x="300" y="962" type="line" smooth="yes"/>
+ <point x="300" y="859"/>
+ <point x="290" y="685"/>
+ <point x="271" y="609" type="curve" smooth="yes"/>
+ <point x="75" y="-180" type="line" smooth="yes"/>
+ <point x="49" y="-286"/>
+ <point x="25" y="-403"/>
+ <point x="25" y="-485" type="curve"/>
+ <point x="314" y="-485" type="line"/>
+ <point x="314" y="-393"/>
+ <point x="328" y="-287"/>
+ <point x="362" y="-149" type="curve" smooth="yes"/>
+ <point x="415" y="64" type="line"/>
+ <point x="495" y="10"/>
+ <point x="562" y="-25"/>
+ <point x="667" y="-25" type="curve" smooth="yes"/>
+ <point x="750" y="-25"/>
+ <point x="833" y="-2"/>
+ <point x="909" y="40" type="curve" smooth="yes"/>
+ <point x="1112" y="152"/>
+ <point x="1267" y="398"/>
+ <point x="1267" y="685" type="curve" smooth="yes"/>
+ <point x="1267" y="884"/>
+ <point x="1176" y="1030"/>
+ <point x="1004" y="1030" type="curve" smooth="yes"/>
+ <point x="849" y="1030"/>
+ <point x="677" y="901"/>
+ <point x="565" y="752" type="curve"/>
+ <point x="574" y="808"/>
+ <point x="579" y="875"/>
+ <point x="579" y="933" type="curve" smooth="yes"/>
+ <point x="579" y="962"/>
+ <point x="578" y="988"/>
+ <point x="575" y="1010" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetkeys.ufo/glyphs/L_tnS_mQ_.glif b/tests/reference/ufo/psfsetkeys.ufo/glyphs/L_tnS_mQ_.glif
new file mode 100644
index 0000000..d3068d2
--- /dev/null
+++ b/tests/reference/ufo/psfsetkeys.ufo/glyphs/L_tnS_mQ_.glif
@@ -0,0 +1,54 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmQ" format="2">
+ <advance width="1206"/>
+ <unicode hex="0071"/>
+ <anchor x="415" y="-500" name="L"/>
+ <anchor x="1400" y="1000" name="R"/>
+ <anchor x="815" y="1100" name="U"/>
+ <outline>
+ <contour>
+ <point x="889" y="583" type="line"/>
+ <point x="832" y="467"/>
+ <point x="615" y="211"/>
+ <point x="520" y="211" type="curve" smooth="yes"/>
+ <point x="457" y="211"/>
+ <point x="429" y="263"/>
+ <point x="429" y="362" type="curve" smooth="yes"/>
+ <point x="429" y="484"/>
+ <point x="469" y="616"/>
+ <point x="551" y="702" type="curve" smooth="yes"/>
+ <point x="605" y="758"/>
+ <point x="676" y="794"/>
+ <point x="765" y="794" type="curve" smooth="yes"/>
+ <point x="806" y="794"/>
+ <point x="897" y="781"/>
+ <point x="933" y="762" type="curve"/>
+ </contour>
+ <contour>
+ <point x="936" y="-485" type="line"/>
+ <point x="936" y="-396"/>
+ <point x="951" y="-299"/>
+ <point x="978" y="-190" type="curve" smooth="yes"/>
+ <point x="1261" y="955" type="line"/>
+ <point x="1134" y="991"/>
+ <point x="972" y="1030"/>
+ <point x="819" y="1030" type="curve" smooth="yes"/>
+ <point x="678" y="1030"/>
+ <point x="516" y="969"/>
+ <point x="403" y="874" type="curve" smooth="yes"/>
+ <point x="244" y="739"/>
+ <point x="145" y="535"/>
+ <point x="145" y="331" type="curve" smooth="yes"/>
+ <point x="145" y="105"/>
+ <point x="275" y="-25"/>
+ <point x="391" y="-25" type="curve" smooth="yes"/>
+ <point x="529" y="-25"/>
+ <point x="729" y="134"/>
+ <point x="838" y="300" type="curve"/>
+ <point x="706" y="-185" type="line" smooth="yes"/>
+ <point x="675" y="-299"/>
+ <point x="661" y="-419"/>
+ <point x="661" y="-485" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetkeys.ufo/glyphs/L_tnS_mR_.glif b/tests/reference/ufo/psfsetkeys.ufo/glyphs/L_tnS_mR_.glif
new file mode 100644
index 0000000..48a3cc8
--- /dev/null
+++ b/tests/reference/ufo/psfsetkeys.ufo/glyphs/L_tnS_mR_.glif
@@ -0,0 +1,42 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmR" format="2">
+ <advance width="1021"/>
+ <unicode hex="0072"/>
+ <anchor x="225" y="0" name="H"/>
+ <anchor x="255" y="-100" name="L"/>
+ <anchor x="765" y="1100" name="U"/>
+ <outline>
+ <contour>
+ <point x="390" y="0" type="line"/>
+ <point x="494" y="420" type="line"/>
+ <point x="555" y="557"/>
+ <point x="727" y="773"/>
+ <point x="810" y="773" type="curve" smooth="yes"/>
+ <point x="864" y="773"/>
+ <point x="887" y="737"/>
+ <point x="887" y="678" type="curve" smooth="yes"/>
+ <point x="887" y="662"/>
+ <point x="885" y="644"/>
+ <point x="882" y="624" type="curve"/>
+ <point x="1114" y="658" type="line"/>
+ <point x="1123" y="706"/>
+ <point x="1136" y="752"/>
+ <point x="1136" y="794" type="curve" smooth="yes"/>
+ <point x="1136" y="931"/>
+ <point x="1084" y="1030"/>
+ <point x="963" y="1030" type="curve" smooth="yes"/>
+ <point x="828" y="1030"/>
+ <point x="670" y="883"/>
+ <point x="544" y="716" type="curve"/>
+ <point x="555" y="787"/>
+ <point x="570" y="960"/>
+ <point x="570" y="1010" type="curve"/>
+ <point x="295" y="1010" type="line"/>
+ <point x="295" y="962" type="line" smooth="yes"/>
+ <point x="295" y="894"/>
+ <point x="281" y="689"/>
+ <point x="261" y="609" type="curve" smooth="yes"/>
+ <point x="110" y="0" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetkeys.ufo/glyphs/L_tnS_mS_.glif b/tests/reference/ufo/psfsetkeys.ufo/glyphs/L_tnS_mS_.glif
new file mode 100644
index 0000000..568c40a
--- /dev/null
+++ b/tests/reference/ufo/psfsetkeys.ufo/glyphs/L_tnS_mS_.glif
@@ -0,0 +1,50 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmS" format="2">
+ <advance width="1015"/>
+ <unicode hex="0073"/>
+ <anchor x="455" y="0" name="H"/>
+ <anchor x="530" y="-100" name="L"/>
+ <anchor x="745" y="1100" name="U"/>
+ <outline>
+ <contour>
+ <point x="1058" y="952" type="line"/>
+ <point x="990" y="990"/>
+ <point x="854" y="1030"/>
+ <point x="691" y="1030" type="curve" smooth="yes"/>
+ <point x="457" y="1030"/>
+ <point x="217" y="936"/>
+ <point x="217" y="722" type="curve" smooth="yes"/>
+ <point x="217" y="593"/>
+ <point x="306" y="517"/>
+ <point x="501" y="430" type="curve" smooth="yes"/>
+ <point x="648" y="364"/>
+ <point x="710" y="345"/>
+ <point x="710" y="288" type="curve" smooth="yes"/>
+ <point x="710" y="224"/>
+ <point x="649" y="197"/>
+ <point x="549" y="197" type="curve" smooth="yes"/>
+ <point x="392" y="197"/>
+ <point x="276" y="280"/>
+ <point x="197" y="371" type="curve"/>
+ <point x="72" y="129" type="line"/>
+ <point x="143" y="68"/>
+ <point x="319" y="-25"/>
+ <point x="498" y="-25" type="curve" smooth="yes"/>
+ <point x="767" y="-25"/>
+ <point x="979" y="104"/>
+ <point x="979" y="315" type="curve" smooth="yes"/>
+ <point x="979" y="440"/>
+ <point x="884" y="513"/>
+ <point x="695" y="600" type="curve" smooth="yes"/>
+ <point x="581" y="652"/>
+ <point x="477" y="688"/>
+ <point x="477" y="743" type="curve" smooth="yes"/>
+ <point x="477" y="785"/>
+ <point x="548" y="808"/>
+ <point x="646" y="808" type="curve" smooth="yes"/>
+ <point x="785" y="808"/>
+ <point x="895" y="764"/>
+ <point x="961" y="716" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetkeys.ufo/glyphs/L_tnS_mT_.glif b/tests/reference/ufo/psfsetkeys.ufo/glyphs/L_tnS_mT_.glif
new file mode 100644
index 0000000..c6a02c1
--- /dev/null
+++ b/tests/reference/ufo/psfsetkeys.ufo/glyphs/L_tnS_mT_.glif
@@ -0,0 +1,45 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmT" format="2">
+ <advance width="900"/>
+ <unicode hex="0074"/>
+ <anchor x="470" y="0" name="H"/>
+ <anchor x="520" y="-100" name="L"/>
+ <anchor x="1075" y="1000" name="R"/>
+ <anchor x="640" y="1360" name="U"/>
+ <outline>
+ <contour>
+ <point x="831" y="278" type="line"/>
+ <point x="740" y="230"/>
+ <point x="670" y="204"/>
+ <point x="619" y="204" type="curve" smooth="yes"/>
+ <point x="556" y="204"/>
+ <point x="536" y="250"/>
+ <point x="536" y="318" type="curve" smooth="yes"/>
+ <point x="536" y="347"/>
+ <point x="539" y="380"/>
+ <point x="545" y="415" type="curve" smooth="yes"/>
+ <point x="567" y="549"/>
+ <point x="700" y="1039"/>
+ <point x="767" y="1307" type="curve"/>
+ <point x="487" y="1307" type="line"/>
+ <point x="419" y="1038"/>
+ <point x="265" y="471"/>
+ <point x="243" y="328" type="curve" smooth="yes"/>
+ <point x="239" y="302"/>
+ <point x="237" y="277"/>
+ <point x="237" y="253" type="curve" smooth="yes"/>
+ <point x="237" y="73"/>
+ <point x="351" y="-25"/>
+ <point x="518" y="-25" type="curve" smooth="yes"/>
+ <point x="590" y="-25"/>
+ <point x="703" y="-4"/>
+ <point x="812" y="55" type="curve"/>
+ </contour>
+ <contour>
+ <point x="945" y="797" type="line"/>
+ <point x="995" y="995" type="line"/>
+ <point x="220" y="995" type="line"/>
+ <point x="170" y="797" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetkeys.ufo/glyphs/L_tnS_mU_.glif b/tests/reference/ufo/psfsetkeys.ufo/glyphs/L_tnS_mU_.glif
new file mode 100644
index 0000000..5067d38
--- /dev/null
+++ b/tests/reference/ufo/psfsetkeys.ufo/glyphs/L_tnS_mU_.glif
@@ -0,0 +1,57 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmU" format="2">
+ <advance width="1257"/>
+ <unicode hex="0075"/>
+ <anchor x="455" y="0" name="H"/>
+ <anchor x="530" y="-100" name="L"/>
+ <anchor x="630" y="0" name="O"/>
+ <anchor x="1448" y="1000" name="R"/>
+ <anchor x="830" y="1100" name="U"/>
+ <outline>
+ <contour>
+ <point x="1117" y="0" type="line"/>
+ <point x="1113" y="29"/>
+ <point x="1112" y="62"/>
+ <point x="1112" y="100" type="curve" smooth="yes"/>
+ <point x="1112" y="206"/>
+ <point x="1131" y="341"/>
+ <point x="1157" y="455" type="curve" smooth="yes"/>
+ <point x="1212" y="689"/>
+ <point x="1274" y="905"/>
+ <point x="1282" y="1010" type="curve"/>
+ <point x="993" y="1010" type="line"/>
+ <point x="981" y="889"/>
+ <point x="992" y="918"/>
+ <point x="910" y="595" type="curve"/>
+ <point x="835" y="427"/>
+ <point x="618" y="205"/>
+ <point x="537" y="205" type="curve" smooth="yes"/>
+ <point x="491" y="205"/>
+ <point x="462" y="236"/>
+ <point x="462" y="308" type="curve" smooth="yes"/>
+ <point x="462" y="405"/>
+ <point x="536" y="663"/>
+ <point x="549" y="712" type="curve" smooth="yes"/>
+ <point x="583" y="847"/>
+ <point x="605" y="935"/>
+ <point x="610" y="1010" type="curve"/>
+ <point x="323" y="1010" type="line"/>
+ <point x="312" y="891"/>
+ <point x="296" y="819"/>
+ <point x="264" y="693" type="curve" smooth="yes"/>
+ <point x="191" y="401" type="line" smooth="yes"/>
+ <point x="173" y="330"/>
+ <point x="165" y="267"/>
+ <point x="165" y="214" type="curve" smooth="yes"/>
+ <point x="165" y="55"/>
+ <point x="252" y="-25"/>
+ <point x="381" y="-25" type="curve" smooth="yes"/>
+ <point x="545" y="-25"/>
+ <point x="769" y="160"/>
+ <point x="860" y="295" type="curve"/>
+ <point x="850" y="227"/>
+ <point x="842" y="53"/>
+ <point x="842" y="0" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetkeys.ufo/glyphs/L_tnS_mV_.glif b/tests/reference/ufo/psfsetkeys.ufo/glyphs/L_tnS_mV_.glif
new file mode 100644
index 0000000..d7ceb46
--- /dev/null
+++ b/tests/reference/ufo/psfsetkeys.ufo/glyphs/L_tnS_mV_.glif
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmV" format="2">
+ <advance width="1049"/>
+ <unicode hex="0076"/>
+ <anchor x="505" y="0" name="H"/>
+ <anchor x="410" y="-100" name="L"/>
+ <anchor x="690" y="0" name="O"/>
+ <anchor x="695" y="1100" name="U"/>
+ <outline>
+ <contour>
+ <point x="881" y="1010" type="line"/>
+ <point x="881" y="788"/>
+ <point x="719" y="534"/>
+ <point x="507" y="270" type="curve"/>
+ <point x="516" y="353"/>
+ <point x="521" y="457"/>
+ <point x="521" y="564" type="curve" smooth="yes"/>
+ <point x="521" y="730"/>
+ <point x="507" y="903"/>
+ <point x="472" y="1010" type="curve"/>
+ <point x="195" y="1010" type="line"/>
+ <point x="259" y="758"/>
+ <point x="282" y="509"/>
+ <point x="282" y="262" type="curve" smooth="yes"/>
+ <point x="282" y="174"/>
+ <point x="279" y="87"/>
+ <point x="274" y="0" type="curve"/>
+ <point x="535" y="0" type="line"/>
+ <point x="823" y="314"/>
+ <point x="1159" y="766"/>
+ <point x="1159" y="1010" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetkeys.ufo/glyphs/L_tnS_mW_.glif b/tests/reference/ufo/psfsetkeys.ufo/glyphs/L_tnS_mW_.glif
new file mode 100644
index 0000000..02f3211
--- /dev/null
+++ b/tests/reference/ufo/psfsetkeys.ufo/glyphs/L_tnS_mW_.glif
@@ -0,0 +1,50 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmW" format="2">
+ <advance width="1620"/>
+ <unicode hex="0077"/>
+ <anchor x="700" y="-100" name="L"/>
+ <anchor x="1000" y="1100" name="U"/>
+ <outline>
+ <contour>
+ <point x="850" y="1010" type="line"/>
+ <point x="758" y="793"/>
+ <point x="592" y="496"/>
+ <point x="438" y="242" type="curve"/>
+ <point x="459" y="351"/>
+ <point x="476" y="509"/>
+ <point x="476" y="669" type="curve" smooth="yes"/>
+ <point x="476" y="788"/>
+ <point x="468" y="908"/>
+ <point x="448" y="1010" type="curve"/>
+ <point x="190" y="1010" type="line"/>
+ <point x="230" y="831"/>
+ <point x="236" y="678"/>
+ <point x="236" y="494" type="curve" smooth="yes"/>
+ <point x="236" y="364"/>
+ <point x="228" y="211"/>
+ <point x="209" y="0" type="curve"/>
+ <point x="499" y="0" type="line"/>
+ <point x="624" y="181"/>
+ <point x="838" y="560"/>
+ <point x="901" y="690" type="curve"/>
+ <point x="919" y="477"/>
+ <point x="919" y="212"/>
+ <point x="919" y="0" type="curve"/>
+ <point x="1179" y="0" type="line"/>
+ <point x="1430" y="328"/>
+ <point x="1710" y="775"/>
+ <point x="1710" y="1010" type="curve"/>
+ <point x="1432" y="1010" type="line"/>
+ <point x="1432" y="995" type="line" smooth="yes"/>
+ <point x="1432" y="797"/>
+ <point x="1245" y="435"/>
+ <point x="1106" y="242" type="curve"/>
+ <point x="1108" y="298"/>
+ <point x="1108" y="355"/>
+ <point x="1108" y="411" type="curve" smooth="yes"/>
+ <point x="1108" y="637"/>
+ <point x="1096" y="860"/>
+ <point x="1070" y="1010" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetkeys.ufo/glyphs/L_tnS_mX_.glif b/tests/reference/ufo/psfsetkeys.ufo/glyphs/L_tnS_mX_.glif
new file mode 100644
index 0000000..2e620de
--- /dev/null
+++ b/tests/reference/ufo/psfsetkeys.ufo/glyphs/L_tnS_mX_.glif
@@ -0,0 +1,40 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmX" format="2">
+ <advance width="1104"/>
+ <unicode hex="0078"/>
+ <anchor x="900" y="0" name="H"/>
+ <anchor x="505" y="-100" name="L"/>
+ <anchor x="730" y="1100" name="U"/>
+ <outline>
+ <contour>
+ <point x="1040" y="0" type="line"/>
+ <point x="860" y="133"/>
+ <point x="655" y="882"/>
+ <point x="524" y="1010" type="curve"/>
+ <point x="186" y="1010" type="line"/>
+ <point x="425" y="832"/>
+ <point x="593" y="141"/>
+ <point x="713" y="0" type="curve"/>
+ </contour>
+ <contour>
+ <point x="509" y="572" type="line"/>
+ <point x="291" y="463"/>
+ <point x="62" y="230"/>
+ <point x="35" y="0" type="curve"/>
+ <point x="335" y="0" type="line"/>
+ <point x="336" y="156"/>
+ <point x="470" y="390"/>
+ <point x="658" y="477" type="curve"/>
+ </contour>
+ <contour>
+ <point x="764" y="471" type="line"/>
+ <point x="943" y="591"/>
+ <point x="1197" y="808"/>
+ <point x="1204" y="1010" type="curve"/>
+ <point x="894" y="1010" type="line"/>
+ <point x="894" y="852"/>
+ <point x="773" y="665"/>
+ <point x="616" y="571" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetkeys.ufo/glyphs/L_tnS_mY_.glif b/tests/reference/ufo/psfsetkeys.ufo/glyphs/L_tnS_mY_.glif
new file mode 100644
index 0000000..f2ae46b
--- /dev/null
+++ b/tests/reference/ufo/psfsetkeys.ufo/glyphs/L_tnS_mY_.glif
@@ -0,0 +1,45 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmY" format="2">
+ <advance width="1041"/>
+ <unicode hex="0079"/>
+ <anchor x="810" y="-100" name="L"/>
+ <anchor x="1325" y="1000" name="R"/>
+ <anchor x="640" y="1100" name="U"/>
+ <outline>
+ <contour>
+ <point x="847" y="1010" type="line"/>
+ <point x="851" y="994"/>
+ <point x="852" y="977"/>
+ <point x="852" y="958" type="curve" smooth="yes"/>
+ <point x="852" y="786"/>
+ <point x="713" y="473"/>
+ <point x="596" y="260" type="curve"/>
+ <point x="596" y="478"/>
+ <point x="503" y="877"/>
+ <point x="403" y="1010" type="curve"/>
+ <point x="120" y="1010" type="line"/>
+ <point x="259" y="811"/>
+ <point x="401" y="401"/>
+ <point x="409" y="-18" type="curve"/>
+ <point x="283" y="-207"/>
+ <point x="183" y="-250"/>
+ <point x="114" y="-250" type="curve" smooth="yes"/>
+ <point x="48" y="-250"/>
+ <point x="-33" y="-201"/>
+ <point x="-63" y="-165" type="curve"/>
+ <point x="-195" y="-381" type="line"/>
+ <point x="-136" y="-435"/>
+ <point x="-13" y="-465"/>
+ <point x="78" y="-465" type="curve" smooth="yes"/>
+ <point x="260" y="-465"/>
+ <point x="447" y="-385"/>
+ <point x="684" y="0" type="curve" smooth="yes"/>
+ <point x="919" y="381"/>
+ <point x="1116" y="766"/>
+ <point x="1116" y="960" type="curve" smooth="yes"/>
+ <point x="1116" y="978"/>
+ <point x="1114" y="995"/>
+ <point x="1110" y="1010" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetkeys.ufo/glyphs/N_onB_reakingH_yphen.glif b/tests/reference/ufo/psfsetkeys.ufo/glyphs/N_onB_reakingH_yphen.glif
new file mode 100644
index 0000000..cd90adf
--- /dev/null
+++ b/tests/reference/ufo/psfsetkeys.ufo/glyphs/N_onB_reakingH_yphen.glif
@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="NonBreakingHyphen" format="2">
+ <advance width="875"/>
+ <unicode hex="2011"/>
+ <anchor x="665" y="1100" name="U"/>
+ <outline>
+ <component base="HyphenMinus"/>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetkeys.ufo/glyphs/N_umS_gn.glif b/tests/reference/ufo/psfsetkeys.ufo/glyphs/N_umS_gn.glif
new file mode 100644
index 0000000..1d3e5e9
--- /dev/null
+++ b/tests/reference/ufo/psfsetkeys.ufo/glyphs/N_umS_gn.glif
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="NumSgn" format="2">
+ <advance width="1180"/>
+ <unicode hex="0023"/>
+ <outline>
+ <contour>
+ <point x="667" y="1346" type="line"/>
+ <point x="16" y="99" type="line"/>
+ <point x="256" y="99" type="line"/>
+ <point x="907" y="1346" type="line"/>
+ </contour>
+ <contour>
+ <point x="54" y="421" type="line"/>
+ <point x="1145" y="421" type="line"/>
+ <point x="1197" y="629" type="line"/>
+ <point x="106" y="629" type="line"/>
+ </contour>
+ <contour>
+ <point x="218" y="841" type="line"/>
+ <point x="1309" y="841" type="line"/>
+ <point x="1361" y="1049" type="line"/>
+ <point x="270" y="1049" type="line"/>
+ </contour>
+ <contour>
+ <point x="1142" y="1346" type="line"/>
+ <point x="491" y="99" type="line"/>
+ <point x="731" y="99" type="line"/>
+ <point x="1382" y="1346" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetkeys.ufo/glyphs/P_ercentS_gn.glif b/tests/reference/ufo/psfsetkeys.ufo/glyphs/P_ercentS_gn.glif
new file mode 100644
index 0000000..f87ea9f
--- /dev/null
+++ b/tests/reference/ufo/psfsetkeys.ufo/glyphs/P_ercentS_gn.glif
@@ -0,0 +1,93 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="PercentSgn" format="2">
+ <advance width="1545"/>
+ <unicode hex="0025"/>
+ <outline>
+ <contour>
+ <point x="1375" y="1465" type="line"/>
+ <point x="221" y="-25" type="line"/>
+ <point x="435" y="-25" type="line"/>
+ <point x="1587" y="1465" type="line"/>
+ </contour>
+ <contour>
+ <point x="714" y="1043" type="curve" smooth="yes"/>
+ <point x="669" y="861"/>
+ <point x="611" y="807"/>
+ <point x="535" y="807" type="curve" smooth="yes"/>
+ <point x="486" y="807"/>
+ <point x="461" y="843"/>
+ <point x="461" y="917" type="curve" smooth="yes"/>
+ <point x="461" y="963"/>
+ <point x="471" y="1023"/>
+ <point x="490" y="1099" type="curve" smooth="yes"/>
+ <point x="535" y="1281"/>
+ <point x="580" y="1336"/>
+ <point x="657" y="1336" type="curve" smooth="yes"/>
+ <point x="710" y="1336"/>
+ <point x="739" y="1296"/>
+ <point x="739" y="1212" type="curve" smooth="yes"/>
+ <point x="739" y="1168"/>
+ <point x="731" y="1111"/>
+ </contour>
+ <contour>
+ <point x="926" y="1054" type="curve" smooth="yes"/>
+ <point x="939" y="1107"/>
+ <point x="946" y="1156"/>
+ <point x="946" y="1199" type="curve" smooth="yes"/>
+ <point x="946" y="1374"/>
+ <point x="842" y="1465"/>
+ <point x="694" y="1465" type="curve" smooth="yes"/>
+ <point x="510" y="1465"/>
+ <point x="346" y="1369"/>
+ <point x="277" y="1090" type="curve" smooth="yes"/>
+ <point x="262" y="1031"/>
+ <point x="255" y="979"/>
+ <point x="255" y="933" type="curve" smooth="yes"/>
+ <point x="255" y="761"/>
+ <point x="353" y="678"/>
+ <point x="499" y="678" type="curve" smooth="yes"/>
+ <point x="684" y="678"/>
+ <point x="853" y="762"/>
+ </contour>
+ <contour>
+ <point x="1314" y="337" type="curve" smooth="yes"/>
+ <point x="1268" y="155"/>
+ <point x="1220" y="104"/>
+ <point x="1144" y="104" type="curve" smooth="yes"/>
+ <point x="1093" y="104"/>
+ <point x="1065" y="144"/>
+ <point x="1065" y="227" type="curve" smooth="yes"/>
+ <point x="1065" y="272"/>
+ <point x="1073" y="329"/>
+ <point x="1090" y="398" type="curve" smooth="yes"/>
+ <point x="1136" y="580"/>
+ <point x="1190" y="634"/>
+ <point x="1267" y="634" type="curve" smooth="yes"/>
+ <point x="1317" y="634"/>
+ <point x="1342" y="596"/>
+ <point x="1342" y="520" type="curve" smooth="yes"/>
+ <point x="1342" y="473"/>
+ <point x="1333" y="412"/>
+ </contour>
+ <contour>
+ <point x="1526" y="350" type="curve" smooth="yes"/>
+ <point x="1540" y="406"/>
+ <point x="1546" y="456"/>
+ <point x="1546" y="501" type="curve" smooth="yes"/>
+ <point x="1546" y="673"/>
+ <point x="1450" y="762"/>
+ <point x="1303" y="762" type="curve" smooth="yes"/>
+ <point x="1119" y="762"/>
+ <point x="946" y="665"/>
+ <point x="876" y="386" type="curve" smooth="yes"/>
+ <point x="862" y="331"/>
+ <point x="856" y="281"/>
+ <point x="856" y="237" type="curve" smooth="yes"/>
+ <point x="856" y="60"/>
+ <point x="960" y="-25"/>
+ <point x="1108" y="-25" type="curve" smooth="yes"/>
+ <point x="1293" y="-25"/>
+ <point x="1453" y="58"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetkeys.ufo/glyphs/P_lusS_gn.glif b/tests/reference/ufo/psfsetkeys.ufo/glyphs/P_lusS_gn.glif
new file mode 100644
index 0000000..bb54e70
--- /dev/null
+++ b/tests/reference/ufo/psfsetkeys.ufo/glyphs/P_lusS_gn.glif
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="PlusSgn" format="2">
+ <advance width="1180"/>
+ <unicode hex="002B"/>
+ <outline>
+ <contour>
+ <point x="722" y="1168" type="line"/>
+ <point x="500" y="282" type="line"/>
+ <point x="715" y="282" type="line"/>
+ <point x="936" y="1168" type="line"/>
+ </contour>
+ <contour>
+ <point x="250" y="624" type="line"/>
+ <point x="1140" y="624" type="line"/>
+ <point x="1192" y="832" type="line"/>
+ <point x="302" y="832" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetkeys.ufo/glyphs/Q_stnM_rk.glif b/tests/reference/ufo/psfsetkeys.ufo/glyphs/Q_stnM_rk.glif
new file mode 100644
index 0000000..5acaded
--- /dev/null
+++ b/tests/reference/ufo/psfsetkeys.ufo/glyphs/Q_stnM_rk.glif
@@ -0,0 +1,49 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="QstnMrk" format="2">
+ <advance width="1070"/>
+ <unicode hex="003F"/>
+ <outline>
+ <contour>
+ <point x="703" y="495" type="line"/>
+ <point x="745" y="664"/>
+ <point x="787" y="792"/>
+ <point x="931" y="933" type="curve" smooth="yes"/>
+ <point x="1034" y="1033"/>
+ <point x="1143" y="1118"/>
+ <point x="1143" y="1256" type="curve" smooth="yes"/>
+ <point x="1143" y="1404"/>
+ <point x="1022" y="1525"/>
+ <point x="800" y="1525" type="curve" smooth="yes"/>
+ <point x="675" y="1525"/>
+ <point x="508" y="1455"/>
+ <point x="427" y="1393" type="curve"/>
+ <point x="413" y="1156" type="line"/>
+ <point x="508" y="1235"/>
+ <point x="621" y="1282"/>
+ <point x="721" y="1282" type="curve" smooth="yes"/>
+ <point x="811" y="1282"/>
+ <point x="846" y="1238"/>
+ <point x="846" y="1189" type="curve" smooth="yes"/>
+ <point x="846" y="1109"/>
+ <point x="760" y="1086"/>
+ <point x="650" y="956" type="curve" smooth="yes"/>
+ <point x="564" y="855"/>
+ <point x="490" y="703"/>
+ <point x="438" y="495" type="curve"/>
+ </contour>
+ <contour>
+ <point x="306" y="116" type="curve" smooth="yes"/>
+ <point x="306" y="35"/>
+ <point x="367" y="-25"/>
+ <point x="453" y="-25" type="curve" smooth="yes"/>
+ <point x="571" y="-25"/>
+ <point x="666" y="71"/>
+ <point x="666" y="181" type="curve" smooth="yes"/>
+ <point x="666" y="261"/>
+ <point x="607" y="322"/>
+ <point x="520" y="322" type="curve" smooth="yes"/>
+ <point x="403" y="322"/>
+ <point x="306" y="226"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetkeys.ufo/glyphs/Q_uotM_rk.glif b/tests/reference/ufo/psfsetkeys.ufo/glyphs/Q_uotM_rk.glif
new file mode 100644
index 0000000..f33fd18
--- /dev/null
+++ b/tests/reference/ufo/psfsetkeys.ufo/glyphs/Q_uotM_rk.glif
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="QuotMrk" format="2">
+ <advance width="1065"/>
+ <unicode hex="0022"/>
+ <outline>
+ <contour>
+ <point x="648" y="1035" type="line"/>
+ <point x="687" y="1174"/>
+ <point x="726" y="1326"/>
+ <point x="816" y="1569" type="curve"/>
+ <point x="571" y="1569" type="line"/>
+ <point x="541" y="1326"/>
+ <point x="503" y="1174"/>
+ <point x="473" y="1035" type="curve"/>
+ </contour>
+ <contour>
+ <point x="1008" y="1035" type="line"/>
+ <point x="1047" y="1174"/>
+ <point x="1086" y="1326"/>
+ <point x="1176" y="1569" type="curve"/>
+ <point x="931" y="1569" type="line"/>
+ <point x="901" y="1326"/>
+ <point x="863" y="1174"/>
+ <point x="833" y="1035" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetkeys.ufo/glyphs/R_everseS_olidus.glif b/tests/reference/ufo/psfsetkeys.ufo/glyphs/R_everseS_olidus.glif
new file mode 100644
index 0000000..0068c20
--- /dev/null
+++ b/tests/reference/ufo/psfsetkeys.ufo/glyphs/R_everseS_olidus.glif
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="ReverseSolidus" format="2">
+ <advance width="1060"/>
+ <unicode hex="005C"/>
+ <outline>
+ <contour>
+ <point x="344" y="1584" type="line"/>
+ <point x="719" y="-243" type="line"/>
+ <point x="949" y="-243" type="line"/>
+ <point x="574" y="1584" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetkeys.ufo/glyphs/R_tC_urlyB_rac.glif b/tests/reference/ufo/psfsetkeys.ufo/glyphs/R_tC_urlyB_rac.glif
new file mode 100644
index 0000000..726adad
--- /dev/null
+++ b/tests/reference/ufo/psfsetkeys.ufo/glyphs/R_tC_urlyB_rac.glif
@@ -0,0 +1,47 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="RtCurlyBrac" format="2">
+ <advance width="1020"/>
+ <unicode hex="007D"/>
+ <outline>
+ <contour>
+ <point x="442" y="1395" type="line"/>
+ <point x="513" y="1366"/>
+ <point x="611" y="1344"/>
+ <point x="611" y="1296" type="curve" smooth="yes"/>
+ <point x="611" y="1200"/>
+ <point x="515" y="837"/>
+ <point x="515" y="782" type="curve" smooth="yes"/>
+ <point x="515" y="743"/>
+ <point x="633" y="649"/>
+ <point x="633" y="613" type="curve" smooth="yes"/>
+ <point x="633" y="573"/>
+ <point x="465" y="486"/>
+ <point x="429" y="441" type="curve" smooth="yes"/>
+ <point x="403" y="407"/>
+ <point x="300" y="-59"/>
+ <point x="255" y="-99" type="curve" smooth="yes"/>
+ <point x="230" y="-121"/>
+ <point x="97" y="-158"/>
+ <point x="25" y="-177" type="curve"/>
+ <point x="17" y="-406" type="line"/>
+ <point x="160" y="-379"/>
+ <point x="377" y="-330"/>
+ <point x="439" y="-282" type="curve" smooth="yes"/>
+ <point x="532" y="-211"/>
+ <point x="666" y="374"/>
+ <point x="696" y="406" type="curve" smooth="yes"/>
+ <point x="734" y="446"/>
+ <point x="947" y="559"/>
+ <point x="947" y="616" type="curve" smooth="yes"/>
+ <point x="947" y="676"/>
+ <point x="796" y="783"/>
+ <point x="796" y="819" type="curve" smooth="yes"/>
+ <point x="796" y="880"/>
+ <point x="896" y="1288"/>
+ <point x="896" y="1453" type="curve" smooth="yes"/>
+ <point x="896" y="1529"/>
+ <point x="709" y="1591"/>
+ <point x="549" y="1624" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetkeys.ufo/glyphs/R_tP_aren.glif b/tests/reference/ufo/psfsetkeys.ufo/glyphs/R_tP_aren.glif
new file mode 100644
index 0000000..544faff
--- /dev/null
+++ b/tests/reference/ufo/psfsetkeys.ufo/glyphs/R_tP_aren.glif
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="RtParen" format="2">
+ <advance width="840"/>
+ <unicode hex="0029"/>
+ <outline>
+ <contour>
+ <point x="476" y="1411" type="line"/>
+ <point x="572" y="1290"/>
+ <point x="616" y="1127"/>
+ <point x="616" y="944" type="curve" smooth="yes"/>
+ <point x="616" y="832"/>
+ <point x="599" y="712"/>
+ <point x="569" y="589" type="curve" smooth="yes"/>
+ <point x="491" y="275"/>
+ <point x="333" y="48"/>
+ <point x="75" y="-198" type="curve"/>
+ <point x="163" y="-406" type="line"/>
+ <point x="509" y="-124"/>
+ <point x="743" y="206"/>
+ <point x="844" y="609" type="curve" smooth="yes"/>
+ <point x="876" y="735"/>
+ <point x="891" y="858"/>
+ <point x="891" y="973" type="curve" smooth="yes"/>
+ <point x="891" y="1252"/>
+ <point x="803" y="1487"/>
+ <point x="649" y="1624" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetkeys.ufo/glyphs/R_tS_qrB_rac.glif b/tests/reference/ufo/psfsetkeys.ufo/glyphs/R_tS_qrB_rac.glif
new file mode 100644
index 0000000..804527d
--- /dev/null
+++ b/tests/reference/ufo/psfsetkeys.ufo/glyphs/R_tS_qrB_rac.glif
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="RtSqrBrac" format="2">
+ <advance width="830"/>
+ <unicode hex="005D"/>
+ <outline>
+ <contour>
+ <point x="503" y="-406" type="line"/>
+ <point x="994" y="1584" type="line"/>
+ <point x="474" y="1584" type="line"/>
+ <point x="423" y="1376" type="line"/>
+ <point x="663" y="1376" type="line"/>
+ <point x="275" y="-198" type="line"/>
+ <point x="35" y="-198" type="line"/>
+ <point x="-17" y="-406" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetkeys.ufo/glyphs/S_emicolon.glif b/tests/reference/ufo/psfsetkeys.ufo/glyphs/S_emicolon.glif
new file mode 100644
index 0000000..1c9af02
--- /dev/null
+++ b/tests/reference/ufo/psfsetkeys.ufo/glyphs/S_emicolon.glif
@@ -0,0 +1,38 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="Semicolon" format="2">
+ <advance width="690"/>
+ <unicode hex="003B"/>
+ <outline>
+ <contour>
+ <point x="137" y="49" type="line"/>
+ <point x="297" y="49" type="line"/>
+ <point x="276" y="-34"/>
+ <point x="192" y="-151"/>
+ <point x="59" y="-262" type="curve"/>
+ <point x="187" y="-332" type="line"/>
+ <point x="337" y="-222"/>
+ <point x="539" y="-11"/>
+ <point x="539" y="165" type="curve" smooth="yes"/>
+ <point x="539" y="262"/>
+ <point x="495" y="337"/>
+ <point x="379" y="337" type="curve" smooth="yes"/>
+ <point x="266" y="337"/>
+ <point x="187" y="252"/>
+ <point x="169" y="178" type="curve" smooth="yes"/>
+ </contour>
+ <contour>
+ <point x="319" y="710" type="curve" smooth="yes"/>
+ <point x="319" y="629"/>
+ <point x="380" y="569"/>
+ <point x="466" y="569" type="curve" smooth="yes"/>
+ <point x="584" y="569"/>
+ <point x="679" y="665"/>
+ <point x="679" y="775" type="curve" smooth="yes"/>
+ <point x="679" y="855"/>
+ <point x="620" y="916"/>
+ <point x="533" y="916" type="curve" smooth="yes"/>
+ <point x="416" y="916"/>
+ <point x="319" y="820"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetkeys.ufo/glyphs/S_olidus.glif b/tests/reference/ufo/psfsetkeys.ufo/glyphs/S_olidus.glif
new file mode 100644
index 0000000..0bac67c
--- /dev/null
+++ b/tests/reference/ufo/psfsetkeys.ufo/glyphs/S_olidus.glif
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="Solidus" format="2">
+ <advance width="1060"/>
+ <unicode hex="002F"/>
+ <outline>
+ <contour>
+ <point x="1164" y="1584" type="line"/>
+ <point x="-120" y="-243" type="line"/>
+ <point x="129" y="-243" type="line"/>
+ <point x="1414" y="1584" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetkeys.ufo/glyphs/S_pace.glif b/tests/reference/ufo/psfsetkeys.ufo/glyphs/S_pace.glif
new file mode 100644
index 0000000..c49f0f2
--- /dev/null
+++ b/tests/reference/ufo/psfsetkeys.ufo/glyphs/S_pace.glif
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="Space" format="2">
+ <advance width="530"/>
+ <unicode hex="0020"/>
+ <outline/>
+</glyph>
diff --git a/tests/reference/ufo/psfsetkeys.ufo/glyphs/T_ilde.glif b/tests/reference/ufo/psfsetkeys.ufo/glyphs/T_ilde.glif
new file mode 100644
index 0000000..26c105f
--- /dev/null
+++ b/tests/reference/ufo/psfsetkeys.ufo/glyphs/T_ilde.glif
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="Tilde" format="2">
+ <advance width="1155"/>
+ <unicode hex="007E"/>
+ <outline>
+ <contour>
+ <point x="190" y="342" type="line"/>
+ <point x="207" y="390"/>
+ <point x="249" y="431"/>
+ <point x="327" y="431" type="curve" smooth="yes"/>
+ <point x="502" y="431"/>
+ <point x="676" y="327"/>
+ <point x="906" y="327" type="curve" smooth="yes"/>
+ <point x="1065" y="327"/>
+ <point x="1206" y="507"/>
+ <point x="1238" y="634" type="curve"/>
+ <point x="1093" y="634" type="line"/>
+ <point x="1074" y="588"/>
+ <point x="1031" y="535"/>
+ <point x="948" y="535" type="curve" smooth="yes"/>
+ <point x="712" y="535"/>
+ <point x="580" y="639"/>
+ <point x="359" y="639" type="curve" smooth="yes"/>
+ <point x="203" y="639"/>
+ <point x="75" y="462"/>
+ <point x="45" y="342" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetkeys.ufo/glyphs/V_ertL_ine.glif b/tests/reference/ufo/psfsetkeys.ufo/glyphs/V_ertL_ine.glif
new file mode 100644
index 0000000..204ac86
--- /dev/null
+++ b/tests/reference/ufo/psfsetkeys.ufo/glyphs/V_ertL_ine.glif
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="VertLine" format="2">
+ <advance width="670"/>
+ <unicode hex="007C"/>
+ <outline>
+ <contour>
+ <point x="574" y="1594" type="line"/>
+ <point x="83" y="-396" type="line"/>
+ <point x="293" y="-396" type="line"/>
+ <point x="784" y="1594" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetkeys.ufo/glyphs/_notdef.glif b/tests/reference/ufo/psfsetkeys.ufo/glyphs/_notdef.glif
new file mode 100644
index 0000000..a3e9354
--- /dev/null
+++ b/tests/reference/ufo/psfsetkeys.ufo/glyphs/_notdef.glif
@@ -0,0 +1,18 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name=".notdef" format="2">
+ <advance width="1400"/>
+ <outline>
+ <contour>
+ <point x="100" y="0" type="line"/>
+ <point x="1300" y="0" type="line"/>
+ <point x="1300" y="1800" type="line"/>
+ <point x="100" y="1800" type="line"/>
+ </contour>
+ <contour>
+ <point x="150" y="1750" type="line"/>
+ <point x="1250" y="1750" type="line"/>
+ <point x="1250" y="50" type="line"/>
+ <point x="150" y="50" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetkeys.ufo/glyphs/_null.glif b/tests/reference/ufo/psfsetkeys.ufo/glyphs/_null.glif
new file mode 100644
index 0000000..0b9caa6
--- /dev/null
+++ b/tests/reference/ufo/psfsetkeys.ufo/glyphs/_null.glif
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name=".null" format="2">
+ <outline/>
+</glyph>
diff --git a/tests/reference/ufo/psfsetkeys.ufo/glyphs/contents.plist b/tests/reference/ufo/psfsetkeys.ufo/glyphs/contents.plist
new file mode 100644
index 0000000..ad2aa41
--- /dev/null
+++ b/tests/reference/ufo/psfsetkeys.ufo/glyphs/contents.plist
@@ -0,0 +1,232 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+ <key>.notdef</key>
+ <string>_notdef.glif</string>
+ <key>.null</key>
+ <string>_null.glif</string>
+ <key>Ampersand</key>
+ <string>A_mpersand.glif</string>
+ <key>Apos</key>
+ <string>A_pos.glif</string>
+ <key>Asterisk</key>
+ <string>A_sterisk.glif</string>
+ <key>AtSgn</key>
+ <string>A_tS_gn.glif</string>
+ <key>CircumAccent</key>
+ <string>C_ircumA_ccent.glif</string>
+ <key>Colon</key>
+ <string>C_olon.glif</string>
+ <key>CombAcute</key>
+ <string>C_ombA_cute.glif</string>
+ <key>CombCircum</key>
+ <string>C_ombC_ircum.glif</string>
+ <key>CombDiaer</key>
+ <string>C_ombD_iaer.glif</string>
+ <key>CombGrave</key>
+ <string>C_ombG_rave.glif</string>
+ <key>CombRingAbv</key>
+ <string>C_ombR_ingA_bv.glif</string>
+ <key>CombTilde</key>
+ <string>C_ombT_ilde.glif</string>
+ <key>Comma</key>
+ <string>C_omma.glif</string>
+ <key>DigitEight</key>
+ <string>D_igitE_ight.glif</string>
+ <key>DigitFive</key>
+ <string>D_igitF_ive.glif</string>
+ <key>DigitFour</key>
+ <string>D_igitF_our.glif</string>
+ <key>DigitNine</key>
+ <string>D_igitN_ine.glif</string>
+ <key>DigitOne</key>
+ <string>D_igitO_ne.glif</string>
+ <key>DigitSeven</key>
+ <string>D_igitS_even.glif</string>
+ <key>DigitSix</key>
+ <string>D_igitS_ix.glif</string>
+ <key>DigitThree</key>
+ <string>D_igitT_hree.glif</string>
+ <key>DigitTwo</key>
+ <string>D_igitT_wo.glif</string>
+ <key>DigitZero</key>
+ <string>D_igitZ_ero.glif</string>
+ <key>DollarSgn</key>
+ <string>D_ollarS_gn.glif</string>
+ <key>DottedCirc</key>
+ <string>D_ottedC_irc.glif</string>
+ <key>EqSgn</key>
+ <string>E_qS_gn.glif</string>
+ <key>ExclamationMrk</key>
+ <string>E_xclamationM_rk.glif</string>
+ <key>FullStop</key>
+ <string>F_ullS_top.glif</string>
+ <key>GTSgn</key>
+ <string>G_T_S_gn.glif</string>
+ <key>GraveAccent</key>
+ <string>G_raveA_ccent.glif</string>
+ <key>Hyphen</key>
+ <string>H_yphen.glif</string>
+ <key>HyphenMinus</key>
+ <string>H_yphenM_inus.glif</string>
+ <key>Hyphen_Soft</key>
+ <string>H_yphen_S_oft.glif</string>
+ <key>LTSgn</key>
+ <string>L_T_S_gn.glif</string>
+ <key>LftCurlyBrac</key>
+ <string>L_ftC_urlyB_rac.glif</string>
+ <key>LftParen</key>
+ <string>L_ftP_aren.glif</string>
+ <key>LftSqrBrac</key>
+ <string>L_ftS_qrB_rac.glif</string>
+ <key>LowLine</key>
+ <string>L_owL_ine.glif</string>
+ <key>LtnCapA</key>
+ <string>L_tnC_apA_.glif</string>
+ <key>LtnCapADiaer</key>
+ <string>L_tnC_apA_D_iaer.glif</string>
+ <key>LtnCapB</key>
+ <string>L_tnC_apB_.glif</string>
+ <key>LtnCapC</key>
+ <string>L_tnC_apC_.glif</string>
+ <key>LtnCapD</key>
+ <string>L_tnC_apD_.glif</string>
+ <key>LtnCapE</key>
+ <string>L_tnC_apE_.glif</string>
+ <key>LtnCapF</key>
+ <string>L_tnC_apF_.glif</string>
+ <key>LtnCapG</key>
+ <string>L_tnC_apG_.glif</string>
+ <key>LtnCapH</key>
+ <string>L_tnC_apH_.glif</string>
+ <key>LtnCapI</key>
+ <string>L_tnC_apI_.glif</string>
+ <key>LtnCapJ</key>
+ <string>L_tnC_apJ_.glif</string>
+ <key>LtnCapK</key>
+ <string>L_tnC_apK_.glif</string>
+ <key>LtnCapL</key>
+ <string>L_tnC_apL_.glif</string>
+ <key>LtnCapM</key>
+ <string>L_tnC_apM_.glif</string>
+ <key>LtnCapN</key>
+ <string>L_tnC_apN_.glif</string>
+ <key>LtnCapO</key>
+ <string>L_tnC_apO_.glif</string>
+ <key>LtnCapP</key>
+ <string>L_tnC_apP_.glif</string>
+ <key>LtnCapQ</key>
+ <string>L_tnC_apQ_.glif</string>
+ <key>LtnCapR</key>
+ <string>L_tnC_apR_.glif</string>
+ <key>LtnCapS</key>
+ <string>L_tnC_apS_.glif</string>
+ <key>LtnCapT</key>
+ <string>L_tnC_apT_.glif</string>
+ <key>LtnCapU</key>
+ <string>L_tnC_apU_.glif</string>
+ <key>LtnCapV</key>
+ <string>L_tnC_apV_.glif</string>
+ <key>LtnCapW</key>
+ <string>L_tnC_apW_.glif</string>
+ <key>LtnCapX</key>
+ <string>L_tnC_apX_.glif</string>
+ <key>LtnCapY</key>
+ <string>L_tnC_apY_.glif</string>
+ <key>LtnSmA</key>
+ <string>L_tnS_mA_.glif</string>
+ <key>LtnSmAAcute</key>
+ <string>L_tnS_mA_A_cute.glif</string>
+ <key>LtnSmACircum</key>
+ <string>L_tnS_mA_C_ircum.glif</string>
+ <key>LtnSmADiaer</key>
+ <string>L_tnS_mA_D_iaer.glif</string>
+ <key>LtnSmAGrave</key>
+ <string>L_tnS_mA_G_rave.glif</string>
+ <key>LtnSmARingAbv</key>
+ <string>L_tnS_mA_R_ingA_bv.glif</string>
+ <key>LtnSmATilde</key>
+ <string>L_tnS_mA_T_ilde.glif</string>
+ <key>LtnSmB</key>
+ <string>L_tnS_mB_.glif</string>
+ <key>LtnSmC</key>
+ <string>L_tnS_mC_.glif</string>
+ <key>LtnSmD</key>
+ <string>L_tnS_mD_.glif</string>
+ <key>LtnSmE</key>
+ <string>L_tnS_mE_.glif</string>
+ <key>LtnSmF</key>
+ <string>L_tnS_mF_.glif</string>
+ <key>LtnSmG</key>
+ <string>L_tnS_mG_.glif</string>
+ <key>LtnSmH</key>
+ <string>L_tnS_mH_.glif</string>
+ <key>LtnSmI</key>
+ <string>L_tnS_mI_.glif</string>
+ <key>LtnSmJ</key>
+ <string>L_tnS_mJ_.glif</string>
+ <key>LtnSmK</key>
+ <string>L_tnS_mK_.glif</string>
+ <key>LtnSmL</key>
+ <string>L_tnS_mL_.glif</string>
+ <key>LtnSmM</key>
+ <string>L_tnS_mM_.glif</string>
+ <key>LtnSmN</key>
+ <string>L_tnS_mN_.glif</string>
+ <key>LtnSmO</key>
+ <string>L_tnS_mO_.glif</string>
+ <key>LtnSmP</key>
+ <string>L_tnS_mP_.glif</string>
+ <key>LtnSmQ</key>
+ <string>L_tnS_mQ_.glif</string>
+ <key>LtnSmR</key>
+ <string>L_tnS_mR_.glif</string>
+ <key>LtnSmS</key>
+ <string>L_tnS_mS_.glif</string>
+ <key>LtnSmT</key>
+ <string>L_tnS_mT_.glif</string>
+ <key>LtnSmU</key>
+ <string>L_tnS_mU_.glif</string>
+ <key>LtnSmV</key>
+ <string>L_tnS_mV_.glif</string>
+ <key>LtnSmW</key>
+ <string>L_tnS_mW_.glif</string>
+ <key>LtnSmX</key>
+ <string>L_tnS_mX_.glif</string>
+ <key>LtnSmY</key>
+ <string>L_tnS_mY_.glif</string>
+ <key>NonBreakingHyphen</key>
+ <string>N_onB_reakingH_yphen.glif</string>
+ <key>NumSgn</key>
+ <string>N_umS_gn.glif</string>
+ <key>PercentSgn</key>
+ <string>P_ercentS_gn.glif</string>
+ <key>PlusSgn</key>
+ <string>P_lusS_gn.glif</string>
+ <key>QstnMrk</key>
+ <string>Q_stnM_rk.glif</string>
+ <key>QuotMrk</key>
+ <string>Q_uotM_rk.glif</string>
+ <key>ReverseSolidus</key>
+ <string>R_everseS_olidus.glif</string>
+ <key>RtCurlyBrac</key>
+ <string>R_tC_urlyB_rac.glif</string>
+ <key>RtParen</key>
+ <string>R_tP_aren.glif</string>
+ <key>RtSqrBrac</key>
+ <string>R_tS_qrB_rac.glif</string>
+ <key>Semicolon</key>
+ <string>S_emicolon.glif</string>
+ <key>Solidus</key>
+ <string>S_olidus.glif</string>
+ <key>Space</key>
+ <string>S_pace.glif</string>
+ <key>Tilde</key>
+ <string>T_ilde.glif</string>
+ <key>VertLine</key>
+ <string>V_ertL_ine.glif</string>
+ <key>nonmarkingreturn</key>
+ <string>nonmarkingreturn.glif</string>
+</dict>
+</plist>
diff --git a/tests/reference/ufo/psfsetkeys.ufo/glyphs/nonmarkingreturn.glif b/tests/reference/ufo/psfsetkeys.ufo/glyphs/nonmarkingreturn.glif
new file mode 100644
index 0000000..9a63f06
--- /dev/null
+++ b/tests/reference/ufo/psfsetkeys.ufo/glyphs/nonmarkingreturn.glif
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="nonmarkingreturn" format="2">
+ <advance width="1004"/>
+ <outline/>
+</glyph>
diff --git a/tests/reference/ufo/psfsetkeys.ufo/layercontents.plist b/tests/reference/ufo/psfsetkeys.ufo/layercontents.plist
new file mode 100644
index 0000000..42b7482
--- /dev/null
+++ b/tests/reference/ufo/psfsetkeys.ufo/layercontents.plist
@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<array>
+ <array>
+ <string>public.default</string>
+ <string>glyphs</string>
+ </array>
+</array>
+</plist>
diff --git a/tests/reference/ufo/psfsetkeys.ufo/lib.plist b/tests/reference/ufo/psfsetkeys.ufo/lib.plist
new file mode 100644
index 0000000..002f2fb
--- /dev/null
+++ b/tests/reference/ufo/psfsetkeys.ufo/lib.plist
@@ -0,0 +1,534 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+ <key>com.schriftgestaltung.Glyphs.fontUserData</key>
+ <dict/>
+ <key>com.schriftgestaltung.appVersion</key>
+ <string>1161</string>
+ <key>com.schriftgestaltung.customName</key>
+ <string>Italic</string>
+ <key>com.schriftgestaltung.customParameter.GSFont.DisplayStrings</key>
+ <string/>
+ <key>com.schriftgestaltung.customParameter.GSFont.disablesAutomaticAlignment</key>
+ <true/>
+ <key>com.schriftgestaltung.customParameter.GSFont.disablesLastChange</key>
+ <true/>
+ <key>com.schriftgestaltung.customParameter.GSFont.useNiceNames</key>
+ <integer>0</integer>
+ <key>com.schriftgestaltung.customParameter.GSFontMaster.customValue</key>
+ <integer>0</integer>
+ <key>com.schriftgestaltung.customParameter.GSFontMaster.customValue1</key>
+ <integer>0</integer>
+ <key>com.schriftgestaltung.customParameter.GSFontMaster.customValue2</key>
+ <integer>0</integer>
+ <key>com.schriftgestaltung.customParameter.GSFontMaster.customValue3</key>
+ <integer>0</integer>
+ <key>com.schriftgestaltung.customParameter.GSFontMaster.iconName</key>
+ <string/>
+ <key>com.schriftgestaltung.customParameter.GSFontMaster.weightValue</key>
+ <integer>700</integer>
+ <key>com.schriftgestaltung.customParameter.GSFontMaster.widthValue</key>
+ <integer>100</integer>
+ <key>com.schriftgestaltung.fontMasterOrder</key>
+ <integer>1</integer>
+ <key>com.schriftgestaltung.glyphOrder</key>
+ <array>
+ <string>.notdef</string>
+ <string>.null</string>
+ <string>nonmarkingreturn</string>
+ <string>Space</string>
+ <string>ExclamationMrk</string>
+ <string>QuotMrk</string>
+ <string>NumSgn</string>
+ <string>DollarSgn</string>
+ <string>PercentSgn</string>
+ <string>Ampersand</string>
+ <string>Apos</string>
+ <string>LftParen</string>
+ <string>RtParen</string>
+ <string>Asterisk</string>
+ <string>PlusSgn</string>
+ <string>Comma</string>
+ <string>HyphenMinus</string>
+ <string>FullStop</string>
+ <string>Solidus</string>
+ <string>DigitZero</string>
+ <string>DigitOne</string>
+ <string>DigitTwo</string>
+ <string>DigitThree</string>
+ <string>DigitFour</string>
+ <string>DigitFive</string>
+ <string>DigitSix</string>
+ <string>DigitSeven</string>
+ <string>DigitEight</string>
+ <string>DigitNine</string>
+ <string>Colon</string>
+ <string>Semicolon</string>
+ <string>LTSgn</string>
+ <string>EqSgn</string>
+ <string>GTSgn</string>
+ <string>QstnMrk</string>
+ <string>AtSgn</string>
+ <string>LtnCapA</string>
+ <string>LtnCapA.alt</string>
+ <string>LtnCapB</string>
+ <string>LtnCapC</string>
+ <string>LtnCapD</string>
+ <string>LtnCapE</string>
+ <string>LtnCapF</string>
+ <string>LtnCapG</string>
+ <string>LtnCapH</string>
+ <string>LtnCapI</string>
+ <string>LtnCapJ</string>
+ <string>LtnCapK</string>
+ <string>LtnCapL</string>
+ <string>LtnCapM</string>
+ <string>LtnCapN</string>
+ <string>LtnCapO</string>
+ <string>LtnCapP</string>
+ <string>LtnCapQ</string>
+ <string>LtnCapR</string>
+ <string>LtnCapS</string>
+ <string>LtnCapT</string>
+ <string>LtnCapU</string>
+ <string>LtnCapV</string>
+ <string>LtnCapW</string>
+ <string>LtnCapX</string>
+ <string>LtnCapY</string>
+ <string>LftSqrBrac</string>
+ <string>ReverseSolidus</string>
+ <string>RtSqrBrac</string>
+ <string>CircumAccent</string>
+ <string>LowLine</string>
+ <string>GraveAccent</string>
+ <string>LtnSmA</string>
+ <string>LtnSmB</string>
+ <string>LtnSmC</string>
+ <string>LtnSmD</string>
+ <string>LtnSmE</string>
+ <string>LtnSmF</string>
+ <string>LtnSmG</string>
+ <string>LtnSmH</string>
+ <string>LtnSmI</string>
+ <string>LtnSmJ</string>
+ <string>LtnSmK</string>
+ <string>LtnSmL</string>
+ <string>LtnSmM</string>
+ <string>LtnSmN</string>
+ <string>LtnSmO</string>
+ <string>LtnSmP</string>
+ <string>LtnSmQ</string>
+ <string>LtnSmR</string>
+ <string>LtnSmS</string>
+ <string>LtnSmT</string>
+ <string>LtnSmU</string>
+ <string>LtnSmV</string>
+ <string>LtnSmW</string>
+ <string>LtnSmX</string>
+ <string>LtnSmY</string>
+ <string>LftCurlyBrac</string>
+ <string>VertLine</string>
+ <string>RtCurlyBrac</string>
+ <string>Tilde</string>
+ <string>LtnCapADiaer</string>
+ <string>LtnSmAAcute</string>
+ <string>LtnSmAGrave</string>
+ <string>LtnSmACircum</string>
+ <string>LtnSmADiaer</string>
+ <string>LtnSmATilde</string>
+ <string>LtnSmARingAbv</string>
+ <string>DottedCirc</string>
+ <string>Hyphen</string>
+ <string>NonBreakingHyphen</string>
+ <string>Hyphen_Soft</string>
+ <string>CombAcute</string>
+ <string>CombGrave</string>
+ <string>CombCircum</string>
+ <string>CombTilde</string>
+ <string>CombDiaer</string>
+ <string>CombRingAbv</string>
+ </array>
+ <key>com.schriftgestaltung.keyboardIncrement</key>
+ <integer>1</integer>
+ <key>com.schriftgestaltung.weight</key>
+ <string>Bold</string>
+ <key>com.schriftgestaltung.weightValue</key>
+ <integer>700</integer>
+ <key>com.schriftgestaltung.width</key>
+ <string>Regular</string>
+ <key>com.schriftgestaltung.widthValue</key>
+ <integer>100</integer>
+ <key>org.sil.lcg.toneLetters</key>
+ <dict>
+ <key>contourWidth</key>
+ <integer>540</integer>
+ <key>dotSize</key>
+ <integer>280</integer>
+ <key>dotSpacing</key>
+ <integer>200</integer>
+ <key>glyphDepth</key>
+ <integer>-25</integer>
+ <key>glyphHeight</key>
+ <integer>1600</integer>
+ <key>italicAngle</key>
+ <integer>14</integer>
+ <key>marginDotLeft</key>
+ <integer>100</integer>
+ <key>marginDotRight</key>
+ <integer>140</integer>
+ <key>marginFlatLeft</key>
+ <integer>100</integer>
+ <key>marginFlatRight</key>
+ <integer>140</integer>
+ <key>marginPointLeft</key>
+ <integer>80</integer>
+ <key>marginPointRight</key>
+ <integer>120</integer>
+ <key>strokeThickness</key>
+ <integer>200</integer>
+ </dict>
+ <key>public.glyphOrder</key>
+ <array>
+ <string>.notdef</string>
+ <string>.null</string>
+ <string>nonmarkingreturn</string>
+ <string>Space</string>
+ <string>ExclamationMrk</string>
+ <string>QuotMrk</string>
+ <string>NumSgn</string>
+ <string>DollarSgn</string>
+ <string>PercentSgn</string>
+ <string>Ampersand</string>
+ <string>Apos</string>
+ <string>LftParen</string>
+ <string>RtParen</string>
+ <string>Asterisk</string>
+ <string>PlusSgn</string>
+ <string>Comma</string>
+ <string>HyphenMinus</string>
+ <string>FullStop</string>
+ <string>Solidus</string>
+ <string>DigitZero</string>
+ <string>DigitOne</string>
+ <string>DigitTwo</string>
+ <string>DigitThree</string>
+ <string>DigitFour</string>
+ <string>DigitFive</string>
+ <string>DigitSix</string>
+ <string>DigitSeven</string>
+ <string>DigitEight</string>
+ <string>DigitNine</string>
+ <string>Colon</string>
+ <string>Semicolon</string>
+ <string>LTSgn</string>
+ <string>EqSgn</string>
+ <string>GTSgn</string>
+ <string>QstnMrk</string>
+ <string>AtSgn</string>
+ <string>LtnCapA</string>
+ <string>LtnCapA.alt</string>
+ <string>LtnCapB</string>
+ <string>LtnCapC</string>
+ <string>LtnCapD</string>
+ <string>LtnCapE</string>
+ <string>LtnCapF</string>
+ <string>LtnCapG</string>
+ <string>LtnCapH</string>
+ <string>LtnCapI</string>
+ <string>LtnCapJ</string>
+ <string>LtnCapK</string>
+ <string>LtnCapL</string>
+ <string>LtnCapM</string>
+ <string>LtnCapN</string>
+ <string>LtnCapO</string>
+ <string>LtnCapP</string>
+ <string>LtnCapQ</string>
+ <string>LtnCapR</string>
+ <string>LtnCapS</string>
+ <string>LtnCapT</string>
+ <string>LtnCapU</string>
+ <string>LtnCapV</string>
+ <string>LtnCapW</string>
+ <string>LtnCapX</string>
+ <string>LtnCapY</string>
+ <string>LftSqrBrac</string>
+ <string>ReverseSolidus</string>
+ <string>RtSqrBrac</string>
+ <string>CircumAccent</string>
+ <string>LowLine</string>
+ <string>GraveAccent</string>
+ <string>LtnSmA</string>
+ <string>LtnSmB</string>
+ <string>LtnSmC</string>
+ <string>LtnSmD</string>
+ <string>LtnSmE</string>
+ <string>LtnSmF</string>
+ <string>LtnSmG</string>
+ <string>LtnSmH</string>
+ <string>LtnSmI</string>
+ <string>LtnSmJ</string>
+ <string>LtnSmK</string>
+ <string>LtnSmL</string>
+ <string>LtnSmM</string>
+ <string>LtnSmN</string>
+ <string>LtnSmO</string>
+ <string>LtnSmP</string>
+ <string>LtnSmQ</string>
+ <string>LtnSmR</string>
+ <string>LtnSmS</string>
+ <string>LtnSmT</string>
+ <string>LtnSmU</string>
+ <string>LtnSmV</string>
+ <string>LtnSmW</string>
+ <string>LtnSmX</string>
+ <string>LtnSmY</string>
+ <string>LftCurlyBrac</string>
+ <string>VertLine</string>
+ <string>RtCurlyBrac</string>
+ <string>Tilde</string>
+ <string>LtnCapADiaer</string>
+ <string>LtnSmAAcute</string>
+ <string>LtnSmAGrave</string>
+ <string>LtnSmACircum</string>
+ <string>LtnSmADiaer</string>
+ <string>LtnSmATilde</string>
+ <string>LtnSmARingAbv</string>
+ <string>DottedCirc</string>
+ <string>Hyphen</string>
+ <string>NonBreakingHyphen</string>
+ <string>Hyphen_Soft</string>
+ <string>CombAcute</string>
+ <string>CombGrave</string>
+ <string>CombCircum</string>
+ <string>CombTilde</string>
+ <string>CombDiaer</string>
+ <string>CombRingAbv</string>
+ </array>
+ <key>public.postscriptNames</key>
+ <dict>
+ <key>Ampersand</key>
+ <string>ampersand</string>
+ <key>Apos</key>
+ <string>quotesingle</string>
+ <key>Asterisk</key>
+ <string>asterisk</string>
+ <key>AtSgn</key>
+ <string>at</string>
+ <key>CircumAccent</key>
+ <string>asciicircum</string>
+ <key>Colon</key>
+ <string>colon</string>
+ <key>CombAcute</key>
+ <string>acutecomb</string>
+ <key>CombCircum</key>
+ <string>uni0302</string>
+ <key>CombDiaer</key>
+ <string>uni0308</string>
+ <key>CombGrave</key>
+ <string>gravecomb</string>
+ <key>CombRingAbv</key>
+ <string>uni030A</string>
+ <key>CombTilde</key>
+ <string>tildecomb</string>
+ <key>Comma</key>
+ <string>comma</string>
+ <key>DigitEight</key>
+ <string>eight</string>
+ <key>DigitFive</key>
+ <string>five</string>
+ <key>DigitFour</key>
+ <string>four</string>
+ <key>DigitNine</key>
+ <string>nine</string>
+ <key>DigitOne</key>
+ <string>one</string>
+ <key>DigitSeven</key>
+ <string>seven</string>
+ <key>DigitSix</key>
+ <string>six</string>
+ <key>DigitThree</key>
+ <string>three</string>
+ <key>DigitTwo</key>
+ <string>two</string>
+ <key>DigitZero</key>
+ <string>zero</string>
+ <key>DollarSgn</key>
+ <string>dollar</string>
+ <key>DottedCirc</key>
+ <string>uni25CC</string>
+ <key>EqSgn</key>
+ <string>equal</string>
+ <key>ExclamationMrk</key>
+ <string>exclam</string>
+ <key>FullStop</key>
+ <string>period</string>
+ <key>GTSgn</key>
+ <string>greater</string>
+ <key>GraveAccent</key>
+ <string>grave</string>
+ <key>Hyphen</key>
+ <string>uni2010</string>
+ <key>HyphenMinus</key>
+ <string>hyphen</string>
+ <key>Hyphen_Soft</key>
+ <string>uni00AD</string>
+ <key>LTSgn</key>
+ <string>less</string>
+ <key>LftCurlyBrac</key>
+ <string>braceleft</string>
+ <key>LftParen</key>
+ <string>parenleft</string>
+ <key>LftSqrBrac</key>
+ <string>bracketleft</string>
+ <key>LowLine</key>
+ <string>underscore</string>
+ <key>LtnCapA</key>
+ <string>A</string>
+ <key>LtnCapA.alt</key>
+ <string>A</string>
+ <key>LtnCapADiaer</key>
+ <string>Adieresis</string>
+ <key>LtnCapB</key>
+ <string>B</string>
+ <key>LtnCapC</key>
+ <string>C</string>
+ <key>LtnCapD</key>
+ <string>D</string>
+ <key>LtnCapE</key>
+ <string>E</string>
+ <key>LtnCapF</key>
+ <string>F</string>
+ <key>LtnCapG</key>
+ <string>G</string>
+ <key>LtnCapH</key>
+ <string>H</string>
+ <key>LtnCapI</key>
+ <string>I</string>
+ <key>LtnCapJ</key>
+ <string>J</string>
+ <key>LtnCapK</key>
+ <string>K</string>
+ <key>LtnCapL</key>
+ <string>L</string>
+ <key>LtnCapM</key>
+ <string>M</string>
+ <key>LtnCapN</key>
+ <string>N</string>
+ <key>LtnCapO</key>
+ <string>O</string>
+ <key>LtnCapP</key>
+ <string>P</string>
+ <key>LtnCapQ</key>
+ <string>Q</string>
+ <key>LtnCapR</key>
+ <string>R</string>
+ <key>LtnCapS</key>
+ <string>S</string>
+ <key>LtnCapT</key>
+ <string>T</string>
+ <key>LtnCapU</key>
+ <string>U</string>
+ <key>LtnCapV</key>
+ <string>V</string>
+ <key>LtnCapW</key>
+ <string>W</string>
+ <key>LtnCapX</key>
+ <string>X</string>
+ <key>LtnCapY</key>
+ <string>Y</string>
+ <key>LtnSmA</key>
+ <string>a</string>
+ <key>LtnSmAAcute</key>
+ <string>aacute</string>
+ <key>LtnSmACircum</key>
+ <string>acircumflex</string>
+ <key>LtnSmADiaer</key>
+ <string>adieresis</string>
+ <key>LtnSmAGrave</key>
+ <string>agrave</string>
+ <key>LtnSmARingAbv</key>
+ <string>aring</string>
+ <key>LtnSmATilde</key>
+ <string>atilde</string>
+ <key>LtnSmB</key>
+ <string>b</string>
+ <key>LtnSmC</key>
+ <string>c</string>
+ <key>LtnSmD</key>
+ <string>d</string>
+ <key>LtnSmE</key>
+ <string>e</string>
+ <key>LtnSmF</key>
+ <string>f</string>
+ <key>LtnSmG</key>
+ <string>g</string>
+ <key>LtnSmH</key>
+ <string>h</string>
+ <key>LtnSmI</key>
+ <string>i</string>
+ <key>LtnSmJ</key>
+ <string>j</string>
+ <key>LtnSmK</key>
+ <string>k</string>
+ <key>LtnSmL</key>
+ <string>l</string>
+ <key>LtnSmM</key>
+ <string>m</string>
+ <key>LtnSmN</key>
+ <string>n</string>
+ <key>LtnSmO</key>
+ <string>o</string>
+ <key>LtnSmP</key>
+ <string>p</string>
+ <key>LtnSmQ</key>
+ <string>q</string>
+ <key>LtnSmR</key>
+ <string>r</string>
+ <key>LtnSmS</key>
+ <string>s</string>
+ <key>LtnSmT</key>
+ <string>t</string>
+ <key>LtnSmU</key>
+ <string>u</string>
+ <key>LtnSmV</key>
+ <string>v</string>
+ <key>LtnSmW</key>
+ <string>w</string>
+ <key>LtnSmX</key>
+ <string>x</string>
+ <key>LtnSmY</key>
+ <string>y</string>
+ <key>NonBreakingHyphen</key>
+ <string>uni2011</string>
+ <key>NumSgn</key>
+ <string>numbersign</string>
+ <key>PercentSgn</key>
+ <string>percent</string>
+ <key>PlusSgn</key>
+ <string>plus</string>
+ <key>QstnMrk</key>
+ <string>question</string>
+ <key>QuotMrk</key>
+ <string>quotedbl</string>
+ <key>ReverseSolidus</key>
+ <string>backslash</string>
+ <key>RtCurlyBrac</key>
+ <string>braceright</string>
+ <key>RtParen</key>
+ <string>parenright</string>
+ <key>RtSqrBrac</key>
+ <string>bracketright</string>
+ <key>Semicolon</key>
+ <string>semicolon</string>
+ <key>Solidus</key>
+ <string>slash</string>
+ <key>Space</key>
+ <string>space</string>
+ <key>Tilde</key>
+ <string>asciitilde</string>
+ <key>VertLine</key>
+ <string>bar</string>
+ </dict>
+</dict>
+</plist>
diff --git a/tests/reference/ufo/psfsetkeys.ufo/metainfo.plist b/tests/reference/ufo/psfsetkeys.ufo/metainfo.plist
new file mode 100644
index 0000000..aa10c5c
--- /dev/null
+++ b/tests/reference/ufo/psfsetkeys.ufo/metainfo.plist
@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+ <key>creator</key>
+ <string>org.sil.scripts.pysilfont</string>
+ <key>formatVersion</key>
+ <integer>3</integer>
+</dict>
+</plist>
diff --git a/tests/reference/ufo/psfsetpsnames.lg b/tests/reference/ufo/psfsetpsnames.lg
new file mode 100644
index 0000000..510c1b9
--- /dev/null
+++ b/tests/reference/ufo/psfsetpsnames.lg
@@ -0,0 +1,155 @@
+2021-06-29 14:42:22 Progress: Running: psfsetpsnames tests/input/font-psf-test/source/PsfTest-BoldItalic.ufo -i tests/input/glyph_data.csv -l local/testresults/ufo/psfsetpsnames.log -p loglevel=i
+2021-06-29 14:42:22 Progress: Opening file for input: tests/input/glyph_data.csv
+2021-06-29 14:42:22 Progress: Reading UFO: tests/input/font-psf-test/source/PsfTest-BoldItalic.ufo
+2021-06-29 14:42:22 Info: Processing Glyph Layer 0: public.defaultglyphs
+2021-06-29 14:42:22 Progress: Checking fontinfo.plist metadata
+2021-06-29 14:42:22 Warning: macintoshFONDName would be removed from fontinfo Old value: My Test
+2021-06-29 14:42:22 Info: Types: Old - string, New - NoneType
+2021-06-29 14:42:22 Warning: openTypeOS2FamilyClass would be removed from fontinfo Old value: [0, 0]
+2021-06-29 14:42:22 Info: Types: Old - list, New - NoneType
+2021-06-29 14:42:22 Warning: postscriptFamilyBlues would be removed from fontinfo Old value: []
+2021-06-29 14:42:22 Info: Types: Old - list, New - NoneType
+2021-06-29 14:42:22 Warning: openTypeOS2Selection would be added New value: [7]
+2021-06-29 14:42:22 Info: Types: Old - NoneType, New - list
+2021-06-29 14:42:22 Warning: openTypeHheaAscender would be updated Old value: 2200, new value: 2100
+2021-06-29 14:42:22 Info: Types: Old - int, New - int
+2021-06-29 14:42:22 Progress: Checking lib.plist metadata
+2021-06-29 14:42:22 Warning: com.schriftgestaltung.disablesAutomaticAlignment would be deleted - obsolete key Old value: True
+2021-06-29 14:42:22 Info: Types: Old - bool, New - NoneType
+2021-06-29 14:42:22 Warning: com.schriftgestaltung.disablesLastChange would be deleted - obsolete key Old value: True
+2021-06-29 14:42:22 Info: Types: Old - bool, New - NoneType
+2021-06-29 14:42:22 Progress: Check & fix results:- Errors: 0, Changes to make: 7, Other warnings: 0
+2021-06-29 14:42:22 Progress: See log file for details
+2021-06-29 14:42:22 Info: No glyph in font for AcuteAccent on line 2
+2021-06-29 14:42:22 Info: No glyph in font for Bullet on line 3
+2021-06-29 14:42:22 Info: No glyph in font for BulletOperator on line 4
+2021-06-29 14:42:22 Info: No glyph in font for DblAcuteAccent on line 7
+2021-06-29 14:42:22 Info: No glyph in font for LtnCapAAcute on line 9
+2021-06-29 14:42:22 Info: No glyph in font for LtnCapEAcute on line 10
+2021-06-29 14:42:22 Info: No glyph in font for LtnCapIAcute on line 11
+2021-06-29 14:42:22 Info: No glyph in font for LtnCapOAcute on line 12
+2021-06-29 14:42:22 Info: No glyph in font for LtnCapUAcute on line 13
+2021-06-29 14:42:22 Info: No glyph in font for LtnCapYAcute on line 14
+2021-06-29 14:42:22 Info: No glyph in font for LtnSmEAcute on line 16
+2021-06-29 14:42:22 Info: No glyph in font for LtnSmIAcute on line 17
+2021-06-29 14:42:22 Info: No glyph in font for LtnSmOAcute on line 18
+2021-06-29 14:42:22 Info: No glyph in font for LtnSmUAcute on line 19
+2021-06-29 14:42:22 Info: No glyph in font for LtnSmYAcute on line 20
+2021-06-29 14:42:22 Info: No glyph in font for ModCircumAccent on line 21
+2021-06-29 14:42:22 Info: No glyph in font for SupOne on line 24
+2021-06-29 14:42:22 Info: No glyph in font for SupThree on line 25
+2021-06-29 14:42:22 Info: No glyph in font for VulgFracOneHalf on line 26
+2021-06-29 14:42:22 Info: No glyph in font for VulgFracOneQuarter on line 27
+2021-06-29 14:42:22 Info: No glyph in font for VulgFracThreeQuarters on line 28
+2021-06-29 14:42:22 Info: No PS name in input file for font glyph .notdef
+2021-06-29 14:42:22 Info: No PS name in input file for font glyph .null
+2021-06-29 14:42:22 Info: No PS name in input file for font glyph Ampersand
+2021-06-29 14:42:22 Info: No PS name in input file for font glyph Apos
+2021-06-29 14:42:22 Info: No PS name in input file for font glyph Asterisk
+2021-06-29 14:42:22 Info: No PS name in input file for font glyph AtSgn
+2021-06-29 14:42:22 Info: No PS name in input file for font glyph Colon
+2021-06-29 14:42:22 Info: No PS name in input file for font glyph CombCircum
+2021-06-29 14:42:22 Info: No PS name in input file for font glyph CombDiaer
+2021-06-29 14:42:22 Info: No PS name in input file for font glyph CombGrave
+2021-06-29 14:42:22 Info: No PS name in input file for font glyph CombRingAbv
+2021-06-29 14:42:22 Info: No PS name in input file for font glyph CombTilde
+2021-06-29 14:42:22 Info: No PS name in input file for font glyph Comma
+2021-06-29 14:42:22 Info: No PS name in input file for font glyph DigitEight
+2021-06-29 14:42:22 Info: No PS name in input file for font glyph DigitFive
+2021-06-29 14:42:22 Info: No PS name in input file for font glyph DigitFour
+2021-06-29 14:42:22 Info: No PS name in input file for font glyph DigitNine
+2021-06-29 14:42:22 Info: No PS name in input file for font glyph DigitOne
+2021-06-29 14:42:22 Info: No PS name in input file for font glyph DigitSeven
+2021-06-29 14:42:22 Info: No PS name in input file for font glyph DigitSix
+2021-06-29 14:42:22 Info: No PS name in input file for font glyph DigitThree
+2021-06-29 14:42:22 Info: No PS name in input file for font glyph DigitTwo
+2021-06-29 14:42:22 Info: No PS name in input file for font glyph DigitZero
+2021-06-29 14:42:22 Info: No PS name in input file for font glyph DollarSgn
+2021-06-29 14:42:22 Info: No PS name in input file for font glyph DottedCirc
+2021-06-29 14:42:22 Info: No PS name in input file for font glyph EqSgn
+2021-06-29 14:42:22 Info: No PS name in input file for font glyph ExclamationMrk
+2021-06-29 14:42:22 Info: No PS name in input file for font glyph FullStop
+2021-06-29 14:42:22 Info: No PS name in input file for font glyph GTSgn
+2021-06-29 14:42:22 Info: No PS name in input file for font glyph GraveAccent
+2021-06-29 14:42:22 Info: No PS name in input file for font glyph Hyphen
+2021-06-29 14:42:22 Info: No PS name in input file for font glyph Hyphen_Soft
+2021-06-29 14:42:22 Info: No PS name in input file for font glyph LTSgn
+2021-06-29 14:42:22 Info: No PS name in input file for font glyph LftCurlyBrac
+2021-06-29 14:42:22 Info: No PS name in input file for font glyph LftParen
+2021-06-29 14:42:22 Info: No PS name in input file for font glyph LftSqrBrac
+2021-06-29 14:42:22 Info: No PS name in input file for font glyph LowLine
+2021-06-29 14:42:22 Info: No PS name in input file for font glyph LtnCapA
+2021-06-29 14:42:22 Info: No PS name in input file for font glyph LtnCapADiaer
+2021-06-29 14:42:22 Info: No PS name in input file for font glyph LtnCapB
+2021-06-29 14:42:22 Info: No PS name in input file for font glyph LtnCapC
+2021-06-29 14:42:22 Info: No PS name in input file for font glyph LtnCapD
+2021-06-29 14:42:22 Info: No PS name in input file for font glyph LtnCapE
+2021-06-29 14:42:22 Info: No PS name in input file for font glyph LtnCapF
+2021-06-29 14:42:22 Info: No PS name in input file for font glyph LtnCapG
+2021-06-29 14:42:22 Info: No PS name in input file for font glyph LtnCapH
+2021-06-29 14:42:22 Info: No PS name in input file for font glyph LtnCapI
+2021-06-29 14:42:22 Info: No PS name in input file for font glyph LtnCapJ
+2021-06-29 14:42:22 Info: No PS name in input file for font glyph LtnCapK
+2021-06-29 14:42:22 Info: No PS name in input file for font glyph LtnCapL
+2021-06-29 14:42:22 Info: No PS name in input file for font glyph LtnCapM
+2021-06-29 14:42:22 Info: No PS name in input file for font glyph LtnCapN
+2021-06-29 14:42:22 Info: No PS name in input file for font glyph LtnCapO
+2021-06-29 14:42:22 Info: No PS name in input file for font glyph LtnCapP
+2021-06-29 14:42:22 Info: No PS name in input file for font glyph LtnCapQ
+2021-06-29 14:42:22 Info: No PS name in input file for font glyph LtnCapR
+2021-06-29 14:42:22 Info: No PS name in input file for font glyph LtnCapS
+2021-06-29 14:42:22 Info: No PS name in input file for font glyph LtnCapT
+2021-06-29 14:42:22 Info: No PS name in input file for font glyph LtnCapU
+2021-06-29 14:42:22 Info: No PS name in input file for font glyph LtnCapV
+2021-06-29 14:42:22 Info: No PS name in input file for font glyph LtnCapW
+2021-06-29 14:42:22 Info: No PS name in input file for font glyph LtnCapX
+2021-06-29 14:42:22 Info: No PS name in input file for font glyph LtnCapY
+2021-06-29 14:42:22 Info: No PS name in input file for font glyph LtnSmA
+2021-06-29 14:42:22 Info: No PS name in input file for font glyph LtnSmACircum
+2021-06-29 14:42:22 Info: No PS name in input file for font glyph LtnSmADiaer
+2021-06-29 14:42:22 Info: No PS name in input file for font glyph LtnSmAGrave
+2021-06-29 14:42:22 Info: No PS name in input file for font glyph LtnSmARingAbv
+2021-06-29 14:42:22 Info: No PS name in input file for font glyph LtnSmATilde
+2021-06-29 14:42:22 Info: No PS name in input file for font glyph LtnSmB
+2021-06-29 14:42:22 Info: No PS name in input file for font glyph LtnSmC
+2021-06-29 14:42:22 Info: No PS name in input file for font glyph LtnSmD
+2021-06-29 14:42:22 Info: No PS name in input file for font glyph LtnSmE
+2021-06-29 14:42:22 Info: No PS name in input file for font glyph LtnSmF
+2021-06-29 14:42:22 Info: No PS name in input file for font glyph LtnSmG
+2021-06-29 14:42:22 Info: No PS name in input file for font glyph LtnSmH
+2021-06-29 14:42:22 Info: No PS name in input file for font glyph LtnSmI
+2021-06-29 14:42:22 Info: No PS name in input file for font glyph LtnSmJ
+2021-06-29 14:42:22 Info: No PS name in input file for font glyph LtnSmK
+2021-06-29 14:42:22 Info: No PS name in input file for font glyph LtnSmL
+2021-06-29 14:42:22 Info: No PS name in input file for font glyph LtnSmM
+2021-06-29 14:42:22 Info: No PS name in input file for font glyph LtnSmN
+2021-06-29 14:42:22 Info: No PS name in input file for font glyph LtnSmO
+2021-06-29 14:42:22 Info: No PS name in input file for font glyph LtnSmP
+2021-06-29 14:42:22 Info: No PS name in input file for font glyph LtnSmQ
+2021-06-29 14:42:22 Info: No PS name in input file for font glyph LtnSmR
+2021-06-29 14:42:22 Info: No PS name in input file for font glyph LtnSmS
+2021-06-29 14:42:22 Info: No PS name in input file for font glyph LtnSmT
+2021-06-29 14:42:22 Info: No PS name in input file for font glyph LtnSmU
+2021-06-29 14:42:22 Info: No PS name in input file for font glyph LtnSmV
+2021-06-29 14:42:22 Info: No PS name in input file for font glyph LtnSmW
+2021-06-29 14:42:22 Info: No PS name in input file for font glyph LtnSmX
+2021-06-29 14:42:22 Info: No PS name in input file for font glyph LtnSmY
+2021-06-29 14:42:22 Info: No PS name in input file for font glyph NonBreakingHyphen
+2021-06-29 14:42:22 Info: No PS name in input file for font glyph NumSgn
+2021-06-29 14:42:22 Info: No PS name in input file for font glyph PercentSgn
+2021-06-29 14:42:22 Info: No PS name in input file for font glyph PlusSgn
+2021-06-29 14:42:22 Info: No PS name in input file for font glyph QstnMrk
+2021-06-29 14:42:22 Info: No PS name in input file for font glyph QuotMrk
+2021-06-29 14:42:22 Info: No PS name in input file for font glyph RtCurlyBrac
+2021-06-29 14:42:22 Info: No PS name in input file for font glyph RtParen
+2021-06-29 14:42:22 Info: No PS name in input file for font glyph RtSqrBrac
+2021-06-29 14:42:22 Info: No PS name in input file for font glyph Semicolon
+2021-06-29 14:42:22 Info: No PS name in input file for font glyph Solidus
+2021-06-29 14:42:22 Info: No PS name in input file for font glyph Space
+2021-06-29 14:42:22 Info: No PS name in input file for font glyph Tilde
+2021-06-29 14:42:22 Info: No PS name in input file for font glyph VertLine
+2021-06-29 14:42:22 Info: No PS name in input file for font glyph nonmarkingreturn
+2021-06-29 14:42:22 Progress: Processing font for output
+2021-06-29 14:42:22 Progress: Output UFO already exists - reading for comparison
+2021-06-29 14:42:22 Progress: Writing font to local/testresults/ufo/psfsetpsnames.ufo
+2021-06-29 14:42:22 Info: Processing glyphs directory
diff --git a/tests/reference/ufo/psfsetpsnames.ufo/fontinfo.plist b/tests/reference/ufo/psfsetpsnames.ufo/fontinfo.plist
new file mode 100644
index 0000000..cab026a
--- /dev/null
+++ b/tests/reference/ufo/psfsetpsnames.ufo/fontinfo.plist
@@ -0,0 +1,245 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+ <key>ascender</key>
+ <integer>2100</integer>
+ <key>capHeight</key>
+ <integer>1485</integer>
+ <key>copyright</key>
+ <string>Copyright (c) 2004-2021 SIL International</string>
+ <key>descender</key>
+ <integer>-550</integer>
+ <key>familyName</key>
+ <string>Psf Test</string>
+ <key>italicAngle</key>
+ <integer>-14</integer>
+ <key>macintoshFONDName</key>
+ <string>My Test</string>
+ <key>openTypeHeadCreated</key>
+ <string>2021/01/29 10:05:07</string>
+ <key>openTypeHheaAscender</key>
+ <integer>2200</integer>
+ <key>openTypeHheaDescender</key>
+ <integer>-550</integer>
+ <key>openTypeHheaLineGap</key>
+ <integer>0</integer>
+ <key>openTypeNameDescription</key>
+ <string>Copyright (c) 2004-2021 SIL International</string>
+ <key>openTypeNameDesigner</key>
+ <string>Victor Gaultney, Annie Olsen, Julie Remington, Don Collingsworth, Eric Hays, Becca Hirsbrunner</string>
+ <key>openTypeNameDesignerURL</key>
+ <string>http://scripts.sil.org/</string>
+ <key>openTypeNameLicense</key>
+ <string>Copyright (c) 2004-2021 SIL International (http://www.sil.org/) with Reserved Font Names "Andika" and "SIL".
+
+This Font Software is licensed under the SIL Open Font License, Version 1.1. This license is copied below, and is also available with a FAQ at: http://scripts.sil.org/OFL
+
+
+-----------------------------------------------------------
+SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007
+-----------------------------------------------------------
+
+PREAMBLE
+The goals of the Open Font License (OFL) are to stimulate worldwide development of collaborative font projects, to support the font creation efforts of academic and linguistic communities, and to provide a free and open framework in which fonts may be shared and improved in partnership with others.
+
+The OFL allows the licensed fonts to be used, studied, modified and redistributed freely as long as they are not sold by themselves. The fonts, including any derivative works, can be bundled, embedded, redistributed and/or sold with any software provided that any reserved names are not used by derivative works. The fonts and derivatives, however, cannot be released under any other type of license. The requirement for fonts to remain under this license does not apply to any document created using the fonts or their derivatives.
+
+DEFINITIONS
+"Font Software" refers to the set of files released by the Copyright Holder(s) under this license and clearly marked as such. This may include source files, build scripts and documentation.
+
+"Reserved Font Name" refers to any names specified as such after the copyright statement(s).
+
+"Original Version" refers to the collection of Font Software components as distributed by the Copyright Holder(s).
+
+"Modified Version" refers to any derivative made by adding to, deleting, or substituting -- in part or in whole -- any of the components of the Original Version, by changing formats or by porting the Font Software to a new environment.
+
+"Author" refers to any designer, engineer, programmer, technical writer or other person who contributed to the Font Software.
+
+PERMISSION &amp; CONDITIONS
+Permission is hereby granted, free of charge, to any person obtaining a copy of the Font Software, to use, study, copy, merge, embed, modify, redistribute, and sell modified and unmodified copies of the Font Software, subject to the following conditions:
+
+1) Neither the Font Software nor any of its individual components, in Original or Modified Versions, may be sold by itself.
+
+2) Original or Modified Versions of the Font Software may be bundled, redistributed and/or sold with any software, provided that each copy contains the above copyright notice and this license. These can be included either as stand-alone text files, human-readable headers or in the appropriate machine-readable metadata fields within text or binary files as long as those fields can be easily viewed by the user.
+
+3) No Modified Version of the Font Software may use the Reserved Font Name(s) unless explicit written permission is granted by the corresponding Copyright Holder. This restriction only applies to the primary font name as presented to the users.
+
+4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font Software shall not be used to promote, endorse or advertise any Modified Version, except to acknowledge the contribution(s) of the Copyright Holder(s) and the Author(s) or with their explicit written permission.
+
+5) The Font Software, modified or unmodified, in part or in whole, must be distributed entirely under this license, and must not be distributed under any other license. The requirement for fonts to remain under this license does not apply to any document created using the Font Software.
+
+TERMINATION
+This license becomes null and void if any of the above conditions are not met.
+
+DISCLAIMER
+THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM OTHER DEALINGS IN THE FONT SOFTWARE.</string>
+ <key>openTypeNameLicenseURL</key>
+ <string>http://scripts.sil.org/OFL</string>
+ <key>openTypeNameManufacturer</key>
+ <string>SIL International</string>
+ <key>openTypeNameManufacturerURL</key>
+ <string>http://scripts.sil.org</string>
+ <key>openTypeNamePreferredFamilyName</key>
+ <string>Psf Test</string>
+ <key>openTypeNamePreferredSubfamilyName</key>
+ <string>Bold Italic</string>
+ <key>openTypeNameUniqueID</key>
+ <string>SIL International: Psf Test Bold Italic: 2022</string>
+ <key>openTypeNameVersion</key>
+ <string>Version 5.550</string>
+ <key>openTypeOS2CodePageRanges</key>
+ <array>
+ <integer>0</integer>
+ <integer>1</integer>
+ <integer>2</integer>
+ <integer>4</integer>
+ <integer>7</integer>
+ <integer>8</integer>
+ </array>
+ <key>openTypeOS2FamilyClass</key>
+ <array>
+ <integer>0</integer>
+ <integer>0</integer>
+ </array>
+ <key>openTypeOS2Panose</key>
+ <array>
+ <integer>2</integer>
+ <integer>0</integer>
+ <integer>0</integer>
+ <integer>0</integer>
+ <integer>0</integer>
+ <integer>0</integer>
+ <integer>0</integer>
+ <integer>0</integer>
+ <integer>0</integer>
+ <integer>0</integer>
+ </array>
+ <key>openTypeOS2StrikeoutPosition</key>
+ <integer>700</integer>
+ <key>openTypeOS2StrikeoutSize</key>
+ <integer>100</integer>
+ <key>openTypeOS2SubscriptXOffset</key>
+ <integer>0</integer>
+ <key>openTypeOS2SubscriptXSize</key>
+ <integer>1433</integer>
+ <key>openTypeOS2SubscriptYOffset</key>
+ <integer>286</integer>
+ <key>openTypeOS2SubscriptYSize</key>
+ <integer>1331</integer>
+ <key>openTypeOS2SuperscriptXOffset</key>
+ <integer>0</integer>
+ <key>openTypeOS2SuperscriptXSize</key>
+ <integer>1433</integer>
+ <key>openTypeOS2SuperscriptYOffset</key>
+ <integer>976</integer>
+ <key>openTypeOS2SuperscriptYSize</key>
+ <integer>1331</integer>
+ <key>openTypeOS2Type</key>
+ <array/>
+ <key>openTypeOS2TypoAscender</key>
+ <integer>2100</integer>
+ <key>openTypeOS2TypoDescender</key>
+ <integer>-550</integer>
+ <key>openTypeOS2TypoLineGap</key>
+ <integer>0</integer>
+ <key>openTypeOS2UnicodeRanges</key>
+ <array>
+ <integer>0</integer>
+ <integer>1</integer>
+ <integer>6</integer>
+ <integer>7</integer>
+ <integer>31</integer>
+ <integer>33</integer>
+ <integer>35</integer>
+ <integer>36</integer>
+ <integer>37</integer>
+ <integer>38</integer>
+ <integer>39</integer>
+ <integer>40</integer>
+ <integer>45</integer>
+ <integer>46</integer>
+ <integer>47</integer>
+ <integer>57</integer>
+ <integer>60</integer>
+ <integer>62</integer>
+ <integer>64</integer>
+ <integer>67</integer>
+ <integer>69</integer>
+ <integer>89</integer>
+ </array>
+ <key>openTypeOS2VendorID</key>
+ <string>SIL</string>
+ <key>openTypeOS2WeightClass</key>
+ <integer>700</integer>
+ <key>openTypeOS2WidthClass</key>
+ <integer>5</integer>
+ <key>openTypeOS2WinAscent</key>
+ <integer>2100</integer>
+ <key>openTypeOS2WinDescent</key>
+ <integer>550</integer>
+ <key>postscriptBlueValues</key>
+ <array>
+ <integer>-490</integer>
+ <integer>-490</integer>
+ <integer>-25</integer>
+ <integer>0</integer>
+ <integer>1020</integer>
+ <integer>1040</integer>
+ <integer>1455</integer>
+ <integer>1485</integer>
+ <integer>1600</integer>
+ <integer>1620</integer>
+ </array>
+ <key>postscriptFamilyBlues</key>
+ <array/>
+ <key>postscriptFontName</key>
+ <string>PsfTest-BoldItalic</string>
+ <key>postscriptFullName</key>
+ <string>Psf Test Bold Italic</string>
+ <key>postscriptStemSnapH</key>
+ <array>
+ <integer>140</integer>
+ <integer>145</integer>
+ <integer>150</integer>
+ <integer>155</integer>
+ <integer>160</integer>
+ <integer>165</integer>
+ <integer>170</integer>
+ <integer>175</integer>
+ <integer>185</integer>
+ <integer>270</integer>
+ </array>
+ <key>postscriptStemSnapV</key>
+ <array>
+ <integer>165</integer>
+ <integer>180</integer>
+ <integer>185</integer>
+ <integer>190</integer>
+ <integer>195</integer>
+ <integer>200</integer>
+ <integer>205</integer>
+ <integer>270</integer>
+ </array>
+ <key>postscriptUnderlinePosition</key>
+ <integer>-110</integer>
+ <key>postscriptUnderlineThickness</key>
+ <integer>80</integer>
+ <key>styleMapFamilyName</key>
+ <string>Psf Test</string>
+ <key>styleMapStyleName</key>
+ <string>bold italic</string>
+ <key>styleName</key>
+ <string>Bold Italic</string>
+ <key>trademark</key>
+ <string>Andika is a trademark of SIL International.</string>
+ <key>unitsPerEm</key>
+ <integer>2048</integer>
+ <key>versionMajor</key>
+ <integer>5</integer>
+ <key>versionMinor</key>
+ <integer>550</integer>
+ <key>xHeight</key>
+ <integer>1040</integer>
+</dict>
+</plist>
diff --git a/tests/reference/ufo/psfsetpsnames.ufo/glyphs/A_mpersand.glif b/tests/reference/ufo/psfsetpsnames.ufo/glyphs/A_mpersand.glif
new file mode 100644
index 0000000..f3fb1c7
--- /dev/null
+++ b/tests/reference/ufo/psfsetpsnames.ufo/glyphs/A_mpersand.glif
@@ -0,0 +1,61 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="Ampersand" format="2">
+ <advance width="1333"/>
+ <unicode hex="0026"/>
+ <outline>
+ <contour>
+ <point x="1146" y="594" type="line"/>
+ <point x="1040" y="429"/>
+ <point x="712" y="198"/>
+ <point x="537" y="198" type="curve" smooth="yes"/>
+ <point x="437" y="198"/>
+ <point x="363" y="257"/>
+ <point x="363" y="345" type="curve" smooth="yes"/>
+ <point x="363" y="490"/>
+ <point x="474" y="535"/>
+ <point x="695" y="693" type="curve" smooth="yes"/>
+ <point x="940" y="868"/>
+ <point x="1160" y="1032"/>
+ <point x="1160" y="1213" type="curve" smooth="yes"/>
+ <point x="1160" y="1361"/>
+ <point x="1026" y="1470"/>
+ <point x="849" y="1470" type="curve" smooth="yes"/>
+ <point x="637" y="1470"/>
+ <point x="414" y="1364"/>
+ <point x="414" y="1124" type="curve" smooth="yes"/>
+ <point x="414" y="968"/>
+ <point x="552" y="751"/>
+ <point x="661" y="535" type="curve" smooth="yes"/>
+ <point x="842" y="177"/>
+ <point x="969" y="-25"/>
+ <point x="1021" y="-25" type="curve" smooth="yes"/>
+ <point x="1056" y="-25"/>
+ <point x="1205" y="57"/>
+ <point x="1250" y="89" type="curve"/>
+ <point x="1165" y="129"/>
+ <point x="1073" y="302"/>
+ <point x="890" y="673" type="curve" smooth="yes"/>
+ <point x="788" y="881"/>
+ <point x="651" y="1063"/>
+ <point x="651" y="1163" type="curve" smooth="yes"/>
+ <point x="651" y="1245"/>
+ <point x="729" y="1307"/>
+ <point x="803" y="1307" type="curve" smooth="yes"/>
+ <point x="873" y="1307"/>
+ <point x="926" y="1250"/>
+ <point x="926" y="1184" type="curve" smooth="yes"/>
+ <point x="926" y="1081"/>
+ <point x="821" y="997"/>
+ <point x="600" y="832" type="curve" smooth="yes"/>
+ <point x="392" y="677"/>
+ <point x="108" y="540"/>
+ <point x="108" y="268" type="curve" smooth="yes"/>
+ <point x="108" y="98"/>
+ <point x="229" y="-25"/>
+ <point x="466" y="-25" type="curve" smooth="yes"/>
+ <point x="749" y="-25"/>
+ <point x="1120" y="261"/>
+ <point x="1237" y="421" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetpsnames.ufo/glyphs/A_pos.glif b/tests/reference/ufo/psfsetpsnames.ufo/glyphs/A_pos.glif
new file mode 100644
index 0000000..68b000e
--- /dev/null
+++ b/tests/reference/ufo/psfsetpsnames.ufo/glyphs/A_pos.glif
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="Apos" format="2">
+ <advance width="605"/>
+ <unicode hex="0027"/>
+ <outline>
+ <contour>
+ <point x="598" y="1035" type="line"/>
+ <point x="637" y="1174"/>
+ <point x="676" y="1326"/>
+ <point x="766" y="1569" type="curve"/>
+ <point x="521" y="1569" type="line"/>
+ <point x="491" y="1326"/>
+ <point x="453" y="1174"/>
+ <point x="423" y="1035" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetpsnames.ufo/glyphs/A_sterisk.glif b/tests/reference/ufo/psfsetpsnames.ufo/glyphs/A_sterisk.glif
new file mode 100644
index 0000000..a36131c
--- /dev/null
+++ b/tests/reference/ufo/psfsetpsnames.ufo/glyphs/A_sterisk.glif
@@ -0,0 +1,51 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="Asterisk" format="2">
+ <advance width="1020"/>
+ <unicode hex="002A"/>
+ <outline>
+ <contour>
+ <point x="1135" y="1478" type="line"/>
+ <point x="1039" y="1412"/>
+ <point x="956" y="1353"/>
+ <point x="856" y="1295" type="curve"/>
+ <point x="885" y="1391"/>
+ <point x="915" y="1471"/>
+ <point x="958" y="1584" type="curve"/>
+ <point x="759" y="1584" type="line"/>
+ <point x="753" y="1482"/>
+ <point x="748" y="1398"/>
+ <point x="730" y="1295" type="curve"/>
+ <point x="658" y="1346"/>
+ <point x="599" y="1394"/>
+ <point x="532" y="1461" type="curve"/>
+ <point x="388" y="1293" type="line"/>
+ <point x="484" y="1258"/>
+ <point x="575" y="1222"/>
+ <point x="647" y="1184" type="curve"/>
+ <point x="552" y="1141"/>
+ <point x="459" y="1109"/>
+ <point x="341" y="1066" type="curve"/>
+ <point x="398" y="888" type="line"/>
+ <point x="494" y="958"/>
+ <point x="575" y="1016"/>
+ <point x="674" y="1076" type="curve"/>
+ <point x="641" y="973"/>
+ <point x="610" y="887"/>
+ <point x="566" y="785" type="curve"/>
+ <point x="767" y="785" type="line"/>
+ <point x="773" y="897"/>
+ <point x="785" y="977"/>
+ <point x="800" y="1073" type="curve"/>
+ <point x="875" y="1017"/>
+ <point x="929" y="971"/>
+ <point x="995" y="905" type="curve"/>
+ <point x="1144" y="1078" type="line"/>
+ <point x="1045" y="1116"/>
+ <point x="967" y="1143"/>
+ <point x="886" y="1184" type="curve"/>
+ <point x="984" y="1229"/>
+ <point x="1075" y="1264"/>
+ <point x="1190" y="1308" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetpsnames.ufo/glyphs/A_tS_gn.glif b/tests/reference/ufo/psfsetpsnames.ufo/glyphs/A_tS_gn.glif
new file mode 100644
index 0000000..e2233cf
--- /dev/null
+++ b/tests/reference/ufo/psfsetpsnames.ufo/glyphs/A_tS_gn.glif
@@ -0,0 +1,104 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="AtSgn" format="2">
+ <advance width="1693"/>
+ <unicode hex="0040"/>
+ <outline>
+ <contour>
+ <point x="1082" y="10" type="line"/>
+ <point x="1008" y="-34"/>
+ <point x="933" y="-59"/>
+ <point x="840" y="-59" type="curve" smooth="yes"/>
+ <point x="540" y="-59"/>
+ <point x="362" y="143"/>
+ <point x="362" y="434" type="curve" smooth="yes"/>
+ <point x="362" y="498"/>
+ <point x="371" y="567"/>
+ <point x="389" y="639" type="curve" smooth="yes"/>
+ <point x="480" y="1003"/>
+ <point x="783" y="1228"/>
+ <point x="1121" y="1228" type="curve" smooth="yes"/>
+ <point x="1424" y="1228"/>
+ <point x="1581" y="1069"/>
+ <point x="1581" y="813" type="curve" smooth="yes"/>
+ <point x="1581" y="753"/>
+ <point x="1572" y="688"/>
+ <point x="1555" y="619" type="curve" smooth="yes"/>
+ <point x="1506" y="418"/>
+ <point x="1400" y="331"/>
+ <point x="1340" y="331" type="curve" smooth="yes"/>
+ <point x="1307" y="331"/>
+ <point x="1287" y="362"/>
+ <point x="1287" y="432" type="curve" smooth="yes"/>
+ <point x="1287" y="482"/>
+ <point x="1297" y="551"/>
+ <point x="1320" y="643" type="curve" smooth="yes"/>
+ <point x="1401" y="970" type="line"/>
+ <point x="1323" y="1005"/>
+ <point x="1182" y="1030"/>
+ <point x="1101" y="1030" type="curve" smooth="yes"/>
+ <point x="937" y="1030"/>
+ <point x="822" y="974"/>
+ <point x="710" y="862" type="curve" smooth="yes"/>
+ <point x="637" y="789"/>
+ <point x="569" y="677"/>
+ <point x="539" y="556" type="curve" smooth="yes"/>
+ <point x="529" y="518"/>
+ <point x="525" y="481"/>
+ <point x="525" y="447" type="curve" smooth="yes"/>
+ <point x="525" y="279"/>
+ <point x="629" y="161"/>
+ <point x="740" y="161" type="curve" smooth="yes"/>
+ <point x="867" y="161"/>
+ <point x="1034" y="328"/>
+ <point x="1117" y="450" type="curve"/>
+ <point x="1112" y="422"/>
+ <point x="1110" y="394"/>
+ <point x="1110" y="367" type="curve" smooth="yes"/>
+ <point x="1110" y="252"/>
+ <point x="1157" y="155"/>
+ <point x="1291" y="155" type="curve" smooth="yes"/>
+ <point x="1454" y="155"/>
+ <point x="1674" y="332"/>
+ <point x="1752" y="646" type="curve" smooth="yes"/>
+ <point x="1768" y="710"/>
+ <point x="1775" y="771"/>
+ <point x="1775" y="829" type="curve" smooth="yes"/>
+ <point x="1775" y="1169"/>
+ <point x="1520" y="1411"/>
+ <point x="1156" y="1411" type="curve" smooth="yes"/>
+ <point x="731" y="1411"/>
+ <point x="322" y="1180"/>
+ <point x="183" y="624" type="curve" smooth="yes"/>
+ <point x="163" y="544"/>
+ <point x="154" y="469"/>
+ <point x="154" y="398" type="curve" smooth="yes"/>
+ <point x="154" y="-1"/>
+ <point x="448" y="-243"/>
+ <point x="789" y="-243" type="curve" smooth="yes"/>
+ <point x="924" y="-243"/>
+ <point x="1076" y="-206"/>
+ <point x="1193" y="-137" type="curve"/>
+ </contour>
+ <contour>
+ <point x="1135" y="703" type="line"/>
+ <point x="1069" y="566"/>
+ <point x="899" y="346"/>
+ <point x="809" y="346" type="curve" smooth="yes"/>
+ <point x="757" y="346"/>
+ <point x="726" y="386"/>
+ <point x="726" y="463" type="curve" smooth="yes"/>
+ <point x="726" y="493"/>
+ <point x="731" y="528"/>
+ <point x="741" y="569" type="curve" smooth="yes"/>
+ <point x="760" y="645"/>
+ <point x="803" y="731"/>
+ <point x="853" y="778" type="curve" smooth="yes"/>
+ <point x="901" y="824"/>
+ <point x="957" y="846"/>
+ <point x="1025" y="846" type="curve" smooth="yes"/>
+ <point x="1099" y="846"/>
+ <point x="1133" y="828"/>
+ <point x="1162" y="812" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetpsnames.ufo/glyphs/C_ircumA_ccent.glif b/tests/reference/ufo/psfsetpsnames.ufo/glyphs/C_ircumA_ccent.glif
new file mode 100644
index 0000000..b60b998
--- /dev/null
+++ b/tests/reference/ufo/psfsetpsnames.ufo/glyphs/C_ircumA_ccent.glif
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="CircumAccent" format="2">
+ <advance width="860"/>
+ <unicode hex="005E"/>
+ <anchor x="788" y="1635" name="U"/>
+ <outline>
+ <contour>
+ <point x="1056" y="1188" type="line"/>
+ <point x="845" y="1584" type="line"/>
+ <point x="545" y="1584" type="line"/>
+ <point x="177" y="1188" type="line"/>
+ <point x="417" y="1188" type="line"/>
+ <point x="674" y="1416" type="line"/>
+ <point x="817" y="1188" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetpsnames.ufo/glyphs/C_olon.glif b/tests/reference/ufo/psfsetpsnames.ufo/glyphs/C_olon.glif
new file mode 100644
index 0000000..37f30d8
--- /dev/null
+++ b/tests/reference/ufo/psfsetpsnames.ufo/glyphs/C_olon.glif
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="Colon" format="2">
+ <advance width="690"/>
+ <unicode hex="003A"/>
+ <outline>
+ <contour>
+ <point x="171" y="116" type="curve" smooth="yes"/>
+ <point x="171" y="35"/>
+ <point x="232" y="-25"/>
+ <point x="318" y="-25" type="curve" smooth="yes"/>
+ <point x="436" y="-25"/>
+ <point x="531" y="71"/>
+ <point x="531" y="181" type="curve" smooth="yes"/>
+ <point x="531" y="261"/>
+ <point x="472" y="322"/>
+ <point x="385" y="322" type="curve" smooth="yes"/>
+ <point x="268" y="322"/>
+ <point x="171" y="226"/>
+ </contour>
+ <contour>
+ <point x="319" y="710" type="curve" smooth="yes"/>
+ <point x="319" y="629"/>
+ <point x="380" y="569"/>
+ <point x="466" y="569" type="curve" smooth="yes"/>
+ <point x="584" y="569"/>
+ <point x="679" y="665"/>
+ <point x="679" y="775" type="curve" smooth="yes"/>
+ <point x="679" y="855"/>
+ <point x="620" y="916"/>
+ <point x="533" y="916" type="curve" smooth="yes"/>
+ <point x="416" y="916"/>
+ <point x="319" y="820"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetpsnames.ufo/glyphs/C_ombA_cute.glif b/tests/reference/ufo/psfsetpsnames.ufo/glyphs/C_ombA_cute.glif
new file mode 100644
index 0000000..f3ea065
--- /dev/null
+++ b/tests/reference/ufo/psfsetpsnames.ufo/glyphs/C_ombA_cute.glif
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="CombAcute" format="2">
+ <unicode hex="0301"/>
+ <anchor x="-251" y="1635" name="U"/>
+ <anchor x="-325" y="1100" name="_U"/>
+ <outline>
+ <contour>
+ <point x="-165" y="1584" type="line"/>
+ <point x="-523" y="1188" type="line"/>
+ <point x="-283" y="1188" type="line"/>
+ <point x="204" y="1584" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetpsnames.ufo/glyphs/C_ombC_ircum.glif b/tests/reference/ufo/psfsetpsnames.ufo/glyphs/C_ombC_ircum.glif
new file mode 100644
index 0000000..9dc18ac
--- /dev/null
+++ b/tests/reference/ufo/psfsetpsnames.ufo/glyphs/C_ombC_ircum.glif
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="CombCircum" format="2">
+ <unicode hex="0302"/>
+ <anchor x="-239" y="1635" name="U"/>
+ <anchor x="-330" y="1100" name="_U"/>
+ <outline>
+ <contour>
+ <point x="88" y="1188" type="line"/>
+ <point x="-123" y="1584" type="line"/>
+ <point x="-423" y="1584" type="line"/>
+ <point x="-791" y="1188" type="line"/>
+ <point x="-551" y="1188" type="line"/>
+ <point x="-294" y="1416" type="line"/>
+ <point x="-151" y="1188" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetpsnames.ufo/glyphs/C_ombD_iaer.glif b/tests/reference/ufo/psfsetpsnames.ufo/glyphs/C_ombD_iaer.glif
new file mode 100644
index 0000000..490587d
--- /dev/null
+++ b/tests/reference/ufo/psfsetpsnames.ufo/glyphs/C_ombD_iaer.glif
@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="CombDiaer" format="2">
+ <unicode hex="0308"/>
+ <anchor x="-243" y="1585" name="U"/>
+ <anchor x="-365" y="1100" name="_U"/>
+ <outline>
+ <contour>
+ <point x="-233" y="1338" type="curve" smooth="yes"/>
+ <point x="-233" y="1256"/>
+ <point x="-172" y="1198"/>
+ <point x="-86" y="1198" type="curve" smooth="yes"/>
+ <point x="32" y="1198"/>
+ <point x="126" y="1294"/>
+ <point x="126" y="1404" type="curve" smooth="yes"/>
+ <point x="126" y="1484"/>
+ <point x="66" y="1544"/>
+ <point x="-21" y="1544" type="curve" smooth="yes"/>
+ <point x="-139" y="1544"/>
+ <point x="-233" y="1447"/>
+ </contour>
+ <contour>
+ <point x="-723" y="1338" type="curve" smooth="yes"/>
+ <point x="-723" y="1256"/>
+ <point x="-662" y="1198"/>
+ <point x="-576" y="1198" type="curve" smooth="yes"/>
+ <point x="-457" y="1198"/>
+ <point x="-363" y="1293"/>
+ <point x="-363" y="1404" type="curve" smooth="yes"/>
+ <point x="-363" y="1484"/>
+ <point x="-423" y="1544"/>
+ <point x="-510" y="1544" type="curve" smooth="yes"/>
+ <point x="-628" y="1544"/>
+ <point x="-723" y="1448"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetpsnames.ufo/glyphs/C_ombG_rave.glif b/tests/reference/ufo/psfsetpsnames.ufo/glyphs/C_ombG_rave.glif
new file mode 100644
index 0000000..49617c2
--- /dev/null
+++ b/tests/reference/ufo/psfsetpsnames.ufo/glyphs/C_ombG_rave.glif
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="CombGrave" format="2">
+ <unicode hex="0300"/>
+ <anchor x="-241" y="1635" name="U"/>
+ <anchor x="-415" y="1100" name="_U"/>
+ <outline>
+ <contour>
+ <point x="-725" y="1584" type="line"/>
+ <point x="-403" y="1188" type="line"/>
+ <point x="-173" y="1188" type="line"/>
+ <point x="-395" y="1584" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetpsnames.ufo/glyphs/C_ombR_ingA_bv.glif b/tests/reference/ufo/psfsetpsnames.ufo/glyphs/C_ombR_ingA_bv.glif
new file mode 100644
index 0000000..27f9832
--- /dev/null
+++ b/tests/reference/ufo/psfsetpsnames.ufo/glyphs/C_ombR_ingA_bv.glif
@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="CombRingAbv" format="2">
+ <unicode hex="030A"/>
+ <anchor x="-221" y="1635" name="U"/>
+ <anchor x="-357" y="1100" name="_U"/>
+ <outline>
+ <contour>
+ <point x="-358" y="1292" type="curve" smooth="yes"/>
+ <point x="-406" y="1292"/>
+ <point x="-442" y="1330"/>
+ <point x="-442" y="1375" type="curve" smooth="yes"/>
+ <point x="-442" y="1440"/>
+ <point x="-385" y="1480"/>
+ <point x="-331" y="1480" type="curve" smooth="yes"/>
+ <point x="-283" y="1480"/>
+ <point x="-247" y="1443"/>
+ <point x="-247" y="1398" type="curve" smooth="yes"/>
+ <point x="-247" y="1335"/>
+ <point x="-301" y="1292"/>
+ </contour>
+ <contour>
+ <point x="-598" y="1348" type="curve" smooth="yes"/>
+ <point x="-598" y="1238"/>
+ <point x="-504" y="1148"/>
+ <point x="-384" y="1148" type="curve" smooth="yes"/>
+ <point x="-223" y="1148"/>
+ <point x="-92" y="1271"/>
+ <point x="-92" y="1424" type="curve" smooth="yes"/>
+ <point x="-92" y="1534"/>
+ <point x="-186" y="1624"/>
+ <point x="-306" y="1624" type="curve" smooth="yes"/>
+ <point x="-467" y="1624"/>
+ <point x="-598" y="1501"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetpsnames.ufo/glyphs/C_ombT_ilde.glif b/tests/reference/ufo/psfsetpsnames.ufo/glyphs/C_ombT_ilde.glif
new file mode 100644
index 0000000..1aa1b62
--- /dev/null
+++ b/tests/reference/ufo/psfsetpsnames.ufo/glyphs/C_ombT_ilde.glif
@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="CombTilde" format="2">
+ <unicode hex="0303"/>
+ <anchor x="-355" y="1490" name="U"/>
+ <anchor x="-390" y="1100" name="_U"/>
+ <outline>
+ <contour>
+ <point x="-687" y="1178" type="line"/>
+ <point x="-673" y="1232"/>
+ <point x="-628" y="1271"/>
+ <point x="-584" y="1271" type="curve" smooth="yes"/>
+ <point x="-546" y="1271"/>
+ <point x="-498" y="1247"/>
+ <point x="-437" y="1217" type="curve" smooth="yes"/>
+ <point x="-375" y="1187"/>
+ <point x="-327" y="1168"/>
+ <point x="-265" y="1168" type="curve" smooth="yes"/>
+ <point x="-129" y="1168"/>
+ <point x="-13" y="1294"/>
+ <point x="30" y="1465" type="curve"/>
+ <point x="-125" y="1465" type="line"/>
+ <point x="-138" y="1415"/>
+ <point x="-190" y="1373"/>
+ <point x="-235" y="1373" type="curve" smooth="yes"/>
+ <point x="-272" y="1373"/>
+ <point x="-306" y="1399"/>
+ <point x="-366" y="1423" type="curve" smooth="yes"/>
+ <point x="-438" y="1452"/>
+ <point x="-498" y="1475"/>
+ <point x="-563" y="1475" type="curve" smooth="yes"/>
+ <point x="-695" y="1475"/>
+ <point x="-802" y="1336"/>
+ <point x="-842" y="1178" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetpsnames.ufo/glyphs/C_omma.glif b/tests/reference/ufo/psfsetpsnames.ufo/glyphs/C_omma.glif
new file mode 100644
index 0000000..4105316
--- /dev/null
+++ b/tests/reference/ufo/psfsetpsnames.ufo/glyphs/C_omma.glif
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="Comma" format="2">
+ <advance width="645"/>
+ <unicode hex="002C"/>
+ <outline>
+ <contour>
+ <point x="137" y="49" type="line"/>
+ <point x="297" y="49" type="line"/>
+ <point x="276" y="-34"/>
+ <point x="192" y="-151"/>
+ <point x="59" y="-262" type="curve"/>
+ <point x="187" y="-332" type="line"/>
+ <point x="337" y="-222"/>
+ <point x="539" y="-11"/>
+ <point x="539" y="165" type="curve" smooth="yes"/>
+ <point x="539" y="262"/>
+ <point x="495" y="337"/>
+ <point x="379" y="337" type="curve" smooth="yes"/>
+ <point x="266" y="337"/>
+ <point x="187" y="252"/>
+ <point x="169" y="178" type="curve" smooth="yes"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetpsnames.ufo/glyphs/D_igitE_ight.glif b/tests/reference/ufo/psfsetpsnames.ufo/glyphs/D_igitE_ight.glif
new file mode 100644
index 0000000..9272dc9
--- /dev/null
+++ b/tests/reference/ufo/psfsetpsnames.ufo/glyphs/D_igitE_ight.glif
@@ -0,0 +1,63 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="DigitEight" format="2">
+ <advance width="1180"/>
+ <unicode hex="0038"/>
+ <anchor x="515" y="-100" name="L"/>
+ <anchor x="922" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="543" y="-25" type="curve" smooth="yes"/>
+ <point x="860" y="-25"/>
+ <point x="1182" y="176"/>
+ <point x="1182" y="498" type="curve" smooth="yes"/>
+ <point x="1182" y="642"/>
+ <point x="1090" y="742"/>
+ <point x="1011" y="787" type="curve"/>
+ <point x="1159" y="866"/>
+ <point x="1279" y="994"/>
+ <point x="1279" y="1163" type="curve" smooth="yes"/>
+ <point x="1279" y="1342"/>
+ <point x="1123" y="1470"/>
+ <point x="906" y="1470" type="curve" smooth="yes"/>
+ <point x="632" y="1470"/>
+ <point x="349" y="1310"/>
+ <point x="349" y="1028" type="curve" smooth="yes"/>
+ <point x="349" y="904"/>
+ <point x="412" y="821"/>
+ <point x="466" y="787" type="curve"/>
+ <point x="270" y="703"/>
+ <point x="108" y="563"/>
+ <point x="108" y="341" type="curve" smooth="yes"/>
+ <point x="108" y="123"/>
+ <point x="301" y="-25"/>
+ </contour>
+ <contour>
+ <point x="760" y="886" type="curve" smooth="yes"/>
+ <point x="651" y="886"/>
+ <point x="593" y="939"/>
+ <point x="593" y="1038" type="curve" smooth="yes"/>
+ <point x="593" y="1175"/>
+ <point x="721" y="1277"/>
+ <point x="858" y="1277" type="curve" smooth="yes"/>
+ <point x="976" y="1277"/>
+ <point x="1028" y="1221"/>
+ <point x="1028" y="1127" type="curve" smooth="yes"/>
+ <point x="1028" y="993"/>
+ <point x="898" y="886"/>
+ </contour>
+ <contour>
+ <point x="595" y="183" type="curve" smooth="yes"/>
+ <point x="458" y="183"/>
+ <point x="375" y="267"/>
+ <point x="375" y="384" type="curve" smooth="yes"/>
+ <point x="375" y="549"/>
+ <point x="549" y="673"/>
+ <point x="707" y="673" type="curve" smooth="yes"/>
+ <point x="833" y="673"/>
+ <point x="920" y="602"/>
+ <point x="920" y="477" type="curve" smooth="yes"/>
+ <point x="920" y="317"/>
+ <point x="759" y="183"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetpsnames.ufo/glyphs/D_igitF_ive.glif b/tests/reference/ufo/psfsetpsnames.ufo/glyphs/D_igitF_ive.glif
new file mode 100644
index 0000000..1c4dd99
--- /dev/null
+++ b/tests/reference/ufo/psfsetpsnames.ufo/glyphs/D_igitF_ive.glif
@@ -0,0 +1,44 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="DigitFive" format="2">
+ <advance width="1180"/>
+ <unicode hex="0035"/>
+ <anchor x="515" y="-100" name="L"/>
+ <anchor x="922" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="1330" y="1445" type="line"/>
+ <point x="475" y="1445" type="line"/>
+ <point x="274" y="639" type="line"/>
+ <point x="410" y="686"/>
+ <point x="519" y="703"/>
+ <point x="625" y="703" type="curve" smooth="yes"/>
+ <point x="763" y="703"/>
+ <point x="867" y="630"/>
+ <point x="867" y="507" type="curve" smooth="yes"/>
+ <point x="867" y="318"/>
+ <point x="680" y="213"/>
+ <point x="503" y="213" type="curve" smooth="yes"/>
+ <point x="363" y="213"/>
+ <point x="255" y="260"/>
+ <point x="168" y="356" type="curve"/>
+ <point x="59" y="79" type="line"/>
+ <point x="165" y="2"/>
+ <point x="308" y="-25"/>
+ <point x="483" y="-25" type="curve" smooth="yes"/>
+ <point x="841" y="-25"/>
+ <point x="1155" y="204"/>
+ <point x="1155" y="564" type="curve" smooth="yes"/>
+ <point x="1155" y="774"/>
+ <point x="1007" y="921"/>
+ <point x="774" y="921" type="curve" smooth="yes"/>
+ <point x="712" y="921"/>
+ <point x="632" y="902"/>
+ <point x="595" y="886" type="curve"/>
+ <point x="674" y="1203" type="line"/>
+ <point x="1004" y="1203" type="line" smooth="yes"/>
+ <point x="1088" y="1203"/>
+ <point x="1193" y="1199"/>
+ <point x="1264" y="1183" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetpsnames.ufo/glyphs/D_igitF_our.glif b/tests/reference/ufo/psfsetpsnames.ufo/glyphs/D_igitF_our.glif
new file mode 100644
index 0000000..617709f
--- /dev/null
+++ b/tests/reference/ufo/psfsetpsnames.ufo/glyphs/D_igitF_our.glif
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="DigitFour" format="2">
+ <advance width="1180"/>
+ <unicode hex="0034"/>
+ <anchor x="522" y="-100" name="L"/>
+ <anchor x="929" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="1180" y="342" type="line"/>
+ <point x="1235" y="564" type="line"/>
+ <point x="1075" y="564" type="line"/>
+ <point x="1295" y="1445" type="line"/>
+ <point x="945" y="1445" type="line"/>
+ <point x="120" y="564" type="line"/>
+ <point x="65" y="342" type="line"/>
+ <point x="755" y="342" type="line"/>
+ <point x="670" y="0" type="line"/>
+ <point x="935" y="0" type="line"/>
+ <point x="1020" y="342" type="line"/>
+ </contour>
+ <contour>
+ <point x="954" y="1143" type="line"/>
+ <point x="810" y="564" type="line"/>
+ <point x="385" y="564" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetpsnames.ufo/glyphs/D_igitN_ine.glif b/tests/reference/ufo/psfsetpsnames.ufo/glyphs/D_igitN_ine.glif
new file mode 100644
index 0000000..85e36a0
--- /dev/null
+++ b/tests/reference/ufo/psfsetpsnames.ufo/glyphs/D_igitN_ine.glif
@@ -0,0 +1,49 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="DigitNine" format="2">
+ <advance width="1180"/>
+ <unicode hex="0039"/>
+ <anchor x="515" y="-100" name="L"/>
+ <anchor x="922" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="119" y="84" type="line"/>
+ <point x="199" y="25"/>
+ <point x="327" y="-25"/>
+ <point x="455" y="-25" type="curve" smooth="yes"/>
+ <point x="979" y="-25"/>
+ <point x="1289" y="533"/>
+ <point x="1289" y="979" type="curve" smooth="yes"/>
+ <point x="1289" y="1248"/>
+ <point x="1164" y="1470"/>
+ <point x="833" y="1470" type="curve" smooth="yes"/>
+ <point x="554" y="1470"/>
+ <point x="255" y="1239"/>
+ <point x="255" y="932" type="curve" smooth="yes"/>
+ <point x="255" y="736"/>
+ <point x="399" y="570"/>
+ <point x="644" y="570" type="curve" smooth="yes"/>
+ <point x="833" y="570"/>
+ <point x="1027" y="700"/>
+ <point x="1164" y="859" type="curve"/>
+ <point x="1123" y="981" type="line"/>
+ <point x="1021" y="868"/>
+ <point x="863" y="782"/>
+ <point x="728" y="782" type="curve" smooth="yes"/>
+ <point x="589" y="782"/>
+ <point x="519" y="845"/>
+ <point x="519" y="955" type="curve" smooth="yes"/>
+ <point x="519" y="1133"/>
+ <point x="653" y="1237"/>
+ <point x="801" y="1237" type="curve" smooth="yes"/>
+ <point x="951" y="1237"/>
+ <point x="1029" y="1136"/>
+ <point x="1029" y="965" type="curve" smooth="yes"/>
+ <point x="1029" y="476"/>
+ <point x="710" y="208"/>
+ <point x="513" y="208" type="curve" smooth="yes"/>
+ <point x="417" y="208"/>
+ <point x="301" y="252"/>
+ <point x="237" y="337" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetpsnames.ufo/glyphs/D_igitO_ne.glif b/tests/reference/ufo/psfsetpsnames.ufo/glyphs/D_igitO_ne.glif
new file mode 100644
index 0000000..df3633d
--- /dev/null
+++ b/tests/reference/ufo/psfsetpsnames.ufo/glyphs/D_igitO_ne.glif
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="DigitOne" format="2">
+ <advance width="1180"/>
+ <unicode hex="0031"/>
+ <anchor x="515" y="-100" name="L"/>
+ <anchor x="922" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="490" y="233" type="line"/>
+ <point x="183" y="233" type="line"/>
+ <point x="125" y="0" type="line"/>
+ <point x="1015" y="0" type="line"/>
+ <point x="1073" y="233" type="line"/>
+ <point x="765" y="233" type="line"/>
+ <point x="1067" y="1445" type="line"/>
+ <point x="792" y="1445" type="line"/>
+ <point x="432" y="1265" type="line"/>
+ <point x="403" y="1008" type="line"/>
+ <point x="720" y="1158" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetpsnames.ufo/glyphs/D_igitS_even.glif b/tests/reference/ufo/psfsetpsnames.ufo/glyphs/D_igitS_even.glif
new file mode 100644
index 0000000..23ac13b
--- /dev/null
+++ b/tests/reference/ufo/psfsetpsnames.ufo/glyphs/D_igitS_even.glif
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="DigitSeven" format="2">
+ <advance width="1180"/>
+ <unicode hex="0037"/>
+ <anchor x="515" y="-100" name="L"/>
+ <anchor x="922" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="480" y="0" type="line"/>
+ <point x="722" y="454"/>
+ <point x="1004" y="846"/>
+ <point x="1400" y="1247" type="curve"/>
+ <point x="1450" y="1445" type="line"/>
+ <point x="390" y="1445" type="line"/>
+ <point x="324" y="1178" type="line"/>
+ <point x="404" y="1194"/>
+ <point x="521" y="1198"/>
+ <point x="709" y="1198" type="curve" smooth="yes"/>
+ <point x="1039" y="1198" type="line"/>
+ <point x="689" y="829"/>
+ <point x="488" y="560"/>
+ <point x="175" y="0" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetpsnames.ufo/glyphs/D_igitS_ix.glif b/tests/reference/ufo/psfsetpsnames.ufo/glyphs/D_igitS_ix.glif
new file mode 100644
index 0000000..5fad278
--- /dev/null
+++ b/tests/reference/ufo/psfsetpsnames.ufo/glyphs/D_igitS_ix.glif
@@ -0,0 +1,49 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="DigitSix" format="2">
+ <advance width="1180"/>
+ <unicode hex="0036"/>
+ <anchor x="525" y="-100" name="L"/>
+ <anchor x="932" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="1347" y="1371" type="line"/>
+ <point x="1260" y="1440"/>
+ <point x="1149" y="1470"/>
+ <point x="1011" y="1470" type="curve" smooth="yes"/>
+ <point x="493" y="1470"/>
+ <point x="181" y="971"/>
+ <point x="181" y="500" type="curve" smooth="yes"/>
+ <point x="181" y="188"/>
+ <point x="368" y="-25"/>
+ <point x="635" y="-25" type="curve" smooth="yes"/>
+ <point x="954" y="-25"/>
+ <point x="1207" y="192"/>
+ <point x="1207" y="498" type="curve" smooth="yes"/>
+ <point x="1207" y="714"/>
+ <point x="1058" y="916"/>
+ <point x="813" y="916" type="curve" smooth="yes"/>
+ <point x="622" y="916"/>
+ <point x="477" y="802"/>
+ <point x="326" y="648" type="curve"/>
+ <point x="363" y="525" type="line"/>
+ <point x="470" y="637"/>
+ <point x="595" y="703"/>
+ <point x="750" y="703" type="curve" smooth="yes"/>
+ <point x="882" y="703"/>
+ <point x="954" y="586"/>
+ <point x="954" y="466" type="curve" smooth="yes"/>
+ <point x="954" y="325"/>
+ <point x="828" y="208"/>
+ <point x="677" y="208" type="curve" smooth="yes"/>
+ <point x="526" y="208"/>
+ <point x="447" y="350"/>
+ <point x="447" y="533" type="curve" smooth="yes"/>
+ <point x="447" y="978"/>
+ <point x="738" y="1237"/>
+ <point x="953" y="1237" type="curve" smooth="yes"/>
+ <point x="1049" y="1237"/>
+ <point x="1155" y="1204"/>
+ <point x="1220" y="1119" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetpsnames.ufo/glyphs/D_igitT_hree.glif b/tests/reference/ufo/psfsetpsnames.ufo/glyphs/D_igitT_hree.glif
new file mode 100644
index 0000000..5be951b
--- /dev/null
+++ b/tests/reference/ufo/psfsetpsnames.ufo/glyphs/D_igitT_hree.glif
@@ -0,0 +1,52 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="DigitThree" format="2">
+ <advance width="1180"/>
+ <unicode hex="0033"/>
+ <anchor x="515" y="-100" name="L"/>
+ <anchor x="922" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="548" y="876" type="line"/>
+ <point x="489" y="639" type="line"/>
+ <point x="579" y="639" type="line" smooth="yes"/>
+ <point x="778" y="639"/>
+ <point x="880" y="555"/>
+ <point x="880" y="452" type="curve" smooth="yes"/>
+ <point x="880" y="295"/>
+ <point x="726" y="208"/>
+ <point x="576" y="208" type="curve" smooth="yes"/>
+ <point x="386" y="208"/>
+ <point x="253" y="279"/>
+ <point x="174" y="401" type="curve"/>
+ <point x="72" y="129" type="line"/>
+ <point x="162" y="32"/>
+ <point x="321" y="-25"/>
+ <point x="518" y="-25" type="curve" smooth="yes"/>
+ <point x="867" y="-25"/>
+ <point x="1163" y="169"/>
+ <point x="1163" y="471" type="curve" smooth="yes"/>
+ <point x="1163" y="644"/>
+ <point x="999" y="751"/>
+ <point x="882" y="772" type="curve"/>
+ <point x="1076" y="817"/>
+ <point x="1296" y="963"/>
+ <point x="1296" y="1172" type="curve" smooth="yes"/>
+ <point x="1296" y="1348"/>
+ <point x="1112" y="1470"/>
+ <point x="856" y="1470" type="curve" smooth="yes"/>
+ <point x="689" y="1470"/>
+ <point x="529" y="1402"/>
+ <point x="427" y="1312" type="curve"/>
+ <point x="405" y="1084" type="line"/>
+ <point x="546" y="1199"/>
+ <point x="664" y="1237"/>
+ <point x="818" y="1237" type="curve" smooth="yes"/>
+ <point x="928" y="1237"/>
+ <point x="1001" y="1178"/>
+ <point x="1001" y="1100" type="curve" smooth="yes"/>
+ <point x="1001" y="975"/>
+ <point x="819" y="876"/>
+ <point x="638" y="876" type="curve" smooth="yes"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetpsnames.ufo/glyphs/D_igitT_wo.glif b/tests/reference/ufo/psfsetpsnames.ufo/glyphs/D_igitT_wo.glif
new file mode 100644
index 0000000..001d438
--- /dev/null
+++ b/tests/reference/ufo/psfsetpsnames.ufo/glyphs/D_igitT_wo.glif
@@ -0,0 +1,37 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="DigitTwo" format="2">
+ <advance width="1180"/>
+ <unicode hex="0032"/>
+ <anchor x="515" y="-100" name="L"/>
+ <anchor x="882" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="1094" y="257" type="line"/>
+ <point x="1010" y="244"/>
+ <point x="942" y="243"/>
+ <point x="745" y="243" type="curve" smooth="yes"/>
+ <point x="480" y="243" type="line"/>
+ <point x="875" y="492"/>
+ <point x="1255" y="786"/>
+ <point x="1255" y="1125" type="curve" smooth="yes"/>
+ <point x="1255" y="1324"/>
+ <point x="1106" y="1470"/>
+ <point x="846" y="1470" type="curve" smooth="yes"/>
+ <point x="667" y="1470"/>
+ <point x="472" y="1388"/>
+ <point x="363" y="1277" type="curve"/>
+ <point x="374" y="1039" type="line"/>
+ <point x="489" y="1146"/>
+ <point x="646" y="1223"/>
+ <point x="762" y="1223" type="curve" smooth="yes"/>
+ <point x="890" y="1223"/>
+ <point x="949" y="1138"/>
+ <point x="949" y="1040" type="curve" smooth="yes"/>
+ <point x="949" y="805"/>
+ <point x="500" y="440"/>
+ <point x="104" y="218" type="curve"/>
+ <point x="50" y="0" type="line"/>
+ <point x="1030" y="0" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetpsnames.ufo/glyphs/D_igitZ_ero.glif b/tests/reference/ufo/psfsetpsnames.ufo/glyphs/D_igitZ_ero.glif
new file mode 100644
index 0000000..895a8e4
--- /dev/null
+++ b/tests/reference/ufo/psfsetpsnames.ufo/glyphs/D_igitZ_ero.glif
@@ -0,0 +1,49 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="DigitZero" format="2">
+ <advance width="1180"/>
+ <unicode hex="0030"/>
+ <anchor x="520" y="-100" name="L"/>
+ <anchor x="927" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="959" y="683" type="curve" smooth="yes"/>
+ <point x="873" y="339"/>
+ <point x="762" y="203"/>
+ <point x="600" y="203" type="curve" smooth="yes"/>
+ <point x="469" y="203"/>
+ <point x="432" y="294"/>
+ <point x="432" y="454" type="curve" smooth="yes"/>
+ <point x="432" y="537"/>
+ <point x="447" y="630"/>
+ <point x="478" y="755" type="curve" smooth="yes"/>
+ <point x="564" y="1099"/>
+ <point x="676" y="1242"/>
+ <point x="839" y="1242" type="curve" smooth="yes"/>
+ <point x="971" y="1242"/>
+ <point x="1010" y="1140"/>
+ <point x="1010" y="992" type="curve" smooth="yes"/>
+ <point x="1010" y="907"/>
+ <point x="991" y="811"/>
+ </contour>
+ <contour>
+ <point x="1246" y="689" type="curve" smooth="yes"/>
+ <point x="1281" y="828"/>
+ <point x="1298" y="927"/>
+ <point x="1298" y="1028" type="curve" smooth="yes"/>
+ <point x="1298" y="1317"/>
+ <point x="1158" y="1470"/>
+ <point x="906" y="1470" type="curve" smooth="yes"/>
+ <point x="587" y="1470"/>
+ <point x="329" y="1302"/>
+ <point x="190" y="745" type="curve" smooth="yes"/>
+ <point x="157" y="611"/>
+ <point x="141" y="516"/>
+ <point x="141" y="420" type="curve" smooth="yes"/>
+ <point x="141" y="131"/>
+ <point x="292" y="-25"/>
+ <point x="533" y="-25" type="curve" smooth="yes"/>
+ <point x="854" y="-25"/>
+ <point x="1103" y="115"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetpsnames.ufo/glyphs/D_ollarS_gn.glif b/tests/reference/ufo/psfsetpsnames.ufo/glyphs/D_ollarS_gn.glif
new file mode 100644
index 0000000..0b8bdfc
--- /dev/null
+++ b/tests/reference/ufo/psfsetpsnames.ufo/glyphs/D_ollarS_gn.glif
@@ -0,0 +1,57 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="DollarSgn" format="2">
+ <advance width="1180"/>
+ <unicode hex="0024"/>
+ <outline>
+ <contour>
+ <point x="879" y="1584" type="line"/>
+ <point x="679" y="780" type="line"/>
+ <point x="634" y="719" type="line"/>
+ <point x="400" y="-218" type="line"/>
+ <point x="576" y="-218" type="line"/>
+ <point x="795" y="661" type="line"/>
+ <point x="842" y="727" type="line"/>
+ <point x="1055" y="1584" type="line"/>
+ </contour>
+ <contour>
+ <point x="1250" y="1303" type="line"/>
+ <point x="1145" y="1355"/>
+ <point x="1026" y="1375"/>
+ <point x="885" y="1375" type="curve" smooth="yes"/>
+ <point x="537" y="1375"/>
+ <point x="345" y="1216"/>
+ <point x="345" y="984" type="curve" smooth="yes"/>
+ <point x="345" y="841"/>
+ <point x="441" y="726"/>
+ <point x="638" y="622" type="curve" smooth="yes"/>
+ <point x="832" y="519"/>
+ <point x="881" y="451"/>
+ <point x="881" y="381" type="curve" smooth="yes"/>
+ <point x="881" y="274"/>
+ <point x="817" y="209"/>
+ <point x="613" y="209" type="curve" smooth="yes"/>
+ <point x="462" y="209"/>
+ <point x="336" y="298"/>
+ <point x="259" y="389" type="curve"/>
+ <point x="133" y="143" type="line"/>
+ <point x="243" y="56"/>
+ <point x="378" y="0"/>
+ <point x="566" y="0" type="curve" smooth="yes"/>
+ <point x="879" y="0"/>
+ <point x="1120" y="142"/>
+ <point x="1120" y="396" type="curve" smooth="yes"/>
+ <point x="1120" y="562"/>
+ <point x="1028" y="682"/>
+ <point x="817" y="803" type="curve" smooth="yes"/>
+ <point x="635" y="908"/>
+ <point x="592" y="958"/>
+ <point x="592" y="1016" type="curve" smooth="yes"/>
+ <point x="592" y="1113"/>
+ <point x="649" y="1176"/>
+ <point x="826" y="1176" type="curve" smooth="yes"/>
+ <point x="954" y="1176"/>
+ <point x="1048" y="1135"/>
+ <point x="1134" y="1066" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetpsnames.ufo/glyphs/D_ottedC_irc.glif b/tests/reference/ufo/psfsetpsnames.ufo/glyphs/D_ottedC_irc.glif
new file mode 100644
index 0000000..f7581b6
--- /dev/null
+++ b/tests/reference/ufo/psfsetpsnames.ufo/glyphs/D_ottedC_irc.glif
@@ -0,0 +1,235 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="DottedCirc" format="2">
+ <advance width="1086"/>
+ <unicode hex="25CC"/>
+ <anchor x="493" y="0" name="H"/>
+ <anchor x="545" y="-100" name="L"/>
+ <anchor x="750" y="0" name="O"/>
+ <anchor x="645" y="1000" name="U"/>
+ <outline>
+ <contour>
+ <point x="443" y="837" type="curve" smooth="yes"/>
+ <point x="443" y="864"/>
+ <point x="423" y="885"/>
+ <point x="398" y="885" type="curve" smooth="yes"/>
+ <point x="371" y="885"/>
+ <point x="348" y="861"/>
+ <point x="348" y="837" type="curve" smooth="yes"/>
+ <point x="348" y="809"/>
+ <point x="372" y="789"/>
+ <point x="398" y="789" type="curve" smooth="yes"/>
+ <point x="425" y="789"/>
+ <point x="443" y="812"/>
+ </contour>
+ <contour>
+ <point x="758" y="79" type="curve" smooth="yes"/>
+ <point x="758" y="106"/>
+ <point x="736" y="127"/>
+ <point x="710" y="127" type="curve" smooth="yes"/>
+ <point x="685" y="127"/>
+ <point x="662" y="103"/>
+ <point x="662" y="80" type="curve" smooth="yes"/>
+ <point x="662" y="52"/>
+ <point x="686" y="31"/>
+ <point x="710" y="31" type="curve" smooth="yes"/>
+ <point x="737" y="31"/>
+ <point x="758" y="55"/>
+ </contour>
+ <contour>
+ <point x="310" y="749" type="curve" smooth="yes"/>
+ <point x="310" y="775"/>
+ <point x="288" y="796"/>
+ <point x="263" y="796" type="curve" smooth="yes"/>
+ <point x="238" y="796"/>
+ <point x="215" y="774"/>
+ <point x="215" y="747" type="curve" smooth="yes"/>
+ <point x="215" y="722"/>
+ <point x="236" y="701"/>
+ <point x="263" y="701" type="curve" smooth="yes"/>
+ <point x="291" y="701"/>
+ <point x="310" y="720"/>
+ </contour>
+ <contour>
+ <point x="891" y="168" type="curve" smooth="yes"/>
+ <point x="891" y="197"/>
+ <point x="870" y="215"/>
+ <point x="843" y="215" type="curve" smooth="yes"/>
+ <point x="817" y="215"/>
+ <point x="795" y="194"/>
+ <point x="795" y="168" type="curve" smooth="yes"/>
+ <point x="795" y="143"/>
+ <point x="816" y="121"/>
+ <point x="843" y="121" type="curve" smooth="yes"/>
+ <point x="871" y="121"/>
+ <point x="891" y="143"/>
+ </contour>
+ <contour>
+ <point x="222" y="613" type="curve" smooth="yes"/>
+ <point x="222" y="640"/>
+ <point x="199" y="663"/>
+ <point x="173" y="663" type="curve" smooth="yes"/>
+ <point x="149" y="663"/>
+ <point x="126" y="642"/>
+ <point x="126" y="615" type="curve" smooth="yes"/>
+ <point x="126" y="591"/>
+ <point x="145" y="567"/>
+ <point x="173" y="567" type="curve" smooth="yes"/>
+ <point x="197" y="567"/>
+ <point x="222" y="587"/>
+ </contour>
+ <contour>
+ <point x="980" y="301" type="curve" smooth="yes"/>
+ <point x="980" y="327"/>
+ <point x="957" y="348"/>
+ <point x="932" y="348" type="curve" smooth="yes"/>
+ <point x="908" y="348"/>
+ <point x="884" y="332"/>
+ <point x="884" y="301" type="curve" smooth="yes"/>
+ <point x="884" y="277"/>
+ <point x="902" y="254"/>
+ <point x="932" y="254" type="curve" smooth="yes"/>
+ <point x="957" y="254"/>
+ <point x="980" y="274"/>
+ </contour>
+ <contour>
+ <point x="191" y="459" type="curve" smooth="yes"/>
+ <point x="191" y="484"/>
+ <point x="168" y="505"/>
+ <point x="143" y="505" type="curve" smooth="yes"/>
+ <point x="116" y="505"/>
+ <point x="95" y="484"/>
+ <point x="95" y="458" type="curve" smooth="yes"/>
+ <point x="95" y="433"/>
+ <point x="115" y="410"/>
+ <point x="143" y="410" type="curve" smooth="yes"/>
+ <point x="167" y="410"/>
+ <point x="191" y="432"/>
+ </contour>
+ <contour>
+ <point x="1011" y="458" type="curve" smooth="yes"/>
+ <point x="1011" y="484"/>
+ <point x="990" y="506"/>
+ <point x="964" y="506" type="curve" smooth="yes"/>
+ <point x="940" y="506"/>
+ <point x="915" y="484"/>
+ <point x="915" y="457" type="curve" smooth="yes"/>
+ <point x="915" y="433"/>
+ <point x="936" y="411"/>
+ <point x="964" y="411" type="curve" smooth="yes"/>
+ <point x="990" y="411"/>
+ <point x="1011" y="433"/>
+ </contour>
+ <contour>
+ <point x="222" y="302" type="curve" smooth="yes"/>
+ <point x="222" y="328"/>
+ <point x="200" y="348"/>
+ <point x="174" y="348" type="curve" smooth="yes"/>
+ <point x="147" y="348"/>
+ <point x="126" y="326"/>
+ <point x="126" y="302" type="curve" smooth="yes"/>
+ <point x="126" y="275"/>
+ <point x="149" y="253"/>
+ <point x="174" y="253" type="curve" smooth="yes"/>
+ <point x="201" y="253"/>
+ <point x="222" y="277"/>
+ </contour>
+ <contour>
+ <point x="980" y="615" type="curve" smooth="yes"/>
+ <point x="980" y="642"/>
+ <point x="955" y="663"/>
+ <point x="931" y="663" type="curve" smooth="yes"/>
+ <point x="904" y="663"/>
+ <point x="885" y="638"/>
+ <point x="885" y="614" type="curve" smooth="yes"/>
+ <point x="885" y="588"/>
+ <point x="907" y="567"/>
+ <point x="931" y="567" type="curve" smooth="yes"/>
+ <point x="959" y="567"/>
+ <point x="980" y="591"/>
+ </contour>
+ <contour>
+ <point x="310" y="168" type="curve" smooth="yes"/>
+ <point x="310" y="195"/>
+ <point x="291" y="215"/>
+ <point x="263" y="215" type="curve" smooth="yes"/>
+ <point x="238" y="215"/>
+ <point x="215" y="190"/>
+ <point x="215" y="168" type="curve" smooth="yes"/>
+ <point x="215" y="143"/>
+ <point x="238" y="120"/>
+ <point x="263" y="120" type="curve" smooth="yes"/>
+ <point x="289" y="120"/>
+ <point x="310" y="143"/>
+ </contour>
+ <contour>
+ <point x="890" y="748" type="curve" smooth="yes"/>
+ <point x="890" y="774"/>
+ <point x="870" y="796"/>
+ <point x="843" y="796" type="curve" smooth="yes"/>
+ <point x="815" y="796"/>
+ <point x="796" y="773"/>
+ <point x="796" y="748" type="curve" smooth="yes"/>
+ <point x="796" y="724"/>
+ <point x="817" y="700"/>
+ <point x="843" y="700" type="curve" smooth="yes"/>
+ <point x="869" y="700"/>
+ <point x="890" y="722"/>
+ </contour>
+ <contour>
+ <point x="444" y="78" type="curve" smooth="yes"/>
+ <point x="444" y="102"/>
+ <point x="423" y="126"/>
+ <point x="396" y="126" type="curve" smooth="yes"/>
+ <point x="370" y="126"/>
+ <point x="348" y="102"/>
+ <point x="348" y="78" type="curve" smooth="yes"/>
+ <point x="348" y="55"/>
+ <point x="370" y="31"/>
+ <point x="396" y="31" type="curve" smooth="yes"/>
+ <point x="420" y="31"/>
+ <point x="444" y="51"/>
+ </contour>
+ <contour>
+ <point x="758" y="836" type="curve" smooth="yes"/>
+ <point x="758" y="861"/>
+ <point x="737" y="885"/>
+ <point x="710" y="885" type="curve" smooth="yes"/>
+ <point x="684" y="885"/>
+ <point x="663" y="862"/>
+ <point x="663" y="838" type="curve" smooth="yes"/>
+ <point x="663" y="814"/>
+ <point x="683" y="789"/>
+ <point x="710" y="789" type="curve" smooth="yes"/>
+ <point x="734" y="789"/>
+ <point x="758" y="809"/>
+ </contour>
+ <contour>
+ <point x="601" y="47" type="curve" smooth="yes"/>
+ <point x="601" y="73"/>
+ <point x="579" y="95"/>
+ <point x="553" y="95" type="curve" smooth="yes"/>
+ <point x="527" y="95"/>
+ <point x="506" y="73"/>
+ <point x="506" y="47" type="curve" smooth="yes"/>
+ <point x="506" y="21"/>
+ <point x="527" y="0"/>
+ <point x="553" y="0" type="curve" smooth="yes"/>
+ <point x="579" y="0"/>
+ <point x="601" y="21"/>
+ </contour>
+ <contour>
+ <point x="601" y="868" type="curve" smooth="yes"/>
+ <point x="601" y="894"/>
+ <point x="579" y="916"/>
+ <point x="553" y="916" type="curve" smooth="yes"/>
+ <point x="527" y="916"/>
+ <point x="506" y="894"/>
+ <point x="506" y="868" type="curve" smooth="yes"/>
+ <point x="506" y="842"/>
+ <point x="527" y="821"/>
+ <point x="553" y="821" type="curve" smooth="yes"/>
+ <point x="579" y="821"/>
+ <point x="601" y="842"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetpsnames.ufo/glyphs/E_qS_gn.glif b/tests/reference/ufo/psfsetpsnames.ufo/glyphs/E_qS_gn.glif
new file mode 100644
index 0000000..0461eab
--- /dev/null
+++ b/tests/reference/ufo/psfsetpsnames.ufo/glyphs/E_qS_gn.glif
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="EqSgn" format="2">
+ <advance width="1180"/>
+ <unicode hex="003D"/>
+ <outline>
+ <contour>
+ <point x="168" y="436" type="line"/>
+ <point x="1128" y="436" type="line"/>
+ <point x="1180" y="643" type="line"/>
+ <point x="220" y="643" type="line"/>
+ </contour>
+ <contour>
+ <point x="259" y="802" type="line"/>
+ <point x="1219" y="802" type="line"/>
+ <point x="1271" y="1010" type="line"/>
+ <point x="311" y="1010" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetpsnames.ufo/glyphs/E_xclamationM_rk.glif b/tests/reference/ufo/psfsetpsnames.ufo/glyphs/E_xclamationM_rk.glif
new file mode 100644
index 0000000..167f45e
--- /dev/null
+++ b/tests/reference/ufo/psfsetpsnames.ufo/glyphs/E_xclamationM_rk.glif
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="ExclamationMrk" format="2">
+ <advance width="760"/>
+ <unicode hex="0021"/>
+ <outline>
+ <contour>
+ <point x="593" y="495" type="line"/>
+ <point x="670" y="782"/>
+ <point x="736" y="1065"/>
+ <point x="882" y="1495" type="curve"/>
+ <point x="547" y="1495" type="line"/>
+ <point x="478" y="1065"/>
+ <point x="402" y="782"/>
+ <point x="338" y="495" type="curve"/>
+ </contour>
+ <contour>
+ <point x="201" y="116" type="curve" smooth="yes"/>
+ <point x="201" y="35"/>
+ <point x="262" y="-25"/>
+ <point x="348" y="-25" type="curve" smooth="yes"/>
+ <point x="466" y="-25"/>
+ <point x="561" y="71"/>
+ <point x="561" y="181" type="curve" smooth="yes"/>
+ <point x="561" y="261"/>
+ <point x="502" y="322"/>
+ <point x="415" y="322" type="curve" smooth="yes"/>
+ <point x="298" y="322"/>
+ <point x="201" y="226"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetpsnames.ufo/glyphs/F_ullS_top.glif b/tests/reference/ufo/psfsetpsnames.ufo/glyphs/F_ullS_top.glif
new file mode 100644
index 0000000..cfedcd4
--- /dev/null
+++ b/tests/reference/ufo/psfsetpsnames.ufo/glyphs/F_ullS_top.glif
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="FullStop" format="2">
+ <advance width="690"/>
+ <unicode hex="002E"/>
+ <outline>
+ <contour>
+ <point x="171" y="116" type="curve" smooth="yes"/>
+ <point x="171" y="35"/>
+ <point x="232" y="-25"/>
+ <point x="318" y="-25" type="curve" smooth="yes"/>
+ <point x="436" y="-25"/>
+ <point x="531" y="71"/>
+ <point x="531" y="181" type="curve" smooth="yes"/>
+ <point x="531" y="261"/>
+ <point x="472" y="322"/>
+ <point x="385" y="322" type="curve" smooth="yes"/>
+ <point x="268" y="322"/>
+ <point x="171" y="226"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetpsnames.ufo/glyphs/G_T_S_gn.glif b/tests/reference/ufo/psfsetpsnames.ufo/glyphs/G_T_S_gn.glif
new file mode 100644
index 0000000..6dab866
--- /dev/null
+++ b/tests/reference/ufo/psfsetpsnames.ufo/glyphs/G_T_S_gn.glif
@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="GTSgn" format="2">
+ <advance width="1180"/>
+ <unicode hex="003E"/>
+ <outline>
+ <contour>
+ <point x="130" y="243" type="line"/>
+ <point x="1186" y="629" type="line"/>
+ <point x="1233" y="817" type="line"/>
+ <point x="369" y="1203" type="line"/>
+ <point x="313" y="975" type="line"/>
+ <point x="930" y="733" type="line"/>
+ <point x="187" y="470" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetpsnames.ufo/glyphs/G_raveA_ccent.glif b/tests/reference/ufo/psfsetpsnames.ufo/glyphs/G_raveA_ccent.glif
new file mode 100644
index 0000000..f745b6a
--- /dev/null
+++ b/tests/reference/ufo/psfsetpsnames.ufo/glyphs/G_raveA_ccent.glif
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="GraveAccent" format="2">
+ <advance width="620"/>
+ <unicode hex="0060"/>
+ <anchor x="848" y="1635" name="U"/>
+ <outline>
+ <contour>
+ <point x="265" y="1584" type="line"/>
+ <point x="587" y="1188" type="line"/>
+ <point x="817" y="1188" type="line"/>
+ <point x="595" y="1584" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetpsnames.ufo/glyphs/H_yphen.glif b/tests/reference/ufo/psfsetpsnames.ufo/glyphs/H_yphen.glif
new file mode 100644
index 0000000..810f855
--- /dev/null
+++ b/tests/reference/ufo/psfsetpsnames.ufo/glyphs/H_yphen.glif
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="Hyphen" format="2">
+ <advance width="860"/>
+ <unicode hex="2010"/>
+ <anchor x="655" y="1100" name="U"/>
+ <outline>
+ <contour>
+ <point x="139" y="520" type="line"/>
+ <point x="879" y="520" type="line"/>
+ <point x="931" y="728" type="line"/>
+ <point x="191" y="728" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetpsnames.ufo/glyphs/H_yphenM_inus.glif b/tests/reference/ufo/psfsetpsnames.ufo/glyphs/H_yphenM_inus.glif
new file mode 100644
index 0000000..d8ce949
--- /dev/null
+++ b/tests/reference/ufo/psfsetpsnames.ufo/glyphs/H_yphenM_inus.glif
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="HyphenMinus" format="2">
+ <advance width="875"/>
+ <unicode hex="002D"/>
+ <anchor x="665" y="1100" name="U"/>
+ <outline>
+ <contour>
+ <point x="149" y="520" type="line"/>
+ <point x="884" y="520" type="line"/>
+ <point x="936" y="728" type="line"/>
+ <point x="201" y="728" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetpsnames.ufo/glyphs/H_yphen_S_oft.glif b/tests/reference/ufo/psfsetpsnames.ufo/glyphs/H_yphen_S_oft.glif
new file mode 100644
index 0000000..2f651fa
--- /dev/null
+++ b/tests/reference/ufo/psfsetpsnames.ufo/glyphs/H_yphen_S_oft.glif
@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="Hyphen_Soft" format="2">
+ <advance width="875"/>
+ <unicode hex="00AD"/>
+ <anchor x="665" y="1100" name="U"/>
+ <outline>
+ <component base="HyphenMinus"/>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetpsnames.ufo/glyphs/L_T_S_gn.glif b/tests/reference/ufo/psfsetpsnames.ufo/glyphs/L_T_S_gn.glif
new file mode 100644
index 0000000..b2883d3
--- /dev/null
+++ b/tests/reference/ufo/psfsetpsnames.ufo/glyphs/L_T_S_gn.glif
@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LTSgn" format="2">
+ <advance width="1180"/>
+ <unicode hex="003C"/>
+ <outline>
+ <contour>
+ <point x="1127" y="470" type="line"/>
+ <point x="510" y="713" type="line"/>
+ <point x="1253" y="975" type="line"/>
+ <point x="1309" y="1203" type="line"/>
+ <point x="253" y="817" type="line"/>
+ <point x="206" y="629" type="line"/>
+ <point x="1070" y="243" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetpsnames.ufo/glyphs/L_ftC_urlyB_rac.glif b/tests/reference/ufo/psfsetpsnames.ufo/glyphs/L_ftC_urlyB_rac.glif
new file mode 100644
index 0000000..c92f889
--- /dev/null
+++ b/tests/reference/ufo/psfsetpsnames.ufo/glyphs/L_ftC_urlyB_rac.glif
@@ -0,0 +1,50 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LftCurlyBrac" format="2">
+ <advance width="1020"/>
+ <unicode hex="007B"/>
+ <outline>
+ <contour>
+ <point x="790" y="-177" type="line"/>
+ <point x="717" y="-149"/>
+ <point x="597" y="-129"/>
+ <point x="597" y="-79" type="curve" smooth="yes"/>
+ <point x="597" y="16"/>
+ <point x="695" y="378"/>
+ <point x="695" y="435" type="curve" smooth="yes"/>
+ <point x="695" y="476"/>
+ <point x="574" y="568"/>
+ <point x="574" y="605" type="curve" smooth="yes"/>
+ <point x="574" y="644"/>
+ <point x="742" y="733"/>
+ <point x="776" y="777" type="curve" smooth="yes"/>
+ <point x="803" y="812"/>
+ <point x="908" y="1276"/>
+ <point x="953" y="1317" type="curve" smooth="yes"/>
+ <point x="975" y="1337"/>
+ <point x="1090" y="1376"/>
+ <point x="1157" y="1395" type="curve"/>
+ <point x="1165" y="1624" type="line"/>
+ <point x="1031" y="1597"/>
+ <point x="827" y="1546"/>
+ <point x="768" y="1500" type="curve" smooth="yes"/>
+ <point x="677" y="1428"/>
+ <point x="542" y="843"/>
+ <point x="512" y="812" type="curve" smooth="yes"/>
+ <point x="472" y="770"/>
+ <point x="260" y="659"/>
+ <point x="260" y="601" type="curve" smooth="yes"/>
+ <point x="260" y="540"/>
+ <point x="412" y="434"/>
+ <point x="412" y="399" type="curve" smooth="yes"/>
+ <point x="412" y="337"/>
+ <point x="311" y="-52"/>
+ <point x="311" y="-216" type="curve" smooth="yes"/>
+ <point x="311" y="-248"/>
+ <point x="315" y="-271"/>
+ <point x="324" y="-282" type="curve" smooth="yes"/>
+ <point x="362" y="-330"/>
+ <point x="554" y="-379"/>
+ <point x="683" y="-406" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetpsnames.ufo/glyphs/L_ftP_aren.glif b/tests/reference/ufo/psfsetpsnames.ufo/glyphs/L_ftP_aren.glif
new file mode 100644
index 0000000..42e4531
--- /dev/null
+++ b/tests/reference/ufo/psfsetpsnames.ufo/glyphs/L_ftP_aren.glif
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LftParen" format="2">
+ <advance width="840"/>
+ <unicode hex="0028"/>
+ <outline>
+ <contour>
+ <point x="899" y="1624" type="line"/>
+ <point x="586" y="1430"/>
+ <point x="317" y="1081"/>
+ <point x="209" y="649" type="curve" smooth="yes"/>
+ <point x="177" y="521"/>
+ <point x="161" y="397"/>
+ <point x="161" y="277" type="curve" smooth="yes"/>
+ <point x="161" y="20"/>
+ <point x="234" y="-214"/>
+ <point x="373" y="-406" type="curve"/>
+ <point x="565" y="-198" type="line"/>
+ <point x="479" y="-42"/>
+ <point x="436" y="130"/>
+ <point x="436" y="315" type="curve" smooth="yes"/>
+ <point x="436" y="422"/>
+ <point x="450" y="534"/>
+ <point x="479" y="649" type="curve" smooth="yes"/>
+ <point x="559" y="972"/>
+ <point x="715" y="1216"/>
+ <point x="966" y="1411" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetpsnames.ufo/glyphs/L_ftS_qrB_rac.glif b/tests/reference/ufo/psfsetpsnames.ufo/glyphs/L_ftS_qrB_rac.glif
new file mode 100644
index 0000000..db76a2d
--- /dev/null
+++ b/tests/reference/ufo/psfsetpsnames.ufo/glyphs/L_ftS_qrB_rac.glif
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LftSqrBrac" format="2">
+ <advance width="830"/>
+ <unicode hex="005B"/>
+ <outline>
+ <contour>
+ <point x="553" y="-406" type="line"/>
+ <point x="605" y="-198" type="line"/>
+ <point x="365" y="-198" type="line"/>
+ <point x="753" y="1376" type="line"/>
+ <point x="993" y="1376" type="line"/>
+ <point x="1044" y="1584" type="line"/>
+ <point x="524" y="1584" type="line"/>
+ <point x="33" y="-406" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetpsnames.ufo/glyphs/L_owL_ine.glif b/tests/reference/ufo/psfsetpsnames.ufo/glyphs/L_owL_ine.glif
new file mode 100644
index 0000000..de8a991
--- /dev/null
+++ b/tests/reference/ufo/psfsetpsnames.ufo/glyphs/L_owL_ine.glif
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LowLine" format="2">
+ <advance width="1254"/>
+ <unicode hex="005F"/>
+ <outline>
+ <contour>
+ <point x="-146" y="-347" type="line"/>
+ <point x="1127" y="-347" type="line"/>
+ <point x="1179" y="-139" type="line"/>
+ <point x="-94" y="-139" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetpsnames.ufo/glyphs/L_tnC_apA_.glif b/tests/reference/ufo/psfsetpsnames.ufo/glyphs/L_tnC_apA_.glif
new file mode 100644
index 0000000..592502c
--- /dev/null
+++ b/tests/reference/ufo/psfsetpsnames.ufo/glyphs/L_tnC_apA_.glif
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnCapA" format="2">
+ <advance width="1465"/>
+ <unicode hex="0041"/>
+ <anchor x="1215" y="0" name="H"/>
+ <anchor x="647" y="-100" name="L"/>
+ <anchor x="1435" y="0" name="O"/>
+ <anchor x="1054" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="1055" y="0" type="line"/>
+ <point x="1338" y="0" type="line"/>
+ <point x="1322" y="79"/>
+ <point x="1312" y="166"/>
+ <point x="1295" y="351" type="curve" smooth="yes"/>
+ <point x="1198" y="1445" type="line"/>
+ <point x="842" y="1445" type="line"/>
+ <point x="199" y="351" type="line" smooth="yes"/>
+ <point x="89" y="164"/>
+ <point x="37" y="80"/>
+ <point x="-18" y="0" type="curve"/>
+ <point x="290" y="0" type="line"/>
+ <point x="487" y="351" type="line"/>
+ <point x="1031" y="351" type="line"/>
+ </contour>
+ <contour>
+ <point x="973" y="1216" type="line"/>
+ <point x="1016" y="564" type="line"/>
+ <point x="606" y="564" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetpsnames.ufo/glyphs/L_tnC_apA_D_iaer.glif b/tests/reference/ufo/psfsetpsnames.ufo/glyphs/L_tnC_apA_D_iaer.glif
new file mode 100644
index 0000000..17600b4
--- /dev/null
+++ b/tests/reference/ufo/psfsetpsnames.ufo/glyphs/L_tnC_apA_D_iaer.glif
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnCapADiaer" format="2">
+ <advance width="1465"/>
+ <unicode hex="00C4"/>
+ <anchor x="1215" y="0" name="H"/>
+ <anchor x="647" y="-100" name="L"/>
+ <anchor x="1435" y="0" name="O"/>
+ <anchor x="1176" y="2015" name="U"/>
+ <outline>
+ <component base="LtnCapA"/>
+ <component base="CombDiaer" xOffset="1419" yOffset="430"/>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetpsnames.ufo/glyphs/L_tnC_apB_.glif b/tests/reference/ufo/psfsetpsnames.ufo/glyphs/L_tnC_apB_.glif
new file mode 100644
index 0000000..2b14150
--- /dev/null
+++ b/tests/reference/ufo/psfsetpsnames.ufo/glyphs/L_tnC_apB_.glif
@@ -0,0 +1,62 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnCapB" format="2">
+ <advance width="1367"/>
+ <unicode hex="0042"/>
+ <anchor x="585" y="-100" name="L"/>
+ <anchor x="992" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="698" y="1236" type="line"/>
+ <point x="735" y="1237"/>
+ <point x="791" y="1240"/>
+ <point x="860" y="1240" type="curve" smooth="yes"/>
+ <point x="1021" y="1240"/>
+ <point x="1101" y="1179"/>
+ <point x="1101" y="1087" type="curve" smooth="yes"/>
+ <point x="1101" y="932"/>
+ <point x="962" y="866"/>
+ <point x="770" y="866" type="curve" smooth="yes"/>
+ <point x="605" y="866" type="line"/>
+ </contour>
+ <contour>
+ <point x="217" y="450" type="line"/>
+ <point x="168" y="254"/>
+ <point x="124" y="79"/>
+ <point x="90" y="0" type="curve"/>
+ <point x="161" y="-3"/>
+ <point x="368" y="-10"/>
+ <point x="598" y="-10" type="curve" smooth="yes"/>
+ <point x="1055" y="-10"/>
+ <point x="1298" y="206"/>
+ <point x="1298" y="508" type="curve" smooth="yes"/>
+ <point x="1298" y="673"/>
+ <point x="1188" y="759"/>
+ <point x="1072" y="792" type="curve"/>
+ <point x="1254" y="848"/>
+ <point x="1388" y="956"/>
+ <point x="1388" y="1155" type="curve" smooth="yes"/>
+ <point x="1388" y="1359"/>
+ <point x="1181" y="1455"/>
+ <point x="897" y="1455" type="curve" smooth="yes"/>
+ <point x="704" y="1455"/>
+ <point x="549" y="1451"/>
+ <point x="450" y="1445" type="curve"/>
+ <point x="445" y="1366"/>
+ <point x="399" y="1182"/>
+ <point x="351" y="990" type="curve" smooth="yes"/>
+ </contour>
+ <contour>
+ <point x="552" y="651" type="line"/>
+ <point x="745" y="651" type="line" smooth="yes"/>
+ <point x="927" y="651"/>
+ <point x="1019" y="577"/>
+ <point x="1019" y="468" type="curve" smooth="yes"/>
+ <point x="1019" y="295"/>
+ <point x="879" y="213"/>
+ <point x="675" y="213" type="curve" smooth="yes"/>
+ <point x="575" y="213"/>
+ <point x="476" y="216"/>
+ <point x="444" y="218" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetpsnames.ufo/glyphs/L_tnC_apC_.glif b/tests/reference/ufo/psfsetpsnames.ufo/glyphs/L_tnC_apC_.glif
new file mode 100644
index 0000000..569eba9
--- /dev/null
+++ b/tests/reference/ufo/psfsetpsnames.ufo/glyphs/L_tnC_apC_.glif
@@ -0,0 +1,38 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnCapC" format="2">
+ <advance width="1357"/>
+ <unicode hex="0043"/>
+ <anchor x="685" y="0" name="H"/>
+ <anchor x="660" y="-100" name="L"/>
+ <anchor x="1067" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="1286" y="391" type="line"/>
+ <point x="1149" y="280"/>
+ <point x="966" y="218"/>
+ <point x="816" y="218" type="curve" smooth="yes"/>
+ <point x="594" y="218"/>
+ <point x="472" y="349"/>
+ <point x="472" y="588" type="curve" smooth="yes"/>
+ <point x="472" y="922"/>
+ <point x="690" y="1230"/>
+ <point x="1039" y="1230" type="curve" smooth="yes"/>
+ <point x="1170" y="1230"/>
+ <point x="1298" y="1188"/>
+ <point x="1385" y="1093" type="curve"/>
+ <point x="1515" y="1331" type="line"/>
+ <point x="1408" y="1418"/>
+ <point x="1247" y="1470"/>
+ <point x="1073" y="1470" type="curve" smooth="yes"/>
+ <point x="545" y="1470"/>
+ <point x="191" y="1032"/>
+ <point x="191" y="544" type="curve" smooth="yes"/>
+ <point x="191" y="210"/>
+ <point x="404" y="-25"/>
+ <point x="750" y="-25" type="curve" smooth="yes"/>
+ <point x="921" y="-25"/>
+ <point x="1124" y="27"/>
+ <point x="1271" y="124" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetpsnames.ufo/glyphs/L_tnC_apD_.glif b/tests/reference/ufo/psfsetpsnames.ufo/glyphs/L_tnC_apD_.glif
new file mode 100644
index 0000000..093d346
--- /dev/null
+++ b/tests/reference/ufo/psfsetpsnames.ufo/glyphs/L_tnC_apD_.glif
@@ -0,0 +1,51 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnCapD" format="2">
+ <advance width="1465"/>
+ <unicode hex="0044"/>
+ <anchor x="690" y="-100" name="L"/>
+ <anchor x="1122" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="217" y="450" type="line" smooth="yes"/>
+ <point x="167" y="251"/>
+ <point x="124" y="79"/>
+ <point x="90" y="0" type="curve"/>
+ <point x="90" y="0"/>
+ <point x="431" y="-10"/>
+ <point x="566" y="-10" type="curve" smooth="yes"/>
+ <point x="1036" y="-10"/>
+ <point x="1361" y="195"/>
+ <point x="1471" y="648" type="curve" smooth="yes"/>
+ <point x="1494" y="742"/>
+ <point x="1505" y="827"/>
+ <point x="1505" y="902" type="curve" smooth="yes"/>
+ <point x="1505" y="1325"/>
+ <point x="1172" y="1455"/>
+ <point x="912" y="1455" type="curve" smooth="yes"/>
+ <point x="769" y="1455"/>
+ <point x="540" y="1451"/>
+ <point x="450" y="1445" type="curve"/>
+ <point x="445" y="1371"/>
+ <point x="404" y="1205"/>
+ <point x="359" y="1024" type="curve" smooth="yes"/>
+ </contour>
+ <contour>
+ <point x="696" y="1229" type="line"/>
+ <point x="738" y="1231"/>
+ <point x="809" y="1234"/>
+ <point x="864" y="1234" type="curve" smooth="yes"/>
+ <point x="1077" y="1234"/>
+ <point x="1212" y="1104"/>
+ <point x="1212" y="871" type="curve" smooth="yes"/>
+ <point x="1212" y="805"/>
+ <point x="1201" y="731"/>
+ <point x="1181" y="647" type="curve" smooth="yes"/>
+ <point x="1108" y="346"/>
+ <point x="930" y="219"/>
+ <point x="647" y="219" type="curve" smooth="yes"/>
+ <point x="568" y="219"/>
+ <point x="485" y="225"/>
+ <point x="447" y="229" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetpsnames.ufo/glyphs/L_tnC_apE_.glif b/tests/reference/ufo/psfsetpsnames.ufo/glyphs/L_tnC_apE_.glif
new file mode 100644
index 0000000..8e7a0a1
--- /dev/null
+++ b/tests/reference/ufo/psfsetpsnames.ufo/glyphs/L_tnC_apE_.glif
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnCapE" format="2">
+ <advance width="1192"/>
+ <unicode hex="0045"/>
+ <anchor x="550" y="0" name="H"/>
+ <anchor x="525" y="-100" name="L"/>
+ <anchor x="944" y="0" name="O"/>
+ <anchor x="1487" y="1200" name="R"/>
+ <anchor x="932" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="605" y="866" type="line"/>
+ <point x="693" y="1217" type="line"/>
+ <point x="1315" y="1217" type="line"/>
+ <point x="1372" y="1445" type="line"/>
+ <point x="450" y="1445" type="line"/>
+ <point x="444" y="1366"/>
+ <point x="406" y="1210"/>
+ <point x="358" y="1015" type="curve" smooth="yes"/>
+ <point x="212" y="431" type="line" smooth="yes"/>
+ <point x="163" y="236"/>
+ <point x="123" y="79"/>
+ <point x="90" y="0" type="curve"/>
+ <point x="1042" y="0" type="line"/>
+ <point x="1102" y="243" type="line"/>
+ <point x="1021" y="229"/>
+ <point x="895" y="228"/>
+ <point x="704" y="228" type="curve" smooth="yes"/>
+ <point x="446" y="228" type="line"/>
+ <point x="550" y="644" type="line"/>
+ <point x="1097" y="644" type="line"/>
+ <point x="1152" y="866" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetpsnames.ufo/glyphs/L_tnC_apF_.glif b/tests/reference/ufo/psfsetpsnames.ufo/glyphs/L_tnC_apF_.glif
new file mode 100644
index 0000000..df3370c
--- /dev/null
+++ b/tests/reference/ufo/psfsetpsnames.ufo/glyphs/L_tnC_apF_.glif
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnCapF" format="2">
+ <advance width="1180"/>
+ <unicode hex="0046"/>
+ <anchor x="545" y="-100" name="L"/>
+ <anchor x="952" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="602" y="851" type="line"/>
+ <point x="693" y="1217" type="line"/>
+ <point x="1333" y="1217" type="line"/>
+ <point x="1390" y="1445" type="line"/>
+ <point x="450" y="1445" type="line"/>
+ <point x="445" y="1366"/>
+ <point x="405" y="1205"/>
+ <point x="356" y="1010" type="curve" smooth="yes"/>
+ <point x="212" y="431" type="line" smooth="yes"/>
+ <point x="163" y="236"/>
+ <point x="123" y="79"/>
+ <point x="90" y="0" type="curve"/>
+ <point x="405" y="0" type="line"/>
+ <point x="407" y="72"/>
+ <point x="444" y="220"/>
+ <point x="490" y="404" type="curve" smooth="yes"/>
+ <point x="546" y="629" type="line"/>
+ <point x="1101" y="629" type="line"/>
+ <point x="1157" y="851" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetpsnames.ufo/glyphs/L_tnC_apG_.glif b/tests/reference/ufo/psfsetpsnames.ufo/glyphs/L_tnC_apG_.glif
new file mode 100644
index 0000000..7d36953
--- /dev/null
+++ b/tests/reference/ufo/psfsetpsnames.ufo/glyphs/L_tnC_apG_.glif
@@ -0,0 +1,48 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnCapG" format="2">
+ <advance width="1452"/>
+ <unicode hex="0047"/>
+ <anchor x="747" y="0" name="H"/>
+ <anchor x="722" y="-100" name="L"/>
+ <anchor x="1129" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="1480" y="767" type="line"/>
+ <point x="910" y="767" type="line"/>
+ <point x="855" y="544" type="line"/>
+ <point x="1170" y="544" type="line"/>
+ <point x="1104" y="271" type="line"/>
+ <point x="1015" y="231"/>
+ <point x="916" y="218"/>
+ <point x="805" y="218" type="curve" smooth="yes"/>
+ <point x="593" y="218"/>
+ <point x="475" y="352"/>
+ <point x="475" y="567" type="curve" smooth="yes"/>
+ <point x="475" y="633"/>
+ <point x="484" y="708"/>
+ <point x="505" y="789" type="curve" smooth="yes"/>
+ <point x="581" y="1079"/>
+ <point x="802" y="1230"/>
+ <point x="1067" y="1230" type="curve" smooth="yes"/>
+ <point x="1220" y="1230"/>
+ <point x="1334" y="1193"/>
+ <point x="1449" y="1096" type="curve"/>
+ <point x="1594" y="1332" type="line"/>
+ <point x="1447" y="1437"/>
+ <point x="1275" y="1470"/>
+ <point x="1094" y="1470" type="curve" smooth="yes"/>
+ <point x="709" y="1470"/>
+ <point x="345" y="1257"/>
+ <point x="227" y="783" type="curve" smooth="yes"/>
+ <point x="205" y="694"/>
+ <point x="194" y="611"/>
+ <point x="194" y="534" type="curve" smooth="yes"/>
+ <point x="194" y="176"/>
+ <point x="419" y="-25"/>
+ <point x="768" y="-25" type="curve" smooth="yes"/>
+ <point x="940" y="-25"/>
+ <point x="1105" y="10"/>
+ <point x="1325" y="133" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetpsnames.ufo/glyphs/L_tnC_apH_.glif b/tests/reference/ufo/psfsetpsnames.ufo/glyphs/L_tnC_apH_.glif
new file mode 100644
index 0000000..a49f5fb
--- /dev/null
+++ b/tests/reference/ufo/psfsetpsnames.ufo/glyphs/L_tnC_apH_.glif
@@ -0,0 +1,40 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnCapH" format="2">
+ <advance width="1495"/>
+ <unicode hex="0048"/>
+ <anchor x="245" y="0" name="H"/>
+ <anchor x="660" y="-100" name="L"/>
+ <anchor x="1067" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="1340" y="1445" type="line"/>
+ <point x="1192" y="851" type="line"/>
+ <point x="602" y="851" type="line"/>
+ <point x="750" y="1445" type="line"/>
+ <point x="450" y="1445" type="line"/>
+ <point x="445" y="1366"/>
+ <point x="408" y="1215"/>
+ <point x="359" y="1020" type="curve" smooth="yes"/>
+ <point x="211" y="426" type="line" smooth="yes"/>
+ <point x="162" y="231"/>
+ <point x="124" y="79"/>
+ <point x="90" y="0" type="curve"/>
+ <point x="90" y="0"/>
+ <point x="390" y="0"/>
+ <point x="390" y="0" type="curve"/>
+ <point x="546" y="629" type="line"/>
+ <point x="1136" y="629" type="line"/>
+ <point x="980" y="0" type="line"/>
+ <point x="980" y="0"/>
+ <point x="1280" y="0"/>
+ <point x="1280" y="0" type="curve"/>
+ <point x="1284" y="79"/>
+ <point x="1322" y="231"/>
+ <point x="1371" y="426" type="curve" smooth="yes"/>
+ <point x="1519" y="1020" type="line" smooth="yes"/>
+ <point x="1567" y="1215"/>
+ <point x="1605" y="1366"/>
+ <point x="1640" y="1445" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetpsnames.ufo/glyphs/L_tnC_apI_.glif b/tests/reference/ufo/psfsetpsnames.ufo/glyphs/L_tnC_apI_.glif
new file mode 100644
index 0000000..fc059de
--- /dev/null
+++ b/tests/reference/ufo/psfsetpsnames.ufo/glyphs/L_tnC_apI_.glif
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnCapI" format="2">
+ <advance width="1025"/>
+ <unicode hex="0049"/>
+ <anchor x="460" y="0" name="H"/>
+ <anchor x="431" y="-100" name="L"/>
+ <anchor x="652" y="0" name="O"/>
+ <anchor x="1254" y="1200" name="R"/>
+ <anchor x="842" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="430" y="1445" type="line"/>
+ <point x="379" y="1242" type="line"/>
+ <point x="619" y="1242" type="line"/>
+ <point x="360" y="203" type="line"/>
+ <point x="120" y="203" type="line"/>
+ <point x="70" y="0" type="line"/>
+ <point x="835" y="0" type="line"/>
+ <point x="885" y="203" type="line"/>
+ <point x="645" y="203" type="line"/>
+ <point x="904" y="1242" type="line"/>
+ <point x="1144" y="1242" type="line"/>
+ <point x="1195" y="1445" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetpsnames.ufo/glyphs/L_tnC_apJ_.glif b/tests/reference/ufo/psfsetpsnames.ufo/glyphs/L_tnC_apJ_.glif
new file mode 100644
index 0000000..6a3a604
--- /dev/null
+++ b/tests/reference/ufo/psfsetpsnames.ufo/glyphs/L_tnC_apJ_.glif
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnCapJ" format="2">
+ <advance width="1010"/>
+ <unicode hex="004A"/>
+ <anchor x="330" y="-100" name="L"/>
+ <anchor x="1027" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="855" y="1445" type="line"/>
+ <point x="842" y="1340"/>
+ <point x="799" y="1163"/>
+ <point x="751" y="970" type="curve" smooth="yes"/>
+ <point x="647" y="552" type="line" smooth="yes"/>
+ <point x="602" y="370"/>
+ <point x="516" y="225"/>
+ <point x="341" y="225" type="curve" smooth="yes"/>
+ <point x="260" y="225"/>
+ <point x="159" y="267"/>
+ <point x="104" y="344" type="curve"/>
+ <point x="-8" y="89" type="line"/>
+ <point x="51" y="19"/>
+ <point x="191" y="-25"/>
+ <point x="326" y="-25" type="curve" smooth="yes"/>
+ <point x="611" y="-25"/>
+ <point x="826" y="128"/>
+ <point x="927" y="530" type="curve" smooth="yes"/>
+ <point x="947" y="612"/>
+ <point x="1155" y="1445"/>
+ <point x="1155" y="1445" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetpsnames.ufo/glyphs/L_tnC_apK_.glif b/tests/reference/ufo/psfsetpsnames.ufo/glyphs/L_tnC_apK_.glif
new file mode 100644
index 0000000..44d4d68
--- /dev/null
+++ b/tests/reference/ufo/psfsetpsnames.ufo/glyphs/L_tnC_apK_.glif
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnCapK" format="2">
+ <advance width="1410"/>
+ <unicode hex="004B"/>
+ <anchor x="260" y="0" name="H"/>
+ <anchor x="655" y="-100" name="L"/>
+ <anchor x="1047" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="750" y="1445" type="line"/>
+ <point x="450" y="1445" type="line"/>
+ <point x="444" y="1366"/>
+ <point x="406" y="1210"/>
+ <point x="358" y="1015" type="curve" smooth="yes"/>
+ <point x="212" y="431" type="line" smooth="yes"/>
+ <point x="163" y="236"/>
+ <point x="123" y="79"/>
+ <point x="90" y="0" type="curve"/>
+ <point x="390" y="0" type="line"/>
+ </contour>
+ <contour>
+ <point x="1244" y="1445" type="line"/>
+ <point x="461" y="697" type="line"/>
+ <point x="634" y="738" type="line"/>
+ <point x="758" y="724" type="line"/>
+ <point x="1580" y="1445" type="line"/>
+ </contour>
+ <contour>
+ <point x="509" y="724" type="line"/>
+ <point x="950" y="0" type="line"/>
+ <point x="1300" y="0" type="line"/>
+ <point x="738" y="801" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetpsnames.ufo/glyphs/L_tnC_apL_.glif b/tests/reference/ufo/psfsetpsnames.ufo/glyphs/L_tnC_apL_.glif
new file mode 100644
index 0000000..f8d6959
--- /dev/null
+++ b/tests/reference/ufo/psfsetpsnames.ufo/glyphs/L_tnC_apL_.glif
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnCapL" format="2">
+ <advance width="1110"/>
+ <unicode hex="004C"/>
+ <anchor x="560" y="0" name="H"/>
+ <anchor x="535" y="-100" name="L"/>
+ <anchor x="890" y="1200" name="R"/>
+ <anchor x="942" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="446" y="228" type="line"/>
+ <point x="750" y="1445" type="line"/>
+ <point x="450" y="1445" type="line"/>
+ <point x="444" y="1366"/>
+ <point x="406" y="1210"/>
+ <point x="358" y="1015" type="curve" smooth="yes"/>
+ <point x="212" y="431" type="line" smooth="yes"/>
+ <point x="163" y="236"/>
+ <point x="123" y="79"/>
+ <point x="90" y="0" type="curve"/>
+ <point x="1025" y="0" type="line"/>
+ <point x="1085" y="243" type="line"/>
+ <point x="1005" y="229"/>
+ <point x="851" y="228"/>
+ <point x="662" y="228" type="curve" smooth="yes"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetpsnames.ufo/glyphs/L_tnC_apM_.glif b/tests/reference/ufo/psfsetpsnames.ufo/glyphs/L_tnC_apM_.glif
new file mode 100644
index 0000000..67d1463
--- /dev/null
+++ b/tests/reference/ufo/psfsetpsnames.ufo/glyphs/L_tnC_apM_.glif
@@ -0,0 +1,38 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnCapM" format="2">
+ <advance width="1835"/>
+ <unicode hex="004D"/>
+ <anchor x="830" y="-100" name="L"/>
+ <anchor x="1237" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="919" y="272" type="line"/>
+ <point x="865" y="1445" type="line"/>
+ <point x="615" y="1445" type="line"/>
+ <point x="664" y="1158" type="line"/>
+ <point x="710" y="0" type="line"/>
+ <point x="1005" y="0" type="line"/>
+ <point x="1625" y="1158" type="line"/>
+ <point x="1817" y="1445" type="line"/>
+ <point x="1550" y="1445" type="line"/>
+ </contour>
+ <contour>
+ <point x="520" y="1445" type="line"/>
+ <point x="520" y="1445"/>
+ <point x="164" y="196"/>
+ <point x="90" y="0" type="curve"/>
+ <point x="360" y="0" type="line"/>
+ <point x="686" y="1193" type="line"/>
+ <point x="785" y="1445" type="line"/>
+ </contour>
+ <contour>
+ <point x="1630" y="0" type="line"/>
+ <point x="1649" y="196"/>
+ <point x="1910" y="1445"/>
+ <point x="1910" y="1445" type="curve"/>
+ <point x="1640" y="1445" type="line"/>
+ <point x="1622" y="1193" type="line"/>
+ <point x="1360" y="0" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetpsnames.ufo/glyphs/L_tnC_apN_.glif b/tests/reference/ufo/psfsetpsnames.ufo/glyphs/L_tnC_apN_.glif
new file mode 100644
index 0000000..838490a
--- /dev/null
+++ b/tests/reference/ufo/psfsetpsnames.ufo/glyphs/L_tnC_apN_.glif
@@ -0,0 +1,37 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnCapN" format="2">
+ <advance width="1525"/>
+ <unicode hex="004E"/>
+ <anchor x="1180" y="0" name="H"/>
+ <anchor x="680" y="-100" name="L"/>
+ <anchor x="1087" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="506" y="1297" type="line"/>
+ <point x="1035" y="0" type="line"/>
+ <point x="1253" y="148" type="line"/>
+ <point x="725" y="1445" type="line"/>
+ </contour>
+ <contour>
+ <point x="1035" y="0" type="line"/>
+ <point x="1305" y="0" type="line"/>
+ <point x="1558" y="1015" type="line" smooth="yes"/>
+ <point x="1606" y="1210"/>
+ <point x="1646" y="1366"/>
+ <point x="1680" y="1445" type="curve"/>
+ <point x="1395" y="1445" type="line"/>
+ </contour>
+ <contour>
+ <point x="725" y="1445" type="line"/>
+ <point x="440" y="1445" type="line"/>
+ <point x="434" y="1366"/>
+ <point x="396" y="1210"/>
+ <point x="348" y="1015" type="curve" smooth="yes"/>
+ <point x="202" y="431" type="line" smooth="yes"/>
+ <point x="153" y="236"/>
+ <point x="113" y="79"/>
+ <point x="80" y="0" type="curve"/>
+ <point x="365" y="0" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetpsnames.ufo/glyphs/L_tnC_apO_.glif b/tests/reference/ufo/psfsetpsnames.ufo/glyphs/L_tnC_apO_.glif
new file mode 100644
index 0000000..4410e20
--- /dev/null
+++ b/tests/reference/ufo/psfsetpsnames.ufo/glyphs/L_tnC_apO_.glif
@@ -0,0 +1,40 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnCapO" format="2">
+ <advance width="1480"/>
+ <unicode hex="004F"/>
+ <anchor x="680" y="0" name="H"/>
+ <anchor x="655" y="-100" name="L"/>
+ <anchor x="916" y="0" name="O"/>
+ <anchor x="1720" y="1200" name="R"/>
+ <anchor x="1062" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="754" y="218" type="curve" smooth="yes"/>
+ <point x="580" y="218"/>
+ <point x="471" y="345"/>
+ <point x="471" y="568" type="curve" smooth="yes"/>
+ <point x="471" y="922"/>
+ <point x="664" y="1228"/>
+ <point x="966" y="1228" type="curve" smooth="yes"/>
+ <point x="1134" y="1228"/>
+ <point x="1237" y="1106"/>
+ <point x="1237" y="891" type="curve" smooth="yes"/>
+ <point x="1237" y="540"/>
+ <point x="1060" y="218"/>
+ </contour>
+ <contour>
+ <point x="1519" y="911" type="curve" smooth="yes"/>
+ <point x="1519" y="1249"/>
+ <point x="1350" y="1470"/>
+ <point x="1026" y="1470" type="curve" smooth="yes"/>
+ <point x="510" y="1470"/>
+ <point x="191" y="1010"/>
+ <point x="191" y="539" type="curve" smooth="yes"/>
+ <point x="191" y="199"/>
+ <point x="401" y="-25"/>
+ <point x="693" y="-25" type="curve" smooth="yes"/>
+ <point x="1121" y="-25"/>
+ <point x="1519" y="337"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetpsnames.ufo/glyphs/L_tnC_apP_.glif b/tests/reference/ufo/psfsetpsnames.ufo/glyphs/L_tnC_apP_.glif
new file mode 100644
index 0000000..b0d40c0
--- /dev/null
+++ b/tests/reference/ufo/psfsetpsnames.ufo/glyphs/L_tnC_apP_.glif
@@ -0,0 +1,50 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnCapP" format="2">
+ <advance width="1255"/>
+ <unicode hex="0050"/>
+ <anchor x="600" y="-100" name="L"/>
+ <anchor x="970" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="519" y="518" type="line"/>
+ <point x="582" y="511"/>
+ <point x="661" y="508"/>
+ <point x="734" y="508" type="curve" smooth="yes"/>
+ <point x="1118" y="508"/>
+ <point x="1393" y="718"/>
+ <point x="1393" y="1076" type="curve" smooth="yes"/>
+ <point x="1393" y="1306"/>
+ <point x="1215" y="1455"/>
+ <point x="940" y="1455" type="curve" smooth="yes"/>
+ <point x="727" y="1455"/>
+ <point x="450" y="1445"/>
+ <point x="450" y="1445" type="curve"/>
+ <point x="445" y="1366"/>
+ <point x="400" y="1184"/>
+ <point x="351" y="990" type="curve" smooth="yes"/>
+ <point x="212" y="431" type="line" smooth="yes"/>
+ <point x="164" y="237"/>
+ <point x="124" y="79"/>
+ <point x="90" y="0" type="curve"/>
+ <point x="405" y="0" type="line"/>
+ <point x="410" y="77"/>
+ <point x="448" y="235"/>
+ <point x="497" y="431" type="curve" smooth="yes"/>
+ </contour>
+ <contour>
+ <point x="696" y="1228" type="line"/>
+ <point x="752" y="1231"/>
+ <point x="781" y="1233"/>
+ <point x="849" y="1233" type="curve" smooth="yes"/>
+ <point x="1020" y="1233"/>
+ <point x="1103" y="1135"/>
+ <point x="1103" y="1020" type="curve" smooth="yes"/>
+ <point x="1103" y="827"/>
+ <point x="965" y="723"/>
+ <point x="758" y="723" type="curve" smooth="yes"/>
+ <point x="696" y="723"/>
+ <point x="614" y="726"/>
+ <point x="572" y="733" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetpsnames.ufo/glyphs/L_tnC_apQ_.glif b/tests/reference/ufo/psfsetpsnames.ufo/glyphs/L_tnC_apQ_.glif
new file mode 100644
index 0000000..7013e5f
--- /dev/null
+++ b/tests/reference/ufo/psfsetpsnames.ufo/glyphs/L_tnC_apQ_.glif
@@ -0,0 +1,52 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnCapQ" format="2">
+ <advance width="1488"/>
+ <unicode hex="0051"/>
+ <anchor x="619" y="-270" name="L"/>
+ <anchor x="1069" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="1527" y="922" type="curve" smooth="yes"/>
+ <point x="1527" y="1259"/>
+ <point x="1324" y="1470"/>
+ <point x="1029" y="1470" type="curve" smooth="yes"/>
+ <point x="663" y="1470"/>
+ <point x="339" y="1229"/>
+ <point x="221" y="755" type="curve" smooth="yes"/>
+ <point x="201" y="673"/>
+ <point x="191" y="597"/>
+ <point x="191" y="526" type="curve" smooth="yes"/>
+ <point x="191" y="185"/>
+ <point x="410" y="-25"/>
+ <point x="696" y="-25" type="curve" smooth="yes"/>
+ <point x="743" y="-25"/>
+ <point x="787" y="-23"/>
+ <point x="838" y="-15" type="curve"/>
+ <point x="907" y="-15"/>
+ <point x="1162" y="-221"/>
+ <point x="1246" y="-221" type="curve" smooth="yes"/>
+ <point x="1310" y="-221"/>
+ <point x="1422" y="-74"/>
+ <point x="1468" y="-22" type="curve"/>
+ <point x="1331" y="-6"/>
+ <point x="1227" y="60"/>
+ <point x="1115" y="134" type="curve"/>
+ <point x="1312" y="242"/>
+ <point x="1527" y="566"/>
+ </contour>
+ <contour>
+ <point x="757" y="218" type="curve" smooth="yes"/>
+ <point x="563" y="218"/>
+ <point x="471" y="355"/>
+ <point x="471" y="558" type="curve" smooth="yes"/>
+ <point x="471" y="912"/>
+ <point x="677" y="1228"/>
+ <point x="969" y="1228" type="curve" smooth="yes"/>
+ <point x="1147" y="1228"/>
+ <point x="1246" y="1106"/>
+ <point x="1246" y="891" type="curve" smooth="yes"/>
+ <point x="1246" y="560"/>
+ <point x="1053" y="218"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetpsnames.ufo/glyphs/L_tnC_apR_.glif b/tests/reference/ufo/psfsetpsnames.ufo/glyphs/L_tnC_apR_.glif
new file mode 100644
index 0000000..9133fd2
--- /dev/null
+++ b/tests/reference/ufo/psfsetpsnames.ufo/glyphs/L_tnC_apR_.glif
@@ -0,0 +1,55 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnCapR" format="2">
+ <advance width="1360"/>
+ <unicode hex="0052"/>
+ <anchor x="630" y="0" name="H"/>
+ <anchor x="605" y="-100" name="L"/>
+ <anchor x="982" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="534" y="579" type="line"/>
+ <point x="749" y="579" type="line" smooth="yes"/>
+ <point x="1071" y="579"/>
+ <point x="1378" y="761"/>
+ <point x="1378" y="1117" type="curve" smooth="yes"/>
+ <point x="1378" y="1332"/>
+ <point x="1199" y="1455"/>
+ <point x="932" y="1455" type="curve" smooth="yes"/>
+ <point x="698" y="1455"/>
+ <point x="450" y="1445"/>
+ <point x="450" y="1445" type="curve"/>
+ <point x="445" y="1366"/>
+ <point x="400" y="1184"/>
+ <point x="351" y="990" type="curve" smooth="yes"/>
+ <point x="212" y="431" type="line"/>
+ <point x="164" y="236"/>
+ <point x="124" y="79"/>
+ <point x="90" y="0" type="curve"/>
+ <point x="405" y="0" type="line"/>
+ <point x="410" y="77"/>
+ <point x="448" y="236"/>
+ <point x="497" y="431" type="curve"/>
+ </contour>
+ <contour>
+ <point x="696" y="1228" type="line"/>
+ <point x="749" y="1231"/>
+ <point x="764" y="1233"/>
+ <point x="842" y="1233" type="curve" smooth="yes"/>
+ <point x="995" y="1233"/>
+ <point x="1089" y="1167"/>
+ <point x="1089" y="1060" type="curve" smooth="yes"/>
+ <point x="1089" y="899"/>
+ <point x="956" y="792"/>
+ <point x="782" y="792" type="curve" smooth="yes"/>
+ <point x="587" y="792" type="line"/>
+ </contour>
+ <contour>
+ <point x="652" y="629" type="line"/>
+ <point x="915" y="0" type="line"/>
+ <point x="1270" y="0" type="line"/>
+ <point x="1220" y="72"/>
+ <point x="962" y="623"/>
+ <point x="936" y="680" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetpsnames.ufo/glyphs/L_tnC_apS_.glif b/tests/reference/ufo/psfsetpsnames.ufo/glyphs/L_tnC_apS_.glif
new file mode 100644
index 0000000..79fe933
--- /dev/null
+++ b/tests/reference/ufo/psfsetpsnames.ufo/glyphs/L_tnC_apS_.glif
@@ -0,0 +1,50 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnCapS" format="2">
+ <advance width="1223"/>
+ <unicode hex="0053"/>
+ <anchor x="556" y="0" name="H"/>
+ <anchor x="531" y="-100" name="L"/>
+ <anchor x="938" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="1339" y="1361" type="line"/>
+ <point x="1232" y="1430"/>
+ <point x="1086" y="1470"/>
+ <point x="916" y="1470" type="curve" smooth="yes"/>
+ <point x="600" y="1470"/>
+ <point x="332" y="1333"/>
+ <point x="332" y="1053" type="curve" smooth="yes"/>
+ <point x="332" y="889"/>
+ <point x="413" y="800"/>
+ <point x="621" y="658" type="curve" smooth="yes"/>
+ <point x="829" y="516"/>
+ <point x="885" y="448"/>
+ <point x="885" y="374" type="curve" smooth="yes"/>
+ <point x="885" y="276"/>
+ <point x="772" y="218"/>
+ <point x="624" y="218" type="curve" smooth="yes"/>
+ <point x="463" y="218"/>
+ <point x="270" y="340"/>
+ <point x="184" y="461" type="curve"/>
+ <point x="67" y="189" type="line"/>
+ <point x="147" y="91"/>
+ <point x="394" y="-25"/>
+ <point x="573" y="-25" type="curve" smooth="yes"/>
+ <point x="923" y="-25"/>
+ <point x="1182" y="124"/>
+ <point x="1182" y="419" type="curve" smooth="yes"/>
+ <point x="1182" y="584"/>
+ <point x="1077" y="682"/>
+ <point x="881" y="831" type="curve" smooth="yes"/>
+ <point x="728" y="947"/>
+ <point x="628" y="1010"/>
+ <point x="628" y="1082" type="curve" smooth="yes"/>
+ <point x="628" y="1198"/>
+ <point x="790" y="1230"/>
+ <point x="877" y="1230" type="curve" smooth="yes"/>
+ <point x="1018" y="1230"/>
+ <point x="1119" y="1189"/>
+ <point x="1228" y="1099" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetpsnames.ufo/glyphs/L_tnC_apT_.glif b/tests/reference/ufo/psfsetpsnames.ufo/glyphs/L_tnC_apT_.glif
new file mode 100644
index 0000000..b7aa4cd
--- /dev/null
+++ b/tests/reference/ufo/psfsetpsnames.ufo/glyphs/L_tnC_apT_.glif
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnCapT" format="2">
+ <advance width="1255"/>
+ <unicode hex="0054"/>
+ <anchor x="572" y="0" name="H"/>
+ <anchor x="547" y="-100" name="L"/>
+ <anchor x="954" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="345" y="1445" type="line"/>
+ <point x="283" y="1198" type="line"/>
+ <point x="359" y="1215"/>
+ <point x="439" y="1218"/>
+ <point x="519" y="1218" type="curve" smooth="yes"/>
+ <point x="731" y="1218" type="line"/>
+ <point x="529" y="409" type="line" smooth="yes"/>
+ <point x="483" y="224"/>
+ <point x="443" y="75"/>
+ <point x="408" y="0" type="curve"/>
+ <point x="733" y="0" type="line"/>
+ <point x="734" y="75"/>
+ <point x="768" y="224"/>
+ <point x="814" y="409" type="curve" smooth="yes"/>
+ <point x="1016" y="1218" type="line"/>
+ <point x="1232" y="1218" type="line" smooth="yes"/>
+ <point x="1313" y="1218"/>
+ <point x="1390" y="1215"/>
+ <point x="1458" y="1198" type="curve"/>
+ <point x="1520" y="1445" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetpsnames.ufo/glyphs/L_tnC_apU_.glif b/tests/reference/ufo/psfsetpsnames.ufo/glyphs/L_tnC_apU_.glif
new file mode 100644
index 0000000..a01a283
--- /dev/null
+++ b/tests/reference/ufo/psfsetpsnames.ufo/glyphs/L_tnC_apU_.glif
@@ -0,0 +1,44 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnCapU" format="2">
+ <advance width="1470"/>
+ <unicode hex="0055"/>
+ <anchor x="672" y="0" name="H"/>
+ <anchor x="647" y="-100" name="L"/>
+ <anchor x="890" y="0" name="O"/>
+ <anchor x="1720" y="1200" name="R"/>
+ <anchor x="1054" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="1315" y="1445" type="line"/>
+ <point x="1093" y="554" type="line" smooth="yes"/>
+ <point x="1040" y="341"/>
+ <point x="952" y="202"/>
+ <point x="735" y="202" type="curve" smooth="yes"/>
+ <point x="572" y="202"/>
+ <point x="515" y="305"/>
+ <point x="515" y="435" type="curve" smooth="yes"/>
+ <point x="515" y="482"/>
+ <point x="523" y="533"/>
+ <point x="535" y="583" type="curve" smooth="yes"/>
+ <point x="750" y="1445" type="line"/>
+ <point x="450" y="1445" type="line"/>
+ <point x="444" y="1366"/>
+ <point x="406" y="1210"/>
+ <point x="358" y="1015" type="curve" smooth="yes"/>
+ <point x="249" y="570" type="line" smooth="yes"/>
+ <point x="235" y="512"/>
+ <point x="228" y="457"/>
+ <point x="228" y="404" type="curve" smooth="yes"/>
+ <point x="228" y="155"/>
+ <point x="385" y="-25"/>
+ <point x="698" y="-25" type="curve" smooth="yes"/>
+ <point x="1063" y="-25"/>
+ <point x="1275" y="148"/>
+ <point x="1356" y="470" type="curve" smooth="yes"/>
+ <point x="1493" y="1015" type="line" smooth="yes"/>
+ <point x="1544" y="1220"/>
+ <point x="1582" y="1366"/>
+ <point x="1615" y="1445" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetpsnames.ufo/glyphs/L_tnC_apV_.glif b/tests/reference/ufo/psfsetpsnames.ufo/glyphs/L_tnC_apV_.glif
new file mode 100644
index 0000000..07a71af
--- /dev/null
+++ b/tests/reference/ufo/psfsetpsnames.ufo/glyphs/L_tnC_apV_.glif
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnCapV" format="2">
+ <advance width="1445"/>
+ <unicode hex="0056"/>
+ <anchor x="670" y="0" name="H"/>
+ <anchor x="637" y="-100" name="L"/>
+ <anchor x="870" y="0" name="O"/>
+ <anchor x="1044" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="1405" y="1445" type="line"/>
+ <point x="721" y="257" type="line"/>
+ <point x="620" y="1445" type="line"/>
+ <point x="325" y="1445" type="line"/>
+ <point x="339" y="1364"/>
+ <point x="354" y="1275"/>
+ <point x="375" y="1084" type="curve" smooth="yes"/>
+ <point x="495" y="0" type="line"/>
+ <point x="830" y="0" type="line"/>
+ <point x="1490" y="1084" type="line" smooth="yes"/>
+ <point x="1606" y="1276"/>
+ <point x="1664" y="1364"/>
+ <point x="1720" y="1445" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetpsnames.ufo/glyphs/L_tnC_apW_.glif b/tests/reference/ufo/psfsetpsnames.ufo/glyphs/L_tnC_apW_.glif
new file mode 100644
index 0000000..f0e3607
--- /dev/null
+++ b/tests/reference/ufo/psfsetpsnames.ufo/glyphs/L_tnC_apW_.glif
@@ -0,0 +1,45 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnCapW" format="2">
+ <advance width="2115"/>
+ <unicode hex="0057"/>
+ <anchor x="967" y="-100" name="L"/>
+ <anchor x="1374" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="1430" y="0" type="line"/>
+ <point x="1595" y="0" type="line"/>
+ <point x="2165" y="1084" type="line" smooth="yes"/>
+ <point x="2266" y="1277"/>
+ <point x="2318" y="1364"/>
+ <point x="2370" y="1445" type="curve"/>
+ <point x="2050" y="1445" type="line"/>
+ <point x="1432" y="129" type="line"/>
+ </contour>
+ <contour>
+ <point x="1470" y="1445" type="line"/>
+ <point x="1220" y="1445" type="line"/>
+ <point x="1257" y="1292" type="line"/>
+ <point x="1280" y="0" type="line"/>
+ <point x="1450" y="0" type="line"/>
+ <point x="1492" y="129" type="line"/>
+ </contour>
+ <contour>
+ <point x="540" y="0" type="line"/>
+ <point x="705" y="0" type="line"/>
+ <point x="1367" y="1292" type="line"/>
+ <point x="1470" y="1445" type="line"/>
+ <point x="1210" y="1445" type="line"/>
+ <point x="542" y="129" type="line"/>
+ </contour>
+ <contour>
+ <point x="630" y="1445" type="line"/>
+ <point x="330" y="1445" type="line"/>
+ <point x="341" y="1367"/>
+ <point x="349" y="1273"/>
+ <point x="355" y="1084" type="curve" smooth="yes"/>
+ <point x="390" y="0" type="line"/>
+ <point x="560" y="0" type="line"/>
+ <point x="602" y="129" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetpsnames.ufo/glyphs/L_tnC_apX_.glif b/tests/reference/ufo/psfsetpsnames.ufo/glyphs/L_tnC_apX_.glif
new file mode 100644
index 0000000..633303c
--- /dev/null
+++ b/tests/reference/ufo/psfsetpsnames.ufo/glyphs/L_tnC_apX_.glif
@@ -0,0 +1,39 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnCapX" format="2">
+ <advance width="1345"/>
+ <unicode hex="0058"/>
+ <anchor x="585" y="-100" name="L"/>
+ <anchor x="992" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="930" y="0" type="line"/>
+ <point x="1240" y="0" type="line"/>
+ <point x="1199" y="81"/>
+ <point x="1172" y="125"/>
+ <point x="1096" y="333" type="curve" smooth="yes"/>
+ <point x="690" y="1445" type="line"/>
+ <point x="375" y="1445" type="line"/>
+ <point x="418" y="1362"/>
+ <point x="454" y="1304"/>
+ <point x="529" y="1099" type="curve" smooth="yes"/>
+ </contour>
+ <contour>
+ <point x="768" y="938" type="line"/>
+ <point x="269" y="337" type="line" smooth="yes"/>
+ <point x="94" y="126"/>
+ <point x="44" y="85"/>
+ <point x="-40" y="0" type="curve"/>
+ <point x="290" y="0" type="line"/>
+ <point x="790" y="603" type="line"/>
+ </contour>
+ <contour>
+ <point x="830" y="603" type="line"/>
+ <point x="1251" y="1099" type="line" smooth="yes"/>
+ <point x="1423" y="1302"/>
+ <point x="1492" y="1369"/>
+ <point x="1575" y="1445" type="curve"/>
+ <point x="1240" y="1445" type="line"/>
+ <point x="808" y="938" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetpsnames.ufo/glyphs/L_tnC_apY_.glif b/tests/reference/ufo/psfsetpsnames.ufo/glyphs/L_tnC_apY_.glif
new file mode 100644
index 0000000..49af854
--- /dev/null
+++ b/tests/reference/ufo/psfsetpsnames.ufo/glyphs/L_tnC_apY_.glif
@@ -0,0 +1,39 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnCapY" format="2">
+ <advance width="1344"/>
+ <unicode hex="0059"/>
+ <anchor x="587" y="-100" name="L"/>
+ <anchor x="994" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="325" y="1445" type="line"/>
+ <point x="400" y="1298"/>
+ <point x="438" y="1185"/>
+ <point x="482" y="1054" type="curve" smooth="yes"/>
+ <point x="653" y="554" type="line"/>
+ <point x="868" y="668" type="line"/>
+ <point x="637" y="1445" type="line"/>
+ </contour>
+ <contour>
+ <point x="1282" y="1445" type="line"/>
+ <point x="668" y="668" type="line"/>
+ <point x="848" y="554" type="line"/>
+ <point x="1271" y="1054" type="line" smooth="yes"/>
+ <point x="1379" y="1183"/>
+ <point x="1459" y="1278"/>
+ <point x="1619" y="1445" type="curve"/>
+ </contour>
+ <contour>
+ <point x="770" y="0" type="line"/>
+ <point x="774" y="79"/>
+ <point x="813" y="236"/>
+ <point x="862" y="431" type="curve" smooth="yes"/>
+ <point x="926" y="688" type="line"/>
+ <point x="641" y="688" type="line"/>
+ <point x="577" y="431" type="line" smooth="yes"/>
+ <point x="528" y="236"/>
+ <point x="488" y="79"/>
+ <point x="455" y="0" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetpsnames.ufo/glyphs/L_tnS_mA_.glif b/tests/reference/ufo/psfsetpsnames.ufo/glyphs/L_tnS_mA_.glif
new file mode 100644
index 0000000..0208140
--- /dev/null
+++ b/tests/reference/ufo/psfsetpsnames.ufo/glyphs/L_tnS_mA_.glif
@@ -0,0 +1,79 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmA" format="2">
+ <advance width="1185"/>
+ <unicode hex="0061"/>
+ <anchor x="925" y="0" name="H"/>
+ <anchor x="525" y="-100" name="L"/>
+ <anchor x="1125" y="0" name="O"/>
+ <anchor x="1335" y="1000" name="R"/>
+ <anchor x="825" y="1100" name="U"/>
+ <outline>
+ <contour>
+ <point x="1060" y="0" type="line"/>
+ <point x="1054" y="44"/>
+ <point x="1051" y="87"/>
+ <point x="1051" y="133" type="curve" smooth="yes"/>
+ <point x="1051" y="204"/>
+ <point x="1059" y="280"/>
+ <point x="1081" y="366" type="curve"/>
+ <point x="1128" y="557"/>
+ <point x="1156" y="665"/>
+ <point x="1170" y="722" type="curve"/>
+ <point x="1174" y="738"/>
+ <point x="1176" y="754"/>
+ <point x="1176" y="770" type="curve" smooth="yes"/>
+ <point x="1176" y="909"/>
+ <point x="1026" y="1030"/>
+ <point x="791" y="1030" type="curve" smooth="yes"/>
+ <point x="632" y="1030"/>
+ <point x="514" y="994"/>
+ <point x="389" y="940" type="curve"/>
+ <point x="363" y="859"/>
+ <point x="327" y="728"/>
+ <point x="315" y="684" type="curve"/>
+ <point x="452" y="765"/>
+ <point x="565" y="808"/>
+ <point x="673" y="808" type="curve" smooth="yes"/>
+ <point x="809" y="808"/>
+ <point x="885" y="760"/>
+ <point x="885" y="709" type="curve" smooth="yes"/>
+ <point x="885" y="705"/>
+ <point x="884" y="700"/>
+ <point x="883" y="696" type="curve" smooth="yes"/>
+ <point x="872" y="653" type="line"/>
+ <point x="831" y="652"/>
+ <point x="669" y="643"/>
+ <point x="598" y="636" type="curve" smooth="yes"/>
+ <point x="367" y="614"/>
+ <point x="109" y="474"/>
+ <point x="109" y="236" type="curve" smooth="yes"/>
+ <point x="109" y="97"/>
+ <point x="215" y="-25"/>
+ <point x="388" y="-25" type="curve" smooth="yes"/>
+ <point x="505" y="-25"/>
+ <point x="633" y="23"/>
+ <point x="773" y="134" type="curve"/>
+ <point x="773" y="78"/>
+ <point x="784" y="28"/>
+ <point x="790" y="0" type="curve"/>
+ </contour>
+ <contour>
+ <point x="797" y="351" type="line"/>
+ <point x="669" y="223"/>
+ <point x="590" y="203"/>
+ <point x="508" y="203" type="curve" smooth="yes"/>
+ <point x="438" y="203"/>
+ <point x="398" y="246"/>
+ <point x="398" y="299" type="curve" smooth="yes"/>
+ <point x="398" y="308"/>
+ <point x="399" y="317"/>
+ <point x="401" y="326" type="curve" smooth="yes"/>
+ <point x="417" y="391"/>
+ <point x="471" y="438"/>
+ <point x="612" y="452" type="curve" smooth="yes"/>
+ <point x="665" y="458"/>
+ <point x="786" y="469"/>
+ <point x="827" y="470" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetpsnames.ufo/glyphs/L_tnS_mA_A_cute.glif b/tests/reference/ufo/psfsetpsnames.ufo/glyphs/L_tnS_mA_A_cute.glif
new file mode 100644
index 0000000..a91e18b
--- /dev/null
+++ b/tests/reference/ufo/psfsetpsnames.ufo/glyphs/L_tnS_mA_A_cute.glif
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmAAcute" format="2">
+ <advance width="1185"/>
+ <unicode hex="00E1"/>
+ <anchor x="925" y="0" name="H"/>
+ <anchor x="525" y="-100" name="L"/>
+ <anchor x="1125" y="0" name="O"/>
+ <anchor x="1335" y="1000" name="R"/>
+ <anchor x="899" y="1635" name="U"/>
+ <outline>
+ <component base="LtnSmA"/>
+ <component base="CombAcute" xOffset="1150"/>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetpsnames.ufo/glyphs/L_tnS_mA_C_ircum.glif b/tests/reference/ufo/psfsetpsnames.ufo/glyphs/L_tnS_mA_C_ircum.glif
new file mode 100644
index 0000000..c17afb1
--- /dev/null
+++ b/tests/reference/ufo/psfsetpsnames.ufo/glyphs/L_tnS_mA_C_ircum.glif
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmACircum" format="2">
+ <advance width="1185"/>
+ <unicode hex="00E2"/>
+ <anchor x="925" y="0" name="H"/>
+ <anchor x="525" y="-100" name="L"/>
+ <anchor x="1125" y="0" name="O"/>
+ <anchor x="1335" y="1000" name="R"/>
+ <anchor x="916" y="1635" name="U"/>
+ <outline>
+ <component base="LtnSmA"/>
+ <component base="CombCircum" xOffset="1155"/>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetpsnames.ufo/glyphs/L_tnS_mA_D_iaer.glif b/tests/reference/ufo/psfsetpsnames.ufo/glyphs/L_tnS_mA_D_iaer.glif
new file mode 100644
index 0000000..af45db4
--- /dev/null
+++ b/tests/reference/ufo/psfsetpsnames.ufo/glyphs/L_tnS_mA_D_iaer.glif
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmADiaer" format="2">
+ <advance width="1185"/>
+ <unicode hex="00E4"/>
+ <anchor x="925" y="0" name="H"/>
+ <anchor x="525" y="-100" name="L"/>
+ <anchor x="1125" y="0" name="O"/>
+ <anchor x="1335" y="1000" name="R"/>
+ <anchor x="947" y="1585" name="U"/>
+ <outline>
+ <component base="LtnSmA"/>
+ <component base="CombDiaer" xOffset="1190"/>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetpsnames.ufo/glyphs/L_tnS_mA_G_rave.glif b/tests/reference/ufo/psfsetpsnames.ufo/glyphs/L_tnS_mA_G_rave.glif
new file mode 100644
index 0000000..2374c69
--- /dev/null
+++ b/tests/reference/ufo/psfsetpsnames.ufo/glyphs/L_tnS_mA_G_rave.glif
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmAGrave" format="2">
+ <advance width="1185"/>
+ <unicode hex="00E0"/>
+ <anchor x="925" y="0" name="H"/>
+ <anchor x="525" y="-100" name="L"/>
+ <anchor x="1125" y="0" name="O"/>
+ <anchor x="1335" y="1000" name="R"/>
+ <anchor x="999" y="1635" name="U"/>
+ <outline>
+ <component base="LtnSmA"/>
+ <component base="CombGrave" xOffset="1240"/>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetpsnames.ufo/glyphs/L_tnS_mA_R_ingA_bv.glif b/tests/reference/ufo/psfsetpsnames.ufo/glyphs/L_tnS_mA_R_ingA_bv.glif
new file mode 100644
index 0000000..f8a7dcc
--- /dev/null
+++ b/tests/reference/ufo/psfsetpsnames.ufo/glyphs/L_tnS_mA_R_ingA_bv.glif
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmARingAbv" format="2">
+ <advance width="1185"/>
+ <unicode hex="00E5"/>
+ <anchor x="925" y="0" name="H"/>
+ <anchor x="525" y="-100" name="L"/>
+ <anchor x="1125" y="0" name="O"/>
+ <anchor x="1335" y="1000" name="R"/>
+ <anchor x="961" y="1635" name="U"/>
+ <outline>
+ <component base="LtnSmA"/>
+ <component base="CombRingAbv" xOffset="1182"/>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetpsnames.ufo/glyphs/L_tnS_mA_T_ilde.glif b/tests/reference/ufo/psfsetpsnames.ufo/glyphs/L_tnS_mA_T_ilde.glif
new file mode 100644
index 0000000..4a46027
--- /dev/null
+++ b/tests/reference/ufo/psfsetpsnames.ufo/glyphs/L_tnS_mA_T_ilde.glif
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmATilde" format="2">
+ <advance width="1185"/>
+ <unicode hex="00E3"/>
+ <anchor x="925" y="0" name="H"/>
+ <anchor x="525" y="-100" name="L"/>
+ <anchor x="1125" y="0" name="O"/>
+ <anchor x="1335" y="1000" name="R"/>
+ <anchor x="860" y="1490" name="U"/>
+ <outline>
+ <component base="LtnSmA"/>
+ <component base="CombTilde" xOffset="1215"/>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetpsnames.ufo/glyphs/L_tnS_mB_.glif b/tests/reference/ufo/psfsetpsnames.ufo/glyphs/L_tnS_mB_.glif
new file mode 100644
index 0000000..92bd16b
--- /dev/null
+++ b/tests/reference/ufo/psfsetpsnames.ufo/glyphs/L_tnS_mB_.glif
@@ -0,0 +1,55 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmB" format="2">
+ <advance width="1229"/>
+ <unicode hex="0062"/>
+ <anchor x="550" y="0" name="H"/>
+ <anchor x="525" y="-100" name="L"/>
+ <anchor x="1405" y="1000" name="R"/>
+ <anchor x="958" y="1635" name="U"/>
+ <outline>
+ <contour>
+ <point x="482" y="432" type="line"/>
+ <point x="576" y="610"/>
+ <point x="726" y="787"/>
+ <point x="829" y="787" type="curve" smooth="yes"/>
+ <point x="911" y="787"/>
+ <point x="946" y="705"/>
+ <point x="946" y="590" type="curve" smooth="yes"/>
+ <point x="946" y="465"/>
+ <point x="897" y="350"/>
+ <point x="823" y="275" type="curve" smooth="yes"/>
+ <point x="769" y="221"/>
+ <point x="703" y="188"/>
+ <point x="631" y="188" type="curve" smooth="yes"/>
+ <point x="564" y="188"/>
+ <point x="502" y="202"/>
+ <point x="434" y="238" type="curve"/>
+ </contour>
+ <contour>
+ <point x="445" y="1585" type="line"/>
+ <point x="445" y="1439"/>
+ <point x="404" y="1242"/>
+ <point x="367" y="1095" type="curve" smooth="yes"/>
+ <point x="110" y="64" type="line"/>
+ <point x="252" y="16"/>
+ <point x="400" y="-25"/>
+ <point x="593" y="-25" type="curve" smooth="yes"/>
+ <point x="727" y="-25"/>
+ <point x="845" y="19"/>
+ <point x="942" y="91" type="curve" smooth="yes"/>
+ <point x="1122" y="224"/>
+ <point x="1229" y="453"/>
+ <point x="1229" y="672" type="curve" smooth="yes"/>
+ <point x="1229" y="906"/>
+ <point x="1138" y="1030"/>
+ <point x="985" y="1030" type="curve" smooth="yes"/>
+ <point x="822" y="1030"/>
+ <point x="684" y="906"/>
+ <point x="562" y="756" type="curve"/>
+ <point x="646" y="1095" type="line" smooth="yes"/>
+ <point x="686" y="1255"/>
+ <point x="725" y="1474"/>
+ <point x="725" y="1585" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetpsnames.ufo/glyphs/L_tnS_mC_.glif b/tests/reference/ufo/psfsetpsnames.ufo/glyphs/L_tnS_mC_.glif
new file mode 100644
index 0000000..62c096c
--- /dev/null
+++ b/tests/reference/ufo/psfsetpsnames.ufo/glyphs/L_tnS_mC_.glif
@@ -0,0 +1,39 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmC" format="2">
+ <advance width="1019"/>
+ <unicode hex="0063"/>
+ <anchor x="495" y="0" name="H"/>
+ <anchor x="490" y="-100" name="L"/>
+ <anchor x="1210" y="1000" name="R"/>
+ <anchor x="790" y="1100" name="U"/>
+ <outline>
+ <contour>
+ <point x="1099" y="959" type="line"/>
+ <point x="1035" y="997"/>
+ <point x="928" y="1030"/>
+ <point x="796" y="1030" type="curve" smooth="yes"/>
+ <point x="446" y="1030"/>
+ <point x="150" y="774"/>
+ <point x="150" y="386" type="curve" smooth="yes"/>
+ <point x="150" y="137"/>
+ <point x="341" y="-25"/>
+ <point x="569" y="-25" type="curve" smooth="yes"/>
+ <point x="718" y="-25"/>
+ <point x="835" y="11"/>
+ <point x="927" y="69" type="curve"/>
+ <point x="937" y="311" type="line"/>
+ <point x="840" y="238"/>
+ <point x="755" y="203"/>
+ <point x="625" y="203" type="curve" smooth="yes"/>
+ <point x="494" y="203"/>
+ <point x="417" y="302"/>
+ <point x="417" y="416" type="curve" smooth="yes"/>
+ <point x="417" y="661"/>
+ <point x="588" y="802"/>
+ <point x="754" y="802" type="curve" smooth="yes"/>
+ <point x="857" y="802"/>
+ <point x="918" y="781"/>
+ <point x="993" y="720" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetpsnames.ufo/glyphs/L_tnS_mD_.glif b/tests/reference/ufo/psfsetpsnames.ufo/glyphs/L_tnS_mD_.glif
new file mode 100644
index 0000000..fa38d37
--- /dev/null
+++ b/tests/reference/ufo/psfsetpsnames.ufo/glyphs/L_tnS_mD_.glif
@@ -0,0 +1,65 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmD" format="2">
+ <advance width="1265"/>
+ <unicode hex="0064"/>
+ <anchor x="535" y="0" name="H"/>
+ <anchor x="540" y="-100" name="L"/>
+ <anchor x="1475" y="1000" name="R"/>
+ <anchor x="958" y="1635" name="U"/>
+ <outline>
+ <contour>
+ <point x="913" y="558" type="line"/>
+ <point x="861" y="438"/>
+ <point x="666" y="200"/>
+ <point x="560" y="200" type="curve" smooth="yes"/>
+ <point x="470" y="200"/>
+ <point x="427" y="263"/>
+ <point x="427" y="367" type="curve" smooth="yes"/>
+ <point x="427" y="480"/>
+ <point x="469" y="626"/>
+ <point x="554" y="714" type="curve" smooth="yes"/>
+ <point x="599" y="761"/>
+ <point x="657" y="792"/>
+ <point x="727" y="792" type="curve" smooth="yes"/>
+ <point x="820" y="792"/>
+ <point x="876" y="775"/>
+ <point x="957" y="731" type="curve"/>
+ </contour>
+ <contour>
+ <point x="1144" y="1585" type="line"/>
+ <point x="1144" y="1471"/>
+ <point x="1116" y="1327"/>
+ <point x="1079" y="1175" type="curve" smooth="yes"/>
+ <point x="1020" y="935" type="line"/>
+ <point x="949" y="989"/>
+ <point x="845" y="1030"/>
+ <point x="756" y="1030" type="curve" smooth="yes"/>
+ <point x="630" y="1030"/>
+ <point x="518" y="987"/>
+ <point x="426" y="917" type="curve" smooth="yes"/>
+ <point x="250" y="784"/>
+ <point x="145" y="553"/>
+ <point x="145" y="341" type="curve" smooth="yes"/>
+ <point x="145" y="130"/>
+ <point x="258" y="-25"/>
+ <point x="448" y="-25" type="curve" smooth="yes"/>
+ <point x="597" y="-25"/>
+ <point x="785" y="145"/>
+ <point x="867" y="267" type="curve"/>
+ <point x="855" y="181"/>
+ <point x="855" y="72"/>
+ <point x="855" y="0" type="curve"/>
+ <point x="1130" y="0" type="line"/>
+ <point x="1126" y="23"/>
+ <point x="1125" y="63"/>
+ <point x="1125" y="100" type="curve" smooth="yes"/>
+ <point x="1125" y="200"/>
+ <point x="1142" y="340"/>
+ <point x="1185" y="520" type="curve" smooth="yes"/>
+ <point x="1345" y="1190" type="line" smooth="yes"/>
+ <point x="1387" y="1366"/>
+ <point x="1415" y="1490"/>
+ <point x="1415" y="1585" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetpsnames.ufo/glyphs/L_tnS_mE_.glif b/tests/reference/ufo/psfsetpsnames.ufo/glyphs/L_tnS_mE_.glif
new file mode 100644
index 0000000..49f5856
--- /dev/null
+++ b/tests/reference/ufo/psfsetpsnames.ufo/glyphs/L_tnS_mE_.glif
@@ -0,0 +1,52 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmE" format="2">
+ <advance width="1087"/>
+ <unicode hex="0065"/>
+ <anchor x="509" y="0" name="H"/>
+ <anchor x="555" y="-100" name="L"/>
+ <anchor x="840" y="0" name="O"/>
+ <anchor x="1320" y="1000" name="R"/>
+ <anchor x="752" y="1100" name="U"/>
+ <outline>
+ <contour>
+ <point x="1013" y="303" type="line"/>
+ <point x="871" y="230"/>
+ <point x="739" y="198"/>
+ <point x="608" y="198" type="curve" smooth="yes"/>
+ <point x="459" y="198"/>
+ <point x="401" y="297"/>
+ <point x="401" y="428" type="curve" smooth="yes"/>
+ <point x="401" y="683"/>
+ <point x="552" y="822"/>
+ <point x="713" y="822" type="curve" smooth="yes"/>
+ <point x="811" y="822"/>
+ <point x="869" y="782"/>
+ <point x="869" y="720" type="curve" smooth="yes"/>
+ <point x="869" y="635"/>
+ <point x="777" y="580"/>
+ <point x="533" y="580" type="curve" smooth="yes"/>
+ <point x="461" y="580"/>
+ <point x="385" y="589"/>
+ <point x="283" y="610" type="curve"/>
+ <point x="283" y="437" type="line"/>
+ <point x="353" y="422"/>
+ <point x="487" y="413"/>
+ <point x="569" y="413" type="curve" smooth="yes"/>
+ <point x="935" y="413"/>
+ <point x="1125" y="583"/>
+ <point x="1125" y="774" type="curve" smooth="yes"/>
+ <point x="1125" y="922"/>
+ <point x="993" y="1030"/>
+ <point x="769" y="1030" type="curve" smooth="yes"/>
+ <point x="435" y="1030"/>
+ <point x="148" y="775"/>
+ <point x="148" y="388" type="curve" smooth="yes"/>
+ <point x="148" y="135"/>
+ <point x="332" y="-25"/>
+ <point x="556" y="-25" type="curve" smooth="yes"/>
+ <point x="712" y="-25"/>
+ <point x="835" y="2"/>
+ <point x="997" y="74" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetpsnames.ufo/glyphs/L_tnS_mF_.glif b/tests/reference/ufo/psfsetpsnames.ufo/glyphs/L_tnS_mF_.glif
new file mode 100644
index 0000000..fd86bf3
--- /dev/null
+++ b/tests/reference/ufo/psfsetpsnames.ufo/glyphs/L_tnS_mF_.glif
@@ -0,0 +1,44 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmF" format="2">
+ <advance width="859"/>
+ <unicode hex="0066"/>
+ <anchor x="320" y="0" name="H"/>
+ <anchor x="400" y="-100" name="L"/>
+ <anchor x="948" y="1635" name="U"/>
+ <outline>
+ <contour>
+ <point x="180" y="797" type="line"/>
+ <point x="915" y="797" type="line"/>
+ <point x="965" y="995" type="line"/>
+ <point x="230" y="995" type="line"/>
+ </contour>
+ <contour>
+ <point x="1189" y="1534" type="line"/>
+ <point x="1139" y="1572"/>
+ <point x="1040" y="1604"/>
+ <point x="966" y="1604" type="curve" smooth="yes"/>
+ <point x="719" y="1604"/>
+ <point x="535" y="1455"/>
+ <point x="460" y="1158" type="curve" smooth="yes"/>
+ <point x="416" y="983"/>
+ <point x="253" y="334"/>
+ <point x="232" y="0" type="curve"/>
+ <point x="542" y="0" type="line"/>
+ <point x="536" y="28"/>
+ <point x="533" y="66"/>
+ <point x="533" y="110" type="curve" smooth="yes"/>
+ <point x="533" y="213"/>
+ <point x="550" y="356"/>
+ <point x="581" y="489" type="curve" smooth="yes"/>
+ <point x="649" y="784"/>
+ <point x="682" y="926"/>
+ <point x="735" y="1147" type="curve" smooth="yes"/>
+ <point x="774" y="1309"/>
+ <point x="836" y="1373"/>
+ <point x="932" y="1373" type="curve" smooth="yes"/>
+ <point x="981" y="1373"/>
+ <point x="1043" y="1348"/>
+ <point x="1076" y="1309" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetpsnames.ufo/glyphs/L_tnS_mG_.glif b/tests/reference/ufo/psfsetpsnames.ufo/glyphs/L_tnS_mG_.glif
new file mode 100644
index 0000000..c651c04
--- /dev/null
+++ b/tests/reference/ufo/psfsetpsnames.ufo/glyphs/L_tnS_mG_.glif
@@ -0,0 +1,91 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmG" format="2">
+ <advance width="1120"/>
+ <unicode hex="0067"/>
+ <anchor x="420" y="-465" name="H"/>
+ <anchor x="403" y="-535" name="L"/>
+ <anchor x="1360" y="1000" name="R"/>
+ <anchor x="782" y="1100" name="U"/>
+ <outline>
+ <contour>
+ <point x="1027" y="-117" type="curve" smooth="yes"/>
+ <point x="1027" y="8"/>
+ <point x="938" y="114"/>
+ <point x="702" y="163" type="curve" smooth="yes"/>
+ <point x="473" y="210"/>
+ <point x="402" y="217"/>
+ <point x="402" y="249" type="curve" smooth="yes"/>
+ <point x="402" y="279"/>
+ <point x="493" y="321"/>
+ <point x="584" y="346" type="curve"/>
+ <point x="359" y="391" type="line"/>
+ <point x="263" y="354"/>
+ <point x="161" y="283"/>
+ <point x="161" y="188" type="curve" smooth="yes"/>
+ <point x="161" y="101"/>
+ <point x="230" y="4"/>
+ <point x="451" y="-23" type="curve" smooth="yes"/>
+ <point x="669" y="-50"/>
+ <point x="740" y="-97"/>
+ <point x="740" y="-157" type="curve" smooth="yes"/>
+ <point x="740" y="-245"/>
+ <point x="591" y="-299"/>
+ <point x="457" y="-299" type="curve" smooth="yes"/>
+ <point x="286" y="-299"/>
+ <point x="197" y="-233"/>
+ <point x="197" y="-180" type="curve" smooth="yes"/>
+ <point x="197" y="-74"/>
+ <point x="405" y="-4"/>
+ <point x="476" y="20" type="curve"/>
+ <point x="476" y="49"/>
+ <point x="250" y="74"/>
+ <point x="250" y="74" type="curve"/>
+ <point x="103" y="20"/>
+ <point x="-91" y="-65"/>
+ <point x="-91" y="-233" type="curve" smooth="yes"/>
+ <point x="-91" y="-409"/>
+ <point x="166" y="-500"/>
+ <point x="392" y="-500" type="curve" smooth="yes"/>
+ <point x="690" y="-500"/>
+ <point x="1027" y="-380"/>
+ </contour>
+ <contour>
+ <point x="1268" y="1030" type="line"/>
+ <point x="1168" y="1023"/>
+ <point x="1027" y="987"/>
+ <point x="924" y="931" type="curve"/>
+ <point x="946" y="762" type="line"/>
+ <point x="1048" y="800"/>
+ <point x="1132" y="815"/>
+ <point x="1205" y="817" type="curve"/>
+ </contour>
+ <contour>
+ <point x="198" y="627" type="curve" smooth="yes"/>
+ <point x="198" y="450"/>
+ <point x="353" y="302"/>
+ <point x="572" y="302" type="curve" smooth="yes"/>
+ <point x="824" y="302"/>
+ <point x="1087" y="444"/>
+ <point x="1087" y="702" type="curve" smooth="yes"/>
+ <point x="1087" y="874"/>
+ <point x="955" y="1030"/>
+ <point x="703" y="1030" type="curve" smooth="yes"/>
+ <point x="454" y="1030"/>
+ <point x="198" y="881"/>
+ </contour>
+ <contour>
+ <point x="663" y="829" type="curve" smooth="yes"/>
+ <point x="761" y="829"/>
+ <point x="842" y="762"/>
+ <point x="842" y="675" type="curve" smooth="yes"/>
+ <point x="842" y="559"/>
+ <point x="733" y="496"/>
+ <point x="620" y="496" type="curve" smooth="yes"/>
+ <point x="524" y="496"/>
+ <point x="450" y="569"/>
+ <point x="450" y="653" type="curve" smooth="yes"/>
+ <point x="450" y="769"/>
+ <point x="560" y="829"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetpsnames.ufo/glyphs/L_tnS_mH_.glif b/tests/reference/ufo/psfsetpsnames.ufo/glyphs/L_tnS_mH_.glif
new file mode 100644
index 0000000..7160c61
--- /dev/null
+++ b/tests/reference/ufo/psfsetpsnames.ufo/glyphs/L_tnS_mH_.glif
@@ -0,0 +1,54 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmH" format="2">
+ <advance width="1273"/>
+ <unicode hex="0068"/>
+ <anchor x="220" y="0" name="H"/>
+ <anchor x="635" y="-100" name="L"/>
+ <anchor x="968" y="1635" name="U"/>
+ <outline>
+ <contour>
+ <point x="1140" y="0" type="line"/>
+ <point x="1135" y="29"/>
+ <point x="1129" y="60"/>
+ <point x="1129" y="90" type="curve" smooth="yes"/>
+ <point x="1129" y="135"/>
+ <point x="1134" y="170"/>
+ <point x="1141" y="215" type="curve" smooth="yes"/>
+ <point x="1171" y="400"/>
+ <point x="1253" y="590"/>
+ <point x="1253" y="725" type="curve" smooth="yes"/>
+ <point x="1253" y="900"/>
+ <point x="1183" y="1030"/>
+ <point x="990" y="1030" type="curve" smooth="yes"/>
+ <point x="849" y="1030"/>
+ <point x="694" y="902"/>
+ <point x="566" y="740" type="curve"/>
+ <point x="656" y="1095" type="line" smooth="yes"/>
+ <point x="696" y="1255"/>
+ <point x="735" y="1474"/>
+ <point x="735" y="1585" type="curve"/>
+ <point x="455" y="1585" type="line"/>
+ <point x="455" y="1439"/>
+ <point x="413" y="1242"/>
+ <point x="377" y="1095" type="curve" smooth="yes"/>
+ <point x="105" y="0" type="line"/>
+ <point x="385" y="0" type="line"/>
+ <point x="485" y="400" type="line"/>
+ <point x="580" y="596"/>
+ <point x="745" y="787"/>
+ <point x="850" y="787" type="curve" smooth="yes"/>
+ <point x="937" y="787"/>
+ <point x="953" y="722"/>
+ <point x="953" y="625" type="curve" smooth="yes"/>
+ <point x="953" y="529"/>
+ <point x="889" y="374"/>
+ <point x="863" y="213" type="curve" smooth="yes"/>
+ <point x="857" y="174"/>
+ <point x="853" y="134"/>
+ <point x="853" y="95" type="curve" smooth="yes"/>
+ <point x="853" y="63"/>
+ <point x="854" y="31"/>
+ <point x="860" y="0" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetpsnames.ufo/glyphs/L_tnS_mI_.glif b/tests/reference/ufo/psfsetpsnames.ufo/glyphs/L_tnS_mI_.glif
new file mode 100644
index 0000000..c19769e
--- /dev/null
+++ b/tests/reference/ufo/psfsetpsnames.ufo/glyphs/L_tnS_mI_.glif
@@ -0,0 +1,50 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmI" format="2">
+ <advance width="625"/>
+ <unicode hex="0069"/>
+ <anchor x="260" y="0" name="H"/>
+ <anchor x="335" y="-100" name="L"/>
+ <anchor x="520" y="0" name="O"/>
+ <anchor x="830" y="1000" name="R"/>
+ <anchor x="535" y="1100" name="U"/>
+ <outline>
+ <contour>
+ <point x="341" y="1010" type="line"/>
+ <point x="341" y="877"/>
+ <point x="290" y="698"/>
+ <point x="252" y="547" type="curve" smooth="yes"/>
+ <point x="213" y="390" type="line" smooth="yes"/>
+ <point x="193" y="309"/>
+ <point x="170" y="191"/>
+ <point x="170" y="88" type="curve" smooth="yes"/>
+ <point x="170" y="57"/>
+ <point x="172" y="27"/>
+ <point x="177" y="0" type="curve"/>
+ <point x="472" y="0" type="line"/>
+ <point x="463" y="39"/>
+ <point x="459" y="82"/>
+ <point x="459" y="126" type="curve" smooth="yes"/>
+ <point x="459" y="217"/>
+ <point x="475" y="310"/>
+ <point x="486" y="358" type="curve" smooth="yes"/>
+ <point x="531" y="546" type="line" smooth="yes"/>
+ <point x="572" y="719"/>
+ <point x="621" y="875"/>
+ <point x="625" y="1010" type="curve"/>
+ </contour>
+ <contour>
+ <point x="404" y="1341" type="curve" smooth="yes"/>
+ <point x="404" y="1259"/>
+ <point x="462" y="1197"/>
+ <point x="548" y="1197" type="curve" smooth="yes"/>
+ <point x="668" y="1197"/>
+ <point x="759" y="1292"/>
+ <point x="759" y="1403" type="curve" smooth="yes"/>
+ <point x="759" y="1483"/>
+ <point x="701" y="1544"/>
+ <point x="614" y="1544" type="curve" smooth="yes"/>
+ <point x="496" y="1544"/>
+ <point x="404" y="1451"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetpsnames.ufo/glyphs/L_tnS_mJ_.glif b/tests/reference/ufo/psfsetpsnames.ufo/glyphs/L_tnS_mJ_.glif
new file mode 100644
index 0000000..a454f7a
--- /dev/null
+++ b/tests/reference/ufo/psfsetpsnames.ufo/glyphs/L_tnS_mJ_.glif
@@ -0,0 +1,45 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmJ" format="2">
+ <advance width="695"/>
+ <unicode hex="006A"/>
+ <anchor x="-45" y="-500" name="L"/>
+ <anchor x="565" y="1100" name="U"/>
+ <outline>
+ <contour>
+ <point x="361" y="1010" type="line"/>
+ <point x="361" y="866"/>
+ <point x="284" y="395"/>
+ <point x="205" y="87" type="curve" smooth="yes"/>
+ <point x="148" y="-136"/>
+ <point x="54" y="-221"/>
+ <point x="-56" y="-221" type="curve" smooth="yes"/>
+ <point x="-137" y="-221"/>
+ <point x="-217" y="-187"/>
+ <point x="-252" y="-150" type="curve"/>
+ <point x="-355" y="-385" type="line"/>
+ <point x="-321" y="-417"/>
+ <point x="-172" y="-465"/>
+ <point x="-79" y="-465" type="curve" smooth="yes"/>
+ <point x="170" y="-465"/>
+ <point x="388" y="-295"/>
+ <point x="481" y="75" type="curve" smooth="yes"/>
+ <point x="501" y="157"/>
+ <point x="646" y="882"/>
+ <point x="646" y="1010" type="curve"/>
+ </contour>
+ <contour>
+ <point x="395" y="1341" type="curve" smooth="yes"/>
+ <point x="395" y="1259"/>
+ <point x="453" y="1197"/>
+ <point x="539" y="1197" type="curve" smooth="yes"/>
+ <point x="659" y="1197"/>
+ <point x="750" y="1292"/>
+ <point x="750" y="1403" type="curve" smooth="yes"/>
+ <point x="750" y="1483"/>
+ <point x="692" y="1544"/>
+ <point x="605" y="1544" type="curve" smooth="yes"/>
+ <point x="487" y="1544"/>
+ <point x="395" y="1451"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetpsnames.ufo/glyphs/L_tnS_mK_.glif b/tests/reference/ufo/psfsetpsnames.ufo/glyphs/L_tnS_mK_.glif
new file mode 100644
index 0000000..ed9d720
--- /dev/null
+++ b/tests/reference/ufo/psfsetpsnames.ufo/glyphs/L_tnS_mK_.glif
@@ -0,0 +1,45 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmK" format="2">
+ <advance width="1209"/>
+ <unicode hex="006B"/>
+ <anchor x="880" y="0" name="H"/>
+ <anchor x="600" y="-100" name="L"/>
+ <anchor x="1330" y="1000" name="R"/>
+ <anchor x="943" y="1635" name="U"/>
+ <outline>
+ <contour>
+ <point x="964" y="1010" type="line"/>
+ <point x="920" y="864"/>
+ <point x="682" y="702"/>
+ <point x="483" y="576" type="curve"/>
+ <point x="676" y="518" type="line"/>
+ <point x="915" y="662"/>
+ <point x="1289" y="867"/>
+ <point x="1289" y="1010" type="curve"/>
+ </contour>
+ <contour>
+ <point x="1168" y="0" type="line"/>
+ <point x="992" y="302"/>
+ <point x="856" y="620"/>
+ <point x="633" y="620" type="curve"/>
+ <point x="442" y="529" type="line"/>
+ <point x="606" y="529"/>
+ <point x="722" y="252"/>
+ <point x="831" y="0" type="curve"/>
+ </contour>
+ <contour>
+ <point x="394" y="0" type="line"/>
+ <point x="669" y="1105" type="line" smooth="yes"/>
+ <point x="713" y="1280"/>
+ <point x="744" y="1497"/>
+ <point x="744" y="1585" type="curve"/>
+ <point x="462" y="1585" type="line"/>
+ <point x="462" y="1471"/>
+ <point x="431" y="1274"/>
+ <point x="393" y="1122" type="curve" smooth="yes"/>
+ <point x="345" y="928"/>
+ <point x="115" y="0"/>
+ <point x="115" y="0" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetpsnames.ufo/glyphs/L_tnS_mL_.glif b/tests/reference/ufo/psfsetpsnames.ufo/glyphs/L_tnS_mL_.glif
new file mode 100644
index 0000000..3ecb48c
--- /dev/null
+++ b/tests/reference/ufo/psfsetpsnames.ufo/glyphs/L_tnS_mL_.glif
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmL" format="2">
+ <advance width="641"/>
+ <unicode hex="006C"/>
+ <anchor x="275" y="0" name="H"/>
+ <anchor x="350" y="-100" name="L"/>
+ <anchor x="850" y="1000" name="R"/>
+ <anchor x="630" y="1635" name="U"/>
+ <outline>
+ <contour>
+ <point x="461" y="1585" type="line"/>
+ <point x="461" y="1439"/>
+ <point x="420" y="1242"/>
+ <point x="383" y="1095" type="curve" smooth="yes"/>
+ <point x="232" y="488" type="line" smooth="yes"/>
+ <point x="208" y="394"/>
+ <point x="175" y="269"/>
+ <point x="175" y="116" type="curve" smooth="yes"/>
+ <point x="175" y="89"/>
+ <point x="178" y="30"/>
+ <point x="180" y="0" type="curve"/>
+ <point x="470" y="0" type="line"/>
+ <point x="464" y="39"/>
+ <point x="461" y="80"/>
+ <point x="461" y="121" type="curve" smooth="yes"/>
+ <point x="461" y="277"/>
+ <point x="498" y="434"/>
+ <point x="518" y="515" type="curve" smooth="yes"/>
+ <point x="662" y="1095" type="line" smooth="yes"/>
+ <point x="702" y="1255"/>
+ <point x="741" y="1474"/>
+ <point x="741" y="1585" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetpsnames.ufo/glyphs/L_tnS_mM_.glif b/tests/reference/ufo/psfsetpsnames.ufo/glyphs/L_tnS_mM_.glif
new file mode 100644
index 0000000..6f5967a
--- /dev/null
+++ b/tests/reference/ufo/psfsetpsnames.ufo/glyphs/L_tnS_mM_.glif
@@ -0,0 +1,80 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmM" format="2">
+ <advance width="1770"/>
+ <unicode hex="006D"/>
+ <anchor x="830" y="0" name="H"/>
+ <anchor x="805" y="-100" name="L"/>
+ <anchor x="1105" y="1100" name="U"/>
+ <outline>
+ <contour>
+ <point x="1609" y="0" type="line"/>
+ <point x="1604" y="29"/>
+ <point x="1602" y="60"/>
+ <point x="1602" y="90" type="curve" smooth="yes"/>
+ <point x="1602" y="136"/>
+ <point x="1606" y="181"/>
+ <point x="1613" y="228" type="curve" smooth="yes"/>
+ <point x="1628" y="333"/>
+ <point x="1747" y="670"/>
+ <point x="1747" y="822" type="curve" smooth="yes"/>
+ <point x="1747" y="958"/>
+ <point x="1681" y="1030"/>
+ <point x="1547" y="1030" type="curve" smooth="yes"/>
+ <point x="1391" y="1030"/>
+ <point x="1227" y="876"/>
+ <point x="1120" y="705" type="curve"/>
+ <point x="1125" y="738"/>
+ <point x="1127" y="769"/>
+ <point x="1127" y="798" type="curve" smooth="yes"/>
+ <point x="1127" y="944"/>
+ <point x="1067" y="1030"/>
+ <point x="941" y="1030" type="curve" smooth="yes"/>
+ <point x="815" y="1030"/>
+ <point x="664" y="911"/>
+ <point x="537" y="715" type="curve"/>
+ <point x="553" y="840"/>
+ <point x="556" y="911"/>
+ <point x="556" y="955" type="curve" smooth="yes"/>
+ <point x="556" y="981"/>
+ <point x="554" y="998"/>
+ <point x="551" y="1010" type="curve"/>
+ <point x="291" y="1010" type="line"/>
+ <point x="293" y="999"/>
+ <point x="294" y="975"/>
+ <point x="294" y="942" type="curve" smooth="yes"/>
+ <point x="294" y="855"/>
+ <point x="286" y="710"/>
+ <point x="261" y="609" type="curve" smooth="yes"/>
+ <point x="110" y="0" type="line"/>
+ <point x="390" y="0" type="line"/>
+ <point x="479" y="370" type="line"/>
+ <point x="541" y="552"/>
+ <point x="711" y="787"/>
+ <point x="791" y="787" type="curve" smooth="yes"/>
+ <point x="843" y="787"/>
+ <point x="857" y="741"/>
+ <point x="857" y="688" type="curve" smooth="yes"/>
+ <point x="857" y="625"/>
+ <point x="832" y="535"/>
+ <point x="819" y="483" type="curve" smooth="yes"/>
+ <point x="695" y="0" type="line"/>
+ <point x="975" y="0" type="line"/>
+ <point x="1067" y="370" type="line"/>
+ <point x="1139" y="556"/>
+ <point x="1300" y="787"/>
+ <point x="1381" y="787" type="curve" smooth="yes"/>
+ <point x="1434" y="787"/>
+ <point x="1450" y="762"/>
+ <point x="1450" y="706" type="curve" smooth="yes"/>
+ <point x="1450" y="592"/>
+ <point x="1350" y="331"/>
+ <point x="1330" y="205" type="curve" smooth="yes"/>
+ <point x="1324" y="168"/>
+ <point x="1321" y="132"/>
+ <point x="1321" y="95" type="curve" smooth="yes"/>
+ <point x="1321" y="63"/>
+ <point x="1323" y="31"/>
+ <point x="1329" y="0" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetpsnames.ufo/glyphs/L_tnS_mN_.glif b/tests/reference/ufo/psfsetpsnames.ufo/glyphs/L_tnS_mN_.glif
new file mode 100644
index 0000000..009224e
--- /dev/null
+++ b/tests/reference/ufo/psfsetpsnames.ufo/glyphs/L_tnS_mN_.glif
@@ -0,0 +1,57 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmN" format="2">
+ <advance width="1281"/>
+ <unicode hex="006E"/>
+ <anchor x="560" y="0" name="H"/>
+ <anchor x="635" y="-100" name="L"/>
+ <anchor x="835" y="1100" name="U"/>
+ <outline>
+ <contour>
+ <point x="1145" y="0" type="line"/>
+ <point x="1140" y="29"/>
+ <point x="1138" y="60"/>
+ <point x="1138" y="90" type="curve" smooth="yes"/>
+ <point x="1138" y="136"/>
+ <point x="1141" y="182"/>
+ <point x="1149" y="228" type="curve" smooth="yes"/>
+ <point x="1173" y="366"/>
+ <point x="1258" y="591"/>
+ <point x="1258" y="725" type="curve" smooth="yes"/>
+ <point x="1258" y="890"/>
+ <point x="1188" y="1030"/>
+ <point x="995" y="1030" type="curve" smooth="yes"/>
+ <point x="844" y="1030"/>
+ <point x="685" y="903"/>
+ <point x="546" y="715" type="curve"/>
+ <point x="555" y="771"/>
+ <point x="569" y="875"/>
+ <point x="569" y="933" type="curve" smooth="yes"/>
+ <point x="569" y="962"/>
+ <point x="568" y="988"/>
+ <point x="565" y="1010" type="curve"/>
+ <point x="290" y="1010" type="line"/>
+ <point x="290" y="962" type="line" smooth="yes"/>
+ <point x="290" y="859"/>
+ <point x="280" y="685"/>
+ <point x="261" y="609" type="curve" smooth="yes"/>
+ <point x="110" y="0" type="line"/>
+ <point x="388" y="0" type="line"/>
+ <point x="490" y="405" type="line"/>
+ <point x="569" y="569"/>
+ <point x="740" y="787"/>
+ <point x="835" y="787" type="curve" smooth="yes"/>
+ <point x="922" y="787"/>
+ <point x="958" y="732"/>
+ <point x="958" y="625" type="curve" smooth="yes"/>
+ <point x="958" y="527"/>
+ <point x="891" y="369"/>
+ <point x="866" y="205" type="curve" smooth="yes"/>
+ <point x="860" y="168"/>
+ <point x="857" y="132"/>
+ <point x="857" y="95" type="curve" smooth="yes"/>
+ <point x="857" y="63"/>
+ <point x="859" y="31"/>
+ <point x="865" y="0" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetpsnames.ufo/glyphs/L_tnS_mO_.glif b/tests/reference/ufo/psfsetpsnames.ufo/glyphs/L_tnS_mO_.glif
new file mode 100644
index 0000000..d21fb58
--- /dev/null
+++ b/tests/reference/ufo/psfsetpsnames.ufo/glyphs/L_tnS_mO_.glif
@@ -0,0 +1,40 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmO" format="2">
+ <advance width="1139"/>
+ <unicode hex="006F"/>
+ <anchor x="518" y="0" name="H"/>
+ <anchor x="530" y="-100" name="L"/>
+ <anchor x="730" y="0" name="O"/>
+ <anchor x="1350" y="1000" name="R"/>
+ <anchor x="795" y="1100" name="U"/>
+ <outline>
+ <contour>
+ <point x="140" y="370" type="curve" smooth="yes"/>
+ <point x="140" y="128"/>
+ <point x="289" y="-25"/>
+ <point x="520" y="-25" type="curve" smooth="yes"/>
+ <point x="906" y="-25"/>
+ <point x="1144" y="295"/>
+ <point x="1144" y="641" type="curve" smooth="yes"/>
+ <point x="1144" y="880"/>
+ <point x="1003" y="1030"/>
+ <point x="773" y="1030" type="curve" smooth="yes"/>
+ <point x="390" y="1030"/>
+ <point x="140" y="718"/>
+ </contour>
+ <contour>
+ <point x="718" y="807" type="curve" smooth="yes"/>
+ <point x="826" y="807"/>
+ <point x="879" y="737"/>
+ <point x="879" y="612" type="curve" smooth="yes"/>
+ <point x="879" y="413"/>
+ <point x="764" y="198"/>
+ <point x="566" y="198" type="curve" smooth="yes"/>
+ <point x="464" y="198"/>
+ <point x="404" y="264"/>
+ <point x="404" y="385" type="curve" smooth="yes"/>
+ <point x="404" y="570"/>
+ <point x="512" y="807"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetpsnames.ufo/glyphs/L_tnS_mP_.glif b/tests/reference/ufo/psfsetpsnames.ufo/glyphs/L_tnS_mP_.glif
new file mode 100644
index 0000000..55c6e8b
--- /dev/null
+++ b/tests/reference/ufo/psfsetpsnames.ufo/glyphs/L_tnS_mP_.glif
@@ -0,0 +1,66 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmP" format="2">
+ <advance width="1272"/>
+ <unicode hex="0070"/>
+ <anchor x="121" y="-435" name="H"/>
+ <anchor x="555" y="-500" name="L"/>
+ <anchor x="1425" y="1000" name="R"/>
+ <anchor x="855" y="1100" name="U"/>
+ <outline>
+ <contour>
+ <point x="523" y="500" type="line"/>
+ <point x="605" y="650"/>
+ <point x="765" y="794"/>
+ <point x="854" y="794" type="curve" smooth="yes"/>
+ <point x="932" y="794"/>
+ <point x="975" y="719"/>
+ <point x="975" y="609" type="curve" smooth="yes"/>
+ <point x="975" y="478"/>
+ <point x="924" y="334"/>
+ <point x="823" y="258" type="curve" smooth="yes"/>
+ <point x="778" y="224"/>
+ <point x="723" y="204"/>
+ <point x="658" y="204" type="curve" smooth="yes"/>
+ <point x="589" y="204"/>
+ <point x="517" y="243"/>
+ <point x="473" y="297" type="curve"/>
+ </contour>
+ <contour>
+ <point x="300" y="1010" type="line"/>
+ <point x="300" y="962" type="line" smooth="yes"/>
+ <point x="300" y="859"/>
+ <point x="290" y="685"/>
+ <point x="271" y="609" type="curve" smooth="yes"/>
+ <point x="75" y="-180" type="line" smooth="yes"/>
+ <point x="49" y="-286"/>
+ <point x="25" y="-403"/>
+ <point x="25" y="-485" type="curve"/>
+ <point x="314" y="-485" type="line"/>
+ <point x="314" y="-393"/>
+ <point x="328" y="-287"/>
+ <point x="362" y="-149" type="curve" smooth="yes"/>
+ <point x="415" y="64" type="line"/>
+ <point x="495" y="10"/>
+ <point x="562" y="-25"/>
+ <point x="667" y="-25" type="curve" smooth="yes"/>
+ <point x="750" y="-25"/>
+ <point x="833" y="-2"/>
+ <point x="909" y="40" type="curve" smooth="yes"/>
+ <point x="1112" y="152"/>
+ <point x="1267" y="398"/>
+ <point x="1267" y="685" type="curve" smooth="yes"/>
+ <point x="1267" y="884"/>
+ <point x="1176" y="1030"/>
+ <point x="1004" y="1030" type="curve" smooth="yes"/>
+ <point x="849" y="1030"/>
+ <point x="677" y="901"/>
+ <point x="565" y="752" type="curve"/>
+ <point x="574" y="808"/>
+ <point x="579" y="875"/>
+ <point x="579" y="933" type="curve" smooth="yes"/>
+ <point x="579" y="962"/>
+ <point x="578" y="988"/>
+ <point x="575" y="1010" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetpsnames.ufo/glyphs/L_tnS_mQ_.glif b/tests/reference/ufo/psfsetpsnames.ufo/glyphs/L_tnS_mQ_.glif
new file mode 100644
index 0000000..d3068d2
--- /dev/null
+++ b/tests/reference/ufo/psfsetpsnames.ufo/glyphs/L_tnS_mQ_.glif
@@ -0,0 +1,54 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmQ" format="2">
+ <advance width="1206"/>
+ <unicode hex="0071"/>
+ <anchor x="415" y="-500" name="L"/>
+ <anchor x="1400" y="1000" name="R"/>
+ <anchor x="815" y="1100" name="U"/>
+ <outline>
+ <contour>
+ <point x="889" y="583" type="line"/>
+ <point x="832" y="467"/>
+ <point x="615" y="211"/>
+ <point x="520" y="211" type="curve" smooth="yes"/>
+ <point x="457" y="211"/>
+ <point x="429" y="263"/>
+ <point x="429" y="362" type="curve" smooth="yes"/>
+ <point x="429" y="484"/>
+ <point x="469" y="616"/>
+ <point x="551" y="702" type="curve" smooth="yes"/>
+ <point x="605" y="758"/>
+ <point x="676" y="794"/>
+ <point x="765" y="794" type="curve" smooth="yes"/>
+ <point x="806" y="794"/>
+ <point x="897" y="781"/>
+ <point x="933" y="762" type="curve"/>
+ </contour>
+ <contour>
+ <point x="936" y="-485" type="line"/>
+ <point x="936" y="-396"/>
+ <point x="951" y="-299"/>
+ <point x="978" y="-190" type="curve" smooth="yes"/>
+ <point x="1261" y="955" type="line"/>
+ <point x="1134" y="991"/>
+ <point x="972" y="1030"/>
+ <point x="819" y="1030" type="curve" smooth="yes"/>
+ <point x="678" y="1030"/>
+ <point x="516" y="969"/>
+ <point x="403" y="874" type="curve" smooth="yes"/>
+ <point x="244" y="739"/>
+ <point x="145" y="535"/>
+ <point x="145" y="331" type="curve" smooth="yes"/>
+ <point x="145" y="105"/>
+ <point x="275" y="-25"/>
+ <point x="391" y="-25" type="curve" smooth="yes"/>
+ <point x="529" y="-25"/>
+ <point x="729" y="134"/>
+ <point x="838" y="300" type="curve"/>
+ <point x="706" y="-185" type="line" smooth="yes"/>
+ <point x="675" y="-299"/>
+ <point x="661" y="-419"/>
+ <point x="661" y="-485" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetpsnames.ufo/glyphs/L_tnS_mR_.glif b/tests/reference/ufo/psfsetpsnames.ufo/glyphs/L_tnS_mR_.glif
new file mode 100644
index 0000000..48a3cc8
--- /dev/null
+++ b/tests/reference/ufo/psfsetpsnames.ufo/glyphs/L_tnS_mR_.glif
@@ -0,0 +1,42 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmR" format="2">
+ <advance width="1021"/>
+ <unicode hex="0072"/>
+ <anchor x="225" y="0" name="H"/>
+ <anchor x="255" y="-100" name="L"/>
+ <anchor x="765" y="1100" name="U"/>
+ <outline>
+ <contour>
+ <point x="390" y="0" type="line"/>
+ <point x="494" y="420" type="line"/>
+ <point x="555" y="557"/>
+ <point x="727" y="773"/>
+ <point x="810" y="773" type="curve" smooth="yes"/>
+ <point x="864" y="773"/>
+ <point x="887" y="737"/>
+ <point x="887" y="678" type="curve" smooth="yes"/>
+ <point x="887" y="662"/>
+ <point x="885" y="644"/>
+ <point x="882" y="624" type="curve"/>
+ <point x="1114" y="658" type="line"/>
+ <point x="1123" y="706"/>
+ <point x="1136" y="752"/>
+ <point x="1136" y="794" type="curve" smooth="yes"/>
+ <point x="1136" y="931"/>
+ <point x="1084" y="1030"/>
+ <point x="963" y="1030" type="curve" smooth="yes"/>
+ <point x="828" y="1030"/>
+ <point x="670" y="883"/>
+ <point x="544" y="716" type="curve"/>
+ <point x="555" y="787"/>
+ <point x="570" y="960"/>
+ <point x="570" y="1010" type="curve"/>
+ <point x="295" y="1010" type="line"/>
+ <point x="295" y="962" type="line" smooth="yes"/>
+ <point x="295" y="894"/>
+ <point x="281" y="689"/>
+ <point x="261" y="609" type="curve" smooth="yes"/>
+ <point x="110" y="0" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetpsnames.ufo/glyphs/L_tnS_mS_.glif b/tests/reference/ufo/psfsetpsnames.ufo/glyphs/L_tnS_mS_.glif
new file mode 100644
index 0000000..568c40a
--- /dev/null
+++ b/tests/reference/ufo/psfsetpsnames.ufo/glyphs/L_tnS_mS_.glif
@@ -0,0 +1,50 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmS" format="2">
+ <advance width="1015"/>
+ <unicode hex="0073"/>
+ <anchor x="455" y="0" name="H"/>
+ <anchor x="530" y="-100" name="L"/>
+ <anchor x="745" y="1100" name="U"/>
+ <outline>
+ <contour>
+ <point x="1058" y="952" type="line"/>
+ <point x="990" y="990"/>
+ <point x="854" y="1030"/>
+ <point x="691" y="1030" type="curve" smooth="yes"/>
+ <point x="457" y="1030"/>
+ <point x="217" y="936"/>
+ <point x="217" y="722" type="curve" smooth="yes"/>
+ <point x="217" y="593"/>
+ <point x="306" y="517"/>
+ <point x="501" y="430" type="curve" smooth="yes"/>
+ <point x="648" y="364"/>
+ <point x="710" y="345"/>
+ <point x="710" y="288" type="curve" smooth="yes"/>
+ <point x="710" y="224"/>
+ <point x="649" y="197"/>
+ <point x="549" y="197" type="curve" smooth="yes"/>
+ <point x="392" y="197"/>
+ <point x="276" y="280"/>
+ <point x="197" y="371" type="curve"/>
+ <point x="72" y="129" type="line"/>
+ <point x="143" y="68"/>
+ <point x="319" y="-25"/>
+ <point x="498" y="-25" type="curve" smooth="yes"/>
+ <point x="767" y="-25"/>
+ <point x="979" y="104"/>
+ <point x="979" y="315" type="curve" smooth="yes"/>
+ <point x="979" y="440"/>
+ <point x="884" y="513"/>
+ <point x="695" y="600" type="curve" smooth="yes"/>
+ <point x="581" y="652"/>
+ <point x="477" y="688"/>
+ <point x="477" y="743" type="curve" smooth="yes"/>
+ <point x="477" y="785"/>
+ <point x="548" y="808"/>
+ <point x="646" y="808" type="curve" smooth="yes"/>
+ <point x="785" y="808"/>
+ <point x="895" y="764"/>
+ <point x="961" y="716" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetpsnames.ufo/glyphs/L_tnS_mT_.glif b/tests/reference/ufo/psfsetpsnames.ufo/glyphs/L_tnS_mT_.glif
new file mode 100644
index 0000000..c6a02c1
--- /dev/null
+++ b/tests/reference/ufo/psfsetpsnames.ufo/glyphs/L_tnS_mT_.glif
@@ -0,0 +1,45 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmT" format="2">
+ <advance width="900"/>
+ <unicode hex="0074"/>
+ <anchor x="470" y="0" name="H"/>
+ <anchor x="520" y="-100" name="L"/>
+ <anchor x="1075" y="1000" name="R"/>
+ <anchor x="640" y="1360" name="U"/>
+ <outline>
+ <contour>
+ <point x="831" y="278" type="line"/>
+ <point x="740" y="230"/>
+ <point x="670" y="204"/>
+ <point x="619" y="204" type="curve" smooth="yes"/>
+ <point x="556" y="204"/>
+ <point x="536" y="250"/>
+ <point x="536" y="318" type="curve" smooth="yes"/>
+ <point x="536" y="347"/>
+ <point x="539" y="380"/>
+ <point x="545" y="415" type="curve" smooth="yes"/>
+ <point x="567" y="549"/>
+ <point x="700" y="1039"/>
+ <point x="767" y="1307" type="curve"/>
+ <point x="487" y="1307" type="line"/>
+ <point x="419" y="1038"/>
+ <point x="265" y="471"/>
+ <point x="243" y="328" type="curve" smooth="yes"/>
+ <point x="239" y="302"/>
+ <point x="237" y="277"/>
+ <point x="237" y="253" type="curve" smooth="yes"/>
+ <point x="237" y="73"/>
+ <point x="351" y="-25"/>
+ <point x="518" y="-25" type="curve" smooth="yes"/>
+ <point x="590" y="-25"/>
+ <point x="703" y="-4"/>
+ <point x="812" y="55" type="curve"/>
+ </contour>
+ <contour>
+ <point x="945" y="797" type="line"/>
+ <point x="995" y="995" type="line"/>
+ <point x="220" y="995" type="line"/>
+ <point x="170" y="797" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetpsnames.ufo/glyphs/L_tnS_mU_.glif b/tests/reference/ufo/psfsetpsnames.ufo/glyphs/L_tnS_mU_.glif
new file mode 100644
index 0000000..5067d38
--- /dev/null
+++ b/tests/reference/ufo/psfsetpsnames.ufo/glyphs/L_tnS_mU_.glif
@@ -0,0 +1,57 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmU" format="2">
+ <advance width="1257"/>
+ <unicode hex="0075"/>
+ <anchor x="455" y="0" name="H"/>
+ <anchor x="530" y="-100" name="L"/>
+ <anchor x="630" y="0" name="O"/>
+ <anchor x="1448" y="1000" name="R"/>
+ <anchor x="830" y="1100" name="U"/>
+ <outline>
+ <contour>
+ <point x="1117" y="0" type="line"/>
+ <point x="1113" y="29"/>
+ <point x="1112" y="62"/>
+ <point x="1112" y="100" type="curve" smooth="yes"/>
+ <point x="1112" y="206"/>
+ <point x="1131" y="341"/>
+ <point x="1157" y="455" type="curve" smooth="yes"/>
+ <point x="1212" y="689"/>
+ <point x="1274" y="905"/>
+ <point x="1282" y="1010" type="curve"/>
+ <point x="993" y="1010" type="line"/>
+ <point x="981" y="889"/>
+ <point x="992" y="918"/>
+ <point x="910" y="595" type="curve"/>
+ <point x="835" y="427"/>
+ <point x="618" y="205"/>
+ <point x="537" y="205" type="curve" smooth="yes"/>
+ <point x="491" y="205"/>
+ <point x="462" y="236"/>
+ <point x="462" y="308" type="curve" smooth="yes"/>
+ <point x="462" y="405"/>
+ <point x="536" y="663"/>
+ <point x="549" y="712" type="curve" smooth="yes"/>
+ <point x="583" y="847"/>
+ <point x="605" y="935"/>
+ <point x="610" y="1010" type="curve"/>
+ <point x="323" y="1010" type="line"/>
+ <point x="312" y="891"/>
+ <point x="296" y="819"/>
+ <point x="264" y="693" type="curve" smooth="yes"/>
+ <point x="191" y="401" type="line" smooth="yes"/>
+ <point x="173" y="330"/>
+ <point x="165" y="267"/>
+ <point x="165" y="214" type="curve" smooth="yes"/>
+ <point x="165" y="55"/>
+ <point x="252" y="-25"/>
+ <point x="381" y="-25" type="curve" smooth="yes"/>
+ <point x="545" y="-25"/>
+ <point x="769" y="160"/>
+ <point x="860" y="295" type="curve"/>
+ <point x="850" y="227"/>
+ <point x="842" y="53"/>
+ <point x="842" y="0" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetpsnames.ufo/glyphs/L_tnS_mV_.glif b/tests/reference/ufo/psfsetpsnames.ufo/glyphs/L_tnS_mV_.glif
new file mode 100644
index 0000000..d7ceb46
--- /dev/null
+++ b/tests/reference/ufo/psfsetpsnames.ufo/glyphs/L_tnS_mV_.glif
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmV" format="2">
+ <advance width="1049"/>
+ <unicode hex="0076"/>
+ <anchor x="505" y="0" name="H"/>
+ <anchor x="410" y="-100" name="L"/>
+ <anchor x="690" y="0" name="O"/>
+ <anchor x="695" y="1100" name="U"/>
+ <outline>
+ <contour>
+ <point x="881" y="1010" type="line"/>
+ <point x="881" y="788"/>
+ <point x="719" y="534"/>
+ <point x="507" y="270" type="curve"/>
+ <point x="516" y="353"/>
+ <point x="521" y="457"/>
+ <point x="521" y="564" type="curve" smooth="yes"/>
+ <point x="521" y="730"/>
+ <point x="507" y="903"/>
+ <point x="472" y="1010" type="curve"/>
+ <point x="195" y="1010" type="line"/>
+ <point x="259" y="758"/>
+ <point x="282" y="509"/>
+ <point x="282" y="262" type="curve" smooth="yes"/>
+ <point x="282" y="174"/>
+ <point x="279" y="87"/>
+ <point x="274" y="0" type="curve"/>
+ <point x="535" y="0" type="line"/>
+ <point x="823" y="314"/>
+ <point x="1159" y="766"/>
+ <point x="1159" y="1010" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetpsnames.ufo/glyphs/L_tnS_mW_.glif b/tests/reference/ufo/psfsetpsnames.ufo/glyphs/L_tnS_mW_.glif
new file mode 100644
index 0000000..02f3211
--- /dev/null
+++ b/tests/reference/ufo/psfsetpsnames.ufo/glyphs/L_tnS_mW_.glif
@@ -0,0 +1,50 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmW" format="2">
+ <advance width="1620"/>
+ <unicode hex="0077"/>
+ <anchor x="700" y="-100" name="L"/>
+ <anchor x="1000" y="1100" name="U"/>
+ <outline>
+ <contour>
+ <point x="850" y="1010" type="line"/>
+ <point x="758" y="793"/>
+ <point x="592" y="496"/>
+ <point x="438" y="242" type="curve"/>
+ <point x="459" y="351"/>
+ <point x="476" y="509"/>
+ <point x="476" y="669" type="curve" smooth="yes"/>
+ <point x="476" y="788"/>
+ <point x="468" y="908"/>
+ <point x="448" y="1010" type="curve"/>
+ <point x="190" y="1010" type="line"/>
+ <point x="230" y="831"/>
+ <point x="236" y="678"/>
+ <point x="236" y="494" type="curve" smooth="yes"/>
+ <point x="236" y="364"/>
+ <point x="228" y="211"/>
+ <point x="209" y="0" type="curve"/>
+ <point x="499" y="0" type="line"/>
+ <point x="624" y="181"/>
+ <point x="838" y="560"/>
+ <point x="901" y="690" type="curve"/>
+ <point x="919" y="477"/>
+ <point x="919" y="212"/>
+ <point x="919" y="0" type="curve"/>
+ <point x="1179" y="0" type="line"/>
+ <point x="1430" y="328"/>
+ <point x="1710" y="775"/>
+ <point x="1710" y="1010" type="curve"/>
+ <point x="1432" y="1010" type="line"/>
+ <point x="1432" y="995" type="line" smooth="yes"/>
+ <point x="1432" y="797"/>
+ <point x="1245" y="435"/>
+ <point x="1106" y="242" type="curve"/>
+ <point x="1108" y="298"/>
+ <point x="1108" y="355"/>
+ <point x="1108" y="411" type="curve" smooth="yes"/>
+ <point x="1108" y="637"/>
+ <point x="1096" y="860"/>
+ <point x="1070" y="1010" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetpsnames.ufo/glyphs/L_tnS_mX_.glif b/tests/reference/ufo/psfsetpsnames.ufo/glyphs/L_tnS_mX_.glif
new file mode 100644
index 0000000..2e620de
--- /dev/null
+++ b/tests/reference/ufo/psfsetpsnames.ufo/glyphs/L_tnS_mX_.glif
@@ -0,0 +1,40 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmX" format="2">
+ <advance width="1104"/>
+ <unicode hex="0078"/>
+ <anchor x="900" y="0" name="H"/>
+ <anchor x="505" y="-100" name="L"/>
+ <anchor x="730" y="1100" name="U"/>
+ <outline>
+ <contour>
+ <point x="1040" y="0" type="line"/>
+ <point x="860" y="133"/>
+ <point x="655" y="882"/>
+ <point x="524" y="1010" type="curve"/>
+ <point x="186" y="1010" type="line"/>
+ <point x="425" y="832"/>
+ <point x="593" y="141"/>
+ <point x="713" y="0" type="curve"/>
+ </contour>
+ <contour>
+ <point x="509" y="572" type="line"/>
+ <point x="291" y="463"/>
+ <point x="62" y="230"/>
+ <point x="35" y="0" type="curve"/>
+ <point x="335" y="0" type="line"/>
+ <point x="336" y="156"/>
+ <point x="470" y="390"/>
+ <point x="658" y="477" type="curve"/>
+ </contour>
+ <contour>
+ <point x="764" y="471" type="line"/>
+ <point x="943" y="591"/>
+ <point x="1197" y="808"/>
+ <point x="1204" y="1010" type="curve"/>
+ <point x="894" y="1010" type="line"/>
+ <point x="894" y="852"/>
+ <point x="773" y="665"/>
+ <point x="616" y="571" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetpsnames.ufo/glyphs/L_tnS_mY_.glif b/tests/reference/ufo/psfsetpsnames.ufo/glyphs/L_tnS_mY_.glif
new file mode 100644
index 0000000..f2ae46b
--- /dev/null
+++ b/tests/reference/ufo/psfsetpsnames.ufo/glyphs/L_tnS_mY_.glif
@@ -0,0 +1,45 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmY" format="2">
+ <advance width="1041"/>
+ <unicode hex="0079"/>
+ <anchor x="810" y="-100" name="L"/>
+ <anchor x="1325" y="1000" name="R"/>
+ <anchor x="640" y="1100" name="U"/>
+ <outline>
+ <contour>
+ <point x="847" y="1010" type="line"/>
+ <point x="851" y="994"/>
+ <point x="852" y="977"/>
+ <point x="852" y="958" type="curve" smooth="yes"/>
+ <point x="852" y="786"/>
+ <point x="713" y="473"/>
+ <point x="596" y="260" type="curve"/>
+ <point x="596" y="478"/>
+ <point x="503" y="877"/>
+ <point x="403" y="1010" type="curve"/>
+ <point x="120" y="1010" type="line"/>
+ <point x="259" y="811"/>
+ <point x="401" y="401"/>
+ <point x="409" y="-18" type="curve"/>
+ <point x="283" y="-207"/>
+ <point x="183" y="-250"/>
+ <point x="114" y="-250" type="curve" smooth="yes"/>
+ <point x="48" y="-250"/>
+ <point x="-33" y="-201"/>
+ <point x="-63" y="-165" type="curve"/>
+ <point x="-195" y="-381" type="line"/>
+ <point x="-136" y="-435"/>
+ <point x="-13" y="-465"/>
+ <point x="78" y="-465" type="curve" smooth="yes"/>
+ <point x="260" y="-465"/>
+ <point x="447" y="-385"/>
+ <point x="684" y="0" type="curve" smooth="yes"/>
+ <point x="919" y="381"/>
+ <point x="1116" y="766"/>
+ <point x="1116" y="960" type="curve" smooth="yes"/>
+ <point x="1116" y="978"/>
+ <point x="1114" y="995"/>
+ <point x="1110" y="1010" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetpsnames.ufo/glyphs/N_onB_reakingH_yphen.glif b/tests/reference/ufo/psfsetpsnames.ufo/glyphs/N_onB_reakingH_yphen.glif
new file mode 100644
index 0000000..cd90adf
--- /dev/null
+++ b/tests/reference/ufo/psfsetpsnames.ufo/glyphs/N_onB_reakingH_yphen.glif
@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="NonBreakingHyphen" format="2">
+ <advance width="875"/>
+ <unicode hex="2011"/>
+ <anchor x="665" y="1100" name="U"/>
+ <outline>
+ <component base="HyphenMinus"/>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetpsnames.ufo/glyphs/N_umS_gn.glif b/tests/reference/ufo/psfsetpsnames.ufo/glyphs/N_umS_gn.glif
new file mode 100644
index 0000000..1d3e5e9
--- /dev/null
+++ b/tests/reference/ufo/psfsetpsnames.ufo/glyphs/N_umS_gn.glif
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="NumSgn" format="2">
+ <advance width="1180"/>
+ <unicode hex="0023"/>
+ <outline>
+ <contour>
+ <point x="667" y="1346" type="line"/>
+ <point x="16" y="99" type="line"/>
+ <point x="256" y="99" type="line"/>
+ <point x="907" y="1346" type="line"/>
+ </contour>
+ <contour>
+ <point x="54" y="421" type="line"/>
+ <point x="1145" y="421" type="line"/>
+ <point x="1197" y="629" type="line"/>
+ <point x="106" y="629" type="line"/>
+ </contour>
+ <contour>
+ <point x="218" y="841" type="line"/>
+ <point x="1309" y="841" type="line"/>
+ <point x="1361" y="1049" type="line"/>
+ <point x="270" y="1049" type="line"/>
+ </contour>
+ <contour>
+ <point x="1142" y="1346" type="line"/>
+ <point x="491" y="99" type="line"/>
+ <point x="731" y="99" type="line"/>
+ <point x="1382" y="1346" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetpsnames.ufo/glyphs/P_ercentS_gn.glif b/tests/reference/ufo/psfsetpsnames.ufo/glyphs/P_ercentS_gn.glif
new file mode 100644
index 0000000..f87ea9f
--- /dev/null
+++ b/tests/reference/ufo/psfsetpsnames.ufo/glyphs/P_ercentS_gn.glif
@@ -0,0 +1,93 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="PercentSgn" format="2">
+ <advance width="1545"/>
+ <unicode hex="0025"/>
+ <outline>
+ <contour>
+ <point x="1375" y="1465" type="line"/>
+ <point x="221" y="-25" type="line"/>
+ <point x="435" y="-25" type="line"/>
+ <point x="1587" y="1465" type="line"/>
+ </contour>
+ <contour>
+ <point x="714" y="1043" type="curve" smooth="yes"/>
+ <point x="669" y="861"/>
+ <point x="611" y="807"/>
+ <point x="535" y="807" type="curve" smooth="yes"/>
+ <point x="486" y="807"/>
+ <point x="461" y="843"/>
+ <point x="461" y="917" type="curve" smooth="yes"/>
+ <point x="461" y="963"/>
+ <point x="471" y="1023"/>
+ <point x="490" y="1099" type="curve" smooth="yes"/>
+ <point x="535" y="1281"/>
+ <point x="580" y="1336"/>
+ <point x="657" y="1336" type="curve" smooth="yes"/>
+ <point x="710" y="1336"/>
+ <point x="739" y="1296"/>
+ <point x="739" y="1212" type="curve" smooth="yes"/>
+ <point x="739" y="1168"/>
+ <point x="731" y="1111"/>
+ </contour>
+ <contour>
+ <point x="926" y="1054" type="curve" smooth="yes"/>
+ <point x="939" y="1107"/>
+ <point x="946" y="1156"/>
+ <point x="946" y="1199" type="curve" smooth="yes"/>
+ <point x="946" y="1374"/>
+ <point x="842" y="1465"/>
+ <point x="694" y="1465" type="curve" smooth="yes"/>
+ <point x="510" y="1465"/>
+ <point x="346" y="1369"/>
+ <point x="277" y="1090" type="curve" smooth="yes"/>
+ <point x="262" y="1031"/>
+ <point x="255" y="979"/>
+ <point x="255" y="933" type="curve" smooth="yes"/>
+ <point x="255" y="761"/>
+ <point x="353" y="678"/>
+ <point x="499" y="678" type="curve" smooth="yes"/>
+ <point x="684" y="678"/>
+ <point x="853" y="762"/>
+ </contour>
+ <contour>
+ <point x="1314" y="337" type="curve" smooth="yes"/>
+ <point x="1268" y="155"/>
+ <point x="1220" y="104"/>
+ <point x="1144" y="104" type="curve" smooth="yes"/>
+ <point x="1093" y="104"/>
+ <point x="1065" y="144"/>
+ <point x="1065" y="227" type="curve" smooth="yes"/>
+ <point x="1065" y="272"/>
+ <point x="1073" y="329"/>
+ <point x="1090" y="398" type="curve" smooth="yes"/>
+ <point x="1136" y="580"/>
+ <point x="1190" y="634"/>
+ <point x="1267" y="634" type="curve" smooth="yes"/>
+ <point x="1317" y="634"/>
+ <point x="1342" y="596"/>
+ <point x="1342" y="520" type="curve" smooth="yes"/>
+ <point x="1342" y="473"/>
+ <point x="1333" y="412"/>
+ </contour>
+ <contour>
+ <point x="1526" y="350" type="curve" smooth="yes"/>
+ <point x="1540" y="406"/>
+ <point x="1546" y="456"/>
+ <point x="1546" y="501" type="curve" smooth="yes"/>
+ <point x="1546" y="673"/>
+ <point x="1450" y="762"/>
+ <point x="1303" y="762" type="curve" smooth="yes"/>
+ <point x="1119" y="762"/>
+ <point x="946" y="665"/>
+ <point x="876" y="386" type="curve" smooth="yes"/>
+ <point x="862" y="331"/>
+ <point x="856" y="281"/>
+ <point x="856" y="237" type="curve" smooth="yes"/>
+ <point x="856" y="60"/>
+ <point x="960" y="-25"/>
+ <point x="1108" y="-25" type="curve" smooth="yes"/>
+ <point x="1293" y="-25"/>
+ <point x="1453" y="58"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetpsnames.ufo/glyphs/P_lusS_gn.glif b/tests/reference/ufo/psfsetpsnames.ufo/glyphs/P_lusS_gn.glif
new file mode 100644
index 0000000..bb54e70
--- /dev/null
+++ b/tests/reference/ufo/psfsetpsnames.ufo/glyphs/P_lusS_gn.glif
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="PlusSgn" format="2">
+ <advance width="1180"/>
+ <unicode hex="002B"/>
+ <outline>
+ <contour>
+ <point x="722" y="1168" type="line"/>
+ <point x="500" y="282" type="line"/>
+ <point x="715" y="282" type="line"/>
+ <point x="936" y="1168" type="line"/>
+ </contour>
+ <contour>
+ <point x="250" y="624" type="line"/>
+ <point x="1140" y="624" type="line"/>
+ <point x="1192" y="832" type="line"/>
+ <point x="302" y="832" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetpsnames.ufo/glyphs/Q_stnM_rk.glif b/tests/reference/ufo/psfsetpsnames.ufo/glyphs/Q_stnM_rk.glif
new file mode 100644
index 0000000..5acaded
--- /dev/null
+++ b/tests/reference/ufo/psfsetpsnames.ufo/glyphs/Q_stnM_rk.glif
@@ -0,0 +1,49 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="QstnMrk" format="2">
+ <advance width="1070"/>
+ <unicode hex="003F"/>
+ <outline>
+ <contour>
+ <point x="703" y="495" type="line"/>
+ <point x="745" y="664"/>
+ <point x="787" y="792"/>
+ <point x="931" y="933" type="curve" smooth="yes"/>
+ <point x="1034" y="1033"/>
+ <point x="1143" y="1118"/>
+ <point x="1143" y="1256" type="curve" smooth="yes"/>
+ <point x="1143" y="1404"/>
+ <point x="1022" y="1525"/>
+ <point x="800" y="1525" type="curve" smooth="yes"/>
+ <point x="675" y="1525"/>
+ <point x="508" y="1455"/>
+ <point x="427" y="1393" type="curve"/>
+ <point x="413" y="1156" type="line"/>
+ <point x="508" y="1235"/>
+ <point x="621" y="1282"/>
+ <point x="721" y="1282" type="curve" smooth="yes"/>
+ <point x="811" y="1282"/>
+ <point x="846" y="1238"/>
+ <point x="846" y="1189" type="curve" smooth="yes"/>
+ <point x="846" y="1109"/>
+ <point x="760" y="1086"/>
+ <point x="650" y="956" type="curve" smooth="yes"/>
+ <point x="564" y="855"/>
+ <point x="490" y="703"/>
+ <point x="438" y="495" type="curve"/>
+ </contour>
+ <contour>
+ <point x="306" y="116" type="curve" smooth="yes"/>
+ <point x="306" y="35"/>
+ <point x="367" y="-25"/>
+ <point x="453" y="-25" type="curve" smooth="yes"/>
+ <point x="571" y="-25"/>
+ <point x="666" y="71"/>
+ <point x="666" y="181" type="curve" smooth="yes"/>
+ <point x="666" y="261"/>
+ <point x="607" y="322"/>
+ <point x="520" y="322" type="curve" smooth="yes"/>
+ <point x="403" y="322"/>
+ <point x="306" y="226"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetpsnames.ufo/glyphs/Q_uotM_rk.glif b/tests/reference/ufo/psfsetpsnames.ufo/glyphs/Q_uotM_rk.glif
new file mode 100644
index 0000000..f33fd18
--- /dev/null
+++ b/tests/reference/ufo/psfsetpsnames.ufo/glyphs/Q_uotM_rk.glif
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="QuotMrk" format="2">
+ <advance width="1065"/>
+ <unicode hex="0022"/>
+ <outline>
+ <contour>
+ <point x="648" y="1035" type="line"/>
+ <point x="687" y="1174"/>
+ <point x="726" y="1326"/>
+ <point x="816" y="1569" type="curve"/>
+ <point x="571" y="1569" type="line"/>
+ <point x="541" y="1326"/>
+ <point x="503" y="1174"/>
+ <point x="473" y="1035" type="curve"/>
+ </contour>
+ <contour>
+ <point x="1008" y="1035" type="line"/>
+ <point x="1047" y="1174"/>
+ <point x="1086" y="1326"/>
+ <point x="1176" y="1569" type="curve"/>
+ <point x="931" y="1569" type="line"/>
+ <point x="901" y="1326"/>
+ <point x="863" y="1174"/>
+ <point x="833" y="1035" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetpsnames.ufo/glyphs/R_everseS_olidus.glif b/tests/reference/ufo/psfsetpsnames.ufo/glyphs/R_everseS_olidus.glif
new file mode 100644
index 0000000..0068c20
--- /dev/null
+++ b/tests/reference/ufo/psfsetpsnames.ufo/glyphs/R_everseS_olidus.glif
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="ReverseSolidus" format="2">
+ <advance width="1060"/>
+ <unicode hex="005C"/>
+ <outline>
+ <contour>
+ <point x="344" y="1584" type="line"/>
+ <point x="719" y="-243" type="line"/>
+ <point x="949" y="-243" type="line"/>
+ <point x="574" y="1584" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetpsnames.ufo/glyphs/R_tC_urlyB_rac.glif b/tests/reference/ufo/psfsetpsnames.ufo/glyphs/R_tC_urlyB_rac.glif
new file mode 100644
index 0000000..726adad
--- /dev/null
+++ b/tests/reference/ufo/psfsetpsnames.ufo/glyphs/R_tC_urlyB_rac.glif
@@ -0,0 +1,47 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="RtCurlyBrac" format="2">
+ <advance width="1020"/>
+ <unicode hex="007D"/>
+ <outline>
+ <contour>
+ <point x="442" y="1395" type="line"/>
+ <point x="513" y="1366"/>
+ <point x="611" y="1344"/>
+ <point x="611" y="1296" type="curve" smooth="yes"/>
+ <point x="611" y="1200"/>
+ <point x="515" y="837"/>
+ <point x="515" y="782" type="curve" smooth="yes"/>
+ <point x="515" y="743"/>
+ <point x="633" y="649"/>
+ <point x="633" y="613" type="curve" smooth="yes"/>
+ <point x="633" y="573"/>
+ <point x="465" y="486"/>
+ <point x="429" y="441" type="curve" smooth="yes"/>
+ <point x="403" y="407"/>
+ <point x="300" y="-59"/>
+ <point x="255" y="-99" type="curve" smooth="yes"/>
+ <point x="230" y="-121"/>
+ <point x="97" y="-158"/>
+ <point x="25" y="-177" type="curve"/>
+ <point x="17" y="-406" type="line"/>
+ <point x="160" y="-379"/>
+ <point x="377" y="-330"/>
+ <point x="439" y="-282" type="curve" smooth="yes"/>
+ <point x="532" y="-211"/>
+ <point x="666" y="374"/>
+ <point x="696" y="406" type="curve" smooth="yes"/>
+ <point x="734" y="446"/>
+ <point x="947" y="559"/>
+ <point x="947" y="616" type="curve" smooth="yes"/>
+ <point x="947" y="676"/>
+ <point x="796" y="783"/>
+ <point x="796" y="819" type="curve" smooth="yes"/>
+ <point x="796" y="880"/>
+ <point x="896" y="1288"/>
+ <point x="896" y="1453" type="curve" smooth="yes"/>
+ <point x="896" y="1529"/>
+ <point x="709" y="1591"/>
+ <point x="549" y="1624" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetpsnames.ufo/glyphs/R_tP_aren.glif b/tests/reference/ufo/psfsetpsnames.ufo/glyphs/R_tP_aren.glif
new file mode 100644
index 0000000..544faff
--- /dev/null
+++ b/tests/reference/ufo/psfsetpsnames.ufo/glyphs/R_tP_aren.glif
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="RtParen" format="2">
+ <advance width="840"/>
+ <unicode hex="0029"/>
+ <outline>
+ <contour>
+ <point x="476" y="1411" type="line"/>
+ <point x="572" y="1290"/>
+ <point x="616" y="1127"/>
+ <point x="616" y="944" type="curve" smooth="yes"/>
+ <point x="616" y="832"/>
+ <point x="599" y="712"/>
+ <point x="569" y="589" type="curve" smooth="yes"/>
+ <point x="491" y="275"/>
+ <point x="333" y="48"/>
+ <point x="75" y="-198" type="curve"/>
+ <point x="163" y="-406" type="line"/>
+ <point x="509" y="-124"/>
+ <point x="743" y="206"/>
+ <point x="844" y="609" type="curve" smooth="yes"/>
+ <point x="876" y="735"/>
+ <point x="891" y="858"/>
+ <point x="891" y="973" type="curve" smooth="yes"/>
+ <point x="891" y="1252"/>
+ <point x="803" y="1487"/>
+ <point x="649" y="1624" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetpsnames.ufo/glyphs/R_tS_qrB_rac.glif b/tests/reference/ufo/psfsetpsnames.ufo/glyphs/R_tS_qrB_rac.glif
new file mode 100644
index 0000000..804527d
--- /dev/null
+++ b/tests/reference/ufo/psfsetpsnames.ufo/glyphs/R_tS_qrB_rac.glif
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="RtSqrBrac" format="2">
+ <advance width="830"/>
+ <unicode hex="005D"/>
+ <outline>
+ <contour>
+ <point x="503" y="-406" type="line"/>
+ <point x="994" y="1584" type="line"/>
+ <point x="474" y="1584" type="line"/>
+ <point x="423" y="1376" type="line"/>
+ <point x="663" y="1376" type="line"/>
+ <point x="275" y="-198" type="line"/>
+ <point x="35" y="-198" type="line"/>
+ <point x="-17" y="-406" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetpsnames.ufo/glyphs/S_emicolon.glif b/tests/reference/ufo/psfsetpsnames.ufo/glyphs/S_emicolon.glif
new file mode 100644
index 0000000..1c9af02
--- /dev/null
+++ b/tests/reference/ufo/psfsetpsnames.ufo/glyphs/S_emicolon.glif
@@ -0,0 +1,38 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="Semicolon" format="2">
+ <advance width="690"/>
+ <unicode hex="003B"/>
+ <outline>
+ <contour>
+ <point x="137" y="49" type="line"/>
+ <point x="297" y="49" type="line"/>
+ <point x="276" y="-34"/>
+ <point x="192" y="-151"/>
+ <point x="59" y="-262" type="curve"/>
+ <point x="187" y="-332" type="line"/>
+ <point x="337" y="-222"/>
+ <point x="539" y="-11"/>
+ <point x="539" y="165" type="curve" smooth="yes"/>
+ <point x="539" y="262"/>
+ <point x="495" y="337"/>
+ <point x="379" y="337" type="curve" smooth="yes"/>
+ <point x="266" y="337"/>
+ <point x="187" y="252"/>
+ <point x="169" y="178" type="curve" smooth="yes"/>
+ </contour>
+ <contour>
+ <point x="319" y="710" type="curve" smooth="yes"/>
+ <point x="319" y="629"/>
+ <point x="380" y="569"/>
+ <point x="466" y="569" type="curve" smooth="yes"/>
+ <point x="584" y="569"/>
+ <point x="679" y="665"/>
+ <point x="679" y="775" type="curve" smooth="yes"/>
+ <point x="679" y="855"/>
+ <point x="620" y="916"/>
+ <point x="533" y="916" type="curve" smooth="yes"/>
+ <point x="416" y="916"/>
+ <point x="319" y="820"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetpsnames.ufo/glyphs/S_olidus.glif b/tests/reference/ufo/psfsetpsnames.ufo/glyphs/S_olidus.glif
new file mode 100644
index 0000000..0bac67c
--- /dev/null
+++ b/tests/reference/ufo/psfsetpsnames.ufo/glyphs/S_olidus.glif
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="Solidus" format="2">
+ <advance width="1060"/>
+ <unicode hex="002F"/>
+ <outline>
+ <contour>
+ <point x="1164" y="1584" type="line"/>
+ <point x="-120" y="-243" type="line"/>
+ <point x="129" y="-243" type="line"/>
+ <point x="1414" y="1584" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetpsnames.ufo/glyphs/S_pace.glif b/tests/reference/ufo/psfsetpsnames.ufo/glyphs/S_pace.glif
new file mode 100644
index 0000000..c49f0f2
--- /dev/null
+++ b/tests/reference/ufo/psfsetpsnames.ufo/glyphs/S_pace.glif
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="Space" format="2">
+ <advance width="530"/>
+ <unicode hex="0020"/>
+ <outline/>
+</glyph>
diff --git a/tests/reference/ufo/psfsetpsnames.ufo/glyphs/T_ilde.glif b/tests/reference/ufo/psfsetpsnames.ufo/glyphs/T_ilde.glif
new file mode 100644
index 0000000..26c105f
--- /dev/null
+++ b/tests/reference/ufo/psfsetpsnames.ufo/glyphs/T_ilde.glif
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="Tilde" format="2">
+ <advance width="1155"/>
+ <unicode hex="007E"/>
+ <outline>
+ <contour>
+ <point x="190" y="342" type="line"/>
+ <point x="207" y="390"/>
+ <point x="249" y="431"/>
+ <point x="327" y="431" type="curve" smooth="yes"/>
+ <point x="502" y="431"/>
+ <point x="676" y="327"/>
+ <point x="906" y="327" type="curve" smooth="yes"/>
+ <point x="1065" y="327"/>
+ <point x="1206" y="507"/>
+ <point x="1238" y="634" type="curve"/>
+ <point x="1093" y="634" type="line"/>
+ <point x="1074" y="588"/>
+ <point x="1031" y="535"/>
+ <point x="948" y="535" type="curve" smooth="yes"/>
+ <point x="712" y="535"/>
+ <point x="580" y="639"/>
+ <point x="359" y="639" type="curve" smooth="yes"/>
+ <point x="203" y="639"/>
+ <point x="75" y="462"/>
+ <point x="45" y="342" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetpsnames.ufo/glyphs/V_ertL_ine.glif b/tests/reference/ufo/psfsetpsnames.ufo/glyphs/V_ertL_ine.glif
new file mode 100644
index 0000000..204ac86
--- /dev/null
+++ b/tests/reference/ufo/psfsetpsnames.ufo/glyphs/V_ertL_ine.glif
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="VertLine" format="2">
+ <advance width="670"/>
+ <unicode hex="007C"/>
+ <outline>
+ <contour>
+ <point x="574" y="1594" type="line"/>
+ <point x="83" y="-396" type="line"/>
+ <point x="293" y="-396" type="line"/>
+ <point x="784" y="1594" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetpsnames.ufo/glyphs/_notdef.glif b/tests/reference/ufo/psfsetpsnames.ufo/glyphs/_notdef.glif
new file mode 100644
index 0000000..a3e9354
--- /dev/null
+++ b/tests/reference/ufo/psfsetpsnames.ufo/glyphs/_notdef.glif
@@ -0,0 +1,18 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name=".notdef" format="2">
+ <advance width="1400"/>
+ <outline>
+ <contour>
+ <point x="100" y="0" type="line"/>
+ <point x="1300" y="0" type="line"/>
+ <point x="1300" y="1800" type="line"/>
+ <point x="100" y="1800" type="line"/>
+ </contour>
+ <contour>
+ <point x="150" y="1750" type="line"/>
+ <point x="1250" y="1750" type="line"/>
+ <point x="1250" y="50" type="line"/>
+ <point x="150" y="50" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetpsnames.ufo/glyphs/_null.glif b/tests/reference/ufo/psfsetpsnames.ufo/glyphs/_null.glif
new file mode 100644
index 0000000..0b9caa6
--- /dev/null
+++ b/tests/reference/ufo/psfsetpsnames.ufo/glyphs/_null.glif
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name=".null" format="2">
+ <outline/>
+</glyph>
diff --git a/tests/reference/ufo/psfsetpsnames.ufo/glyphs/contents.plist b/tests/reference/ufo/psfsetpsnames.ufo/glyphs/contents.plist
new file mode 100644
index 0000000..ad2aa41
--- /dev/null
+++ b/tests/reference/ufo/psfsetpsnames.ufo/glyphs/contents.plist
@@ -0,0 +1,232 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+ <key>.notdef</key>
+ <string>_notdef.glif</string>
+ <key>.null</key>
+ <string>_null.glif</string>
+ <key>Ampersand</key>
+ <string>A_mpersand.glif</string>
+ <key>Apos</key>
+ <string>A_pos.glif</string>
+ <key>Asterisk</key>
+ <string>A_sterisk.glif</string>
+ <key>AtSgn</key>
+ <string>A_tS_gn.glif</string>
+ <key>CircumAccent</key>
+ <string>C_ircumA_ccent.glif</string>
+ <key>Colon</key>
+ <string>C_olon.glif</string>
+ <key>CombAcute</key>
+ <string>C_ombA_cute.glif</string>
+ <key>CombCircum</key>
+ <string>C_ombC_ircum.glif</string>
+ <key>CombDiaer</key>
+ <string>C_ombD_iaer.glif</string>
+ <key>CombGrave</key>
+ <string>C_ombG_rave.glif</string>
+ <key>CombRingAbv</key>
+ <string>C_ombR_ingA_bv.glif</string>
+ <key>CombTilde</key>
+ <string>C_ombT_ilde.glif</string>
+ <key>Comma</key>
+ <string>C_omma.glif</string>
+ <key>DigitEight</key>
+ <string>D_igitE_ight.glif</string>
+ <key>DigitFive</key>
+ <string>D_igitF_ive.glif</string>
+ <key>DigitFour</key>
+ <string>D_igitF_our.glif</string>
+ <key>DigitNine</key>
+ <string>D_igitN_ine.glif</string>
+ <key>DigitOne</key>
+ <string>D_igitO_ne.glif</string>
+ <key>DigitSeven</key>
+ <string>D_igitS_even.glif</string>
+ <key>DigitSix</key>
+ <string>D_igitS_ix.glif</string>
+ <key>DigitThree</key>
+ <string>D_igitT_hree.glif</string>
+ <key>DigitTwo</key>
+ <string>D_igitT_wo.glif</string>
+ <key>DigitZero</key>
+ <string>D_igitZ_ero.glif</string>
+ <key>DollarSgn</key>
+ <string>D_ollarS_gn.glif</string>
+ <key>DottedCirc</key>
+ <string>D_ottedC_irc.glif</string>
+ <key>EqSgn</key>
+ <string>E_qS_gn.glif</string>
+ <key>ExclamationMrk</key>
+ <string>E_xclamationM_rk.glif</string>
+ <key>FullStop</key>
+ <string>F_ullS_top.glif</string>
+ <key>GTSgn</key>
+ <string>G_T_S_gn.glif</string>
+ <key>GraveAccent</key>
+ <string>G_raveA_ccent.glif</string>
+ <key>Hyphen</key>
+ <string>H_yphen.glif</string>
+ <key>HyphenMinus</key>
+ <string>H_yphenM_inus.glif</string>
+ <key>Hyphen_Soft</key>
+ <string>H_yphen_S_oft.glif</string>
+ <key>LTSgn</key>
+ <string>L_T_S_gn.glif</string>
+ <key>LftCurlyBrac</key>
+ <string>L_ftC_urlyB_rac.glif</string>
+ <key>LftParen</key>
+ <string>L_ftP_aren.glif</string>
+ <key>LftSqrBrac</key>
+ <string>L_ftS_qrB_rac.glif</string>
+ <key>LowLine</key>
+ <string>L_owL_ine.glif</string>
+ <key>LtnCapA</key>
+ <string>L_tnC_apA_.glif</string>
+ <key>LtnCapADiaer</key>
+ <string>L_tnC_apA_D_iaer.glif</string>
+ <key>LtnCapB</key>
+ <string>L_tnC_apB_.glif</string>
+ <key>LtnCapC</key>
+ <string>L_tnC_apC_.glif</string>
+ <key>LtnCapD</key>
+ <string>L_tnC_apD_.glif</string>
+ <key>LtnCapE</key>
+ <string>L_tnC_apE_.glif</string>
+ <key>LtnCapF</key>
+ <string>L_tnC_apF_.glif</string>
+ <key>LtnCapG</key>
+ <string>L_tnC_apG_.glif</string>
+ <key>LtnCapH</key>
+ <string>L_tnC_apH_.glif</string>
+ <key>LtnCapI</key>
+ <string>L_tnC_apI_.glif</string>
+ <key>LtnCapJ</key>
+ <string>L_tnC_apJ_.glif</string>
+ <key>LtnCapK</key>
+ <string>L_tnC_apK_.glif</string>
+ <key>LtnCapL</key>
+ <string>L_tnC_apL_.glif</string>
+ <key>LtnCapM</key>
+ <string>L_tnC_apM_.glif</string>
+ <key>LtnCapN</key>
+ <string>L_tnC_apN_.glif</string>
+ <key>LtnCapO</key>
+ <string>L_tnC_apO_.glif</string>
+ <key>LtnCapP</key>
+ <string>L_tnC_apP_.glif</string>
+ <key>LtnCapQ</key>
+ <string>L_tnC_apQ_.glif</string>
+ <key>LtnCapR</key>
+ <string>L_tnC_apR_.glif</string>
+ <key>LtnCapS</key>
+ <string>L_tnC_apS_.glif</string>
+ <key>LtnCapT</key>
+ <string>L_tnC_apT_.glif</string>
+ <key>LtnCapU</key>
+ <string>L_tnC_apU_.glif</string>
+ <key>LtnCapV</key>
+ <string>L_tnC_apV_.glif</string>
+ <key>LtnCapW</key>
+ <string>L_tnC_apW_.glif</string>
+ <key>LtnCapX</key>
+ <string>L_tnC_apX_.glif</string>
+ <key>LtnCapY</key>
+ <string>L_tnC_apY_.glif</string>
+ <key>LtnSmA</key>
+ <string>L_tnS_mA_.glif</string>
+ <key>LtnSmAAcute</key>
+ <string>L_tnS_mA_A_cute.glif</string>
+ <key>LtnSmACircum</key>
+ <string>L_tnS_mA_C_ircum.glif</string>
+ <key>LtnSmADiaer</key>
+ <string>L_tnS_mA_D_iaer.glif</string>
+ <key>LtnSmAGrave</key>
+ <string>L_tnS_mA_G_rave.glif</string>
+ <key>LtnSmARingAbv</key>
+ <string>L_tnS_mA_R_ingA_bv.glif</string>
+ <key>LtnSmATilde</key>
+ <string>L_tnS_mA_T_ilde.glif</string>
+ <key>LtnSmB</key>
+ <string>L_tnS_mB_.glif</string>
+ <key>LtnSmC</key>
+ <string>L_tnS_mC_.glif</string>
+ <key>LtnSmD</key>
+ <string>L_tnS_mD_.glif</string>
+ <key>LtnSmE</key>
+ <string>L_tnS_mE_.glif</string>
+ <key>LtnSmF</key>
+ <string>L_tnS_mF_.glif</string>
+ <key>LtnSmG</key>
+ <string>L_tnS_mG_.glif</string>
+ <key>LtnSmH</key>
+ <string>L_tnS_mH_.glif</string>
+ <key>LtnSmI</key>
+ <string>L_tnS_mI_.glif</string>
+ <key>LtnSmJ</key>
+ <string>L_tnS_mJ_.glif</string>
+ <key>LtnSmK</key>
+ <string>L_tnS_mK_.glif</string>
+ <key>LtnSmL</key>
+ <string>L_tnS_mL_.glif</string>
+ <key>LtnSmM</key>
+ <string>L_tnS_mM_.glif</string>
+ <key>LtnSmN</key>
+ <string>L_tnS_mN_.glif</string>
+ <key>LtnSmO</key>
+ <string>L_tnS_mO_.glif</string>
+ <key>LtnSmP</key>
+ <string>L_tnS_mP_.glif</string>
+ <key>LtnSmQ</key>
+ <string>L_tnS_mQ_.glif</string>
+ <key>LtnSmR</key>
+ <string>L_tnS_mR_.glif</string>
+ <key>LtnSmS</key>
+ <string>L_tnS_mS_.glif</string>
+ <key>LtnSmT</key>
+ <string>L_tnS_mT_.glif</string>
+ <key>LtnSmU</key>
+ <string>L_tnS_mU_.glif</string>
+ <key>LtnSmV</key>
+ <string>L_tnS_mV_.glif</string>
+ <key>LtnSmW</key>
+ <string>L_tnS_mW_.glif</string>
+ <key>LtnSmX</key>
+ <string>L_tnS_mX_.glif</string>
+ <key>LtnSmY</key>
+ <string>L_tnS_mY_.glif</string>
+ <key>NonBreakingHyphen</key>
+ <string>N_onB_reakingH_yphen.glif</string>
+ <key>NumSgn</key>
+ <string>N_umS_gn.glif</string>
+ <key>PercentSgn</key>
+ <string>P_ercentS_gn.glif</string>
+ <key>PlusSgn</key>
+ <string>P_lusS_gn.glif</string>
+ <key>QstnMrk</key>
+ <string>Q_stnM_rk.glif</string>
+ <key>QuotMrk</key>
+ <string>Q_uotM_rk.glif</string>
+ <key>ReverseSolidus</key>
+ <string>R_everseS_olidus.glif</string>
+ <key>RtCurlyBrac</key>
+ <string>R_tC_urlyB_rac.glif</string>
+ <key>RtParen</key>
+ <string>R_tP_aren.glif</string>
+ <key>RtSqrBrac</key>
+ <string>R_tS_qrB_rac.glif</string>
+ <key>Semicolon</key>
+ <string>S_emicolon.glif</string>
+ <key>Solidus</key>
+ <string>S_olidus.glif</string>
+ <key>Space</key>
+ <string>S_pace.glif</string>
+ <key>Tilde</key>
+ <string>T_ilde.glif</string>
+ <key>VertLine</key>
+ <string>V_ertL_ine.glif</string>
+ <key>nonmarkingreturn</key>
+ <string>nonmarkingreturn.glif</string>
+</dict>
+</plist>
diff --git a/tests/reference/ufo/psfsetpsnames.ufo/glyphs/nonmarkingreturn.glif b/tests/reference/ufo/psfsetpsnames.ufo/glyphs/nonmarkingreturn.glif
new file mode 100644
index 0000000..9a63f06
--- /dev/null
+++ b/tests/reference/ufo/psfsetpsnames.ufo/glyphs/nonmarkingreturn.glif
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="nonmarkingreturn" format="2">
+ <advance width="1004"/>
+ <outline/>
+</glyph>
diff --git a/tests/reference/ufo/psfsetpsnames.ufo/layercontents.plist b/tests/reference/ufo/psfsetpsnames.ufo/layercontents.plist
new file mode 100644
index 0000000..42b7482
--- /dev/null
+++ b/tests/reference/ufo/psfsetpsnames.ufo/layercontents.plist
@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<array>
+ <array>
+ <string>public.default</string>
+ <string>glyphs</string>
+ </array>
+</array>
+</plist>
diff --git a/tests/reference/ufo/psfsetpsnames.ufo/lib.plist b/tests/reference/ufo/psfsetpsnames.ufo/lib.plist
new file mode 100644
index 0000000..28d3bd9
--- /dev/null
+++ b/tests/reference/ufo/psfsetpsnames.ufo/lib.plist
@@ -0,0 +1,368 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+ <key>com.schriftgestaltung.Glyphs.fontUserData</key>
+ <dict/>
+ <key>com.schriftgestaltung.appVersion</key>
+ <string>1161</string>
+ <key>com.schriftgestaltung.customName</key>
+ <string>Italic</string>
+ <key>com.schriftgestaltung.customParameter.GSFont.DisplayStrings</key>
+ <string/>
+ <key>com.schriftgestaltung.customParameter.GSFont.disablesAutomaticAlignment</key>
+ <true/>
+ <key>com.schriftgestaltung.customParameter.GSFont.disablesLastChange</key>
+ <true/>
+ <key>com.schriftgestaltung.customParameter.GSFont.useNiceNames</key>
+ <integer>0</integer>
+ <key>com.schriftgestaltung.customParameter.GSFontMaster.customValue</key>
+ <integer>0</integer>
+ <key>com.schriftgestaltung.customParameter.GSFontMaster.customValue1</key>
+ <integer>0</integer>
+ <key>com.schriftgestaltung.customParameter.GSFontMaster.customValue2</key>
+ <integer>0</integer>
+ <key>com.schriftgestaltung.customParameter.GSFontMaster.customValue3</key>
+ <integer>0</integer>
+ <key>com.schriftgestaltung.customParameter.GSFontMaster.iconName</key>
+ <string/>
+ <key>com.schriftgestaltung.customParameter.GSFontMaster.weightValue</key>
+ <integer>700</integer>
+ <key>com.schriftgestaltung.customParameter.GSFontMaster.widthValue</key>
+ <integer>100</integer>
+ <key>com.schriftgestaltung.disablesAutomaticAlignment</key>
+ <true/>
+ <key>com.schriftgestaltung.disablesLastChange</key>
+ <true/>
+ <key>com.schriftgestaltung.fontMasterOrder</key>
+ <integer>1</integer>
+ <key>com.schriftgestaltung.glyphOrder</key>
+ <array>
+ <string>.notdef</string>
+ <string>.null</string>
+ <string>nonmarkingreturn</string>
+ <string>Space</string>
+ <string>ExclamationMrk</string>
+ <string>QuotMrk</string>
+ <string>NumSgn</string>
+ <string>DollarSgn</string>
+ <string>PercentSgn</string>
+ <string>Ampersand</string>
+ <string>Apos</string>
+ <string>LftParen</string>
+ <string>RtParen</string>
+ <string>Asterisk</string>
+ <string>PlusSgn</string>
+ <string>Comma</string>
+ <string>HyphenMinus</string>
+ <string>FullStop</string>
+ <string>Solidus</string>
+ <string>DigitZero</string>
+ <string>DigitOne</string>
+ <string>DigitTwo</string>
+ <string>DigitThree</string>
+ <string>DigitFour</string>
+ <string>DigitFive</string>
+ <string>DigitSix</string>
+ <string>DigitSeven</string>
+ <string>DigitEight</string>
+ <string>DigitNine</string>
+ <string>Colon</string>
+ <string>Semicolon</string>
+ <string>LTSgn</string>
+ <string>EqSgn</string>
+ <string>GTSgn</string>
+ <string>QstnMrk</string>
+ <string>AtSgn</string>
+ <string>LtnCapA</string>
+ <string>LtnCapA.alt</string>
+ <string>LtnCapB</string>
+ <string>LtnCapC</string>
+ <string>LtnCapD</string>
+ <string>LtnCapE</string>
+ <string>LtnCapF</string>
+ <string>LtnCapG</string>
+ <string>LtnCapH</string>
+ <string>LtnCapI</string>
+ <string>LtnCapJ</string>
+ <string>LtnCapK</string>
+ <string>LtnCapL</string>
+ <string>LtnCapM</string>
+ <string>LtnCapN</string>
+ <string>LtnCapO</string>
+ <string>LtnCapP</string>
+ <string>LtnCapQ</string>
+ <string>LtnCapR</string>
+ <string>LtnCapS</string>
+ <string>LtnCapT</string>
+ <string>LtnCapU</string>
+ <string>LtnCapV</string>
+ <string>LtnCapW</string>
+ <string>LtnCapX</string>
+ <string>LtnCapY</string>
+ <string>LftSqrBrac</string>
+ <string>ReverseSolidus</string>
+ <string>RtSqrBrac</string>
+ <string>CircumAccent</string>
+ <string>LowLine</string>
+ <string>GraveAccent</string>
+ <string>LtnSmA</string>
+ <string>LtnSmB</string>
+ <string>LtnSmC</string>
+ <string>LtnSmD</string>
+ <string>LtnSmE</string>
+ <string>LtnSmF</string>
+ <string>LtnSmG</string>
+ <string>LtnSmH</string>
+ <string>LtnSmI</string>
+ <string>LtnSmJ</string>
+ <string>LtnSmK</string>
+ <string>LtnSmL</string>
+ <string>LtnSmM</string>
+ <string>LtnSmN</string>
+ <string>LtnSmO</string>
+ <string>LtnSmP</string>
+ <string>LtnSmQ</string>
+ <string>LtnSmR</string>
+ <string>LtnSmS</string>
+ <string>LtnSmT</string>
+ <string>LtnSmU</string>
+ <string>LtnSmV</string>
+ <string>LtnSmW</string>
+ <string>LtnSmX</string>
+ <string>LtnSmY</string>
+ <string>LftCurlyBrac</string>
+ <string>VertLine</string>
+ <string>RtCurlyBrac</string>
+ <string>Tilde</string>
+ <string>LtnCapADiaer</string>
+ <string>LtnSmAAcute</string>
+ <string>LtnSmAGrave</string>
+ <string>LtnSmACircum</string>
+ <string>LtnSmADiaer</string>
+ <string>LtnSmATilde</string>
+ <string>LtnSmARingAbv</string>
+ <string>DottedCirc</string>
+ <string>Hyphen</string>
+ <string>NonBreakingHyphen</string>
+ <string>Hyphen_Soft</string>
+ <string>CombAcute</string>
+ <string>CombGrave</string>
+ <string>CombCircum</string>
+ <string>CombTilde</string>
+ <string>CombDiaer</string>
+ <string>CombRingAbv</string>
+ </array>
+ <key>com.schriftgestaltung.keyboardIncrement</key>
+ <integer>1</integer>
+ <key>com.schriftgestaltung.weight</key>
+ <string>Bold</string>
+ <key>com.schriftgestaltung.weightValue</key>
+ <integer>700</integer>
+ <key>com.schriftgestaltung.width</key>
+ <string>Regular</string>
+ <key>com.schriftgestaltung.widthValue</key>
+ <integer>100</integer>
+ <key>org.sil.lcg.toneLetters</key>
+ <dict>
+ <key>contourWidth</key>
+ <integer>540</integer>
+ <key>dotSize</key>
+ <integer>280</integer>
+ <key>dotSpacing</key>
+ <integer>200</integer>
+ <key>glyphDepth</key>
+ <integer>-25</integer>
+ <key>glyphHeight</key>
+ <integer>1600</integer>
+ <key>italicAngle</key>
+ <integer>14</integer>
+ <key>marginDotLeft</key>
+ <integer>100</integer>
+ <key>marginDotRight</key>
+ <integer>140</integer>
+ <key>marginFlatLeft</key>
+ <integer>100</integer>
+ <key>marginFlatRight</key>
+ <integer>140</integer>
+ <key>marginPointLeft</key>
+ <integer>80</integer>
+ <key>marginPointRight</key>
+ <integer>120</integer>
+ <key>strokeThickness</key>
+ <integer>200</integer>
+ </dict>
+ <key>public.glyphOrder</key>
+ <array>
+ <string>.notdef</string>
+ <string>.null</string>
+ <string>nonmarkingreturn</string>
+ <string>Space</string>
+ <string>ExclamationMrk</string>
+ <string>QuotMrk</string>
+ <string>NumSgn</string>
+ <string>DollarSgn</string>
+ <string>PercentSgn</string>
+ <string>Ampersand</string>
+ <string>Apos</string>
+ <string>LftParen</string>
+ <string>RtParen</string>
+ <string>Asterisk</string>
+ <string>PlusSgn</string>
+ <string>Comma</string>
+ <string>HyphenMinus</string>
+ <string>FullStop</string>
+ <string>Solidus</string>
+ <string>DigitZero</string>
+ <string>DigitOne</string>
+ <string>DigitTwo</string>
+ <string>DigitThree</string>
+ <string>DigitFour</string>
+ <string>DigitFive</string>
+ <string>DigitSix</string>
+ <string>DigitSeven</string>
+ <string>DigitEight</string>
+ <string>DigitNine</string>
+ <string>Colon</string>
+ <string>Semicolon</string>
+ <string>LTSgn</string>
+ <string>EqSgn</string>
+ <string>GTSgn</string>
+ <string>QstnMrk</string>
+ <string>AtSgn</string>
+ <string>LtnCapA</string>
+ <string>LtnCapA.alt</string>
+ <string>LtnCapB</string>
+ <string>LtnCapC</string>
+ <string>LtnCapD</string>
+ <string>LtnCapE</string>
+ <string>LtnCapF</string>
+ <string>LtnCapG</string>
+ <string>LtnCapH</string>
+ <string>LtnCapI</string>
+ <string>LtnCapJ</string>
+ <string>LtnCapK</string>
+ <string>LtnCapL</string>
+ <string>LtnCapM</string>
+ <string>LtnCapN</string>
+ <string>LtnCapO</string>
+ <string>LtnCapP</string>
+ <string>LtnCapQ</string>
+ <string>LtnCapR</string>
+ <string>LtnCapS</string>
+ <string>LtnCapT</string>
+ <string>LtnCapU</string>
+ <string>LtnCapV</string>
+ <string>LtnCapW</string>
+ <string>LtnCapX</string>
+ <string>LtnCapY</string>
+ <string>LftSqrBrac</string>
+ <string>ReverseSolidus</string>
+ <string>RtSqrBrac</string>
+ <string>CircumAccent</string>
+ <string>LowLine</string>
+ <string>GraveAccent</string>
+ <string>LtnSmA</string>
+ <string>LtnSmB</string>
+ <string>LtnSmC</string>
+ <string>LtnSmD</string>
+ <string>LtnSmE</string>
+ <string>LtnSmF</string>
+ <string>LtnSmG</string>
+ <string>LtnSmH</string>
+ <string>LtnSmI</string>
+ <string>LtnSmJ</string>
+ <string>LtnSmK</string>
+ <string>LtnSmL</string>
+ <string>LtnSmM</string>
+ <string>LtnSmN</string>
+ <string>LtnSmO</string>
+ <string>LtnSmP</string>
+ <string>LtnSmQ</string>
+ <string>LtnSmR</string>
+ <string>LtnSmS</string>
+ <string>LtnSmT</string>
+ <string>LtnSmU</string>
+ <string>LtnSmV</string>
+ <string>LtnSmW</string>
+ <string>LtnSmX</string>
+ <string>LtnSmY</string>
+ <string>LftCurlyBrac</string>
+ <string>VertLine</string>
+ <string>RtCurlyBrac</string>
+ <string>Tilde</string>
+ <string>LtnCapADiaer</string>
+ <string>LtnSmAAcute</string>
+ <string>LtnSmAGrave</string>
+ <string>LtnSmACircum</string>
+ <string>LtnSmADiaer</string>
+ <string>LtnSmATilde</string>
+ <string>LtnSmARingAbv</string>
+ <string>DottedCirc</string>
+ <string>Hyphen</string>
+ <string>NonBreakingHyphen</string>
+ <string>Hyphen_Soft</string>
+ <string>CombAcute</string>
+ <string>CombGrave</string>
+ <string>CombCircum</string>
+ <string>CombTilde</string>
+ <string>CombDiaer</string>
+ <string>CombRingAbv</string>
+ </array>
+ <key>public.postscriptNames</key>
+ <dict>
+ <key>AcuteAccent</key>
+ <string>acute</string>
+ <key>Bullet</key>
+ <string>bullet</string>
+ <key>BulletOperator</key>
+ <string>uni2219</string>
+ <key>CircumAccent</key>
+ <string>asciicircum</string>
+ <key>CombAcute</key>
+ <string>acutecomb</string>
+ <key>DblAcuteAccent</key>
+ <string>hungarumlaut</string>
+ <key>HyphenMinus</key>
+ <string>hyphen</string>
+ <key>LtnCapAAcute</key>
+ <string>Aacute</string>
+ <key>LtnCapEAcute</key>
+ <string>Eacute</string>
+ <key>LtnCapIAcute</key>
+ <string>Iacute</string>
+ <key>LtnCapOAcute</key>
+ <string>Oacute</string>
+ <key>LtnCapUAcute</key>
+ <string>Uacute</string>
+ <key>LtnCapYAcute</key>
+ <string>Yacute</string>
+ <key>LtnSmAAcute</key>
+ <string>aacute</string>
+ <key>LtnSmEAcute</key>
+ <string>eacute</string>
+ <key>LtnSmIAcute</key>
+ <string>iacute</string>
+ <key>LtnSmOAcute</key>
+ <string>oacute</string>
+ <key>LtnSmUAcute</key>
+ <string>uacute</string>
+ <key>LtnSmYAcute</key>
+ <string>yacute</string>
+ <key>ModCircumAccent</key>
+ <string>circumflex</string>
+ <key>ReverseSolidus</key>
+ <string>backslash</string>
+ <key>SupOne</key>
+ <string>onesuperior</string>
+ <key>SupThree</key>
+ <string>threesuperior</string>
+ <key>VulgFracOneHalf</key>
+ <string>onehalf</string>
+ <key>VulgFracOneQuarter</key>
+ <string>onequarter</string>
+ <key>VulgFracThreeQuarters</key>
+ <string>threequarters</string>
+ </dict>
+</dict>
+</plist>
diff --git a/tests/reference/ufo/psfsetpsnames.ufo/metainfo.plist b/tests/reference/ufo/psfsetpsnames.ufo/metainfo.plist
new file mode 100644
index 0000000..aa10c5c
--- /dev/null
+++ b/tests/reference/ufo/psfsetpsnames.ufo/metainfo.plist
@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+ <key>creator</key>
+ <string>org.sil.scripts.pysilfont</string>
+ <key>formatVersion</key>
+ <integer>3</integer>
+</dict>
+</plist>
diff --git a/tests/reference/ufo/psfsetunicodes.lg b/tests/reference/ufo/psfsetunicodes.lg
new file mode 100644
index 0000000..c1dac72
--- /dev/null
+++ b/tests/reference/ufo/psfsetunicodes.lg
@@ -0,0 +1,149 @@
+2021-06-29 14:42:23 Progress: Running: psfsetunicodes tests/input/font-psf-test/source/PsfTest-Italic.ufo -i tests/input/psfsetunicodes.csv -l local/testresults/ufo/psfsetunicodes.log -p loglevel=v -p checkfix=fix
+2021-06-29 14:42:23 Progress: Opening file for input: tests/input/psfsetunicodes.csv
+2021-06-29 14:42:23 Progress: Reading UFO: tests/input/font-psf-test/source/PsfTest-Italic.ufo
+2021-06-29 14:42:23 Info: Processing Glyph Layer 0: public.defaultglyphs
+2021-06-29 14:42:23 Progress: Checking fontinfo.plist metadata
+2021-06-29 14:42:23 Warning: openTypeOS2FamilyClass removed from fontinfo. Old value: [0, 0]
+2021-06-29 14:42:23 Info: Types: Old - list, New - NoneType
+2021-06-29 14:42:23 Warning: year removed from fontinfo. Old value: 2021
+2021-06-29 14:42:23 Info: Types: Old - int, New - NoneType
+2021-06-29 14:42:23 Warning: capHeight updated Old value: 1485.3, new value: 1485
+2021-06-29 14:42:23 Info: Types: Old - float, New - int
+2021-06-29 14:42:23 Warning: styleMapFamilyName uppdated Old value: Psf test, new value: Psf Test
+2021-06-29 14:42:23 Info: Types: Old - string, New - string
+2021-06-29 14:42:23 Warning: openTypeOS2TypoLineGap updated Old value: 1, new value: 0
+2021-06-29 14:42:23 Info: Types: Old - int, New - int
+2021-06-29 14:42:23 Warning: openTypeOS2Selection added New value: [7]
+2021-06-29 14:42:23 Info: Types: Old - NoneType, New - list
+2021-06-29 14:42:23 Warning: openTypeNamePreferredFamilyName updated Old value: Psf Testing, new value: Psf Test
+2021-06-29 14:42:23 Info: Types: Old - string, New - string
+2021-06-29 14:42:23 Progress: Checking lib.plist metadata
+2021-06-29 14:42:23 Warning: com.schriftgestaltung.disablesAutomaticAlignment deleted - obsolete key Old value: True
+2021-06-29 14:42:23 Info: Types: Old - bool, New - NoneType
+2021-06-29 14:42:23 Warning: com.schriftgestaltung.disablesLastChange deleted - obsolete key Old value: True
+2021-06-29 14:42:23 Info: Types: Old - bool, New - NoneType
+2021-06-29 14:42:23 Progress: Check & fix results:- Errors: 0, Changes made: 9, Other warnings: 0
+2021-06-29 14:42:23 Progress: See log file for details
+2021-06-29 14:42:23 Info: Glyph 'Notthere' not in font; line 3 ignored.
+2021-06-29 14:42:23 Progress: Processing font for output
+2021-06-29 14:42:23 Progress: Output UFO already exists - reading for comparison
+2021-06-29 14:42:23 Progress: Writing font to local/testresults/ufo/psfsetunicodes.ufo
+2021-06-29 14:42:23 Info: Processing glyphs directory
+2021-06-29 14:42:23 Verbose: A_mpersand.glif
+2021-06-29 14:42:23 Verbose: A_pos.glif
+2021-06-29 14:42:23 Verbose: A_sterisk.glif
+2021-06-29 14:42:23 Verbose: A_tS_gn.glif
+2021-06-29 14:42:23 Verbose: C_ircumA_ccent.glif
+2021-06-29 14:42:23 Verbose: C_olon.glif
+2021-06-29 14:42:23 Verbose: C_ombA_cute.glif
+2021-06-29 14:42:23 Verbose: C_ombC_ircum.glif
+2021-06-29 14:42:23 Verbose: C_ombD_iaer.glif
+2021-06-29 14:42:23 Verbose: C_ombG_rave.glif
+2021-06-29 14:42:23 Verbose: C_ombR_ingA_bv.glif
+2021-06-29 14:42:23 Verbose: C_ombT_ilde.glif
+2021-06-29 14:42:23 Verbose: C_omma.glif
+2021-06-29 14:42:23 Verbose: D_igitE_ight.glif
+2021-06-29 14:42:23 Verbose: D_igitF_ive.glif
+2021-06-29 14:42:23 Verbose: D_igitF_our.glif
+2021-06-29 14:42:23 Verbose: D_igitN_ine.glif
+2021-06-29 14:42:23 Verbose: D_igitO_ne.glif
+2021-06-29 14:42:23 Verbose: D_igitS_even.glif
+2021-06-29 14:42:23 Verbose: D_igitS_ix.glif
+2021-06-29 14:42:23 Verbose: D_igitT_hree.glif
+2021-06-29 14:42:23 Verbose: D_igitT_wo.glif
+2021-06-29 14:42:23 Verbose: D_igitZ_ero.glif
+2021-06-29 14:42:23 Verbose: D_ollarS_gn.glif
+2021-06-29 14:42:23 Verbose: D_ottedC_irc.glif
+2021-06-29 14:42:23 Verbose: E_qS_gn.glif
+2021-06-29 14:42:23 Verbose: E_xclamationM_rk.glif
+2021-06-29 14:42:23 Verbose: F_ullS_top.glif
+2021-06-29 14:42:23 Verbose: G_T_S_gn.glif
+2021-06-29 14:42:23 Verbose: G_raveA_ccent.glif
+2021-06-29 14:42:23 Verbose: H_yphen.glif
+2021-06-29 14:42:23 Verbose: H_yphenM_inus.glif
+2021-06-29 14:42:23 Verbose: H_yphen_S_oft.glif
+2021-06-29 14:42:23 Verbose: L_T_S_gn.glif
+2021-06-29 14:42:23 Verbose: L_ftC_urlyB_rac.glif
+2021-06-29 14:42:23 Verbose: L_ftP_aren.glif
+2021-06-29 14:42:23 Verbose: L_ftS_qrB_rac.glif
+2021-06-29 14:42:23 Verbose: L_owL_ine.glif
+2021-06-29 14:42:23 Verbose: L_tnC_apA_.glif
+2021-06-29 14:42:23 Verbose: L_tnC_apA_D_iaer.glif
+2021-06-29 14:42:23 Verbose: L_tnC_apB_.glif
+2021-06-29 14:42:23 Verbose: L_tnC_apC_.glif
+2021-06-29 14:42:23 Verbose: L_tnC_apD_.glif
+2021-06-29 14:42:23 Verbose: L_tnC_apE_.glif
+2021-06-29 14:42:23 Verbose: L_tnC_apF_.glif
+2021-06-29 14:42:23 Verbose: L_tnC_apG_.glif
+2021-06-29 14:42:23 Verbose: L_tnC_apH_.glif
+2021-06-29 14:42:23 Verbose: L_tnC_apI_.glif
+2021-06-29 14:42:23 Verbose: L_tnC_apJ_.glif
+2021-06-29 14:42:23 Verbose: L_tnC_apK_.glif
+2021-06-29 14:42:23 Verbose: L_tnC_apL_.glif
+2021-06-29 14:42:23 Verbose: L_tnC_apM_.glif
+2021-06-29 14:42:23 Verbose: L_tnC_apN_.glif
+2021-06-29 14:42:23 Verbose: L_tnC_apO_.glif
+2021-06-29 14:42:23 Verbose: L_tnC_apP_.glif
+2021-06-29 14:42:23 Verbose: L_tnC_apQ_.glif
+2021-06-29 14:42:23 Verbose: L_tnC_apR_.glif
+2021-06-29 14:42:23 Verbose: L_tnC_apS_.glif
+2021-06-29 14:42:23 Verbose: L_tnC_apT_.glif
+2021-06-29 14:42:23 Verbose: L_tnC_apU_.glif
+2021-06-29 14:42:23 Verbose: L_tnC_apV_.glif
+2021-06-29 14:42:23 Verbose: L_tnC_apW_.glif
+2021-06-29 14:42:23 Verbose: L_tnC_apX_.glif
+2021-06-29 14:42:23 Verbose: L_tnC_apY_.glif
+2021-06-29 14:42:23 Verbose: L_tnS_mA_.glif
+2021-06-29 14:42:23 Verbose: L_tnS_mA_A_cute.glif
+2021-06-29 14:42:23 Verbose: L_tnS_mA_C_ircum.glif
+2021-06-29 14:42:23 Verbose: L_tnS_mA_D_iaer.glif
+2021-06-29 14:42:23 Verbose: L_tnS_mA_G_rave.glif
+2021-06-29 14:42:23 Verbose: L_tnS_mA_R_ingA_bv.glif
+2021-06-29 14:42:23 Verbose: L_tnS_mA_T_ilde.glif
+2021-06-29 14:42:23 Verbose: L_tnS_mB_.glif
+2021-06-29 14:42:23 Verbose: L_tnS_mC_.glif
+2021-06-29 14:42:23 Verbose: L_tnS_mD_.glif
+2021-06-29 14:42:23 Verbose: L_tnS_mE_.glif
+2021-06-29 14:42:23 Verbose: L_tnS_mF_.glif
+2021-06-29 14:42:23 Verbose: L_tnS_mG_.glif
+2021-06-29 14:42:23 Verbose: L_tnS_mH_.glif
+2021-06-29 14:42:23 Verbose: L_tnS_mI_.glif
+2021-06-29 14:42:23 Verbose: L_tnS_mJ_.glif
+2021-06-29 14:42:23 Verbose: L_tnS_mK_.glif
+2021-06-29 14:42:23 Verbose: L_tnS_mL_.glif
+2021-06-29 14:42:23 Verbose: L_tnS_mM_.glif
+2021-06-29 14:42:23 Verbose: L_tnS_mN_.glif
+2021-06-29 14:42:23 Verbose: L_tnS_mO_.glif
+2021-06-29 14:42:23 Verbose: L_tnS_mP_.glif
+2021-06-29 14:42:23 Verbose: L_tnS_mQ_.glif
+2021-06-29 14:42:23 Verbose: L_tnS_mR_.glif
+2021-06-29 14:42:23 Verbose: L_tnS_mS_.glif
+2021-06-29 14:42:23 Verbose: L_tnS_mT_.glif
+2021-06-29 14:42:23 Verbose: L_tnS_mU_.glif
+2021-06-29 14:42:23 Verbose: L_tnS_mV_.glif
+2021-06-29 14:42:23 Verbose: L_tnS_mW_.glif
+2021-06-29 14:42:23 Verbose: L_tnS_mX_.glif
+2021-06-29 14:42:23 Verbose: L_tnS_mY_.glif
+2021-06-29 14:42:23 Verbose: N_onB_reakingH_yphen.glif
+2021-06-29 14:42:23 Verbose: N_umS_gn.glif
+2021-06-29 14:42:23 Verbose: P_ercentS_gn.glif
+2021-06-29 14:42:23 Verbose: P_lusS_gn.glif
+2021-06-29 14:42:23 Verbose: Q_stnM_rk.glif
+2021-06-29 14:42:23 Verbose: Q_uotM_rk.glif
+2021-06-29 14:42:23 Verbose: R_everseS_olidus.glif
+2021-06-29 14:42:23 Verbose: R_tC_urlyB_rac.glif
+2021-06-29 14:42:23 Verbose: R_tP_aren.glif
+2021-06-29 14:42:23 Verbose: R_tS_qrB_rac.glif
+2021-06-29 14:42:23 Verbose: S_emicolon.glif
+2021-06-29 14:42:23 Verbose: S_olidus.glif
+2021-06-29 14:42:23 Verbose: S_pace.glif
+2021-06-29 14:42:23 Verbose: T_ilde.glif
+2021-06-29 14:42:23 Verbose: V_ertL_ine.glif
+2021-06-29 14:42:23 Verbose: _notdef.glif
+2021-06-29 14:42:23 Verbose: _null.glif
+2021-06-29 14:42:23 Verbose: contents.plist
+2021-06-29 14:42:23 Verbose: nonmarkingreturn.glif
+2021-06-29 14:42:23 Verbose: fontinfo.plist
+2021-06-29 14:42:23 Verbose: layercontents.plist
+2021-06-29 14:42:23 Verbose: lib.plist
+2021-06-29 14:42:23 Verbose: metainfo.plist
diff --git a/tests/reference/ufo/psfsetunicodes.ufo/fontinfo.plist b/tests/reference/ufo/psfsetunicodes.ufo/fontinfo.plist
new file mode 100644
index 0000000..92c6d24
--- /dev/null
+++ b/tests/reference/ufo/psfsetunicodes.ufo/fontinfo.plist
@@ -0,0 +1,240 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+ <key>ascender</key>
+ <integer>2100</integer>
+ <key>capHeight</key>
+ <integer>1485</integer>
+ <key>copyright</key>
+ <string>Copyright (c) 2004-2021 SIL International</string>
+ <key>descender</key>
+ <integer>-550</integer>
+ <key>familyName</key>
+ <string>Psf Test</string>
+ <key>italicAngle</key>
+ <integer>-14</integer>
+ <key>openTypeHeadCreated</key>
+ <string>2021/06/29 14:43:52</string>
+ <key>openTypeHheaAscender</key>
+ <integer>2100</integer>
+ <key>openTypeHheaDescender</key>
+ <integer>-550</integer>
+ <key>openTypeHheaLineGap</key>
+ <integer>0</integer>
+ <key>openTypeNameDescription</key>
+ <string>Copyright (c) 2004-2021 SIL International</string>
+ <key>openTypeNameDesigner</key>
+ <string>Victor Gaultney, Annie Olsen, Julie Remington, Don Collingsworth, Eric Hays, Becca Hirsbrunner</string>
+ <key>openTypeNameDesignerURL</key>
+ <string>http://scripts.sil.org/</string>
+ <key>openTypeNameLicense</key>
+ <string>Copyright (c) 2004-2021 SIL International (http://www.sil.org/) with Reserved Font Names "Andika" and "SIL".
+
+This Font Software is licensed under the SIL Open Font License, Version 1.1. This license is copied below, and is also available with a FAQ at: http://scripts.sil.org/OFL
+
+
+-----------------------------------------------------------
+SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007
+-----------------------------------------------------------
+
+PREAMBLE
+The goals of the Open Font License (OFL) are to stimulate worldwide development of collaborative font projects, to support the font creation efforts of academic and linguistic communities, and to provide a free and open framework in which fonts may be shared and improved in partnership with others.
+
+The OFL allows the licensed fonts to be used, studied, modified and redistributed freely as long as they are not sold by themselves. The fonts, including any derivative works, can be bundled, embedded, redistributed and/or sold with any software provided that any reserved names are not used by derivative works. The fonts and derivatives, however, cannot be released under any other type of license. The requirement for fonts to remain under this license does not apply to any document created using the fonts or their derivatives.
+
+DEFINITIONS
+"Font Software" refers to the set of files released by the Copyright Holder(s) under this license and clearly marked as such. This may include source files, build scripts and documentation.
+
+"Reserved Font Name" refers to any names specified as such after the copyright statement(s).
+
+"Original Version" refers to the collection of Font Software components as distributed by the Copyright Holder(s).
+
+"Modified Version" refers to any derivative made by adding to, deleting, or substituting -- in part or in whole -- any of the components of the Original Version, by changing formats or by porting the Font Software to a new environment.
+
+"Author" refers to any designer, engineer, programmer, technical writer or other person who contributed to the Font Software.
+
+PERMISSION &amp; CONDITIONS
+Permission is hereby granted, free of charge, to any person obtaining a copy of the Font Software, to use, study, copy, merge, embed, modify, redistribute, and sell modified and unmodified copies of the Font Software, subject to the following conditions:
+
+1) Neither the Font Software nor any of its individual components, in Original or Modified Versions, may be sold by itself.
+
+2) Original or Modified Versions of the Font Software may be bundled, redistributed and/or sold with any software, provided that each copy contains the above copyright notice and this license. These can be included either as stand-alone text files, human-readable headers or in the appropriate machine-readable metadata fields within text or binary files as long as those fields can be easily viewed by the user.
+
+3) No Modified Version of the Font Software may use the Reserved Font Name(s) unless explicit written permission is granted by the corresponding Copyright Holder. This restriction only applies to the primary font name as presented to the users.
+
+4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font Software shall not be used to promote, endorse or advertise any Modified Version, except to acknowledge the contribution(s) of the Copyright Holder(s) and the Author(s) or with their explicit written permission.
+
+5) The Font Software, modified or unmodified, in part or in whole, must be distributed entirely under this license, and must not be distributed under any other license. The requirement for fonts to remain under this license does not apply to any document created using the Font Software.
+
+TERMINATION
+This license becomes null and void if any of the above conditions are not met.
+
+DISCLAIMER
+THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM OTHER DEALINGS IN THE FONT SOFTWARE.</string>
+ <key>openTypeNameLicenseURL</key>
+ <string>http://scripts.sil.org/OFL</string>
+ <key>openTypeNameManufacturer</key>
+ <string>SIL International</string>
+ <key>openTypeNameManufacturerURL</key>
+ <string>http://scripts.sil.org</string>
+ <key>openTypeNamePreferredFamilyName</key>
+ <string>Psf Test</string>
+ <key>openTypeNamePreferredSubfamilyName</key>
+ <string>Italic</string>
+ <key>openTypeNameUniqueID</key>
+ <string>SIL International: Psf Test Italic: 2022</string>
+ <key>openTypeNameVersion</key>
+ <string>Version 5.550</string>
+ <key>openTypeOS2CodePageRanges</key>
+ <array>
+ <integer>0</integer>
+ <integer>1</integer>
+ <integer>2</integer>
+ <integer>4</integer>
+ <integer>7</integer>
+ <integer>8</integer>
+ </array>
+ <key>openTypeOS2Panose</key>
+ <array>
+ <integer>2</integer>
+ <integer>0</integer>
+ <integer>0</integer>
+ <integer>0</integer>
+ <integer>0</integer>
+ <integer>0</integer>
+ <integer>0</integer>
+ <integer>0</integer>
+ <integer>0</integer>
+ <integer>0</integer>
+ </array>
+ <key>openTypeOS2Selection</key>
+ <array>
+ <integer>7</integer>
+ </array>
+ <key>openTypeOS2StrikeoutPosition</key>
+ <integer>700</integer>
+ <key>openTypeOS2StrikeoutSize</key>
+ <integer>100</integer>
+ <key>openTypeOS2SubscriptXOffset</key>
+ <integer>0</integer>
+ <key>openTypeOS2SubscriptXSize</key>
+ <integer>1433</integer>
+ <key>openTypeOS2SubscriptYOffset</key>
+ <integer>286</integer>
+ <key>openTypeOS2SubscriptYSize</key>
+ <integer>1331</integer>
+ <key>openTypeOS2SuperscriptXOffset</key>
+ <integer>0</integer>
+ <key>openTypeOS2SuperscriptXSize</key>
+ <integer>1433</integer>
+ <key>openTypeOS2SuperscriptYOffset</key>
+ <integer>976</integer>
+ <key>openTypeOS2SuperscriptYSize</key>
+ <integer>1331</integer>
+ <key>openTypeOS2Type</key>
+ <array/>
+ <key>openTypeOS2TypoAscender</key>
+ <integer>2100</integer>
+ <key>openTypeOS2TypoDescender</key>
+ <integer>-550</integer>
+ <key>openTypeOS2TypoLineGap</key>
+ <integer>0</integer>
+ <key>openTypeOS2UnicodeRanges</key>
+ <array>
+ <integer>0</integer>
+ <integer>1</integer>
+ <integer>6</integer>
+ <integer>7</integer>
+ <integer>31</integer>
+ <integer>33</integer>
+ <integer>35</integer>
+ <integer>36</integer>
+ <integer>37</integer>
+ <integer>38</integer>
+ <integer>39</integer>
+ <integer>40</integer>
+ <integer>45</integer>
+ <integer>46</integer>
+ <integer>47</integer>
+ <integer>57</integer>
+ <integer>60</integer>
+ <integer>62</integer>
+ <integer>64</integer>
+ <integer>67</integer>
+ <integer>69</integer>
+ <integer>89</integer>
+ </array>
+ <key>openTypeOS2VendorID</key>
+ <string>SIL</string>
+ <key>openTypeOS2WeightClass</key>
+ <integer>400</integer>
+ <key>openTypeOS2WidthClass</key>
+ <integer>5</integer>
+ <key>openTypeOS2WinAscent</key>
+ <integer>2100</integer>
+ <key>openTypeOS2WinDescent</key>
+ <integer>550</integer>
+ <key>postscriptBlueValues</key>
+ <array>
+ <integer>-490</integer>
+ <integer>-490</integer>
+ <integer>-25</integer>
+ <integer>0</integer>
+ <integer>1020</integer>
+ <integer>1040</integer>
+ <integer>1455</integer>
+ <integer>1485</integer>
+ <integer>1600</integer>
+ <integer>1620</integer>
+ </array>
+ <key>postscriptFontName</key>
+ <string>PsfTest-Italic</string>
+ <key>postscriptFullName</key>
+ <string>Psf Test Italic</string>
+ <key>postscriptStemSnapH</key>
+ <array>
+ <integer>140</integer>
+ <integer>145</integer>
+ <integer>150</integer>
+ <integer>155</integer>
+ <integer>160</integer>
+ <integer>165</integer>
+ <integer>170</integer>
+ <integer>175</integer>
+ <integer>185</integer>
+ <integer>270</integer>
+ </array>
+ <key>postscriptStemSnapV</key>
+ <array>
+ <integer>165</integer>
+ <integer>180</integer>
+ <integer>185</integer>
+ <integer>190</integer>
+ <integer>195</integer>
+ <integer>200</integer>
+ <integer>205</integer>
+ <integer>270</integer>
+ </array>
+ <key>postscriptUnderlinePosition</key>
+ <integer>-110</integer>
+ <key>postscriptUnderlineThickness</key>
+ <integer>80</integer>
+ <key>styleMapFamilyName</key>
+ <string>Psf Test</string>
+ <key>styleMapStyleName</key>
+ <string>italic</string>
+ <key>styleName</key>
+ <string>Italic</string>
+ <key>trademark</key>
+ <string>Andika is a trademark of SIL International.</string>
+ <key>unitsPerEm</key>
+ <integer>2048</integer>
+ <key>versionMajor</key>
+ <integer>5</integer>
+ <key>versionMinor</key>
+ <integer>550</integer>
+ <key>xHeight</key>
+ <integer>1040</integer>
+</dict>
+</plist>
diff --git a/tests/reference/ufo/psfsetunicodes.ufo/glyphs/A_mpersand.glif b/tests/reference/ufo/psfsetunicodes.ufo/glyphs/A_mpersand.glif
new file mode 100644
index 0000000..4108ea7
--- /dev/null
+++ b/tests/reference/ufo/psfsetunicodes.ufo/glyphs/A_mpersand.glif
@@ -0,0 +1,61 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="Ampersand" format="2">
+ <advance width="1202"/>
+ <unicode hex="002A"/>
+ <outline>
+ <contour>
+ <point x="1054" y="559" type="line"/>
+ <point x="949" y="395"/>
+ <point x="616" y="147"/>
+ <point x="441" y="147" type="curve" smooth="yes"/>
+ <point x="318" y="147"/>
+ <point x="256" y="224"/>
+ <point x="256" y="314" type="curve" smooth="yes"/>
+ <point x="256" y="453"/>
+ <point x="369" y="575"/>
+ <point x="590" y="725" type="curve" smooth="yes"/>
+ <point x="836" y="892"/>
+ <point x="1022" y="1067"/>
+ <point x="1022" y="1223" type="curve" smooth="yes"/>
+ <point x="1022" y="1363"/>
+ <point x="894" y="1455"/>
+ <point x="762" y="1455" type="curve" smooth="yes"/>
+ <point x="504" y="1455"/>
+ <point x="378" y="1328"/>
+ <point x="378" y="1114" type="curve" smooth="yes"/>
+ <point x="378" y="953"/>
+ <point x="514" y="771"/>
+ <point x="614" y="559" type="curve" smooth="yes"/>
+ <point x="783" y="198"/>
+ <point x="906" y="-25"/>
+ <point x="958" y="-25" type="curve" smooth="yes"/>
+ <point x="993" y="-25"/>
+ <point x="1087" y="37"/>
+ <point x="1132" y="69" type="curve"/>
+ <point x="1046" y="108"/>
+ <point x="926" y="291"/>
+ <point x="756" y="666" type="curve" smooth="yes"/>
+ <point x="665" y="866"/>
+ <point x="544" y="1029"/>
+ <point x="544" y="1149" type="curve" smooth="yes"/>
+ <point x="544" y="1252"/>
+ <point x="632" y="1323"/>
+ <point x="724" y="1323" type="curve" smooth="yes"/>
+ <point x="794" y="1323"/>
+ <point x="858" y="1266"/>
+ <point x="858" y="1193" type="curve" smooth="yes"/>
+ <point x="858" y="1107"/>
+ <point x="743" y="1004"/>
+ <point x="492" y="826" type="curve" smooth="yes"/>
+ <point x="182" y="606"/>
+ <point x="73" y="439"/>
+ <point x="73" y="288" type="curve" smooth="yes"/>
+ <point x="73" y="113"/>
+ <point x="195" y="-25"/>
+ <point x="383" y="-25" type="curve" smooth="yes"/>
+ <point x="656" y="-25"/>
+ <point x="1009" y="269"/>
+ <point x="1126" y="426" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetunicodes.ufo/glyphs/A_pos.glif b/tests/reference/ufo/psfsetunicodes.ufo/glyphs/A_pos.glif
new file mode 100644
index 0000000..deb1650
--- /dev/null
+++ b/tests/reference/ufo/psfsetunicodes.ufo/glyphs/A_pos.glif
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="Apos" format="2">
+ <advance width="585"/>
+ <unicode hex="0027"/>
+ <outline>
+ <contour>
+ <point x="560" y="1024" type="line"/>
+ <point x="599" y="1162"/>
+ <point x="643" y="1312"/>
+ <point x="732" y="1553" type="curve"/>
+ <point x="527" y="1553" type="line"/>
+ <point x="498" y="1312"/>
+ <point x="465" y="1162"/>
+ <point x="435" y="1024" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetunicodes.ufo/glyphs/A_sterisk.glif b/tests/reference/ufo/psfsetunicodes.ufo/glyphs/A_sterisk.glif
new file mode 100644
index 0000000..b2f15bd
--- /dev/null
+++ b/tests/reference/ufo/psfsetunicodes.ufo/glyphs/A_sterisk.glif
@@ -0,0 +1,51 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="Asterisk" format="2">
+ <advance width="1008"/>
+ <unicode hex="0026"/>
+ <outline>
+ <contour>
+ <point x="745" y="1568" type="line"/>
+ <point x="733" y="1438"/>
+ <point x="725" y="1359"/>
+ <point x="707" y="1274" type="curve"/>
+ <point x="644" y="1317"/>
+ <point x="587" y="1359"/>
+ <point x="498" y="1436" type="curve"/>
+ <point x="392" y="1313" type="line"/>
+ <point x="505" y="1264"/>
+ <point x="575" y="1236"/>
+ <point x="643" y="1196" type="curve"/>
+ <point x="556" y="1153"/>
+ <point x="474" y="1117"/>
+ <point x="340" y="1063" type="curve"/>
+ <point x="379" y="941" type="line"/>
+ <point x="504" y="1021"/>
+ <point x="584" y="1072"/>
+ <point x="668" y="1117" type="curve"/>
+ <point x="645" y="1034"/>
+ <point x="619" y="954"/>
+ <point x="575" y="823" type="curve"/>
+ <point x="715" y="823" type="line"/>
+ <point x="727" y="954"/>
+ <point x="741" y="1031"/>
+ <point x="758" y="1117" type="curve"/>
+ <point x="821" y="1073"/>
+ <point x="878" y="1032"/>
+ <point x="968" y="956" type="curve"/>
+ <point x="1073" y="1078" type="line"/>
+ <point x="959" y="1126"/>
+ <point x="890" y="1155"/>
+ <point x="823" y="1196" type="curve"/>
+ <point x="909" y="1236"/>
+ <point x="990" y="1273"/>
+ <point x="1126" y="1328" type="curve"/>
+ <point x="1086" y="1450" type="line"/>
+ <point x="961" y="1368"/>
+ <point x="883" y="1321"/>
+ <point x="797" y="1274" type="curve"/>
+ <point x="819" y="1359"/>
+ <point x="845" y="1438"/>
+ <point x="890" y="1568" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetunicodes.ufo/glyphs/A_tS_gn.glif b/tests/reference/ufo/psfsetunicodes.ufo/glyphs/A_tS_gn.glif
new file mode 100644
index 0000000..2cd2542
--- /dev/null
+++ b/tests/reference/ufo/psfsetunicodes.ufo/glyphs/A_tS_gn.glif
@@ -0,0 +1,104 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="AtSgn" format="2">
+ <advance width="1682"/>
+ <unicode hex="0040"/>
+ <outline>
+ <contour>
+ <point x="1082" y="-10" type="line"/>
+ <point x="980" y="-69"/>
+ <point x="889" y="-93"/>
+ <point x="796" y="-93" type="curve" smooth="yes"/>
+ <point x="507" y="-93"/>
+ <point x="301" y="104"/>
+ <point x="301" y="414" type="curve" smooth="yes"/>
+ <point x="301" y="476"/>
+ <point x="309" y="543"/>
+ <point x="327" y="613" type="curve" smooth="yes"/>
+ <point x="425" y="1003"/>
+ <point x="782" y="1245"/>
+ <point x="1110" y="1245" type="curve" smooth="yes"/>
+ <point x="1433" y="1245"/>
+ <point x="1590" y="1060"/>
+ <point x="1590" y="813" type="curve" smooth="yes"/>
+ <point x="1590" y="760"/>
+ <point x="1582" y="705"/>
+ <point x="1568" y="647" type="curve" smooth="yes"/>
+ <point x="1510" y="413"/>
+ <point x="1365" y="309"/>
+ <point x="1297" y="309" type="curve" smooth="yes"/>
+ <point x="1261" y="309"/>
+ <point x="1238" y="344"/>
+ <point x="1238" y="420" type="curve" smooth="yes"/>
+ <point x="1238" y="468"/>
+ <point x="1247" y="533"/>
+ <point x="1268" y="617" type="curve" smooth="yes"/>
+ <point x="1354" y="960" type="line"/>
+ <point x="1276" y="995"/>
+ <point x="1155" y="1019"/>
+ <point x="1074" y="1019" type="curve" smooth="yes"/>
+ <point x="910" y="1019"/>
+ <point x="790" y="962"/>
+ <point x="673" y="828" type="curve" smooth="yes"/>
+ <point x="607" y="751"/>
+ <point x="554" y="650"/>
+ <point x="524" y="529" type="curve" smooth="yes"/>
+ <point x="514" y="488"/>
+ <point x="509" y="450"/>
+ <point x="509" y="416" type="curve" smooth="yes"/>
+ <point x="509" y="259"/>
+ <point x="609" y="179"/>
+ <point x="719" y="179" type="curve" smooth="yes"/>
+ <point x="836" y="179"/>
+ <point x="1017" y="359"/>
+ <point x="1099" y="480" type="curve"/>
+ <point x="1093" y="446"/>
+ <point x="1089" y="413"/>
+ <point x="1089" y="382" type="curve" smooth="yes"/>
+ <point x="1089" y="264"/>
+ <point x="1136" y="176"/>
+ <point x="1233" y="176" type="curve" smooth="yes"/>
+ <point x="1408" y="176"/>
+ <point x="1635" y="331"/>
+ <point x="1716" y="656" type="curve" smooth="yes"/>
+ <point x="1732" y="722"/>
+ <point x="1740" y="784"/>
+ <point x="1740" y="843" type="curve" smooth="yes"/>
+ <point x="1740" y="1161"/>
+ <point x="1513" y="1377"/>
+ <point x="1153" y="1377" type="curve" smooth="yes"/>
+ <point x="738" y="1377"/>
+ <point x="310" y="1143"/>
+ <point x="175" y="603" type="curve" smooth="yes"/>
+ <point x="155" y="522"/>
+ <point x="145" y="446"/>
+ <point x="145" y="375" type="curve" smooth="yes"/>
+ <point x="145" y="-5"/>
+ <point x="417" y="-230"/>
+ <point x="747" y="-230" type="curve" smooth="yes"/>
+ <point x="882" y="-230"/>
+ <point x="1044" y="-184"/>
+ <point x="1161" y="-116" type="curve"/>
+ </contour>
+ <contour>
+ <point x="1141" y="706" type="line"/>
+ <point x="1075" y="570"/>
+ <point x="856" y="314"/>
+ <point x="766" y="314" type="curve" smooth="yes"/>
+ <point x="712" y="314"/>
+ <point x="669" y="362"/>
+ <point x="669" y="459" type="curve" smooth="yes"/>
+ <point x="669" y="491"/>
+ <point x="674" y="530"/>
+ <point x="685" y="573" type="curve" smooth="yes"/>
+ <point x="704" y="649"/>
+ <point x="739" y="726"/>
+ <point x="780" y="774" type="curve" smooth="yes"/>
+ <point x="859" y="868"/>
+ <point x="943" y="887"/>
+ <point x="1011" y="887" type="curve" smooth="yes"/>
+ <point x="1085" y="887"/>
+ <point x="1148" y="868"/>
+ <point x="1177" y="853" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetunicodes.ufo/glyphs/C_ircumA_ccent.glif b/tests/reference/ufo/psfsetunicodes.ufo/glyphs/C_ircumA_ccent.glif
new file mode 100644
index 0000000..91ab811
--- /dev/null
+++ b/tests/reference/ufo/psfsetunicodes.ufo/glyphs/C_ircumA_ccent.glif
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="CircumAccent" format="2">
+ <advance width="830"/>
+ <unicode hex="005E"/>
+ <anchor x="705" y="1635" name="U"/>
+ <outline>
+ <contour>
+ <point x="316" y="1147" type="line"/>
+ <point x="660" y="1421" type="line"/>
+ <point x="866" y="1147" type="line"/>
+ <point x="1015" y="1147" type="line"/>
+ <point x="761" y="1568" type="line"/>
+ <point x="591" y="1568" type="line"/>
+ <point x="166" y="1147" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetunicodes.ufo/glyphs/C_olon.glif b/tests/reference/ufo/psfsetunicodes.ufo/glyphs/C_olon.glif
new file mode 100644
index 0000000..bcccfc2
--- /dev/null
+++ b/tests/reference/ufo/psfsetunicodes.ufo/glyphs/C_olon.glif
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="Colon" format="2">
+ <advance width="620"/>
+ <unicode hex="003A"/>
+ <outline>
+ <contour>
+ <point x="314" y="758" type="curve" smooth="yes"/>
+ <point x="314" y="696"/>
+ <point x="365" y="642"/>
+ <point x="430" y="642" type="curve" smooth="yes"/>
+ <point x="514" y="642"/>
+ <point x="590" y="712"/>
+ <point x="590" y="792" type="curve" smooth="yes"/>
+ <point x="590" y="854"/>
+ <point x="540" y="907"/>
+ <point x="476" y="907" type="curve" smooth="yes"/>
+ <point x="393" y="907"/>
+ <point x="314" y="837"/>
+ </contour>
+ <contour>
+ <point x="148" y="90" type="curve" smooth="yes"/>
+ <point x="148" y="28"/>
+ <point x="198" y="-25"/>
+ <point x="263" y="-25" type="curve" smooth="yes"/>
+ <point x="347" y="-25"/>
+ <point x="424" y="45"/>
+ <point x="424" y="125" type="curve" smooth="yes"/>
+ <point x="424" y="186"/>
+ <point x="374" y="240"/>
+ <point x="309" y="240" type="curve" smooth="yes"/>
+ <point x="225" y="240"/>
+ <point x="148" y="170"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetunicodes.ufo/glyphs/C_ombA_cute.glif b/tests/reference/ufo/psfsetunicodes.ufo/glyphs/C_ombA_cute.glif
new file mode 100644
index 0000000..a7607fe
--- /dev/null
+++ b/tests/reference/ufo/psfsetunicodes.ufo/glyphs/C_ombA_cute.glif
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="CombAcute" format="2">
+ <unicode hex="0301"/>
+ <anchor x="-221" y="1635" name="U"/>
+ <anchor x="-355" y="1100" name="_U"/>
+ <outline>
+ <contour>
+ <point x="-99" y="1568" type="line"/>
+ <point x="-524" y="1147" type="line"/>
+ <point x="-354" y="1147" type="line"/>
+ <point x="150" y="1568" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetunicodes.ufo/glyphs/C_ombC_ircum.glif b/tests/reference/ufo/psfsetunicodes.ufo/glyphs/C_ombC_ircum.glif
new file mode 100644
index 0000000..6614f85
--- /dev/null
+++ b/tests/reference/ufo/psfsetunicodes.ufo/glyphs/C_ombC_ircum.glif
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="CombCircum" format="2">
+ <unicode hex="0302"/>
+ <anchor x="-221" y="1635" name="U"/>
+ <anchor x="-320" y="1100" name="_U"/>
+ <outline>
+ <contour>
+ <point x="-619" y="1147" type="line"/>
+ <point x="-275" y="1421" type="line"/>
+ <point x="-69" y="1147" type="line"/>
+ <point x="80" y="1147" type="line"/>
+ <point x="-174" y="1568" type="line"/>
+ <point x="-344" y="1568" type="line"/>
+ <point x="-769" y="1147" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetunicodes.ufo/glyphs/C_ombD_iaer.glif b/tests/reference/ufo/psfsetunicodes.ufo/glyphs/C_ombD_iaer.glif
new file mode 100644
index 0000000..d6b35b7
--- /dev/null
+++ b/tests/reference/ufo/psfsetunicodes.ufo/glyphs/C_ombD_iaer.glif
@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="CombDiaer" format="2">
+ <unicode hex="0308"/>
+ <anchor x="-253" y="1505" name="U"/>
+ <anchor x="-350" y="1100" name="_U"/>
+ <outline>
+ <contour>
+ <point x="39" y="1338" type="curve" smooth="yes"/>
+ <point x="39" y="1399"/>
+ <point x="-7" y="1450"/>
+ <point x="-72" y="1450" type="curve" smooth="yes"/>
+ <point x="-167" y="1450"/>
+ <point x="-229" y="1372"/>
+ <point x="-229" y="1299" type="curve" smooth="yes"/>
+ <point x="-229" y="1238"/>
+ <point x="-182" y="1186"/>
+ <point x="-118" y="1186" type="curve" smooth="yes"/>
+ <point x="-33" y="1186"/>
+ <point x="39" y="1259"/>
+ </contour>
+ <contour>
+ <point x="-381" y="1338" type="curve" smooth="yes"/>
+ <point x="-381" y="1399"/>
+ <point x="-427" y="1450"/>
+ <point x="-492" y="1450" type="curve" smooth="yes"/>
+ <point x="-587" y="1450"/>
+ <point x="-649" y="1372"/>
+ <point x="-649" y="1299" type="curve" smooth="yes"/>
+ <point x="-649" y="1238"/>
+ <point x="-602" y="1186"/>
+ <point x="-538" y="1186" type="curve" smooth="yes"/>
+ <point x="-453" y="1186"/>
+ <point x="-381" y="1259"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetunicodes.ufo/glyphs/C_ombG_rave.glif b/tests/reference/ufo/psfsetunicodes.ufo/glyphs/C_ombG_rave.glif
new file mode 100644
index 0000000..8869bb9
--- /dev/null
+++ b/tests/reference/ufo/psfsetunicodes.ufo/glyphs/C_ombG_rave.glif
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="CombGrave" format="2">
+ <unicode hex="0300"/>
+ <anchor x="-201" y="1635" name="U"/>
+ <anchor x="-335" y="1100" name="_U"/>
+ <outline>
+ <contour>
+ <point x="-619" y="1568" type="line"/>
+ <point x="-284" y="1147" type="line"/>
+ <point x="-134" y="1147" type="line"/>
+ <point x="-409" y="1568" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetunicodes.ufo/glyphs/C_ombR_ingA_bv.glif b/tests/reference/ufo/psfsetunicodes.ufo/glyphs/C_ombR_ingA_bv.glif
new file mode 100644
index 0000000..38232a0
--- /dev/null
+++ b/tests/reference/ufo/psfsetunicodes.ufo/glyphs/C_ombR_ingA_bv.glif
@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="CombRingAbv" format="2">
+ <unicode hex="030A"/>
+ <anchor x="-221" y="1635" name="U"/>
+ <anchor x="-385" y="1100" name="_U"/>
+ <outline>
+ <contour>
+ <point x="-377" y="1259" type="curve" smooth="yes"/>
+ <point x="-427" y="1259"/>
+ <point x="-456" y="1287"/>
+ <point x="-456" y="1329" type="curve" smooth="yes"/>
+ <point x="-456" y="1400"/>
+ <point x="-393" y="1455"/>
+ <point x="-328" y="1455" type="curve" smooth="yes"/>
+ <point x="-278" y="1455"/>
+ <point x="-248" y="1428"/>
+ <point x="-248" y="1385" type="curve" smooth="yes"/>
+ <point x="-248" y="1314"/>
+ <point x="-312" y="1259"/>
+ </contour>
+ <contour>
+ <point x="-573" y="1320" type="curve" smooth="yes"/>
+ <point x="-573" y="1224"/>
+ <point x="-498" y="1147"/>
+ <point x="-395" y="1147" type="curve" smooth="yes"/>
+ <point x="-257" y="1147"/>
+ <point x="-131" y="1263"/>
+ <point x="-131" y="1394" type="curve" smooth="yes"/>
+ <point x="-131" y="1491"/>
+ <point x="-206" y="1568"/>
+ <point x="-310" y="1568" type="curve" smooth="yes"/>
+ <point x="-448" y="1568"/>
+ <point x="-573" y="1451"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetunicodes.ufo/glyphs/C_ombT_ilde.glif b/tests/reference/ufo/psfsetunicodes.ufo/glyphs/C_ombT_ilde.glif
new file mode 100644
index 0000000..f79322e
--- /dev/null
+++ b/tests/reference/ufo/psfsetunicodes.ufo/glyphs/C_ombT_ilde.glif
@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="CombTilde" format="2">
+ <unicode hex="0303"/>
+ <anchor x="-290" y="1475" name="U"/>
+ <anchor x="-385" y="1100" name="_U"/>
+ <outline>
+ <contour>
+ <point x="-646" y="1181" type="line"/>
+ <point x="-629" y="1229"/>
+ <point x="-589" y="1269"/>
+ <point x="-540" y="1269" type="curve" smooth="yes"/>
+ <point x="-503" y="1269"/>
+ <point x="-466" y="1253"/>
+ <point x="-398" y="1218" type="curve" smooth="yes"/>
+ <point x="-344" y="1190"/>
+ <point x="-296" y="1171"/>
+ <point x="-243" y="1171" type="curve" smooth="yes"/>
+ <point x="-120" y="1171"/>
+ <point x="-15" y="1286"/>
+ <point x="16" y="1411" type="curve"/>
+ <point x="-89" y="1411" type="line"/>
+ <point x="-107" y="1366"/>
+ <point x="-147" y="1323"/>
+ <point x="-194" y="1323" type="curve" smooth="yes"/>
+ <point x="-236" y="1323"/>
+ <point x="-273" y="1342"/>
+ <point x="-338" y="1370" type="curve" smooth="yes"/>
+ <point x="-401" y="1397"/>
+ <point x="-442" y="1421"/>
+ <point x="-498" y="1421" type="curve" smooth="yes"/>
+ <point x="-617" y="1421"/>
+ <point x="-721" y="1300"/>
+ <point x="-751" y="1181" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetunicodes.ufo/glyphs/C_omma.glif b/tests/reference/ufo/psfsetunicodes.ufo/glyphs/C_omma.glif
new file mode 100644
index 0000000..80f2d6e
--- /dev/null
+++ b/tests/reference/ufo/psfsetunicodes.ufo/glyphs/C_omma.glif
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="Comma" format="2">
+ <advance width="630"/>
+ <outline>
+ <contour>
+ <point x="137" y="49" type="line"/>
+ <point x="277" y="49" type="line"/>
+ <point x="252" y="-50"/>
+ <point x="145" y="-169"/>
+ <point x="73" y="-225" type="curve"/>
+ <point x="163" y="-265" type="line"/>
+ <point x="280" y="-175"/>
+ <point x="431" y="-28"/>
+ <point x="431" y="118" type="curve" smooth="yes"/>
+ <point x="431" y="193"/>
+ <point x="378" y="245"/>
+ <point x="311" y="245" type="curve" smooth="yes"/>
+ <point x="254" y="245"/>
+ <point x="190" y="209"/>
+ <point x="161" y="147" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetunicodes.ufo/glyphs/D_igitE_ight.glif b/tests/reference/ufo/psfsetunicodes.ufo/glyphs/D_igitE_ight.glif
new file mode 100644
index 0000000..262f860
--- /dev/null
+++ b/tests/reference/ufo/psfsetunicodes.ufo/glyphs/D_igitE_ight.glif
@@ -0,0 +1,63 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="DigitEight" format="2">
+ <advance width="1180"/>
+ <unicode hex="0038"/>
+ <anchor x="515" y="-100" name="L"/>
+ <anchor x="922" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="542" y="-25" type="curve" smooth="yes"/>
+ <point x="839" y="-25"/>
+ <point x="1160" y="170"/>
+ <point x="1160" y="475" type="curve" smooth="yes"/>
+ <point x="1160" y="626"/>
+ <point x="1068" y="733"/>
+ <point x="988" y="779" type="curve"/>
+ <point x="1155" y="860"/>
+ <point x="1270" y="970"/>
+ <point x="1270" y="1151" type="curve" smooth="yes"/>
+ <point x="1270" y="1340"/>
+ <point x="1102" y="1455"/>
+ <point x="901" y="1455" type="curve" smooth="yes"/>
+ <point x="620" y="1455"/>
+ <point x="348" y="1292"/>
+ <point x="348" y="1018" type="curve" smooth="yes"/>
+ <point x="348" y="891"/>
+ <point x="427" y="814"/>
+ <point x="483" y="779" type="curve"/>
+ <point x="297" y="706"/>
+ <point x="115" y="549"/>
+ <point x="115" y="325" type="curve" smooth="yes"/>
+ <point x="115" y="111"/>
+ <point x="317" y="-25"/>
+ </contour>
+ <contour>
+ <point x="750" y="848" type="curve" smooth="yes"/>
+ <point x="628" y="848"/>
+ <point x="541" y="917"/>
+ <point x="541" y="1029" type="curve" smooth="yes"/>
+ <point x="541" y="1205"/>
+ <point x="704" y="1299"/>
+ <point x="862" y="1299" type="curve" smooth="yes"/>
+ <point x="985" y="1299"/>
+ <point x="1076" y="1235"/>
+ <point x="1076" y="1128" type="curve" smooth="yes"/>
+ <point x="1076" y="955"/>
+ <point x="907" y="848"/>
+ </contour>
+ <contour>
+ <point x="564" y="142" type="curve" smooth="yes"/>
+ <point x="413" y="142"/>
+ <point x="322" y="225"/>
+ <point x="322" y="350" type="curve" smooth="yes"/>
+ <point x="322" y="557"/>
+ <point x="520" y="696"/>
+ <point x="712" y="696" type="curve" smooth="yes"/>
+ <point x="864" y="696"/>
+ <point x="961" y="602"/>
+ <point x="961" y="476" type="curve" smooth="yes"/>
+ <point x="961" y="266"/>
+ <point x="753" y="142"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetunicodes.ufo/glyphs/D_igitF_ive.glif b/tests/reference/ufo/psfsetunicodes.ufo/glyphs/D_igitF_ive.glif
new file mode 100644
index 0000000..a224838
--- /dev/null
+++ b/tests/reference/ufo/psfsetunicodes.ufo/glyphs/D_igitF_ive.glif
@@ -0,0 +1,44 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="DigitFive" format="2">
+ <advance width="1180"/>
+ <unicode hex="0035"/>
+ <anchor x="515" y="-100" name="L"/>
+ <anchor x="922" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="1296" y="1431" type="line"/>
+ <point x="491" y="1431" type="line"/>
+ <point x="302" y="671" type="line"/>
+ <point x="438" y="718"/>
+ <point x="537" y="735"/>
+ <point x="643" y="735" type="curve" smooth="yes"/>
+ <point x="784" y="735"/>
+ <point x="933" y="660"/>
+ <point x="933" y="508" type="curve" smooth="yes"/>
+ <point x="933" y="273"/>
+ <point x="710" y="152"/>
+ <point x="497" y="152" type="curve" smooth="yes"/>
+ <point x="357" y="152"/>
+ <point x="263" y="195"/>
+ <point x="170" y="284" type="curve"/>
+ <point x="89" y="78" type="line"/>
+ <point x="195" y="2"/>
+ <point x="326" y="-25"/>
+ <point x="481" y="-25" type="curve" smooth="yes"/>
+ <point x="807" y="-25"/>
+ <point x="1129" y="190"/>
+ <point x="1129" y="546" type="curve" smooth="yes"/>
+ <point x="1129" y="757"/>
+ <point x="951" y="911"/>
+ <point x="702" y="911" type="curve" smooth="yes"/>
+ <point x="629" y="911"/>
+ <point x="576" y="906"/>
+ <point x="544" y="902" type="curve"/>
+ <point x="635" y="1264" type="line"/>
+ <point x="1020" y="1264" type="line" smooth="yes"/>
+ <point x="1104" y="1264"/>
+ <point x="1179" y="1260"/>
+ <point x="1250" y="1245" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetunicodes.ufo/glyphs/D_igitF_our.glif b/tests/reference/ufo/psfsetunicodes.ufo/glyphs/D_igitF_our.glif
new file mode 100644
index 0000000..eeccb48
--- /dev/null
+++ b/tests/reference/ufo/psfsetunicodes.ufo/glyphs/D_igitF_our.glif
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="DigitFour" format="2">
+ <advance width="1180"/>
+ <unicode hex="0034"/>
+ <anchor x="522" y="-100" name="L"/>
+ <anchor x="929" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="1161" y="387" type="line"/>
+ <point x="1199" y="539" type="line"/>
+ <point x="1009" y="539" type="line"/>
+ <point x="1236" y="1450" type="line"/>
+ <point x="1026" y="1450" type="line"/>
+ <point x="144" y="539" type="line"/>
+ <point x="106" y="387" type="line"/>
+ <point x="781" y="387" type="line"/>
+ <point x="685" y="0" type="line"/>
+ <point x="875" y="0" type="line"/>
+ <point x="971" y="387" type="line"/>
+ </contour>
+ <contour>
+ <point x="985" y="1205" type="line"/>
+ <point x="819" y="539" type="line"/>
+ <point x="337" y="539" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetunicodes.ufo/glyphs/D_igitN_ine.glif b/tests/reference/ufo/psfsetunicodes.ufo/glyphs/D_igitN_ine.glif
new file mode 100644
index 0000000..191cd79
--- /dev/null
+++ b/tests/reference/ufo/psfsetunicodes.ufo/glyphs/D_igitN_ine.glif
@@ -0,0 +1,49 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="DigitNine" format="2">
+ <advance width="1180"/>
+ <unicode hex="0039"/>
+ <anchor x="515" y="-100" name="L"/>
+ <anchor x="922" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="157" y="94" type="line"/>
+ <point x="208" y="29"/>
+ <point x="355" y="-25"/>
+ <point x="473" y="-25" type="curve" smooth="yes"/>
+ <point x="999" y="-25"/>
+ <point x="1267" y="520"/>
+ <point x="1267" y="982" type="curve" smooth="yes"/>
+ <point x="1267" y="1248"/>
+ <point x="1127" y="1455"/>
+ <point x="866" y="1455" type="curve" smooth="yes"/>
+ <point x="596" y="1455"/>
+ <point x="303" y="1269"/>
+ <point x="303" y="932" type="curve" smooth="yes"/>
+ <point x="303" y="761"/>
+ <point x="425" y="574"/>
+ <point x="661" y="574" type="curve" smooth="yes"/>
+ <point x="852" y="574"/>
+ <point x="1036" y="683"/>
+ <point x="1172" y="840" type="curve"/>
+ <point x="1121" y="922" type="line"/>
+ <point x="1019" y="810"/>
+ <point x="872" y="745"/>
+ <point x="717" y="745" type="curve" smooth="yes"/>
+ <point x="584" y="745"/>
+ <point x="498" y="833"/>
+ <point x="498" y="956" type="curve" smooth="yes"/>
+ <point x="498" y="1146"/>
+ <point x="638" y="1284"/>
+ <point x="821" y="1284" type="curve" smooth="yes"/>
+ <point x="998" y="1284"/>
+ <point x="1073" y="1119"/>
+ <point x="1073" y="956" type="curve" smooth="yes"/>
+ <point x="1073" y="455"/>
+ <point x="760" y="147"/>
+ <point x="496" y="147" type="curve" smooth="yes"/>
+ <point x="410" y="147"/>
+ <point x="298" y="209"/>
+ <point x="249" y="285" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetunicodes.ufo/glyphs/D_igitO_ne.glif b/tests/reference/ufo/psfsetunicodes.ufo/glyphs/D_igitO_ne.glif
new file mode 100644
index 0000000..a639774
--- /dev/null
+++ b/tests/reference/ufo/psfsetunicodes.ufo/glyphs/D_igitO_ne.glif
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="DigitOne" format="2">
+ <advance width="1180"/>
+ <unicode hex="0031"/>
+ <anchor x="515" y="-100" name="L"/>
+ <anchor x="922" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="1021" y="167" type="line"/>
+ <point x="706" y="167" type="line"/>
+ <point x="1026" y="1450" type="line"/>
+ <point x="856" y="1450" type="line"/>
+ <point x="459" y="1243" type="line"/>
+ <point x="440" y="1066" type="line"/>
+ <point x="782" y="1235" type="line"/>
+ <point x="516" y="167" type="line"/>
+ <point x="201" y="167" type="line"/>
+ <point x="160" y="0" type="line"/>
+ <point x="980" y="0" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetunicodes.ufo/glyphs/D_igitS_even.glif b/tests/reference/ufo/psfsetunicodes.ufo/glyphs/D_igitS_even.glif
new file mode 100644
index 0000000..68c6ef6
--- /dev/null
+++ b/tests/reference/ufo/psfsetunicodes.ufo/glyphs/D_igitS_even.glif
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="DigitSeven" format="2">
+ <advance width="1180"/>
+ <unicode hex="0037"/>
+ <anchor x="515" y="-100" name="L"/>
+ <anchor x="922" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="420" y="0" type="line"/>
+ <point x="661" y="450"/>
+ <point x="972" y="877"/>
+ <point x="1367" y="1274" type="curve"/>
+ <point x="1406" y="1431" type="line"/>
+ <point x="386" y="1431" type="line"/>
+ <point x="341" y="1245" type="line"/>
+ <point x="421" y="1260"/>
+ <point x="538" y="1264"/>
+ <point x="726" y="1264" type="curve" smooth="yes"/>
+ <point x="1126" y="1264" type="line"/>
+ <point x="774" y="889"/>
+ <point x="517" y="555"/>
+ <point x="215" y="0" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetunicodes.ufo/glyphs/D_igitS_ix.glif b/tests/reference/ufo/psfsetunicodes.ufo/glyphs/D_igitS_ix.glif
new file mode 100644
index 0000000..b6be793
--- /dev/null
+++ b/tests/reference/ufo/psfsetunicodes.ufo/glyphs/D_igitS_ix.glif
@@ -0,0 +1,49 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="DigitSix" format="2">
+ <advance width="1180"/>
+ <unicode hex="0036"/>
+ <anchor x="515" y="-100" name="L"/>
+ <anchor x="922" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="1313" y="1347" type="line"/>
+ <point x="1248" y="1418"/>
+ <point x="1135" y="1455"/>
+ <point x="1017" y="1455" type="curve" smooth="yes"/>
+ <point x="481" y="1454"/>
+ <point x="208" y="915"/>
+ <point x="208" y="475" type="curve" smooth="yes"/>
+ <point x="208" y="167"/>
+ <point x="392" y="-25"/>
+ <point x="623" y="-25" type="curve" smooth="yes"/>
+ <point x="947" y="-25"/>
+ <point x="1183" y="169"/>
+ <point x="1183" y="517" type="curve" smooth="yes"/>
+ <point x="1183" y="709"/>
+ <point x="1029" y="887"/>
+ <point x="793" y="887" type="curve" smooth="yes"/>
+ <point x="636" y="887"/>
+ <point x="432" y="784"/>
+ <point x="317" y="633" type="curve"/>
+ <point x="364" y="559" type="line"/>
+ <point x="471" y="660"/>
+ <point x="596" y="716"/>
+ <point x="751" y="716" type="curve" smooth="yes"/>
+ <point x="898" y="716"/>
+ <point x="987" y="614"/>
+ <point x="987" y="454" type="curve" smooth="yes"/>
+ <point x="987" y="263"/>
+ <point x="816" y="147"/>
+ <point x="656" y="147" type="curve" smooth="yes"/>
+ <point x="491" y="147"/>
+ <point x="403" y="284"/>
+ <point x="403" y="472" type="curve" smooth="yes"/>
+ <point x="403" y="962"/>
+ <point x="664" y="1284"/>
+ <point x="985" y="1284" type="curve" smooth="yes"/>
+ <point x="1081" y="1284"/>
+ <point x="1174" y="1235"/>
+ <point x="1222" y="1156" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetunicodes.ufo/glyphs/D_igitT_hree.glif b/tests/reference/ufo/psfsetunicodes.ufo/glyphs/D_igitT_hree.glif
new file mode 100644
index 0000000..e01df2c
--- /dev/null
+++ b/tests/reference/ufo/psfsetunicodes.ufo/glyphs/D_igitT_hree.glif
@@ -0,0 +1,52 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="DigitThree" format="2">
+ <advance width="1180"/>
+ <unicode hex="0033"/>
+ <anchor x="515" y="-100" name="L"/>
+ <anchor x="922" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="562" y="853" type="line"/>
+ <point x="521" y="686" type="line"/>
+ <point x="591" y="686" type="line" smooth="yes"/>
+ <point x="802" y="686"/>
+ <point x="944" y="606"/>
+ <point x="944" y="476" type="curve" smooth="yes"/>
+ <point x="944" y="268"/>
+ <point x="738" y="147"/>
+ <point x="551" y="147" type="curve" smooth="yes"/>
+ <point x="371" y="147"/>
+ <point x="260" y="227"/>
+ <point x="181" y="348" type="curve"/>
+ <point x="104" y="137" type="line"/>
+ <point x="185" y="41"/>
+ <point x="341" y="-25"/>
+ <point x="518" y="-25" type="curve" smooth="yes"/>
+ <point x="815" y="-25"/>
+ <point x="1141" y="168"/>
+ <point x="1141" y="475" type="curve" smooth="yes"/>
+ <point x="1141" y="670"/>
+ <point x="973" y="763"/>
+ <point x="855" y="784" type="curve"/>
+ <point x="1046" y="827"/>
+ <point x="1266" y="955"/>
+ <point x="1266" y="1163" type="curve" smooth="yes"/>
+ <point x="1266" y="1338"/>
+ <point x="1073" y="1455"/>
+ <point x="852" y="1455" type="curve" smooth="yes"/>
+ <point x="685" y="1455"/>
+ <point x="536" y="1388"/>
+ <point x="433" y="1299" type="curve"/>
+ <point x="427" y="1132" type="line"/>
+ <point x="568" y="1246"/>
+ <point x="696" y="1284"/>
+ <point x="850" y="1284" type="curve" smooth="yes"/>
+ <point x="957" y="1284"/>
+ <point x="1068" y="1236"/>
+ <point x="1068" y="1137" type="curve" smooth="yes"/>
+ <point x="1068" y="949"/>
+ <point x="781" y="853"/>
+ <point x="632" y="853" type="curve" smooth="yes"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetunicodes.ufo/glyphs/D_igitT_wo.glif b/tests/reference/ufo/psfsetunicodes.ufo/glyphs/D_igitT_wo.glif
new file mode 100644
index 0000000..d1bbb54
--- /dev/null
+++ b/tests/reference/ufo/psfsetunicodes.ufo/glyphs/D_igitT_wo.glif
@@ -0,0 +1,37 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="DigitTwo" format="2">
+ <advance width="1180"/>
+ <unicode hex="0032"/>
+ <anchor x="515" y="-100" name="L"/>
+ <anchor x="882" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="1063" y="176" type="line"/>
+ <point x="980" y="163"/>
+ <point x="822" y="162"/>
+ <point x="625" y="162" type="curve" smooth="yes"/>
+ <point x="370" y="162" type="line"/>
+ <point x="783" y="393"/>
+ <point x="1210" y="830"/>
+ <point x="1210" y="1098" type="curve" smooth="yes"/>
+ <point x="1210" y="1296"/>
+ <point x="1075" y="1455"/>
+ <point x="842" y="1455" type="curve" smooth="yes"/>
+ <point x="673" y="1455"/>
+ <point x="488" y="1374"/>
+ <point x="380" y="1264" type="curve"/>
+ <point x="388" y="1098" type="line"/>
+ <point x="503" y="1203"/>
+ <point x="660" y="1279"/>
+ <point x="783" y="1279" type="curve" smooth="yes"/>
+ <point x="915" y="1279"/>
+ <point x="1003" y="1199"/>
+ <point x="1003" y="1063" type="curve" smooth="yes"/>
+ <point x="1003" y="848"/>
+ <point x="506" y="386"/>
+ <point x="101" y="167" type="curve"/>
+ <point x="60" y="0" type="line"/>
+ <point x="1020" y="0" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetunicodes.ufo/glyphs/D_igitZ_ero.glif b/tests/reference/ufo/psfsetunicodes.ufo/glyphs/D_igitZ_ero.glif
new file mode 100644
index 0000000..5d1bf0e
--- /dev/null
+++ b/tests/reference/ufo/psfsetunicodes.ufo/glyphs/D_igitZ_ero.glif
@@ -0,0 +1,49 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="DigitZero" format="2">
+ <advance width="1180"/>
+ <unicode hex="0030"/>
+ <anchor x="520" y="-100" name="L"/>
+ <anchor x="927" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="1024" y="711" type="curve" smooth="yes"/>
+ <point x="925" y="312"/>
+ <point x="747" y="142"/>
+ <point x="565" y="142" type="curve" smooth="yes"/>
+ <point x="432" y="142"/>
+ <point x="360" y="218"/>
+ <point x="360" y="383" type="curve" smooth="yes"/>
+ <point x="360" y="468"/>
+ <point x="377" y="579"/>
+ <point x="412" y="720" type="curve" smooth="yes"/>
+ <point x="512" y="1120"/>
+ <point x="678" y="1289"/>
+ <point x="871" y="1289" type="curve" smooth="yes"/>
+ <point x="1006" y="1289"/>
+ <point x="1077" y="1223"/>
+ <point x="1077" y="1051" type="curve" smooth="yes"/>
+ <point x="1077" y="966"/>
+ <point x="1060" y="854"/>
+ </contour>
+ <contour>
+ <point x="1230" y="715" type="curve" smooth="yes"/>
+ <point x="1262" y="841"/>
+ <point x="1276" y="949"/>
+ <point x="1276" y="1040" type="curve" smooth="yes"/>
+ <point x="1276" y="1335"/>
+ <point x="1124" y="1455"/>
+ <point x="902" y="1455" type="curve" smooth="yes"/>
+ <point x="613" y="1455"/>
+ <point x="344" y="1267"/>
+ <point x="206" y="716" type="curve" smooth="yes"/>
+ <point x="173" y="584"/>
+ <point x="158" y="474"/>
+ <point x="158" y="381" type="curve" smooth="yes"/>
+ <point x="158" y="104"/>
+ <point x="313" y="-25"/>
+ <point x="533" y="-25" type="curve" smooth="yes"/>
+ <point x="804" y="-25"/>
+ <point x="1086" y="138"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetunicodes.ufo/glyphs/D_ollarS_gn.glif b/tests/reference/ufo/psfsetunicodes.ufo/glyphs/D_ollarS_gn.glif
new file mode 100644
index 0000000..5c2db20
--- /dev/null
+++ b/tests/reference/ufo/psfsetunicodes.ufo/glyphs/D_ollarS_gn.glif
@@ -0,0 +1,53 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="DollarSgn" format="2">
+ <advance width="1180"/>
+ <unicode hex="0024"/>
+ <outline>
+ <contour>
+ <point x="1225" y="1280" type="line"/>
+ <point x="1119" y="1337"/>
+ <point x="1023" y="1361"/>
+ <point x="882" y="1361" type="curve" smooth="yes"/>
+ <point x="513" y="1361"/>
+ <point x="354" y="1182"/>
+ <point x="354" y="992" type="curve" smooth="yes"/>
+ <point x="354" y="837"/>
+ <point x="446" y="771"/>
+ <point x="639" y="650" type="curve" smooth="yes"/>
+ <point x="844" y="521"/>
+ <point x="919" y="439"/>
+ <point x="919" y="357" type="curve" smooth="yes"/>
+ <point x="919" y="244"/>
+ <point x="826" y="158"/>
+ <point x="635" y="158" type="curve" smooth="yes"/>
+ <point x="469" y="158"/>
+ <point x="314" y="266"/>
+ <point x="251" y="347" type="curve"/>
+ <point x="163" y="162" type="line"/>
+ <point x="304" y="58"/>
+ <point x="453" y="0"/>
+ <point x="606" y="0" type="curve" smooth="yes"/>
+ <point x="872" y="0"/>
+ <point x="1102" y="119"/>
+ <point x="1102" y="381" type="curve" smooth="yes"/>
+ <point x="1102" y="528"/>
+ <point x="981" y="657"/>
+ <point x="801" y="771" type="curve" smooth="yes"/>
+ <point x="610" y="892"/>
+ <point x="535" y="943"/>
+ <point x="535" y="1024" type="curve" smooth="yes"/>
+ <point x="535" y="1116"/>
+ <point x="657" y="1203"/>
+ <point x="832" y="1203" type="curve" smooth="yes"/>
+ <point x="950" y="1203"/>
+ <point x="1031" y="1176"/>
+ <point x="1144" y="1104" type="curve"/>
+ </contour>
+ <contour>
+ <point x="878" y="1568" type="line"/>
+ <point x="434" y="-216" type="line"/>
+ <point x="574" y="-216" type="line"/>
+ <point x="1018" y="1568" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetunicodes.ufo/glyphs/D_ottedC_irc.glif b/tests/reference/ufo/psfsetunicodes.ufo/glyphs/D_ottedC_irc.glif
new file mode 100644
index 0000000..2cdf8fd
--- /dev/null
+++ b/tests/reference/ufo/psfsetunicodes.ufo/glyphs/D_ottedC_irc.glif
@@ -0,0 +1,235 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="DottedCirc" format="2">
+ <advance width="1086"/>
+ <unicode hex="25CC"/>
+ <anchor x="493" y="0" name="H"/>
+ <anchor x="468" y="-100" name="L"/>
+ <anchor x="750" y="0" name="O"/>
+ <anchor x="743" y="1000" name="U"/>
+ <outline>
+ <contour>
+ <point x="588" y="834" type="curve" smooth="yes"/>
+ <point x="588" y="858"/>
+ <point x="571" y="867"/>
+ <point x="553" y="867" type="curve" smooth="yes"/>
+ <point x="521" y="867"/>
+ <point x="491" y="837"/>
+ <point x="491" y="809" type="curve" smooth="yes"/>
+ <point x="491" y="788"/>
+ <point x="508" y="773"/>
+ <point x="530" y="773" type="curve" smooth="yes"/>
+ <point x="564" y="773"/>
+ <point x="588" y="805"/>
+ </contour>
+ <contour>
+ <point x="677" y="124" type="curve" smooth="yes"/>
+ <point x="647" y="124"/>
+ <point x="620" y="93"/>
+ <point x="620" y="67" type="curve" smooth="yes"/>
+ <point x="620" y="46"/>
+ <point x="636" y="30"/>
+ <point x="657" y="30" type="curve" smooth="yes"/>
+ <point x="687" y="30"/>
+ <point x="718" y="60"/>
+ <point x="718" y="86" type="curve" smooth="yes"/>
+ <point x="718" y="109"/>
+ <point x="700" y="124"/>
+ </contour>
+ <contour>
+ <point x="396" y="780" type="curve" smooth="yes"/>
+ <point x="369" y="780"/>
+ <point x="336" y="753"/>
+ <point x="336" y="722" type="curve" smooth="yes"/>
+ <point x="336" y="702"/>
+ <point x="351" y="687"/>
+ <point x="374" y="687" type="curve" smooth="yes"/>
+ <point x="403" y="687"/>
+ <point x="434" y="711"/>
+ <point x="434" y="744" type="curve" smooth="yes"/>
+ <point x="434" y="764"/>
+ <point x="414" y="780"/>
+ </contour>
+ <contour>
+ <point x="873" y="175" type="curve" smooth="yes"/>
+ <point x="872" y="199"/>
+ <point x="854" y="211"/>
+ <point x="833" y="211" type="curve" smooth="yes"/>
+ <point x="803" y="211"/>
+ <point x="774" y="183"/>
+ <point x="774" y="153" type="curve" smooth="yes"/>
+ <point x="774" y="133"/>
+ <point x="789" y="119"/>
+ <point x="812" y="119" type="curve" smooth="yes"/>
+ <point x="843" y="119"/>
+ <point x="873" y="146"/>
+ </contour>
+ <contour>
+ <point x="313" y="612" type="curve" smooth="yes"/>
+ <point x="312" y="633"/>
+ <point x="296" y="650"/>
+ <point x="275" y="650" type="curve" smooth="yes"/>
+ <point x="247" y="650"/>
+ <point x="215" y="623"/>
+ <point x="215" y="592" type="curve" smooth="yes"/>
+ <point x="215" y="573"/>
+ <point x="227" y="556"/>
+ <point x="251" y="556" type="curve" smooth="yes"/>
+ <point x="278" y="556"/>
+ <point x="313" y="581"/>
+ </contour>
+ <contour>
+ <point x="994" y="306" type="curve" smooth="yes"/>
+ <point x="993" y="327"/>
+ <point x="978" y="341"/>
+ <point x="958" y="341" type="curve" smooth="yes"/>
+ <point x="933" y="341"/>
+ <point x="896" y="321"/>
+ <point x="896" y="284" type="curve" smooth="yes"/>
+ <point x="896" y="265"/>
+ <point x="909" y="249"/>
+ <point x="934" y="249" type="curve" smooth="yes"/>
+ <point x="963" y="249"/>
+ <point x="994" y="275"/>
+ </contour>
+ <contour>
+ <point x="205" y="495" type="curve" smooth="yes"/>
+ <point x="175" y="495"/>
+ <point x="145" y="468"/>
+ <point x="145" y="438" type="curve" smooth="yes"/>
+ <point x="145" y="418"/>
+ <point x="159" y="402"/>
+ <point x="183" y="402" type="curve" smooth="yes"/>
+ <point x="208" y="402"/>
+ <point x="244" y="428"/>
+ <point x="244" y="459" type="curve" smooth="yes"/>
+ <point x="244" y="479"/>
+ <point x="227" y="495"/>
+ </contour>
+ <contour>
+ <point x="1026" y="496" type="curve" smooth="yes"/>
+ <point x="999" y="496"/>
+ <point x="965" y="469"/>
+ <point x="965" y="438" type="curve" smooth="yes"/>
+ <point x="965" y="418"/>
+ <point x="979" y="403"/>
+ <point x="1004" y="403" type="curve" smooth="yes"/>
+ <point x="1033" y="403"/>
+ <point x="1064" y="431"/>
+ <point x="1064" y="460" type="curve" smooth="yes"/>
+ <point x="1064" y="480"/>
+ <point x="1048" y="496"/>
+ </contour>
+ <contour>
+ <point x="237" y="307" type="curve" smooth="yes"/>
+ <point x="237" y="327"/>
+ <point x="221" y="341"/>
+ <point x="199" y="341" type="curve" smooth="yes"/>
+ <point x="169" y="341"/>
+ <point x="138" y="314"/>
+ <point x="138" y="285" type="curve" smooth="yes"/>
+ <point x="138" y="263"/>
+ <point x="153" y="248"/>
+ <point x="175" y="248" type="curve" smooth="yes"/>
+ <point x="206" y="248"/>
+ <point x="237" y="278"/>
+ </contour>
+ <contour>
+ <point x="1071" y="613" type="curve" smooth="yes"/>
+ <point x="1071" y="634"/>
+ <point x="1055" y="650"/>
+ <point x="1034" y="650" type="curve" smooth="yes"/>
+ <point x="1003" y="650"/>
+ <point x="973" y="619"/>
+ <point x="973" y="590" type="curve" smooth="yes"/>
+ <point x="973" y="570"/>
+ <point x="989" y="556"/>
+ <point x="1009" y="556" type="curve" smooth="yes"/>
+ <point x="1041" y="556"/>
+ <point x="1071" y="585"/>
+ </contour>
+ <contour>
+ <point x="292" y="177" type="curve" smooth="yes"/>
+ <point x="292" y="197"/>
+ <point x="277" y="211"/>
+ <point x="253" y="211" type="curve" smooth="yes"/>
+ <point x="224" y="211"/>
+ <point x="194" y="181"/>
+ <point x="194" y="154" type="curve" smooth="yes"/>
+ <point x="194" y="134"/>
+ <point x="211" y="118"/>
+ <point x="232" y="118" type="curve" smooth="yes"/>
+ <point x="262" y="118"/>
+ <point x="292" y="148"/>
+ </contour>
+ <contour>
+ <point x="917" y="724" type="curve" smooth="yes"/>
+ <point x="917" y="704"/>
+ <point x="931" y="686"/>
+ <point x="954" y="686" type="curve" smooth="yes"/>
+ <point x="984" y="686"/>
+ <point x="1014" y="716"/>
+ <point x="1014" y="745" type="curve" smooth="yes"/>
+ <point x="1014" y="765"/>
+ <point x="1000" y="780"/>
+ <point x="977" y="780" type="curve" smooth="yes"/>
+ <point x="947" y="780"/>
+ <point x="917" y="753"/>
+ </contour>
+ <contour>
+ <point x="403" y="87" type="curve" smooth="yes"/>
+ <point x="403" y="107"/>
+ <point x="390" y="123"/>
+ <point x="367" y="123" type="curve" smooth="yes"/>
+ <point x="339" y="123"/>
+ <point x="305" y="96"/>
+ <point x="305" y="68" type="curve" smooth="yes"/>
+ <point x="305" y="49"/>
+ <point x="320" y="30"/>
+ <point x="343" y="30" type="curve" smooth="yes"/>
+ <point x="371" y="30"/>
+ <point x="403" y="56"/>
+ </contour>
+ <contour>
+ <point x="806" y="810" type="curve" smooth="yes"/>
+ <point x="806" y="791"/>
+ <point x="819" y="773"/>
+ <point x="842" y="773" type="curve" smooth="yes"/>
+ <point x="869" y="773"/>
+ <point x="903" y="799"/>
+ <point x="903" y="830" type="curve" smooth="yes"/>
+ <point x="903" y="850"/>
+ <point x="889" y="867"/>
+ <point x="866" y="867" type="curve" smooth="yes"/>
+ <point x="836" y="867"/>
+ <point x="806" y="839"/>
+ </contour>
+ <contour>
+ <point x="553" y="57" type="curve" smooth="yes"/>
+ <point x="553" y="78"/>
+ <point x="538" y="93"/>
+ <point x="516" y="93" type="curve" smooth="yes"/>
+ <point x="485" y="93"/>
+ <point x="456" y="65"/>
+ <point x="456" y="36" type="curve" smooth="yes"/>
+ <point x="456" y="16"/>
+ <point x="471" y="0"/>
+ <point x="493" y="0" type="curve" smooth="yes"/>
+ <point x="523" y="0"/>
+ <point x="553" y="27"/>
+ </contour>
+ <contour>
+ <point x="656" y="839" type="curve" smooth="yes"/>
+ <point x="656" y="819"/>
+ <point x="671" y="805"/>
+ <point x="693" y="805" type="curve" smooth="yes"/>
+ <point x="721" y="805"/>
+ <point x="754" y="830"/>
+ <point x="754" y="861" type="curve" smooth="yes"/>
+ <point x="754" y="882"/>
+ <point x="738" y="898"/>
+ <point x="716" y="898" type="curve" smooth="yes"/>
+ <point x="685" y="898"/>
+ <point x="656" y="868"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetunicodes.ufo/glyphs/E_qS_gn.glif b/tests/reference/ufo/psfsetunicodes.ufo/glyphs/E_qS_gn.glif
new file mode 100644
index 0000000..3d756e8
--- /dev/null
+++ b/tests/reference/ufo/psfsetunicodes.ufo/glyphs/E_qS_gn.glif
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="EqSgn" format="2">
+ <advance width="1180"/>
+ <unicode hex="003D"/>
+ <outline>
+ <contour>
+ <point x="177" y="470" type="line"/>
+ <point x="1137" y="470" type="line"/>
+ <point x="1173" y="617" type="line"/>
+ <point x="213" y="617" type="line"/>
+ </contour>
+ <contour>
+ <point x="262" y="813" type="line"/>
+ <point x="1222" y="813" type="line"/>
+ <point x="1259" y="960" type="line"/>
+ <point x="299" y="960" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetunicodes.ufo/glyphs/E_xclamationM_rk.glif b/tests/reference/ufo/psfsetunicodes.ufo/glyphs/E_xclamationM_rk.glif
new file mode 100644
index 0000000..a1c14d9
--- /dev/null
+++ b/tests/reference/ufo/psfsetunicodes.ufo/glyphs/E_xclamationM_rk.glif
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="ExclamationMrk" format="2">
+ <advance width="744"/>
+ <unicode hex="0021"/>
+ <outline>
+ <contour>
+ <point x="497" y="431" type="line"/>
+ <point x="574" y="715"/>
+ <point x="653" y="1054"/>
+ <point x="799" y="1480" type="curve"/>
+ <point x="544" y="1480" type="line"/>
+ <point x="475" y="1054"/>
+ <point x="386" y="715"/>
+ <point x="322" y="431" type="curve"/>
+ </contour>
+ <contour>
+ <point x="188" y="90" type="curve" smooth="yes"/>
+ <point x="188" y="28"/>
+ <point x="238" y="-25"/>
+ <point x="303" y="-25" type="curve" smooth="yes"/>
+ <point x="387" y="-25"/>
+ <point x="464" y="45"/>
+ <point x="464" y="125" type="curve" smooth="yes"/>
+ <point x="464" y="186"/>
+ <point x="414" y="240"/>
+ <point x="349" y="240" type="curve" smooth="yes"/>
+ <point x="265" y="240"/>
+ <point x="188" y="170"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetunicodes.ufo/glyphs/F_ullS_top.glif b/tests/reference/ufo/psfsetunicodes.ufo/glyphs/F_ullS_top.glif
new file mode 100644
index 0000000..a6c4d08
--- /dev/null
+++ b/tests/reference/ufo/psfsetunicodes.ufo/glyphs/F_ullS_top.glif
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="FullStop" format="2">
+ <advance width="620"/>
+ <unicode hex="002E"/>
+ <outline>
+ <contour>
+ <point x="148" y="90" type="curve" smooth="yes"/>
+ <point x="148" y="28"/>
+ <point x="198" y="-25"/>
+ <point x="263" y="-25" type="curve" smooth="yes"/>
+ <point x="347" y="-25"/>
+ <point x="424" y="45"/>
+ <point x="424" y="125" type="curve" smooth="yes"/>
+ <point x="424" y="186"/>
+ <point x="374" y="240"/>
+ <point x="309" y="240" type="curve" smooth="yes"/>
+ <point x="225" y="240"/>
+ <point x="148" y="170"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetunicodes.ufo/glyphs/G_T_S_gn.glif b/tests/reference/ufo/psfsetunicodes.ufo/glyphs/G_T_S_gn.glif
new file mode 100644
index 0000000..12da8b3
--- /dev/null
+++ b/tests/reference/ufo/psfsetunicodes.ufo/glyphs/G_T_S_gn.glif
@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="GTSgn" format="2">
+ <advance width="1180"/>
+ <unicode hex="003E"/>
+ <outline>
+ <contour>
+ <point x="312" y="1014" type="line"/>
+ <point x="1028" y="725" type="line"/>
+ <point x="163" y="417" type="line"/>
+ <point x="119" y="240" type="line"/>
+ <point x="1197" y="632" type="line"/>
+ <point x="1239" y="799" type="line"/>
+ <point x="356" y="1191" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetunicodes.ufo/glyphs/G_raveA_ccent.glif b/tests/reference/ufo/psfsetunicodes.ufo/glyphs/G_raveA_ccent.glif
new file mode 100644
index 0000000..48adfc4
--- /dev/null
+++ b/tests/reference/ufo/psfsetunicodes.ufo/glyphs/G_raveA_ccent.glif
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="GraveAccent" format="2">
+ <advance width="560"/>
+ <unicode hex="0060"/>
+ <anchor x="738" y="1635" name="U"/>
+ <outline>
+ <contour>
+ <point x="261" y="1568" type="line"/>
+ <point x="596" y="1147" type="line"/>
+ <point x="746" y="1147" type="line"/>
+ <point x="471" y="1568" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetunicodes.ufo/glyphs/H_yphen.glif b/tests/reference/ufo/psfsetunicodes.ufo/glyphs/H_yphen.glif
new file mode 100644
index 0000000..987a167
--- /dev/null
+++ b/tests/reference/ufo/psfsetunicodes.ufo/glyphs/H_yphen.glif
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="Hyphen" format="2">
+ <advance width="840"/>
+ <unicode hex="002C"/>
+ <anchor x="645" y="1100" name="U"/>
+ <outline>
+ <contour>
+ <point x="155" y="544" type="line"/>
+ <point x="855" y="544" type="line"/>
+ <point x="892" y="691" type="line"/>
+ <point x="192" y="691" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetunicodes.ufo/glyphs/H_yphenM_inus.glif b/tests/reference/ufo/psfsetunicodes.ufo/glyphs/H_yphenM_inus.glif
new file mode 100644
index 0000000..155b460
--- /dev/null
+++ b/tests/reference/ufo/psfsetunicodes.ufo/glyphs/H_yphenM_inus.glif
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="HyphenMinus" format="2">
+ <advance width="840"/>
+ <unicode hex="002D"/>
+ <anchor x="645" y="1100" name="U"/>
+ <outline>
+ <contour>
+ <point x="155" y="544" type="line"/>
+ <point x="855" y="544" type="line"/>
+ <point x="892" y="691" type="line"/>
+ <point x="192" y="691" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetunicodes.ufo/glyphs/H_yphen_S_oft.glif b/tests/reference/ufo/psfsetunicodes.ufo/glyphs/H_yphen_S_oft.glif
new file mode 100644
index 0000000..0c7b834
--- /dev/null
+++ b/tests/reference/ufo/psfsetunicodes.ufo/glyphs/H_yphen_S_oft.glif
@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="Hyphen_Soft" format="2">
+ <advance width="840"/>
+ <unicode hex="00AD"/>
+ <anchor x="645" y="1100" name="U"/>
+ <outline>
+ <component base="HyphenMinus"/>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetunicodes.ufo/glyphs/L_T_S_gn.glif b/tests/reference/ufo/psfsetunicodes.ufo/glyphs/L_T_S_gn.glif
new file mode 100644
index 0000000..3c857a5
--- /dev/null
+++ b/tests/reference/ufo/psfsetunicodes.ufo/glyphs/L_T_S_gn.glif
@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LTSgn" format="2">
+ <advance width="1180"/>
+ <unicode hex="003C"/>
+ <outline>
+ <contour>
+ <point x="1123" y="417" type="line"/>
+ <point x="408" y="705" type="line"/>
+ <point x="1272" y="1014" type="line"/>
+ <point x="1316" y="1191" type="line"/>
+ <point x="239" y="799" type="line"/>
+ <point x="197" y="632" type="line"/>
+ <point x="1079" y="240" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetunicodes.ufo/glyphs/L_ftC_urlyB_rac.glif b/tests/reference/ufo/psfsetunicodes.ufo/glyphs/L_ftC_urlyB_rac.glif
new file mode 100644
index 0000000..4f8c90c
--- /dev/null
+++ b/tests/reference/ufo/psfsetunicodes.ufo/glyphs/L_ftC_urlyB_rac.glif
@@ -0,0 +1,50 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LftCurlyBrac" format="2">
+ <advance width="980"/>
+ <unicode hex="007B"/>
+ <outline>
+ <contour>
+ <point x="713" y="-265" type="line"/>
+ <point x="660" y="-250"/>
+ <point x="526" y="-188"/>
+ <point x="526" y="-158" type="curve" smooth="yes"/>
+ <point x="526" y="-59"/>
+ <point x="649" y="404"/>
+ <point x="649" y="469" type="curve" smooth="yes"/>
+ <point x="649" y="509"/>
+ <point x="520" y="577"/>
+ <point x="520" y="602" type="curve" smooth="yes"/>
+ <point x="520" y="620"/>
+ <point x="688" y="700"/>
+ <point x="712" y="730" type="curve" smooth="yes"/>
+ <point x="741" y="767"/>
+ <point x="867" y="1326"/>
+ <point x="912" y="1372" type="curve" smooth="yes"/>
+ <point x="938" y="1399"/>
+ <point x="1073" y="1447"/>
+ <point x="1146" y="1470" type="curve"/>
+ <point x="1140" y="1607" type="line"/>
+ <point x="1030" y="1581"/>
+ <point x="856" y="1529"/>
+ <point x="805" y="1485" type="curve" smooth="yes"/>
+ <point x="714" y="1406"/>
+ <point x="572" y="796"/>
+ <point x="540" y="764" type="curve" smooth="yes"/>
+ <point x="504" y="729"/>
+ <point x="300" y="633"/>
+ <point x="300" y="601" type="curve" smooth="yes"/>
+ <point x="300" y="560"/>
+ <point x="460" y="468"/>
+ <point x="460" y="432" type="curve" smooth="yes"/>
+ <point x="460" y="362"/>
+ <point x="355" y="-53"/>
+ <point x="355" y="-219" type="curve" smooth="yes"/>
+ <point x="355" y="-247"/>
+ <point x="358" y="-268"/>
+ <point x="365" y="-279" type="curve" smooth="yes"/>
+ <point x="394" y="-323"/>
+ <point x="542" y="-375"/>
+ <point x="639" y="-402" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetunicodes.ufo/glyphs/L_ftP_aren.glif b/tests/reference/ufo/psfsetunicodes.ufo/glyphs/L_ftP_aren.glif
new file mode 100644
index 0000000..bc65fc1
--- /dev/null
+++ b/tests/reference/ufo/psfsetunicodes.ufo/glyphs/L_ftP_aren.glif
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LftParen" format="2">
+ <advance width="775"/>
+ <unicode hex="0028"/>
+ <outline>
+ <contour>
+ <point x="895" y="1607" type="line"/>
+ <point x="582" y="1415"/>
+ <point x="314" y="1061"/>
+ <point x="207" y="633" type="curve" smooth="yes"/>
+ <point x="176" y="508"/>
+ <point x="161" y="386"/>
+ <point x="161" y="270" type="curve" smooth="yes"/>
+ <point x="161" y="17"/>
+ <point x="233" y="-211"/>
+ <point x="374" y="-402" type="curve"/>
+ <point x="505" y="-260" type="line"/>
+ <point x="397" y="-102"/>
+ <point x="348" y="75"/>
+ <point x="348" y="270" type="curve" smooth="yes"/>
+ <point x="348" y="385"/>
+ <point x="365" y="506"/>
+ <point x="397" y="633" type="curve" smooth="yes"/>
+ <point x="484" y="982"/>
+ <point x="647" y="1254"/>
+ <point x="932" y="1455" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetunicodes.ufo/glyphs/L_ftS_qrB_rac.glif b/tests/reference/ufo/psfsetunicodes.ufo/glyphs/L_ftS_qrB_rac.glif
new file mode 100644
index 0000000..6d064d1
--- /dev/null
+++ b/tests/reference/ufo/psfsetunicodes.ufo/glyphs/L_ftS_qrB_rac.glif
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LftSqrBrac" format="2">
+ <advance width="770"/>
+ <unicode hex="005B"/>
+ <outline>
+ <contour>
+ <point x="484" y="-402" type="line"/>
+ <point x="521" y="-255" type="line"/>
+ <point x="266" y="-255" type="line"/>
+ <point x="679" y="1421" type="line"/>
+ <point x="934" y="1421" type="line"/>
+ <point x="970" y="1568" type="line"/>
+ <point x="530" y="1568" type="line"/>
+ <point x="44" y="-402" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetunicodes.ufo/glyphs/L_owL_ine.glif b/tests/reference/ufo/psfsetunicodes.ufo/glyphs/L_owL_ine.glif
new file mode 100644
index 0000000..879d36b
--- /dev/null
+++ b/tests/reference/ufo/psfsetunicodes.ufo/glyphs/L_owL_ine.glif
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LowLine" format="2">
+ <advance width="1254"/>
+ <unicode hex="005F"/>
+ <outline>
+ <contour>
+ <point x="-138" y="-314" type="line"/>
+ <point x="1135" y="-314" type="line"/>
+ <point x="1172" y="-167" type="line"/>
+ <point x="-101" y="-167" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetunicodes.ufo/glyphs/L_tnC_apA_.glif b/tests/reference/ufo/psfsetunicodes.ufo/glyphs/L_tnC_apA_.glif
new file mode 100644
index 0000000..3a14b0e
--- /dev/null
+++ b/tests/reference/ufo/psfsetunicodes.ufo/glyphs/L_tnC_apA_.glif
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnCapA" format="2">
+ <advance width="1395"/>
+ <unicode hex="0041"/>
+ <anchor x="1170" y="0" name="H"/>
+ <anchor x="602" y="-100" name="L"/>
+ <anchor x="1390" y="0" name="O"/>
+ <anchor x="1009" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="1080" y="0" type="line"/>
+ <point x="1275" y="0" type="line"/>
+ <point x="1259" y="78"/>
+ <point x="1243" y="166"/>
+ <point x="1221" y="348" type="curve" smooth="yes"/>
+ <point x="1091" y="1431" type="line"/>
+ <point x="876" y="1431" type="line"/>
+ <point x="206" y="348" type="line" smooth="yes"/>
+ <point x="93" y="165"/>
+ <point x="35" y="79"/>
+ <point x="-20" y="0" type="curve"/>
+ <point x="195" y="0" type="line"/>
+ <point x="422" y="377" type="line"/>
+ <point x="1038" y="377" type="line"/>
+ </contour>
+ <contour>
+ <point x="944" y="1240" type="line"/>
+ <point x="1022" y="529" type="line"/>
+ <point x="514" y="529" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetunicodes.ufo/glyphs/L_tnC_apA_D_iaer.glif b/tests/reference/ufo/psfsetunicodes.ufo/glyphs/L_tnC_apA_D_iaer.glif
new file mode 100644
index 0000000..6c3502c
--- /dev/null
+++ b/tests/reference/ufo/psfsetunicodes.ufo/glyphs/L_tnC_apA_D_iaer.glif
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnCapADiaer" format="2">
+ <advance width="1395"/>
+ <unicode hex="00C4"/>
+ <anchor x="1170" y="0" name="H"/>
+ <anchor x="602" y="-100" name="L"/>
+ <anchor x="1390" y="0" name="O"/>
+ <anchor x="1106" y="1935" name="U"/>
+ <outline>
+ <component base="LtnCapA"/>
+ <component base="CombDiaer" xOffset="1359" yOffset="430"/>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetunicodes.ufo/glyphs/L_tnC_apB_.glif b/tests/reference/ufo/psfsetunicodes.ufo/glyphs/L_tnC_apB_.glif
new file mode 100644
index 0000000..5445f93
--- /dev/null
+++ b/tests/reference/ufo/psfsetunicodes.ufo/glyphs/L_tnC_apB_.glif
@@ -0,0 +1,62 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnCapB" format="2">
+ <advance width="1271"/>
+ <unicode hex="0042"/>
+ <anchor x="530" y="-100" name="L"/>
+ <anchor x="937" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="625" y="1284" type="line"/>
+ <point x="667" y="1286"/>
+ <point x="733" y="1289"/>
+ <point x="811" y="1289" type="curve" smooth="yes"/>
+ <point x="993" y="1289"/>
+ <point x="1080" y="1230"/>
+ <point x="1080" y="1105" type="curve" smooth="yes"/>
+ <point x="1080" y="932"/>
+ <point x="931" y="838"/>
+ <point x="698" y="838" type="curve" smooth="yes"/>
+ <point x="513" y="838" type="line"/>
+ </contour>
+ <contour>
+ <point x="226" y="446" type="line"/>
+ <point x="178" y="252"/>
+ <point x="134" y="78"/>
+ <point x="100" y="0" type="curve"/>
+ <point x="151" y="-5"/>
+ <point x="359" y="-10"/>
+ <point x="562" y="-10" type="curve" smooth="yes"/>
+ <point x="960" y="-10"/>
+ <point x="1201" y="149"/>
+ <point x="1201" y="453" type="curve" smooth="yes"/>
+ <point x="1201" y="644"/>
+ <point x="1067" y="736"/>
+ <point x="955" y="764" type="curve"/>
+ <point x="1155" y="819"/>
+ <point x="1283" y="941"/>
+ <point x="1283" y="1140" type="curve" smooth="yes"/>
+ <point x="1283" y="1310"/>
+ <point x="1136" y="1441"/>
+ <point x="869" y="1441" type="curve" smooth="yes"/>
+ <point x="700" y="1441"/>
+ <point x="546" y="1437"/>
+ <point x="456" y="1431" type="curve"/>
+ <point x="452" y="1352"/>
+ <point x="407" y="1172"/>
+ <point x="359" y="980" type="curve" smooth="yes"/>
+ </contour>
+ <contour>
+ <point x="476" y="686" type="line"/>
+ <point x="721" y="686" type="line" smooth="yes"/>
+ <point x="892" y="686"/>
+ <point x="1011" y="598"/>
+ <point x="1011" y="450" type="curve" smooth="yes"/>
+ <point x="1011" y="218"/>
+ <point x="806" y="147"/>
+ <point x="586" y="147" type="curve" smooth="yes"/>
+ <point x="474" y="147"/>
+ <point x="379" y="150"/>
+ <point x="342" y="152" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetunicodes.ufo/glyphs/L_tnC_apC_.glif b/tests/reference/ufo/psfsetunicodes.ufo/glyphs/L_tnC_apC_.glif
new file mode 100644
index 0000000..c2e4948
--- /dev/null
+++ b/tests/reference/ufo/psfsetunicodes.ufo/glyphs/L_tnC_apC_.glif
@@ -0,0 +1,38 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnCapC" format="2">
+ <advance width="1341"/>
+ <unicode hex="0043"/>
+ <anchor x="690" y="0" name="H"/>
+ <anchor x="665" y="-100" name="L"/>
+ <anchor x="1072" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="1237" y="318" type="line"/>
+ <point x="1115" y="222"/>
+ <point x="934" y="147"/>
+ <point x="752" y="147" type="curve" smooth="yes"/>
+ <point x="537" y="147"/>
+ <point x="385" y="304"/>
+ <point x="385" y="532" type="curve" smooth="yes"/>
+ <point x="385" y="964"/>
+ <point x="704" y="1289"/>
+ <point x="1037" y="1289" type="curve" smooth="yes"/>
+ <point x="1168" y="1289"/>
+ <point x="1310" y="1235"/>
+ <point x="1385" y="1132" type="curve"/>
+ <point x="1489" y="1308" type="line"/>
+ <point x="1388" y="1408"/>
+ <point x="1201" y="1455"/>
+ <point x="1058" y="1455" type="curve" smooth="yes"/>
+ <point x="645" y="1455"/>
+ <point x="185" y="1093"/>
+ <point x="185" y="513" type="curve" smooth="yes"/>
+ <point x="185" y="202"/>
+ <point x="381" y="-25"/>
+ <point x="709" y="-25" type="curve" smooth="yes"/>
+ <point x="896" y="-25"/>
+ <point x="1087" y="21"/>
+ <point x="1230" y="127" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetunicodes.ufo/glyphs/L_tnC_apD_.glif b/tests/reference/ufo/psfsetunicodes.ufo/glyphs/L_tnC_apD_.glif
new file mode 100644
index 0000000..3b93811
--- /dev/null
+++ b/tests/reference/ufo/psfsetunicodes.ufo/glyphs/L_tnC_apD_.glif
@@ -0,0 +1,51 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnCapD" format="2">
+ <advance width="1421"/>
+ <unicode hex="0044"/>
+ <anchor x="630" y="-100" name="L"/>
+ <anchor x="1037" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="226" y="446" type="line"/>
+ <point x="176" y="252"/>
+ <point x="134" y="78"/>
+ <point x="100" y="0" type="curve"/>
+ <point x="100" y="0"/>
+ <point x="414" y="-10"/>
+ <point x="542" y="-10" type="curve" smooth="yes"/>
+ <point x="985" y="-10"/>
+ <point x="1299" y="181"/>
+ <point x="1415" y="648" type="curve" smooth="yes"/>
+ <point x="1437" y="738"/>
+ <point x="1447" y="819"/>
+ <point x="1447" y="891" type="curve" smooth="yes"/>
+ <point x="1447" y="1279"/>
+ <point x="1188" y="1441"/>
+ <point x="894" y="1441" type="curve" smooth="yes"/>
+ <point x="759" y="1441"/>
+ <point x="543" y="1437"/>
+ <point x="456" y="1431" type="curve"/>
+ <point x="452" y="1352"/>
+ <point x="407" y="1172"/>
+ <point x="359" y="980" type="curve" smooth="yes"/>
+ </contour>
+ <contour>
+ <point x="623" y="1279" type="line"/>
+ <point x="674" y="1281"/>
+ <point x="764" y="1284"/>
+ <point x="830" y="1284" type="curve" smooth="yes"/>
+ <point x="1105" y="1284"/>
+ <point x="1246" y="1140"/>
+ <point x="1246" y="850" type="curve" smooth="yes"/>
+ <point x="1246" y="784"/>
+ <point x="1236" y="710"/>
+ <point x="1216" y="629" type="curve" smooth="yes"/>
+ <point x="1134" y="300"/>
+ <point x="925" y="152"/>
+ <point x="572" y="152" type="curve" smooth="yes"/>
+ <point x="477" y="152"/>
+ <point x="391" y="158"/>
+ <point x="345" y="162" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetunicodes.ufo/glyphs/L_tnC_apE_.glif b/tests/reference/ufo/psfsetunicodes.ufo/glyphs/L_tnC_apE_.glif
new file mode 100644
index 0000000..8b5f8b9
--- /dev/null
+++ b/tests/reference/ufo/psfsetunicodes.ufo/glyphs/L_tnC_apE_.glif
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnCapE" format="2">
+ <advance width="1140"/>
+ <unicode hex="0045"/>
+ <anchor x="540" y="0" name="H"/>
+ <anchor x="515" y="-100" name="L"/>
+ <anchor x="857" y="0" name="O"/>
+ <anchor x="1400" y="1200" name="R"/>
+ <anchor x="922" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="511" y="828" type="line"/>
+ <point x="621" y="1269" type="line"/>
+ <point x="1266" y="1269" type="line"/>
+ <point x="1306" y="1431" type="line"/>
+ <point x="456" y="1431" type="line"/>
+ <point x="452" y="1352"/>
+ <point x="413" y="1197"/>
+ <point x="365" y="1005" type="curve" smooth="yes"/>
+ <point x="221" y="426" type="line" smooth="yes"/>
+ <point x="173" y="233"/>
+ <point x="134" y="78"/>
+ <point x="100" y="0" type="curve"/>
+ <point x="980" y="0" type="line"/>
+ <point x="1023" y="176" type="line"/>
+ <point x="940" y="163"/>
+ <point x="806" y="162"/>
+ <point x="609" y="162" type="curve" smooth="yes"/>
+ <point x="345" y="162" type="line"/>
+ <point x="472" y="671" type="line"/>
+ <point x="1042" y="671" type="line"/>
+ <point x="1081" y="828" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetunicodes.ufo/glyphs/L_tnC_apF_.glif b/tests/reference/ufo/psfsetunicodes.ufo/glyphs/L_tnC_apF_.glif
new file mode 100644
index 0000000..cbc1726
--- /dev/null
+++ b/tests/reference/ufo/psfsetunicodes.ufo/glyphs/L_tnC_apF_.glif
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnCapF" format="2">
+ <advance width="1130"/>
+ <unicode hex="0046"/>
+ <anchor x="510" y="-100" name="L"/>
+ <anchor x="917" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="508" y="818" type="line"/>
+ <point x="621" y="1269" type="line"/>
+ <point x="1286" y="1269" type="line"/>
+ <point x="1326" y="1431" type="line"/>
+ <point x="456" y="1431" type="line"/>
+ <point x="452" y="1352"/>
+ <point x="412" y="1193"/>
+ <point x="364" y="1000" type="curve" smooth="yes"/>
+ <point x="221" y="426" type="line" smooth="yes"/>
+ <point x="173" y="233"/>
+ <point x="134" y="78"/>
+ <point x="100" y="0" type="curve"/>
+ <point x="320" y="0" type="line"/>
+ <point x="323" y="76"/>
+ <point x="362" y="232"/>
+ <point x="411" y="426" type="curve" smooth="yes"/>
+ <point x="470" y="662" type="line"/>
+ <point x="1050" y="662" type="line"/>
+ <point x="1088" y="818" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetunicodes.ufo/glyphs/L_tnC_apG_.glif b/tests/reference/ufo/psfsetunicodes.ufo/glyphs/L_tnC_apG_.glif
new file mode 100644
index 0000000..c39b75a
--- /dev/null
+++ b/tests/reference/ufo/psfsetunicodes.ufo/glyphs/L_tnC_apG_.glif
@@ -0,0 +1,48 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnCapG" format="2">
+ <advance width="1406"/>
+ <unicode hex="0047"/>
+ <anchor x="685" y="0" name="H"/>
+ <anchor x="660" y="-100" name="L"/>
+ <anchor x="1067" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="1403" y="710" type="line"/>
+ <point x="863" y="710" type="line"/>
+ <point x="822" y="548" type="line"/>
+ <point x="1172" y="548" type="line"/>
+ <point x="1090" y="220" type="line"/>
+ <point x="1012" y="176"/>
+ <point x="858" y="147"/>
+ <point x="739" y="147" type="curve" smooth="yes"/>
+ <point x="520" y="147"/>
+ <point x="384" y="272"/>
+ <point x="384" y="493" type="curve" smooth="yes"/>
+ <point x="384" y="560"/>
+ <point x="394" y="636"/>
+ <point x="415" y="720" type="curve" smooth="yes"/>
+ <point x="500" y="1062"/>
+ <point x="747" y="1289"/>
+ <point x="1052" y="1289" type="curve" smooth="yes"/>
+ <point x="1195" y="1289"/>
+ <point x="1335" y="1233"/>
+ <point x="1425" y="1122" type="curve"/>
+ <point x="1534" y="1298" type="line"/>
+ <point x="1409" y="1405"/>
+ <point x="1235" y="1455"/>
+ <point x="1063" y="1455" type="curve" smooth="yes"/>
+ <point x="680" y="1455"/>
+ <point x="334" y="1195"/>
+ <point x="217" y="726" type="curve" smooth="yes"/>
+ <point x="195" y="639"/>
+ <point x="185" y="559"/>
+ <point x="185" y="486" type="curve" smooth="yes"/>
+ <point x="185" y="162"/>
+ <point x="406" y="-25"/>
+ <point x="714" y="-25" type="curve" smooth="yes"/>
+ <point x="907" y="-25"/>
+ <point x="1149" y="50"/>
+ <point x="1258" y="132" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetunicodes.ufo/glyphs/L_tnC_apH_.glif b/tests/reference/ufo/psfsetunicodes.ufo/glyphs/L_tnC_apH_.glif
new file mode 100644
index 0000000..f454288
--- /dev/null
+++ b/tests/reference/ufo/psfsetunicodes.ufo/glyphs/L_tnC_apH_.glif
@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnCapH" format="2">
+ <advance width="1455"/>
+ <unicode hex="0048"/>
+ <anchor x="225" y="0" name="H"/>
+ <anchor x="640" y="-100" name="L"/>
+ <anchor x="1047" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="1230" y="0" type="line"/>
+ <point x="1234" y="78"/>
+ <point x="1273" y="233"/>
+ <point x="1321" y="426" type="curve" smooth="yes"/>
+ <point x="1465" y="1005" type="line" smooth="yes"/>
+ <point x="1513" y="1198"/>
+ <point x="1552" y="1352"/>
+ <point x="1586" y="1431" type="curve"/>
+ <point x="1381" y="1431" type="line"/>
+ <point x="1228" y="818" type="line"/>
+ <point x="508" y="818" type="line"/>
+ <point x="661" y="1431" type="line"/>
+ <point x="456" y="1431" type="line"/>
+ <point x="452" y="1352"/>
+ <point x="413" y="1197"/>
+ <point x="365" y="1005" type="curve" smooth="yes"/>
+ <point x="221" y="426" type="line" smooth="yes"/>
+ <point x="173" y="233"/>
+ <point x="134" y="78"/>
+ <point x="100" y="0" type="curve"/>
+ <point x="305" y="0" type="line"/>
+ <point x="470" y="662" type="line"/>
+ <point x="1190" y="662" type="line"/>
+ <point x="1025" y="0" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetunicodes.ufo/glyphs/L_tnC_apI_.glif b/tests/reference/ufo/psfsetunicodes.ufo/glyphs/L_tnC_apI_.glif
new file mode 100644
index 0000000..78b151c
--- /dev/null
+++ b/tests/reference/ufo/psfsetunicodes.ufo/glyphs/L_tnC_apI_.glif
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnCapI" format="2">
+ <advance width="955"/>
+ <unicode hex="0049"/>
+ <anchor x="417" y="0" name="H"/>
+ <anchor x="392" y="-100" name="L"/>
+ <anchor x="613" y="0" name="O"/>
+ <anchor x="1215" y="1200" name="R"/>
+ <anchor x="799" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="436" y="1431" type="line"/>
+ <point x="401" y="1289" type="line"/>
+ <point x="641" y="1289" type="line"/>
+ <point x="355" y="142" type="line"/>
+ <point x="115" y="142" type="line"/>
+ <point x="80" y="0" type="line"/>
+ <point x="755" y="0" type="line"/>
+ <point x="790" y="142" type="line"/>
+ <point x="545" y="142" type="line"/>
+ <point x="831" y="1289" type="line"/>
+ <point x="1076" y="1289" type="line"/>
+ <point x="1111" y="1431" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetunicodes.ufo/glyphs/L_tnC_apJ_.glif b/tests/reference/ufo/psfsetunicodes.ufo/glyphs/L_tnC_apJ_.glif
new file mode 100644
index 0000000..417d1f8
--- /dev/null
+++ b/tests/reference/ufo/psfsetunicodes.ufo/glyphs/L_tnC_apJ_.glif
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnCapJ" format="2">
+ <advance width="996"/>
+ <unicode hex="004A"/>
+ <anchor x="325" y="-100" name="L"/>
+ <anchor x="997" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="871" y="1431" type="line"/>
+ <point x="858" y="1327"/>
+ <point x="817" y="1151"/>
+ <point x="769" y="960" type="curve" smooth="yes"/>
+ <point x="648" y="475" type="line" smooth="yes"/>
+ <point x="592" y="251"/>
+ <point x="484" y="152"/>
+ <point x="337" y="152" type="curve" smooth="yes"/>
+ <point x="245" y="152"/>
+ <point x="145" y="224"/>
+ <point x="97" y="299" type="curve"/>
+ <point x="6" y="118" type="line"/>
+ <point x="58" y="39"/>
+ <point x="193" y="-25"/>
+ <point x="298" y="-25" type="curve" smooth="yes"/>
+ <point x="555" y="-25"/>
+ <point x="749" y="117"/>
+ <point x="850" y="524" type="curve" smooth="yes"/>
+ <point x="1076" y="1431" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetunicodes.ufo/glyphs/L_tnC_apK_.glif b/tests/reference/ufo/psfsetunicodes.ufo/glyphs/L_tnC_apK_.glif
new file mode 100644
index 0000000..8e54a6d
--- /dev/null
+++ b/tests/reference/ufo/psfsetunicodes.ufo/glyphs/L_tnC_apK_.glif
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnCapK" format="2">
+ <advance width="1261"/>
+ <unicode hex="004B"/>
+ <anchor x="210" y="0" name="H"/>
+ <anchor x="610" y="-100" name="L"/>
+ <anchor x="972" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="1221" y="1431" type="line"/>
+ <point x="406" y="689" type="line"/>
+ <point x="547" y="730" type="line"/>
+ <point x="660" y="725" type="line"/>
+ <point x="1461" y="1431" type="line"/>
+ </contour>
+ <contour>
+ <point x="1170" y="0" type="line"/>
+ <point x="615" y="823" type="line"/>
+ <point x="469" y="720" type="line"/>
+ <point x="925" y="0" type="line"/>
+ </contour>
+ <contour>
+ <point x="661" y="1431" type="line"/>
+ <point x="456" y="1431" type="line"/>
+ <point x="452" y="1352"/>
+ <point x="413" y="1197"/>
+ <point x="365" y="1005" type="curve" smooth="yes"/>
+ <point x="221" y="426" type="line" smooth="yes"/>
+ <point x="173" y="233"/>
+ <point x="134" y="78"/>
+ <point x="100" y="0" type="curve"/>
+ <point x="305" y="0" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetunicodes.ufo/glyphs/L_tnC_apL_.glif b/tests/reference/ufo/psfsetunicodes.ufo/glyphs/L_tnC_apL_.glif
new file mode 100644
index 0000000..d2eb932
--- /dev/null
+++ b/tests/reference/ufo/psfsetunicodes.ufo/glyphs/L_tnC_apL_.glif
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnCapL" format="2">
+ <advance width="1060"/>
+ <unicode hex="004C"/>
+ <anchor x="532" y="0" name="H"/>
+ <anchor x="507" y="-100" name="L"/>
+ <anchor x="780" y="1200" name="R"/>
+ <anchor x="914" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="345" y="162" type="line"/>
+ <point x="661" y="1431" type="line"/>
+ <point x="456" y="1431" type="line"/>
+ <point x="452" y="1352"/>
+ <point x="413" y="1197"/>
+ <point x="365" y="1005" type="curve" smooth="yes"/>
+ <point x="221" y="426" type="line" smooth="yes"/>
+ <point x="173" y="233"/>
+ <point x="134" y="78"/>
+ <point x="100" y="0" type="curve"/>
+ <point x="965" y="0" type="line"/>
+ <point x="1008" y="176" type="line"/>
+ <point x="925" y="163"/>
+ <point x="766" y="162"/>
+ <point x="569" y="162" type="curve" smooth="yes"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetunicodes.ufo/glyphs/L_tnC_apM_.glif b/tests/reference/ufo/psfsetunicodes.ufo/glyphs/L_tnC_apM_.glif
new file mode 100644
index 0000000..7c3c824
--- /dev/null
+++ b/tests/reference/ufo/psfsetunicodes.ufo/glyphs/L_tnC_apM_.glif
@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnCapM" format="2">
+ <advance width="1785"/>
+ <unicode hex="004D"/>
+ <anchor x="800" y="-100" name="L"/>
+ <anchor x="1207" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="880" y="201" type="line"/>
+ <point x="751" y="1431" type="line"/>
+ <point x="591" y="1431" type="line"/>
+ <point x="740" y="0" type="line"/>
+ <point x="935" y="0" type="line"/>
+ <point x="1793" y="1431" type="line"/>
+ <point x="1616" y="1431" type="line"/>
+ </contour>
+ <contour>
+ <point x="536" y="1431" type="line"/>
+ <point x="536" y="1431"/>
+ <point x="184" y="194"/>
+ <point x="110" y="0" type="curve"/>
+ <point x="295" y="0" type="line"/>
+ <point x="621" y="1181" type="line"/>
+ <point x="711" y="1431" type="line"/>
+ </contour>
+ <contour>
+ <point x="1560" y="0" type="line"/>
+ <point x="1579" y="194"/>
+ <point x="1846" y="1431"/>
+ <point x="1846" y="1431" type="curve"/>
+ <point x="1671" y="1431" type="line"/>
+ <point x="1641" y="1181" type="line"/>
+ <point x="1375" y="0" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetunicodes.ufo/glyphs/L_tnC_apN_.glif b/tests/reference/ufo/psfsetunicodes.ufo/glyphs/L_tnC_apN_.glif
new file mode 100644
index 0000000..7306669
--- /dev/null
+++ b/tests/reference/ufo/psfsetunicodes.ufo/glyphs/L_tnC_apN_.glif
@@ -0,0 +1,37 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnCapN" format="2">
+ <advance width="1480"/>
+ <unicode hex="004E"/>
+ <anchor x="1170" y="0" name="H"/>
+ <anchor x="652" y="-100" name="L"/>
+ <anchor x="1059" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="491" y="1328" type="line"/>
+ <point x="1075" y="0" type="line"/>
+ <point x="1219" y="98" type="line"/>
+ <point x="636" y="1431" type="line"/>
+ </contour>
+ <contour>
+ <point x="1075" y="0" type="line"/>
+ <point x="1250" y="0" type="line"/>
+ <point x="1500" y="1005" type="line" smooth="yes"/>
+ <point x="1548" y="1198"/>
+ <point x="1588" y="1352"/>
+ <point x="1621" y="1431" type="curve"/>
+ <point x="1431" y="1431" type="line"/>
+ </contour>
+ <contour>
+ <point x="636" y="1431" type="line"/>
+ <point x="446" y="1431" type="line"/>
+ <point x="442" y="1352"/>
+ <point x="403" y="1197"/>
+ <point x="355" y="1005" type="curve" smooth="yes"/>
+ <point x="211" y="426" type="line" smooth="yes"/>
+ <point x="163" y="233"/>
+ <point x="124" y="78"/>
+ <point x="90" y="0" type="curve"/>
+ <point x="280" y="0" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetunicodes.ufo/glyphs/L_tnC_apO_.glif b/tests/reference/ufo/psfsetunicodes.ufo/glyphs/L_tnC_apO_.glif
new file mode 100644
index 0000000..19c4886
--- /dev/null
+++ b/tests/reference/ufo/psfsetunicodes.ufo/glyphs/L_tnC_apO_.glif
@@ -0,0 +1,40 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnCapO" format="2">
+ <advance width="1447"/>
+ <unicode hex="004F"/>
+ <anchor x="657" y="0" name="H"/>
+ <anchor x="632" y="-100" name="L"/>
+ <anchor x="896" y="0" name="O"/>
+ <anchor x="1700" y="1200" name="R"/>
+ <anchor x="1039" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="719" y="147" type="curve" smooth="yes"/>
+ <point x="514" y="147"/>
+ <point x="386" y="300"/>
+ <point x="386" y="541" type="curve" smooth="yes"/>
+ <point x="386" y="871"/>
+ <point x="606" y="1284"/>
+ <point x="963" y="1284" type="curve" smooth="yes"/>
+ <point x="1164" y="1284"/>
+ <point x="1291" y="1133"/>
+ <point x="1291" y="892" type="curve" smooth="yes"/>
+ <point x="1291" y="563"/>
+ <point x="1077" y="147"/>
+ </contour>
+ <contour>
+ <point x="1492" y="931" type="curve" smooth="yes"/>
+ <point x="1492" y="1263"/>
+ <point x="1278" y="1455"/>
+ <point x="1015" y="1455" type="curve" smooth="yes"/>
+ <point x="599" y="1455"/>
+ <point x="185" y="1036"/>
+ <point x="185" y="500" type="curve" smooth="yes"/>
+ <point x="185" y="167"/>
+ <point x="400" y="-25"/>
+ <point x="666" y="-25" type="curve" smooth="yes"/>
+ <point x="1078" y="-25"/>
+ <point x="1492" y="395"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetunicodes.ufo/glyphs/L_tnC_apP_.glif b/tests/reference/ufo/psfsetunicodes.ufo/glyphs/L_tnC_apP_.glif
new file mode 100644
index 0000000..5b51a57
--- /dev/null
+++ b/tests/reference/ufo/psfsetunicodes.ufo/glyphs/L_tnC_apP_.glif
@@ -0,0 +1,50 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnCapP" format="2">
+ <advance width="1190"/>
+ <unicode hex="0050"/>
+ <anchor x="552" y="-100" name="L"/>
+ <anchor x="959" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="443" y="554" type="line"/>
+ <point x="506" y="547"/>
+ <point x="597" y="544"/>
+ <point x="670" y="544" type="curve" smooth="yes"/>
+ <point x="1058" y="544"/>
+ <point x="1321" y="733"/>
+ <point x="1321" y="1084" type="curve" smooth="yes"/>
+ <point x="1321" y="1302"/>
+ <point x="1141" y="1441"/>
+ <point x="864" y="1441" type="curve" smooth="yes"/>
+ <point x="651" y="1441"/>
+ <point x="456" y="1431"/>
+ <point x="456" y="1431" type="curve"/>
+ <point x="452" y="1352"/>
+ <point x="407" y="1172"/>
+ <point x="359" y="980" type="curve"/>
+ <point x="221" y="426" type="line" smooth="yes"/>
+ <point x="173" y="233"/>
+ <point x="134" y="78"/>
+ <point x="100" y="0" type="curve"/>
+ <point x="320" y="0" type="line"/>
+ <point x="324" y="76"/>
+ <point x="362" y="232"/>
+ <point x="411" y="426" type="curve" smooth="yes"/>
+ </contour>
+ <contour>
+ <point x="623" y="1279" type="line"/>
+ <point x="692" y="1282"/>
+ <point x="721" y="1284"/>
+ <point x="815" y="1284" type="curve" smooth="yes"/>
+ <point x="1036" y="1284"/>
+ <point x="1121" y="1172"/>
+ <point x="1121" y="1048" type="curve" smooth="yes"/>
+ <point x="1121" y="845"/>
+ <point x="968" y="696"/>
+ <point x="693" y="696" type="curve" smooth="yes"/>
+ <point x="618" y="696"/>
+ <point x="542" y="698"/>
+ <point x="481" y="706" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetunicodes.ufo/glyphs/L_tnC_apQ_.glif b/tests/reference/ufo/psfsetunicodes.ufo/glyphs/L_tnC_apQ_.glif
new file mode 100644
index 0000000..3dcbc8d
--- /dev/null
+++ b/tests/reference/ufo/psfsetunicodes.ufo/glyphs/L_tnC_apQ_.glif
@@ -0,0 +1,52 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnCapQ" format="2">
+ <advance width="1459"/>
+ <unicode hex="0051"/>
+ <anchor x="589" y="-270" name="L"/>
+ <anchor x="1039" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="1495" y="939" type="curve" smooth="yes"/>
+ <point x="1495" y="1266"/>
+ <point x="1306" y="1455"/>
+ <point x="1026" y="1455" type="curve" smooth="yes"/>
+ <point x="703" y="1455"/>
+ <point x="332" y="1195"/>
+ <point x="215" y="726" type="curve" smooth="yes"/>
+ <point x="194" y="642"/>
+ <point x="185" y="564"/>
+ <point x="185" y="492" type="curve" smooth="yes"/>
+ <point x="185" y="165"/>
+ <point x="388" y="-25"/>
+ <point x="652" y="-25" type="curve" smooth="yes"/>
+ <point x="714" y="-25"/>
+ <point x="781" y="-17"/>
+ <point x="829" y="0" type="curve"/>
+ <point x="898" y="0"/>
+ <point x="1133" y="-186"/>
+ <point x="1217" y="-186" type="curve" smooth="yes"/>
+ <point x="1271" y="-186"/>
+ <point x="1355" y="-79"/>
+ <point x="1388" y="-44" type="curve"/>
+ <point x="1258" y="-27"/>
+ <point x="1155" y="27"/>
+ <point x="1049" y="103" type="curve"/>
+ <point x="1253" y="217"/>
+ <point x="1495" y="528"/>
+ </contour>
+ <contour>
+ <point x="690" y="147" type="curve" smooth="yes"/>
+ <point x="492" y="147"/>
+ <point x="384" y="284"/>
+ <point x="384" y="508" type="curve" smooth="yes"/>
+ <point x="384" y="856"/>
+ <point x="609" y="1284"/>
+ <point x="994" y="1284" type="curve" smooth="yes"/>
+ <point x="1188" y="1284"/>
+ <point x="1295" y="1149"/>
+ <point x="1295" y="925" type="curve" smooth="yes"/>
+ <point x="1295" y="490"/>
+ <point x="985" y="147"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetunicodes.ufo/glyphs/L_tnC_apR_.glif b/tests/reference/ufo/psfsetunicodes.ufo/glyphs/L_tnC_apR_.glif
new file mode 100644
index 0000000..c8f8186
--- /dev/null
+++ b/tests/reference/ufo/psfsetunicodes.ufo/glyphs/L_tnC_apR_.glif
@@ -0,0 +1,55 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnCapR" format="2">
+ <advance width="1295"/>
+ <unicode hex="0052"/>
+ <anchor x="590" y="0" name="H"/>
+ <anchor x="525" y="-100" name="L"/>
+ <anchor x="932" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="457" y="613" type="line"/>
+ <point x="712" y="613" type="line" smooth="yes"/>
+ <point x="1010" y="613"/>
+ <point x="1303" y="784"/>
+ <point x="1303" y="1114" type="curve" smooth="yes"/>
+ <point x="1303" y="1326"/>
+ <point x="1114" y="1441"/>
+ <point x="844" y="1441" type="curve" smooth="yes"/>
+ <point x="610" y="1441"/>
+ <point x="456" y="1431"/>
+ <point x="456" y="1431" type="curve"/>
+ <point x="452" y="1352"/>
+ <point x="407" y="1172"/>
+ <point x="359" y="980" type="curve" smooth="yes"/>
+ <point x="221" y="426" type="line"/>
+ <point x="173" y="233"/>
+ <point x="134" y="78"/>
+ <point x="100" y="0" type="curve"/>
+ <point x="320" y="0" type="line"/>
+ <point x="324" y="76"/>
+ <point x="363" y="233"/>
+ <point x="411" y="426" type="curve"/>
+ </contour>
+ <contour>
+ <point x="623" y="1279" type="line"/>
+ <point x="677" y="1281"/>
+ <point x="725" y="1284"/>
+ <point x="795" y="1284" type="curve" smooth="yes"/>
+ <point x="1003" y="1284"/>
+ <point x="1104" y="1203"/>
+ <point x="1104" y="1076" type="curve" smooth="yes"/>
+ <point x="1104" y="856"/>
+ <point x="921" y="764"/>
+ <point x="685" y="764" type="curve" smooth="yes"/>
+ <point x="495" y="764" type="line"/>
+ </contour>
+ <contour>
+ <point x="656" y="622" type="line"/>
+ <point x="930" y="0" type="line"/>
+ <point x="1185" y="0" type="line"/>
+ <point x="1122" y="89"/>
+ <point x="864" y="602"/>
+ <point x="828" y="676" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetunicodes.ufo/glyphs/L_tnC_apS_.glif b/tests/reference/ufo/psfsetunicodes.ufo/glyphs/L_tnC_apS_.glif
new file mode 100644
index 0000000..01e9f47
--- /dev/null
+++ b/tests/reference/ufo/psfsetunicodes.ufo/glyphs/L_tnC_apS_.glif
@@ -0,0 +1,50 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnCapS" format="2">
+ <advance width="1155"/>
+ <unicode hex="0053"/>
+ <anchor x="520" y="0" name="H"/>
+ <anchor x="495" y="-100" name="L"/>
+ <anchor x="902" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="1260" y="1347" type="line"/>
+ <point x="1146" y="1419"/>
+ <point x="1021" y="1455"/>
+ <point x="867" y="1455" type="curve" smooth="yes"/>
+ <point x="549" y="1455"/>
+ <point x="320" y="1303"/>
+ <point x="320" y="1040" type="curve" smooth="yes"/>
+ <point x="320" y="901"/>
+ <point x="438" y="794"/>
+ <point x="622" y="691" type="curve" smooth="yes"/>
+ <point x="877" y="549"/>
+ <point x="914" y="461"/>
+ <point x="914" y="378" type="curve" smooth="yes"/>
+ <point x="914" y="256"/>
+ <point x="792" y="147"/>
+ <point x="621" y="147" type="curve" smooth="yes"/>
+ <point x="473" y="147"/>
+ <point x="278" y="235"/>
+ <point x="161" y="378" type="curve"/>
+ <point x="65" y="187" type="line"/>
+ <point x="178" y="73"/>
+ <point x="365" y="-25"/>
+ <point x="558" y="-25" type="curve" smooth="yes"/>
+ <point x="852" y="-25"/>
+ <point x="1114" y="115"/>
+ <point x="1114" y="414" type="curve" smooth="yes"/>
+ <point x="1114" y="526"/>
+ <point x="1057" y="679"/>
+ <point x="800" y="828" type="curve" smooth="yes"/>
+ <point x="597" y="946"/>
+ <point x="510" y="1005"/>
+ <point x="510" y="1079" type="curve" smooth="yes"/>
+ <point x="510" y="1210"/>
+ <point x="659" y="1284"/>
+ <point x="845" y="1284" type="curve" smooth="yes"/>
+ <point x="959" y="1284"/>
+ <point x="1075" y="1240"/>
+ <point x="1173" y="1156" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetunicodes.ufo/glyphs/L_tnC_apT_.glif b/tests/reference/ufo/psfsetunicodes.ufo/glyphs/L_tnC_apT_.glif
new file mode 100644
index 0000000..0eeece4
--- /dev/null
+++ b/tests/reference/ufo/psfsetunicodes.ufo/glyphs/L_tnC_apT_.glif
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnCapT" format="2">
+ <advance width="1245"/>
+ <unicode hex="0054"/>
+ <anchor x="562" y="0" name="H"/>
+ <anchor x="562" y="-100" name="L"/>
+ <anchor x="944" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="341" y="1431" type="line"/>
+ <point x="296" y="1250" type="line"/>
+ <point x="380" y="1266"/>
+ <point x="457" y="1269"/>
+ <point x="546" y="1269" type="curve" smooth="yes"/>
+ <point x="781" y="1269" type="line"/>
+ <point x="571" y="426" type="line" smooth="yes"/>
+ <point x="523" y="233"/>
+ <point x="481" y="78"/>
+ <point x="445" y="0" type="curve"/>
+ <point x="675" y="0" type="line"/>
+ <point x="677" y="78"/>
+ <point x="713" y="233"/>
+ <point x="761" y="426" type="curve" smooth="yes"/>
+ <point x="971" y="1269" type="line"/>
+ <point x="1211" y="1269" type="line" smooth="yes"/>
+ <point x="1301" y="1269"/>
+ <point x="1375" y="1266"/>
+ <point x="1451" y="1250" type="curve"/>
+ <point x="1496" y="1431" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetunicodes.ufo/glyphs/L_tnC_apU_.glif b/tests/reference/ufo/psfsetunicodes.ufo/glyphs/L_tnC_apU_.glif
new file mode 100644
index 0000000..9576e20
--- /dev/null
+++ b/tests/reference/ufo/psfsetunicodes.ufo/glyphs/L_tnC_apU_.glif
@@ -0,0 +1,44 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnCapU" format="2">
+ <advance width="1420"/>
+ <unicode hex="0055"/>
+ <anchor x="647" y="0" name="H"/>
+ <anchor x="622" y="-100" name="L"/>
+ <anchor x="865" y="0" name="O"/>
+ <anchor x="1640" y="1200" name="R"/>
+ <anchor x="1029" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="1346" y="1431" type="line"/>
+ <point x="1126" y="549" type="line" smooth="yes"/>
+ <point x="1055" y="264"/>
+ <point x="916" y="132"/>
+ <point x="682" y="132" type="curve" smooth="yes"/>
+ <point x="485" y="132"/>
+ <point x="421" y="244"/>
+ <point x="421" y="391" type="curve" smooth="yes"/>
+ <point x="421" y="451"/>
+ <point x="431" y="516"/>
+ <point x="448" y="582" type="curve" smooth="yes"/>
+ <point x="661" y="1431" type="line"/>
+ <point x="456" y="1431" type="line"/>
+ <point x="451" y="1352"/>
+ <point x="414" y="1198"/>
+ <point x="365" y="1005" type="curve" smooth="yes"/>
+ <point x="251" y="552" type="line" smooth="yes"/>
+ <point x="236" y="493"/>
+ <point x="228" y="435"/>
+ <point x="228" y="379" type="curve" smooth="yes"/>
+ <point x="228" y="157"/>
+ <point x="351" y="-25"/>
+ <point x="643" y="-25" type="curve" smooth="yes"/>
+ <point x="1020" y="-25"/>
+ <point x="1223" y="177"/>
+ <point x="1299" y="480" type="curve" smooth="yes"/>
+ <point x="1430" y="1005" type="line" smooth="yes"/>
+ <point x="1480" y="1207"/>
+ <point x="1519" y="1352"/>
+ <point x="1551" y="1431" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetunicodes.ufo/glyphs/L_tnC_apV_.glif b/tests/reference/ufo/psfsetunicodes.ufo/glyphs/L_tnC_apV_.glif
new file mode 100644
index 0000000..2bf8b96
--- /dev/null
+++ b/tests/reference/ufo/psfsetunicodes.ufo/glyphs/L_tnC_apV_.glif
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnCapV" format="2">
+ <advance width="1345"/>
+ <unicode hex="0056"/>
+ <anchor x="620" y="0" name="H"/>
+ <anchor x="587" y="-100" name="L"/>
+ <anchor x="820" y="0" name="O"/>
+ <anchor x="994" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="1381" y="1431" type="line"/>
+ <point x="654" y="191" type="line"/>
+ <point x="536" y="1431" type="line"/>
+ <point x="331" y="1431" type="line"/>
+ <point x="344" y="1350"/>
+ <point x="355" y="1262"/>
+ <point x="377" y="1073" type="curve" smooth="yes"/>
+ <point x="500" y="0" type="line"/>
+ <point x="725" y="0" type="line"/>
+ <point x="1377" y="1073" type="line" smooth="yes"/>
+ <point x="1492" y="1263"/>
+ <point x="1550" y="1350"/>
+ <point x="1606" y="1431" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetunicodes.ufo/glyphs/L_tnC_apW_.glif b/tests/reference/ufo/psfsetunicodes.ufo/glyphs/L_tnC_apW_.glif
new file mode 100644
index 0000000..553ea17
--- /dev/null
+++ b/tests/reference/ufo/psfsetunicodes.ufo/glyphs/L_tnC_apW_.glif
@@ -0,0 +1,44 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnCapW" format="2">
+ <advance width="2060"/>
+ <unicode hex="0057"/>
+ <anchor x="942" y="-100" name="L"/>
+ <anchor x="1349" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="1535" y="0" type="line"/>
+ <point x="2107" y="1073" type="line" smooth="yes"/>
+ <point x="2208" y="1263"/>
+ <point x="2259" y="1350"/>
+ <point x="2311" y="1431" type="curve"/>
+ <point x="2081" y="1431" type="line"/>
+ <point x="1431" y="127" type="line"/>
+ <point x="1420" y="0" type="line"/>
+ </contour>
+ <contour>
+ <point x="1310" y="0" type="line"/>
+ <point x="1420" y="0" type="line"/>
+ <point x="1461" y="127" type="line"/>
+ <point x="1406" y="1431" type="line"/>
+ <point x="1231" y="1431" type="line"/>
+ <point x="1248" y="1279" type="line"/>
+ </contour>
+ <contour>
+ <point x="625" y="0" type="line"/>
+ <point x="1406" y="1431" type="line"/>
+ <point x="1221" y="1431" type="line"/>
+ <point x="521" y="127" type="line"/>
+ <point x="521" y="0" type="line"/>
+ </contour>
+ <contour>
+ <point x="546" y="1431" type="line"/>
+ <point x="336" y="1431" type="line"/>
+ <point x="348" y="1353"/>
+ <point x="355" y="1260"/>
+ <point x="362" y="1073" type="curve" smooth="yes"/>
+ <point x="400" y="0" type="line"/>
+ <point x="521" y="0" type="line"/>
+ <point x="551" y="127" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetunicodes.ufo/glyphs/L_tnC_apX_.glif b/tests/reference/ufo/psfsetunicodes.ufo/glyphs/L_tnC_apX_.glif
new file mode 100644
index 0000000..2da5787
--- /dev/null
+++ b/tests/reference/ufo/psfsetunicodes.ufo/glyphs/L_tnC_apX_.glif
@@ -0,0 +1,39 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnCapX" format="2">
+ <advance width="1305"/>
+ <unicode hex="0058"/>
+ <anchor x="565" y="-100" name="L"/>
+ <anchor x="972" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="970" y="0" type="line"/>
+ <point x="1190" y="0" type="line"/>
+ <point x="1148" y="80"/>
+ <point x="1125" y="124"/>
+ <point x="1045" y="329" type="curve" smooth="yes"/>
+ <point x="611" y="1431" type="line"/>
+ <point x="386" y="1431" type="line"/>
+ <point x="430" y="1348"/>
+ <point x="462" y="1289"/>
+ <point x="541" y="1088" type="curve" smooth="yes"/>
+ </contour>
+ <contour>
+ <point x="752" y="872" type="line"/>
+ <point x="278" y="333" type="line" smooth="yes"/>
+ <point x="98" y="129"/>
+ <point x="53" y="84"/>
+ <point x="-30" y="0" type="curve"/>
+ <point x="210" y="0" type="line"/>
+ <point x="750" y="622" type="line"/>
+ </contour>
+ <contour>
+ <point x="765" y="622" type="line"/>
+ <point x="1183" y="1088" type="line" smooth="yes"/>
+ <point x="1360" y="1285"/>
+ <point x="1425" y="1355"/>
+ <point x="1506" y="1431" type="curve"/>
+ <point x="1261" y="1431" type="line"/>
+ <point x="767" y="872" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetunicodes.ufo/glyphs/L_tnC_apY_.glif b/tests/reference/ufo/psfsetunicodes.ufo/glyphs/L_tnC_apY_.glif
new file mode 100644
index 0000000..9ec65ef
--- /dev/null
+++ b/tests/reference/ufo/psfsetunicodes.ufo/glyphs/L_tnC_apY_.glif
@@ -0,0 +1,39 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnCapY" format="2">
+ <advance width="1300"/>
+ <unicode hex="0059"/>
+ <anchor x="565" y="-100" name="L"/>
+ <anchor x="972" y="1530" name="U"/>
+ <outline>
+ <contour>
+ <point x="331" y="1431" type="line"/>
+ <point x="407" y="1285"/>
+ <point x="446" y="1173"/>
+ <point x="490" y="1044" type="curve"/>
+ <point x="661" y="549" type="line"/>
+ <point x="829" y="661" type="line"/>
+ <point x="551" y="1431" type="line"/>
+ </contour>
+ <contour>
+ <point x="1321" y="1431" type="line"/>
+ <point x="684" y="661" type="line"/>
+ <point x="796" y="549" type="line"/>
+ <point x="1215" y="1044" type="line" smooth="yes"/>
+ <point x="1322" y="1171"/>
+ <point x="1402" y="1265"/>
+ <point x="1561" y="1431" type="curve"/>
+ </contour>
+ <contour>
+ <point x="700" y="0" type="line"/>
+ <point x="704" y="78"/>
+ <point x="743" y="233"/>
+ <point x="791" y="426" type="curve" smooth="yes"/>
+ <point x="854" y="681" type="line"/>
+ <point x="664" y="681" type="line"/>
+ <point x="601" y="426" type="line" smooth="yes"/>
+ <point x="553" y="233"/>
+ <point x="514" y="78"/>
+ <point x="480" y="0" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetunicodes.ufo/glyphs/L_tnS_mA_.glif b/tests/reference/ufo/psfsetunicodes.ufo/glyphs/L_tnS_mA_.glif
new file mode 100644
index 0000000..586e494
--- /dev/null
+++ b/tests/reference/ufo/psfsetunicodes.ufo/glyphs/L_tnS_mA_.glif
@@ -0,0 +1,77 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmA" format="2">
+ <advance width="1107"/>
+ <unicode hex="0061"/>
+ <anchor x="860" y="0" name="H"/>
+ <anchor x="455" y="-100" name="L"/>
+ <anchor x="1065" y="0" name="O"/>
+ <anchor x="1310" y="1000" name="R"/>
+ <anchor x="755" y="1100" name="U"/>
+ <outline>
+ <contour>
+ <point x="972" y="0" type="line"/>
+ <point x="965" y="48"/>
+ <point x="960" y="98"/>
+ <point x="960" y="149" type="curve" smooth="yes"/>
+ <point x="960" y="214"/>
+ <point x="967" y="284"/>
+ <point x="987" y="363" type="curve"/>
+ <point x="1077" y="726" type="line"/>
+ <point x="1081" y="744"/>
+ <point x="1084" y="762"/>
+ <point x="1084" y="779" type="curve" smooth="yes"/>
+ <point x="1084" y="912"/>
+ <point x="955" y="1019"/>
+ <point x="751" y="1019" type="curve" smooth="yes"/>
+ <point x="599" y="1019"/>
+ <point x="502" y="974"/>
+ <point x="389" y="931" type="curve"/>
+ <point x="373" y="889"/>
+ <point x="343" y="783"/>
+ <point x="331" y="740" type="curve"/>
+ <point x="468" y="820"/>
+ <point x="560" y="862"/>
+ <point x="666" y="862" type="curve" smooth="yes"/>
+ <point x="798" y="862"/>
+ <point x="885" y="810"/>
+ <point x="885" y="718" type="curve" smooth="yes"/>
+ <point x="885" y="705"/>
+ <point x="884" y="691"/>
+ <point x="880" y="677" type="curve" smooth="yes"/>
+ <point x="867" y="622" type="line"/>
+ <point x="825" y="619"/>
+ <point x="661" y="605"/>
+ <point x="591" y="598" type="curve" smooth="yes"/>
+ <point x="282" y="568"/>
+ <point x="102" y="415"/>
+ <point x="102" y="233" type="curve" smooth="yes"/>
+ <point x="102" y="103"/>
+ <point x="223" y="-25"/>
+ <point x="390" y="-25" type="curve" smooth="yes"/>
+ <point x="514" y="-25"/>
+ <point x="674" y="47"/>
+ <point x="779" y="152" type="curve"/>
+ <point x="779" y="89"/>
+ <point x="787" y="31"/>
+ <point x="792" y="0" type="curve"/>
+ </contour>
+ <contour>
+ <point x="791" y="319" type="line"/>
+ <point x="674" y="191"/>
+ <point x="553" y="137"/>
+ <point x="451" y="137" type="curve" smooth="yes"/>
+ <point x="355" y="137"/>
+ <point x="290" y="192"/>
+ <point x="290" y="264" type="curve" smooth="yes"/>
+ <point x="290" y="274"/>
+ <point x="291" y="285"/>
+ <point x="294" y="296" type="curve" smooth="yes"/>
+ <point x="315" y="380"/>
+ <point x="432" y="450"/>
+ <point x="566" y="461" type="curve" smooth="yes"/>
+ <point x="631" y="466"/>
+ <point x="782" y="483"/>
+ <point x="832" y="485" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetunicodes.ufo/glyphs/L_tnS_mA_A_cute.glif b/tests/reference/ufo/psfsetunicodes.ufo/glyphs/L_tnS_mA_A_cute.glif
new file mode 100644
index 0000000..198d6db
--- /dev/null
+++ b/tests/reference/ufo/psfsetunicodes.ufo/glyphs/L_tnS_mA_A_cute.glif
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmAAcute" format="2">
+ <advance width="1107"/>
+ <unicode hex="00E1"/>
+ <anchor x="860" y="0" name="H"/>
+ <anchor x="455" y="-100" name="L"/>
+ <anchor x="1065" y="0" name="O"/>
+ <anchor x="1310" y="1000" name="R"/>
+ <anchor x="889" y="1635" name="U"/>
+ <outline>
+ <component base="LtnSmA"/>
+ <component base="CombAcute" xOffset="1110"/>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetunicodes.ufo/glyphs/L_tnS_mA_C_ircum.glif b/tests/reference/ufo/psfsetunicodes.ufo/glyphs/L_tnS_mA_C_ircum.glif
new file mode 100644
index 0000000..f5cfb16
--- /dev/null
+++ b/tests/reference/ufo/psfsetunicodes.ufo/glyphs/L_tnS_mA_C_ircum.glif
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmACircum" format="2">
+ <advance width="1107"/>
+ <unicode hex="00E2"/>
+ <anchor x="860" y="0" name="H"/>
+ <anchor x="455" y="-100" name="L"/>
+ <anchor x="1065" y="0" name="O"/>
+ <anchor x="1310" y="1000" name="R"/>
+ <anchor x="854" y="1635" name="U"/>
+ <outline>
+ <component base="LtnSmA"/>
+ <component base="CombCircum" xOffset="1075"/>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetunicodes.ufo/glyphs/L_tnS_mA_D_iaer.glif b/tests/reference/ufo/psfsetunicodes.ufo/glyphs/L_tnS_mA_D_iaer.glif
new file mode 100644
index 0000000..6f05301
--- /dev/null
+++ b/tests/reference/ufo/psfsetunicodes.ufo/glyphs/L_tnS_mA_D_iaer.glif
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmADiaer" format="2">
+ <advance width="1107"/>
+ <unicode hex="00E4"/>
+ <anchor x="860" y="0" name="H"/>
+ <anchor x="455" y="-100" name="L"/>
+ <anchor x="1065" y="0" name="O"/>
+ <anchor x="1310" y="1000" name="R"/>
+ <anchor x="852" y="1505" name="U"/>
+ <outline>
+ <component base="LtnSmA"/>
+ <component base="CombDiaer" xOffset="1105"/>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetunicodes.ufo/glyphs/L_tnS_mA_G_rave.glif b/tests/reference/ufo/psfsetunicodes.ufo/glyphs/L_tnS_mA_G_rave.glif
new file mode 100644
index 0000000..9048920
--- /dev/null
+++ b/tests/reference/ufo/psfsetunicodes.ufo/glyphs/L_tnS_mA_G_rave.glif
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmAGrave" format="2">
+ <advance width="1107"/>
+ <unicode hex="00E0"/>
+ <anchor x="860" y="0" name="H"/>
+ <anchor x="455" y="-100" name="L"/>
+ <anchor x="1065" y="0" name="O"/>
+ <anchor x="1310" y="1000" name="R"/>
+ <anchor x="889" y="1635" name="U"/>
+ <outline>
+ <component base="LtnSmA"/>
+ <component base="CombGrave" xOffset="1090"/>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetunicodes.ufo/glyphs/L_tnS_mA_R_ingA_bv.glif b/tests/reference/ufo/psfsetunicodes.ufo/glyphs/L_tnS_mA_R_ingA_bv.glif
new file mode 100644
index 0000000..8ada58f
--- /dev/null
+++ b/tests/reference/ufo/psfsetunicodes.ufo/glyphs/L_tnS_mA_R_ingA_bv.glif
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmARingAbv" format="2">
+ <advance width="1107"/>
+ <unicode hex="00E5"/>
+ <anchor x="860" y="0" name="H"/>
+ <anchor x="455" y="-100" name="L"/>
+ <anchor x="1065" y="0" name="O"/>
+ <anchor x="1310" y="1000" name="R"/>
+ <anchor x="919" y="1635" name="U"/>
+ <outline>
+ <component base="LtnSmA"/>
+ <component base="CombRingAbv" xOffset="1140"/>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetunicodes.ufo/glyphs/L_tnS_mA_T_ilde.glif b/tests/reference/ufo/psfsetunicodes.ufo/glyphs/L_tnS_mA_T_ilde.glif
new file mode 100644
index 0000000..c29348b
--- /dev/null
+++ b/tests/reference/ufo/psfsetunicodes.ufo/glyphs/L_tnS_mA_T_ilde.glif
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmATilde" format="2">
+ <advance width="1107"/>
+ <unicode hex="00E3"/>
+ <anchor x="860" y="0" name="H"/>
+ <anchor x="455" y="-100" name="L"/>
+ <anchor x="1065" y="0" name="O"/>
+ <anchor x="1310" y="1000" name="R"/>
+ <anchor x="850" y="1475" name="U"/>
+ <outline>
+ <component base="LtnSmA"/>
+ <component base="CombTilde" xOffset="1140"/>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetunicodes.ufo/glyphs/L_tnS_mB_.glif b/tests/reference/ufo/psfsetunicodes.ufo/glyphs/L_tnS_mB_.glif
new file mode 100644
index 0000000..b3a3696
--- /dev/null
+++ b/tests/reference/ufo/psfsetunicodes.ufo/glyphs/L_tnS_mB_.glif
@@ -0,0 +1,55 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmB" format="2">
+ <advance width="1144"/>
+ <unicode hex="0062"/>
+ <anchor x="530" y="0" name="H"/>
+ <anchor x="505" y="-100" name="L"/>
+ <anchor x="1345" y="1000" name="R"/>
+ <anchor x="938" y="1635" name="U"/>
+ <outline>
+ <contour>
+ <point x="437" y="1570" type="line"/>
+ <point x="437" y="1456"/>
+ <point x="402" y="1246"/>
+ <point x="367" y="1105" type="curve" smooth="yes"/>
+ <point x="110" y="85" type="line"/>
+ <point x="198" y="44"/>
+ <point x="355" y="-25"/>
+ <point x="517" y="-25" type="curve" smooth="yes"/>
+ <point x="675" y="-25"/>
+ <point x="795" y="24"/>
+ <point x="907" y="125" type="curve" smooth="yes"/>
+ <point x="1050" y="255"/>
+ <point x="1162" y="466"/>
+ <point x="1162" y="695" type="curve" smooth="yes"/>
+ <point x="1162" y="930"/>
+ <point x="1046" y="1020"/>
+ <point x="907" y="1020" type="curve" smooth="yes"/>
+ <point x="754" y="1020"/>
+ <point x="584" y="878"/>
+ <point x="456" y="719" type="curve"/>
+ <point x="552" y="1105" type="line" smooth="yes"/>
+ <point x="600" y="1296"/>
+ <point x="627" y="1508"/>
+ <point x="627" y="1570" type="curve"/>
+ </contour>
+ <contour>
+ <point x="382" y="429" type="line"/>
+ <point x="485" y="617"/>
+ <point x="708" y="850"/>
+ <point x="822" y="850" type="curve" smooth="yes"/>
+ <point x="913" y="850"/>
+ <point x="972" y="784"/>
+ <point x="972" y="635" type="curve" smooth="yes"/>
+ <point x="972" y="469"/>
+ <point x="909" y="336"/>
+ <point x="822" y="250" type="curve" smooth="yes"/>
+ <point x="741" y="169"/>
+ <point x="638" y="125"/>
+ <point x="552" y="125" type="curve" smooth="yes"/>
+ <point x="466" y="125"/>
+ <point x="376" y="167"/>
+ <point x="325" y="200" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetunicodes.ufo/glyphs/L_tnS_mC_.glif b/tests/reference/ufo/psfsetunicodes.ufo/glyphs/L_tnS_mC_.glif
new file mode 100644
index 0000000..f54fbe9
--- /dev/null
+++ b/tests/reference/ufo/psfsetunicodes.ufo/glyphs/L_tnS_mC_.glif
@@ -0,0 +1,39 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmC" format="2">
+ <advance width="989"/>
+ <unicode hex="0063"/>
+ <anchor x="520" y="0" name="H"/>
+ <anchor x="495" y="-100" name="L"/>
+ <anchor x="1210" y="1000" name="R"/>
+ <anchor x="785" y="1100" name="U"/>
+ <outline>
+ <contour>
+ <point x="917" y="255" type="line"/>
+ <point x="811" y="179"/>
+ <point x="703" y="137"/>
+ <point x="583" y="137" type="curve" smooth="yes"/>
+ <point x="427" y="137"/>
+ <point x="331" y="239"/>
+ <point x="331" y="406" type="curve" smooth="yes"/>
+ <point x="331" y="619"/>
+ <point x="499" y="858"/>
+ <point x="742" y="858" type="curve" smooth="yes"/>
+ <point x="845" y="858"/>
+ <point x="924" y="824"/>
+ <point x="998" y="760" type="curve"/>
+ <point x="1077" y="936" type="line"/>
+ <point x="1016" y="985"/>
+ <point x="902" y="1020"/>
+ <point x="789" y="1020" type="curve" smooth="yes"/>
+ <point x="420" y="1020"/>
+ <point x="139" y="737"/>
+ <point x="139" y="381" type="curve" smooth="yes"/>
+ <point x="139" y="130"/>
+ <point x="309" y="-25"/>
+ <point x="532" y="-25" type="curve" smooth="yes"/>
+ <point x="682" y="-25"/>
+ <point x="785" y="9"/>
+ <point x="904" y="83" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetunicodes.ufo/glyphs/L_tnS_mD_.glif b/tests/reference/ufo/psfsetunicodes.ufo/glyphs/L_tnS_mD_.glif
new file mode 100644
index 0000000..4ea9ea1
--- /dev/null
+++ b/tests/reference/ufo/psfsetunicodes.ufo/glyphs/L_tnS_mD_.glif
@@ -0,0 +1,65 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmD" format="2">
+ <advance width="1197"/>
+ <unicode hex="0064"/>
+ <anchor x="545" y="0" name="H"/>
+ <anchor x="520" y="-100" name="L"/>
+ <anchor x="1380" y="1000" name="R"/>
+ <anchor x="953" y="1635" name="U"/>
+ <outline>
+ <contour>
+ <point x="1144" y="1570" type="line"/>
+ <point x="1144" y="1456"/>
+ <point x="1114" y="1327"/>
+ <point x="1079" y="1175" type="curve" smooth="yes"/>
+ <point x="1024" y="935" type="line"/>
+ <point x="957" y="978"/>
+ <point x="854" y="1020"/>
+ <point x="759" y="1020" type="curve" smooth="yes"/>
+ <point x="650" y="1020"/>
+ <point x="534" y="979"/>
+ <point x="429" y="895" type="curve" smooth="yes"/>
+ <point x="262" y="761"/>
+ <point x="139" y="532"/>
+ <point x="139" y="288" type="curve" smooth="yes"/>
+ <point x="139" y="94"/>
+ <point x="250" y="-25"/>
+ <point x="424" y="-25" type="curve" smooth="yes"/>
+ <point x="563" y="-25"/>
+ <point x="791" y="141"/>
+ <point x="899" y="305" type="curve"/>
+ <point x="875" y="196"/>
+ <point x="869" y="93"/>
+ <point x="869" y="0" type="curve"/>
+ <point x="1052" y="0" type="line"/>
+ <point x="1048" y="23"/>
+ <point x="1047" y="53"/>
+ <point x="1047" y="90" type="curve" smooth="yes"/>
+ <point x="1047" y="190"/>
+ <point x="1063" y="340"/>
+ <point x="1107" y="520" type="curve" smooth="yes"/>
+ <point x="1267" y="1175" type="line" smooth="yes"/>
+ <point x="1310" y="1351"/>
+ <point x="1337" y="1475"/>
+ <point x="1337" y="1570" type="curve"/>
+ </contour>
+ <contour>
+ <point x="930" y="545" type="line"/>
+ <point x="846" y="370"/>
+ <point x="592" y="130"/>
+ <point x="479" y="130" type="curve" smooth="yes"/>
+ <point x="374" y="130"/>
+ <point x="330" y="195"/>
+ <point x="330" y="316" type="curve" smooth="yes"/>
+ <point x="330" y="460"/>
+ <point x="397" y="649"/>
+ <point x="509" y="760" type="curve" smooth="yes"/>
+ <point x="572" y="822"/>
+ <point x="643" y="855"/>
+ <point x="734" y="855" type="curve" smooth="yes"/>
+ <point x="835" y="855"/>
+ <point x="898" y="832"/>
+ <point x="984" y="780" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetunicodes.ufo/glyphs/L_tnS_mE_.glif b/tests/reference/ufo/psfsetunicodes.ufo/glyphs/L_tnS_mE_.glif
new file mode 100644
index 0000000..a3a6490
--- /dev/null
+++ b/tests/reference/ufo/psfsetunicodes.ufo/glyphs/L_tnS_mE_.glif
@@ -0,0 +1,52 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmE" format="2">
+ <advance width="1042"/>
+ <unicode hex="0065"/>
+ <anchor x="485" y="0" name="H"/>
+ <anchor x="484" y="-100" name="L"/>
+ <anchor x="840" y="0" name="O"/>
+ <anchor x="1285" y="1000" name="R"/>
+ <anchor x="784" y="1100" name="U"/>
+ <outline>
+ <contour>
+ <point x="967" y="270" type="line"/>
+ <point x="854" y="189"/>
+ <point x="700" y="135"/>
+ <point x="567" y="135" type="curve" smooth="yes"/>
+ <point x="386" y="135"/>
+ <point x="317" y="263"/>
+ <point x="317" y="420" type="curve" smooth="yes"/>
+ <point x="317" y="686"/>
+ <point x="522" y="872"/>
+ <point x="720" y="872" type="curve" smooth="yes"/>
+ <point x="813" y="872"/>
+ <point x="883" y="823"/>
+ <point x="883" y="753" type="curve" smooth="yes"/>
+ <point x="883" y="660"/>
+ <point x="766" y="590"/>
+ <point x="539" y="590" type="curve" smooth="yes"/>
+ <point x="468" y="590"/>
+ <point x="382" y="596"/>
+ <point x="279" y="610" type="curve"/>
+ <point x="279" y="477" type="line"/>
+ <point x="391" y="461"/>
+ <point x="487" y="453"/>
+ <point x="569" y="453" type="curve" smooth="yes"/>
+ <point x="931" y="453"/>
+ <point x="1077" y="609"/>
+ <point x="1077" y="791" type="curve" smooth="yes"/>
+ <point x="1077" y="899"/>
+ <point x="986" y="1020"/>
+ <point x="772" y="1020" type="curve" smooth="yes"/>
+ <point x="399" y="1020"/>
+ <point x="137" y="710"/>
+ <point x="137" y="380" type="curve" smooth="yes"/>
+ <point x="137" y="147"/>
+ <point x="258" y="-25"/>
+ <point x="523" y="-25" type="curve" smooth="yes"/>
+ <point x="689" y="-25"/>
+ <point x="849" y="26"/>
+ <point x="955" y="83" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetunicodes.ufo/glyphs/L_tnS_mF_.glif b/tests/reference/ufo/psfsetunicodes.ufo/glyphs/L_tnS_mF_.glif
new file mode 100644
index 0000000..ede52a9
--- /dev/null
+++ b/tests/reference/ufo/psfsetunicodes.ufo/glyphs/L_tnS_mF_.glif
@@ -0,0 +1,44 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmF" format="2">
+ <advance width="756"/>
+ <unicode hex="0066"/>
+ <anchor x="290" y="0" name="H"/>
+ <anchor x="315" y="-100" name="L"/>
+ <anchor x="908" y="1635" name="U"/>
+ <outline>
+ <contour>
+ <point x="180" y="833" type="line"/>
+ <point x="835" y="833" type="line"/>
+ <point x="871" y="975" type="line"/>
+ <point x="216" y="975" type="line"/>
+ </contour>
+ <contour>
+ <point x="1106" y="1519" type="line"/>
+ <point x="1062" y="1555"/>
+ <point x="981" y="1588"/>
+ <point x="903" y="1588" type="curve" smooth="yes"/>
+ <point x="687" y="1588"/>
+ <point x="533" y="1478"/>
+ <point x="448" y="1147" type="curve" smooth="yes"/>
+ <point x="403" y="972"/>
+ <point x="244" y="334"/>
+ <point x="223" y="0" type="curve"/>
+ <point x="436" y="0" type="line"/>
+ <point x="430" y="28"/>
+ <point x="427" y="66"/>
+ <point x="427" y="110" type="curve" smooth="yes"/>
+ <point x="427" y="213"/>
+ <point x="447" y="351"/>
+ <point x="476" y="484" type="curve" smooth="yes"/>
+ <point x="510" y="641"/>
+ <point x="558" y="846"/>
+ <point x="641" y="1186" type="curve" smooth="yes"/>
+ <point x="682" y="1353"/>
+ <point x="758" y="1421"/>
+ <point x="862" y="1421" type="curve" smooth="yes"/>
+ <point x="920" y="1421"/>
+ <point x="988" y="1392"/>
+ <point x="1022" y="1362" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetunicodes.ufo/glyphs/L_tnS_mG_.glif b/tests/reference/ufo/psfsetunicodes.ufo/glyphs/L_tnS_mG_.glif
new file mode 100644
index 0000000..8931f8d
--- /dev/null
+++ b/tests/reference/ufo/psfsetunicodes.ufo/glyphs/L_tnS_mG_.glif
@@ -0,0 +1,100 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmG" format="2">
+ <advance width="1075"/>
+ <unicode hex="0067"/>
+ <anchor x="368" y="-465" name="H"/>
+ <anchor x="351" y="-535" name="L"/>
+ <anchor x="1285" y="1000" name="R"/>
+ <anchor x="730" y="1100" name="U"/>
+ <outline>
+ <contour>
+ <point x="360" y="389" type="line"/>
+ <point x="277" y="352"/>
+ <point x="168" y="266"/>
+ <point x="168" y="176" type="curve" smooth="yes"/>
+ <point x="168" y="96"/>
+ <point x="246" y="33"/>
+ <point x="483" y="-5" type="curve" smooth="yes"/>
+ <point x="707" y="-41"/>
+ <point x="781" y="-94"/>
+ <point x="781" y="-151" type="curve" smooth="yes"/>
+ <point x="781" y="-256"/>
+ <point x="580" y="-353"/>
+ <point x="411" y="-353" type="curve" smooth="yes"/>
+ <point x="202" y="-353"/>
+ <point x="104" y="-271"/>
+ <point x="104" y="-196" type="curve" smooth="yes"/>
+ <point x="104" y="-189"/>
+ <point x="104" y="-183"/>
+ <point x="106" y="-176" type="curve" smooth="yes"/>
+ <point x="120" y="-119"/>
+ <point x="170" y="-55"/>
+ <point x="409" y="20" type="curve"/>
+ <point x="410" y="48"/>
+ <point x="248" y="73"/>
+ <point x="248" y="73" type="curve"/>
+ <point x="53" y="12"/>
+ <point x="-51" y="-77"/>
+ <point x="-78" y="-186" type="curve" smooth="yes"/>
+ <point x="-82" y="-201"/>
+ <point x="-84" y="-217"/>
+ <point x="-84" y="-231" type="curve" smooth="yes"/>
+ <point x="-84" y="-396"/>
+ <point x="158" y="-495"/>
+ <point x="371" y="-495" type="curve" smooth="yes"/>
+ <point x="632" y="-495"/>
+ <point x="972" y="-360"/>
+ <point x="972" y="-125" type="curve" smooth="yes"/>
+ <point x="972" y="0"/>
+ <point x="849" y="90"/>
+ <point x="619" y="127" type="curve" smooth="yes"/>
+ <point x="403" y="162"/>
+ <point x="341" y="184"/>
+ <point x="341" y="218" type="curve" smooth="yes"/>
+ <point x="341" y="263"/>
+ <point x="447" y="325"/>
+ <point x="522" y="342" type="curve"/>
+ </contour>
+ <contour>
+ <point x="1244" y="1019" type="line"/>
+ <point x="1143" y="1012"/>
+ <point x="1002" y="977"/>
+ <point x="899" y="921" type="curve"/>
+ <point x="936" y="809" type="line"/>
+ <point x="1037" y="846"/>
+ <point x="1121" y="860"/>
+ <point x="1194" y="862" type="curve"/>
+ </contour>
+ <contour>
+ <point x="212" y="613" type="curve" smooth="yes"/>
+ <point x="212" y="449"/>
+ <point x="356" y="319"/>
+ <point x="554" y="319" type="curve" smooth="yes"/>
+ <point x="791" y="319"/>
+ <point x="1030" y="495"/>
+ <point x="1030" y="729" type="curve" smooth="yes"/>
+ <point x="1030" y="894"/>
+ <point x="887" y="1019"/>
+ <point x="689" y="1019" type="curve" smooth="yes"/>
+ <point x="441" y="1019"/>
+ <point x="212" y="847"/>
+ </contour>
+ <contour>
+ <point x="857" y="704" type="curve" smooth="yes"/>
+ <point x="857" y="555"/>
+ <point x="712" y="456"/>
+ <point x="578" y="456" type="curve" smooth="yes"/>
+ <point x="463" y="456"/>
+ <point x="385" y="530"/>
+ <point x="385" y="628" type="curve" smooth="yes"/>
+ <point x="385" y="643"/>
+ <point x="387" y="660"/>
+ <point x="391" y="676" type="curve" smooth="yes"/>
+ <point x="421" y="797"/>
+ <point x="530" y="877"/>
+ <point x="663" y="877" type="curve" smooth="yes"/>
+ <point x="779" y="877"/>
+ <point x="857" y="802"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetunicodes.ufo/glyphs/L_tnS_mH_.glif b/tests/reference/ufo/psfsetunicodes.ufo/glyphs/L_tnS_mH_.glif
new file mode 100644
index 0000000..08afbac
--- /dev/null
+++ b/tests/reference/ufo/psfsetunicodes.ufo/glyphs/L_tnS_mH_.glif
@@ -0,0 +1,54 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmH" format="2">
+ <advance width="1185"/>
+ <unicode hex="0068"/>
+ <anchor x="190" y="0" name="H"/>
+ <anchor x="550" y="-100" name="L"/>
+ <anchor x="933" y="1635" name="U"/>
+ <outline>
+ <contour>
+ <point x="1055" y="0" type="line"/>
+ <point x="1047" y="30"/>
+ <point x="1043" y="65"/>
+ <point x="1043" y="102" type="curve" smooth="yes"/>
+ <point x="1043" y="143"/>
+ <point x="1048" y="188"/>
+ <point x="1055" y="238" type="curve" smooth="yes"/>
+ <point x="1069" y="327"/>
+ <point x="1170" y="636"/>
+ <point x="1170" y="745" type="curve" smooth="yes"/>
+ <point x="1170" y="917"/>
+ <point x="1095" y="1020"/>
+ <point x="930" y="1020" type="curve" smooth="yes"/>
+ <point x="760" y="1020"/>
+ <point x="591" y="877"/>
+ <point x="475" y="723" type="curve"/>
+ <point x="571" y="1105" type="line" smooth="yes"/>
+ <point x="609" y="1259"/>
+ <point x="645" y="1482"/>
+ <point x="645" y="1570" type="curve"/>
+ <point x="455" y="1570" type="line"/>
+ <point x="455" y="1456"/>
+ <point x="423" y="1257"/>
+ <point x="385" y="1105" type="curve" smooth="yes"/>
+ <point x="110" y="0" type="line"/>
+ <point x="295" y="0" type="line"/>
+ <point x="397" y="408" type="line"/>
+ <point x="492" y="612"/>
+ <point x="717" y="850"/>
+ <point x="840" y="850" type="curve" smooth="yes"/>
+ <point x="937" y="850"/>
+ <point x="970" y="798"/>
+ <point x="970" y="680" type="curve" smooth="yes"/>
+ <point x="970" y="592"/>
+ <point x="886" y="319"/>
+ <point x="872" y="203" type="curve" smooth="yes"/>
+ <point x="867" y="158"/>
+ <point x="864" y="115"/>
+ <point x="864" y="77" type="curve" smooth="yes"/>
+ <point x="864" y="48"/>
+ <point x="866" y="21"/>
+ <point x="870" y="0" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetunicodes.ufo/glyphs/L_tnS_mI_.glif b/tests/reference/ufo/psfsetunicodes.ufo/glyphs/L_tnS_mI_.glif
new file mode 100644
index 0000000..65ed550
--- /dev/null
+++ b/tests/reference/ufo/psfsetunicodes.ufo/glyphs/L_tnS_mI_.glif
@@ -0,0 +1,50 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmI" format="2">
+ <advance width="554"/>
+ <unicode hex="0069"/>
+ <anchor x="235" y="0" name="H"/>
+ <anchor x="250" y="-100" name="L"/>
+ <anchor x="455" y="0" name="O"/>
+ <anchor x="745" y="1000" name="R"/>
+ <anchor x="472" y="1100" name="U"/>
+ <outline>
+ <contour>
+ <point x="361" y="1297" type="curve" smooth="yes"/>
+ <point x="361" y="1237"/>
+ <point x="404" y="1186"/>
+ <point x="467" y="1186" type="curve" smooth="yes"/>
+ <point x="552" y="1186"/>
+ <point x="624" y="1259"/>
+ <point x="624" y="1338" type="curve" smooth="yes"/>
+ <point x="624" y="1399"/>
+ <point x="578" y="1450"/>
+ <point x="513" y="1450" type="curve" smooth="yes"/>
+ <point x="428" y="1450"/>
+ <point x="361" y="1375"/>
+ </contour>
+ <contour>
+ <point x="335" y="1000" type="line"/>
+ <point x="335" y="886"/>
+ <point x="286" y="688"/>
+ <point x="246" y="537" type="curve" smooth="yes"/>
+ <point x="207" y="388" type="line" smooth="yes"/>
+ <point x="180" y="284"/>
+ <point x="165" y="172"/>
+ <point x="165" y="87" type="curve" smooth="yes"/>
+ <point x="165" y="53"/>
+ <point x="167" y="24"/>
+ <point x="172" y="0" type="curve"/>
+ <point x="372" y="0" type="line"/>
+ <point x="365" y="37"/>
+ <point x="360" y="85"/>
+ <point x="360" y="136" type="curve" smooth="yes"/>
+ <point x="360" y="208"/>
+ <point x="368" y="287"/>
+ <point x="386" y="357" type="curve" smooth="yes"/>
+ <point x="431" y="536" type="line" smooth="yes"/>
+ <point x="476" y="712"/>
+ <point x="525" y="912"/>
+ <point x="525" y="1000" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetunicodes.ufo/glyphs/L_tnS_mJ_.glif b/tests/reference/ufo/psfsetunicodes.ufo/glyphs/L_tnS_mJ_.glif
new file mode 100644
index 0000000..e9e18b8
--- /dev/null
+++ b/tests/reference/ufo/psfsetunicodes.ufo/glyphs/L_tnS_mJ_.glif
@@ -0,0 +1,45 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmJ" format="2">
+ <advance width="602"/>
+ <unicode hex="006A"/>
+ <anchor x="-60" y="-500" name="L"/>
+ <anchor x="510" y="1100" name="U"/>
+ <outline>
+ <contour>
+ <point x="370" y="1000" type="line"/>
+ <point x="370" y="856"/>
+ <point x="288" y="374"/>
+ <point x="214" y="77" type="curve" smooth="yes"/>
+ <point x="152" y="-173"/>
+ <point x="29" y="-295"/>
+ <point x="-77" y="-295" type="curve" smooth="yes"/>
+ <point x="-133" y="-295"/>
+ <point x="-217" y="-264"/>
+ <point x="-253" y="-229" type="curve"/>
+ <point x="-328" y="-397" type="line"/>
+ <point x="-278" y="-437"/>
+ <point x="-170" y="-465"/>
+ <point x="-114" y="-465" type="curve" smooth="yes"/>
+ <point x="103" y="-465"/>
+ <point x="303" y="-314"/>
+ <point x="396" y="66" type="curve" smooth="yes"/>
+ <point x="455" y="307"/>
+ <point x="560" y="872"/>
+ <point x="560" y="1000" type="curve"/>
+ </contour>
+ <contour>
+ <point x="397" y="1297" type="curve" smooth="yes"/>
+ <point x="397" y="1237"/>
+ <point x="440" y="1186"/>
+ <point x="503" y="1186" type="curve" smooth="yes"/>
+ <point x="588" y="1186"/>
+ <point x="660" y="1259"/>
+ <point x="660" y="1338" type="curve" smooth="yes"/>
+ <point x="660" y="1399"/>
+ <point x="614" y="1450"/>
+ <point x="549" y="1450" type="curve" smooth="yes"/>
+ <point x="464" y="1450"/>
+ <point x="397" y="1375"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetunicodes.ufo/glyphs/L_tnS_mK_.glif b/tests/reference/ufo/psfsetunicodes.ufo/glyphs/L_tnS_mK_.glif
new file mode 100644
index 0000000..28fbc71
--- /dev/null
+++ b/tests/reference/ufo/psfsetunicodes.ufo/glyphs/L_tnS_mK_.glif
@@ -0,0 +1,50 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmK" format="2">
+ <advance width="1059"/>
+ <unicode hex="006B"/>
+ <anchor x="840" y="0" name="H"/>
+ <anchor x="537" y="-100" name="L"/>
+ <anchor x="1225" y="1000" name="R"/>
+ <anchor x="920" y="1635" name="U"/>
+ <outline>
+ <contour>
+ <point x="295" y="0" type="line"/>
+ <point x="570" y="1105" type="line" smooth="yes"/>
+ <point x="614" y="1280"/>
+ <point x="645" y="1482"/>
+ <point x="645" y="1570" type="curve"/>
+ <point x="455" y="1570" type="line"/>
+ <point x="455" y="1456"/>
+ <point x="424" y="1259"/>
+ <point x="386" y="1107" type="curve" smooth="yes"/>
+ <point x="338" y="915"/>
+ <point x="110" y="0"/>
+ <point x="110" y="0" type="curve"/>
+ </contour>
+ <contour>
+ <point x="909" y="1000" type="line"/>
+ <point x="885" y="863"/>
+ <point x="654" y="700"/>
+ <point x="379" y="539" type="curve"/>
+ <point x="386" y="540"/>
+ <point x="393" y="540"/>
+ <point x="400" y="540" type="curve" smooth="yes"/>
+ <point x="467" y="540"/>
+ <point x="559" y="514"/>
+ <point x="559" y="514" type="curve"/>
+ <point x="902" y="702"/>
+ <point x="1134" y="884"/>
+ <point x="1134" y="1000" type="curve"/>
+ </contour>
+ <contour>
+ <point x="1010" y="0" type="line"/>
+ <point x="863" y="238"/>
+ <point x="718" y="600"/>
+ <point x="527" y="600" type="curve"/>
+ <point x="385" y="529" type="line"/>
+ <point x="540" y="529"/>
+ <point x="667" y="246"/>
+ <point x="775" y="0" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetunicodes.ufo/glyphs/L_tnS_mL_.glif b/tests/reference/ufo/psfsetunicodes.ufo/glyphs/L_tnS_mL_.glif
new file mode 100644
index 0000000..06d68fd
--- /dev/null
+++ b/tests/reference/ufo/psfsetunicodes.ufo/glyphs/L_tnS_mL_.glif
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmL" format="2">
+ <advance width="575"/>
+ <unicode hex="006C"/>
+ <anchor x="230" y="0" name="H"/>
+ <anchor x="255" y="-100" name="L"/>
+ <anchor x="740" y="1000" name="R"/>
+ <anchor x="630" y="1635" name="U"/>
+ <outline>
+ <contour>
+ <point x="465" y="1570" type="line"/>
+ <point x="465" y="1456"/>
+ <point x="434" y="1259"/>
+ <point x="396" y="1107" type="curve" smooth="yes"/>
+ <point x="241" y="489" type="line" smooth="yes"/>
+ <point x="204" y="343"/>
+ <point x="186" y="220"/>
+ <point x="186" y="104" type="curve" smooth="yes"/>
+ <point x="186" y="69"/>
+ <point x="188" y="34"/>
+ <point x="191" y="0" type="curve"/>
+ <point x="391" y="0" type="line"/>
+ <point x="386" y="32"/>
+ <point x="384" y="70"/>
+ <point x="384" y="112" type="curve" smooth="yes"/>
+ <point x="384" y="230"/>
+ <point x="402" y="380"/>
+ <point x="436" y="517" type="curve" smooth="yes"/>
+ <point x="580" y="1105" type="line" smooth="yes"/>
+ <point x="623" y="1280"/>
+ <point x="655" y="1482"/>
+ <point x="655" y="1570" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetunicodes.ufo/glyphs/L_tnS_mM_.glif b/tests/reference/ufo/psfsetunicodes.ufo/glyphs/L_tnS_mM_.glif
new file mode 100644
index 0000000..a6b80db
--- /dev/null
+++ b/tests/reference/ufo/psfsetunicodes.ufo/glyphs/L_tnS_mM_.glif
@@ -0,0 +1,80 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmM" format="2">
+ <advance width="1680"/>
+ <unicode hex="006D"/>
+ <anchor x="805" y="0" name="H"/>
+ <anchor x="780" y="-100" name="L"/>
+ <anchor x="1080" y="1100" name="U"/>
+ <outline>
+ <contour>
+ <point x="1520" y="0" type="line"/>
+ <point x="1512" y="30"/>
+ <point x="1510" y="65"/>
+ <point x="1510" y="102" type="curve" smooth="yes"/>
+ <point x="1510" y="143"/>
+ <point x="1515" y="188"/>
+ <point x="1522" y="238" type="curve" smooth="yes"/>
+ <point x="1536" y="327"/>
+ <point x="1655" y="691"/>
+ <point x="1655" y="800" type="curve" smooth="yes"/>
+ <point x="1655" y="930"/>
+ <point x="1594" y="1020"/>
+ <point x="1445" y="1020" type="curve" smooth="yes"/>
+ <point x="1292" y="1020"/>
+ <point x="1124" y="867"/>
+ <point x="1026" y="680" type="curve"/>
+ <point x="1030" y="704"/>
+ <point x="1045" y="778"/>
+ <point x="1045" y="800" type="curve" smooth="yes"/>
+ <point x="1045" y="932"/>
+ <point x="982" y="1020"/>
+ <point x="860" y="1020" type="curve" smooth="yes"/>
+ <point x="717" y="1020"/>
+ <point x="563" y="879"/>
+ <point x="446" y="680" type="curve"/>
+ <point x="466" y="753"/>
+ <point x="476" y="880"/>
+ <point x="476" y="961" type="curve" smooth="yes"/>
+ <point x="476" y="976"/>
+ <point x="476" y="989"/>
+ <point x="475" y="1000" type="curve"/>
+ <point x="295" y="1000" type="line"/>
+ <point x="296" y="983"/>
+ <point x="296" y="964"/>
+ <point x="296" y="945" type="curve" smooth="yes"/>
+ <point x="296" y="825"/>
+ <point x="283" y="680"/>
+ <point x="262" y="595" type="curve" smooth="yes"/>
+ <point x="115" y="0" type="line"/>
+ <point x="300" y="0" type="line"/>
+ <point x="389" y="359" type="line"/>
+ <point x="475" y="573"/>
+ <point x="685" y="850"/>
+ <point x="775" y="850" type="curve" smooth="yes"/>
+ <point x="833" y="850"/>
+ <point x="865" y="813"/>
+ <point x="865" y="720" type="curve" smooth="yes"/>
+ <point x="865" y="679"/>
+ <point x="846" y="583"/>
+ <point x="822" y="486" type="curve" smooth="yes"/>
+ <point x="700" y="0" type="line"/>
+ <point x="885" y="0" type="line"/>
+ <point x="974" y="359" type="line"/>
+ <point x="1032" y="531"/>
+ <point x="1242" y="850"/>
+ <point x="1357" y="850" type="curve" smooth="yes"/>
+ <point x="1425" y="850"/>
+ <point x="1457" y="813"/>
+ <point x="1457" y="720" type="curve" smooth="yes"/>
+ <point x="1457" y="632"/>
+ <point x="1349" y="319"/>
+ <point x="1335" y="203" type="curve" smooth="yes"/>
+ <point x="1330" y="158"/>
+ <point x="1327" y="115"/>
+ <point x="1327" y="77" type="curve" smooth="yes"/>
+ <point x="1327" y="48"/>
+ <point x="1331" y="21"/>
+ <point x="1335" y="0" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetunicodes.ufo/glyphs/L_tnS_mN_.glif b/tests/reference/ufo/psfsetunicodes.ufo/glyphs/L_tnS_mN_.glif
new file mode 100644
index 0000000..1f38f20
--- /dev/null
+++ b/tests/reference/ufo/psfsetunicodes.ufo/glyphs/L_tnS_mN_.glif
@@ -0,0 +1,57 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmN" format="2">
+ <advance width="1195"/>
+ <unicode hex="006E"/>
+ <anchor x="540" y="0" name="H"/>
+ <anchor x="565" y="-100" name="L"/>
+ <anchor x="815" y="1100" name="U"/>
+ <outline>
+ <contour>
+ <point x="1060" y="0" type="line"/>
+ <point x="1052" y="30"/>
+ <point x="1050" y="65"/>
+ <point x="1050" y="102" type="curve" smooth="yes"/>
+ <point x="1050" y="143"/>
+ <point x="1055" y="188"/>
+ <point x="1062" y="238" type="curve" smooth="yes"/>
+ <point x="1075" y="327"/>
+ <point x="1175" y="636"/>
+ <point x="1175" y="745" type="curve" smooth="yes"/>
+ <point x="1175" y="917"/>
+ <point x="1100" y="1020"/>
+ <point x="935" y="1020" type="curve" smooth="yes"/>
+ <point x="755" y="1020"/>
+ <point x="581" y="870"/>
+ <point x="445" y="672" type="curve"/>
+ <point x="463" y="740"/>
+ <point x="477" y="873"/>
+ <point x="477" y="957" type="curve" smooth="yes"/>
+ <point x="477" y="973"/>
+ <point x="476" y="988"/>
+ <point x="475" y="1000" type="curve"/>
+ <point x="295" y="1000" type="line"/>
+ <point x="295" y="961" type="line" smooth="yes"/>
+ <point x="295" y="833"/>
+ <point x="283" y="679"/>
+ <point x="262" y="595" type="curve" smooth="yes"/>
+ <point x="115" y="0" type="line"/>
+ <point x="300" y="0" type="line"/>
+ <point x="392" y="370" type="line"/>
+ <point x="478" y="573"/>
+ <point x="708" y="850"/>
+ <point x="835" y="850" type="curve" smooth="yes"/>
+ <point x="927" y="850"/>
+ <point x="975" y="798"/>
+ <point x="975" y="680" type="curve" smooth="yes"/>
+ <point x="975" y="592"/>
+ <point x="888" y="319"/>
+ <point x="875" y="203" type="curve" smooth="yes"/>
+ <point x="870" y="158"/>
+ <point x="867" y="115"/>
+ <point x="867" y="77" type="curve" smooth="yes"/>
+ <point x="867" y="48"/>
+ <point x="871" y="21"/>
+ <point x="875" y="0" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetunicodes.ufo/glyphs/L_tnS_mO_.glif b/tests/reference/ufo/psfsetunicodes.ufo/glyphs/L_tnS_mO_.glif
new file mode 100644
index 0000000..bec7b9e
--- /dev/null
+++ b/tests/reference/ufo/psfsetunicodes.ufo/glyphs/L_tnS_mO_.glif
@@ -0,0 +1,40 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmO" format="2">
+ <advance width="1133"/>
+ <unicode hex="006F"/>
+ <anchor x="510" y="0" name="H"/>
+ <anchor x="505" y="-100" name="L"/>
+ <anchor x="800" y="0" name="O"/>
+ <anchor x="1330" y="1000" name="R"/>
+ <anchor x="785" y="1100" name="U"/>
+ <outline>
+ <contour>
+ <point x="142" y="344" type="curve" smooth="yes"/>
+ <point x="142" y="114"/>
+ <point x="306" y="-25"/>
+ <point x="530" y="-25" type="curve" smooth="yes"/>
+ <point x="896" y="-25"/>
+ <point x="1138" y="314"/>
+ <point x="1138" y="648" type="curve" smooth="yes"/>
+ <point x="1138" y="879"/>
+ <point x="985" y="1020"/>
+ <point x="761" y="1020" type="curve" smooth="yes"/>
+ <point x="387" y="1020"/>
+ <point x="142" y="677"/>
+ </contour>
+ <contour>
+ <point x="721" y="862" type="curve" smooth="yes"/>
+ <point x="859" y="862"/>
+ <point x="947" y="767"/>
+ <point x="947" y="611" type="curve" smooth="yes"/>
+ <point x="947" y="391"/>
+ <point x="795" y="132"/>
+ <point x="559" y="132" type="curve" smooth="yes"/>
+ <point x="421" y="132"/>
+ <point x="333" y="226"/>
+ <point x="333" y="380" type="curve" smooth="yes"/>
+ <point x="333" y="599"/>
+ <point x="486" y="862"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetunicodes.ufo/glyphs/L_tnS_mP_.glif b/tests/reference/ufo/psfsetunicodes.ufo/glyphs/L_tnS_mP_.glif
new file mode 100644
index 0000000..f9e06b1
--- /dev/null
+++ b/tests/reference/ufo/psfsetunicodes.ufo/glyphs/L_tnS_mP_.glif
@@ -0,0 +1,66 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmP" format="2">
+ <advance width="1185"/>
+ <unicode hex="0070"/>
+ <anchor x="105" y="-435" name="H"/>
+ <anchor x="405" y="-500" name="L"/>
+ <anchor x="1360" y="1000" name="R"/>
+ <anchor x="805" y="1100" name="U"/>
+ <outline>
+ <contour>
+ <point x="215" y="-480" type="line"/>
+ <point x="215" y="-388"/>
+ <point x="229" y="-282"/>
+ <point x="255" y="-175" type="curve" smooth="yes"/>
+ <point x="320" y="85" type="line"/>
+ <point x="399" y="20"/>
+ <point x="468" y="-25"/>
+ <point x="575" y="-25" type="curve" smooth="yes"/>
+ <point x="685" y="-25"/>
+ <point x="797" y="9"/>
+ <point x="895" y="85" type="curve" smooth="yes"/>
+ <point x="1063" y="215"/>
+ <point x="1185" y="438"/>
+ <point x="1185" y="680" type="curve" smooth="yes"/>
+ <point x="1185" y="878"/>
+ <point x="1101" y="1020"/>
+ <point x="920" y="1020" type="curve" smooth="yes"/>
+ <point x="757" y="1020"/>
+ <point x="559" y="842"/>
+ <point x="452" y="680" type="curve"/>
+ <point x="468" y="760"/>
+ <point x="477" y="860"/>
+ <point x="477" y="940" type="curve" smooth="yes"/>
+ <point x="477" y="962"/>
+ <point x="477" y="982"/>
+ <point x="475" y="1000" type="curve"/>
+ <point x="295" y="1000" type="line"/>
+ <point x="295" y="971" type="line" smooth="yes"/>
+ <point x="295" y="819"/>
+ <point x="273" y="625"/>
+ <point x="235" y="475" type="curve" smooth="yes"/>
+ <point x="70" y="-175" type="line" smooth="yes"/>
+ <point x="43" y="-281"/>
+ <point x="20" y="-398"/>
+ <point x="20" y="-480" type="curve"/>
+ </contour>
+ <contour>
+ <point x="407" y="432" type="line"/>
+ <point x="544" y="656"/>
+ <point x="732" y="850"/>
+ <point x="840" y="850" type="curve" smooth="yes"/>
+ <point x="939" y="850"/>
+ <point x="990" y="763"/>
+ <point x="990" y="630" type="curve" smooth="yes"/>
+ <point x="990" y="491"/>
+ <point x="926" y="322"/>
+ <point x="815" y="220" type="curve" smooth="yes"/>
+ <point x="759" y="168"/>
+ <point x="693" y="135"/>
+ <point x="615" y="135" type="curve" smooth="yes"/>
+ <point x="523" y="135"/>
+ <point x="479" y="161"/>
+ <point x="365" y="255" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetunicodes.ufo/glyphs/L_tnS_mQ_.glif b/tests/reference/ufo/psfsetunicodes.ufo/glyphs/L_tnS_mQ_.glif
new file mode 100644
index 0000000..58d9f87
--- /dev/null
+++ b/tests/reference/ufo/psfsetunicodes.ufo/glyphs/L_tnS_mQ_.glif
@@ -0,0 +1,54 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmQ" format="2">
+ <advance width="1115"/>
+ <unicode hex="0071"/>
+ <anchor x="370" y="-500" name="L"/>
+ <anchor x="1320" y="1000" name="R"/>
+ <anchor x="770" y="1100" name="U"/>
+ <outline>
+ <contour>
+ <point x="843" y="-480" type="line"/>
+ <point x="843" y="-391"/>
+ <point x="858" y="-294"/>
+ <point x="885" y="-185" type="curve" smooth="yes"/>
+ <point x="1165" y="945" type="line"/>
+ <point x="1066" y="980"/>
+ <point x="946" y="1020"/>
+ <point x="825" y="1020" type="curve" smooth="yes"/>
+ <point x="675" y="1020"/>
+ <point x="550" y="977"/>
+ <point x="440" y="890" type="curve" smooth="yes"/>
+ <point x="260" y="747"/>
+ <point x="135" y="505"/>
+ <point x="135" y="285" type="curve" smooth="yes"/>
+ <point x="135" y="73"/>
+ <point x="261" y="-25"/>
+ <point x="380" y="-25" type="curve" smooth="yes"/>
+ <point x="524" y="-25"/>
+ <point x="751" y="172"/>
+ <point x="825" y="300" type="curve"/>
+ <point x="693" y="-180" type="line" smooth="yes"/>
+ <point x="662" y="-294"/>
+ <point x="648" y="-414"/>
+ <point x="648" y="-480" type="curve"/>
+ </contour>
+ <contour>
+ <point x="885" y="565" type="line"/>
+ <point x="807" y="413"/>
+ <point x="550" y="140"/>
+ <point x="455" y="140" type="curve" smooth="yes"/>
+ <point x="376" y="140"/>
+ <point x="330" y="199"/>
+ <point x="330" y="330" type="curve" smooth="yes"/>
+ <point x="330" y="481"/>
+ <point x="400" y="658"/>
+ <point x="515" y="760" type="curve" smooth="yes"/>
+ <point x="580" y="817"/>
+ <point x="658" y="855"/>
+ <point x="750" y="855" type="curve" smooth="yes"/>
+ <point x="811" y="855"/>
+ <point x="893" y="840"/>
+ <point x="947" y="817" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetunicodes.ufo/glyphs/L_tnS_mR_.glif b/tests/reference/ufo/psfsetunicodes.ufo/glyphs/L_tnS_mR_.glif
new file mode 100644
index 0000000..8037612
--- /dev/null
+++ b/tests/reference/ufo/psfsetunicodes.ufo/glyphs/L_tnS_mR_.glif
@@ -0,0 +1,42 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmR" format="2">
+ <advance width="910"/>
+ <unicode hex="0072"/>
+ <anchor x="210" y="0" name="H"/>
+ <anchor x="220" y="-100" name="L"/>
+ <anchor x="670" y="1100" name="U"/>
+ <outline>
+ <contour>
+ <point x="300" y="0" type="line"/>
+ <point x="402" y="415" type="line"/>
+ <point x="502" y="602"/>
+ <point x="703" y="850"/>
+ <point x="785" y="850" type="curve" smooth="yes"/>
+ <point x="831" y="850"/>
+ <point x="855" y="801"/>
+ <point x="855" y="740" type="curve" smooth="yes"/>
+ <point x="855" y="715"/>
+ <point x="852" y="689"/>
+ <point x="845" y="660" type="curve"/>
+ <point x="1010" y="690" type="line"/>
+ <point x="1022" y="737"/>
+ <point x="1030" y="783"/>
+ <point x="1030" y="825" type="curve" smooth="yes"/>
+ <point x="1030" y="935"/>
+ <point x="986" y="1020"/>
+ <point x="865" y="1020" type="curve" smooth="yes"/>
+ <point x="735" y="1020"/>
+ <point x="575" y="867"/>
+ <point x="445" y="675" type="curve"/>
+ <point x="467" y="773"/>
+ <point x="475" y="929"/>
+ <point x="475" y="1000" type="curve"/>
+ <point x="295" y="1000" type="line"/>
+ <point x="295" y="961" type="line" smooth="yes"/>
+ <point x="295" y="833"/>
+ <point x="283" y="679"/>
+ <point x="262" y="595" type="curve" smooth="yes"/>
+ <point x="115" y="0" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetunicodes.ufo/glyphs/L_tnS_mS_.glif b/tests/reference/ufo/psfsetunicodes.ufo/glyphs/L_tnS_mS_.glif
new file mode 100644
index 0000000..848ddda
--- /dev/null
+++ b/tests/reference/ufo/psfsetunicodes.ufo/glyphs/L_tnS_mS_.glif
@@ -0,0 +1,50 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmS" format="2">
+ <advance width="945"/>
+ <unicode hex="0073"/>
+ <anchor x="435" y="0" name="H"/>
+ <anchor x="440" y="-100" name="L"/>
+ <anchor x="710" y="1100" name="U"/>
+ <outline>
+ <contour>
+ <point x="990" y="941" type="line"/>
+ <point x="930" y="978"/>
+ <point x="815" y="1020"/>
+ <point x="640" y="1020" type="curve" smooth="yes"/>
+ <point x="384" y="1020"/>
+ <point x="230" y="881"/>
+ <point x="230" y="716" type="curve" smooth="yes"/>
+ <point x="230" y="614"/>
+ <point x="320" y="533"/>
+ <point x="466" y="461" type="curve" smooth="yes"/>
+ <point x="638" y="376"/>
+ <point x="700" y="333"/>
+ <point x="700" y="265" type="curve" smooth="yes"/>
+ <point x="700" y="188"/>
+ <point x="621" y="132"/>
+ <point x="532" y="132" type="curve" smooth="yes"/>
+ <point x="376" y="132"/>
+ <point x="244" y="216"/>
+ <point x="159" y="325" type="curve"/>
+ <point x="71" y="158" type="line"/>
+ <point x="160" y="60"/>
+ <point x="296" y="-25"/>
+ <point x="488" y="-25" type="curve" smooth="yes"/>
+ <point x="713" y="-25"/>
+ <point x="891" y="106"/>
+ <point x="891" y="306" type="curve" smooth="yes"/>
+ <point x="891" y="432"/>
+ <point x="774" y="515"/>
+ <point x="626" y="593" type="curve" smooth="yes"/>
+ <point x="476" y="672"/>
+ <point x="418" y="695"/>
+ <point x="418" y="753" type="curve" smooth="yes"/>
+ <point x="418" y="822"/>
+ <point x="494" y="862"/>
+ <point x="619" y="862" type="curve" smooth="yes"/>
+ <point x="743" y="862"/>
+ <point x="854" y="808"/>
+ <point x="911" y="769" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetunicodes.ufo/glyphs/L_tnS_mT_.glif b/tests/reference/ufo/psfsetunicodes.ufo/glyphs/L_tnS_mT_.glif
new file mode 100644
index 0000000..0eddfe9
--- /dev/null
+++ b/tests/reference/ufo/psfsetunicodes.ufo/glyphs/L_tnS_mT_.glif
@@ -0,0 +1,45 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmT" format="2">
+ <advance width="815"/>
+ <unicode hex="0074"/>
+ <anchor x="455" y="0" name="H"/>
+ <anchor x="390" y="-100" name="L"/>
+ <anchor x="1025" y="1000" name="R"/>
+ <anchor x="605" y="1360" name="U"/>
+ <outline>
+ <contour>
+ <point x="752" y="211" type="line"/>
+ <point x="665" y="169"/>
+ <point x="593" y="134"/>
+ <point x="527" y="134" type="curve" smooth="yes"/>
+ <point x="448" y="134"/>
+ <point x="425" y="188"/>
+ <point x="425" y="247" type="curve" smooth="yes"/>
+ <point x="425" y="274"/>
+ <point x="429" y="301"/>
+ <point x="434" y="326" type="curve" smooth="yes"/>
+ <point x="470" y="519"/>
+ <point x="564" y="843"/>
+ <point x="677" y="1294" type="curve"/>
+ <point x="492" y="1294" type="line"/>
+ <point x="377" y="841"/>
+ <point x="263" y="429"/>
+ <point x="243" y="301" type="curve" smooth="yes"/>
+ <point x="238" y="269"/>
+ <point x="236" y="240"/>
+ <point x="236" y="213" type="curve" smooth="yes"/>
+ <point x="236" y="41"/>
+ <point x="330" y="-25"/>
+ <point x="465" y="-25" type="curve" smooth="yes"/>
+ <point x="535" y="-25"/>
+ <point x="634" y="-6"/>
+ <point x="740" y="52" type="curve"/>
+ </contour>
+ <contour>
+ <point x="177" y="833" type="line"/>
+ <point x="887" y="833" type="line"/>
+ <point x="923" y="975" type="line"/>
+ <point x="213" y="975" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetunicodes.ufo/glyphs/L_tnS_mU_.glif b/tests/reference/ufo/psfsetunicodes.ufo/glyphs/L_tnS_mU_.glif
new file mode 100644
index 0000000..0eda3d2
--- /dev/null
+++ b/tests/reference/ufo/psfsetunicodes.ufo/glyphs/L_tnS_mU_.glif
@@ -0,0 +1,57 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmU" format="2">
+ <advance width="1175"/>
+ <unicode hex="0075"/>
+ <anchor x="465" y="0" name="H"/>
+ <anchor x="504" y="-100" name="L"/>
+ <anchor x="640" y="0" name="O"/>
+ <anchor x="1375" y="1000" name="R"/>
+ <anchor x="804" y="1100" name="U"/>
+ <outline>
+ <contour>
+ <point x="1040" y="0" type="line"/>
+ <point x="1036" y="29"/>
+ <point x="1035" y="62"/>
+ <point x="1035" y="100" type="curve" smooth="yes"/>
+ <point x="1035" y="206"/>
+ <point x="1054" y="341"/>
+ <point x="1080" y="455" type="curve" smooth="yes"/>
+ <point x="1135" y="689"/>
+ <point x="1197" y="895"/>
+ <point x="1205" y="1000" type="curve"/>
+ <point x="1010" y="1000" type="line"/>
+ <point x="1003" y="882"/>
+ <point x="971" y="769"/>
+ <point x="920" y="565" type="curve"/>
+ <point x="827" y="376"/>
+ <point x="573" y="135"/>
+ <point x="475" y="135" type="curve" smooth="yes"/>
+ <point x="409" y="135"/>
+ <point x="365" y="181"/>
+ <point x="365" y="280" type="curve" smooth="yes"/>
+ <point x="365" y="347"/>
+ <point x="407" y="500"/>
+ <point x="459" y="702" type="curve" smooth="yes"/>
+ <point x="494" y="837"/>
+ <point x="515" y="925"/>
+ <point x="520" y="1000" type="curve"/>
+ <point x="325" y="1000" type="line"/>
+ <point x="313" y="882"/>
+ <point x="295" y="809"/>
+ <point x="265" y="685" type="curve" smooth="yes"/>
+ <point x="195" y="395" type="line" smooth="yes"/>
+ <point x="179" y="330"/>
+ <point x="170" y="275"/>
+ <point x="170" y="225" type="curve" smooth="yes"/>
+ <point x="170" y="60"/>
+ <point x="257" y="-25"/>
+ <point x="410" y="-25" type="curve" smooth="yes"/>
+ <point x="551" y="-25"/>
+ <point x="745" y="118"/>
+ <point x="880" y="305" type="curve"/>
+ <point x="861" y="196"/>
+ <point x="860" y="98"/>
+ <point x="860" y="0" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetunicodes.ufo/glyphs/L_tnS_mV_.glif b/tests/reference/ufo/psfsetunicodes.ufo/glyphs/L_tnS_mV_.glif
new file mode 100644
index 0000000..33e91d6
--- /dev/null
+++ b/tests/reference/ufo/psfsetunicodes.ufo/glyphs/L_tnS_mV_.glif
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmV" format="2">
+ <advance width="941"/>
+ <unicode hex="0076"/>
+ <anchor x="359" y="0" name="H"/>
+ <anchor x="350" y="-100" name="L"/>
+ <anchor x="565" y="0" name="O"/>
+ <anchor x="650" y="1100" name="U"/>
+ <outline>
+ <contour>
+ <point x="180" y="1000" type="line"/>
+ <point x="232" y="825"/>
+ <point x="256" y="602"/>
+ <point x="256" y="354" type="curve" smooth="yes"/>
+ <point x="256" y="241"/>
+ <point x="251" y="122"/>
+ <point x="241" y="0" type="curve"/>
+ <point x="441" y="0" type="line"/>
+ <point x="744" y="336"/>
+ <point x="1056" y="765"/>
+ <point x="1056" y="1000" type="curve"/>
+ <point x="856" y="1000" type="line"/>
+ <point x="856" y="769"/>
+ <point x="606" y="394"/>
+ <point x="404" y="176" type="curve"/>
+ <point x="421" y="277"/>
+ <point x="429" y="402"/>
+ <point x="429" y="526" type="curve" smooth="yes"/>
+ <point x="429" y="707"/>
+ <point x="412" y="887"/>
+ <point x="380" y="1000" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetunicodes.ufo/glyphs/L_tnS_mW_.glif b/tests/reference/ufo/psfsetunicodes.ufo/glyphs/L_tnS_mW_.glif
new file mode 100644
index 0000000..1daea7c
--- /dev/null
+++ b/tests/reference/ufo/psfsetunicodes.ufo/glyphs/L_tnS_mW_.glif
@@ -0,0 +1,50 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmW" format="2">
+ <advance width="1555"/>
+ <unicode hex="0077"/>
+ <anchor x="690" y="-100" name="L"/>
+ <anchor x="990" y="1100" name="U"/>
+ <outline>
+ <contour>
+ <point x="858" y="1000" type="line"/>
+ <point x="743" y="739"/>
+ <point x="588" y="466"/>
+ <point x="388" y="181" type="curve"/>
+ <point x="417" y="339"/>
+ <point x="430" y="500"/>
+ <point x="430" y="644" type="curve" smooth="yes"/>
+ <point x="430" y="784"/>
+ <point x="418" y="908"/>
+ <point x="395" y="1000" type="curve"/>
+ <point x="195" y="1000" type="line"/>
+ <point x="234" y="873"/>
+ <point x="256" y="688"/>
+ <point x="256" y="472" type="curve" smooth="yes"/>
+ <point x="256" y="326"/>
+ <point x="246" y="166"/>
+ <point x="225" y="0" type="curve"/>
+ <point x="425" y="0" type="line"/>
+ <point x="632" y="298"/>
+ <point x="825" y="583"/>
+ <point x="896" y="765" type="curve"/>
+ <point x="920" y="478"/>
+ <point x="912" y="233"/>
+ <point x="915" y="0" type="curve"/>
+ <point x="1115" y="0" type="line"/>
+ <point x="1362" y="330"/>
+ <point x="1642" y="777"/>
+ <point x="1645" y="1000" type="curve"/>
+ <point x="1445" y="1000" type="line"/>
+ <point x="1445" y="990" type="line"/>
+ <point x="1445" y="797"/>
+ <point x="1242" y="417"/>
+ <point x="1063" y="181" type="curve"/>
+ <point x="1064" y="221"/>
+ <point x="1064" y="260"/>
+ <point x="1064" y="298" type="curve" smooth="yes"/>
+ <point x="1064" y="577"/>
+ <point x="1046" y="811"/>
+ <point x="1020" y="1000" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetunicodes.ufo/glyphs/L_tnS_mX_.glif b/tests/reference/ufo/psfsetunicodes.ufo/glyphs/L_tnS_mX_.glif
new file mode 100644
index 0000000..5508ff9
--- /dev/null
+++ b/tests/reference/ufo/psfsetunicodes.ufo/glyphs/L_tnS_mX_.glif
@@ -0,0 +1,40 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmX" format="2">
+ <advance width="1009"/>
+ <unicode hex="0078"/>
+ <anchor x="840" y="0" name="H"/>
+ <anchor x="457" y="-100" name="L"/>
+ <anchor x="657" y="1100" name="U"/>
+ <outline>
+ <contour>
+ <point x="945" y="0" type="line"/>
+ <point x="765" y="133"/>
+ <point x="558" y="867"/>
+ <point x="439" y="1000" type="curve"/>
+ <point x="181" y="1000" type="line"/>
+ <point x="410" y="832"/>
+ <point x="578" y="141"/>
+ <point x="698" y="0" type="curve"/>
+ </contour>
+ <contour>
+ <point x="504" y="572" type="line"/>
+ <point x="286" y="463"/>
+ <point x="57" y="230"/>
+ <point x="30" y="0" type="curve"/>
+ <point x="230" y="0" type="line"/>
+ <point x="231" y="156"/>
+ <point x="375" y="380"/>
+ <point x="563" y="467" type="curve"/>
+ </contour>
+ <contour>
+ <point x="659" y="471" type="line"/>
+ <point x="838" y="591"/>
+ <point x="1092" y="798"/>
+ <point x="1099" y="1000" type="curve"/>
+ <point x="889" y="1000" type="line"/>
+ <point x="883" y="842"/>
+ <point x="758" y="675"/>
+ <point x="601" y="581" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetunicodes.ufo/glyphs/L_tnS_mY_.glif b/tests/reference/ufo/psfsetunicodes.ufo/glyphs/L_tnS_mY_.glif
new file mode 100644
index 0000000..b9000c5
--- /dev/null
+++ b/tests/reference/ufo/psfsetunicodes.ufo/glyphs/L_tnS_mY_.glif
@@ -0,0 +1,45 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="LtnSmY" format="2">
+ <advance width="976"/>
+ <unicode hex="0079"/>
+ <anchor x="710" y="-100" name="L"/>
+ <anchor x="1270" y="1000" name="R"/>
+ <anchor x="630" y="1100" name="U"/>
+ <outline>
+ <contour>
+ <point x="132" y="1000" type="line"/>
+ <point x="270" y="825"/>
+ <point x="398" y="406"/>
+ <point x="403" y="-16" type="curve"/>
+ <point x="263" y="-232"/>
+ <point x="145" y="-295"/>
+ <point x="64" y="-295" type="curve" smooth="yes"/>
+ <point x="-2" y="-295"/>
+ <point x="-69" y="-254"/>
+ <point x="-102" y="-220" type="curve"/>
+ <point x="-200" y="-377" type="line"/>
+ <point x="-141" y="-430"/>
+ <point x="-68" y="-465"/>
+ <point x="23" y="-465" type="curve" smooth="yes"/>
+ <point x="193" y="-465"/>
+ <point x="369" y="-371"/>
+ <point x="609" y="0" type="curve" smooth="yes"/>
+ <point x="877" y="414"/>
+ <point x="1056" y="808"/>
+ <point x="1056" y="964" type="curve" smooth="yes"/>
+ <point x="1056" y="978"/>
+ <point x="1055" y="990"/>
+ <point x="1052" y="1000" type="curve"/>
+ <point x="852" y="1000" type="line"/>
+ <point x="856" y="984"/>
+ <point x="858" y="967"/>
+ <point x="858" y="946" type="curve" smooth="yes"/>
+ <point x="858" y="783"/>
+ <point x="722" y="472"/>
+ <point x="548" y="189" type="curve"/>
+ <point x="548" y="484"/>
+ <point x="447" y="866"/>
+ <point x="347" y="1000" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetunicodes.ufo/glyphs/N_onB_reakingH_yphen.glif b/tests/reference/ufo/psfsetunicodes.ufo/glyphs/N_onB_reakingH_yphen.glif
new file mode 100644
index 0000000..e7d9c06
--- /dev/null
+++ b/tests/reference/ufo/psfsetunicodes.ufo/glyphs/N_onB_reakingH_yphen.glif
@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="NonBreakingHyphen" format="2">
+ <advance width="840"/>
+ <unicode hex="2011"/>
+ <anchor x="645" y="1100" name="U"/>
+ <outline>
+ <component base="HyphenMinus"/>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetunicodes.ufo/glyphs/N_umS_gn.glif b/tests/reference/ufo/psfsetunicodes.ufo/glyphs/N_umS_gn.glif
new file mode 100644
index 0000000..b7506f7
--- /dev/null
+++ b/tests/reference/ufo/psfsetunicodes.ufo/glyphs/N_umS_gn.glif
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="NumSgn" format="2">
+ <advance width="1180"/>
+ <unicode hex="0023"/>
+ <outline>
+ <contour>
+ <point x="739" y="1333" type="line"/>
+ <point x="91" y="98" type="line"/>
+ <point x="261" y="98" type="line"/>
+ <point x="909" y="1333" type="line"/>
+ </contour>
+ <contour>
+ <point x="80" y="465" type="line"/>
+ <point x="1171" y="465" type="line"/>
+ <point x="1208" y="612" type="line"/>
+ <point x="117" y="612" type="line"/>
+ </contour>
+ <contour>
+ <point x="234" y="843" type="line"/>
+ <point x="1325" y="843" type="line"/>
+ <point x="1361" y="990" type="line"/>
+ <point x="270" y="990" type="line"/>
+ </contour>
+ <contour>
+ <point x="1164" y="1333" type="line"/>
+ <point x="516" y="98" type="line"/>
+ <point x="686" y="98" type="line"/>
+ <point x="1334" y="1333" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetunicodes.ufo/glyphs/P_ercentS_gn.glif b/tests/reference/ufo/psfsetunicodes.ufo/glyphs/P_ercentS_gn.glif
new file mode 100644
index 0000000..84241ea
--- /dev/null
+++ b/tests/reference/ufo/psfsetunicodes.ufo/glyphs/P_ercentS_gn.glif
@@ -0,0 +1,93 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="PercentSgn" format="2">
+ <advance width="1506"/>
+ <unicode hex="0025"/>
+ <outline>
+ <contour>
+ <point x="1300" y="349" type="curve" smooth="yes"/>
+ <point x="1255" y="168"/>
+ <point x="1204" y="113"/>
+ <point x="1118" y="113" type="curve" smooth="yes"/>
+ <point x="1056" y="113"/>
+ <point x="1021" y="148"/>
+ <point x="1021" y="235" type="curve" smooth="yes"/>
+ <point x="1021" y="274"/>
+ <point x="1028" y="322"/>
+ <point x="1043" y="383" type="curve" smooth="yes"/>
+ <point x="1088" y="564"/>
+ <point x="1136" y="617"/>
+ <point x="1223" y="617" type="curve" smooth="yes"/>
+ <point x="1286" y="617"/>
+ <point x="1322" y="582"/>
+ <point x="1322" y="496" type="curve" smooth="yes"/>
+ <point x="1322" y="458"/>
+ <point x="1315" y="409"/>
+ </contour>
+ <contour>
+ <point x="1468" y="361" type="curve" smooth="yes"/>
+ <point x="1483" y="419"/>
+ <point x="1489" y="470"/>
+ <point x="1489" y="515" type="curve" smooth="yes"/>
+ <point x="1489" y="677"/>
+ <point x="1400" y="755"/>
+ <point x="1263" y="755" type="curve" smooth="yes"/>
+ <point x="1089" y="755"/>
+ <point x="945" y="647"/>
+ <point x="876" y="371" type="curve" smooth="yes"/>
+ <point x="861" y="310"/>
+ <point x="854" y="256"/>
+ <point x="854" y="210" type="curve" smooth="yes"/>
+ <point x="854" y="47"/>
+ <point x="943" y="-25"/>
+ <point x="1079" y="-25" type="curve" smooth="yes"/>
+ <point x="1254" y="-25"/>
+ <point x="1396" y="72"/>
+ </contour>
+ <contour>
+ <point x="1369" y="1450" type="line"/>
+ <point x="219" y="-25" type="line"/>
+ <point x="397" y="-25" type="line"/>
+ <point x="1545" y="1450" type="line"/>
+ </contour>
+ <contour>
+ <point x="717" y="1044" type="curve" smooth="yes"/>
+ <point x="672" y="864"/>
+ <point x="621" y="809"/>
+ <point x="535" y="809" type="curve" smooth="yes"/>
+ <point x="474" y="809"/>
+ <point x="439" y="844"/>
+ <point x="439" y="930" type="curve" smooth="yes"/>
+ <point x="439" y="969"/>
+ <point x="446" y="1018"/>
+ <point x="461" y="1079" type="curve" smooth="yes"/>
+ <point x="506" y="1260"/>
+ <point x="554" y="1313"/>
+ <point x="641" y="1313" type="curve" smooth="yes"/>
+ <point x="704" y="1313"/>
+ <point x="739" y="1278"/>
+ <point x="739" y="1192" type="curve" smooth="yes"/>
+ <point x="739" y="1153"/>
+ <point x="732" y="1105"/>
+ </contour>
+ <contour>
+ <point x="886" y="1057" type="curve" smooth="yes"/>
+ <point x="900" y="1114"/>
+ <point x="907" y="1166"/>
+ <point x="907" y="1210" type="curve" smooth="yes"/>
+ <point x="907" y="1373"/>
+ <point x="817" y="1450"/>
+ <point x="680" y="1450" type="curve" smooth="yes"/>
+ <point x="506" y="1450"/>
+ <point x="362" y="1343"/>
+ <point x="293" y="1066" type="curve" smooth="yes"/>
+ <point x="278" y="1005"/>
+ <point x="271" y="952"/>
+ <point x="271" y="906" type="curve" smooth="yes"/>
+ <point x="271" y="743"/>
+ <point x="360" y="671"/>
+ <point x="497" y="671" type="curve" smooth="yes"/>
+ <point x="672" y="671"/>
+ <point x="813" y="768"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetunicodes.ufo/glyphs/P_lusS_gn.glif b/tests/reference/ufo/psfsetunicodes.ufo/glyphs/P_lusS_gn.glif
new file mode 100644
index 0000000..8c4577e
--- /dev/null
+++ b/tests/reference/ufo/psfsetunicodes.ufo/glyphs/P_lusS_gn.glif
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="PlusSgn" format="2">
+ <advance width="1180"/>
+ <unicode hex="002B"/>
+ <outline>
+ <contour>
+ <point x="748" y="1156" type="line"/>
+ <point x="529" y="279" type="line"/>
+ <point x="684" y="279" type="line"/>
+ <point x="903" y="1156" type="line"/>
+ </contour>
+ <contour>
+ <point x="256" y="647" type="line"/>
+ <point x="1146" y="647" type="line"/>
+ <point x="1182" y="794" type="line"/>
+ <point x="292" y="794" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetunicodes.ufo/glyphs/Q_stnM_rk.glif b/tests/reference/ufo/psfsetunicodes.ufo/glyphs/Q_stnM_rk.glif
new file mode 100644
index 0000000..8b14a6c
--- /dev/null
+++ b/tests/reference/ufo/psfsetunicodes.ufo/glyphs/Q_stnM_rk.glif
@@ -0,0 +1,49 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="QstnMrk" format="2">
+ <advance width="1030"/>
+ <unicode hex="003F"/>
+ <outline>
+ <contour>
+ <point x="419" y="1226" type="line"/>
+ <point x="514" y="1303"/>
+ <point x="615" y="1338"/>
+ <point x="685" y="1338" type="curve" smooth="yes"/>
+ <point x="800" y="1338"/>
+ <point x="858" y="1294"/>
+ <point x="858" y="1222" type="curve" smooth="yes"/>
+ <point x="858" y="1122"/>
+ <point x="713" y="1017"/>
+ <point x="654" y="960" type="curve" smooth="yes"/>
+ <point x="538" y="850"/>
+ <point x="473" y="715"/>
+ <point x="402" y="431" type="curve"/>
+ <point x="587" y="431" type="line"/>
+ <point x="656" y="707"/>
+ <point x="697" y="778"/>
+ <point x="831" y="901" type="curve" smooth="yes"/>
+ <point x="949" y="1010"/>
+ <point x="1072" y="1146"/>
+ <point x="1072" y="1272" type="curve" smooth="yes"/>
+ <point x="1072" y="1409"/>
+ <point x="947" y="1509"/>
+ <point x="746" y="1509" type="curve" smooth="yes"/>
+ <point x="631" y="1509"/>
+ <point x="500" y="1463"/>
+ <point x="419" y="1401" type="curve"/>
+ </contour>
+ <contour>
+ <point x="278" y="90" type="curve" smooth="yes"/>
+ <point x="278" y="28"/>
+ <point x="328" y="-25"/>
+ <point x="393" y="-25" type="curve" smooth="yes"/>
+ <point x="477" y="-25"/>
+ <point x="554" y="45"/>
+ <point x="554" y="125" type="curve" smooth="yes"/>
+ <point x="554" y="186"/>
+ <point x="504" y="240"/>
+ <point x="439" y="240" type="curve" smooth="yes"/>
+ <point x="355" y="240"/>
+ <point x="278" y="170"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetunicodes.ufo/glyphs/Q_uotM_rk.glif b/tests/reference/ufo/psfsetunicodes.ufo/glyphs/Q_uotM_rk.glif
new file mode 100644
index 0000000..4a8357b
--- /dev/null
+++ b/tests/reference/ufo/psfsetunicodes.ufo/glyphs/Q_uotM_rk.glif
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="QuotMrk" format="2">
+ <advance width="1005"/>
+ <unicode hex="0022"/>
+ <outline>
+ <contour>
+ <point x="600" y="1024" type="line"/>
+ <point x="639" y="1162"/>
+ <point x="683" y="1312"/>
+ <point x="772" y="1553" type="curve"/>
+ <point x="567" y="1553" type="line"/>
+ <point x="538" y="1312"/>
+ <point x="505" y="1162"/>
+ <point x="475" y="1024" type="curve"/>
+ </contour>
+ <contour>
+ <point x="940" y="1024" type="line"/>
+ <point x="979" y="1162"/>
+ <point x="1023" y="1312"/>
+ <point x="1112" y="1553" type="curve"/>
+ <point x="907" y="1553" type="line"/>
+ <point x="878" y="1312"/>
+ <point x="845" y="1162"/>
+ <point x="815" y="1024" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetunicodes.ufo/glyphs/R_everseS_olidus.glif b/tests/reference/ufo/psfsetunicodes.ufo/glyphs/R_everseS_olidus.glif
new file mode 100644
index 0000000..f146267
--- /dev/null
+++ b/tests/reference/ufo/psfsetunicodes.ufo/glyphs/R_everseS_olidus.glif
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="ReverseSolidus" format="2">
+ <advance width="1005"/>
+ <unicode hex="005C"/>
+ <outline>
+ <contour>
+ <point x="473" y="1538" type="line"/>
+ <point x="656" y="-123" type="line"/>
+ <point x="799" y="-93" type="line"/>
+ <point x="620" y="1568" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetunicodes.ufo/glyphs/R_tC_urlyB_rac.glif b/tests/reference/ufo/psfsetunicodes.ufo/glyphs/R_tC_urlyB_rac.glif
new file mode 100644
index 0000000..82df531
--- /dev/null
+++ b/tests/reference/ufo/psfsetunicodes.ufo/glyphs/R_tC_urlyB_rac.glif
@@ -0,0 +1,50 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="RtCurlyBrac" format="2">
+ <advance width="980"/>
+ <unicode hex="007D"/>
+ <outline>
+ <contour>
+ <point x="466" y="1470" type="line"/>
+ <point x="513" y="1452"/>
+ <point x="653" y="1397"/>
+ <point x="653" y="1366" type="curve" smooth="yes"/>
+ <point x="653" y="1238"/>
+ <point x="531" y="801"/>
+ <point x="531" y="737" type="curve" smooth="yes"/>
+ <point x="531" y="701"/>
+ <point x="660" y="627"/>
+ <point x="660" y="603" type="curve" smooth="yes"/>
+ <point x="660" y="585"/>
+ <point x="496" y="511"/>
+ <point x="468" y="475" type="curve" smooth="yes"/>
+ <point x="439" y="438"/>
+ <point x="312" y="-121"/>
+ <point x="268" y="-167" type="curve" smooth="yes"/>
+ <point x="241" y="-194"/>
+ <point x="106" y="-242"/>
+ <point x="33" y="-265" type="curve"/>
+ <point x="39" y="-402" type="line"/>
+ <point x="150" y="-375"/>
+ <point x="324" y="-323"/>
+ <point x="375" y="-279" type="curve" smooth="yes"/>
+ <point x="465" y="-201"/>
+ <point x="608" y="410"/>
+ <point x="639" y="441" type="curve" smooth="yes"/>
+ <point x="675" y="476"/>
+ <point x="880" y="571"/>
+ <point x="880" y="607" type="curve" smooth="yes"/>
+ <point x="880" y="639"/>
+ <point x="719" y="740"/>
+ <point x="719" y="771" type="curve" smooth="yes"/>
+ <point x="719" y="839"/>
+ <point x="825" y="1259"/>
+ <point x="825" y="1425" type="curve" smooth="yes"/>
+ <point x="825" y="1453"/>
+ <point x="822" y="1474"/>
+ <point x="815" y="1485" type="curve" smooth="yes"/>
+ <point x="786" y="1529"/>
+ <point x="638" y="1581"/>
+ <point x="540" y="1607" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetunicodes.ufo/glyphs/R_tP_aren.glif b/tests/reference/ufo/psfsetunicodes.ufo/glyphs/R_tP_aren.glif
new file mode 100644
index 0000000..3950e09
--- /dev/null
+++ b/tests/reference/ufo/psfsetunicodes.ufo/glyphs/R_tP_aren.glif
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="RtParen" format="2">
+ <advance width="775"/>
+ <unicode hex="0029"/>
+ <outline>
+ <contour>
+ <point x="467" y="1455" type="line"/>
+ <point x="578" y="1327"/>
+ <point x="628" y="1146"/>
+ <point x="628" y="946" type="curve" smooth="yes"/>
+ <point x="628" y="832"/>
+ <point x="612" y="713"/>
+ <point x="582" y="593" type="curve" smooth="yes"/>
+ <point x="497" y="252"/>
+ <point x="328" y="-8"/>
+ <point x="40" y="-260" type="curve"/>
+ <point x="99" y="-402" type="line"/>
+ <point x="444" y="-123"/>
+ <point x="673" y="194"/>
+ <point x="772" y="593" type="curve" smooth="yes"/>
+ <point x="804" y="719"/>
+ <point x="819" y="843"/>
+ <point x="819" y="959" type="curve" smooth="yes"/>
+ <point x="819" y="1236"/>
+ <point x="733" y="1472"/>
+ <point x="580" y="1607" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetunicodes.ufo/glyphs/R_tS_qrB_rac.glif b/tests/reference/ufo/psfsetunicodes.ufo/glyphs/R_tS_qrB_rac.glif
new file mode 100644
index 0000000..4c13a82
--- /dev/null
+++ b/tests/reference/ufo/psfsetunicodes.ufo/glyphs/R_tS_qrB_rac.glif
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="RtSqrBrac" format="2">
+ <advance width="770"/>
+ <unicode hex="005D"/>
+ <outline>
+ <contour>
+ <point x="434" y="-402" type="line"/>
+ <point x="920" y="1568" type="line"/>
+ <point x="480" y="1568" type="line"/>
+ <point x="444" y="1421" type="line"/>
+ <point x="699" y="1421" type="line"/>
+ <point x="286" y="-255" type="line"/>
+ <point x="31" y="-255" type="line"/>
+ <point x="-6" y="-402" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetunicodes.ufo/glyphs/S_emicolon.glif b/tests/reference/ufo/psfsetunicodes.ufo/glyphs/S_emicolon.glif
new file mode 100644
index 0000000..be971ac
--- /dev/null
+++ b/tests/reference/ufo/psfsetunicodes.ufo/glyphs/S_emicolon.glif
@@ -0,0 +1,38 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="Semicolon" format="2">
+ <advance width="630"/>
+ <unicode hex="003B"/>
+ <outline>
+ <contour>
+ <point x="314" y="758" type="curve" smooth="yes"/>
+ <point x="314" y="696"/>
+ <point x="365" y="642"/>
+ <point x="430" y="642" type="curve" smooth="yes"/>
+ <point x="514" y="642"/>
+ <point x="590" y="712"/>
+ <point x="590" y="792" type="curve" smooth="yes"/>
+ <point x="590" y="854"/>
+ <point x="540" y="907"/>
+ <point x="476" y="907" type="curve" smooth="yes"/>
+ <point x="393" y="907"/>
+ <point x="314" y="837"/>
+ </contour>
+ <contour>
+ <point x="137" y="49" type="line"/>
+ <point x="277" y="49" type="line"/>
+ <point x="252" y="-50"/>
+ <point x="145" y="-169"/>
+ <point x="73" y="-225" type="curve"/>
+ <point x="163" y="-265" type="line"/>
+ <point x="280" y="-175"/>
+ <point x="431" y="-28"/>
+ <point x="431" y="118" type="curve" smooth="yes"/>
+ <point x="431" y="193"/>
+ <point x="378" y="245"/>
+ <point x="311" y="245" type="curve" smooth="yes"/>
+ <point x="254" y="245"/>
+ <point x="190" y="209"/>
+ <point x="161" y="147" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetunicodes.ufo/glyphs/S_olidus.glif b/tests/reference/ufo/psfsetunicodes.ufo/glyphs/S_olidus.glif
new file mode 100644
index 0000000..589697b
--- /dev/null
+++ b/tests/reference/ufo/psfsetunicodes.ufo/glyphs/S_olidus.glif
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="Solidus" format="2">
+ <advance width="980"/>
+ <unicode hex="002F"/>
+ <outline>
+ <contour>
+ <point x="1160" y="1568" type="line"/>
+ <point x="-119" y="-240" type="line"/>
+ <point x="50" y="-240" type="line"/>
+ <point x="1330" y="1568" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetunicodes.ufo/glyphs/S_pace.glif b/tests/reference/ufo/psfsetunicodes.ufo/glyphs/S_pace.glif
new file mode 100644
index 0000000..c49f0f2
--- /dev/null
+++ b/tests/reference/ufo/psfsetunicodes.ufo/glyphs/S_pace.glif
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="Space" format="2">
+ <advance width="530"/>
+ <unicode hex="0020"/>
+ <outline/>
+</glyph>
diff --git a/tests/reference/ufo/psfsetunicodes.ufo/glyphs/T_ilde.glif b/tests/reference/ufo/psfsetunicodes.ufo/glyphs/T_ilde.glif
new file mode 100644
index 0000000..bf260b8
--- /dev/null
+++ b/tests/reference/ufo/psfsetunicodes.ufo/glyphs/T_ilde.glif
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="Tilde" format="2">
+ <advance width="1095"/>
+ <unicode hex="007E"/>
+ <outline>
+ <contour>
+ <point x="156" y="368" type="line"/>
+ <point x="173" y="416"/>
+ <point x="215" y="456"/>
+ <point x="293" y="456" type="curve" smooth="yes"/>
+ <point x="468" y="456"/>
+ <point x="643" y="353"/>
+ <point x="873" y="353" type="curve" smooth="yes"/>
+ <point x="1032" y="353"/>
+ <point x="1137" y="472"/>
+ <point x="1169" y="598" type="curve"/>
+ <point x="1064" y="598" type="line"/>
+ <point x="1045" y="553"/>
+ <point x="1002" y="500"/>
+ <point x="919" y="500" type="curve" smooth="yes"/>
+ <point x="683" y="500"/>
+ <point x="551" y="603"/>
+ <point x="330" y="603" type="curve" smooth="yes"/>
+ <point x="184" y="603"/>
+ <point x="81" y="487"/>
+ <point x="51" y="368" type="curve"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetunicodes.ufo/glyphs/V_ertL_ine.glif b/tests/reference/ufo/psfsetunicodes.ufo/glyphs/V_ertL_ine.glif
new file mode 100644
index 0000000..445d622
--- /dev/null
+++ b/tests/reference/ufo/psfsetunicodes.ufo/glyphs/V_ertL_ine.glif
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="VertLine" format="2">
+ <advance width="670"/>
+ <unicode hex="007C"/>
+ <outline>
+ <contour>
+ <point x="602" y="1578" type="line"/>
+ <point x="112" y="-392" type="line"/>
+ <point x="262" y="-392" type="line"/>
+ <point x="752" y="1578" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetunicodes.ufo/glyphs/_notdef.glif b/tests/reference/ufo/psfsetunicodes.ufo/glyphs/_notdef.glif
new file mode 100644
index 0000000..a3e9354
--- /dev/null
+++ b/tests/reference/ufo/psfsetunicodes.ufo/glyphs/_notdef.glif
@@ -0,0 +1,18 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name=".notdef" format="2">
+ <advance width="1400"/>
+ <outline>
+ <contour>
+ <point x="100" y="0" type="line"/>
+ <point x="1300" y="0" type="line"/>
+ <point x="1300" y="1800" type="line"/>
+ <point x="100" y="1800" type="line"/>
+ </contour>
+ <contour>
+ <point x="150" y="1750" type="line"/>
+ <point x="1250" y="1750" type="line"/>
+ <point x="1250" y="50" type="line"/>
+ <point x="150" y="50" type="line"/>
+ </contour>
+ </outline>
+</glyph>
diff --git a/tests/reference/ufo/psfsetunicodes.ufo/glyphs/_null.glif b/tests/reference/ufo/psfsetunicodes.ufo/glyphs/_null.glif
new file mode 100644
index 0000000..0b9caa6
--- /dev/null
+++ b/tests/reference/ufo/psfsetunicodes.ufo/glyphs/_null.glif
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name=".null" format="2">
+ <outline/>
+</glyph>
diff --git a/tests/reference/ufo/psfsetunicodes.ufo/glyphs/contents.plist b/tests/reference/ufo/psfsetunicodes.ufo/glyphs/contents.plist
new file mode 100644
index 0000000..ad2aa41
--- /dev/null
+++ b/tests/reference/ufo/psfsetunicodes.ufo/glyphs/contents.plist
@@ -0,0 +1,232 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+ <key>.notdef</key>
+ <string>_notdef.glif</string>
+ <key>.null</key>
+ <string>_null.glif</string>
+ <key>Ampersand</key>
+ <string>A_mpersand.glif</string>
+ <key>Apos</key>
+ <string>A_pos.glif</string>
+ <key>Asterisk</key>
+ <string>A_sterisk.glif</string>
+ <key>AtSgn</key>
+ <string>A_tS_gn.glif</string>
+ <key>CircumAccent</key>
+ <string>C_ircumA_ccent.glif</string>
+ <key>Colon</key>
+ <string>C_olon.glif</string>
+ <key>CombAcute</key>
+ <string>C_ombA_cute.glif</string>
+ <key>CombCircum</key>
+ <string>C_ombC_ircum.glif</string>
+ <key>CombDiaer</key>
+ <string>C_ombD_iaer.glif</string>
+ <key>CombGrave</key>
+ <string>C_ombG_rave.glif</string>
+ <key>CombRingAbv</key>
+ <string>C_ombR_ingA_bv.glif</string>
+ <key>CombTilde</key>
+ <string>C_ombT_ilde.glif</string>
+ <key>Comma</key>
+ <string>C_omma.glif</string>
+ <key>DigitEight</key>
+ <string>D_igitE_ight.glif</string>
+ <key>DigitFive</key>
+ <string>D_igitF_ive.glif</string>
+ <key>DigitFour</key>
+ <string>D_igitF_our.glif</string>
+ <key>DigitNine</key>
+ <string>D_igitN_ine.glif</string>
+ <key>DigitOne</key>
+ <string>D_igitO_ne.glif</string>
+ <key>DigitSeven</key>
+ <string>D_igitS_even.glif</string>
+ <key>DigitSix</key>
+ <string>D_igitS_ix.glif</string>
+ <key>DigitThree</key>
+ <string>D_igitT_hree.glif</string>
+ <key>DigitTwo</key>
+ <string>D_igitT_wo.glif</string>
+ <key>DigitZero</key>
+ <string>D_igitZ_ero.glif</string>
+ <key>DollarSgn</key>
+ <string>D_ollarS_gn.glif</string>
+ <key>DottedCirc</key>
+ <string>D_ottedC_irc.glif</string>
+ <key>EqSgn</key>
+ <string>E_qS_gn.glif</string>
+ <key>ExclamationMrk</key>
+ <string>E_xclamationM_rk.glif</string>
+ <key>FullStop</key>
+ <string>F_ullS_top.glif</string>
+ <key>GTSgn</key>
+ <string>G_T_S_gn.glif</string>
+ <key>GraveAccent</key>
+ <string>G_raveA_ccent.glif</string>
+ <key>Hyphen</key>
+ <string>H_yphen.glif</string>
+ <key>HyphenMinus</key>
+ <string>H_yphenM_inus.glif</string>
+ <key>Hyphen_Soft</key>
+ <string>H_yphen_S_oft.glif</string>
+ <key>LTSgn</key>
+ <string>L_T_S_gn.glif</string>
+ <key>LftCurlyBrac</key>
+ <string>L_ftC_urlyB_rac.glif</string>
+ <key>LftParen</key>
+ <string>L_ftP_aren.glif</string>
+ <key>LftSqrBrac</key>
+ <string>L_ftS_qrB_rac.glif</string>
+ <key>LowLine</key>
+ <string>L_owL_ine.glif</string>
+ <key>LtnCapA</key>
+ <string>L_tnC_apA_.glif</string>
+ <key>LtnCapADiaer</key>
+ <string>L_tnC_apA_D_iaer.glif</string>
+ <key>LtnCapB</key>
+ <string>L_tnC_apB_.glif</string>
+ <key>LtnCapC</key>
+ <string>L_tnC_apC_.glif</string>
+ <key>LtnCapD</key>
+ <string>L_tnC_apD_.glif</string>
+ <key>LtnCapE</key>
+ <string>L_tnC_apE_.glif</string>
+ <key>LtnCapF</key>
+ <string>L_tnC_apF_.glif</string>
+ <key>LtnCapG</key>
+ <string>L_tnC_apG_.glif</string>
+ <key>LtnCapH</key>
+ <string>L_tnC_apH_.glif</string>
+ <key>LtnCapI</key>
+ <string>L_tnC_apI_.glif</string>
+ <key>LtnCapJ</key>
+ <string>L_tnC_apJ_.glif</string>
+ <key>LtnCapK</key>
+ <string>L_tnC_apK_.glif</string>
+ <key>LtnCapL</key>
+ <string>L_tnC_apL_.glif</string>
+ <key>LtnCapM</key>
+ <string>L_tnC_apM_.glif</string>
+ <key>LtnCapN</key>
+ <string>L_tnC_apN_.glif</string>
+ <key>LtnCapO</key>
+ <string>L_tnC_apO_.glif</string>
+ <key>LtnCapP</key>
+ <string>L_tnC_apP_.glif</string>
+ <key>LtnCapQ</key>
+ <string>L_tnC_apQ_.glif</string>
+ <key>LtnCapR</key>
+ <string>L_tnC_apR_.glif</string>
+ <key>LtnCapS</key>
+ <string>L_tnC_apS_.glif</string>
+ <key>LtnCapT</key>
+ <string>L_tnC_apT_.glif</string>
+ <key>LtnCapU</key>
+ <string>L_tnC_apU_.glif</string>
+ <key>LtnCapV</key>
+ <string>L_tnC_apV_.glif</string>
+ <key>LtnCapW</key>
+ <string>L_tnC_apW_.glif</string>
+ <key>LtnCapX</key>
+ <string>L_tnC_apX_.glif</string>
+ <key>LtnCapY</key>
+ <string>L_tnC_apY_.glif</string>
+ <key>LtnSmA</key>
+ <string>L_tnS_mA_.glif</string>
+ <key>LtnSmAAcute</key>
+ <string>L_tnS_mA_A_cute.glif</string>
+ <key>LtnSmACircum</key>
+ <string>L_tnS_mA_C_ircum.glif</string>
+ <key>LtnSmADiaer</key>
+ <string>L_tnS_mA_D_iaer.glif</string>
+ <key>LtnSmAGrave</key>
+ <string>L_tnS_mA_G_rave.glif</string>
+ <key>LtnSmARingAbv</key>
+ <string>L_tnS_mA_R_ingA_bv.glif</string>
+ <key>LtnSmATilde</key>
+ <string>L_tnS_mA_T_ilde.glif</string>
+ <key>LtnSmB</key>
+ <string>L_tnS_mB_.glif</string>
+ <key>LtnSmC</key>
+ <string>L_tnS_mC_.glif</string>
+ <key>LtnSmD</key>
+ <string>L_tnS_mD_.glif</string>
+ <key>LtnSmE</key>
+ <string>L_tnS_mE_.glif</string>
+ <key>LtnSmF</key>
+ <string>L_tnS_mF_.glif</string>
+ <key>LtnSmG</key>
+ <string>L_tnS_mG_.glif</string>
+ <key>LtnSmH</key>
+ <string>L_tnS_mH_.glif</string>
+ <key>LtnSmI</key>
+ <string>L_tnS_mI_.glif</string>
+ <key>LtnSmJ</key>
+ <string>L_tnS_mJ_.glif</string>
+ <key>LtnSmK</key>
+ <string>L_tnS_mK_.glif</string>
+ <key>LtnSmL</key>
+ <string>L_tnS_mL_.glif</string>
+ <key>LtnSmM</key>
+ <string>L_tnS_mM_.glif</string>
+ <key>LtnSmN</key>
+ <string>L_tnS_mN_.glif</string>
+ <key>LtnSmO</key>
+ <string>L_tnS_mO_.glif</string>
+ <key>LtnSmP</key>
+ <string>L_tnS_mP_.glif</string>
+ <key>LtnSmQ</key>
+ <string>L_tnS_mQ_.glif</string>
+ <key>LtnSmR</key>
+ <string>L_tnS_mR_.glif</string>
+ <key>LtnSmS</key>
+ <string>L_tnS_mS_.glif</string>
+ <key>LtnSmT</key>
+ <string>L_tnS_mT_.glif</string>
+ <key>LtnSmU</key>
+ <string>L_tnS_mU_.glif</string>
+ <key>LtnSmV</key>
+ <string>L_tnS_mV_.glif</string>
+ <key>LtnSmW</key>
+ <string>L_tnS_mW_.glif</string>
+ <key>LtnSmX</key>
+ <string>L_tnS_mX_.glif</string>
+ <key>LtnSmY</key>
+ <string>L_tnS_mY_.glif</string>
+ <key>NonBreakingHyphen</key>
+ <string>N_onB_reakingH_yphen.glif</string>
+ <key>NumSgn</key>
+ <string>N_umS_gn.glif</string>
+ <key>PercentSgn</key>
+ <string>P_ercentS_gn.glif</string>
+ <key>PlusSgn</key>
+ <string>P_lusS_gn.glif</string>
+ <key>QstnMrk</key>
+ <string>Q_stnM_rk.glif</string>
+ <key>QuotMrk</key>
+ <string>Q_uotM_rk.glif</string>
+ <key>ReverseSolidus</key>
+ <string>R_everseS_olidus.glif</string>
+ <key>RtCurlyBrac</key>
+ <string>R_tC_urlyB_rac.glif</string>
+ <key>RtParen</key>
+ <string>R_tP_aren.glif</string>
+ <key>RtSqrBrac</key>
+ <string>R_tS_qrB_rac.glif</string>
+ <key>Semicolon</key>
+ <string>S_emicolon.glif</string>
+ <key>Solidus</key>
+ <string>S_olidus.glif</string>
+ <key>Space</key>
+ <string>S_pace.glif</string>
+ <key>Tilde</key>
+ <string>T_ilde.glif</string>
+ <key>VertLine</key>
+ <string>V_ertL_ine.glif</string>
+ <key>nonmarkingreturn</key>
+ <string>nonmarkingreturn.glif</string>
+</dict>
+</plist>
diff --git a/tests/reference/ufo/psfsetunicodes.ufo/glyphs/nonmarkingreturn.glif b/tests/reference/ufo/psfsetunicodes.ufo/glyphs/nonmarkingreturn.glif
new file mode 100644
index 0000000..9a63f06
--- /dev/null
+++ b/tests/reference/ufo/psfsetunicodes.ufo/glyphs/nonmarkingreturn.glif
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glyph name="nonmarkingreturn" format="2">
+ <advance width="1004"/>
+ <outline/>
+</glyph>
diff --git a/tests/reference/ufo/psfsetunicodes.ufo/layercontents.plist b/tests/reference/ufo/psfsetunicodes.ufo/layercontents.plist
new file mode 100644
index 0000000..42b7482
--- /dev/null
+++ b/tests/reference/ufo/psfsetunicodes.ufo/layercontents.plist
@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<array>
+ <array>
+ <string>public.default</string>
+ <string>glyphs</string>
+ </array>
+</array>
+</plist>
diff --git a/tests/reference/ufo/psfsetunicodes.ufo/lib.plist b/tests/reference/ufo/psfsetunicodes.ufo/lib.plist
new file mode 100644
index 0000000..fa77038
--- /dev/null
+++ b/tests/reference/ufo/psfsetunicodes.ufo/lib.plist
@@ -0,0 +1,534 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+ <key>com.schriftgestaltung.Glyphs.fontUserData</key>
+ <dict/>
+ <key>com.schriftgestaltung.appVersion</key>
+ <string>1161</string>
+ <key>com.schriftgestaltung.customName</key>
+ <string>Italic</string>
+ <key>com.schriftgestaltung.customParameter.GSFont.DisplayStrings</key>
+ <string/>
+ <key>com.schriftgestaltung.customParameter.GSFont.disablesAutomaticAlignment</key>
+ <true/>
+ <key>com.schriftgestaltung.customParameter.GSFont.disablesLastChange</key>
+ <true/>
+ <key>com.schriftgestaltung.customParameter.GSFont.useNiceNames</key>
+ <integer>0</integer>
+ <key>com.schriftgestaltung.customParameter.GSFontMaster.customValue</key>
+ <integer>0</integer>
+ <key>com.schriftgestaltung.customParameter.GSFontMaster.customValue1</key>
+ <integer>0</integer>
+ <key>com.schriftgestaltung.customParameter.GSFontMaster.customValue2</key>
+ <integer>0</integer>
+ <key>com.schriftgestaltung.customParameter.GSFontMaster.customValue3</key>
+ <integer>0</integer>
+ <key>com.schriftgestaltung.customParameter.GSFontMaster.iconName</key>
+ <string/>
+ <key>com.schriftgestaltung.customParameter.GSFontMaster.weightValue</key>
+ <integer>400</integer>
+ <key>com.schriftgestaltung.customParameter.GSFontMaster.widthValue</key>
+ <integer>100</integer>
+ <key>com.schriftgestaltung.fontMasterOrder</key>
+ <integer>0</integer>
+ <key>com.schriftgestaltung.glyphOrder</key>
+ <array>
+ <string>.notdef</string>
+ <string>.null</string>
+ <string>nonmarkingreturn</string>
+ <string>Space</string>
+ <string>ExclamationMrk</string>
+ <string>QuotMrk</string>
+ <string>NumSgn</string>
+ <string>DollarSgn</string>
+ <string>PercentSgn</string>
+ <string>Ampersand</string>
+ <string>Apos</string>
+ <string>LftParen</string>
+ <string>RtParen</string>
+ <string>Asterisk</string>
+ <string>PlusSgn</string>
+ <string>Comma</string>
+ <string>HyphenMinus</string>
+ <string>FullStop</string>
+ <string>Solidus</string>
+ <string>DigitZero</string>
+ <string>DigitOne</string>
+ <string>DigitTwo</string>
+ <string>DigitThree</string>
+ <string>DigitFour</string>
+ <string>DigitFive</string>
+ <string>DigitSix</string>
+ <string>DigitSeven</string>
+ <string>DigitEight</string>
+ <string>DigitNine</string>
+ <string>Colon</string>
+ <string>Semicolon</string>
+ <string>LTSgn</string>
+ <string>EqSgn</string>
+ <string>GTSgn</string>
+ <string>QstnMrk</string>
+ <string>AtSgn</string>
+ <string>LtnCapA</string>
+ <string>LtnCapA.alt</string>
+ <string>LtnCapB</string>
+ <string>LtnCapC</string>
+ <string>LtnCapD</string>
+ <string>LtnCapE</string>
+ <string>LtnCapF</string>
+ <string>LtnCapG</string>
+ <string>LtnCapH</string>
+ <string>LtnCapI</string>
+ <string>LtnCapJ</string>
+ <string>LtnCapK</string>
+ <string>LtnCapL</string>
+ <string>LtnCapM</string>
+ <string>LtnCapN</string>
+ <string>LtnCapO</string>
+ <string>LtnCapP</string>
+ <string>LtnCapQ</string>
+ <string>LtnCapR</string>
+ <string>LtnCapS</string>
+ <string>LtnCapT</string>
+ <string>LtnCapU</string>
+ <string>LtnCapV</string>
+ <string>LtnCapW</string>
+ <string>LtnCapX</string>
+ <string>LtnCapY</string>
+ <string>LftSqrBrac</string>
+ <string>ReverseSolidus</string>
+ <string>RtSqrBrac</string>
+ <string>CircumAccent</string>
+ <string>LowLine</string>
+ <string>GraveAccent</string>
+ <string>LtnSmA</string>
+ <string>LtnSmB</string>
+ <string>LtnSmC</string>
+ <string>LtnSmD</string>
+ <string>LtnSmE</string>
+ <string>LtnSmF</string>
+ <string>LtnSmG</string>
+ <string>LtnSmH</string>
+ <string>LtnSmI</string>
+ <string>LtnSmJ</string>
+ <string>LtnSmK</string>
+ <string>LtnSmL</string>
+ <string>LtnSmM</string>
+ <string>LtnSmN</string>
+ <string>LtnSmO</string>
+ <string>LtnSmP</string>
+ <string>LtnSmQ</string>
+ <string>LtnSmR</string>
+ <string>LtnSmS</string>
+ <string>LtnSmT</string>
+ <string>LtnSmU</string>
+ <string>LtnSmV</string>
+ <string>LtnSmW</string>
+ <string>LtnSmX</string>
+ <string>LtnSmY</string>
+ <string>LftCurlyBrac</string>
+ <string>VertLine</string>
+ <string>RtCurlyBrac</string>
+ <string>Tilde</string>
+ <string>LtnCapADiaer</string>
+ <string>LtnSmAAcute</string>
+ <string>LtnSmAGrave</string>
+ <string>LtnSmACircum</string>
+ <string>LtnSmADiaer</string>
+ <string>LtnSmATilde</string>
+ <string>LtnSmARingAbv</string>
+ <string>DottedCirc</string>
+ <string>Hyphen</string>
+ <string>NonBreakingHyphen</string>
+ <string>Hyphen_Soft</string>
+ <string>CombAcute</string>
+ <string>CombGrave</string>
+ <string>CombCircum</string>
+ <string>CombTilde</string>
+ <string>CombDiaer</string>
+ <string>CombRingAbv</string>
+ </array>
+ <key>com.schriftgestaltung.keyboardIncrement</key>
+ <integer>1</integer>
+ <key>com.schriftgestaltung.weight</key>
+ <string>Regular</string>
+ <key>com.schriftgestaltung.weightValue</key>
+ <integer>400</integer>
+ <key>com.schriftgestaltung.width</key>
+ <string>Regular</string>
+ <key>com.schriftgestaltung.widthValue</key>
+ <integer>100</integer>
+ <key>org.sil.lcg.toneLetters</key>
+ <dict>
+ <key>contourWidth</key>
+ <integer>480</integer>
+ <key>dotSize</key>
+ <integer>180</integer>
+ <key>dotSpacing</key>
+ <integer>200</integer>
+ <key>glyphDepth</key>
+ <integer>-25</integer>
+ <key>glyphHeight</key>
+ <integer>1600</integer>
+ <key>italicAngle</key>
+ <integer>14</integer>
+ <key>marginDotLeft</key>
+ <integer>120</integer>
+ <key>marginDotRight</key>
+ <integer>160</integer>
+ <key>marginFlatLeft</key>
+ <integer>120</integer>
+ <key>marginFlatRight</key>
+ <integer>160</integer>
+ <key>marginPointLeft</key>
+ <integer>100</integer>
+ <key>marginPointRight</key>
+ <integer>140</integer>
+ <key>strokeThickness</key>
+ <integer>120</integer>
+ </dict>
+ <key>public.glyphOrder</key>
+ <array>
+ <string>.notdef</string>
+ <string>.null</string>
+ <string>nonmarkingreturn</string>
+ <string>Space</string>
+ <string>ExclamationMrk</string>
+ <string>QuotMrk</string>
+ <string>NumSgn</string>
+ <string>DollarSgn</string>
+ <string>PercentSgn</string>
+ <string>Ampersand</string>
+ <string>Apos</string>
+ <string>LftParen</string>
+ <string>RtParen</string>
+ <string>Asterisk</string>
+ <string>PlusSgn</string>
+ <string>Comma</string>
+ <string>HyphenMinus</string>
+ <string>FullStop</string>
+ <string>Solidus</string>
+ <string>DigitZero</string>
+ <string>DigitOne</string>
+ <string>DigitTwo</string>
+ <string>DigitThree</string>
+ <string>DigitFour</string>
+ <string>DigitFive</string>
+ <string>DigitSix</string>
+ <string>DigitSeven</string>
+ <string>DigitEight</string>
+ <string>DigitNine</string>
+ <string>Colon</string>
+ <string>Semicolon</string>
+ <string>LTSgn</string>
+ <string>EqSgn</string>
+ <string>GTSgn</string>
+ <string>QstnMrk</string>
+ <string>AtSgn</string>
+ <string>LtnCapA</string>
+ <string>LtnCapA.alt</string>
+ <string>LtnCapB</string>
+ <string>LtnCapC</string>
+ <string>LtnCapD</string>
+ <string>LtnCapE</string>
+ <string>LtnCapF</string>
+ <string>LtnCapG</string>
+ <string>LtnCapH</string>
+ <string>LtnCapI</string>
+ <string>LtnCapJ</string>
+ <string>LtnCapK</string>
+ <string>LtnCapL</string>
+ <string>LtnCapM</string>
+ <string>LtnCapN</string>
+ <string>LtnCapO</string>
+ <string>LtnCapP</string>
+ <string>LtnCapQ</string>
+ <string>LtnCapR</string>
+ <string>LtnCapS</string>
+ <string>LtnCapT</string>
+ <string>LtnCapU</string>
+ <string>LtnCapV</string>
+ <string>LtnCapW</string>
+ <string>LtnCapX</string>
+ <string>LtnCapY</string>
+ <string>LftSqrBrac</string>
+ <string>ReverseSolidus</string>
+ <string>RtSqrBrac</string>
+ <string>CircumAccent</string>
+ <string>LowLine</string>
+ <string>GraveAccent</string>
+ <string>LtnSmA</string>
+ <string>LtnSmB</string>
+ <string>LtnSmC</string>
+ <string>LtnSmD</string>
+ <string>LtnSmE</string>
+ <string>LtnSmF</string>
+ <string>LtnSmG</string>
+ <string>LtnSmH</string>
+ <string>LtnSmI</string>
+ <string>LtnSmJ</string>
+ <string>LtnSmK</string>
+ <string>LtnSmL</string>
+ <string>LtnSmM</string>
+ <string>LtnSmN</string>
+ <string>LtnSmO</string>
+ <string>LtnSmP</string>
+ <string>LtnSmQ</string>
+ <string>LtnSmR</string>
+ <string>LtnSmS</string>
+ <string>LtnSmT</string>
+ <string>LtnSmU</string>
+ <string>LtnSmV</string>
+ <string>LtnSmW</string>
+ <string>LtnSmX</string>
+ <string>LtnSmY</string>
+ <string>LftCurlyBrac</string>
+ <string>VertLine</string>
+ <string>RtCurlyBrac</string>
+ <string>Tilde</string>
+ <string>LtnCapADiaer</string>
+ <string>LtnSmAAcute</string>
+ <string>LtnSmAGrave</string>
+ <string>LtnSmACircum</string>
+ <string>LtnSmADiaer</string>
+ <string>LtnSmATilde</string>
+ <string>LtnSmARingAbv</string>
+ <string>DottedCirc</string>
+ <string>Hyphen</string>
+ <string>NonBreakingHyphen</string>
+ <string>Hyphen_Soft</string>
+ <string>CombAcute</string>
+ <string>CombGrave</string>
+ <string>CombCircum</string>
+ <string>CombTilde</string>
+ <string>CombDiaer</string>
+ <string>CombRingAbv</string>
+ </array>
+ <key>public.postscriptNames</key>
+ <dict>
+ <key>Ampersand</key>
+ <string>ampersand</string>
+ <key>Apos</key>
+ <string>quotesingle</string>
+ <key>Asterisk</key>
+ <string>asterisk</string>
+ <key>AtSgn</key>
+ <string>at</string>
+ <key>CircumAccent</key>
+ <string>asciicircum</string>
+ <key>Colon</key>
+ <string>colon</string>
+ <key>CombAcute</key>
+ <string>acutecomb</string>
+ <key>CombCircum</key>
+ <string>uni0302</string>
+ <key>CombDiaer</key>
+ <string>uni0308</string>
+ <key>CombGrave</key>
+ <string>gravecomb</string>
+ <key>CombRingAbv</key>
+ <string>uni030A</string>
+ <key>CombTilde</key>
+ <string>tildecomb</string>
+ <key>Comma</key>
+ <string>comma</string>
+ <key>DigitEight</key>
+ <string>eight</string>
+ <key>DigitFive</key>
+ <string>five</string>
+ <key>DigitFour</key>
+ <string>four</string>
+ <key>DigitNine</key>
+ <string>nine</string>
+ <key>DigitOne</key>
+ <string>one</string>
+ <key>DigitSeven</key>
+ <string>seven</string>
+ <key>DigitSix</key>
+ <string>six</string>
+ <key>DigitThree</key>
+ <string>three</string>
+ <key>DigitTwo</key>
+ <string>two</string>
+ <key>DigitZero</key>
+ <string>zero</string>
+ <key>DollarSgn</key>
+ <string>dollar</string>
+ <key>DottedCirc</key>
+ <string>uni25CC</string>
+ <key>EqSgn</key>
+ <string>equal</string>
+ <key>ExclamationMrk</key>
+ <string>exclam</string>
+ <key>FullStop</key>
+ <string>period</string>
+ <key>GTSgn</key>
+ <string>greater</string>
+ <key>GraveAccent</key>
+ <string>grave</string>
+ <key>Hyphen</key>
+ <string>uni2010</string>
+ <key>HyphenMinus</key>
+ <string>hyphen</string>
+ <key>Hyphen_Soft</key>
+ <string>uni00AD</string>
+ <key>LTSgn</key>
+ <string>less</string>
+ <key>LftCurlyBrac</key>
+ <string>braceleft</string>
+ <key>LftParen</key>
+ <string>parenleft</string>
+ <key>LftSqrBrac</key>
+ <string>bracketleft</string>
+ <key>LowLine</key>
+ <string>underscore</string>
+ <key>LtnCapA</key>
+ <string>A</string>
+ <key>LtnCapA.alt</key>
+ <string>A</string>
+ <key>LtnCapADiaer</key>
+ <string>Adieresis</string>
+ <key>LtnCapB</key>
+ <string>B</string>
+ <key>LtnCapC</key>
+ <string>C</string>
+ <key>LtnCapD</key>
+ <string>D</string>
+ <key>LtnCapE</key>
+ <string>E</string>
+ <key>LtnCapF</key>
+ <string>F</string>
+ <key>LtnCapG</key>
+ <string>G</string>
+ <key>LtnCapH</key>
+ <string>H</string>
+ <key>LtnCapI</key>
+ <string>I</string>
+ <key>LtnCapJ</key>
+ <string>J</string>
+ <key>LtnCapK</key>
+ <string>K</string>
+ <key>LtnCapL</key>
+ <string>L</string>
+ <key>LtnCapM</key>
+ <string>M</string>
+ <key>LtnCapN</key>
+ <string>N</string>
+ <key>LtnCapO</key>
+ <string>O</string>
+ <key>LtnCapP</key>
+ <string>P</string>
+ <key>LtnCapQ</key>
+ <string>Q</string>
+ <key>LtnCapR</key>
+ <string>R</string>
+ <key>LtnCapS</key>
+ <string>S</string>
+ <key>LtnCapT</key>
+ <string>T</string>
+ <key>LtnCapU</key>
+ <string>U</string>
+ <key>LtnCapV</key>
+ <string>V</string>
+ <key>LtnCapW</key>
+ <string>W</string>
+ <key>LtnCapX</key>
+ <string>X</string>
+ <key>LtnCapY</key>
+ <string>Y</string>
+ <key>LtnSmA</key>
+ <string>a</string>
+ <key>LtnSmAAcute</key>
+ <string>aacute</string>
+ <key>LtnSmACircum</key>
+ <string>acircumflex</string>
+ <key>LtnSmADiaer</key>
+ <string>adieresis</string>
+ <key>LtnSmAGrave</key>
+ <string>agrave</string>
+ <key>LtnSmARingAbv</key>
+ <string>aring</string>
+ <key>LtnSmATilde</key>
+ <string>atilde</string>
+ <key>LtnSmB</key>
+ <string>b</string>
+ <key>LtnSmC</key>
+ <string>c</string>
+ <key>LtnSmD</key>
+ <string>d</string>
+ <key>LtnSmE</key>
+ <string>e</string>
+ <key>LtnSmF</key>
+ <string>f</string>
+ <key>LtnSmG</key>
+ <string>g</string>
+ <key>LtnSmH</key>
+ <string>h</string>
+ <key>LtnSmI</key>
+ <string>i</string>
+ <key>LtnSmJ</key>
+ <string>j</string>
+ <key>LtnSmK</key>
+ <string>k</string>
+ <key>LtnSmL</key>
+ <string>l</string>
+ <key>LtnSmM</key>
+ <string>m</string>
+ <key>LtnSmN</key>
+ <string>n</string>
+ <key>LtnSmO</key>
+ <string>o</string>
+ <key>LtnSmP</key>
+ <string>p</string>
+ <key>LtnSmQ</key>
+ <string>q</string>
+ <key>LtnSmR</key>
+ <string>r</string>
+ <key>LtnSmS</key>
+ <string>s</string>
+ <key>LtnSmT</key>
+ <string>t</string>
+ <key>LtnSmU</key>
+ <string>u</string>
+ <key>LtnSmV</key>
+ <string>v</string>
+ <key>LtnSmW</key>
+ <string>w</string>
+ <key>LtnSmX</key>
+ <string>x</string>
+ <key>LtnSmY</key>
+ <string>y</string>
+ <key>NonBreakingHyphen</key>
+ <string>uni2011</string>
+ <key>NumSgn</key>
+ <string>numbersign</string>
+ <key>PercentSgn</key>
+ <string>percent</string>
+ <key>PlusSgn</key>
+ <string>plus</string>
+ <key>QstnMrk</key>
+ <string>question</string>
+ <key>QuotMrk</key>
+ <string>quotedbl</string>
+ <key>ReverseSolidus</key>
+ <string>backslash</string>
+ <key>RtCurlyBrac</key>
+ <string>braceright</string>
+ <key>RtParen</key>
+ <string>parenright</string>
+ <key>RtSqrBrac</key>
+ <string>bracketright</string>
+ <key>Semicolon</key>
+ <string>semicolon</string>
+ <key>Solidus</key>
+ <string>slash</string>
+ <key>Space</key>
+ <string>space</string>
+ <key>Tilde</key>
+ <string>asciitilde</string>
+ <key>VertLine</key>
+ <string>bar</string>
+ </dict>
+</dict>
+</plist>
diff --git a/tests/reference/ufo/psfsetunicodes.ufo/metainfo.plist b/tests/reference/ufo/psfsetunicodes.ufo/metainfo.plist
new file mode 100644
index 0000000..aa10c5c
--- /dev/null
+++ b/tests/reference/ufo/psfsetunicodes.ufo/metainfo.plist
@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+ <key>creator</key>
+ <string>org.sil.scripts.pysilfont</string>
+ <key>formatVersion</key>
+ <integer>3</integer>
+</dict>
+</plist>
diff --git a/tests/reference/ufo/psfsyncmasters-Bold-fontinfo.plist b/tests/reference/ufo/psfsyncmasters-Bold-fontinfo.plist
new file mode 100644
index 0000000..4e412bf
--- /dev/null
+++ b/tests/reference/ufo/psfsyncmasters-Bold-fontinfo.plist
@@ -0,0 +1,245 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+ <key>ascender</key>
+ <integer>2100</integer>
+ <key>capHeight</key>
+ <integer>1485</integer>
+ <key>copyright</key>
+ <string>Copyright (c) 2004-2021 SIL International</string>
+ <key>descender</key>
+ <integer>-550</integer>
+ <key>familyName</key>
+ <string>Psf Test</string>
+ <key>note</key>
+ <string>Test note
+Second line
+
+Third line
+</string>
+ <key>openTypeHeadCreated</key>
+ <string>2021/01/29 11:19:45</string>
+ <key>openTypeHheaAscender</key>
+ <integer>2100</integer>
+ <key>openTypeHheaDescender</key>
+ <integer>-550</integer>
+ <key>openTypeHheaLineGap</key>
+ <integer>0</integer>
+ <key>openTypeNameDescription</key>
+ <string>Copyright (c) 2004-2021 SIL International</string>
+ <key>openTypeNameDesigner</key>
+ <string>Victor Gaultney, Annie Olsen, Julie Remington, Don Collingsworth, Eric Hays, Becca Hirsbrunner</string>
+ <key>openTypeNameDesignerURL</key>
+ <string>http://scripts.sil.org/</string>
+ <key>openTypeNameLicense</key>
+ <string>Copyright (c) 2004-2021 SIL International (http://www.sil.org/) with Reserved Font Names "Andika" and "SIL".
+
+This Font Software is licensed under the SIL Open Font License, Version 1.1. This license is copied below, and is also available with a FAQ at: http://scripts.sil.org/OFL
+
+
+-----------------------------------------------------------
+SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007
+-----------------------------------------------------------
+
+PREAMBLE
+The goals of the Open Font License (OFL) are to stimulate worldwide development of collaborative font projects, to support the font creation efforts of academic and linguistic communities, and to provide a free and open framework in which fonts may be shared and improved in partnership with others.
+
+The OFL allows the licensed fonts to be used, studied, modified and redistributed freely as long as they are not sold by themselves. The fonts, including any derivative works, can be bundled, embedded, redistributed and/or sold with any software provided that any reserved names are not used by derivative works. The fonts and derivatives, however, cannot be released under any other type of license. The requirement for fonts to remain under this license does not apply to any document created using the fonts or their derivatives.
+
+DEFINITIONS
+"Font Software" refers to the set of files released by the Copyright Holder(s) under this license and clearly marked as such. This may include source files, build scripts and documentation.
+
+"Reserved Font Name" refers to any names specified as such after the copyright statement(s).
+
+"Original Version" refers to the collection of Font Software components as distributed by the Copyright Holder(s).
+
+"Modified Version" refers to any derivative made by adding to, deleting, or substituting -- in part or in whole -- any of the components of the Original Version, by changing formats or by porting the Font Software to a new environment.
+
+"Author" refers to any designer, engineer, programmer, technical writer or other person who contributed to the Font Software.
+
+PERMISSION &amp; CONDITIONS
+Permission is hereby granted, free of charge, to any person obtaining a copy of the Font Software, to use, study, copy, merge, embed, modify, redistribute, and sell modified and unmodified copies of the Font Software, subject to the following conditions:
+
+1) Neither the Font Software nor any of its individual components, in Original or Modified Versions, may be sold by itself.
+
+2) Original or Modified Versions of the Font Software may be bundled, redistributed and/or sold with any software, provided that each copy contains the above copyright notice and this license. These can be included either as stand-alone text files, human-readable headers or in the appropriate machine-readable metadata fields within text or binary files as long as those fields can be easily viewed by the user.
+
+3) No Modified Version of the Font Software may use the Reserved Font Name(s) unless explicit written permission is granted by the corresponding Copyright Holder. This restriction only applies to the primary font name as presented to the users.
+
+4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font Software shall not be used to promote, endorse or advertise any Modified Version, except to acknowledge the contribution(s) of the Copyright Holder(s) and the Author(s) or with their explicit written permission.
+
+5) The Font Software, modified or unmodified, in part or in whole, must be distributed entirely under this license, and must not be distributed under any other license. The requirement for fonts to remain under this license does not apply to any document created using the Font Software.
+
+TERMINATION
+This license becomes null and void if any of the above conditions are not met.
+
+DISCLAIMER
+THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM OTHER DEALINGS IN THE FONT SOFTWARE.</string>
+ <key>openTypeNameLicenseURL</key>
+ <string>http://scripts.sil.org/OFL</string>
+ <key>openTypeNameManufacturer</key>
+ <string>SIL International</string>
+ <key>openTypeNameManufacturerURL</key>
+ <string>http://scripts.sil.org</string>
+ <key>openTypeNamePreferredFamilyName</key>
+ <string>Psf Test</string>
+ <key>openTypeNamePreferredSubfamilyName</key>
+ <string>Bold</string>
+ <key>openTypeNameUniqueID</key>
+ <string>SIL International: Psf Test Bold: 2022</string>
+ <key>openTypeNameVersion</key>
+ <string>Version 5.550</string>
+ <key>openTypeOS2CodePageRanges</key>
+ <array>
+ <integer>0</integer>
+ <integer>1</integer>
+ <integer>2</integer>
+ <integer>4</integer>
+ <integer>7</integer>
+ <integer>8</integer>
+ </array>
+ <key>openTypeOS2FamilyClass</key>
+ <array>
+ <integer>0</integer>
+ <integer>0</integer>
+ </array>
+ <key>openTypeOS2Panose</key>
+ <array>
+ <integer>2</integer>
+ <integer>0</integer>
+ <integer>0</integer>
+ <integer>0</integer>
+ <integer>0</integer>
+ <integer>0</integer>
+ <integer>0</integer>
+ <integer>0</integer>
+ <integer>0</integer>
+ <integer>0</integer>
+ </array>
+ <key>openTypeOS2StrikeoutPosition</key>
+ <integer>700</integer>
+ <key>openTypeOS2StrikeoutSize</key>
+ <integer>100</integer>
+ <key>openTypeOS2SubscriptXOffset</key>
+ <integer>0</integer>
+ <key>openTypeOS2SubscriptXSize</key>
+ <integer>1433</integer>
+ <key>openTypeOS2SubscriptYOffset</key>
+ <integer>286</integer>
+ <key>openTypeOS2SubscriptYSize</key>
+ <integer>1331</integer>
+ <key>openTypeOS2SuperscriptXOffset</key>
+ <integer>0</integer>
+ <key>openTypeOS2SuperscriptXSize</key>
+ <integer>1433</integer>
+ <key>openTypeOS2SuperscriptYOffset</key>
+ <integer>976</integer>
+ <key>openTypeOS2SuperscriptYSize</key>
+ <integer>1331</integer>
+ <key>openTypeOS2Type</key>
+ <array/>
+ <key>openTypeOS2TypoAscender</key>
+ <integer>2100</integer>
+ <key>openTypeOS2TypoDescender</key>
+ <integer>-550</integer>
+ <key>openTypeOS2TypoLineGap</key>
+ <integer>0</integer>
+ <key>openTypeOS2UnicodeRanges</key>
+ <array>
+ <integer>0</integer>
+ <integer>1</integer>
+ <integer>6</integer>
+ <integer>7</integer>
+ <integer>31</integer>
+ <integer>33</integer>
+ <integer>35</integer>
+ <integer>36</integer>
+ <integer>37</integer>
+ <integer>38</integer>
+ <integer>39</integer>
+ <integer>40</integer>
+ <integer>45</integer>
+ <integer>46</integer>
+ <integer>47</integer>
+ <integer>57</integer>
+ <integer>60</integer>
+ <integer>62</integer>
+ <integer>64</integer>
+ <integer>67</integer>
+ <integer>69</integer>
+ <integer>89</integer>
+ </array>
+ <key>openTypeOS2VendorID</key>
+ <string>SIL</string>
+ <key>openTypeOS2WeightClass</key>
+ <integer>700</integer>
+ <key>openTypeOS2WidthClass</key>
+ <integer>5</integer>
+ <key>openTypeOS2WinAscent</key>
+ <integer>2100</integer>
+ <key>openTypeOS2WinDescent</key>
+ <integer>550</integer>
+ <key>postscriptBlueValues</key>
+ <array>
+ <integer>-490</integer>
+ <integer>-490</integer>
+ <integer>-25</integer>
+ <integer>0</integer>
+ <integer>1020</integer>
+ <integer>1040</integer>
+ <integer>1455</integer>
+ <integer>1485</integer>
+ <integer>1600</integer>
+ <integer>1620</integer>
+ </array>
+ <key>postscriptFontName</key>
+ <string>PsfTest-Bold</string>
+ <key>postscriptFullName</key>
+ <string>Psf Test Bold</string>
+ <key>postscriptStemSnapH</key>
+ <array>
+ <integer>140</integer>
+ <integer>145</integer>
+ <integer>150</integer>
+ <integer>155</integer>
+ <integer>160</integer>
+ <integer>165</integer>
+ <integer>170</integer>
+ <integer>175</integer>
+ <integer>185</integer>
+ <integer>270</integer>
+ </array>
+ <key>postscriptStemSnapV</key>
+ <array>
+ <integer>165</integer>
+ <integer>180</integer>
+ <integer>185</integer>
+ <integer>190</integer>
+ <integer>195</integer>
+ <integer>200</integer>
+ <integer>205</integer>
+ <integer>270</integer>
+ </array>
+ <key>postscriptUnderlinePosition</key>
+ <integer>-110</integer>
+ <key>postscriptUnderlineThickness</key>
+ <integer>80</integer>
+ <key>styleMapFamilyName</key>
+ <string>Psf Test</string>
+ <key>styleMapStyleName</key>
+ <string>bold</string>
+ <key>styleName</key>
+ <string>Bold</string>
+ <key>trademark</key>
+ <string>Andika is a trademark of SIL International.</string>
+ <key>unitsPerEm</key>
+ <integer>2048</integer>
+ <key>versionMajor</key>
+ <integer>5</integer>
+ <key>versionMinor</key>
+ <integer>550</integer>
+ <key>xHeight</key>
+ <integer>1040</integer>
+</dict>
+</plist>
diff --git a/tests/reference/ufo/psfsyncmasters-Bold-lib.plist b/tests/reference/ufo/psfsyncmasters-Bold-lib.plist
new file mode 100644
index 0000000..03492dd
--- /dev/null
+++ b/tests/reference/ufo/psfsyncmasters-Bold-lib.plist
@@ -0,0 +1,536 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+ <key>com.schriftgestaltung.Glyphs.fontUserData</key>
+ <dict/>
+ <key>com.schriftgestaltung.appVersion</key>
+ <string>1161</string>
+ <key>com.schriftgestaltung.customParameter.GSFont.DisplayStrings</key>
+ <string/>
+ <key>com.schriftgestaltung.customParameter.GSFont.disablesAutomaticAlignment</key>
+ <true/>
+ <key>com.schriftgestaltung.customParameter.GSFont.disablesLastChange</key>
+ <true/>
+ <key>com.schriftgestaltung.customParameter.GSFont.useNiceNames</key>
+ <integer>0</integer>
+ <key>com.schriftgestaltung.customParameter.GSFontMaster.customValue</key>
+ <integer>0</integer>
+ <key>com.schriftgestaltung.customParameter.GSFontMaster.customValue1</key>
+ <integer>0</integer>
+ <key>com.schriftgestaltung.customParameter.GSFontMaster.customValue2</key>
+ <integer>0</integer>
+ <key>com.schriftgestaltung.customParameter.GSFontMaster.customValue3</key>
+ <integer>0</integer>
+ <key>com.schriftgestaltung.customParameter.GSFontMaster.iconName</key>
+ <string/>
+ <key>com.schriftgestaltung.customParameter.GSFontMaster.weightValue</key>
+ <integer>700</integer>
+ <key>com.schriftgestaltung.customParameter.GSFontMaster.widthValue</key>
+ <integer>100</integer>
+ <key>com.schriftgestaltung.disablesAutomaticAlignment</key>
+ <true/>
+ <key>com.schriftgestaltung.disablesLastChange</key>
+ <true/>
+ <key>com.schriftgestaltung.fontMasterOrder</key>
+ <integer>1</integer>
+ <key>com.schriftgestaltung.glyphOrder</key>
+ <array>
+ <string>.notdef</string>
+ <string>.null</string>
+ <string>nonmarkingreturn</string>
+ <string>Space</string>
+ <string>ExclamationMrk</string>
+ <string>QuotMrk</string>
+ <string>NumSgn</string>
+ <string>DollarSgn</string>
+ <string>PercentSgn</string>
+ <string>Ampersand</string>
+ <string>Apos</string>
+ <string>LftParen</string>
+ <string>RtParen</string>
+ <string>Asterisk</string>
+ <string>PlusSgn</string>
+ <string>Comma</string>
+ <string>HyphenMinus</string>
+ <string>FullStop</string>
+ <string>Solidus</string>
+ <string>DigitZero</string>
+ <string>DigitOne</string>
+ <string>DigitTwo</string>
+ <string>DigitThree</string>
+ <string>DigitFour</string>
+ <string>DigitFive</string>
+ <string>DigitSix</string>
+ <string>DigitSeven</string>
+ <string>DigitEight</string>
+ <string>DigitNine</string>
+ <string>Colon</string>
+ <string>Semicolon</string>
+ <string>LTSgn</string>
+ <string>EqSgn</string>
+ <string>GTSgn</string>
+ <string>QstnMrk</string>
+ <string>AtSgn</string>
+ <string>LtnCapA</string>
+ <string>LtnCapA.alt</string>
+ <string>LtnCapB</string>
+ <string>LtnCapC</string>
+ <string>LtnCapD</string>
+ <string>LtnCapE</string>
+ <string>LtnCapF</string>
+ <string>LtnCapG</string>
+ <string>LtnCapH</string>
+ <string>LtnCapI</string>
+ <string>LtnCapJ</string>
+ <string>LtnCapK</string>
+ <string>LtnCapL</string>
+ <string>LtnCapM</string>
+ <string>LtnCapN</string>
+ <string>LtnCapO</string>
+ <string>LtnCapP</string>
+ <string>LtnCapQ</string>
+ <string>LtnCapR</string>
+ <string>LtnCapS</string>
+ <string>LtnCapT</string>
+ <string>LtnCapU</string>
+ <string>LtnCapV</string>
+ <string>LtnCapW</string>
+ <string>LtnCapX</string>
+ <string>LtnCapY</string>
+ <string>LftSqrBrac</string>
+ <string>ReverseSolidus</string>
+ <string>RtSqrBrac</string>
+ <string>CircumAccent</string>
+ <string>LowLine</string>
+ <string>GraveAccent</string>
+ <string>LtnSmA</string>
+ <string>LtnSmB</string>
+ <string>LtnSmC</string>
+ <string>LtnSmD</string>
+ <string>LtnSmE</string>
+ <string>LtnSmF</string>
+ <string>LtnSmG</string>
+ <string>LtnSmH</string>
+ <string>LtnSmI</string>
+ <string>LtnSmJ</string>
+ <string>LtnSmK</string>
+ <string>LtnSmL</string>
+ <string>LtnSmM</string>
+ <string>LtnSmN</string>
+ <string>LtnSmO</string>
+ <string>LtnSmP</string>
+ <string>LtnSmQ</string>
+ <string>LtnSmR</string>
+ <string>LtnSmS</string>
+ <string>LtnSmT</string>
+ <string>LtnSmU</string>
+ <string>LtnSmV</string>
+ <string>LtnSmW</string>
+ <string>LtnSmX</string>
+ <string>LtnSmY</string>
+ <string>LftCurlyBrac</string>
+ <string>VertLine</string>
+ <string>RtCurlyBrac</string>
+ <string>Tilde</string>
+ <string>LtnCapADiaer</string>
+ <string>LtnSmAAcute</string>
+ <string>LtnSmAGrave</string>
+ <string>LtnSmACircum</string>
+ <string>LtnSmADiaer</string>
+ <string>LtnSmATilde</string>
+ <string>LtnSmARingAbv</string>
+ <string>DottedCirc</string>
+ <string>Hyphen</string>
+ <string>NonBreakingHyphen</string>
+ <string>Hyphen_Soft</string>
+ <string>CombAcute</string>
+ <string>CombGrave</string>
+ <string>CombCircum</string>
+ <string>CombTilde</string>
+ <string>CombDiaer</string>
+ <string>CombRingAbv</string>
+ </array>
+ <key>com.schriftgestaltung.keyboardIncrement</key>
+ <integer>1</integer>
+ <key>com.schriftgestaltung.weight</key>
+ <string>Bold</string>
+ <key>com.schriftgestaltung.weightValue</key>
+ <integer>700</integer>
+ <key>com.schriftgestaltung.width</key>
+ <string>Regular</string>
+ <key>com.schriftgestaltung.widthValue</key>
+ <integer>100</integer>
+ <key>org.sil.lcg.toneLetters</key>
+ <dict>
+ <key>contourWidth</key>
+ <integer>540</integer>
+ <key>dotSize</key>
+ <integer>280</integer>
+ <key>dotSpacing</key>
+ <integer>200</integer>
+ <key>glyphDepth</key>
+ <integer>-25</integer>
+ <key>glyphHeight</key>
+ <integer>1600</integer>
+ <key>italicAngle</key>
+ <integer>0</integer>
+ <key>marginDotLeft</key>
+ <integer>100</integer>
+ <key>marginDotRight</key>
+ <integer>140</integer>
+ <key>marginFlatLeft</key>
+ <integer>100</integer>
+ <key>marginFlatRight</key>
+ <integer>140</integer>
+ <key>marginPointLeft</key>
+ <integer>80</integer>
+ <key>marginPointRight</key>
+ <integer>120</integer>
+ <key>strokeThickness</key>
+ <integer>200</integer>
+ </dict>
+ <key>public.glyphOrder</key>
+ <array>
+ <string>.notdef</string>
+ <string>.null</string>
+ <string>nonmarkingreturn</string>
+ <string>Space</string>
+ <string>ExclamationMrk</string>
+ <string>QuotMrk</string>
+ <string>NumSgn</string>
+ <string>DollarSgn</string>
+ <string>PercentSgn</string>
+ <string>Ampersand</string>
+ <string>Apos</string>
+ <string>LftParen</string>
+ <string>RtParen</string>
+ <string>Asterisk</string>
+ <string>PlusSgn</string>
+ <string>Comma</string>
+ <string>HyphenMinus</string>
+ <string>FullStop</string>
+ <string>Solidus</string>
+ <string>DigitZero</string>
+ <string>DigitOne</string>
+ <string>DigitTwo</string>
+ <string>DigitThree</string>
+ <string>DigitFour</string>
+ <string>DigitFive</string>
+ <string>DigitSix</string>
+ <string>DigitSeven</string>
+ <string>DigitEight</string>
+ <string>DigitNine</string>
+ <string>Colon</string>
+ <string>Semicolon</string>
+ <string>LTSgn</string>
+ <string>EqSgn</string>
+ <string>GTSgn</string>
+ <string>QstnMrk</string>
+ <string>AtSgn</string>
+ <string>LtnCapA</string>
+ <string>LtnCapA.alt</string>
+ <string>LtnCapB</string>
+ <string>LtnCapC</string>
+ <string>LtnCapD</string>
+ <string>LtnCapE</string>
+ <string>LtnCapF</string>
+ <string>LtnCapG</string>
+ <string>LtnCapH</string>
+ <string>LtnCapI</string>
+ <string>LtnCapJ</string>
+ <string>LtnCapK</string>
+ <string>LtnCapL</string>
+ <string>LtnCapM</string>
+ <string>LtnCapN</string>
+ <string>LtnCapO</string>
+ <string>LtnCapP</string>
+ <string>LtnCapQ</string>
+ <string>LtnCapR</string>
+ <string>LtnCapS</string>
+ <string>LtnCapT</string>
+ <string>LtnCapU</string>
+ <string>LtnCapV</string>
+ <string>LtnCapW</string>
+ <string>LtnCapX</string>
+ <string>LtnCapY</string>
+ <string>LftSqrBrac</string>
+ <string>ReverseSolidus</string>
+ <string>RtSqrBrac</string>
+ <string>CircumAccent</string>
+ <string>LowLine</string>
+ <string>GraveAccent</string>
+ <string>LtnSmA</string>
+ <string>LtnSmB</string>
+ <string>LtnSmC</string>
+ <string>LtnSmD</string>
+ <string>LtnSmE</string>
+ <string>LtnSmF</string>
+ <string>LtnSmG</string>
+ <string>LtnSmH</string>
+ <string>LtnSmI</string>
+ <string>LtnSmJ</string>
+ <string>LtnSmK</string>
+ <string>LtnSmL</string>
+ <string>LtnSmM</string>
+ <string>LtnSmN</string>
+ <string>LtnSmO</string>
+ <string>LtnSmP</string>
+ <string>LtnSmQ</string>
+ <string>LtnSmR</string>
+ <string>LtnSmS</string>
+ <string>LtnSmT</string>
+ <string>LtnSmU</string>
+ <string>LtnSmV</string>
+ <string>LtnSmW</string>
+ <string>LtnSmX</string>
+ <string>LtnSmY</string>
+ <string>LftCurlyBrac</string>
+ <string>VertLine</string>
+ <string>RtCurlyBrac</string>
+ <string>Tilde</string>
+ <string>LtnCapADiaer</string>
+ <string>LtnSmAAcute</string>
+ <string>LtnSmAGrave</string>
+ <string>LtnSmACircum</string>
+ <string>LtnSmADiaer</string>
+ <string>LtnSmATilde</string>
+ <string>LtnSmARingAbv</string>
+ <string>DottedCirc</string>
+ <string>Hyphen</string>
+ <string>NonBreakingHyphen</string>
+ <string>Hyphen_Soft</string>
+ <string>CombAcute</string>
+ <string>CombGrave</string>
+ <string>CombCircum</string>
+ <string>CombTilde</string>
+ <string>CombDiaer</string>
+ <string>CombRingAbv</string>
+ </array>
+ <key>public.postscriptNames</key>
+ <dict>
+ <key>Ampersand</key>
+ <string>ampersand</string>
+ <key>Apos</key>
+ <string>quotesingle</string>
+ <key>Asterisk</key>
+ <string>asterisk</string>
+ <key>AtSgn</key>
+ <string>at</string>
+ <key>CircumAccent</key>
+ <string>asciicircum</string>
+ <key>Colon</key>
+ <string>colon</string>
+ <key>CombAcute</key>
+ <string>acutecomb</string>
+ <key>CombCircum</key>
+ <string>uni0302</string>
+ <key>CombDiaer</key>
+ <string>uni0308</string>
+ <key>CombGrave</key>
+ <string>gravecomb</string>
+ <key>CombRingAbv</key>
+ <string>uni030A</string>
+ <key>CombTilde</key>
+ <string>tildecomb</string>
+ <key>Comma</key>
+ <string>comma</string>
+ <key>DigitEight</key>
+ <string>eight</string>
+ <key>DigitFive</key>
+ <string>five</string>
+ <key>DigitFour</key>
+ <string>four</string>
+ <key>DigitNine</key>
+ <string>nine</string>
+ <key>DigitOne</key>
+ <string>one</string>
+ <key>DigitSeven</key>
+ <string>seven</string>
+ <key>DigitSix</key>
+ <string>six</string>
+ <key>DigitThree</key>
+ <string>three</string>
+ <key>DigitTwo</key>
+ <string>two</string>
+ <key>DigitZero</key>
+ <string>zero</string>
+ <key>DollarSgn</key>
+ <string>dollar</string>
+ <key>DottedCirc</key>
+ <string>uni25CC</string>
+ <key>EqSgn</key>
+ <string>equal</string>
+ <key>ExclamationMrk</key>
+ <string>exclam</string>
+ <key>FullStop</key>
+ <string>period</string>
+ <key>GTSgn</key>
+ <string>greater</string>
+ <key>GraveAccent</key>
+ <string>grave</string>
+ <key>Hyphen</key>
+ <string>uni2010</string>
+ <key>HyphenMinus</key>
+ <string>hyphen</string>
+ <key>Hyphen_Soft</key>
+ <string>uni00AD</string>
+ <key>LTSgn</key>
+ <string>less</string>
+ <key>LftCurlyBrac</key>
+ <string>braceleft</string>
+ <key>LftParen</key>
+ <string>parenleft</string>
+ <key>LftSqrBrac</key>
+ <string>bracketleft</string>
+ <key>LowLine</key>
+ <string>underscore</string>
+ <key>LtnCapA</key>
+ <string>A</string>
+ <key>LtnCapA.alt</key>
+ <string>A</string>
+ <key>LtnCapADiaer</key>
+ <string>Adieresis</string>
+ <key>LtnCapB</key>
+ <string>B</string>
+ <key>LtnCapC</key>
+ <string>C</string>
+ <key>LtnCapD</key>
+ <string>D</string>
+ <key>LtnCapE</key>
+ <string>E</string>
+ <key>LtnCapF</key>
+ <string>F</string>
+ <key>LtnCapG</key>
+ <string>G</string>
+ <key>LtnCapH</key>
+ <string>H</string>
+ <key>LtnCapI</key>
+ <string>I</string>
+ <key>LtnCapJ</key>
+ <string>J</string>
+ <key>LtnCapK</key>
+ <string>K</string>
+ <key>LtnCapL</key>
+ <string>L</string>
+ <key>LtnCapM</key>
+ <string>M</string>
+ <key>LtnCapN</key>
+ <string>N</string>
+ <key>LtnCapO</key>
+ <string>O</string>
+ <key>LtnCapP</key>
+ <string>P</string>
+ <key>LtnCapQ</key>
+ <string>Q</string>
+ <key>LtnCapR</key>
+ <string>R</string>
+ <key>LtnCapS</key>
+ <string>S</string>
+ <key>LtnCapT</key>
+ <string>T</string>
+ <key>LtnCapU</key>
+ <string>U</string>
+ <key>LtnCapV</key>
+ <string>V</string>
+ <key>LtnCapW</key>
+ <string>W</string>
+ <key>LtnCapX</key>
+ <string>X</string>
+ <key>LtnCapY</key>
+ <string>Y</string>
+ <key>LtnSmA</key>
+ <string>a</string>
+ <key>LtnSmAAcute</key>
+ <string>aacute</string>
+ <key>LtnSmACircum</key>
+ <string>acircumflex</string>
+ <key>LtnSmADiaer</key>
+ <string>adieresis</string>
+ <key>LtnSmAGrave</key>
+ <string>agrave</string>
+ <key>LtnSmARingAbv</key>
+ <string>aring</string>
+ <key>LtnSmATilde</key>
+ <string>atilde</string>
+ <key>LtnSmB</key>
+ <string>b</string>
+ <key>LtnSmC</key>
+ <string>c</string>
+ <key>LtnSmD</key>
+ <string>d</string>
+ <key>LtnSmE</key>
+ <string>e</string>
+ <key>LtnSmF</key>
+ <string>f</string>
+ <key>LtnSmG</key>
+ <string>g</string>
+ <key>LtnSmH</key>
+ <string>h</string>
+ <key>LtnSmI</key>
+ <string>i</string>
+ <key>LtnSmJ</key>
+ <string>j</string>
+ <key>LtnSmK</key>
+ <string>k</string>
+ <key>LtnSmL</key>
+ <string>l</string>
+ <key>LtnSmM</key>
+ <string>m</string>
+ <key>LtnSmN</key>
+ <string>n</string>
+ <key>LtnSmO</key>
+ <string>o</string>
+ <key>LtnSmP</key>
+ <string>p</string>
+ <key>LtnSmQ</key>
+ <string>q</string>
+ <key>LtnSmR</key>
+ <string>r</string>
+ <key>LtnSmS</key>
+ <string>s</string>
+ <key>LtnSmT</key>
+ <string>t</string>
+ <key>LtnSmU</key>
+ <string>u</string>
+ <key>LtnSmV</key>
+ <string>v</string>
+ <key>LtnSmW</key>
+ <string>w</string>
+ <key>LtnSmX</key>
+ <string>x</string>
+ <key>LtnSmY</key>
+ <string>y</string>
+ <key>NonBreakingHyphen</key>
+ <string>uni2011</string>
+ <key>NumSgn</key>
+ <string>numbersign</string>
+ <key>PercentSgn</key>
+ <string>percent</string>
+ <key>PlusSgn</key>
+ <string>plus</string>
+ <key>QstnMrk</key>
+ <string>question</string>
+ <key>QuotMrk</key>
+ <string>quotedbl</string>
+ <key>ReverseSolidus</key>
+ <string>backslash</string>
+ <key>RtCurlyBrac</key>
+ <string>braceright</string>
+ <key>RtParen</key>
+ <string>parenright</string>
+ <key>RtSqrBrac</key>
+ <string>bracketright</string>
+ <key>Semicolon</key>
+ <string>semicolon</string>
+ <key>Solidus</key>
+ <string>slash</string>
+ <key>Space</key>
+ <string>space</string>
+ <key>Tilde</key>
+ <string>asciitilde</string>
+ <key>VertLine</key>
+ <string>bar</string>
+ </dict>
+</dict>
+</plist>
diff --git a/tests/reference/ufo/psfsyncmasters-BoldItalic-fontinfo.plist b/tests/reference/ufo/psfsyncmasters-BoldItalic-fontinfo.plist
new file mode 100644
index 0000000..ae16540
--- /dev/null
+++ b/tests/reference/ufo/psfsyncmasters-BoldItalic-fontinfo.plist
@@ -0,0 +1,243 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+ <key>ascender</key>
+ <integer>2100</integer>
+ <key>capHeight</key>
+ <integer>1485</integer>
+ <key>copyright</key>
+ <string>Copyright (c) 2004-2021 SIL International</string>
+ <key>descender</key>
+ <integer>-550</integer>
+ <key>familyName</key>
+ <string>Psf Test</string>
+ <key>italicAngle</key>
+ <integer>-14</integer>
+ <key>macintoshFONDName</key>
+ <string>My Test</string>
+ <key>openTypeHeadCreated</key>
+ <string>2021/01/29 11:19:45</string>
+ <key>openTypeHheaAscender</key>
+ <integer>2100</integer>
+ <key>openTypeHheaDescender</key>
+ <integer>-550</integer>
+ <key>openTypeHheaLineGap</key>
+ <integer>0</integer>
+ <key>openTypeNameDescription</key>
+ <string>Copyright (c) 2004-2021 SIL International</string>
+ <key>openTypeNameDesigner</key>
+ <string>Victor Gaultney, Annie Olsen, Julie Remington, Don Collingsworth, Eric Hays, Becca Hirsbrunner</string>
+ <key>openTypeNameDesignerURL</key>
+ <string>http://scripts.sil.org/</string>
+ <key>openTypeNameLicense</key>
+ <string>Copyright (c) 2004-2021 SIL International (http://www.sil.org/) with Reserved Font Names "Andika" and "SIL".
+
+This Font Software is licensed under the SIL Open Font License, Version 1.1. This license is copied below, and is also available with a FAQ at: http://scripts.sil.org/OFL
+
+
+-----------------------------------------------------------
+SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007
+-----------------------------------------------------------
+
+PREAMBLE
+The goals of the Open Font License (OFL) are to stimulate worldwide development of collaborative font projects, to support the font creation efforts of academic and linguistic communities, and to provide a free and open framework in which fonts may be shared and improved in partnership with others.
+
+The OFL allows the licensed fonts to be used, studied, modified and redistributed freely as long as they are not sold by themselves. The fonts, including any derivative works, can be bundled, embedded, redistributed and/or sold with any software provided that any reserved names are not used by derivative works. The fonts and derivatives, however, cannot be released under any other type of license. The requirement for fonts to remain under this license does not apply to any document created using the fonts or their derivatives.
+
+DEFINITIONS
+"Font Software" refers to the set of files released by the Copyright Holder(s) under this license and clearly marked as such. This may include source files, build scripts and documentation.
+
+"Reserved Font Name" refers to any names specified as such after the copyright statement(s).
+
+"Original Version" refers to the collection of Font Software components as distributed by the Copyright Holder(s).
+
+"Modified Version" refers to any derivative made by adding to, deleting, or substituting -- in part or in whole -- any of the components of the Original Version, by changing formats or by porting the Font Software to a new environment.
+
+"Author" refers to any designer, engineer, programmer, technical writer or other person who contributed to the Font Software.
+
+PERMISSION &amp; CONDITIONS
+Permission is hereby granted, free of charge, to any person obtaining a copy of the Font Software, to use, study, copy, merge, embed, modify, redistribute, and sell modified and unmodified copies of the Font Software, subject to the following conditions:
+
+1) Neither the Font Software nor any of its individual components, in Original or Modified Versions, may be sold by itself.
+
+2) Original or Modified Versions of the Font Software may be bundled, redistributed and/or sold with any software, provided that each copy contains the above copyright notice and this license. These can be included either as stand-alone text files, human-readable headers or in the appropriate machine-readable metadata fields within text or binary files as long as those fields can be easily viewed by the user.
+
+3) No Modified Version of the Font Software may use the Reserved Font Name(s) unless explicit written permission is granted by the corresponding Copyright Holder. This restriction only applies to the primary font name as presented to the users.
+
+4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font Software shall not be used to promote, endorse or advertise any Modified Version, except to acknowledge the contribution(s) of the Copyright Holder(s) and the Author(s) or with their explicit written permission.
+
+5) The Font Software, modified or unmodified, in part or in whole, must be distributed entirely under this license, and must not be distributed under any other license. The requirement for fonts to remain under this license does not apply to any document created using the Font Software.
+
+TERMINATION
+This license becomes null and void if any of the above conditions are not met.
+
+DISCLAIMER
+THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM OTHER DEALINGS IN THE FONT SOFTWARE.</string>
+ <key>openTypeNameLicenseURL</key>
+ <string>http://scripts.sil.org/OFL</string>
+ <key>openTypeNameManufacturer</key>
+ <string>SIL International</string>
+ <key>openTypeNameManufacturerURL</key>
+ <string>http://scripts.sil.org</string>
+ <key>openTypeNamePreferredFamilyName</key>
+ <string>Psf Test</string>
+ <key>openTypeNamePreferredSubfamilyName</key>
+ <string>Bold Italic</string>
+ <key>openTypeNameUniqueID</key>
+ <string>SIL International: Psf Test Bold Italic: 2022</string>
+ <key>openTypeNameVersion</key>
+ <string>Version 5.550</string>
+ <key>openTypeOS2CodePageRanges</key>
+ <array>
+ <integer>0</integer>
+ <integer>1</integer>
+ <integer>2</integer>
+ <integer>4</integer>
+ <integer>7</integer>
+ <integer>8</integer>
+ </array>
+ <key>openTypeOS2FamilyClass</key>
+ <array>
+ <integer>0</integer>
+ <integer>0</integer>
+ </array>
+ <key>openTypeOS2Panose</key>
+ <array>
+ <integer>2</integer>
+ <integer>0</integer>
+ <integer>0</integer>
+ <integer>0</integer>
+ <integer>0</integer>
+ <integer>0</integer>
+ <integer>0</integer>
+ <integer>0</integer>
+ <integer>0</integer>
+ <integer>0</integer>
+ </array>
+ <key>openTypeOS2StrikeoutPosition</key>
+ <integer>700</integer>
+ <key>openTypeOS2StrikeoutSize</key>
+ <integer>100</integer>
+ <key>openTypeOS2SubscriptXOffset</key>
+ <integer>0</integer>
+ <key>openTypeOS2SubscriptXSize</key>
+ <integer>1433</integer>
+ <key>openTypeOS2SubscriptYOffset</key>
+ <integer>286</integer>
+ <key>openTypeOS2SubscriptYSize</key>
+ <integer>1331</integer>
+ <key>openTypeOS2SuperscriptXOffset</key>
+ <integer>0</integer>
+ <key>openTypeOS2SuperscriptXSize</key>
+ <integer>1433</integer>
+ <key>openTypeOS2SuperscriptYOffset</key>
+ <integer>976</integer>
+ <key>openTypeOS2SuperscriptYSize</key>
+ <integer>1331</integer>
+ <key>openTypeOS2Type</key>
+ <array/>
+ <key>openTypeOS2TypoAscender</key>
+ <integer>2100</integer>
+ <key>openTypeOS2TypoDescender</key>
+ <integer>-550</integer>
+ <key>openTypeOS2TypoLineGap</key>
+ <integer>0</integer>
+ <key>openTypeOS2UnicodeRanges</key>
+ <array>
+ <integer>0</integer>
+ <integer>1</integer>
+ <integer>6</integer>
+ <integer>7</integer>
+ <integer>31</integer>
+ <integer>33</integer>
+ <integer>35</integer>
+ <integer>36</integer>
+ <integer>37</integer>
+ <integer>38</integer>
+ <integer>39</integer>
+ <integer>40</integer>
+ <integer>45</integer>
+ <integer>46</integer>
+ <integer>47</integer>
+ <integer>57</integer>
+ <integer>60</integer>
+ <integer>62</integer>
+ <integer>64</integer>
+ <integer>67</integer>
+ <integer>69</integer>
+ <integer>89</integer>
+ </array>
+ <key>openTypeOS2VendorID</key>
+ <string>SIL</string>
+ <key>openTypeOS2WeightClass</key>
+ <integer>700</integer>
+ <key>openTypeOS2WidthClass</key>
+ <integer>5</integer>
+ <key>openTypeOS2WinAscent</key>
+ <integer>2100</integer>
+ <key>openTypeOS2WinDescent</key>
+ <integer>550</integer>
+ <key>postscriptBlueValues</key>
+ <array>
+ <integer>-490</integer>
+ <integer>-490</integer>
+ <integer>-25</integer>
+ <integer>0</integer>
+ <integer>1020</integer>
+ <integer>1040</integer>
+ <integer>1455</integer>
+ <integer>1485</integer>
+ <integer>1600</integer>
+ <integer>1620</integer>
+ </array>
+ <key>postscriptFontName</key>
+ <string>PsfTest-BoldItalic</string>
+ <key>postscriptFullName</key>
+ <string>Psf Test Bold Italic</string>
+ <key>postscriptStemSnapH</key>
+ <array>
+ <integer>140</integer>
+ <integer>145</integer>
+ <integer>150</integer>
+ <integer>155</integer>
+ <integer>160</integer>
+ <integer>165</integer>
+ <integer>170</integer>
+ <integer>175</integer>
+ <integer>185</integer>
+ <integer>270</integer>
+ </array>
+ <key>postscriptStemSnapV</key>
+ <array>
+ <integer>165</integer>
+ <integer>180</integer>
+ <integer>185</integer>
+ <integer>190</integer>
+ <integer>195</integer>
+ <integer>200</integer>
+ <integer>205</integer>
+ <integer>270</integer>
+ </array>
+ <key>postscriptUnderlinePosition</key>
+ <integer>-110</integer>
+ <key>postscriptUnderlineThickness</key>
+ <integer>80</integer>
+ <key>styleMapFamilyName</key>
+ <string>Psf Test</string>
+ <key>styleMapStyleName</key>
+ <string>bold italic</string>
+ <key>styleName</key>
+ <string>Bold Italic</string>
+ <key>trademark</key>
+ <string>Andika is a trademark of SIL International.</string>
+ <key>unitsPerEm</key>
+ <integer>2048</integer>
+ <key>versionMajor</key>
+ <integer>5</integer>
+ <key>versionMinor</key>
+ <integer>550</integer>
+ <key>xHeight</key>
+ <integer>1040</integer>
+</dict>
+</plist>
diff --git a/tests/reference/ufo/psfsyncmasters-Italic-fontinfo.plist b/tests/reference/ufo/psfsyncmasters-Italic-fontinfo.plist
new file mode 100644
index 0000000..93c215b
--- /dev/null
+++ b/tests/reference/ufo/psfsyncmasters-Italic-fontinfo.plist
@@ -0,0 +1,243 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+ <key>ascender</key>
+ <integer>2100</integer>
+ <key>capHeight</key>
+ <real>1485.3</real>
+ <key>copyright</key>
+ <string>Copyright (c) 2004-2021 SIL International</string>
+ <key>descender</key>
+ <integer>-550</integer>
+ <key>familyName</key>
+ <string>Psf Test</string>
+ <key>italicAngle</key>
+ <integer>-14</integer>
+ <key>openTypeHeadCreated</key>
+ <string>2021/01/29 11:19:45</string>
+ <key>openTypeHheaAscender</key>
+ <integer>2100</integer>
+ <key>openTypeHheaDescender</key>
+ <integer>-550</integer>
+ <key>openTypeHheaLineGap</key>
+ <integer>0</integer>
+ <key>openTypeNameDescription</key>
+ <string>Copyright (c) 2004-2021 SIL International</string>
+ <key>openTypeNameDesigner</key>
+ <string>Victor Gaultney, Annie Olsen, Julie Remington, Don Collingsworth, Eric Hays, Becca Hirsbrunner</string>
+ <key>openTypeNameDesignerURL</key>
+ <string>http://scripts.sil.org/</string>
+ <key>openTypeNameLicense</key>
+ <string>Copyright (c) 2004-2021 SIL International (http://www.sil.org/) with Reserved Font Names "Andika" and "SIL".
+
+This Font Software is licensed under the SIL Open Font License, Version 1.1. This license is copied below, and is also available with a FAQ at: http://scripts.sil.org/OFL
+
+
+-----------------------------------------------------------
+SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007
+-----------------------------------------------------------
+
+PREAMBLE
+The goals of the Open Font License (OFL) are to stimulate worldwide development of collaborative font projects, to support the font creation efforts of academic and linguistic communities, and to provide a free and open framework in which fonts may be shared and improved in partnership with others.
+
+The OFL allows the licensed fonts to be used, studied, modified and redistributed freely as long as they are not sold by themselves. The fonts, including any derivative works, can be bundled, embedded, redistributed and/or sold with any software provided that any reserved names are not used by derivative works. The fonts and derivatives, however, cannot be released under any other type of license. The requirement for fonts to remain under this license does not apply to any document created using the fonts or their derivatives.
+
+DEFINITIONS
+"Font Software" refers to the set of files released by the Copyright Holder(s) under this license and clearly marked as such. This may include source files, build scripts and documentation.
+
+"Reserved Font Name" refers to any names specified as such after the copyright statement(s).
+
+"Original Version" refers to the collection of Font Software components as distributed by the Copyright Holder(s).
+
+"Modified Version" refers to any derivative made by adding to, deleting, or substituting -- in part or in whole -- any of the components of the Original Version, by changing formats or by porting the Font Software to a new environment.
+
+"Author" refers to any designer, engineer, programmer, technical writer or other person who contributed to the Font Software.
+
+PERMISSION &amp; CONDITIONS
+Permission is hereby granted, free of charge, to any person obtaining a copy of the Font Software, to use, study, copy, merge, embed, modify, redistribute, and sell modified and unmodified copies of the Font Software, subject to the following conditions:
+
+1) Neither the Font Software nor any of its individual components, in Original or Modified Versions, may be sold by itself.
+
+2) Original or Modified Versions of the Font Software may be bundled, redistributed and/or sold with any software, provided that each copy contains the above copyright notice and this license. These can be included either as stand-alone text files, human-readable headers or in the appropriate machine-readable metadata fields within text or binary files as long as those fields can be easily viewed by the user.
+
+3) No Modified Version of the Font Software may use the Reserved Font Name(s) unless explicit written permission is granted by the corresponding Copyright Holder. This restriction only applies to the primary font name as presented to the users.
+
+4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font Software shall not be used to promote, endorse or advertise any Modified Version, except to acknowledge the contribution(s) of the Copyright Holder(s) and the Author(s) or with their explicit written permission.
+
+5) The Font Software, modified or unmodified, in part or in whole, must be distributed entirely under this license, and must not be distributed under any other license. The requirement for fonts to remain under this license does not apply to any document created using the Font Software.
+
+TERMINATION
+This license becomes null and void if any of the above conditions are not met.
+
+DISCLAIMER
+THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM OTHER DEALINGS IN THE FONT SOFTWARE.</string>
+ <key>openTypeNameLicenseURL</key>
+ <string>http://scripts.sil.org/OFL</string>
+ <key>openTypeNameManufacturer</key>
+ <string>SIL International</string>
+ <key>openTypeNameManufacturerURL</key>
+ <string>http://scripts.sil.org</string>
+ <key>openTypeNamePreferredFamilyName</key>
+ <string>Psf Test</string>
+ <key>openTypeNamePreferredSubfamilyName</key>
+ <string>Italic</string>
+ <key>openTypeNameUniqueID</key>
+ <string>SIL International: Psf Test Italic: 2022</string>
+ <key>openTypeNameVersion</key>
+ <string>Version 5.550</string>
+ <key>openTypeOS2CodePageRanges</key>
+ <array>
+ <integer>0</integer>
+ <integer>1</integer>
+ <integer>2</integer>
+ <integer>4</integer>
+ <integer>7</integer>
+ <integer>8</integer>
+ </array>
+ <key>openTypeOS2FamilyClass</key>
+ <array>
+ <integer>0</integer>
+ <integer>0</integer>
+ </array>
+ <key>openTypeOS2Panose</key>
+ <array>
+ <integer>2</integer>
+ <integer>0</integer>
+ <integer>0</integer>
+ <integer>0</integer>
+ <integer>0</integer>
+ <integer>0</integer>
+ <integer>0</integer>
+ <integer>0</integer>
+ <integer>0</integer>
+ <integer>0</integer>
+ </array>
+ <key>openTypeOS2StrikeoutPosition</key>
+ <integer>700</integer>
+ <key>openTypeOS2StrikeoutSize</key>
+ <integer>100</integer>
+ <key>openTypeOS2SubscriptXOffset</key>
+ <integer>0</integer>
+ <key>openTypeOS2SubscriptXSize</key>
+ <integer>1433</integer>
+ <key>openTypeOS2SubscriptYOffset</key>
+ <integer>286</integer>
+ <key>openTypeOS2SubscriptYSize</key>
+ <integer>1331</integer>
+ <key>openTypeOS2SuperscriptXOffset</key>
+ <integer>0</integer>
+ <key>openTypeOS2SuperscriptXSize</key>
+ <integer>1433</integer>
+ <key>openTypeOS2SuperscriptYOffset</key>
+ <integer>976</integer>
+ <key>openTypeOS2SuperscriptYSize</key>
+ <integer>1331</integer>
+ <key>openTypeOS2Type</key>
+ <array/>
+ <key>openTypeOS2TypoAscender</key>
+ <integer>2100</integer>
+ <key>openTypeOS2TypoDescender</key>
+ <integer>-550</integer>
+ <key>openTypeOS2TypoLineGap</key>
+ <integer>0</integer>
+ <key>openTypeOS2UnicodeRanges</key>
+ <array>
+ <integer>0</integer>
+ <integer>1</integer>
+ <integer>6</integer>
+ <integer>7</integer>
+ <integer>31</integer>
+ <integer>33</integer>
+ <integer>35</integer>
+ <integer>36</integer>
+ <integer>37</integer>
+ <integer>38</integer>
+ <integer>39</integer>
+ <integer>40</integer>
+ <integer>45</integer>
+ <integer>46</integer>
+ <integer>47</integer>
+ <integer>57</integer>
+ <integer>60</integer>
+ <integer>62</integer>
+ <integer>64</integer>
+ <integer>67</integer>
+ <integer>69</integer>
+ <integer>89</integer>
+ </array>
+ <key>openTypeOS2VendorID</key>
+ <string>SIL</string>
+ <key>openTypeOS2WeightClass</key>
+ <integer>400</integer>
+ <key>openTypeOS2WidthClass</key>
+ <integer>5</integer>
+ <key>openTypeOS2WinAscent</key>
+ <integer>2100</integer>
+ <key>openTypeOS2WinDescent</key>
+ <integer>550</integer>
+ <key>postscriptBlueValues</key>
+ <array>
+ <integer>-490</integer>
+ <integer>-490</integer>
+ <integer>-25</integer>
+ <integer>0</integer>
+ <integer>1020</integer>
+ <integer>1040</integer>
+ <integer>1455</integer>
+ <integer>1485</integer>
+ <integer>1600</integer>
+ <integer>1620</integer>
+ </array>
+ <key>postscriptFontName</key>
+ <string>PsfTest-Italic</string>
+ <key>postscriptFullName</key>
+ <string>Psf Test Italic</string>
+ <key>postscriptStemSnapH</key>
+ <array>
+ <integer>140</integer>
+ <integer>145</integer>
+ <integer>150</integer>
+ <integer>155</integer>
+ <integer>160</integer>
+ <integer>165</integer>
+ <integer>170</integer>
+ <integer>175</integer>
+ <integer>185</integer>
+ <integer>270</integer>
+ </array>
+ <key>postscriptStemSnapV</key>
+ <array>
+ <integer>165</integer>
+ <integer>180</integer>
+ <integer>185</integer>
+ <integer>190</integer>
+ <integer>195</integer>
+ <integer>200</integer>
+ <integer>205</integer>
+ <integer>270</integer>
+ </array>
+ <key>postscriptUnderlinePosition</key>
+ <integer>-110</integer>
+ <key>postscriptUnderlineThickness</key>
+ <integer>80</integer>
+ <key>styleMapFamilyName</key>
+ <string>Psf Test</string>
+ <key>styleMapStyleName</key>
+ <string>italic</string>
+ <key>styleName</key>
+ <string>Italic</string>
+ <key>trademark</key>
+ <string>Andika is a trademark of SIL International.</string>
+ <key>unitsPerEm</key>
+ <integer>2048</integer>
+ <key>versionMajor</key>
+ <integer>5</integer>
+ <key>versionMinor</key>
+ <integer>550</integer>
+ <key>xHeight</key>
+ <integer>1040</integer>
+ <key>year</key>
+ <integer>2021</integer>
+</dict>
+</plist>
diff --git a/tests/reference/ufo/psfsyncmasters.lg b/tests/reference/ufo/psfsyncmasters.lg
new file mode 100644
index 0000000..dabd1cc
--- /dev/null
+++ b/tests/reference/ufo/psfsyncmasters.lg
@@ -0,0 +1,12 @@
+2020-07-28 14:36:09 Progress: Running: psfsyncmasters -n tests/input/font-psf-test/source/PsfTestRoman.designspace tests/input/font-psf-test/source/PsfTestItalic.designspace -l local/testresults/ufo/psfsyncmasters.log
+2020-07-28 14:36:09 Warning: PsfTest-Bold.ufo com.schriftgestaltung.glyphOrder updated: Old value: ['.notdef', '.null',..., new value: ['.notdef', '.null',...
+2020-07-28 14:36:09 Progress: Writing updated lib.plist to lib_new.plist
+2020-07-28 14:36:09 Progress: Writing updated fontinfo.plist to fontinfo_new.plist
+2020-07-28 14:36:09 Warning: PsfTest-Italic.ufo openTypeNamePreferredFamilyName updated: Old value: Psf Testing, new value: Psf Test
+2020-07-28 14:36:09 Warning: PsfTest-Italic.ufo openTypeOS2TypoLineGap updated: Old value: 1, new value: 0
+2020-07-28 14:36:09 Warning: PsfTest-Italic.ufo styleMapFamilyName updated: Old value: Psf test, new value: Psf Test
+2020-07-28 14:36:09 Progress: Writing updated fontinfo.plist to fontinfo_new.plist
+2020-07-28 14:36:09 Warning: PsfTest-BoldItalic.ufo openTypeHheaAscender updated: Old value: 2200, new value: 2100
+2020-07-28 14:36:09 Warning: PsfTest-BoldItalic.ufo postscriptFamilyBlues removed: Old value: []
+2020-07-28 14:36:09 Progress: Writing updated fontinfo.plist to fontinfo_new.plist
+2020-07-28 14:36:09 Progress: psfsyncmasters completed
diff --git a/tests/reference/ufo/psfufo2ttf.lg b/tests/reference/ufo/psfufo2ttf.lg
new file mode 100644
index 0000000..53e7ee8
--- /dev/null
+++ b/tests/reference/ufo/psfufo2ttf.lg
@@ -0,0 +1,4 @@
+2020-07-28 14:36:09 Progress: Running: psfufo2ttf tests/input/font-psf-test/source/PsfTest-Regular.ufo local/testresults/ufo/psfufo2ttf.ttf -l local/testresults/ufo/psfufo2ttf.log
+2020-07-28 14:36:09 Progress: Converting UFO to ttf without OT
+2020-07-28 14:36:09 Progress: Saving ttf file
+2020-07-28 14:36:09 Progress: Done
diff --git a/tests/reference/ufo/psfufo2ttf.ttf b/tests/reference/ufo/psfufo2ttf.ttf
new file mode 100644
index 0000000..748c82b
--- /dev/null
+++ b/tests/reference/ufo/psfufo2ttf.ttf
Binary files differ
diff --git a/tests/resetreferencelogs.py b/tests/resetreferencelogs.py
new file mode 100644
index 0000000..064a1e3
--- /dev/null
+++ b/tests/resetreferencelogs.py
@@ -0,0 +1,67 @@
+#!/usr/bin/env python
+''' Reset the reference log files following changes to tests
+Works on one test group at a time.
+Copies the results logs to reference .lg files, replacing making file paths generic.
+setupTestdata.py then generates correct log files from .lg files
+'''
+__url__ = 'http://github.com/silnrsi/pysilfont'
+__copyright__ = 'Copyright (c) 2018 SIL International (http://www.sil.org)'
+__license__ = 'Released under the MIT License (http://opensource.org/licenses/MIT)'
+__author__ = 'David Raymond'
+
+import os, sys, shutil, glob, io
+from silfont.util import text_diff
+
+# Check being run in pysilfont root directory
+cwd = os.getcwd()
+if os.path.split(cwd)[1] != "pysilfont":
+ print("resetReferenceLogs must be run in pysilfont root directory")
+ sys.exit(1)
+
+if len(sys.argv) != 2:
+ print("Usage: resetReferenceLogs testgroupname")
+ print("*** Should only be run when reference logs in the local/testresults/<testgorupname> directory"
+ " are known to be good ***")
+ sys.exit()
+
+testgroup = sys.argv[1]
+
+if testgroup not in ("ufo", "fontparts"):
+ print("Invalid test group")
+ sys.exit()
+
+logsdir = "local/testresults/" + testgroup + "/"
+refdir = "tests/reference/" + testgroup + "/"
+
+if not os.path.isdir(logsdir):
+ print(logsdir + " does not exist")
+ sys.exit()
+
+
+# Read the new log files and create new .lg files from them
+logs = glob.iglob(logsdir + "*.log")
+updates = False
+for log in logs:
+ inlog = io.open(log, mode="r", encoding="utf-8")
+ testn = os.path.splitext(os.path.split(log)[1])[0]
+ outtmp = refdir + testn + ".tmp"
+ outlg = refdir + testn + ".lg"
+ outlog = io.open(outtmp, mode="w", encoding="utf-8")
+ for line in inlog:
+ line = line.replace(cwd, "@cwd@") # Replace machine-specific cwd with placeholder
+ line = line.replace("\\","/") # Replace Windows \ with /
+ outlog.write(line)
+ outlog.close()
+ # Only update the .lg if it has changed
+ diff = text_diff(outtmp, outlg, ignore_chars=20)
+ if diff.returncode: # Either they are different or .lg file is missing
+ try:
+ os.remove(outlg)
+ except:
+ pass
+ os.rename(outtmp, outlg)
+ updates = True
+ print(outlg + " recreated")
+ else:
+ os.remove(outtmp)
+if updates: print("Run tests/setuptestdata.py to reset reference .log files") \ No newline at end of file
diff --git a/tests/runlocalufotests.py b/tests/runlocalufotests.py
new file mode 100644
index 0000000..5d79d70
--- /dev/null
+++ b/tests/runlocalufotests.py
@@ -0,0 +1,63 @@
+#!/usr/bin/env python
+''' For running local tests, assuming setuplocalufotests.py has been run
+The copy in pysilfont/tests should never be run. setuplocalufotests makes a copy in local/tests and renames it to
+test_localufos so that "pytest local" or "pytest local/ufotests" will find and run it
+It assumes setuplocalufotests had run cleanly, so minimal checking for validity of csv file
+'''
+__url__ = 'http://github.com/silnrsi/pysilfont'
+__copyright__ = 'Copyright (c) 2018 SIL International (http://www.sil.org)'
+__license__ = 'Released under the MIT License (http://opensource.org/licenses/MIT)'
+__author__ = 'David Raymond'
+
+from silfont.core import execute, csvreader
+import silfont.util as UT
+import silfont.scripts.psfnormalize as psfnormalize
+import os, sys, shutil, glob, io
+
+
+# Open config file
+cfg = csvreader("local/ufotests/ufolist.csv")
+cfg.numfields=4
+
+# Clear out any previous results
+resultsdir = "local/ufotests/results/"
+if os.path.isdir(resultsdir):
+ shutil.rmtree(resultsdir)
+os.makedirs(resultsdir)
+
+ufolist = []
+for line in cfg: ufolist.append(line)
+
+def test_normalize():
+ global ufolist
+ allclear = True
+
+ for (ufo, ufoname, errorcount, warningcount) in ufolist:
+ cl = " ".join(["psfnormalize", ufo, "-l", resultsdir + ufoname + ".log", "-q", "-p", "checkfix=fix"])
+ result = UT.test_run("UFO", cl, psfnormalize, resultsdir + ufoname + ".ufo", int(errorcount), int(warningcount))
+ if not result:
+ print("The above issues were with normalizing " + ufo)
+ allclear = False
+
+ assert allclear
+
+def test_diffs():
+ global ufolist
+ allclear = True
+
+ for line in ufolist:
+ ufoname = line[1]
+ diff = UT.ufo_diff(resultsdir + ufoname + ".ufo", "local/ufotests/reference/" + ufoname + ".ufo")
+ if diff.returncode:
+ allclear = False
+ diff.print_text()
+ diff = UT.text_diff(resultsdir + ufoname + ".log", "local/ufotests/reference/" + ufoname + ".log", ignore_chars=20)
+ if diff.returncode:
+ allclear = False
+ diff.print_text()
+
+ assert allclear
+
+if __name__ == "__main__":
+ test_normalize()
+ test_diffs()
diff --git a/tests/runmakefeatests.py b/tests/runmakefeatests.py
new file mode 100644
index 0000000..7243202
--- /dev/null
+++ b/tests/runmakefeatests.py
@@ -0,0 +1,46 @@
+#!/usr/bin/env python
+''' Test of script named in testname below
+'''
+__url__ = 'http://github.com/silnrsi/pysilfont'
+__copyright__ = 'Copyright (c) 2019 SIL International (http://www.sil.org)'
+__license__ = 'Released under the MIT License (http://opensource.org/licenses/MIT)'
+__author__ = 'David Raymond'
+
+import silfont.util
+
+# Next 7 lines of code may be test-specific
+import os
+import silfont.scripts.psfmakefea as testcommand
+from glob import glob
+
+testname = "psfmakefea"
+outdir = "local/testresults/psfmakefea"
+cl = "psfmakefea -i tests/input/{name}.feax -o {outdir}/{name}.fea -l {outdir}/{name}.log"
+outfont = None # Set to None for commands which don't output a font
+diffexts = [".fea", ".log"] # List of extensions of all output files
+exp_errors = 0 # These may need updating if the test ufo is updated
+exp_warnings = 0 # The test ufo should have some errors/warnings to test the code!
+test_files = [os.path.splitext(os.path.basename(f))[0] for f in glob("tests/input/*.feax")]
+# Code after this can be the same for most/all tests; if needed to be different for a test remove this comment!
+
+def test_run():
+ if not os.path.exists(outdir):
+ os.makedirs(outdir)
+ for name in test_files:
+ command = cl.format(name=name, outdir=outdir)
+ result = silfont.util.test_run(None, command, testcommand, outfont, exp_errors, exp_warnings)
+ assert result
+
+def test_diffs(): # Do a diff on all output files
+ for name in test_files:
+ result = silfont.util.test_diffs("psfmakefea", name, diffexts)
+ assert result
+
+if __name__ == "__main__":
+ test_run()
+ test_diffs()
+
+
+
+
+
diff --git a/tests/setuplocalufotests.py b/tests/setuplocalufotests.py
new file mode 100644
index 0000000..f8ca322
--- /dev/null
+++ b/tests/setuplocalufotests.py
@@ -0,0 +1,69 @@
+#!/usr/bin/env python
+''' Setup test based on locally-stored UFOs
+Reads from tests/localufos.csv which has format ufopath,type where
+- ufopath is the full path to the ufo
+- type is either:
+ - "copy" to copy the ufo to local/ufotests/source (to protect against future changes to the ufo
+ - "insitu" to use the uso from where it is, for ufos unlikely to be changed during a development cycle
+It should be run with stable pysilfont code prior to starting development and will create reference copies of the fonts
+by normalizing with checkfix=fix
+Once setup, "pytest local/ufotests" will again normalize all the fonts listed and compare with the reference fonts
+'''
+__url__ = 'http://github.com/silnrsi/pysilfont'
+__copyright__ = 'Copyright (c) 2018 SIL International (http://www.sil.org)'
+__license__ = 'Released under the MIT License (http://opensource.org/licenses/MIT)'
+__author__ = 'David Raymond'
+
+from silfont.core import execute, csvreader
+import silfont.scripts.psfnormalize as psfnormalize
+import os, sys, shutil
+
+# Check being run in pysilfont root directory
+cwd = os.getcwd()
+if os.path.split(cwd)[1] != "pysilfont":
+ print("setupTestdata must be run in pysilfont root directory")
+ sys.exit(1)
+
+# Open config file
+cfg = csvreader("tests/localufos.csv")
+cfg.numfields=2
+
+# Clear out any previous data and create directory tree
+if os.path.isdir("local/ufotests"): shutil.rmtree("local/ufotests")
+for type in ("source", "results", "reference", "logs"): os.makedirs("local/ufotests/" + type)
+
+# Create source (for type=copy) and reference copies of the ufos
+ufolist = []
+for ufo,type in cfg:
+ (path,ufoname) = os.path.split(ufo)
+ logname = ufoname[:-4] + ".log"
+ if not os.path.isdir(ufo):
+ print (ufo + " is not a directory")
+ continue
+ if type == "copy":
+ sourcedir = "local/ufotests/source/" + ufoname
+ shutil.copytree(ufo, sourcedir)
+ elif type == "insitu":
+ sourcedir = ufo
+ else:
+ print("Invalid type '" + type + "' for " + ufo)
+ continue
+
+ sys.argv = ["psfnormalize", sourcedir, "-l", "local/ufotests/results/" + logname, "-q", "-p", "checkfix=fix"]
+ print("Normalizing " + sourcedir + " for reference")
+ (args, font) = execute("UFO", psfnormalize.doit, psfnormalize.argspec, chain="first")
+ font.write("local/ufotests/results/" + ufoname)
+ # Move from results to reference - originally written to results to get reference log file correct
+ os.rename("local/ufotests/results/" + ufoname, "local/ufotests/reference/" + ufoname)
+ os.rename("local/ufotests/results/" + logname, "local/ufotests/reference/" + logname)
+ #errorcount = args.logger.errorcount -1 if args.logger.errorcount else 0 # If there is an error, reduce count for extra error reporting that there were errors!
+ ufolist.append((sourcedir, ufoname[:-4], str(args.logger.errorcount), str(args.logger.warningcount)))
+args.logger.logfile.close() # Make sure final log file is closed
+
+# Create ufolist.csv
+ufofile = open("local/ufotests/ufolist.csv", "w")
+for line in ufolist:
+ ufofile.write(",".join(line) + "\n")
+
+# Copy the main test to local/ufotests
+shutil.copy("tests/runlocalufotests.py", "local/ufotests/test_localufos.py")
diff --git a/tests/setuptestdata.py b/tests/setuptestdata.py
new file mode 100644
index 0000000..7dbe296
--- /dev/null
+++ b/tests/setuptestdata.py
@@ -0,0 +1,47 @@
+#!/usr/bin/env python
+''' Setup the test environment
+'''
+__url__ = 'http://github.com/silnrsi/pysilfont'
+__copyright__ = 'Copyright (c) 2018 SIL International (http://www.sil.org)'
+__license__ = 'Released under the MIT License (http://opensource.org/licenses/MIT)'
+__author__ = 'David Raymond'
+
+import os, sys, shutil, glob, io
+
+# Check being run in pysilfont root directory
+cwd = os.getcwd()
+if os.path.split(cwd)[1] != "pysilfont":
+ print("setupTestdata must be run in pysilfont root directory")
+ sys.exit(1)
+
+resultsdir = "local/testresults/"
+oldresultsdir = "local/oldtestresults/"
+
+if os.path.isdir(resultsdir):
+ if os.path.isdir(oldresultsdir): shutil.rmtree(oldresultsdir)
+ os.rename(resultsdir, oldresultsdir)
+os.makedirs(resultsdir + "ufo/psfglyphs2ufo")
+os.makedirs(resultsdir + "fontparts")
+
+
+# Copy standard UFO results across so that the log files consistently say:
+# "Progress: Output UFO already exists - reading for comparison"
+
+ufos = glob.iglob("tests/reference/ufo/*.ufo")
+for ufo in ufos:
+ (base, ufoname) = os.path.split(ufo)
+ resultufo = os.path.join(resultsdir, "ufo", ufoname)
+ shutil.copytree(ufo, resultufo)
+
+# Create reference log files from .lg files
+for name in os.listdir("tests/reference/"):
+ fulldir = "tests/reference/" + name
+ if os.path.isdir(fulldir):
+ for filen in os.listdir(fulldir):
+ (base,ext) = os.path.splitext(filen)
+ if ext == ".lg":
+ inlog = io.open(os.path.join(fulldir, filen), mode="r", encoding="utf-8")
+ outlog = io.open(os.path.join(fulldir, base + ".log"), mode="w", encoding="utf-8")
+ for line in inlog:
+ line = line.replace("@cwd@", cwd) # Replace placeholder with machine-specific cwd
+ outlog.write(line)
diff --git a/tests/ufo/test_10_psfbuildcomp.py b/tests/ufo/test_10_psfbuildcomp.py
new file mode 100644
index 0000000..d599c7e
--- /dev/null
+++ b/tests/ufo/test_10_psfbuildcomp.py
@@ -0,0 +1,37 @@
+#!/usr/bin/env python
+''' Test of script named in testname below
+'''
+__url__ = 'http://github.com/silnrsi/pysilfont'
+__copyright__ = 'Copyright (c) 2018 SIL International (http://www.sil.org)'
+__license__ = 'Released under the MIT License (http://opensource.org/licenses/MIT)'
+__author__ = 'David Raymond'
+
+import silfont.util
+
+# Next 7 lines of code may be test-specific
+import silfont.scripts.psfbuildcomp as testcommand
+testname = "psfbuildcomp"
+cl = "psfbuildcomp tests/input/font-psf-test/source/PsfTest-Regular.ufo -i tests/input/psfbuildcomp.txt -l local/testresults/ufo/psfbuildcomp.log -p loglevel=i"
+outfont = "local/testresults/ufo/psfbuildcomp.ufo" # Set to None for commands which don't output a font
+diffexts = [".ufo", ".log"] # List of extensions of all output files
+exp_errors = 9 # These may need updating if the test ufo is updated
+exp_warnings = 5 # The test ufo should have some errors/warnings to test the code!
+
+# Code after this can be the same for most/all tests; if needed to be different for a test remove this comment!
+
+def test_run():
+ result = silfont.util.test_run("UFO", cl, testcommand, outfont, exp_errors, exp_warnings)
+ assert result
+
+def test_diffs(): # Do a diff on all output files
+ result = silfont.util.test_diffs("ufo", testname, diffexts)
+ assert result
+
+if __name__ == "__main__":
+ test_run()
+ test_diffs()
+
+
+
+
+
diff --git a/tests/ufo/test_16_psfchangettfglyphnames.py b/tests/ufo/test_16_psfchangettfglyphnames.py
new file mode 100644
index 0000000..72b7dc1
--- /dev/null
+++ b/tests/ufo/test_16_psfchangettfglyphnames.py
@@ -0,0 +1,37 @@
+#!/usr/bin/env python
+'Test for psfchangettfglyphnames'
+__url__ = 'http://github.com/silnrsi/pysilfont'
+__copyright__ = 'Copyright (c) 2018 SIL International (http://www.sil.org)'
+__license__ = 'Released under the MIT License (http://opensource.org/licenses/MIT)'
+__author__ = 'David Raymond'
+
+import silfont.util
+
+# Next 5 lines of code are test-specific
+import silfont.scripts.psfchangettfglyphnames as testcommand
+testname = "psfchangettfglyphnames"
+cl = "psfchangettfglyphnames tests/input/font-psf-test/source/PsfTest-Regular.ufo " \
+ "tests/input/PsfTest-R.ttf local/testresults/ufo/psfchangettfglyphnames.ttf -l local/testresults/ufo/psfchangettfglyphnames.log"
+outfont = None
+diffexts = [".ttf", ".log"]
+exp_errors = 0 # These may need updating if the test ufo is updated
+exp_warnings = 0 # The test ufo should have some errors/warnings to test the code!
+
+# Code after this can be the same for most tests; if needed to be different for a test remove this comment!
+
+def test_run():
+ result = silfont.util.test_run("UFO", cl, testcommand, outfont, exp_errors, exp_warnings)
+ assert result
+
+def test_diffs(): # Generic function for all UFO tests
+ result = silfont.util.test_diffs("ufo", testname, diffexts)
+ assert result
+
+if __name__ == "__main__":
+ test_run()
+ test_diffs()
+
+
+
+
+
diff --git a/tests/ufo/test_18_psfcheckbasicchars.py b/tests/ufo/test_18_psfcheckbasicchars.py
new file mode 100644
index 0000000..9e685ce
--- /dev/null
+++ b/tests/ufo/test_18_psfcheckbasicchars.py
@@ -0,0 +1,36 @@
+#!/usr/bin/env python
+'Test for psfcheckbasicchars'
+__url__ = 'http://github.com/silnrsi/pysilfont'
+__copyright__ = 'Copyright (c) 2018 SIL International (http://www.sil.org)'
+__license__ = 'Released under the MIT License (http://opensource.org/licenses/MIT)'
+__author__ = 'David Raymond'
+
+import silfont.util
+
+# Next 5 lines of code are test-specific
+import silfont.scripts.psfcheckbasicchars as testcommand
+testname = "psfcheckbasicchars"
+cl = "psfcheckbasicchars tests/input/font-psf-test/source/PsfTest-Regular.ufo -l local/testresults/ufo/psfcheckbasicchars.log"
+outfont = None
+diffexts = [".log"]
+exp_errors = 1 # These may need updating if the test ufo is updated
+exp_warnings = 192 # The test ufo should have some errors/warnings to test the code!
+
+# Code after this can be the same for most tests; if needed to be different for a test remove this comment!
+
+def test_run():
+ result = silfont.util.test_run("UFO", cl, testcommand, outfont, exp_errors, exp_warnings)
+ assert result
+
+def test_diffs(): # Generic function for all UFO tests
+ result = silfont.util.test_diffs("ufo", testname, diffexts)
+ assert result
+
+if __name__ == "__main__":
+ test_run()
+ test_diffs()
+
+
+
+
+
diff --git a/tests/ufo/test_23_psfcopyglyphs.py b/tests/ufo/test_23_psfcopyglyphs.py
new file mode 100644
index 0000000..b874cea
--- /dev/null
+++ b/tests/ufo/test_23_psfcopyglyphs.py
@@ -0,0 +1,41 @@
+#!/usr/bin/env python
+''' Test of script named in testname below
+'''
+__url__ = 'http://github.com/silnrsi/pysilfont'
+__copyright__ = 'Copyright (c) 2018 SIL International (http://www.sil.org)'
+__license__ = 'Released under the MIT License (http://opensource.org/licenses/MIT)'
+__author__ = 'David Raymond'
+
+import silfont.util
+
+# Next 7 lines of code may be test-specific
+import silfont.scripts.psfcopyglyphs as testcommand
+testname = "psfcopyglyphs"
+cl = "psfcopyglyphs -s tests/input/font-psf-test/source/PsfTest-Regular.ufo " \
+ "tests/input/font-psf-test/source/PsfTest-Italic.ufo " \
+ "-i tests/input/psfcopyglyphs.csv " \
+ "-l local/testresults/ufo/psfcopyglyphs.log " \
+ "--rename newname --unicode usv"
+outfont = "local/testresults/ufo/psfcopyglyphs.ufo" # Set to None for commands which don't output a font
+diffexts = [".ufo", ".log"] # List of extensions of all output files
+exp_errors = 0 # These may need updating if the test ufo is updated
+exp_warnings = 15 # The test ufo should have some errors/warnings to test the code!
+
+# Code after this can be the same for most/all tests; if needed to be different for a test remove this comment!
+
+def test_run():
+ result = silfont.util.test_run("UFO", cl, testcommand, outfont, exp_errors, exp_warnings)
+ assert result
+
+def test_diffs(): # Do a diff on all output files
+ result = silfont.util.test_diffs("ufo", testname, diffexts)
+ assert result
+
+if __name__ == "__main__":
+ test_run()
+ test_diffs()
+
+
+
+
+
diff --git a/tests/ufo/test_30_psfdeleteglyphs.py b/tests/ufo/test_30_psfdeleteglyphs.py
new file mode 100644
index 0000000..c5c461a
--- /dev/null
+++ b/tests/ufo/test_30_psfdeleteglyphs.py
@@ -0,0 +1,37 @@
+#!/usr/bin/env python
+''' Test of script named in testname below
+'''
+__url__ = 'http://github.com/silnrsi/pysilfont'
+__copyright__ = 'Copyright (c) 2018 SIL International (http://www.sil.org)'
+__license__ = 'Released under the MIT License (http://opensource.org/licenses/MIT)'
+__author__ = 'David Raymond'
+
+import silfont.util
+
+# Next 7 lines of code may be test-specific
+import silfont.scripts.psfdeleteglyphs as testcommand
+testname = "psfdeleteglyphs"
+cl = "psfdeleteglyphs tests/input/font-psf-test/source/PsfTest-Regular.ufo -i tests/input/psfdeleteglyphs.txt -l local/testresults/ufo/psfdeleteglyphs.log -p loglevel=i -p scrlevel=w"
+outfont = "local/testresults/ufo/psfdeleteglyphs.ufo" # Set to None for commands which don't output a font
+diffexts = [".ufo", ".log"] # List of extensions of all output files
+exp_errors = 0 # These may need updating if the test ufo is updated
+exp_warnings = 6 # The test ufo should have some errors/warnings to test the code!
+
+# Code after this can be the same for most/all tests; if needed to be different for a test remove this comment!
+
+def test_run():
+ result = silfont.util.test_run("UFO", cl, testcommand, outfont, exp_errors, exp_warnings)
+ assert result
+
+def test_diffs(): # Do a diff on all output files
+ result = silfont.util.test_diffs("ufo", testname, diffexts)
+ assert result
+
+if __name__ == "__main__":
+ test_run()
+ test_diffs()
+
+
+
+
+
diff --git a/tests/ufo/test_34_psfexportanchors.py b/tests/ufo/test_34_psfexportanchors.py
new file mode 100644
index 0000000..fff85a7
--- /dev/null
+++ b/tests/ufo/test_34_psfexportanchors.py
@@ -0,0 +1,36 @@
+#!/usr/bin/env python
+'Test for psfexportanchors'
+__url__ = 'http://github.com/silnrsi/pysilfont'
+__copyright__ = 'Copyright (c) 2018 SIL International (http://www.sil.org)'
+__license__ = 'Released under the MIT License (http://opensource.org/licenses/MIT)'
+__author__ = 'David Raymond'
+
+import silfont.util
+
+# Next 5 lines of code are test-specific
+import silfont.scripts.psfexportanchors as testcommand
+testname = "psfexportanchors"
+cl = "psfexportanchors tests/input/font-psf-test/source/PsfTest-Italic.ufo local/testresults/ufo/psfexportanchors.xml -l local/testresults/ufo/psfexportanchors.log"
+outfont = None
+diffexts = [".xml", ".log"]
+exp_errors = 0 # These may need updating if the test ufo is updated
+exp_warnings = 10 # The test ufo should have some errors/warnings to test the code!
+
+# Code after this can be the same for most tests; if needed to be different for a test remove this comment!
+
+def test_run():
+ result = silfont.util.test_run("UFO", cl, testcommand, outfont, exp_errors, exp_warnings)
+ assert result
+
+def test_diffs(): # Generic function for all UFO tests
+ result = silfont.util.test_diffs("ufo", testname, diffexts)
+ assert result
+
+if __name__ == "__main__":
+ test_run()
+ test_diffs()
+
+
+
+
+
diff --git a/tests/ufo/test_36_psfexportunicodes.py b/tests/ufo/test_36_psfexportunicodes.py
new file mode 100644
index 0000000..6d5cad9
--- /dev/null
+++ b/tests/ufo/test_36_psfexportunicodes.py
@@ -0,0 +1,36 @@
+#!/usr/bin/env python
+'Test for psfexportunicodes'
+__url__ = 'http://github.com/silnrsi/pysilfont'
+__copyright__ = 'Copyright (c) 2018 SIL International (http://www.sil.org)'
+__license__ = 'Released under the MIT License (http://opensource.org/licenses/MIT)'
+__author__ = 'David Raymond'
+
+import silfont.util
+
+# Next 5 lines of code are test-specific
+import silfont.scripts.psfexportunicodes as testcommand
+testname = "psfexportunicodes"
+cl = "psfexportunicodes tests/input/font-psf-test/source/PsfTest-BoldItalic.ufo -o local/testresults/ufo/psfexportunicodes.csv -l local/testresults/ufo/psfexportunicodes.log"
+outfont = None
+diffexts = [".csv", ".log"]
+exp_errors = 0 # These may need updating if the test ufo is updated
+exp_warnings = 7 # The test ufo should have some errors/warnings to test the code!
+
+# Code after this can be the same for most tests; if needed to be different for a test remove this comment!
+
+def test_run():
+ result = silfont.util.test_run("UFO", cl, testcommand, outfont, exp_errors, exp_warnings)
+ assert result
+
+def test_diffs(): # Generic function for all UFO tests
+ result = silfont.util.test_diffs("ufo", testname, diffexts)
+ assert result
+
+if __name__ == "__main__":
+ test_run()
+ test_diffs()
+
+
+
+
+
diff --git a/tests/ufo/test_38_psfgenftml.py b/tests/ufo/test_38_psfgenftml.py
new file mode 100644
index 0000000..6c2483f
--- /dev/null
+++ b/tests/ufo/test_38_psfgenftml.py
@@ -0,0 +1,75 @@
+#!/usr/bin/env python
+''' Test of script named in testname below
+'''
+__url__ = 'http://github.com/silnrsi/pysilfont'
+__copyright__ = 'Copyright (c) 2018 SIL International (http://www.sil.org)'
+__license__ = 'Released under the MIT License (http://opensource.org/licenses/MIT)'
+__author__ = 'Bob Hallissy'
+
+import silfont.util
+import silfont.ftml_builder as FB
+
+# There is no one psfgenftml script -- each project will have its own. So here is what we'll use for testing:
+
+class testcommand(object):
+ argspec = [
+ ('ifont',{'help': 'Input UFO'}, {'type': 'infont'}),
+ ('output',{'help': 'Output file ftml in XML format', 'nargs': '?'}, {'type': 'outfile', 'def': '_out.ftml'}),
+ ('-i','--input',{'help': 'Glyph info csv file'}, {'type': 'incsv', 'def': 'glyph_data.csv'}),
+ ('-l','--log',{'help': 'Set log file name'}, {'type': 'outfile', 'def': '_ftml.log'}),
+ ]
+
+ @staticmethod
+ def doit(args):
+ logger = args.logger
+
+ # Read input csv
+ builder = FB.FTMLBuilder(logger, incsv = args.input, font = args.ifont)
+
+ # Initialize FTML document:
+ test = "ftml_builder test"
+ ftml = FB.FTML(test, logger)
+
+ # all chars that should be in the font:
+ ftml.startTestGroup('Encoded characters')
+ for uid in sorted(builder.uids()):
+ if uid < 32: continue
+ c = builder.char(uid)
+ # iterate over all permutations of feature settings that might affect this character:
+ for featlist in builder.permuteFeatures(uids = (uid,)):
+ ftml.setFeatures(featlist)
+ builder.render((uid,), ftml)
+ # Test one character with RTL enabled:
+ if uid == 67:
+ builder.render((uid,), ftml, rtl = True)
+ # Don't close test -- collect consecutive encoded chars in a single row
+ ftml.clearFeatures()
+ for langID in sorted(c.langs):
+ ftml.setLang(langID)
+ builder.render((uid,), ftml)
+ ftml.clearLang()
+
+ # Write the output ftml file
+ ftml.writeFile(args.output)
+
+testname = "psfgenftml"
+cl = testname + " -i tests/input/psfgenftml.csv -l local/testresults/ufo/psfgenftml.log " \
+ "tests/input/font-psf-test/source/PsfTest-Italic.ufo local/testresults/ufo/psfgenftml.ftml"
+outfont = None
+diffexts = [".ftml", ".log"]
+exp_errors = 0 # These may need updating if the test ufo is updated
+exp_warnings = 11 # The test ufo should have some errors/warnings to test the code!
+
+# Code after this can be the same for most tests; if needed to be different for a test remove this comment!
+
+def test_run():
+ result = silfont.util.test_run("UFO", cl, testcommand, outfont, exp_errors, exp_warnings)
+ assert result
+
+def test_diffs(): # Generic function for all UFO tests
+ result = silfont.util.test_diffs("ufo", testname, diffexts)
+ assert result
+
+if __name__ == "__main__":
+ test_run()
+ test_diffs()
diff --git a/tests/ufo/test_40_psfglyphs2ufo.py b/tests/ufo/test_40_psfglyphs2ufo.py
new file mode 100644
index 0000000..a5a74ff
--- /dev/null
+++ b/tests/ufo/test_40_psfglyphs2ufo.py
@@ -0,0 +1,64 @@
+#!/usr/bin/env python
+''' Test of script named in testname below
+'''
+__url__ = 'http://github.com/silnrsi/pysilfont'
+__copyright__ = 'Copyright (c) 2018 SIL International (http://www.sil.org)'
+__license__ = 'Released under the MIT License (http://opensource.org/licenses/MIT)'
+__author__ = 'David Raymond'
+
+import silfont.util
+import sys
+from silfont.core import execute
+import silfont.scripts.psfglyphs2ufo as psfglyphs2ufo
+import silfont.scripts.psfnormalize as psfnormalize
+
+def test_run():
+ cl = "psfglyphs2ufo --nofea tests/input/font-psf-test/source/PsfTestRoman.glyphs " \
+ "local/testresults/ufo/psfglyphs2ufo -l local/testresults/ufo/psfglyphs2ufo.log"
+ sys.argv = cl.split(" ")
+ (args, font) = execute("UFO", psfglyphs2ufo.doit, psfglyphs2ufo.argspec, chain="first")
+ args.logger.logfile.close()
+ exp_counts = (1, 0)
+ actual_counts = (args.logger.errorcount, args.logger.warningcount)
+ # Now normalize the output ufos
+ for weight in ("Regular", "Bold"):
+ fontname = "local/testresults/ufo/psfglyphs2ufo/PsfTest-" + weight + ".ufo"
+ cl = "psfnormalize " + fontname
+ sys.argv = cl.split(" ")
+ (args, font) = execute("UFO", psfnormalize.doit, psfnormalize.argspec, chain="first")
+ font.write(fontname)
+
+ if exp_counts == actual_counts:
+ assert True
+ else:
+ print("Mis-match of logger errors/warnings: " + str(exp_counts) + " vs " + str(actual_counts))
+ assert False
+
+def test_diffs(): # Do a diff on all output files
+ result = True
+ refdir = "tests/reference/ufo/"
+ resdir = "local/testresults/ufo/"
+
+ ufodiff = False
+
+ diff = silfont.util.ufo_diff(resdir + "psfglyphs2ufo/PsfTest-Regular.ufo", refdir + "psfglyphs2ufo/PsfTest-Regular.ufo")
+ if diff.returncode:
+ ufodiff = True
+ diff.print_text()
+ result = False
+
+ diff = silfont.util.ufo_diff(resdir + "psfglyphs2ufo/PsfTest-Bold.ufo", refdir + "psfglyphs2ufo/PsfTest-Bold.ufo")
+ if diff.returncode:
+ diff.print_text()
+ result = False
+
+ diff = silfont.util.text_diff(resdir + "psfglyphs2ufo.log", refdir + "psfglyphs2ufo.log", ignore_chars=20)
+ if diff.returncode:
+ diff.print_text()
+ result = False
+
+ assert result
+
+if __name__ == "__main__":
+ test_run()
+ test_diffs()
diff --git a/tests/ufo/test_42_psfmakefea.py b/tests/ufo/test_42_psfmakefea.py
new file mode 100644
index 0000000..4f4e069
--- /dev/null
+++ b/tests/ufo/test_42_psfmakefea.py
@@ -0,0 +1,37 @@
+#!/usr/bin/env python
+''' Test of script named in testname below
+'''
+__url__ = 'http://github.com/silnrsi/pysilfont'
+__copyright__ = 'Copyright (c) 2019 SIL International (http://www.sil.org)'
+__license__ = 'Released under the MIT License (http://opensource.org/licenses/MIT)'
+__author__ = 'David Raymond'
+
+import silfont.util
+
+# Next 7 lines of code may be test-specific
+import silfont.scripts.psfmakefea as testcommand
+testname = "psfmakefea"
+cl = "psfmakefea -i tests/input/psfmakefea.feax -o local/testresults/ufo/psfmakefea.fea -l local/testresults/ufo/psfmakefea.log tests/input/font-psf-test/source/PsfTest-Regular.ufo"
+outfont = None # Set to None for commands which don't output a font
+diffexts = [".fea", ".log"] # List of extensions of all output files
+exp_errors = 0 # These may need updating if the test ufo is updated
+exp_warnings = 0 # The test ufo should have some errors/warnings to test the code!
+
+# Code after this can be the same for most/all tests; if needed to be different for a test remove this comment!
+
+def test_run():
+ result = silfont.util.test_run("UFO", cl, testcommand, outfont, exp_errors, exp_warnings)
+ assert result
+
+def test_diffs(): # Do a diff on all output files
+ result = silfont.util.test_diffs("ufo", testname, diffexts)
+ assert result
+
+if __name__ == "__main__":
+ test_run()
+ test_diffs()
+
+
+
+
+
diff --git a/tests/ufo/test_44_psfmakewoffmetatdata.py b/tests/ufo/test_44_psfmakewoffmetatdata.py
new file mode 100644
index 0000000..ff8325d
--- /dev/null
+++ b/tests/ufo/test_44_psfmakewoffmetatdata.py
@@ -0,0 +1,37 @@
+#!/usr/bin/env python
+'Test for psfmakewoffmetadata'
+__url__ = 'http://github.com/silnrsi/pysilfont'
+__copyright__ = 'Copyright (c) 2018 SIL International (http://www.sil.org)'
+__license__ = 'Released under the MIT License (http://opensource.org/licenses/MIT)'
+__author__ = 'David Raymond'
+
+import silfont.util
+
+# Next 5 lines of code are test-specific
+import silfont.scripts.psfmakewoffmetadata as testcommand
+testname = "psfmakewoffmetadata"
+cl = "psfmakewoffmetadata tests/input/font-psf-test/source/PsfTest-Regular.ufo -n Test -i SIL -f tests/input/psfmakewoffmetadata.txt" \
+ + " -o local/testresults/ufo/psfmakewoffmetadata.xml -l local/testresults/ufo/psfmakewoffmetadata.log"
+outfont = None
+diffexts = [".xml", ".log"]
+exp_errors = 0 # These may need updating if the test ufo is updated
+exp_warnings = 6 # The test ufo should have some errors/warnings to test the code!
+
+# Code after this can be the same for most tests; if needed to be different for a test remove this comment!
+
+def test_run():
+ result = silfont.util.test_run("UFO", cl, testcommand, outfont, exp_errors, exp_warnings)
+ assert result
+
+def test_diffs(): # Generic function for all UFO tests
+ result = silfont.util.test_diffs("ufo", testname, diffexts)
+ assert result
+
+if __name__ == "__main__":
+ test_run()
+ test_diffs()
+
+
+
+
+
diff --git a/tests/ufo/test_46_psfrenameglyphs.py b/tests/ufo/test_46_psfrenameglyphs.py
new file mode 100644
index 0000000..d040c25
--- /dev/null
+++ b/tests/ufo/test_46_psfrenameglyphs.py
@@ -0,0 +1,37 @@
+#!/usr/bin/env python
+''' Test of script named in testname below
+'''
+__url__ = 'http://github.com/silnrsi/pysilfont'
+__copyright__ = 'Copyright (c) 2018 SIL International (http://www.sil.org)'
+__license__ = 'Released under the MIT License (http://opensource.org/licenses/MIT)'
+__author__ = 'David Raymond'
+
+import silfont.util
+
+# Next 7 lines of code may be test-specific
+import silfont.scripts.psfrenameglyphs as testcommand
+testname = "psfrenameglyphs"
+cl = "psfrenameglyphs tests/input/font-psf-test/source/PsfTest-Bold.ufo -i tests/input/psfrenameglyphs.csv -l local/testresults/ufo/psfrenameglyphs.log -p loglevel=i -p checkfix=fix"
+outfont = "local/testresults/ufo/psfrenameglyphs.ufo" # Set to None for commands which don't output a font
+diffexts = [".ufo", ".log"] # List of extensions of all output files
+exp_errors = 0 # These may need updating if the test ufo is updated
+exp_warnings = 5 # The test ufo should have some errors/warnings to test the code!
+
+# Code after this can be the same for most/all tests; if needed to be different for a test remove this comment!
+
+def test_run():
+ result = silfont.util.test_run("UFO", cl, testcommand, outfont, exp_errors, exp_warnings)
+ assert result
+
+def test_diffs(): # Do a diff on all output files
+ result = silfont.util.test_diffs("ufo", testname, diffexts)
+ assert result
+
+if __name__ == "__main__":
+ test_run()
+ test_diffs()
+
+
+
+
+
diff --git a/tests/ufo/test_50_psfsetassocfeat.py b/tests/ufo/test_50_psfsetassocfeat.py
new file mode 100644
index 0000000..060a25d
--- /dev/null
+++ b/tests/ufo/test_50_psfsetassocfeat.py
@@ -0,0 +1,37 @@
+#!/usr/bin/env python
+''' Test of script named in testname below
+'''
+__url__ = 'http://github.com/silnrsi/pysilfont'
+__copyright__ = 'Copyright (c) 2018 SIL International (http://www.sil.org)'
+__license__ = 'Released under the MIT License (http://opensource.org/licenses/MIT)'
+__author__ = 'David Raymond'
+
+import silfont.util
+
+# Next 7 lines of code may be test-specific
+import silfont.scripts.psfsetassocfeat as testcommand
+testname = "psfsetassocfeat"
+cl = "psfsetassocfeat tests/input/font-psf-test/source/PsfTest-Italic.ufo -i tests/input/psfsetassocfeat.csv -l local/testresults/ufo/psfsetassocfeat.log -p loglevel=i"
+outfont = "local/testresults/ufo/psfsetassocfeat.ufo" # Set to None for commands which don't output a font
+diffexts = [".ufo", ".log"] # List of extensions of all output files
+exp_errors = 0 # These may need updating if the test ufo is updated
+exp_warnings = 9 # The test ufo should have some errors/warnings to test the code!
+
+# Code after this can be the same for most/all tests; if needed to be different for a test remove this comment!
+
+def test_run():
+ result = silfont.util.test_run("UFO", cl, testcommand, outfont, exp_errors, exp_warnings)
+ assert result
+
+def test_diffs(): # Do a diff on all output files
+ result = silfont.util.test_diffs("ufo", testname, diffexts)
+ assert result
+
+if __name__ == "__main__":
+ test_run()
+ test_diffs()
+
+
+
+
+
diff --git a/tests/ufo/test_52_psfsetassocuids.py b/tests/ufo/test_52_psfsetassocuids.py
new file mode 100644
index 0000000..adb35c7
--- /dev/null
+++ b/tests/ufo/test_52_psfsetassocuids.py
@@ -0,0 +1,37 @@
+#!/usr/bin/env python
+''' Test of script named in testname below
+'''
+__url__ = 'http://github.com/silnrsi/pysilfont'
+__copyright__ = 'Copyright (c) 2018 SIL International (http://www.sil.org)'
+__license__ = 'Released under the MIT License (http://opensource.org/licenses/MIT)'
+__author__ = 'David Raymond'
+
+import silfont.util
+
+# Next 7 lines of code may be test-specific
+import silfont.scripts.psfsetassocuids as testcommand
+testname = "psfsetassocuids"
+cl = "psfsetassocuids tests/input/font-psf-test/source/PsfTest-Bold.ufo -i tests/input/psfsetassocuids.csv -l local/testresults/ufo/psfsetassocuids.log -p loglevel=i"
+outfont = "local/testresults/ufo/psfsetassocuids.ufo" # Set to None for commands which don't output a font
+diffexts = [".ufo", ".log"] # List of extensions of all output files
+exp_errors = 1 # These may need updating if the test ufo is updated
+exp_warnings = 5 # The test ufo should have some errors/warnings to test the code!
+
+# Code after this can be the same for most/all tests; if needed to be different for a test remove this comment!
+
+def test_run():
+ result = silfont.util.test_run("UFO", cl, testcommand, outfont, exp_errors, exp_warnings)
+ assert result
+
+def test_diffs(): # Do a diff on all output files
+ result = silfont.util.test_diffs("ufo", testname, diffexts)
+ assert result
+
+if __name__ == "__main__":
+ test_run()
+ test_diffs()
+
+
+
+
+
diff --git a/tests/ufo/test_54_psfsetglyphorder.py b/tests/ufo/test_54_psfsetglyphorder.py
new file mode 100644
index 0000000..8d4181c
--- /dev/null
+++ b/tests/ufo/test_54_psfsetglyphorder.py
@@ -0,0 +1,37 @@
+#!/usr/bin/env python
+''' Test of script named in testname below
+'''
+__url__ = 'http://github.com/silnrsi/pysilfont'
+__copyright__ = 'Copyright (c) 2018 SIL International (http://www.sil.org)'
+__license__ = 'Released under the MIT License (http://opensource.org/licenses/MIT)'
+__author__ = 'David Raymond'
+
+import silfont.util
+
+# Next 7 lines of code may be test-specific
+import silfont.scripts.psfsetglyphorder as testcommand
+testname = "psfsetglyphorder"
+cl = "psfsetglyphorder tests/input/font-psf-test/source/PsfTest-Italic.ufo -i tests/input/glyph_data.csv -l local/testresults/ufo/psfsetglyphorder.log -p loglevel=i"
+outfont = "local/testresults/ufo/psfsetglyphorder.ufo" # Set to None for commands which don't output a font
+diffexts = [".ufo", ".log"] # List of extensions of all output files
+exp_errors = 0 # These may need updating if the test ufo is updated
+exp_warnings = 9 # The test ufo should have some errors/warnings to test the code!
+
+# Code after this can be the same for most/all tests; if needed to be different for a test remove this comment!
+
+def test_run():
+ result = silfont.util.test_run("UFO", cl, testcommand, outfont, exp_errors, exp_warnings)
+ assert result
+
+def test_diffs(): # Do a diff on all output files
+ result = silfont.util.test_diffs("ufo", testname, diffexts)
+ assert result
+
+if __name__ == "__main__":
+ test_run()
+ test_diffs()
+
+
+
+
+
diff --git a/tests/ufo/test_56_psfsetkeys.py b/tests/ufo/test_56_psfsetkeys.py
new file mode 100644
index 0000000..ac5505c
--- /dev/null
+++ b/tests/ufo/test_56_psfsetkeys.py
@@ -0,0 +1,37 @@
+#!/usr/bin/env python
+''' Test of script named in testname below
+'''
+__url__ = 'http://github.com/silnrsi/pysilfont'
+__copyright__ = 'Copyright (c) 2018 SIL International (http://www.sil.org)'
+__license__ = 'Released under the MIT License (http://opensource.org/licenses/MIT)'
+__author__ = 'David Raymond'
+
+import silfont.util
+
+# Next 7 lines of code may be test-specific
+import silfont.scripts.psfsetkeys as testcommand
+testname = "psfsetkeys"
+cl = "psfsetkeys tests/input/font-psf-test/source/PsfTest-BoldItalic.ufo -k org.sil.newkey -v newvalue -l local/testresults/ufo/psfsetkeys.log -p loglevel=i -p checkfix=fix"
+outfont = "local/testresults/ufo/psfsetkeys.ufo" # Set to None for commands which don't output a font
+diffexts = [".ufo", ".log"] # List of extensions of all output files
+exp_errors = 0 # These may need updating if the test ufo is updated
+exp_warnings = 7 # The test ufo should have some errors/warnings to test the code!
+
+# Code after this can be the same for most/all tests; if needed to be different for a test remove this comment!
+
+def test_run():
+ result = silfont.util.test_run("UFO", cl, testcommand, outfont, exp_errors, exp_warnings)
+ assert result
+
+def test_diffs(): # Do a diff on all output files
+ result = silfont.util.test_diffs("ufo", testname, diffexts)
+ assert result
+
+if __name__ == "__main__":
+ test_run()
+ test_diffs()
+
+
+
+
+
diff --git a/tests/ufo/test_60_psfsetpsnames.py b/tests/ufo/test_60_psfsetpsnames.py
new file mode 100644
index 0000000..924a815
--- /dev/null
+++ b/tests/ufo/test_60_psfsetpsnames.py
@@ -0,0 +1,37 @@
+#!/usr/bin/env python
+''' Test of script named in testname below
+'''
+__url__ = 'http://github.com/silnrsi/pysilfont'
+__copyright__ = 'Copyright (c) 2018 SIL International (http://www.sil.org)'
+__license__ = 'Released under the MIT License (http://opensource.org/licenses/MIT)'
+__author__ = 'David Raymond'
+
+import silfont.util
+
+# Next 7 lines of code may be test-specific
+import silfont.scripts.psfsetpsnames as testcommand
+testname = "psfsetpsnames"
+cl = "psfsetpsnames tests/input/font-psf-test/source/PsfTest-BoldItalic.ufo -i tests/input/glyph_data.csv -l local/testresults/ufo/psfsetpsnames.log -p loglevel=i"
+outfont = "local/testresults/ufo/psfsetpsnames.ufo" # Set to None for commands which don't output a font
+diffexts = [".ufo", ".log"] # List of extensions of all output files
+exp_errors = 0 # These may need updating if the test ufo is updated
+exp_warnings = 7 # The test ufo should have some errors/warnings to test the code!
+
+# Code after this can be the same for most/all tests; if needed to be different for a test remove this comment!
+
+def test_run():
+ result = silfont.util.test_run("UFO", cl, testcommand, outfont, exp_errors, exp_warnings)
+ assert result
+
+def test_diffs(): # Do a diff on all output files
+ result = silfont.util.test_diffs("ufo", testname, diffexts)
+ assert result
+
+if __name__ == "__main__":
+ test_run()
+ test_diffs()
+
+
+
+
+
diff --git a/tests/ufo/test_62_psfsetunicodes.py b/tests/ufo/test_62_psfsetunicodes.py
new file mode 100644
index 0000000..c12f3d4
--- /dev/null
+++ b/tests/ufo/test_62_psfsetunicodes.py
@@ -0,0 +1,37 @@
+#!/usr/bin/env python
+''' Test of script named in testname below
+'''
+__url__ = 'http://github.com/silnrsi/pysilfont'
+__copyright__ = 'Copyright (c) 2018 SIL International (http://www.sil.org)'
+__license__ = 'Released under the MIT License (http://opensource.org/licenses/MIT)'
+__author__ = 'David Raymond'
+
+import silfont.util
+
+# Next 7 lines of code may be test-specific
+import silfont.scripts.psfsetunicodes as testcommand
+testname = "psfsetunicodes"
+cl = "psfsetunicodes tests/input/font-psf-test/source/PsfTest-Italic.ufo -i tests/input/psfsetunicodes.csv -l local/testresults/ufo/psfsetunicodes.log -p loglevel=v -p checkfix=fix"
+outfont = "local/testresults/ufo/psfsetunicodes.ufo" # Set to None for commands which don't output a font
+diffexts = [".ufo", ".log"] # List of extensions of all output files
+exp_errors = 0 # These may need updating if the test ufo is updated
+exp_warnings = 9 # The test ufo should have some errors/warnings to test the code!
+
+# Code after this can be the same for most/all tests; if needed to be different for a test remove this comment!
+
+def test_run():
+ result = silfont.util.test_run("UFO", cl, testcommand, outfont, exp_errors, exp_warnings)
+ assert result
+
+def test_diffs(): # Do a diff on all output files
+ result = silfont.util.test_diffs("ufo", testname, diffexts)
+ assert result
+
+if __name__ == "__main__":
+ test_run()
+ test_diffs()
+
+
+
+
+
diff --git a/tests/ufo/test_80_psfsyncmasters.py b/tests/ufo/test_80_psfsyncmasters.py
new file mode 100644
index 0000000..128d7e6
--- /dev/null
+++ b/tests/ufo/test_80_psfsyncmasters.py
@@ -0,0 +1,73 @@
+#!/usr/bin/env python
+''' Test of script named in testname below
+'''
+__url__ = 'http://github.com/silnrsi/pysilfont'
+__copyright__ = 'Copyright (c) 2018 SIL International (http://www.sil.org)'
+__license__ = 'Released under the MIT License (http://opensource.org/licenses/MIT)'
+__author__ = 'David Raymond'
+
+import silfont.util
+import sys, os, glob, subprocess
+from silfont.core import execute
+import silfont.scripts.psfsyncmasters as psfsyncmasters
+
+def test_run():
+ cl = "psfsyncmasters -n tests/input/font-psf-test/source/PsfTestRoman.designspace " \
+ "tests/input/font-psf-test/source/PsfTestItalic.designspace -l local/testresults/ufo/psfsyncmasters.log"
+ sys.argv = cl.split(" ")
+ (args, font) = execute("UFO", psfsyncmasters.doit, psfsyncmasters.argspec, chain="first")
+ args.logger.logfile.close()
+ exp_counts = (0, 6)
+ actual_counts = (args.logger.errorcount, args.logger.warningcount)
+ if exp_counts == actual_counts:
+ assert True
+ else:
+ print("Mis-match of logger errors/warnings: " + str(exp_counts) + " vs " + str(actual_counts))
+ assert False
+
+def test_diffs(): # Do a diff on all output files
+ result = True
+ sourcedir = "tests/input/font-psf-test/source/"
+ refdir = "tests/reference/ufo/"
+ resdir = "local/testresults/ufo/"
+ # -n in commands will have created _new versions of changed files in the source directory,
+ # so move them to results prior to running diff commands
+ for f in glob.glob(resdir + "psfsyncmasters*.plist"): os.remove(f) # Delete any old results
+ filelist = []
+ for style in ("Regular", "Italic", "Bold", "BoldItalic"):
+ ufodir = sourcedir + "PsfTest-" + style + ".ufo/"
+ for f in glob.glob(ufodir + "*_new.plist"):
+ (dir,filen) = os.path.split(f)
+ filen = "fontinfo.plist" if filen[0] == "f" else "lib.plist"
+ filen = style + "-" + filen
+ filelist.append(filen)
+ os.rename(f, resdir + "psfsyncmasters-" + filen )
+ filelist.sort()
+ expectedlist = ['Bold-fontinfo.plist', 'Bold-lib.plist', 'BoldItalic-fontinfo.plist', 'Italic-fontinfo.plist']
+ if filelist != expectedlist:
+ print("None-standard output files: \n" + str(filelist))
+ print("Expected: \n" + str(expectedlist))
+ result = False
+ for f in filelist:
+ # Need to diff the plists with subprocess("diff") to be able handle openTypeHeadCreated issue
+ filen = "psfsyncmasters-" + f
+ diff = subprocess.Popen(["diff", resdir + filen, refdir + filen, "-c1"], stdout=subprocess.PIPE, stderr=subprocess.PIPE)
+ text = diff.communicate()
+ if diff.returncode == 1:
+ difftext = text[0].decode("utf-8").split("\n")
+ # Need to rule out only change being openTypeHeadCreated (which should be the case for fontinfo)
+ if not(difftext[4].strip() == "<key>openTypeHeadCreated</key>" and len(difftext) == 12):
+ print(filen + " different from reference")
+ for line in difftext: print(line)
+ result = False
+
+ diff = silfont.util.text_diff(resdir + "psfsyncmasters.log", refdir + "psfsyncmasters.log", ignore_chars=20)
+ if diff.returncode:
+ diff.print_text()
+ result = False
+
+ assert result
+
+if __name__ == "__main__":
+ test_run()
+ test_diffs() \ No newline at end of file
diff --git a/tests/ufo/test_88_psfufo2ttf.py b/tests/ufo/test_88_psfufo2ttf.py
new file mode 100644
index 0000000..e90373d
--- /dev/null
+++ b/tests/ufo/test_88_psfufo2ttf.py
@@ -0,0 +1,37 @@
+#!/usr/bin/env python
+'Test for psfufo2ttf'
+__url__ = 'http://github.com/silnrsi/pysilfont'
+__copyright__ = 'Copyright (c) 2018 SIL International (http://www.sil.org)'
+__license__ = 'Released under the MIT License (http://opensource.org/licenses/MIT)'
+__author__ = 'David Raymond'
+
+import silfont.util
+
+# Next 5 lines of code are test-specific
+import silfont.scripts.psfufo2ttf as testcommand
+testname = "psfufo2ttf"
+cl = "psfufo2ttf tests/input/font-psf-test/source/PsfTest-Regular.ufo " \
+ "local/testresults/ufo/psfufo2ttf.ttf -l local/testresults/ufo/psfufo2ttf.log"
+outfont = None
+diffexts = [".ttf", ".log"]
+exp_errors = 0 # These may need updating if the test ufo is updated
+exp_warnings = 0 # The test ufo should have some errors/warnings to test the code!
+
+# Code after this can be the same for most tests; if needed to be different for a test remove this comment!
+
+def test_run():
+ result = silfont.util.test_run("UFO", cl, testcommand, outfont, exp_errors, exp_warnings)
+ assert result
+
+def test_diffs(): # Generic function for all UFO tests
+ result = silfont.util.test_diffs("ufo", testname, diffexts)
+ assert result
+
+if __name__ == "__main__":
+ test_run()
+ test_diffs()
+
+
+
+
+
diff --git a/tests/ufo/test_99_psfnormalize.py b/tests/ufo/test_99_psfnormalize.py
new file mode 100644
index 0000000..0449d03
--- /dev/null
+++ b/tests/ufo/test_99_psfnormalize.py
@@ -0,0 +1,37 @@
+#!/usr/bin/env python
+''' Test of script named in testname below
+'''
+__url__ = 'http://github.com/silnrsi/pysilfont'
+__copyright__ = 'Copyright (c) 2018 SIL International (http://www.sil.org)'
+__license__ = 'Released under the MIT License (http://opensource.org/licenses/MIT)'
+__author__ = 'David Raymond'
+
+import silfont.util
+
+# Next 7 lines of code may be test-specific
+import silfont.scripts.psfnormalize as testcommand
+testname = "psfnormalize"
+cl = "psfnormalize tests/input/font-psf-test/source/PsfTest-Italic.ufo -l local/testresults/ufo/psfnormalize.log -p checkfix=fix"
+outfont = "local/testresults/ufo/psfnormalize.ufo" # Set to None for commands which don't output a font
+diffexts = [".ufo", ".log"] # List of extensions of all output files
+exp_errors = 0 # These may need updating if the test ufo is updated
+exp_warnings = 9 # The test ufo should have some errors/warnings to test the code!
+
+# Code after this can be the same for most/all tests; if needed to be different for a test remove this comment!
+
+def test_run():
+ result = silfont.util.test_run("UFO", cl, testcommand, outfont, exp_errors, exp_warnings)
+ assert result
+
+def test_diffs(): # Do a diff on all output files
+ result = silfont.util.test_diffs("ufo", testname, diffexts)
+ assert result
+
+if __name__ == "__main__":
+ test_run()
+ test_diffs()
+
+
+
+
+
diff --git a/update_headers.py b/update_headers.py
new file mode 100755
index 0000000..15c549b
--- /dev/null
+++ b/update_headers.py
@@ -0,0 +1,196 @@
+#!/usr/bin/env python
+'Checks for standard headers and update version and copyright info in python files'
+__url__ = 'http://github.com/silnrsi/pysilfont'
+__copyright__ = 'Copyright (c) 2016 SIL International (http://www.sil.org)'
+__license__ = 'Released under the MIT License (http://opensource.org/licenses/MIT)'
+__author__ = 'David Raymond'
+
+cyear = "2016" # Year to use if no other copyright year present
+
+from silfont.core import execute
+import os,sys
+
+argspec = [
+ ('action',{'help': 'Action - report or update', 'nargs': '?', 'default': 'report', 'choices': ('report','update')},{}),
+ ('-l','--log',{'help': 'Log file'}, {'type': 'outfile', 'def': 'local/update_headers.log'})]
+
+def doit(args) :
+ global file
+ action = args.action
+ params = args.paramsobj
+ logger=params.logger
+
+ varlist = ['url', 'copyright', 'license', 'author', 'version']
+
+ copyrightpre = 'Copyright (c) '
+ copyrightpost = ' SIL International (http://www.sil.org)'
+
+ standards = {
+ 'copyright': copyrightpre + cyear + copyrightpost,
+ 'version': params.sets['default']['version'],
+ 'url': 'http://github.com/silnrsi/pysilfont',
+ 'license': 'Released under the MIT License (http://opensource.org/licenses/MIT)'}
+
+ pythonfiles = {}
+ otherfiles = []
+
+ for subdir, dirs, files in os.walk("."):
+ if not (subdir=="." or subdir[0:5] in ("./lib","./scr")) : continue
+ if subdir[0:] == "./lib/pysilfont.egg-info" : continue
+
+ for filen in files:
+ if filen[-1:]=="~" : continue
+ if filen[-3:]=="pyc" : continue
+ if filen in ("__init__.py", "ez_setup.py") : continue
+ needver = (True if filen in ('setup.py', 'param.py') else False)
+ fulln = os.path.join(subdir,filen)
+ file = open(fulln,"r")
+ line1 = nextline()
+ pyline1 = (True if line1 in ("#!/usr/bin/env python", "#!/usr/bin/python") else False)
+ if pyline1 or filen[-3:] == ".py" :
+ # Look for standard headers
+ headererror = []
+ headers = "#!/usr/bin/env python"
+ if pyline1 :
+ # Read description which may be single or multiline
+ line = nextline()
+ headers = headers + "\n"+line
+ if line[0:3] == "'''" :
+ while line[-3:] != "'''" :
+ line = nextline()
+ if line =="EOF" : break # Must be EOF
+ headers = headers + "\n"+line
+ if line =="EOF" : headererror.append("No closing ''' to description")
+ elif line[0:1] != "'" : headererror.append("No description")
+ if headererror :
+ for line in headererror : logger.log(fulln + ": "+line,"E")
+ continue
+ # Read header variables
+ headvar={}
+ line = nextline()
+ while line[0:2] == "__" :
+ endn = line.find("__ = '")
+ if endn == -1 : std = headererror.append("Invalid variable line: " + line)
+ varn = line[2:endn]
+ val = line[endn+6:-1]
+ headvar[varn] = val
+ line = nextline()
+ # Check header variables
+ updatevars = {}
+ reportvars = {}
+ author = None
+ for varn in varlist :
+ if varn in headvar:
+ headval = headvar[varn]
+ if varn == 'author' : # Simply use existing author
+ author = headval
+ elif varn == "version" and not needver :
+ updatevars[varn] = "deleted"
+ elif varn == "copyright" : # Need to check dates and use oldest
+ # Find existing dates, assuming format 20nn and one or two dates
+ cdate = cyear
+ valid = True
+ datpos = headval.find("20")
+ if datpos != -1 :
+ # read any more digits
+ cdate='20'
+ nextpos = datpos+2
+ while headval[nextpos] in '0123456789' and nextpos < len(headval) :
+ cdate = cdate + headval[nextpos]
+ nextpos += 1
+ # Look for second date
+ rest = headval[nextpos:]
+ datpos = rest.find("20")
+ date2 = ""
+ if datpos != -1 :
+ date2 = '20'
+ nextpos = datpos+2
+ while rest[nextpos] in '0123456789' and nextpos < len(rest) :
+ date2 = date2 + rest[nextpos]
+ nextpos += 1
+ cval=int(cdate)
+ if cval < 2000 or cval > int(cyear) : valid = False
+ if date2 != "" :
+ val2 = int(date2)
+ if val2 < cval or val2 > int(cyear) : valid = False
+ if not valid : cdate = cyear
+ copyright = copyrightpre + cdate + copyrightpost
+ if headval != copyright :
+ updatevars[varn] = ("updated" if valid else "update (invalid dates)")
+ else :
+ if headval != standards[varn] :
+ updatevars[varn] = "updated"
+ else :
+ if varn == 'author' :
+ reportvars[varn] = "no author"
+ elif varn == "version" and not needver :
+ pass
+ else:
+ updatevars[varn] ="added"
+ for varn in headvar:
+ if varn not in varlist: reportvars[varn] = "non-standard"
+ else :
+ logger.log( fulln + ": " + "No python header - first line is " + line1, "E")
+ continue
+ else :
+ otherfiles.append(fulln)
+ continue
+
+ # Now have python file with no errors, so can update headers
+ if action == 'update' and updatevars :
+ logger.log("Updating "+fulln,"P")
+ outfile = open("update_headers_temp.txt", "w")
+ outfile.write(headers + "\n")
+ for varn in varlist :
+ if varn == "version" and not needver :
+ pass
+ elif varn == "author" :
+ if author : outfile.write("__author__ = '" + author + "'\n")
+ elif varn == "copyright" :
+ outfile.write("__copyright__ = '" + copyright + "'\n")
+ else:
+ outfile.write("__" + varn + "__ = '" + standards[varn] + "'\n")
+ if varn in updatevars :
+ reason = updatevars[varn]
+ if reason == "no author" :
+ logger.log("No author header variable ", "I")
+ else :
+ logger.log("Header variable " + varn + " " + reason, "I")
+ for varn in reportvars :
+ reason = reportvars[varn]
+ if reason == "non-standard" :
+ outfile.write("__" + varn + "__ = '" + headvar[varn] + "'\n")
+ logger.log("Non-standard header variable " + varn + " retained", "W")
+ else:
+ logger.log("No author header variable", "I")
+ # Write the rest of the file
+ outfile.write(line + "\n") # last line read checking headers
+ for line in file: outfile.write(line)
+ outfile.close()
+ file.close()
+ os.rename(fulln, fulln+"~")
+ os.rename("update_headers_temp.txt",fulln)
+ else :
+ for varn in updatevars :
+ logger.log(fulln + ": Header variable " + varn + " will be " + updatevars[varn], "I")
+ for varn in reportvars :
+ reason = reportvars[varn]
+ if reason == "non-standard" :
+ logger.log(fulln + ": Non-standard header variable " + varn + " present", "W")
+ else:
+ logger.log(fulln + ": No author header variable", "I")
+
+ print "\n"+"Non-python files"+"\n"
+ for filen in otherfiles:
+ print filen
+
+ return
+
+def nextline() :
+ global file
+ line = file.readline()
+ line = ("EOF" if line == "" else line.strip())
+ return line
+
+execute(None,doit, argspec)
+