interpolatableTestContourOrder.py 2.7 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374
  1. from .interpolatableHelpers import *
  2. def test_contour_order(glyph0, glyph1):
  3. # We try matching both the StatisticsControlPen vector
  4. # and the StatisticsPen vector.
  5. #
  6. # If either method found a identity matching, accept it.
  7. # This is crucial for fonts like Kablammo[MORF].ttf and
  8. # Nabla[EDPT,EHLT].ttf, since they really confuse the
  9. # StatisticsPen vector because of their area=0 contours.
  10. n = len(glyph0.controlVectors)
  11. matching = None
  12. matching_cost = 0
  13. identity_cost = 0
  14. done = n <= 1
  15. if not done:
  16. m0Control = glyph0.controlVectors
  17. m1Control = glyph1.controlVectors
  18. (
  19. matching_control,
  20. matching_cost_control,
  21. identity_cost_control,
  22. ) = matching_for_vectors(m0Control, m1Control)
  23. done = matching_cost_control == identity_cost_control
  24. if not done:
  25. m0Green = glyph0.greenVectors
  26. m1Green = glyph1.greenVectors
  27. (
  28. matching_green,
  29. matching_cost_green,
  30. identity_cost_green,
  31. ) = matching_for_vectors(m0Green, m1Green)
  32. done = matching_cost_green == identity_cost_green
  33. if not done:
  34. # See if reversing contours in one master helps.
  35. # That's a common problem. Then the wrong_start_point
  36. # test will fix them.
  37. #
  38. # Reverse the sign of the area (0); the rest stay the same.
  39. if not done:
  40. m1ControlReversed = [(-m[0],) + m[1:] for m in m1Control]
  41. (
  42. matching_control_reversed,
  43. matching_cost_control_reversed,
  44. identity_cost_control_reversed,
  45. ) = matching_for_vectors(m0Control, m1ControlReversed)
  46. done = matching_cost_control_reversed == identity_cost_control_reversed
  47. if not done:
  48. m1GreenReversed = [(-m[0],) + m[1:] for m in m1Green]
  49. (
  50. matching_control_reversed,
  51. matching_cost_control_reversed,
  52. identity_cost_control_reversed,
  53. ) = matching_for_vectors(m0Control, m1ControlReversed)
  54. done = matching_cost_control_reversed == identity_cost_control_reversed
  55. if not done:
  56. # Otherwise, use the worst of the two matchings.
  57. if (
  58. matching_cost_control / identity_cost_control
  59. < matching_cost_green / identity_cost_green
  60. ):
  61. matching = matching_control
  62. matching_cost = matching_cost_control
  63. identity_cost = identity_cost_control
  64. else:
  65. matching = matching_green
  66. matching_cost = matching_cost_green
  67. identity_cost = identity_cost_green
  68. return matching, matching_cost, identity_cost