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