anchorFix.py 16 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012
  1. """
  2. Fix glyph anchors for Roboto VF.
  3. Script uses lxml since ufoLib rearranges data.
  4. The script will do the following:
  5. 1. Deletes anchors used for design puposes e.g making glyphs built with
  6. components
  7. 2. Renames anchors so no custom MarkWriterFeature is needed for fontmake
  8. 3. Ensures each mark glyph only has 1 anchor which starts with an '_'
  9. """
  10. from __future__ import print_function
  11. import sys
  12. from lxml import etree
  13. import copy
  14. import os
  15. from glob import glob
  16. DUPLICATE_ANCHOR_GLYPHS = [
  17. "A",
  18. "A",
  19. "A.smcp",
  20. "A.smcp",
  21. "A.unic",
  22. "A.unic",
  23. "AE",
  24. "AE",
  25. "AE.smcp",
  26. "AE.smcp",
  27. "B",
  28. "B",
  29. "B.smcp",
  30. "B.smcp",
  31. "C",
  32. "C",
  33. "C.smcp",
  34. "C.smcp",
  35. "D",
  36. "D",
  37. "D.smcp",
  38. "D.smcp",
  39. "E",
  40. "E",
  41. "E.smcp",
  42. "E.smcp",
  43. "E.unic",
  44. "E.unic",
  45. "Eng",
  46. "Eng",
  47. "Eng.smcp",
  48. "Eng.smcp",
  49. "Epsilon1",
  50. "Epsilon1",
  51. "Esh",
  52. "Esh",
  53. "F",
  54. "F",
  55. "F.smcp",
  56. "F.smcp",
  57. "G",
  58. "G",
  59. "G.smcp",
  60. "G.smcp",
  61. "Gamma",
  62. "Gamma",
  63. "Gamma.smcp",
  64. "Gamma.smcp",
  65. "Gbar",
  66. "Gbar",
  67. "Gsmallcap",
  68. "Gsmallcap",
  69. "Gsmallcaphook",
  70. "Gsmallcaphook",
  71. "H",
  72. "H",
  73. "H.smcp",
  74. "H.smcp",
  75. "Hbar",
  76. "Hbar",
  77. "Hbar.smcp",
  78. "Hbar.smcp",
  79. "I",
  80. "I",
  81. "I.smcp",
  82. "I.smcp",
  83. "Ibar",
  84. "Ibar",
  85. "Ismallcap",
  86. "Ismallcap",
  87. "J",
  88. "J",
  89. "J.smcp",
  90. "J.smcp",
  91. "K",
  92. "K",
  93. "K.smcp",
  94. "K.smcp",
  95. "L",
  96. "L",
  97. "L.smcp",
  98. "L.smcp",
  99. "Lslash",
  100. "Lslash",
  101. "Lslash.smcp",
  102. "Lslash.smcp",
  103. "Lsmallcap",
  104. "Lsmallcap",
  105. "M",
  106. "M",
  107. "M.smcp",
  108. "M.smcp",
  109. "M.unic",
  110. "M.unic",
  111. "N",
  112. "N",
  113. "N.smcp",
  114. "N.smcp",
  115. "N.unic",
  116. "N.unic",
  117. "Nsmallcap",
  118. "Nsmallcap",
  119. "O",
  120. "O",
  121. "O.smcp",
  122. "O.smcp",
  123. "OE",
  124. "OE",
  125. "OEsmallcap",
  126. "OEsmallcap",
  127. "Ohorn",
  128. "Ohorn",
  129. "Oslash",
  130. "Oslash",
  131. "Oslash.smcp",
  132. "Oslash.smcp",
  133. "P",
  134. "P",
  135. "P.smcp",
  136. "P.smcp",
  137. "Q",
  138. "Q",
  139. "Q.smcp",
  140. "Q.smcp",
  141. "R",
  142. "R",
  143. "R.alt",
  144. "R.alt",
  145. "R.smcp",
  146. "R.smcp",
  147. "Rsmallcap",
  148. "Rsmallcap",
  149. "Rsmallcapinv",
  150. "Rsmallcapinv",
  151. "S",
  152. "S",
  153. "S.smcp",
  154. "S.smcp",
  155. "Schwa",
  156. "Schwa",
  157. "T",
  158. "T",
  159. "T.smcp",
  160. "T.smcp",
  161. "Thorn.smcp",
  162. "Thorn.smcp",
  163. "U",
  164. "U",
  165. "U.smcp",
  166. "U.smcp",
  167. "U.unic",
  168. "U.unic",
  169. "Uhorn",
  170. "Uhorn",
  171. "V",
  172. "V",
  173. "V.smcp",
  174. "V.smcp",
  175. "W",
  176. "W",
  177. "W.smcp",
  178. "W.smcp",
  179. "X",
  180. "X",
  181. "X.smcp",
  182. "X.smcp",
  183. "Y",
  184. "Y",
  185. "Y.smcp",
  186. "Y.smcp",
  187. "Ysmallcap",
  188. "Ysmallcap",
  189. "Z",
  190. "Z",
  191. "Z.smcp",
  192. "Z.smcp",
  193. "Zbar",
  194. "Zbar",
  195. "a",
  196. "a",
  197. "a_uni02DE",
  198. "a_uni02DE",
  199. "ae",
  200. "ae",
  201. "alpha",
  202. "alpha",
  203. "ascript",
  204. "ascript",
  205. "ascriptturn",
  206. "ascriptturn",
  207. "aturn",
  208. "aturn",
  209. "b",
  210. "b",
  211. "babygamma",
  212. "babygamma",
  213. "bbar",
  214. "bbar",
  215. "bbar_uni1ABE",
  216. "bbar_uni1ABE",
  217. "bhook",
  218. "bhook",
  219. "bullseye",
  220. "bullseye",
  221. "c",
  222. "c",
  223. "ccurl",
  224. "ccurl",
  225. "cstretch",
  226. "cstretch",
  227. "d",
  228. "d",
  229. "dcroat",
  230. "dcroat",
  231. "dcroat_uni1ABE",
  232. "dcroat_uni1ABE",
  233. "dhook",
  234. "dhook",
  235. "dotlessi",
  236. "dotlessi",
  237. "drthook",
  238. "drthook",
  239. "dyogh",
  240. "dyogh",
  241. "dz",
  242. "dz",
  243. "dzcurl",
  244. "dzcurl",
  245. "e",
  246. "e",
  247. "eng",
  248. "eng",
  249. "eng_uni1ABE",
  250. "eng_uni1ABE",
  251. "epsilon",
  252. "epsilon",
  253. "epsilon1",
  254. "epsilon1",
  255. "epsilon1rev",
  256. "epsilon1rev",
  257. "epsilon1revclosed",
  258. "epsilon1revclosed",
  259. "epsilon1revhook",
  260. "epsilon1revhook",
  261. "epsilonclosed",
  262. "epsilonclosed",
  263. "erev",
  264. "erev",
  265. "esh",
  266. "esh",
  267. "eshcurl",
  268. "eshcurl",
  269. "eshshortrev",
  270. "eshshortrev",
  271. "eta",
  272. "eta",
  273. "f",
  274. "f",
  275. "finalkaf",
  276. "finalkaf",
  277. "finalmem",
  278. "finalmem",
  279. "finalnun",
  280. "finalnun",
  281. "g",
  282. "g",
  283. "gamma1",
  284. "gamma1",
  285. "gbar",
  286. "gbar",
  287. "gbar_uni1ABE",
  288. "gbar_uni1ABE",
  289. "gcursive",
  290. "gcursive",
  291. "ghook",
  292. "ghook",
  293. "glottalstop",
  294. "glottalstop",
  295. "glottalstopbar",
  296. "glottalstopbar",
  297. "glottalstopbarrev",
  298. "glottalstopbarrev",
  299. "glottalstopinv",
  300. "glottalstopinv",
  301. "glottalstoprevinv",
  302. "glottalstoprevinv",
  303. "h",
  304. "h",
  305. "henghook",
  306. "henghook",
  307. "hhook",
  308. "hhook",
  309. "hturn",
  310. "hturn",
  311. "i",
  312. "i",
  313. "ibar",
  314. "ibar",
  315. "iota",
  316. "iota",
  317. "iota1",
  318. "iota1",
  319. "j",
  320. "j",
  321. "jcrosstail",
  322. "jcrosstail",
  323. "jdotlessbar",
  324. "jdotlessbar",
  325. "jhookdblbar",
  326. "jhookdblbar",
  327. "k",
  328. "k",
  329. "k.alt",
  330. "k.alt",
  331. "kgreenlandic",
  332. "kgreenlandic",
  333. "kturn",
  334. "kturn",
  335. "l",
  336. "l",
  337. "lbar",
  338. "lbar",
  339. "lbelt",
  340. "lbelt",
  341. "lmidtilde",
  342. "lmidtilde",
  343. "longs",
  344. "longs",
  345. "lrthook",
  346. "lrthook",
  347. "lslash",
  348. "lslash",
  349. "lyogh",
  350. "lyogh",
  351. "m",
  352. "m",
  353. "mhook",
  354. "mhook",
  355. "mturn",
  356. "mturn",
  357. "mturndescend",
  358. "mturndescend",
  359. "n",
  360. "n",
  361. "nlfthook",
  362. "nlfthook",
  363. "nrthook",
  364. "nrthook",
  365. "o",
  366. "o",
  367. "oe",
  368. "oe",
  369. "ohorn",
  370. "ohorn",
  371. "omega",
  372. "omega",
  373. "omegaclosed",
  374. "omegaclosed",
  375. "oopen",
  376. "oopen",
  377. "oslash",
  378. "oslash",
  379. "p",
  380. "p",
  381. "philatin",
  382. "philatin",
  383. "psi",
  384. "psi",
  385. "q",
  386. "q",
  387. "qhook",
  388. "qhook",
  389. "r",
  390. "r",
  391. "rdescend",
  392. "rdescend",
  393. "rfishhook",
  394. "rfishhook",
  395. "rfishhookrev",
  396. "rfishhookrev",
  397. "rho",
  398. "rho",
  399. "rrthook",
  400. "rrthook",
  401. "rturn",
  402. "rturn",
  403. "rturnascend",
  404. "rturnascend",
  405. "rturnrthook",
  406. "rturnrthook",
  407. "s",
  408. "s",
  409. "schwa",
  410. "schwa",
  411. "schwahook",
  412. "schwahook",
  413. "srthook",
  414. "srthook",
  415. "t",
  416. "t",
  417. "tccurl",
  418. "tccurl",
  419. "tesh",
  420. "tesh",
  421. "trthook",
  422. "trthook",
  423. "ts",
  424. "ts",
  425. "tturn",
  426. "tturn",
  427. "u",
  428. "u",
  429. "ubar",
  430. "ubar",
  431. "uhorn",
  432. "uhorn",
  433. "uni0069.ccmp",
  434. "uni0069.ccmp",
  435. "uni006A.ccmp",
  436. "uni006A.ccmp",
  437. "uni012F.ccmp",
  438. "uni012F.ccmp",
  439. "uni0237",
  440. "uni0237",
  441. "uni023D",
  442. "uni023D",
  443. "uni0243",
  444. "uni0243",
  445. "uni0244",
  446. "uni0244",
  447. "uni0248",
  448. "uni0248",
  449. "uni0249",
  450. "uni0249",
  451. "uni0249.ccmp",
  452. "uni0249.ccmp",
  453. "uni024C",
  454. "uni024C",
  455. "uni024D",
  456. "uni024D",
  457. "uni024E",
  458. "uni024E",
  459. "uni024F",
  460. "uni024F",
  461. "uni0268.ccmp",
  462. "uni0268.ccmp",
  463. "uni0292",
  464. "uni0292",
  465. "uni0293",
  466. "uni0293",
  467. "uni029D.ccmp",
  468. "uni029D.ccmp",
  469. "uni02A9",
  470. "uni02A9",
  471. "uni02AB",
  472. "uni02AB",
  473. "uni02AC",
  474. "uni02AC",
  475. "uni02AE",
  476. "uni02AE",
  477. "uni02B2.ccmp",
  478. "uni02B2.ccmp",
  479. "uni03D2",
  480. "uni03D2",
  481. "uni03D6",
  482. "uni03D6",
  483. "uni03F3.ccmp",
  484. "uni03F3.ccmp",
  485. "uni0404",
  486. "uni0404",
  487. "uni0404.smcp",
  488. "uni0404.smcp",
  489. "uni0416",
  490. "uni0416",
  491. "uni0416.smcp",
  492. "uni0416.smcp",
  493. "uni0417",
  494. "uni0417",
  495. "uni0417.smcp",
  496. "uni0417.smcp",
  497. "uni0418",
  498. "uni0418",
  499. "uni0418.smcp",
  500. "uni0418.smcp",
  501. "uni0423",
  502. "uni0423",
  503. "uni0423.smcp",
  504. "uni0423.smcp",
  505. "uni0427",
  506. "uni0427",
  507. "uni0427.smcp",
  508. "uni0427.smcp",
  509. "uni042B",
  510. "uni042B",
  511. "uni042B.smcp",
  512. "uni042B.smcp",
  513. "uni042D",
  514. "uni042D",
  515. "uni042D.smcp",
  516. "uni042D.smcp",
  517. "uni042E",
  518. "uni042E",
  519. "uni042E.smcp",
  520. "uni042E.smcp",
  521. "uni042F",
  522. "uni042F",
  523. "uni042F.smcp",
  524. "uni042F.smcp",
  525. "uni0432",
  526. "uni0432",
  527. "uni0433",
  528. "uni0433",
  529. "uni0434",
  530. "uni0434",
  531. "uni0436",
  532. "uni0436",
  533. "uni0437",
  534. "uni0437",
  535. "uni0438",
  536. "uni0438",
  537. "uni043A",
  538. "uni043A",
  539. "uni043B",
  540. "uni043B",
  541. "uni043C",
  542. "uni043C",
  543. "uni043D",
  544. "uni043D",
  545. "uni043F",
  546. "uni043F",
  547. "uni0442",
  548. "uni0442",
  549. "uni0444",
  550. "uni0444",
  551. "uni0446",
  552. "uni0446",
  553. "uni0447",
  554. "uni0447",
  555. "uni0448",
  556. "uni0448",
  557. "uni0449",
  558. "uni0449",
  559. "uni044B",
  560. "uni044B",
  561. "uni044D",
  562. "uni044D",
  563. "uni044E",
  564. "uni044E",
  565. "uni044F",
  566. "uni044F",
  567. "uni0454",
  568. "uni0454",
  569. "uni0456.ccmp",
  570. "uni0456.ccmp",
  571. "uni0458.ccmp",
  572. "uni0458.ccmp",
  573. "uni0460",
  574. "uni0460",
  575. "uni0461",
  576. "uni0461",
  577. "uni046F",
  578. "uni046F",
  579. "uni0472",
  580. "uni0472",
  581. "uni0473",
  582. "uni0473",
  583. "uni0474",
  584. "uni0474",
  585. "uni0475",
  586. "uni0475",
  587. "uni047B",
  588. "uni047B",
  589. "uni047F",
  590. "uni047F",
  591. "uni0480",
  592. "uni0480",
  593. "uni0481",
  594. "uni0481",
  595. "uni048A",
  596. "uni048A",
  597. "uni048B",
  598. "uni048B",
  599. "uni04A8",
  600. "uni04A8",
  601. "uni04A8.smcp",
  602. "uni04A8.smcp",
  603. "uni04A9",
  604. "uni04A9",
  605. "uni04BA",
  606. "uni04BA",
  607. "uni04BA.smcp",
  608. "uni04BA.smcp",
  609. "uni04D8",
  610. "uni04D8",
  611. "uni04D8.smcp",
  612. "uni04D8.smcp",
  613. "uni04E8.smcp",
  614. "uni04E8.smcp",
  615. "uni0504",
  616. "uni0504",
  617. "uni0506",
  618. "uni0506",
  619. "uni050A",
  620. "uni050A",
  621. "uni050C",
  622. "uni050C",
  623. "uni050D",
  624. "uni050D",
  625. "uni050E",
  626. "uni050E",
  627. "uni0510",
  628. "uni0510",
  629. "uni1D00",
  630. "uni1D00",
  631. "uni1D01",
  632. "uni1D01",
  633. "uni1D02",
  634. "uni1D02",
  635. "uni1D03",
  636. "uni1D03",
  637. "uni1D04",
  638. "uni1D04",
  639. "uni1D05",
  640. "uni1D05",
  641. "uni1D06",
  642. "uni1D06",
  643. "uni1D07",
  644. "uni1D07",
  645. "uni1D08",
  646. "uni1D08",
  647. "uni1D09",
  648. "uni1D09",
  649. "uni1D0A",
  650. "uni1D0A",
  651. "uni1D0B",
  652. "uni1D0B",
  653. "uni1D0C",
  654. "uni1D0C",
  655. "uni1D0D",
  656. "uni1D0D",
  657. "uni1D0E",
  658. "uni1D0E",
  659. "uni1D0F",
  660. "uni1D0F",
  661. "uni1D10",
  662. "uni1D10",
  663. "uni1D14",
  664. "uni1D14",
  665. "uni1D15",
  666. "uni1D15",
  667. "uni1D18",
  668. "uni1D18",
  669. "uni1D19",
  670. "uni1D19",
  671. "uni1D1A",
  672. "uni1D1A",
  673. "uni1D1B",
  674. "uni1D1B",
  675. "uni1D1C",
  676. "uni1D1C",
  677. "uni1D20",
  678. "uni1D20",
  679. "uni1D21",
  680. "uni1D21",
  681. "uni1D22",
  682. "uni1D22",
  683. "uni1D23",
  684. "uni1D23",
  685. "uni1D24",
  686. "uni1D24",
  687. "uni1D25",
  688. "uni1D25",
  689. "uni1D26",
  690. "uni1D26",
  691. "uni1D27",
  692. "uni1D27",
  693. "uni1D28",
  694. "uni1D28",
  695. "uni1D29",
  696. "uni1D29",
  697. "uni1D2A",
  698. "uni1D2A",
  699. "uni1D2B",
  700. "uni1D2B",
  701. "uni1D62.ccmp",
  702. "uni1D62.ccmp",
  703. "uni1D6B",
  704. "uni1D6B",
  705. "uni1D6C",
  706. "uni1D6C",
  707. "uni1D6D",
  708. "uni1D6D",
  709. "uni1D6E",
  710. "uni1D6E",
  711. "uni1D6F",
  712. "uni1D6F",
  713. "uni1D70",
  714. "uni1D70",
  715. "uni1D71",
  716. "uni1D71",
  717. "uni1D72",
  718. "uni1D72",
  719. "uni1D73",
  720. "uni1D73",
  721. "uni1D74",
  722. "uni1D74",
  723. "uni1D75",
  724. "uni1D75",
  725. "uni1D76",
  726. "uni1D76",
  727. "uni1D77",
  728. "uni1D77",
  729. "uni1D79",
  730. "uni1D79",
  731. "uni1D7A",
  732. "uni1D7A",
  733. "uni1D7C",
  734. "uni1D7C",
  735. "uni1D7D",
  736. "uni1D7D",
  737. "uni1D7E",
  738. "uni1D7E",
  739. "uni1D7F",
  740. "uni1D7F",
  741. "uni1D80",
  742. "uni1D80",
  743. "uni1D81",
  744. "uni1D81",
  745. "uni1D82",
  746. "uni1D82",
  747. "uni1D83",
  748. "uni1D83",
  749. "uni1D84",
  750. "uni1D84",
  751. "uni1D85",
  752. "uni1D85",
  753. "uni1D86",
  754. "uni1D86",
  755. "uni1D87",
  756. "uni1D87",
  757. "uni1D88",
  758. "uni1D88",
  759. "uni1D89",
  760. "uni1D89",
  761. "uni1D8A",
  762. "uni1D8A",
  763. "uni1D8B",
  764. "uni1D8B",
  765. "uni1D8C",
  766. "uni1D8C",
  767. "uni1D8D",
  768. "uni1D8D",
  769. "uni1D8E",
  770. "uni1D8E",
  771. "uni1D8F",
  772. "uni1D8F",
  773. "uni1D90",
  774. "uni1D90",
  775. "uni1D91",
  776. "uni1D91",
  777. "uni1D92",
  778. "uni1D92",
  779. "uni1D93",
  780. "uni1D93",
  781. "uni1D94",
  782. "uni1D94",
  783. "uni1D95",
  784. "uni1D95",
  785. "uni1D96",
  786. "uni1D96",
  787. "uni1D96.ccmp",
  788. "uni1D96.ccmp",
  789. "uni1D97",
  790. "uni1D97",
  791. "uni1D98",
  792. "uni1D98",
  793. "uni1D99",
  794. "uni1D99",
  795. "uni1D9A",
  796. "uni1D9A",
  797. "uni1DA4.ccmp",
  798. "uni1DA4.ccmp",
  799. "uni1DA8.ccmp",
  800. "uni1DA8.ccmp",
  801. "uni1E2C",
  802. "uni1E2C",
  803. "uni1E2D",
  804. "uni1E2D",
  805. "uni1E2E",
  806. "uni1E2E",
  807. "uni1E2F",
  808. "uni1E2F",
  809. "uni2071.ccmp",
  810. "uni2071.ccmp",
  811. "uni2C7C.ccmp",
  812. "uni2C7C.ccmp",
  813. "upsilon",
  814. "upsilon",
  815. "upsilonlatin",
  816. "upsilonlatin",
  817. "v",
  818. "v",
  819. "vscript",
  820. "vscript",
  821. "vturn",
  822. "vturn",
  823. "w",
  824. "w",
  825. "wturn",
  826. "wturn",
  827. "x",
  828. "x",
  829. "y",
  830. "y",
  831. "yturn",
  832. "yturn",
  833. "z",
  834. "z",
  835. "zbar",
  836. "zbar",
  837. "zcurl",
  838. "zcurl",
  839. "zrthook",
  840. "zrthook"
  841. # mkmk
  842. "uni0351",
  843. "uni0350",
  844. "uni0357",
  845. "uni035B",
  846. "uni0343",
  847. "uni0342",
  848. "acuterightnosp",
  849. "graveleftnosp",
  850. "uni0346",
  851. "diaeresistonosnosp",
  852. "uni034A",
  853. "overscoredblnosp",
  854. "tildevertsupnosp",
  855. "xsupnosp",
  856. "anglesupnosp",
  857. "uni030C_uni1ABB",
  858. "dieresisnosp_uni1ABB",
  859. "uni034C",
  860. "tildecomb_uni1ABB",
  861. "uni0352",
  862. "uni034B",
  863. "macroncomb_uni1ABB",
  864. "tildecomb_uni1ABC",
  865. "tildevertsupnosp",
  866. "overscoredblnosp",
  867. "xsupnosp",
  868. "anglesupnosp",
  869. "uni0357",
  870. "uni0352",
  871. "uni0350",
  872. "uni0351",
  873. "uni035B",
  874. "uni0346",
  875. "diaeresistonosnosp",
  876. "acuterightnosp",
  877. "uni034C",
  878. "uni034B",
  879. "tildecomb_uni1ABC",
  880. "dieresisnosp_uni1ABB",
  881. "tildecomb_uni1ABB",
  882. "uni0342",
  883. "uni0343",
  884. "graveleftnosp",
  885. "uni030C_uni1ABB",
  886. "macroncomb_uni1ABB",
  887. "uni034A"
  888. ]
  889. def duplicate_anchor(glyph, src, dst):
  890. outline = glyph.find('outline')
  891. src_anc = glyph.xpath("//point[@name='{}']".format(src))[0]
  892. dst_anc = glyph.xpath("//point[@name='{}']".format(dst))
  893. if not dst_anc:
  894. dst_anc = copy.deepcopy(src_anc.getparent())
  895. dst_anc.getchildren()[0].attrib['name'] = dst
  896. outline.append(dst_anc)
  897. def rename_anchor(glyph, src, dst):
  898. anc = glyph.xpath("//point[@name='{}']".format(src))
  899. if anc:
  900. anc[0].attrib['name'] = dst
  901. def delete_anchor(glyph, anc_name):
  902. anc = glyph.xpath("//point[@name='{}']".format(anc_name))
  903. if anc:
  904. anc = anc[0].getparent()
  905. anc.getparent().remove(anc)
  906. def _delete_design_anchors(glyph):
  907. anchors_to_delete = [
  908. "_ogonek",
  909. "_rhalfring",
  910. "_right",
  911. "_tonos",
  912. "_top",
  913. "_bottom",
  914. "_bottomu",
  915. "_caron",
  916. "_cross",
  917. "_dot",
  918. "_left",
  919. "ogonek",
  920. "rhalfring",
  921. "right",
  922. "tonos",
  923. "bottomu",
  924. "caron",
  925. "cross",
  926. "dot",
  927. "left"
  928. ]
  929. for anchor in anchors_to_delete:
  930. delete_anchor(glyph, anchor)
  931. def _rename_anchors(glyph):
  932. anchors = [
  933. ("_marktop", "_top"),
  934. ("_markbottom", "_bottom"),
  935. ("_marktop_dd", "_top_dd"),
  936. ("_markbottom_dd", "_bottom_dd"),
  937. ("_markrhotichook", "_rhotichook"),
  938. ("_marktop0315", "_top0315"),
  939. ("_markparent_top", "_parent_top"),
  940. ("_markparenthesses.w1", "_parenthesses.w1"),
  941. ("_markparenthesses.w2", "_parenthesses.w2"),
  942. ("_markparenthesses.w3", "_parenthesses.w3"),
  943. ("mkmktop", "top"),
  944. ("mkmkbottom_acc", "bottom"),
  945. ]
  946. for before_anchor, after_anchor in anchors:
  947. rename_anchor(glyph, before_anchor, after_anchor)
  948. def _script_already_used(glyph):
  949. """Check if a user has already executed the script on the .ufo.
  950. Executing the script multiple times on the same .ufo will lead to
  951. unforeseen modifications."""
  952. prev_added_anc = glyph.xpath("//point[@name='parent_top']")
  953. if prev_added_anc:
  954. return True
  955. return False
  956. def main(ufo_path):
  957. if not ufo_path.endswith('ufo'):
  958. raise Exception('{} is not a ufo'.format(ufo_path))
  959. glifs = glob(os.path.join(ufo_path, 'glyphs', '*.glif'))
  960. # check script has not already been run on this font
  961. a_glyph = etree.parse(os.path.join(ufo_path, 'glyphs', 'a.glif'))
  962. if _script_already_used(a_glyph):
  963. raise Exception('Script has already been used')
  964. for path in glifs:
  965. glyph = etree.parse(path)
  966. glyph_name = glyph.getroot().attrib['name']
  967. _delete_design_anchors(glyph)
  968. _rename_anchors(glyph)
  969. if glyph_name in ['cedilla', 'commaaccent', 'ogonek']:
  970. delete_anchor(glyph, 'bottom')
  971. if glyph_name in ['uni1ABB', 'uni1ABC']:
  972. delete_anchor(glyph, '_top')
  973. if glyph_name in DUPLICATE_ANCHOR_GLYPHS:
  974. duplicate_anchor(glyph, "top", "parent_top")
  975. glyph.write(path)
  976. print('Fixed anchors: {}'.format(ufo_path))
  977. if __name__ == '__main__':
  978. if len(sys.argv) != 2:
  979. raise Exception("Include path to ufo")
  980. else:
  981. ufo_path = sys.argv[1]
  982. main(sys.argv[1])