1cb93a386Sopenharmony_ci<html>
2cb93a386Sopenharmony_ci<head>
3cb93a386Sopenharmony_ci<div height="0" hidden="true">
4cb93a386Sopenharmony_ci<div id="bug8380">
5cb93a386Sopenharmony_ciSkDCubic::ComplexBreak
6cb93a386Sopenharmony_ci{{{126, 9.396100044250488281}, {125.6320571899414063, 9.295844078063964844}, {125.1227340698242188, 9.337338447570800781}, {124.6031646728515625, 9.379667282104492188}}},
7cb93a386Sopenharmony_ciinflectionsTs[0]=0.999997776 {{{126.1618761931709827, 9.252680507258252973}, {123.04446008475567, 9.506653492188940291}}},
8cb93a386Sopenharmony_ciSkDCubic::ComplexBreak
9cb93a386Sopenharmony_ci{{{124.6031646728515625, 9.379667282104492188}, {124.1427383422851563, 9.417178153991699219}, {123.6742630004882813, 9.45534515380859375}, {123.28900146484375, 9.396100044250488281}}},
10cb93a386Sopenharmony_ciinflectionsTs[0]=4.14921088e-06 {{{125.984438133710114, 9.267135117035042668}, {123.2218797495565639, 9.492200381017113386}}},
11cb93a386Sopenharmony_cimaxCurvature[0]=0.0817322831 {{{125.8735553329735666, 9.277935394706121386}, {123.1067608854740314, 9.499713475347833835}}},
12cb93a386Sopenharmony_ciSkDCubic::ComplexBreak
13cb93a386Sopenharmony_ci{{{126, 9.396200180053710938}, {125.305999755859375, 9.206999778747558594}, {124.1090011596679688, 9.522199630737304688}, {123.28900146484375, 9.396200180053710938}}},
14cb93a386Sopenharmony_ciinflectionsTs[0]=0.530286644 {{{127.5428560571536707, 9.140180090182106198}, {121.6628069847287179, 9.619260454379688241}}},
15cb93a386Sopenharmony_cimaxCurvature[0]=0.568563182 {{{127.4346914043237859, 9.15278490094694952}, {121.5456828946143446, 9.624913158409162506}}},
16cb93a386Sopenharmony_ciseg=1 {{{0, 353.891998f}, {126, 9.39610004f}}}
17cb93a386Sopenharmony_ciseg=2 {{{126, 9.39610004f}, {125.632057f, 9.29584408f}, {125.122734f, 9.33733845f}, {124.603165f, 9.37966728f}}}
18cb93a386Sopenharmony_ciseg=3 {{{124.603165f, 9.37966728f}, {124.142731f, 9.41717815f}, {123.674263f, 9.45534515f}, {123.289001f, 9.39610004f}}}
19cb93a386Sopenharmony_ciseg=4 {{{123.289001f, 9.39610004f}, {118.119003f, 8.07219982f}}}
20cb93a386Sopenharmony_ciseg=5 {{{118.119003f, 8.07219982f}, {8.17210007f, 104.212997f}}}
21cb93a386Sopenharmony_ciseg=6 {{{8.17210007f, 104.212997f}, {0, 259.298737f}}}
22cb93a386Sopenharmony_ciseg=7 {{{0, 259.298737f}, {0, 353.891998f}}}
23cb93a386Sopenharmony_ciop sect
24cb93a386Sopenharmony_ciseg=8 {{{8.17210007f, 104.212997f}, {-5.82350016f, 369.813995f}}}
25cb93a386Sopenharmony_ciseg=9 {{{-5.82350016f, 369.813995f}, {126, 9.39620018f}}}
26cb93a386Sopenharmony_ciseg=10 {{{126, 9.39620018f}, {125.631981f, 9.29586983f}, {125.12252f, 9.3373785f}, {124.602829f, 9.37972069f}}}
27cb93a386Sopenharmony_ciseg=11 {{{124.602829f, 9.37972069f}, {124.142509f, 9.41722488f}, {123.674164f, 9.45538425f}, {123.289001f, 9.39620018f}}}
28cb93a386Sopenharmony_ciseg=12 {{{123.289001f, 9.39620018f}, {118.119003f, 8.07219982f}}}
29cb93a386Sopenharmony_ciseg=13 {{{118.119003f, 8.07219982f}, {8.17210007f, 104.212997f}}}
30cb93a386Sopenharmony_cidebugShowLineIntersection wtTs[0]=1 {{{8.17210007,104.212997}, {-5.82350016,369.813995}}} {{-5.82350016,369.813995}} wnTs[0]=0 {{{-5.82350016,369.813995}, {126,9.39620018}}}
31cb93a386Sopenharmony_cidebugShowLineIntersection wtTs[0]=0 {{{8.17210007,104.212997}, {-5.82350016,369.813995}}} {{8.17210007,104.212997}} wnTs[0]=1 {{{118.119003,8.07219982}, {8.17210007,104.212997}}}
32cb93a386Sopenharmony_cidebugShowCubicLineIntersection wtTs[0]=0 {{{126,9.39620018}, {125.631981,9.29586983}, {125.12252,9.3373785}, {124.602829,9.37972069}}} {{126,9.39620018}} wnTs[0]=1 {{{-5.82350016,369.813995}, {126,9.39620018}}}
33cb93a386Sopenharmony_cidebugShowCubicLineIntersection no intersect {{{124.602829,9.37972069}, {124.142509,9.41722488}, {123.674164,9.45538425}, {123.289001,9.39620018}}} {{{-5.82350016,369.813995}, {126,9.39620018}}}
34cb93a386Sopenharmony_cidebugShowLineIntersection no intersect {{{-5.82350016,369.813995}, {126,9.39620018}}} {{{123.289001,9.39620018}, {118.119003,8.07219982}}}
35cb93a386Sopenharmony_cidebugShowLineIntersection no intersect {{{-5.82350016,369.813995}, {126,9.39620018}}} {{{118.119003,8.07219982}, {8.17210007,104.212997}}}
36cb93a386Sopenharmony_cidebugShowCubicIntersection wtTs[0]=1 {{{126,9.39620018}, {125.631981,9.29586983}, {125.12252,9.3373785}, {124.602829,9.37972069}}} {{124.602829,9.37972069}} wnTs[0]=0 {{{124.602829,9.37972069}, {124.142509,9.41722488}, {123.674164,9.45538425}, {123.289001,9.39620018}}}
37cb93a386Sopenharmony_cidebugShowCubicLineIntersection wtTs[0]=1 {{{124.602829,9.37972069}, {124.142509,9.41722488}, {123.674164,9.45538425}, {123.289001,9.39620018}}} {{123.289001,9.39620018}} wnTs[0]=0 {{{123.289001,9.39620018}, {118.119003,8.07219982}}}
38cb93a386Sopenharmony_cidebugShowLineIntersection wtTs[0]=1 {{{123.289001,9.39620018}, {118.119003,8.07219982}}} {{118.119003,8.07219982}} wnTs[0]=0 {{{118.119003,8.07219982}, {8.17210007,104.212997}}}
39cb93a386Sopenharmony_cidebugShowLineIntersection no intersect {{{8.17210007,104.212997}, {-5.82350016,369.813995}}} {{{0,353.891998}, {126,9.39610004}}}
40cb93a386Sopenharmony_cidebugShowLineIntersection wtTs[0]=0 {{{8.17210007,104.212997}, {-5.82350016,369.813995}}} {{8.17210007,104.212997}} wnTs[0]=1 {{{118.119003,8.07219982}, {8.17210007,104.212997}}}
41cb93a386Sopenharmony_cidebugShowLineIntersection wtTs[0]=0 {{{8.17210007,104.212997}, {-5.82350016,369.813995}}} {{8.17210007,104.212997}} wtTs[1]=0.583904956 {{0,259.298737}} wnTs[0]=0 {{{8.17210007,104.212997}, {0,259.298737}}} wnTs[1]=1
42cb93a386Sopenharmony_ciSkOpSegment::addT insert t=0.583904956 segID=8 spanID=27
43cb93a386Sopenharmony_cidebugShowLineIntersection wtTs[0]=0.583904956 {{{8.17210007,104.212997}, {-5.82350016,369.813995}}} {{0,259.298737}} wnTs[0]=0 {{{0,259.298737}, {0,353.891998}}}
44cb93a386Sopenharmony_cidebugShowLineIntersection wtTs[0]=0.0441765002 {{{-5.82350016,369.813995}, {126,9.39620018}}} {{0,353.891998}} wtTs[1]=1 {{126,9.39620018}} wnTs[0]=0 {{{0,353.891998}, {126,9.39610004}}} wnTs[1]=0.999999744
45cb93a386Sopenharmony_ciSkOpSegment::addT insert t=0.0441765002 segID=9 spanID=28
46cb93a386Sopenharmony_cidebugShowCubicLineIntersection no intersect {{{124.603165,9.37966728}, {124.142731,9.41717815}, {123.674263,9.45534515}, {123.289001,9.39610004}}} {{{-5.82350016,369.813995}, {126,9.39620018}}}
47cb93a386Sopenharmony_cidebugShowLineIntersection no intersect {{{-5.82350016,369.813995}, {126,9.39620018}}} {{{118.119003,8.07219982}, {8.17210007,104.212997}}}
48cb93a386Sopenharmony_cidebugShowLineIntersection no intersect {{{-5.82350016,369.813995}, {126,9.39620018}}} {{{8.17210007,104.212997}, {0,259.298737}}}
49cb93a386Sopenharmony_cidebugShowLineIntersection wtTs[0]=0.0441765002 {{{-5.82350016,369.813995}, {126,9.39620018}}} {{0,353.891998}} wnTs[0]=1 {{{0,259.298737}, {0,353.891998}}}
50cb93a386Sopenharmony_cidebugShowCubicLineIntersection wtTs[0]=0 {{{126,9.39620018}, {125.631981,9.29586983}, {125.12252,9.3373785}, {124.602829,9.37972069}}} {{126,9.39620018}} wnTs[0]=1 {{{0,353.891998}, {126,9.39610004}}}
51cb93a386Sopenharmony_ci-1=(0.375,0.5) [-1]
52cb93a386Sopenharmony_ciSkTSect::addForPerp addBounded span=-1 opp=-1
53cb93a386Sopenharmony_ci-1=(0.5,0.625) [-1]
54cb93a386Sopenharmony_ciSkTSect::addForPerp addBounded span=-1 opp=-1
55cb93a386Sopenharmony_ci-1=(0.625,0.75) [-1]
56cb93a386Sopenharmony_ciSkTSect::addForPerp addBounded span=-1 opp=-1
57cb93a386Sopenharmony_ci-1=(0.75,0.8125) [-1]
58cb93a386Sopenharmony_ciSkTSect::addForPerp addBounded span=-1 opp=-1
59cb93a386Sopenharmony_ci-1=(0.8125,0.875) [-1]
60cb93a386Sopenharmony_ciSkTSect::addForPerp addBounded span=-1 opp=-1
61cb93a386Sopenharmony_ci-1=(0.875,0.9375) [-1]
62cb93a386Sopenharmony_ciSkTSect::addForPerp addBounded span=-1 opp=-1
63cb93a386Sopenharmony_ciSkTSect::addForPerp priorSpan=-1 t=0.937702598 opp=-1
64cb93a386Sopenharmony_ci-1=(0.9375,1) []
65cb93a386Sopenharmony_ciSkTSect::addForPerp addBounded span=-1 opp=-1
66cb93a386Sopenharmony_cidebugShowCubicIntersection wtTs[0]=0.307128906 {{{126,9.39620018}, {125.631981,9.29586983}, {125.12252,9.3373785}, {124.602829,9.37972069}}} {{125.624687,9.33981037}} wtTs[1]=0.9375 {{124.700119,9.37182617}} wnTs[0]=0.307191 {{{126,9.39610004}, {125.632057,9.29584408}, {125.122734,9.33733845}, {124.603165,9.37966728}}} wnTs[1]=0.937702598
67cb93a386Sopenharmony_ciSkOpSegment::addT insert t=0.307128906 segID=10 spanID=29
68cb93a386Sopenharmony_ciSkOpSegment::addT insert t=0.307190555 segID=2 spanID=30
69cb93a386Sopenharmony_ciSkOpSegment::addT insert t=0.9375 segID=10 spanID=31
70cb93a386Sopenharmony_ciSkOpSegment::addT insert t=0.937702598 segID=2 spanID=32
71cb93a386Sopenharmony_cidebugShowCubicIntersection no intersect {{{126,9.39620018}, {125.631981,9.29586983}, {125.12252,9.3373785}, {124.602829,9.37972069}}} {{{124.603165,9.37966728}, {124.142731,9.41717815}, {123.674263,9.45534515}, {123.289001,9.39610004}}}
72cb93a386Sopenharmony_cidebugShowCubicLineIntersection no intersect {{{124.602829,9.37972069}, {124.142509,9.41722488}, {123.674164,9.45538425}, {123.289001,9.39620018}}} {{{0,353.891998}, {126,9.39610004}}}
73cb93a386Sopenharmony_ci-1=(0.125,0.1875) [-1]
74cb93a386Sopenharmony_ciSkTSect::addForPerp addBounded span=-1 opp=-1
75cb93a386Sopenharmony_ci-1=(0.1875,0.25) [-1]
76cb93a386Sopenharmony_ciSkTSect::addForPerp addBounded span=-1 opp=-1
77cb93a386Sopenharmony_ci-1=(0.25,0.375) [-1]
78cb93a386Sopenharmony_ciSkTSect::addForPerp addBounded span=-1 opp=-1
79cb93a386Sopenharmony_ci-1=(0.375,0.5) [-1]
80cb93a386Sopenharmony_ciSkTSect::addForPerp addBounded span=-1 opp=-1
81cb93a386Sopenharmony_ci-1=(0.5,0.625) [-1]
82cb93a386Sopenharmony_ciSkTSect::addForPerp addBounded span=-1 opp=-1
83cb93a386Sopenharmony_ci-1=(0.625,0.75) [-1]
84cb93a386Sopenharmony_ciSkTSect::addForPerp addBounded span=-1 opp=-1
85cb93a386Sopenharmony_cidebugShowCubicIntersection wtTs[0]=0.0625 {{{124.602829,9.37972069}, {124.142509,9.41722488}, {123.674164,9.45538425}, {123.289001,9.39620018}}} {{124.516449,9.38673687}} wtTs[1]=0.625 {{123.752594,9.4268837}} wnTs[0]=0.0627287 {{{124.603165,9.37966728}, {124.142731,9.41717815}, {123.674263,9.45534515}, {123.289001,9.39610004}}} wnTs[1]=0.625091708
86cb93a386Sopenharmony_ciSkOpSegment::addT insert t=0.0625 segID=11 spanID=33
87cb93a386Sopenharmony_ciSkOpSegment::addT insert t=0.0627286673 segID=3 spanID=34
88cb93a386Sopenharmony_ciSkOpSegment::addT insert t=0.625 segID=11 spanID=35
89cb93a386Sopenharmony_ciSkOpSegment::addT insert t=0.625091708 segID=3 spanID=36
90cb93a386Sopenharmony_cidebugShowCubicLineIntersection no intersect {{{124.602829,9.37972069}, {124.142509,9.41722488}, {123.674164,9.45538425}, {123.289001,9.39620018}}} {{{123.289001,9.39610004}, {118.119003,8.07219982}}}
91cb93a386Sopenharmony_cidebugShowLineIntersection no intersect {{{123.289001,9.39620018}, {118.119003,8.07219982}}} {{{0,353.891998}, {126,9.39610004}}}
92cb93a386Sopenharmony_cidebugShowCubicLineIntersection wtTs[0]=0.999978653 {{{124.603165,9.37966728}, {124.142731,9.41717815}, {123.674263,9.45534515}, {123.289001,9.39610004}}} {{123.289001,9.39620018}} wnTs[0]=0 {{{123.289001,9.39620018}, {118.119003,8.07219982}}}
93cb93a386Sopenharmony_cidebugShowLineIntersection wtTs[0]=4.65488731e-06 {{{123.289001,9.39620018}, {118.119003,8.07219982}}} {{123.289001,9.39610004}} wtTs[1]=1 {{118.119003,8.07219982}} wnTs[0]=0 {{{123.289001,9.39610004}, {118.119003,8.07219982}}} wnTs[1]=1
94cb93a386Sopenharmony_cidebugShowLineIntersection wtTs[0]=1 {{{123.289001,9.39620018}, {118.119003,8.07219982}}} {{118.119003,8.07219982}} wnTs[0]=0 {{{118.119003,8.07219982}, {8.17210007,104.212997}}}
95cb93a386Sopenharmony_cidebugShowLineIntersection no intersect {{{118.119003,8.07219982}, {8.17210007,104.212997}}} {{{0,353.891998}, {126,9.39610004}}}
96cb93a386Sopenharmony_cidebugShowLineIntersection wtTs[0]=0 {{{118.119003,8.07219982}, {8.17210007,104.212997}}} {{118.119003,8.07219982}} wnTs[0]=1 {{{123.289001,9.39610004}, {118.119003,8.07219982}}}
97cb93a386Sopenharmony_cidebugShowLineIntersection wtTs[0]=0 {{{118.119003,8.07219982}, {8.17210007,104.212997}}} {{118.119003,8.07219982}} wtTs[1]=1 {{8.17210007,104.212997}} wnTs[0]=0 {{{118.119003,8.07219982}, {8.17210007,104.212997}}} wnTs[1]=1
98cb93a386Sopenharmony_cidebugShowLineIntersection wtTs[0]=1 {{{118.119003,8.07219982}, {8.17210007,104.212997}}} {{8.17210007,104.212997}} wnTs[0]=0 {{{8.17210007,104.212997}, {0,259.298737}}}
99cb93a386Sopenharmony_cidebugShowCubicLineIntersection wtTs[0]=0 {{{126,9.39610004}, {125.632057,9.29584408}, {125.122734,9.33733845}, {124.603165,9.37966728}}} {{126,9.39610004}} wnTs[0]=1 {{{0,353.891998}, {126,9.39610004}}}
100cb93a386Sopenharmony_cidebugShowCubicLineIntersection no intersect {{{124.603165,9.37966728}, {124.142731,9.41717815}, {123.674263,9.45534515}, {123.289001,9.39610004}}} {{{0,353.891998}, {126,9.39610004}}}
101cb93a386Sopenharmony_cidebugShowLineIntersection no intersect {{{0,353.891998}, {126,9.39610004}}} {{{123.289001,9.39610004}, {118.119003,8.07219982}}}
102cb93a386Sopenharmony_cidebugShowLineIntersection no intersect {{{0,353.891998}, {126,9.39610004}}} {{{118.119003,8.07219982}, {8.17210007,104.212997}}}
103cb93a386Sopenharmony_cidebugShowLineIntersection no intersect {{{0,353.891998}, {126,9.39610004}}} {{{8.17210007,104.212997}, {0,259.298737}}}
104cb93a386Sopenharmony_cidebugShowLineIntersection wtTs[0]=0 {{{0,353.891998}, {126,9.39610004}}} {{0,353.891998}} wnTs[0]=1 {{{0,259.298737}, {0,353.891998}}}
105cb93a386Sopenharmony_cidebugShowCubicIntersection wtTs[0]=1 {{{126,9.39610004}, {125.632057,9.29584408}, {125.122734,9.33733845}, {124.603165,9.37966728}}} {{124.603165,9.37966728}} wnTs[0]=0 {{{124.603165,9.37966728}, {124.142731,9.41717815}, {123.674263,9.45534515}, {123.289001,9.39610004}}}
106cb93a386Sopenharmony_cidebugShowCubicLineIntersection wtTs[0]=1 {{{124.603165,9.37966728}, {124.142731,9.41717815}, {123.674263,9.45534515}, {123.289001,9.39610004}}} {{123.289001,9.39610004}} wnTs[0]=0 {{{123.289001,9.39610004}, {118.119003,8.07219982}}}
107cb93a386Sopenharmony_cidebugShowLineIntersection wtTs[0]=1 {{{123.289001,9.39610004}, {118.119003,8.07219982}}} {{118.119003,8.07219982}} wnTs[0]=0 {{{118.119003,8.07219982}, {8.17210007,104.212997}}}
108cb93a386Sopenharmony_cidebugShowLineIntersection wtTs[0]=1 {{{118.119003,8.07219982}, {8.17210007,104.212997}}} {{8.17210007,104.212997}} wnTs[0]=0 {{{8.17210007,104.212997}, {0,259.298737}}}
109cb93a386Sopenharmony_cidebugShowLineIntersection wtTs[0]=1 {{{8.17210007,104.212997}, {0,259.298737}}} {{0,259.298737}} wnTs[0]=0 {{{0,259.298737}, {0,353.891998}}}
110cb93a386Sopenharmony_ci----------------x-x--x-x-------------- addExpanded
111cb93a386Sopenharmony_ci00:  coinSeg/Span/PtT=2/3/3 endSpan=30 oppSeg/Span/PtT=10/19/19 oppEndSpan=29 MissingCoin
112cb93a386Sopenharmony_ci01:  coinSeg/Span/PtT=3/36/36 endSpan=6 oppSeg/Span/PtT=11/35/35 oppEndSpan=22 MissingCoin
113cb93a386Sopenharmony_ci02:  coinSeg/Span/PtT=5/9/9 endSpan=10 oppSeg/Span/PtT=13/25/25 oppEndSpan=26 MissingCoin
114cb93a386Sopenharmony_ci03:  coinSeg/Span/PtT=2/3/3 endSpan=30 oppSeg/Span/PtT=10/19/19 oppEndSpan=29 MissingCoin
115cb93a386Sopenharmony_ci04:  coinSeg/Span/PtT=3/36/36 endSpan=6 oppSeg/Span/PtT=11/35/35 oppEndSpan=22 MissingCoin
116cb93a386Sopenharmony_ci05:  coinSeg/Span/PtT=5/9/9 endSpan=10 oppSeg/Span/PtT=13/25/25 oppEndSpan=26 MissingCoin
117cb93a386Sopenharmony_ci06:  coinSeg/Span/PtT=10/19/19 endSpan=29 oppSeg/Span/PtT=2/3/3 oppEndSpan=30 MissingCoin
118cb93a386Sopenharmony_ci07:  coinSeg/Span/PtT=11/35/35 endSpan=22 oppSeg/Span/PtT=3/36/36 oppEndSpan=6 MissingCoin
119cb93a386Sopenharmony_ci08:  coinSeg/Span/PtT=10/19/19 endSpan=29 oppSeg/Span/PtT=2/3/3 oppEndSpan=30 MissingCoin
120cb93a386Sopenharmony_ci09:  coinSeg/Span/PtT=11/35/35 endSpan=22 oppSeg/Span/PtT=3/36/36 oppEndSpan=6 MissingCoin
121cb93a386Sopenharmony_ci10:  coinSeg/Span/PtT=11/33/33 endSpan=6 oppSeg/Span/PtT=11/22/22 oppEndSpan=6 ExpandCoin
122cb93a386Sopenharmony_ci11:  coinSeg/Span/PtT=2/30/30 endSpan=19 oppSeg/Span/PtT=2/3/3 oppEndSpan=19 ExpandCoin
123cb93a386Sopenharmony_ci12:  seg/base=13/25 seg/base=5/9 MarkCoinStart
124cb93a386Sopenharmony_ci13:  seg/base=13/26 seg/base=5/10 MarkCoinEnd
125cb93a386Sopenharmony_ci14:  seg/base=4/7 seg/base=12/23 MarkCoinStart
126cb93a386Sopenharmony_ci15:  seg/base=4/8 seg/base=12/24 MarkCoinEnd
127cb93a386Sopenharmony_ci16:  seg/base=11/33 seg/base=3/34 MarkCoinStart
128cb93a386Sopenharmony_ci17:  seg/base=11/35 seg/base=3/36 MarkCoinEnd
129cb93a386Sopenharmony_ci18:  seg/base=2/30 seg/base=10/29 MarkCoinStart
130cb93a386Sopenharmony_ci19:  seg/base=2/32 seg/base=10/31 MarkCoinEnd
131cb93a386Sopenharmony_ci20:  seg/base=9/28 seg/base=1/1 MarkCoinStart
132cb93a386Sopenharmony_ci21:  seg/base=9/18 seg/base=1/2 MarkCoinEnd
133cb93a386Sopenharmony_ci22:  seg/base=8/15 seg/base=6/11 MarkCoinStart
134cb93a386Sopenharmony_ci23:  seg/base=8/27 seg/base=6/12 MarkCoinEnd
135cb93a386Sopenharmony_ciSkOpSegment::debugShowActiveSpans id=8 (8.17210007,104.212997 -2.71619996e-07,259.298737) t=0 tEnd=0.583904956 windSum=? windValue=1
136cb93a386Sopenharmony_ciSkOpSegment::debugShowActiveSpans id=8 (-2.71619996e-07,259.298737 -5.82350016,369.813995) t=0.583904956 tEnd=1 windSum=? windValue=1
137cb93a386Sopenharmony_ciSkOpSegment::debugShowActiveSpans id=9 (-5.82350016,369.813995 7.26031715e-07,353.891998) t=0 tEnd=0.0441765002 windSum=? windValue=1
138cb93a386Sopenharmony_ciSkOpSegment::debugShowActiveSpans id=9 (7.26031715e-07,353.891998 126,9.39620018) t=0.0441765002 tEnd=1 windSum=? windValue=1
139cb93a386Sopenharmony_ciSkOpSegment::debugShowActiveSpans id=10 (126,9.39620018 125.886971,9.36538583 125.760599,9.34795095 125.624687,9.33981037) t=0 tEnd=0.307128906 windSum=? windValue=1
140cb93a386Sopenharmony_ciSkOpSegment::debugShowActiveSpans id=10 (125.624687,9.33981037 125.345733,9.32310212 125.026588,9.34554777 124.700119,9.37182617) t=0.307128906 tEnd=0.9375 windSum=? windValue=1
141cb93a386Sopenharmony_ciSkOpSegment::debugShowActiveSpans id=10 (124.700119,9.37182617 124.66775,9.37443162 124.63531,9.3770743 124.602829,9.37972069) t=0.9375 tEnd=1 windSum=? windValue=1
142cb93a386Sopenharmony_ciSkOpSegment::debugShowActiveSpans id=11 (124.602829,9.37972069 124.574059,9.3820647 124.545259,9.38441166 124.516449,9.38673687) t=0 tEnd=0.0625 windSum=? windValue=1
143cb93a386Sopenharmony_ciSkOpSegment::debugShowActiveSpans id=11 (124.516449,9.38673687 124.257155,9.40766372 123.997126,9.42685982 123.752594,9.4268837) t=0.0625 tEnd=0.625 windSum=? windValue=1
144cb93a386Sopenharmony_ciSkOpSegment::debugShowActiveSpans id=11 (123.752594,9.4268837 123.589573,9.42689962 123.433437,9.41839421 123.289001,9.39620018) t=0.625 tEnd=1 windSum=? windValue=1
145cb93a386Sopenharmony_ciSkOpSegment::debugShowActiveSpans id=12 (123.289001,9.39620018 118.119003,8.07219982) t=0 tEnd=1 windSum=? windValue=1
146cb93a386Sopenharmony_ciSkOpSegment::debugShowActiveSpans id=13 (118.119003,8.07219982 8.17210007,104.212997) t=0 tEnd=1 windSum=? windValue=1
147cb93a386Sopenharmony_ciSkOpSegment::debugShowActiveSpans id=1 (0,353.891998 126,9.39610004) t=0 tEnd=1 windSum=? windValue=1
148cb93a386Sopenharmony_ciSkOpSegment::debugShowActiveSpans id=2 (126,9.39610004 125.886971,9.36530236 125.760605,9.34788101 125.624695,9.33975124) t=0 tEnd=0.307190555 windSum=? windValue=1
149cb93a386Sopenharmony_ciSkOpSegment::debugShowActiveSpans id=2 (125.624695,9.33975124 125.345738,9.3230648 125.026588,9.34552196 124.700119,9.37180042) t=0.307190555 tEnd=0.937702598 windSum=? windValue=1
150cb93a386Sopenharmony_ciSkOpSegment::debugShowActiveSpans id=2 (124.700119,9.37180042 124.667862,9.37439685 124.635532,9.37703031 124.603165,9.37966728) t=0.937702598 tEnd=1 windSum=? windValue=1
151cb93a386Sopenharmony_ciSkOpSegment::debugShowActiveSpans id=3 (124.603165,9.37966728 124.574282,9.38202029 124.545364,9.3843762 124.516441,9.38671017) t=0 tEnd=0.0627286673 windSum=? windValue=1
152cb93a386Sopenharmony_ciSkOpSegment::debugShowActiveSpans id=3 (124.516441,9.38671017 124.257145,9.40763418 123.997124,9.42681973 123.752594,9.42682648) t=0.0627286673 tEnd=0.625091708 windSum=? windValue=1
153cb93a386Sopenharmony_ciSkOpSegment::debugShowActiveSpans id=3 (123.752594,9.42682648 123.589574,9.42683098 123.433439,9.41831153 123.289001,9.39610004) t=0.625091708 tEnd=1 windSum=? windValue=1
154cb93a386Sopenharmony_ciSkOpSegment::debugShowActiveSpans id=4 (123.289001,9.39610004 118.119003,8.07219982) t=0 tEnd=1 windSum=? windValue=1
155cb93a386Sopenharmony_ciSkOpSegment::debugShowActiveSpans id=5 (118.119003,8.07219982 8.17210007,104.212997) t=0 tEnd=1 windSum=? windValue=1
156cb93a386Sopenharmony_ciSkOpSegment::debugShowActiveSpans id=6 (8.17210007,104.212997 0,259.298737) t=0 tEnd=1 windSum=? windValue=1
157cb93a386Sopenharmony_ciSkOpSegment::debugShowActiveSpans id=7 (0,259.298737 0,353.891998) t=0 tEnd=1 windSum=? windValue=1
158cb93a386Sopenharmony_ci----------------x-x--x-x-------------- move_multiples
159cb93a386Sopenharmony_ci00:  coinSeg/Span/PtT=2/3/3 endSpan=30 oppSeg/Span/PtT=10/19/19 oppEndSpan=29 MissingCoin
160cb93a386Sopenharmony_ci01:  coinSeg/Span/PtT=3/36/36 endSpan=6 oppSeg/Span/PtT=11/35/35 oppEndSpan=22 MissingCoin
161cb93a386Sopenharmony_ci02:  coinSeg/Span/PtT=5/9/9 endSpan=10 oppSeg/Span/PtT=13/25/25 oppEndSpan=26 MissingCoin
162cb93a386Sopenharmony_ci03:  coinSeg/Span/PtT=2/3/3 endSpan=30 oppSeg/Span/PtT=10/19/19 oppEndSpan=29 MissingCoin
163cb93a386Sopenharmony_ci04:  coinSeg/Span/PtT=3/36/36 endSpan=6 oppSeg/Span/PtT=11/35/35 oppEndSpan=22 MissingCoin
164cb93a386Sopenharmony_ci05:  coinSeg/Span/PtT=5/9/9 endSpan=10 oppSeg/Span/PtT=13/25/25 oppEndSpan=26 MissingCoin
165cb93a386Sopenharmony_ci06:  coinSeg/Span/PtT=10/19/19 endSpan=29 oppSeg/Span/PtT=2/3/3 oppEndSpan=30 MissingCoin
166cb93a386Sopenharmony_ci07:  coinSeg/Span/PtT=11/35/35 endSpan=22 oppSeg/Span/PtT=3/36/36 oppEndSpan=6 MissingCoin
167cb93a386Sopenharmony_ci08:  coinSeg/Span/PtT=10/19/19 endSpan=29 oppSeg/Span/PtT=2/3/3 oppEndSpan=30 MissingCoin
168cb93a386Sopenharmony_ci09:  coinSeg/Span/PtT=11/35/35 endSpan=22 oppSeg/Span/PtT=3/36/36 oppEndSpan=6 MissingCoin
169cb93a386Sopenharmony_ci10:  coinSeg/Span/PtT=11/33/33 endSpan=6 oppSeg/Span/PtT=11/22/22 oppEndSpan=6 ExpandCoin
170cb93a386Sopenharmony_ci11:  coinSeg/Span/PtT=2/30/30 endSpan=19 oppSeg/Span/PtT=2/3/3 oppEndSpan=19 ExpandCoin
171cb93a386Sopenharmony_ci12:  seg/base=13/25 seg/base=5/9 MarkCoinStart
172cb93a386Sopenharmony_ci13:  seg/base=13/26 seg/base=5/10 MarkCoinEnd
173cb93a386Sopenharmony_ci14:  seg/base=4/7 seg/base=12/23 MarkCoinStart
174cb93a386Sopenharmony_ci15:  seg/base=4/8 seg/base=12/24 MarkCoinEnd
175cb93a386Sopenharmony_ci16:  seg/base=11/33 seg/base=3/34 MarkCoinStart
176cb93a386Sopenharmony_ci17:  seg/base=11/35 seg/base=3/36 MarkCoinEnd
177cb93a386Sopenharmony_ci18:  seg/base=2/30 seg/base=10/29 MarkCoinStart
178cb93a386Sopenharmony_ci19:  seg/base=2/32 seg/base=10/31 MarkCoinEnd
179cb93a386Sopenharmony_ci20:  seg/base=9/28 seg/base=1/1 MarkCoinStart
180cb93a386Sopenharmony_ci21:  seg/base=9/18 seg/base=1/2 MarkCoinEnd
181cb93a386Sopenharmony_ci22:  seg/base=8/15 seg/base=6/11 MarkCoinStart
182cb93a386Sopenharmony_ci23:  seg/base=8/27 seg/base=6/12 MarkCoinEnd
183cb93a386Sopenharmony_ci----------------x-x--x-x-------------- move_nearby
184cb93a386Sopenharmony_ci00:  coinSeg/Span/PtT=2/3/3 endSpan=30 oppSeg/Span/PtT=10/19/19 oppEndSpan=29 MissingCoin
185cb93a386Sopenharmony_ci01:  coinSeg/Span/PtT=3/36/36 endSpan=6 oppSeg/Span/PtT=11/35/35 oppEndSpan=22 MissingCoin
186cb93a386Sopenharmony_ci02:  coinSeg/Span/PtT=5/9/9 endSpan=10 oppSeg/Span/PtT=13/25/25 oppEndSpan=26 MissingCoin
187cb93a386Sopenharmony_ci03:  coinSeg/Span/PtT=2/3/3 endSpan=30 oppSeg/Span/PtT=10/19/19 oppEndSpan=29 MissingCoin
188cb93a386Sopenharmony_ci04:  coinSeg/Span/PtT=3/36/36 endSpan=6 oppSeg/Span/PtT=11/35/35 oppEndSpan=22 MissingCoin
189cb93a386Sopenharmony_ci05:  coinSeg/Span/PtT=5/9/9 endSpan=10 oppSeg/Span/PtT=13/25/25 oppEndSpan=26 MissingCoin
190cb93a386Sopenharmony_ci06:  coinSeg/Span/PtT=10/19/19 endSpan=29 oppSeg/Span/PtT=2/3/3 oppEndSpan=30 MissingCoin
191cb93a386Sopenharmony_ci07:  coinSeg/Span/PtT=11/35/35 endSpan=22 oppSeg/Span/PtT=3/36/36 oppEndSpan=6 MissingCoin
192cb93a386Sopenharmony_ci08:  coinSeg/Span/PtT=10/19/19 endSpan=29 oppSeg/Span/PtT=2/3/3 oppEndSpan=30 MissingCoin
193cb93a386Sopenharmony_ci09:  coinSeg/Span/PtT=11/35/35 endSpan=22 oppSeg/Span/PtT=3/36/36 oppEndSpan=6 MissingCoin
194cb93a386Sopenharmony_ci10:  coinSeg/Span/PtT=11/33/33 endSpan=6 oppSeg/Span/PtT=11/22/22 oppEndSpan=6 ExpandCoin
195cb93a386Sopenharmony_ci11:  coinSeg/Span/PtT=2/30/30 endSpan=19 oppSeg/Span/PtT=2/3/3 oppEndSpan=19 ExpandCoin
196cb93a386Sopenharmony_ci12:  seg/base=13/25 seg/base=5/9 MarkCoinStart
197cb93a386Sopenharmony_ci13:  seg/base=13/26 seg/base=5/10 MarkCoinEnd
198cb93a386Sopenharmony_ci14:  seg/base=4/7 seg/base=12/23 MarkCoinStart
199cb93a386Sopenharmony_ci15:  seg/base=4/8 seg/base=12/24 MarkCoinEnd
200cb93a386Sopenharmony_ci16:  seg/base=11/33 seg/base=3/34 MarkCoinStart
201cb93a386Sopenharmony_ci17:  seg/base=11/35 seg/base=3/36 MarkCoinEnd
202cb93a386Sopenharmony_ci18:  seg/base=2/30 seg/base=10/29 MarkCoinStart
203cb93a386Sopenharmony_ci19:  seg/base=2/32 seg/base=10/31 MarkCoinEnd
204cb93a386Sopenharmony_ci20:  seg/base=9/28 seg/base=1/1 MarkCoinStart
205cb93a386Sopenharmony_ci21:  seg/base=9/18 seg/base=1/2 MarkCoinEnd
206cb93a386Sopenharmony_ci22:  seg/base=8/15 seg/base=6/11 MarkCoinStart
207cb93a386Sopenharmony_ci23:  seg/base=8/27 seg/base=6/12 MarkCoinEnd
208cb93a386Sopenharmony_ci----------------x-x--x-x-------------- correctEnds
209cb93a386Sopenharmony_ci00:  coinSeg/Span/PtT=2/3/3 endSpan=30 oppSeg/Span/PtT=10/19/19 oppEndSpan=29 MissingCoin
210cb93a386Sopenharmony_ci01:  coinSeg/Span/PtT=3/36/36 endSpan=6 oppSeg/Span/PtT=11/35/35 oppEndSpan=22 MissingCoin
211cb93a386Sopenharmony_ci02:  coinSeg/Span/PtT=5/9/9 endSpan=10 oppSeg/Span/PtT=13/25/25 oppEndSpan=26 MissingCoin
212cb93a386Sopenharmony_ci03:  coinSeg/Span/PtT=2/3/3 endSpan=30 oppSeg/Span/PtT=10/19/19 oppEndSpan=29 MissingCoin
213cb93a386Sopenharmony_ci04:  coinSeg/Span/PtT=3/36/36 endSpan=6 oppSeg/Span/PtT=11/35/35 oppEndSpan=22 MissingCoin
214cb93a386Sopenharmony_ci05:  coinSeg/Span/PtT=5/9/9 endSpan=10 oppSeg/Span/PtT=13/25/25 oppEndSpan=26 MissingCoin
215cb93a386Sopenharmony_ci06:  coinSeg/Span/PtT=10/19/19 endSpan=29 oppSeg/Span/PtT=2/3/3 oppEndSpan=30 MissingCoin
216cb93a386Sopenharmony_ci07:  coinSeg/Span/PtT=11/35/35 endSpan=22 oppSeg/Span/PtT=3/36/36 oppEndSpan=6 MissingCoin
217cb93a386Sopenharmony_ci08:  coinSeg/Span/PtT=10/19/19 endSpan=29 oppSeg/Span/PtT=2/3/3 oppEndSpan=30 MissingCoin
218cb93a386Sopenharmony_ci09:  coinSeg/Span/PtT=11/35/35 endSpan=22 oppSeg/Span/PtT=3/36/36 oppEndSpan=6 MissingCoin
219cb93a386Sopenharmony_ci10:  coinSeg/Span/PtT=11/33/33 endSpan=6 oppSeg/Span/PtT=11/22/22 oppEndSpan=6 ExpandCoin
220cb93a386Sopenharmony_ci11:  coinSeg/Span/PtT=2/30/30 endSpan=19 oppSeg/Span/PtT=2/3/3 oppEndSpan=19 ExpandCoin
221cb93a386Sopenharmony_ci12:  seg/base=13/25 seg/base=5/9 MarkCoinStart
222cb93a386Sopenharmony_ci13:  seg/base=13/26 seg/base=5/10 MarkCoinEnd
223cb93a386Sopenharmony_ci14:  seg/base=4/7 seg/base=12/23 MarkCoinStart
224cb93a386Sopenharmony_ci15:  seg/base=4/8 seg/base=12/24 MarkCoinEnd
225cb93a386Sopenharmony_ci16:  seg/base=11/33 seg/base=3/34 MarkCoinStart
226cb93a386Sopenharmony_ci17:  seg/base=11/35 seg/base=3/36 MarkCoinEnd
227cb93a386Sopenharmony_ci18:  seg/base=2/30 seg/base=10/29 MarkCoinStart
228cb93a386Sopenharmony_ci19:  seg/base=2/32 seg/base=10/31 MarkCoinEnd
229cb93a386Sopenharmony_ci20:  seg/base=9/28 seg/base=1/1 MarkCoinStart
230cb93a386Sopenharmony_ci21:  seg/base=9/18 seg/base=1/2 MarkCoinEnd
231cb93a386Sopenharmony_ci22:  seg/base=8/15 seg/base=6/11 MarkCoinStart
232cb93a386Sopenharmony_ci23:  seg/base=8/27 seg/base=6/12 MarkCoinEnd
233cb93a386Sopenharmony_ci----------------x-x--x-x-------------- addEndMovedSpans
234cb93a386Sopenharmony_ci00:  coinSeg/Span/PtT=2/3/3 endSpan=30 oppSeg/Span/PtT=10/19/19 oppEndSpan=29 MissingCoin
235cb93a386Sopenharmony_ci01:  coinSeg/Span/PtT=3/36/36 endSpan=6 oppSeg/Span/PtT=11/35/35 oppEndSpan=22 MissingCoin
236cb93a386Sopenharmony_ci02:  coinSeg/Span/PtT=5/9/9 endSpan=10 oppSeg/Span/PtT=13/25/25 oppEndSpan=26 MissingCoin
237cb93a386Sopenharmony_ci03:  coinSeg/Span/PtT=2/3/3 endSpan=30 oppSeg/Span/PtT=10/19/19 oppEndSpan=29 MissingCoin
238cb93a386Sopenharmony_ci04:  coinSeg/Span/PtT=3/36/36 endSpan=6 oppSeg/Span/PtT=11/35/35 oppEndSpan=22 MissingCoin
239cb93a386Sopenharmony_ci05:  coinSeg/Span/PtT=5/9/9 endSpan=10 oppSeg/Span/PtT=13/25/25 oppEndSpan=26 MissingCoin
240cb93a386Sopenharmony_ci06:  coinSeg/Span/PtT=10/19/19 endSpan=29 oppSeg/Span/PtT=2/3/3 oppEndSpan=30 MissingCoin
241cb93a386Sopenharmony_ci07:  coinSeg/Span/PtT=11/35/35 endSpan=22 oppSeg/Span/PtT=3/36/36 oppEndSpan=6 MissingCoin
242cb93a386Sopenharmony_ci08:  coinSeg/Span/PtT=10/19/19 endSpan=29 oppSeg/Span/PtT=2/3/3 oppEndSpan=30 MissingCoin
243cb93a386Sopenharmony_ci09:  coinSeg/Span/PtT=11/35/35 endSpan=22 oppSeg/Span/PtT=3/36/36 oppEndSpan=6 MissingCoin
244cb93a386Sopenharmony_ci10:  coinSeg/Span/PtT=11/33/33 endSpan=6 oppSeg/Span/PtT=11/22/22 oppEndSpan=6 ExpandCoin
245cb93a386Sopenharmony_ci11:  coinSeg/Span/PtT=2/30/30 endSpan=19 oppSeg/Span/PtT=2/3/3 oppEndSpan=19 ExpandCoin
246cb93a386Sopenharmony_ci12:  seg/base=13/25 seg/base=5/9 MarkCoinStart
247cb93a386Sopenharmony_ci13:  seg/base=13/26 seg/base=5/10 MarkCoinEnd
248cb93a386Sopenharmony_ci14:  seg/base=4/7 seg/base=12/23 MarkCoinStart
249cb93a386Sopenharmony_ci15:  seg/base=4/8 seg/base=12/24 MarkCoinEnd
250cb93a386Sopenharmony_ci16:  seg/base=11/33 seg/base=3/34 MarkCoinStart
251cb93a386Sopenharmony_ci17:  seg/base=11/35 seg/base=3/36 MarkCoinEnd
252cb93a386Sopenharmony_ci18:  seg/base=2/30 seg/base=10/29 MarkCoinStart
253cb93a386Sopenharmony_ci19:  seg/base=2/32 seg/base=10/31 MarkCoinEnd
254cb93a386Sopenharmony_ci20:  seg/base=9/28 seg/base=1/1 MarkCoinStart
255cb93a386Sopenharmony_ci21:  seg/base=9/18 seg/base=1/2 MarkCoinEnd
256cb93a386Sopenharmony_ci22:  seg/base=8/15 seg/base=6/11 MarkCoinStart
257cb93a386Sopenharmony_ci23:  seg/base=8/27 seg/base=6/12 MarkCoinEnd
258cb93a386Sopenharmony_ci----------------x-x--x-x-------------- expand
259cb93a386Sopenharmony_ci00:  coinSeg/Span/PtT=2/3/3 endSpan=30 oppSeg/Span/PtT=10/19/19 oppEndSpan=29 MissingCoin
260cb93a386Sopenharmony_ci01:  coinSeg/Span/PtT=3/36/36 endSpan=6 oppSeg/Span/PtT=11/35/35 oppEndSpan=22 MissingCoin
261cb93a386Sopenharmony_ci02:  coinSeg/Span/PtT=5/9/9 endSpan=10 oppSeg/Span/PtT=13/25/25 oppEndSpan=26 MissingCoin
262cb93a386Sopenharmony_ci03:  coinSeg/Span/PtT=2/3/3 endSpan=30 oppSeg/Span/PtT=10/19/19 oppEndSpan=29 MissingCoin
263cb93a386Sopenharmony_ci04:  coinSeg/Span/PtT=3/36/36 endSpan=6 oppSeg/Span/PtT=11/35/35 oppEndSpan=22 MissingCoin
264cb93a386Sopenharmony_ci05:  coinSeg/Span/PtT=5/9/9 endSpan=10 oppSeg/Span/PtT=13/25/25 oppEndSpan=26 MissingCoin
265cb93a386Sopenharmony_ci06:  coinSeg/Span/PtT=10/19/19 endSpan=29 oppSeg/Span/PtT=2/3/3 oppEndSpan=30 MissingCoin
266cb93a386Sopenharmony_ci07:  coinSeg/Span/PtT=11/35/35 endSpan=22 oppSeg/Span/PtT=3/36/36 oppEndSpan=6 MissingCoin
267cb93a386Sopenharmony_ci08:  coinSeg/Span/PtT=10/19/19 endSpan=29 oppSeg/Span/PtT=2/3/3 oppEndSpan=30 MissingCoin
268cb93a386Sopenharmony_ci09:  coinSeg/Span/PtT=11/35/35 endSpan=22 oppSeg/Span/PtT=3/36/36 oppEndSpan=6 MissingCoin
269cb93a386Sopenharmony_ci10:  coinSeg/Span/PtT=11/33/33 endSpan=6 oppSeg/Span/PtT=11/22/22 oppEndSpan=6 ExpandCoin
270cb93a386Sopenharmony_ci11:  coinSeg/Span/PtT=2/30/30 endSpan=19 oppSeg/Span/PtT=2/3/3 oppEndSpan=19 ExpandCoin
271cb93a386Sopenharmony_ci12:  seg/base=13/25 seg/base=5/9 MarkCoinStart
272cb93a386Sopenharmony_ci13:  seg/base=13/26 seg/base=5/10 MarkCoinEnd
273cb93a386Sopenharmony_ci14:  seg/base=4/7 seg/base=12/23 MarkCoinStart
274cb93a386Sopenharmony_ci15:  seg/base=4/8 seg/base=12/24 MarkCoinEnd
275cb93a386Sopenharmony_ci16:  seg/base=11/33 seg/base=3/34 MarkCoinStart
276cb93a386Sopenharmony_ci17:  seg/base=11/35 seg/base=3/36 MarkCoinEnd
277cb93a386Sopenharmony_ci18:  seg/base=2/30 seg/base=10/29 MarkCoinStart
278cb93a386Sopenharmony_ci19:  seg/base=2/32 seg/base=10/31 MarkCoinEnd
279cb93a386Sopenharmony_ci20:  seg/base=9/28 seg/base=1/1 MarkCoinStart
280cb93a386Sopenharmony_ci21:  seg/base=9/18 seg/base=1/2 MarkCoinEnd
281cb93a386Sopenharmony_ci22:  seg/base=8/15 seg/base=6/11 MarkCoinStart
282cb93a386Sopenharmony_ci23:  seg/base=8/27 seg/base=6/12 MarkCoinEnd
283cb93a386Sopenharmony_ci------------------xx-x-x-------------- addExpanded
284cb93a386Sopenharmony_ci00:  coinSeg/Span/PtT=5/9/9 endSpan=10 oppSeg/Span/PtT=13/25/25 oppEndSpan=26 MissingCoin
285cb93a386Sopenharmony_ci01:  coinSeg/Span/PtT=5/9/9 endSpan=10 oppSeg/Span/PtT=13/25/25 oppEndSpan=26 MissingCoin
286cb93a386Sopenharmony_ci02:  seg/base=13/25 seg/base=5/9 MarkCoinStart
287cb93a386Sopenharmony_ci03:  seg/base=13/26 seg/base=5/10 MarkCoinEnd
288cb93a386Sopenharmony_ci04:  seg/base=4/7 seg/base=12/23 MarkCoinStart
289cb93a386Sopenharmony_ci05:  seg/base=4/8 seg/base=12/24 MarkCoinEnd
290cb93a386Sopenharmony_ci06:  seg/base=11/33 seg/base=3/34 MarkCoinStart
291cb93a386Sopenharmony_ci07:  seg/base=11/22 seg/base=3/6 MarkCoinEnd
292cb93a386Sopenharmony_ci08:  seg/base=3/36 MarkCoinInsert
293cb93a386Sopenharmony_ci09:  seg/base=11/35 MarkCoinInsert
294cb93a386Sopenharmony_ci10:  seg/base=2/3 seg/base=10/19 MarkCoinStart
295cb93a386Sopenharmony_ci11:  seg/base=2/32 seg/base=10/31 MarkCoinEnd
296cb93a386Sopenharmony_ci12:  seg/base=10/29 MarkCoinInsert
297cb93a386Sopenharmony_ci13:  seg/base=2/30 MarkCoinInsert
298cb93a386Sopenharmony_ci14:  seg/base=9/28 seg/base=1/1 MarkCoinStart
299cb93a386Sopenharmony_ci15:  seg/base=9/18 seg/base=1/2 MarkCoinEnd
300cb93a386Sopenharmony_ci16:  seg/base=8/15 seg/base=6/11 MarkCoinStart
301cb93a386Sopenharmony_ci17:  seg/base=8/27 seg/base=6/12 MarkCoinEnd
302cb93a386Sopenharmony_ci------------------xx-x-x-------------- move_multiples
303cb93a386Sopenharmony_ci00:  coinSeg/Span/PtT=5/9/9 endSpan=10 oppSeg/Span/PtT=13/25/25 oppEndSpan=26 MissingCoin
304cb93a386Sopenharmony_ci01:  coinSeg/Span/PtT=5/9/9 endSpan=10 oppSeg/Span/PtT=13/25/25 oppEndSpan=26 MissingCoin
305cb93a386Sopenharmony_ci02:  seg/base=13/25 seg/base=5/9 MarkCoinStart
306cb93a386Sopenharmony_ci03:  seg/base=13/26 seg/base=5/10 MarkCoinEnd
307cb93a386Sopenharmony_ci04:  seg/base=4/7 seg/base=12/23 MarkCoinStart
308cb93a386Sopenharmony_ci05:  seg/base=4/8 seg/base=12/24 MarkCoinEnd
309cb93a386Sopenharmony_ci06:  seg/base=11/33 seg/base=3/34 MarkCoinStart
310cb93a386Sopenharmony_ci07:  seg/base=11/22 seg/base=3/6 MarkCoinEnd
311cb93a386Sopenharmony_ci08:  seg/base=3/36 MarkCoinInsert
312cb93a386Sopenharmony_ci09:  seg/base=11/35 MarkCoinInsert
313cb93a386Sopenharmony_ci10:  seg/base=2/3 seg/base=10/19 MarkCoinStart
314cb93a386Sopenharmony_ci11:  seg/base=2/32 seg/base=10/31 MarkCoinEnd
315cb93a386Sopenharmony_ci12:  seg/base=10/29 MarkCoinInsert
316cb93a386Sopenharmony_ci13:  seg/base=2/30 MarkCoinInsert
317cb93a386Sopenharmony_ci14:  seg/base=9/28 seg/base=1/1 MarkCoinStart
318cb93a386Sopenharmony_ci15:  seg/base=9/18 seg/base=1/2 MarkCoinEnd
319cb93a386Sopenharmony_ci16:  seg/base=8/15 seg/base=6/11 MarkCoinStart
320cb93a386Sopenharmony_ci17:  seg/base=8/27 seg/base=6/12 MarkCoinEnd
321cb93a386Sopenharmony_ci------------------xx-x-x-------------- move_nearby
322cb93a386Sopenharmony_ci00:  coinSeg/Span/PtT=5/9/9 endSpan=10 oppSeg/Span/PtT=13/25/25 oppEndSpan=26 MissingCoin
323cb93a386Sopenharmony_ci01:  coinSeg/Span/PtT=5/9/9 endSpan=10 oppSeg/Span/PtT=13/25/25 oppEndSpan=26 MissingCoin
324cb93a386Sopenharmony_ci02:  seg/base=13/25 seg/base=5/9 MarkCoinStart
325cb93a386Sopenharmony_ci03:  seg/base=13/26 seg/base=5/10 MarkCoinEnd
326cb93a386Sopenharmony_ci04:  seg/base=4/7 seg/base=12/23 MarkCoinStart
327cb93a386Sopenharmony_ci05:  seg/base=4/8 seg/base=12/24 MarkCoinEnd
328cb93a386Sopenharmony_ci06:  seg/base=11/33 seg/base=3/34 MarkCoinStart
329cb93a386Sopenharmony_ci07:  seg/base=11/22 seg/base=3/6 MarkCoinEnd
330cb93a386Sopenharmony_ci08:  seg/base=3/36 MarkCoinInsert
331cb93a386Sopenharmony_ci09:  seg/base=11/35 MarkCoinInsert
332cb93a386Sopenharmony_ci10:  seg/base=2/3 seg/base=10/19 MarkCoinStart
333cb93a386Sopenharmony_ci11:  seg/base=2/32 seg/base=10/31 MarkCoinEnd
334cb93a386Sopenharmony_ci12:  seg/base=10/29 MarkCoinInsert
335cb93a386Sopenharmony_ci13:  seg/base=2/30 MarkCoinInsert
336cb93a386Sopenharmony_ci14:  seg/base=9/28 seg/base=1/1 MarkCoinStart
337cb93a386Sopenharmony_ci15:  seg/base=9/18 seg/base=1/2 MarkCoinEnd
338cb93a386Sopenharmony_ci16:  seg/base=8/15 seg/base=6/11 MarkCoinStart
339cb93a386Sopenharmony_ci17:  seg/base=8/27 seg/base=6/12 MarkCoinEnd
340cb93a386Sopenharmony_ci------------------xx-x-x-------------- addExpanded
341cb93a386Sopenharmony_ci00:  coinSeg/Span/PtT=5/9/9 endSpan=10 oppSeg/Span/PtT=13/25/25 oppEndSpan=26 MissingCoin
342cb93a386Sopenharmony_ci01:  coinSeg/Span/PtT=5/9/9 endSpan=10 oppSeg/Span/PtT=13/25/25 oppEndSpan=26 MissingCoin
343cb93a386Sopenharmony_ci02:  seg/base=13/25 seg/base=5/9 MarkCoinStart
344cb93a386Sopenharmony_ci03:  seg/base=13/26 seg/base=5/10 MarkCoinEnd
345cb93a386Sopenharmony_ci04:  seg/base=4/7 seg/base=12/23 MarkCoinStart
346cb93a386Sopenharmony_ci05:  seg/base=4/8 seg/base=12/24 MarkCoinEnd
347cb93a386Sopenharmony_ci06:  seg/base=11/33 seg/base=3/34 MarkCoinStart
348cb93a386Sopenharmony_ci07:  seg/base=11/22 seg/base=3/6 MarkCoinEnd
349cb93a386Sopenharmony_ci08:  seg/base=3/36 MarkCoinInsert
350cb93a386Sopenharmony_ci09:  seg/base=11/35 MarkCoinInsert
351cb93a386Sopenharmony_ci10:  seg/base=2/3 seg/base=10/19 MarkCoinStart
352cb93a386Sopenharmony_ci11:  seg/base=2/32 seg/base=10/31 MarkCoinEnd
353cb93a386Sopenharmony_ci12:  seg/base=10/29 MarkCoinInsert
354cb93a386Sopenharmony_ci13:  seg/base=2/30 MarkCoinInsert
355cb93a386Sopenharmony_ci14:  seg/base=9/28 seg/base=1/1 MarkCoinStart
356cb93a386Sopenharmony_ci15:  seg/base=9/18 seg/base=1/2 MarkCoinEnd
357cb93a386Sopenharmony_ci16:  seg/base=8/15 seg/base=6/11 MarkCoinStart
358cb93a386Sopenharmony_ci17:  seg/base=8/27 seg/base=6/12 MarkCoinEnd
359cb93a386Sopenharmony_ci------------------xx-x-x-------------- mark
360cb93a386Sopenharmony_ci00:  coinSeg/Span/PtT=5/9/9 endSpan=10 oppSeg/Span/PtT=13/25/25 oppEndSpan=26 MissingCoin
361cb93a386Sopenharmony_ci01:  coinSeg/Span/PtT=5/9/9 endSpan=10 oppSeg/Span/PtT=13/25/25 oppEndSpan=26 MissingCoin
362cb93a386Sopenharmony_ci02:  seg/base=13/25 seg/base=5/9 MarkCoinStart
363cb93a386Sopenharmony_ci03:  seg/base=13/26 seg/base=5/10 MarkCoinEnd
364cb93a386Sopenharmony_ci04:  seg/base=4/7 seg/base=12/23 MarkCoinStart
365cb93a386Sopenharmony_ci05:  seg/base=4/8 seg/base=12/24 MarkCoinEnd
366cb93a386Sopenharmony_ci06:  seg/base=11/33 seg/base=3/34 MarkCoinStart
367cb93a386Sopenharmony_ci07:  seg/base=11/22 seg/base=3/6 MarkCoinEnd
368cb93a386Sopenharmony_ci08:  seg/base=3/36 MarkCoinInsert
369cb93a386Sopenharmony_ci09:  seg/base=11/35 MarkCoinInsert
370cb93a386Sopenharmony_ci10:  seg/base=2/3 seg/base=10/19 MarkCoinStart
371cb93a386Sopenharmony_ci11:  seg/base=2/32 seg/base=10/31 MarkCoinEnd
372cb93a386Sopenharmony_ci12:  seg/base=10/29 MarkCoinInsert
373cb93a386Sopenharmony_ci13:  seg/base=2/30 MarkCoinInsert
374cb93a386Sopenharmony_ci14:  seg/base=9/28 seg/base=1/1 MarkCoinStart
375cb93a386Sopenharmony_ci15:  seg/base=9/18 seg/base=1/2 MarkCoinEnd
376cb93a386Sopenharmony_ci16:  seg/base=8/15 seg/base=6/11 MarkCoinStart
377cb93a386Sopenharmony_ci17:  seg/base=8/27 seg/base=6/12 MarkCoinEnd
378cb93a386Sopenharmony_ci-------------------------------------- missing_coincidence
379cb93a386Sopenharmony_ci-------------------------------------- expand
380cb93a386Sopenharmony_ci-------------------------------------- expand
381cb93a386Sopenharmony_ci-------------------------------------- apply
382cb93a386Sopenharmony_ciSkOpSegment::markDone id=5 (118.119003,8.07219982 8.17210007,104.212997) t=0 [9] (118.119003,8.07219982) tEnd=1 newWindSum=? newOppSum=? oppSum=? windSum=? windValue=0 oppValue=0
383cb93a386Sopenharmony_ciSkOpSegment::markDone id=12 (123.289001,9.39620018 118.119003,8.07219982) t=0 [23] (123.289001,9.39620018) tEnd=1 newWindSum=? newOppSum=? oppSum=? windSum=? windValue=0 oppValue=0
384cb93a386Sopenharmony_ciSkOpSegment::markDone id=3 (124.603165,9.37966728 124.142731,9.41717815 123.674263,9.45534515 123.289001,9.39610004) t=0.0627286673 [34] (124.516441,9.38671017) tEnd=0.625091708 newWindSum=? newOppSum=? oppSum=? windSum=? windValue=0 oppValue=0
385cb93a386Sopenharmony_ciSkOpSegment::markDone id=3 (124.603165,9.37966728 124.142731,9.41717815 123.674263,9.45534515 123.289001,9.39610004) t=0.625091708 [36] (123.752594,9.42682648) tEnd=1 newWindSum=? newOppSum=? oppSum=? windSum=? windValue=0 oppValue=0
386cb93a386Sopenharmony_ciSkOpSegment::markDone id=10 (126,9.39620018 125.631981,9.29586983 125.12252,9.3373785 124.602829,9.37972069) t=0 [19] (126,9.39620018) tEnd=0.307128906 newWindSum=? newOppSum=? oppSum=? windSum=? windValue=0 oppValue=0
387cb93a386Sopenharmony_ciSkOpSegment::markDone id=10 (126,9.39620018 125.631981,9.29586983 125.12252,9.3373785 124.602829,9.37972069) t=0.307128906 [29] (125.624687,9.33981037) tEnd=0.9375 newWindSum=? newOppSum=? oppSum=? windSum=? windValue=0 oppValue=0
388cb93a386Sopenharmony_ciSkOpSegment::markDone id=1 (0,353.891998 126,9.39610004) t=0 [1] (0,353.891998) tEnd=1 newWindSum=? newOppSum=? oppSum=? windSum=? windValue=0 oppValue=0
389cb93a386Sopenharmony_ciSkOpSegment::markDone id=6 (8.17210007,104.212997 0,259.298737) t=0 [11] (8.17210007,104.212997) tEnd=1 newWindSum=? newOppSum=? oppSum=? windSum=? windValue=0 oppValue=0
390cb93a386Sopenharmony_ci-------------------------------------- findOverlaps
391cb93a386Sopenharmony_ciSkOpSegment::debugShowActiveSpans id=8 (8.17210007,104.212997 -2.71619996e-07,259.298737) t=0 tEnd=0.583904956 windSum=? oppSum=? windValue=1 oppValue=1
392cb93a386Sopenharmony_ciSkOpSegment::debugShowActiveSpans id=8 (-2.71619996e-07,259.298737 -5.82350016,369.813995) t=0.583904956 tEnd=1 windSum=? windValue=1
393cb93a386Sopenharmony_ciSkOpSegment::debugShowActiveSpans id=9 (-5.82350016,369.813995 7.26031715e-07,353.891998) t=0 tEnd=0.0441765002 windSum=? windValue=1
394cb93a386Sopenharmony_ciSkOpSegment::debugShowActiveSpans id=9 (7.26031715e-07,353.891998 126,9.39620018) t=0.0441765002 tEnd=1 windSum=? oppSum=? windValue=1 oppValue=1
395cb93a386Sopenharmony_ciSkOpSegment::debugShowActiveSpans id=10 (124.700119,9.37182617 124.66775,9.37443162 124.63531,9.3770743 124.602829,9.37972069) t=0.9375 tEnd=1 windSum=? windValue=1
396cb93a386Sopenharmony_ciSkOpSegment::debugShowActiveSpans id=11 (124.602829,9.37972069 124.574059,9.3820647 124.545259,9.38441166 124.516449,9.38673687) t=0 tEnd=0.0625 windSum=? windValue=1
397cb93a386Sopenharmony_ciSkOpSegment::debugShowActiveSpans id=11 (124.516449,9.38673687 124.257155,9.40766372 123.997126,9.42685982 123.752594,9.4268837) t=0.0625 tEnd=0.625 windSum=? oppSum=? windValue=1 oppValue=1
398cb93a386Sopenharmony_ciSkOpSegment::debugShowActiveSpans id=11 (123.752594,9.4268837 123.589573,9.42689962 123.433437,9.41839421 123.289001,9.39620018) t=0.625 tEnd=1 windSum=? oppSum=? windValue=1 oppValue=1
399cb93a386Sopenharmony_ciSkOpSegment::debugShowActiveSpans id=13 (118.119003,8.07219982 8.17210007,104.212997) t=0 tEnd=1 windSum=? oppSum=? windValue=1 oppValue=1
400cb93a386Sopenharmony_ciSkOpSegment::debugShowActiveSpans id=2 (126,9.39610004 125.886971,9.36530236 125.760605,9.34788101 125.624695,9.33975124) t=0 tEnd=0.307190555 windSum=? oppSum=? windValue=1 oppValue=1
401cb93a386Sopenharmony_ciSkOpSegment::debugShowActiveSpans id=2 (125.624695,9.33975124 125.345738,9.3230648 125.026588,9.34552196 124.700119,9.37180042) t=0.307190555 tEnd=0.937702598 windSum=? oppSum=? windValue=1 oppValue=1
402cb93a386Sopenharmony_ciSkOpSegment::debugShowActiveSpans id=2 (124.700119,9.37180042 124.667862,9.37439685 124.635532,9.37703031 124.603165,9.37966728) t=0.937702598 tEnd=1 windSum=? windValue=1
403cb93a386Sopenharmony_ciSkOpSegment::debugShowActiveSpans id=3 (124.603165,9.37966728 124.574282,9.38202029 124.545364,9.3843762 124.516441,9.38671017) t=0 tEnd=0.0627286673 windSum=? windValue=1
404cb93a386Sopenharmony_ciSkOpSegment::debugShowActiveSpans id=4 (123.289001,9.39610004 118.119003,8.07219982) t=0 tEnd=1 windSum=? oppSum=? windValue=1 oppValue=1
405cb93a386Sopenharmony_ciSkOpSegment::debugShowActiveSpans id=7 (0,259.298737 0,353.891998) t=0 tEnd=1 windSum=? windValue=1
406cb93a386Sopenharmony_ci-------------------------------------- calc_angles
407cb93a386Sopenharmony_ciSkOpSegment::sortAngles [8] tStart=0 [15]
408cb93a386Sopenharmony_ciSkOpSegment::sortAngles [8] tStart=0.583904956 [27]
409cb93a386Sopenharmony_ciSkOpAngle::after [8/2] 5/5 tStart=0.583904956 tEnd=0 < [7/23] 23/23 tStart=0 tEnd=1 < [8/3] 21/21 tStart=0.583904956 tEnd=1  F 4
410cb93a386Sopenharmony_ciSkOpAngle::afterPart {{{0,259.298737}, {8.17210034,104.212997}}} id=8
411cb93a386Sopenharmony_ciSkOpAngle::afterPart {{{0,259.298737}, {0,353.891998}}} id=7
412cb93a386Sopenharmony_ciSkOpAngle::afterPart {{{0,259.298737}, {-5.82349988,369.813995}}} id=8
413cb93a386Sopenharmony_ciSkOpSegment::sortAngles [9] tStart=0.0441765002 [28]
414cb93a386Sopenharmony_ciSkOpAngle::after [9/4] 21/21 tStart=0.0441765002 tEnd=0 < [7/24] 7/7 tStart=1 tEnd=0 < [9/5] 5/5 tStart=0.0441765002 tEnd=1  F 4
415cb93a386Sopenharmony_ciSkOpAngle::afterPart {{{0,353.891998}, {-5.82350088,369.813995}}} id=9
416cb93a386Sopenharmony_ciSkOpAngle::afterPart {{{0,353.891998}, {0,259.298737}}} id=7
417cb93a386Sopenharmony_ciSkOpAngle::afterPart {{{0,353.891998}, {125.999999,9.39620018}}} id=9
418cb93a386Sopenharmony_ciSkOpSegment::sortAngles [9] tStart=1 [18]
419cb93a386Sopenharmony_ciSkOpSegment::sortAngles [10] tStart=0.9375 [31]
420cb93a386Sopenharmony_ciSkOpAngle::after [10/7] 17/17 tStart=0.9375 tEnd=1 < [2/19] 17/17 tStart=0.937702598 tEnd=1 < [2/18] 1/1 tStart=0.937702598 tEnd=0.307190555  T 12
421cb93a386Sopenharmony_ciSkOpAngle::afterPart {{{124.700119,9.37180042}, {124.66775,9.37440587}, {124.63531,9.37704855}, {124.602829,9.37969494}}} id=10
422cb93a386Sopenharmony_ciSkOpAngle::afterPart {{{124.700119,9.37180042}, {124.667862,9.37439685}, {124.635532,9.37703031}, {124.603165,9.37966728}}} id=2
423cb93a386Sopenharmony_ciSkOpAngle::afterPart {{{124.700119,9.37180042}, {125.026588,9.34552196}, {125.345738,9.3230648}, {125.624695,9.33975124}}} id=2
424cb93a386Sopenharmony_ciSkOpSegment::sortAngles [11] tStart=0.0625 [33]
425cb93a386Sopenharmony_ciSkOpAngle::after [11/8] 1/1 tStart=0.0625 tEnd=0 < [3/20] 1/1 tStart=0.0627286673 tEnd=0 < [11/9] 17/17 tStart=0.0625 tEnd=0.625  T 12
426cb93a386Sopenharmony_ciSkOpAngle::afterPart {{{124.516441,9.38671017}, {124.545252,9.38438496}, {124.574051,9.382038}, {124.602821,9.37969398}}} id=11
427cb93a386Sopenharmony_ciSkOpAngle::afterPart {{{124.516441,9.38671017}, {124.545364,9.3843762}, {124.574282,9.38202029}, {124.603165,9.37966728}}} id=3
428cb93a386Sopenharmony_ciSkOpAngle::afterPart {{{124.516441,9.38671017}, {124.257148,9.40763702}, {123.997118,9.42683311}, {123.752586,9.42685699}}} id=11
429cb93a386Sopenharmony_ciSkOpSegment::sortAngles [11] tStart=0.625 [35]
430cb93a386Sopenharmony_ciSkOpSegment::sortAngles [11] tStart=1 [22]
431cb93a386Sopenharmony_ciSkOpSegment::sortAngles [13] tStart=0 [25]
432cb93a386Sopenharmony_ciSkOpSegment::sortAngles [13] tStart=1 [26]
433cb93a386Sopenharmony_ciSkOpSegment::sortAngles [2] tStart=0 [3]
434cb93a386Sopenharmony_ciSkOpSegment::sortAngles [2] tStart=0.307190555 [30]
435cb93a386Sopenharmony_ciSkOpSegment::sortAngles [2] tStart=0.937702598 [32]
436cb93a386Sopenharmony_ciSkOpSegment::sortAngles [3] tStart=0.0627286673 [34]
437cb93a386Sopenharmony_ciSkOpSegment::sortAngles [4] tStart=0 [7]
438cb93a386Sopenharmony_ciSkOpSegment::sortAngles [4] tStart=1 [8]
439cb93a386Sopenharmony_ciSkOpSegment::sortAngles [7] tStart=0 [13]
440cb93a386Sopenharmony_ciSkOpSegment::sortAngles [7] tStart=1 [14]
441cb93a386Sopenharmony_cicoinSpan - id=13 t=0 tEnd=1
442cb93a386Sopenharmony_cicoinSpan + id=5 t=0 tEnd=1
443cb93a386Sopenharmony_cicoinSpan - id=4 t=0 tEnd=1
444cb93a386Sopenharmony_cicoinSpan + id=12 t=0 tEnd=1
445cb93a386Sopenharmony_cicoinSpan - id=11 t=0.0625 tEnd=1
446cb93a386Sopenharmony_cicoinSpan + id=3 t=0.0627286673 tEnd=1
447cb93a386Sopenharmony_cicoinSpan - id=2 t=0 tEnd=0.937702598
448cb93a386Sopenharmony_cicoinSpan + id=10 t=0 tEnd=0.9375
449cb93a386Sopenharmony_cicoinSpan - id=9 t=0.0441765002 tEnd=1
450cb93a386Sopenharmony_cicoinSpan + id=1 t=0 tEnd=1
451cb93a386Sopenharmony_cicoinSpan - id=8 t=0 tEnd=0.583904956
452cb93a386Sopenharmony_cicoinSpan + id=6 t=0 tEnd=1
453cb93a386Sopenharmony_ciSkOpSpan::sortableTop dir=kLeft seg=8 t=0.291952478 pt=(4.08605003,181.755859)
454cb93a386Sopenharmony_ciSkOpSpan::sortableTop [0] valid=1 operand=1 span=15 ccw=0 seg=8 {{{8.17210007f, 104.212997f}, {-5.82350016f, 369.813995f}}} t=0.291952478 pt=(4.08605003,181.755859) slope=(-13.9956002,265.600998)
455cb93a386Sopenharmony_ciSkOpSegment::markWinding id=8 (8.17210007,104.212997 -5.82350016,369.813995) t=0 [15] (8.17210007,104.212997) tEnd=0.583904956 newWindSum=1 newOppSum=1 oppSum=1 windSum=1 windValue=1 oppValue=1
456cb93a386Sopenharmony_ciSkOpSegment::markWinding id=8 (8.17210007,104.212997 -5.82350016,369.813995) t=0 [15] (8.17210007,104.212997) tEnd=0.583904956 newWindSum=1 newOppSum=1 oppSum=1 windSum=1 windValue=1 oppValue=1
457cb93a386Sopenharmony_ciSkOpSegment::markWinding id=13 (118.119003,8.07219982 8.17210007,104.212997) t=0 [25] (118.119003,8.07219982) tEnd=1 newWindSum=1 newOppSum=1 oppSum=? windSum=? windValue=1 oppValue=1
458cb93a386Sopenharmony_ciSkOpSegment::markWinding id=4 (123.289001,9.39610004 118.119003,8.07219982) t=0 [7] (123.289001,9.39610004) tEnd=1 newWindSum=1 newOppSum=1 oppSum=? windSum=? windValue=1 oppValue=1
459cb93a386Sopenharmony_ciSkOpSegment::markWinding id=11 (124.602829,9.37972069 124.142509,9.41722488 123.674164,9.45538425 123.289001,9.39620018) t=0.625 [35] (123.752594,9.4268837) tEnd=1 newWindSum=1 newOppSum=1 oppSum=? windSum=? windValue=1 oppValue=1
460cb93a386Sopenharmony_ciSkOpSegment::markWinding id=11 (124.602829,9.37972069 124.142509,9.41722488 123.674164,9.45538425 123.289001,9.39620018) t=0.0625 [33] (124.516449,9.38673687) tEnd=0.625 newWindSum=1 newOppSum=1 oppSum=? windSum=? windValue=1 oppValue=1
461cb93a386Sopenharmony_ciSkOpSegment::activeOp id=8 t=0.583904956 tEnd=0 op=sect miFrom=1 miTo=0 suFrom=1 suTo=0 result=1
462cb93a386Sopenharmony_ciSkOpSegment::findNextOp simple
463cb93a386Sopenharmony_ciSkOpSegment::markDone id=8 (8.17210007,104.212997 -5.82350016,369.813995) t=0 [15] (8.17210007,104.212997) tEnd=0.583904956 newWindSum=1 newOppSum=1 oppSum=1 windSum=1 windValue=1 oppValue=1
464cb93a386Sopenharmony_cibridgeOp current id=8 from=(-2.71619996e-07,259.298737) to=(8.17210007,104.212997)
465cb93a386Sopenharmony_ciSkOpSegment::findNextOp simple
466cb93a386Sopenharmony_ciSkOpSegment::markDone id=13 (118.119003,8.07219982 8.17210007,104.212997) t=0 [25] (118.119003,8.07219982) tEnd=1 newWindSum=1 newOppSum=1 oppSum=1 windSum=1 windValue=1 oppValue=1
467cb93a386Sopenharmony_cibridgeOp current id=13 from=(8.17210007,104.212997) to=(118.119003,8.07219982)
468cb93a386Sopenharmony_cipath.moveTo(-2.71619996e-07,259.298737);
469cb93a386Sopenharmony_cipath.lineTo(8.17210007,104.212997);
470cb93a386Sopenharmony_ciSkOpSegment::findNextOp simple
471cb93a386Sopenharmony_ciSkOpSegment::markDone id=4 (123.289001,9.39610004 118.119003,8.07219982) t=0 [7] (123.289001,9.39610004) tEnd=1 newWindSum=1 newOppSum=1 oppSum=1 windSum=1 windValue=1 oppValue=1
472cb93a386Sopenharmony_cibridgeOp current id=4 from=(118.119003,8.07219982) to=(123.289001,9.39610004)
473cb93a386Sopenharmony_cipath.lineTo(118.119003,8.07219982);
474cb93a386Sopenharmony_ciSkOpSegment::findNextOp simple
475cb93a386Sopenharmony_ciSkOpSegment::markDone id=11 (124.602829,9.37972069 124.142509,9.41722488 123.674164,9.45538425 123.289001,9.39620018) t=0.625 [35] (123.752594,9.4268837) tEnd=1 newWindSum=1 newOppSum=1 oppSum=1 windSum=1 windValue=1 oppValue=1
476cb93a386Sopenharmony_cibridgeOp current id=11 from=(123.289001,9.39620018) to=(123.752594,9.4268837)
477cb93a386Sopenharmony_cipath.lineTo(123.289001,9.39610004);
478cb93a386Sopenharmony_cipath.cubicTo(123.433441,9.41839409, 123.589569,9.42689991, 123.752594,9.4268837);
479cb93a386Sopenharmony_ciSkOpSegment::markWinding id=11 (124.602829,9.37972069 124.142509,9.41722488 123.674164,9.45538425 123.289001,9.39620018) t=0 [21] (124.602829,9.37972069) tEnd=0.0625 newWindSum=1 newOppSum=1 oppSum=? windSum=? windValue=1 oppValue=0
480cb93a386Sopenharmony_ciSkOpSegment::markWinding id=10 (126,9.39620018 125.631981,9.29586983 125.12252,9.3373785 124.602829,9.37972069) t=0.9375 [31] (124.700119,9.37182617) tEnd=1 newWindSum=1 newOppSum=1 oppSum=? windSum=? windValue=1 oppValue=0
481cb93a386Sopenharmony_ciSkOpSegment::markAngle last segment=10 span=31 windSum=1
482cb93a386Sopenharmony_ciSkOpSegment::markWinding id=3 (124.603165,9.37966728 124.142731,9.41717815 123.674263,9.45534515 123.289001,9.39610004) t=0 [5] (124.603165,9.37966728) tEnd=0.0627286673 newWindSum=1 newOppSum=0 oppSum=? windSum=? windValue=1 oppValue=0
483cb93a386Sopenharmony_ciSkOpSegment::markWinding id=2 (126,9.39610004 125.632057,9.29584408 125.122734,9.33733845 124.603165,9.37966728) t=0.937702598 [32] (124.700119,9.37180042) tEnd=1 newWindSum=1 newOppSum=0 oppSum=? windSum=? windValue=1 oppValue=0
484cb93a386Sopenharmony_ciSkOpSegment::markAngle last segment=2 span=32 windSum=1
485cb93a386Sopenharmony_ciSkOpSegment::findNextOp
486cb93a386Sopenharmony_ciSkOpAngle::dumpOne [11/9] next=11/8 sect=17/17  s=0.0625 [33] e=0.625 [35] sgn=-1 windVal=1 windSum=1 oppVal=1 oppSum=1 operand
487cb93a386Sopenharmony_ciSkOpAngle::dumpOne [11/8] next=3/20 sect=1/1  s=0.0625 [33] e=0 [21] sgn=1 windVal=1 windSum=1 oppVal=0 oppSum=1 operand
488cb93a386Sopenharmony_ciSkOpAngle::dumpOne [3/20] next=11/9 sect=1/1  s=0.0627286673 [34] e=0 [5] sgn=1 windVal=1 windSum=1 oppVal=0 oppSum=0
489cb93a386Sopenharmony_ciSkOpSegment::activeOp id=11 t=0.0625 tEnd=0 op=sect miFrom=1 miTo=1 suFrom=1 suTo=0 result=1
490cb93a386Sopenharmony_ciSkOpSegment::findNextOp chase.append segment=10 span=31 windSum=1
491cb93a386Sopenharmony_ciSkOpSegment::activeOp id=3 t=0.0627286673 tEnd=0 op=sect miFrom=1 miTo=0 suFrom=0 suTo=0 result=0
492cb93a386Sopenharmony_ciSkOpSegment::markDone id=3 (124.603165,9.37966728 124.142731,9.41717815 123.674263,9.45534515 123.289001,9.39610004) t=0 [5] (124.603165,9.37966728) tEnd=0.0627286673 newWindSum=1 newOppSum=0 oppSum=0 windSum=1 windValue=1 oppValue=0
493cb93a386Sopenharmony_ciSkOpSegment::markDone id=2 (126,9.39610004 125.632057,9.29584408 125.122734,9.33733845 124.603165,9.37966728) t=0.937702598 [32] (124.700119,9.37180042) tEnd=1 newWindSum=1 newOppSum=0 oppSum=0 windSum=1 windValue=1 oppValue=0
494cb93a386Sopenharmony_ciSkOpSegment::findNextOp chase.append segment=2 span=32 windSum=1
495cb93a386Sopenharmony_ciSkOpSegment::markDone id=11 (124.602829,9.37972069 124.142509,9.41722488 123.674164,9.45538425 123.289001,9.39620018) t=0.0625 [33] (124.516449,9.38673687) tEnd=0.625 newWindSum=1 newOppSum=1 oppSum=1 windSum=1 windValue=1 oppValue=1
496cb93a386Sopenharmony_ciSkOpSegment::findNextOp from:[11] to:[11] start=-1132576784 end=-1353716568
497cb93a386Sopenharmony_cibridgeOp current id=11 from=(123.752594,9.4268837) to=(124.516449,9.38673687)
498cb93a386Sopenharmony_cipath.cubicTo(123.997124,9.42685986, 124.257156,9.40766335, 124.516449,9.38673687);
499cb93a386Sopenharmony_ciSkOpSegment::findNextOp simple
500cb93a386Sopenharmony_ciSkOpSegment::markDone id=11 (124.602829,9.37972069 124.142509,9.41722488 123.674164,9.45538425 123.289001,9.39620018) t=0 [21] (124.602829,9.37972069) tEnd=0.0625 newWindSum=1 newOppSum=1 oppSum=1 windSum=1 windValue=1 oppValue=0
501cb93a386Sopenharmony_cibridgeOp current id=11 from=(124.516449,9.38673687) to=(124.602829,9.37972069)
502cb93a386Sopenharmony_cipath.cubicTo(124.545258,9.38441181, 124.574059,9.38206482, 124.602829,9.37972069);
503cb93a386Sopenharmony_ciSkOpSegment::markWinding id=2 (126,9.39610004 125.632057,9.29584408 125.122734,9.33733845 124.603165,9.37966728) t=0.307190555 [30] (125.624695,9.33975124) tEnd=0.937702598 newWindSum=1 newOppSum=-1 oppSum=? windSum=? windValue=1 oppValue=1
504cb93a386Sopenharmony_ciSkOpSegment::markWinding id=2 (126,9.39610004 125.632057,9.29584408 125.122734,9.33733845 124.603165,9.37966728) t=0 [3] (126,9.39610004) tEnd=0.307190555 newWindSum=1 newOppSum=-1 oppSum=? windSum=? windValue=1 oppValue=1
505cb93a386Sopenharmony_ciSkOpSegment::markWinding id=9 (-5.82350016,369.813995 126,9.39620018) t=0.0441765002 [28] (7.26031715e-07,353.891998) tEnd=1 newWindSum=-1 newOppSum=1 oppSum=? windSum=? windValue=1 oppValue=1
506cb93a386Sopenharmony_ciSkOpSegment::markAngle last segment=9 span=28 windSum=-1
507cb93a386Sopenharmony_ciSkOpSegment::findNextOp
508cb93a386Sopenharmony_ciSkOpAngle::dumpOne [10/7] next=2/19 sect=17/17  s=0.9375 [31] e=1 [20] sgn=-1 windVal=1 windSum=1 oppVal=0 oppSum=1 operand
509cb93a386Sopenharmony_ciSkOpAngle::dumpOne [2/19] next=2/18 sect=17/17  s=0.937702598 [32] e=1 [4] sgn=-1 windVal=1 windSum=1 oppVal=0 oppSum=0 done
510cb93a386Sopenharmony_ciSkOpAngle::dumpOne [2/18] next=10/7 sect=1/1  s=0.937702598 [32] e=0.307190555 [30] sgn=1 windVal=1 windSum=1 oppVal=1 oppSum=-1
511cb93a386Sopenharmony_ciSkOpSegment::activeOp id=2 t=0.937702598 tEnd=1 op=sect = result=1
512cb93a386Sopenharmony_ciSkOpSegment::activeOp id=2 t=0.937702598 tEnd=0.307190555 op=sect miFrom=0 miTo=1 suFrom=1 suTo=0 result=0
513cb93a386Sopenharmony_ciSkOpSegment::markDone id=2 (126,9.39610004 125.632057,9.29584408 125.122734,9.33733845 124.603165,9.37966728) t=0.307190555 [30] (125.624695,9.33975124) tEnd=0.937702598 newWindSum=1 newOppSum=-1 oppSum=-1 windSum=1 windValue=1 oppValue=1
514cb93a386Sopenharmony_ciSkOpSegment::markDone id=2 (126,9.39610004 125.632057,9.29584408 125.122734,9.33733845 124.603165,9.37966728) t=0 [3] (126,9.39610004) tEnd=0.307190555 newWindSum=1 newOppSum=-1 oppSum=-1 windSum=1 windValue=1 oppValue=1
515cb93a386Sopenharmony_ciSkOpSegment::markDone id=9 (-5.82350016,369.813995 126,9.39620018) t=0.0441765002 [28] (7.26031715e-07,353.891998) tEnd=1 newWindSum=-1 newOppSum=1 oppSum=1 windSum=-1 windValue=1 oppValue=1
516cb93a386Sopenharmony_ciSkOpSegment::findNextOp chase.append segment=9 span=28 windSum=-1
517cb93a386Sopenharmony_ciSkOpSegment::markDone id=10 (126,9.39620018 125.631981,9.29586983 125.12252,9.3373785 124.602829,9.37972069) t=0.9375 [31] (124.700119,9.37182617) tEnd=1 newWindSum=1 newOppSum=1 oppSum=1 windSum=1 windValue=1 oppValue=0
518cb93a386Sopenharmony_ciSkOpSegment::findNextOp from:[10] to:[2] start=-1132576976 end=-1353719496
519cb93a386Sopenharmony_cibridgeOp current id=10 from=(124.602829,9.37972069) to=(124.700119,9.37182617)
520cb93a386Sopenharmony_cipath.cubicTo(124.635307,9.37707424, 124.667747,9.37443161, 124.700119,9.37182617);
521cb93a386Sopenharmony_ciSkOpSegment::markWinding id=7 (0,259.298737 0,353.891998) t=0 [13] (0,259.298737) tEnd=1 newWindSum=1 newOppSum=0 oppSum=? windSum=? windValue=1 oppValue=0
522cb93a386Sopenharmony_ciSkOpSegment::markWinding id=9 (-5.82350016,369.813995 126,9.39620018) t=0 [17] (-5.82350016,369.813995) tEnd=0.0441765002 newWindSum=-1 newOppSum=0 oppSum=? windSum=? windValue=1 oppValue=0
523cb93a386Sopenharmony_ciSkOpSegment::markWinding id=8 (8.17210007,104.212997 -5.82350016,369.813995) t=0.583904956 [27] (-2.71619996e-07,259.298737) tEnd=1 newWindSum=-1 newOppSum=0 oppSum=? windSum=? windValue=1 oppValue=0
524cb93a386Sopenharmony_ciSkOpSegment::debugShowActiveSpans id=8 (-2.71619996e-07,259.298737 -5.82350016,369.813995) t=0.583904956 tEnd=1 windSum=-1 oppSum=0 windValue=1 oppValue=0
525cb93a386Sopenharmony_ciSkOpSegment::debugShowActiveSpans id=9 (-5.82350016,369.813995 7.26031715e-07,353.891998) t=0 tEnd=0.0441765002 windSum=-1 oppSum=0 windValue=1 oppValue=0
526cb93a386Sopenharmony_ciSkOpSegment::debugShowActiveSpans id=7 (0,259.298737 0,353.891998) t=0 tEnd=1 windSum=1 oppSum=0 windValue=1 oppValue=0
527cb93a386Sopenharmony_ciSkOpSegment::activeOp id=7 t=1 tEnd=0 op=sect miFrom=1 miTo=0 suFrom=0 suTo=0 result=0
528cb93a386Sopenharmony_ciSkOpSegment::markDone id=7 (0,259.298737 0,353.891998) t=0 [13] (0,259.298737) tEnd=1 newWindSum=1 newOppSum=0 oppSum=0 windSum=1 windValue=1 oppValue=0
529cb93a386Sopenharmony_cibridgeOp chase.append id=7 windSum=1
530cb93a386Sopenharmony_ciSkOpSegment::debugShowActiveSpans id=8 (-2.71619996e-07,259.298737 -5.82350016,369.813995) t=0.583904956 tEnd=1 windSum=-1 oppSum=0 windValue=1 oppValue=0
531cb93a386Sopenharmony_ciSkOpSegment::debugShowActiveSpans id=9 (-5.82350016,369.813995 7.26031715e-07,353.891998) t=0 tEnd=0.0441765002 windSum=-1 oppSum=0 windValue=1 oppValue=0
532cb93a386Sopenharmony_ciSkOpSegment::activeOp id=8 t=0.583904956 tEnd=1 op=sect miFrom=0 miTo=0 suFrom=1 suTo=0 result=0
533cb93a386Sopenharmony_ciSkOpSegment::markDone id=8 (8.17210007,104.212997 -5.82350016,369.813995) t=0.583904956 [27] (-2.71619996e-07,259.298737) tEnd=1 newWindSum=-1 newOppSum=0 oppSum=0 windSum=-1 windValue=1 oppValue=0
534cb93a386Sopenharmony_ciSkOpSegment::markDone id=9 (-5.82350016,369.813995 126,9.39620018) t=0 [17] (-5.82350016,369.813995) tEnd=0.0441765002 newWindSum=-1 newOppSum=0 oppSum=0 windSum=-1 windValue=1 oppValue=0
535cb93a386Sopenharmony_ci</div>
536cb93a386Sopenharmony_ci
537cb93a386Sopenharmony_ci
538cb93a386Sopenharmony_ci
539cb93a386Sopenharmony_ci    </div>
540cb93a386Sopenharmony_ci
541cb93a386Sopenharmony_ci<script type="text/javascript">
542cb93a386Sopenharmony_ci
543cb93a386Sopenharmony_ci    var testDivs = [
544cb93a386Sopenharmony_ci        bug8380,
545cb93a386Sopenharmony_ci    ];
546cb93a386Sopenharmony_ci
547cb93a386Sopenharmony_civar decimal_places = 3; // make this 3 to show more precision
548cb93a386Sopenharmony_ci
549cb93a386Sopenharmony_civar tests = [];
550cb93a386Sopenharmony_civar testLines = [];
551cb93a386Sopenharmony_civar testTitles = [];
552cb93a386Sopenharmony_civar testIndex = 0;
553cb93a386Sopenharmony_civar ctx;
554cb93a386Sopenharmony_ci
555cb93a386Sopenharmony_civar xmin, xmax, focusXmin, focusXmax;
556cb93a386Sopenharmony_civar ymin, ymax, focusYmin, focusYmax;
557cb93a386Sopenharmony_civar scale;
558cb93a386Sopenharmony_civar mouseX, mouseY;
559cb93a386Sopenharmony_civar srcLeft, srcTop;
560cb93a386Sopenharmony_civar screenWidth, screenHeight;
561cb93a386Sopenharmony_civar drawnPts, drawnLines, drawnQuads, drawnConics, drawnCubics;
562cb93a386Sopenharmony_civar curveT = 0;
563cb93a386Sopenharmony_ci
564cb93a386Sopenharmony_civar pt_labels = 2;
565cb93a386Sopenharmony_civar collect_bounds = false;
566cb93a386Sopenharmony_civar control_lines = 0;
567cb93a386Sopenharmony_civar curve_t = false;
568cb93a386Sopenharmony_civar debug_xy = 1;
569cb93a386Sopenharmony_civar focus_enabled = false;
570cb93a386Sopenharmony_civar focus_on_selection = false;
571cb93a386Sopenharmony_civar step_limit = 0;
572cb93a386Sopenharmony_civar draw_active = false;
573cb93a386Sopenharmony_civar draw_add = false;
574cb93a386Sopenharmony_civar draw_angle = 0;
575cb93a386Sopenharmony_civar draw_coincidence = false;
576cb93a386Sopenharmony_civar draw_deriviatives = 0;
577cb93a386Sopenharmony_civar draw_direction = false;
578cb93a386Sopenharmony_civar draw_hints = false;
579cb93a386Sopenharmony_civar draw_id = false;
580cb93a386Sopenharmony_civar draw_intersection = 0;
581cb93a386Sopenharmony_civar draw_intersectT = false;
582cb93a386Sopenharmony_civar draw_legend = true;
583cb93a386Sopenharmony_civar draw_log = false;
584cb93a386Sopenharmony_civar draw_mark = false;
585cb93a386Sopenharmony_civar draw_midpoint = false;
586cb93a386Sopenharmony_civar draw_op = 0;
587cb93a386Sopenharmony_civar draw_sequence = false;
588cb93a386Sopenharmony_civar draw_sort = 0;
589cb93a386Sopenharmony_civar draw_top = false;
590cb93a386Sopenharmony_civar draw_path = 3;
591cb93a386Sopenharmony_civar draw_computed = 0;
592cb93a386Sopenharmony_civar retina_scale = !!window.devicePixelRatio;
593cb93a386Sopenharmony_ci
594cb93a386Sopenharmony_civar activeCount = 0;
595cb93a386Sopenharmony_civar addCount = 0;
596cb93a386Sopenharmony_civar angleCount = 0;
597cb93a386Sopenharmony_civar coinCount = 0;
598cb93a386Sopenharmony_civar opCount = 0;
599cb93a386Sopenharmony_civar sectCount = 0;
600cb93a386Sopenharmony_civar sortCount = 0;
601cb93a386Sopenharmony_civar topCount = 0;
602cb93a386Sopenharmony_civar markCount = 0;
603cb93a386Sopenharmony_civar activeMax = 0;
604cb93a386Sopenharmony_civar addMax = 0;
605cb93a386Sopenharmony_civar angleMax = 0;
606cb93a386Sopenharmony_civar coinMax = 0;
607cb93a386Sopenharmony_civar sectMax = 0;
608cb93a386Sopenharmony_civar sectMax2 = 0;
609cb93a386Sopenharmony_civar sortMax = 0;
610cb93a386Sopenharmony_civar topMax = 0;
611cb93a386Sopenharmony_civar markMax = 0;
612cb93a386Sopenharmony_civar opMax = 0;
613cb93a386Sopenharmony_civar stepMax = 0;
614cb93a386Sopenharmony_civar lastIndex = 0;
615cb93a386Sopenharmony_civar hasPath = false;
616cb93a386Sopenharmony_civar hasAlignedPath = false;
617cb93a386Sopenharmony_civar hasComputedPath = false;
618cb93a386Sopenharmony_civar angleBetween = false;
619cb93a386Sopenharmony_civar afterIndex = 0;
620cb93a386Sopenharmony_ci
621cb93a386Sopenharmony_civar firstActiveSpan = -1;
622cb93a386Sopenharmony_civar logStart = -1;
623cb93a386Sopenharmony_civar logRange = 0;
624cb93a386Sopenharmony_ci
625cb93a386Sopenharmony_civar SPAN_ID = 0;
626cb93a386Sopenharmony_civar SPAN_X1 = SPAN_ID + 1;
627cb93a386Sopenharmony_civar SPAN_Y1 = SPAN_X1 + 1;
628cb93a386Sopenharmony_civar SPAN_X2 = SPAN_Y1 + 1;
629cb93a386Sopenharmony_civar SPAN_Y2 = SPAN_X2 + 1;
630cb93a386Sopenharmony_ci
631cb93a386Sopenharmony_civar SPAN_L_TX = SPAN_Y2 + 1;
632cb93a386Sopenharmony_civar SPAN_L_TY = SPAN_L_TX + 1;
633cb93a386Sopenharmony_civar SPAN_L_OTHER = SPAN_L_TY + 1;
634cb93a386Sopenharmony_civar SPAN_L_OTHERT = SPAN_L_OTHER + 1;
635cb93a386Sopenharmony_civar SPAN_L_OTHERI = SPAN_L_OTHERT + 1;
636cb93a386Sopenharmony_civar SPAN_L_SUM = SPAN_L_OTHERI + 1;
637cb93a386Sopenharmony_civar SPAN_L_VAL = SPAN_L_SUM + 1;
638cb93a386Sopenharmony_civar SPAN_L_OPP = SPAN_L_VAL + 1;
639cb93a386Sopenharmony_ci
640cb93a386Sopenharmony_civar SPAN_X3 = SPAN_Y2 + 1;
641cb93a386Sopenharmony_civar SPAN_Y3 = SPAN_X3 + 1;
642cb93a386Sopenharmony_ci
643cb93a386Sopenharmony_civar SPAN_Q_TX = SPAN_Y3 + 1;
644cb93a386Sopenharmony_civar SPAN_Q_TY = SPAN_Q_TX + 1;
645cb93a386Sopenharmony_civar SPAN_Q_OTHER = SPAN_Q_TY + 1;
646cb93a386Sopenharmony_civar SPAN_Q_OTHERT = SPAN_Q_OTHER + 1;
647cb93a386Sopenharmony_civar SPAN_Q_OTHERI = SPAN_Q_OTHERT + 1;
648cb93a386Sopenharmony_civar SPAN_Q_SUM = SPAN_Q_OTHERI + 1;
649cb93a386Sopenharmony_civar SPAN_Q_VAL = SPAN_Q_SUM + 1;
650cb93a386Sopenharmony_civar SPAN_Q_OPP = SPAN_Q_VAL + 1;
651cb93a386Sopenharmony_ci
652cb93a386Sopenharmony_civar SPAN_K_W = SPAN_Y3 + 1;
653cb93a386Sopenharmony_civar SPAN_K_TX = SPAN_K_W + 1;
654cb93a386Sopenharmony_civar SPAN_K_TY = SPAN_K_TX + 1;
655cb93a386Sopenharmony_civar SPAN_K_OTHER = SPAN_K_TY + 1;
656cb93a386Sopenharmony_civar SPAN_K_OTHERT = SPAN_K_OTHER + 1;
657cb93a386Sopenharmony_civar SPAN_K_OTHERI = SPAN_K_OTHERT + 1;
658cb93a386Sopenharmony_civar SPAN_K_SUM = SPAN_K_OTHERI + 1;
659cb93a386Sopenharmony_civar SPAN_K_VAL = SPAN_K_SUM + 1;
660cb93a386Sopenharmony_civar SPAN_K_OPP = SPAN_K_VAL + 1;
661cb93a386Sopenharmony_ci
662cb93a386Sopenharmony_civar SPAN_X4 = SPAN_Y3 + 1;
663cb93a386Sopenharmony_civar SPAN_Y4 = SPAN_X4 + 1;
664cb93a386Sopenharmony_ci
665cb93a386Sopenharmony_civar SPAN_C_TX = SPAN_Y4 + 1;
666cb93a386Sopenharmony_civar SPAN_C_TY = SPAN_C_TX + 1;
667cb93a386Sopenharmony_civar SPAN_C_OTHER = SPAN_C_TY + 1;
668cb93a386Sopenharmony_civar SPAN_C_OTHERT = SPAN_C_OTHER + 1;
669cb93a386Sopenharmony_civar SPAN_C_OTHERI = SPAN_C_OTHERT + 1;
670cb93a386Sopenharmony_civar SPAN_C_SUM = SPAN_C_OTHERI + 1;
671cb93a386Sopenharmony_civar SPAN_C_VAL = SPAN_C_SUM + 1;
672cb93a386Sopenharmony_civar SPAN_C_OPP = SPAN_C_VAL + 1;
673cb93a386Sopenharmony_ci
674cb93a386Sopenharmony_civar ACTIVE_LINE_SPAN =        1;
675cb93a386Sopenharmony_civar ACTIVE_QUAD_SPAN =        ACTIVE_LINE_SPAN + 1;
676cb93a386Sopenharmony_civar ACTIVE_CONIC_SPAN =       ACTIVE_QUAD_SPAN + 1;
677cb93a386Sopenharmony_civar ACTIVE_CUBIC_SPAN =       ACTIVE_CONIC_SPAN + 1;
678cb93a386Sopenharmony_ci
679cb93a386Sopenharmony_civar ADD_MOVETO =              ACTIVE_CUBIC_SPAN + 1;
680cb93a386Sopenharmony_civar ADD_LINETO =              ADD_MOVETO + 1;
681cb93a386Sopenharmony_civar ADD_QUADTO =              ADD_LINETO + 1;
682cb93a386Sopenharmony_civar ADD_CONICTO =             ADD_QUADTO + 1;
683cb93a386Sopenharmony_civar ADD_CUBICTO =             ADD_CONICTO + 1;
684cb93a386Sopenharmony_civar ADD_CLOSE =               ADD_CUBICTO + 1;
685cb93a386Sopenharmony_civar ADD_FILL =                ADD_CLOSE + 1;
686cb93a386Sopenharmony_ci
687cb93a386Sopenharmony_civar PATH_LINE =               ADD_FILL + 1;
688cb93a386Sopenharmony_civar PATH_QUAD =               PATH_LINE + 1;
689cb93a386Sopenharmony_civar PATH_CONIC =              PATH_QUAD + 1;
690cb93a386Sopenharmony_civar PATH_CUBIC =              PATH_CONIC + 1;
691cb93a386Sopenharmony_ci
692cb93a386Sopenharmony_civar INTERSECT_LINE =          PATH_CUBIC + 1;
693cb93a386Sopenharmony_civar INTERSECT_LINE_2 =        INTERSECT_LINE + 1;
694cb93a386Sopenharmony_civar INTERSECT_LINE_NO =       INTERSECT_LINE_2 + 1;
695cb93a386Sopenharmony_civar INTERSECT_QUAD_LINE =     INTERSECT_LINE_NO + 1;
696cb93a386Sopenharmony_civar INTERSECT_QUAD_LINE_2 =   INTERSECT_QUAD_LINE + 1;
697cb93a386Sopenharmony_civar INTERSECT_QUAD_LINE_NO =  INTERSECT_QUAD_LINE_2 + 1;
698cb93a386Sopenharmony_civar INTERSECT_QUAD =          INTERSECT_QUAD_LINE_NO + 1;
699cb93a386Sopenharmony_civar INTERSECT_QUAD_2 =        INTERSECT_QUAD + 1;
700cb93a386Sopenharmony_civar INTERSECT_QUAD_NO =       INTERSECT_QUAD_2 + 1;
701cb93a386Sopenharmony_civar INTERSECT_CONIC_LINE =    INTERSECT_QUAD_NO + 1;
702cb93a386Sopenharmony_civar INTERSECT_CONIC_LINE_2 =  INTERSECT_CONIC_LINE + 1;
703cb93a386Sopenharmony_civar INTERSECT_CONIC_LINE_NO = INTERSECT_CONIC_LINE_2 + 1;
704cb93a386Sopenharmony_civar INTERSECT_CONIC_QUAD =    INTERSECT_CONIC_LINE_NO + 1;
705cb93a386Sopenharmony_civar INTERSECT_CONIC_QUAD_2 =  INTERSECT_CONIC_QUAD + 1;
706cb93a386Sopenharmony_civar INTERSECT_CONIC_QUAD_3 =  INTERSECT_CONIC_QUAD_2 + 1;
707cb93a386Sopenharmony_civar INTERSECT_CONIC_QUAD_4 =  INTERSECT_CONIC_QUAD_3 + 1;
708cb93a386Sopenharmony_civar INTERSECT_CONIC_QUAD_NO = INTERSECT_CONIC_QUAD_4 + 1;
709cb93a386Sopenharmony_civar INTERSECT_CONIC =         INTERSECT_CONIC_QUAD_NO + 1;
710cb93a386Sopenharmony_civar INTERSECT_CONIC_2 =       INTERSECT_CONIC + 1;
711cb93a386Sopenharmony_civar INTERSECT_CONIC_NO =      INTERSECT_CONIC_2 + 1;
712cb93a386Sopenharmony_civar INTERSECT_SELF_CUBIC =    INTERSECT_CONIC_NO + 1;
713cb93a386Sopenharmony_civar INTERSECT_SELF_CUBIC_NO = INTERSECT_SELF_CUBIC + 1;
714cb93a386Sopenharmony_civar INTERSECT_CUBIC_LINE =    INTERSECT_SELF_CUBIC_NO + 1;
715cb93a386Sopenharmony_civar INTERSECT_CUBIC_LINE_2 =  INTERSECT_CUBIC_LINE + 1;
716cb93a386Sopenharmony_civar INTERSECT_CUBIC_LINE_3 =  INTERSECT_CUBIC_LINE_2 + 1;
717cb93a386Sopenharmony_civar INTERSECT_CUBIC_LINE_NO = INTERSECT_CUBIC_LINE_3 + 1;
718cb93a386Sopenharmony_civar INTERSECT_CUBIC_QUAD =    INTERSECT_CUBIC_LINE_NO + 1;
719cb93a386Sopenharmony_civar INTERSECT_CUBIC_QUAD_2 =  INTERSECT_CUBIC_QUAD + 1;
720cb93a386Sopenharmony_civar INTERSECT_CUBIC_QUAD_3 =  INTERSECT_CUBIC_QUAD_2 + 1;
721cb93a386Sopenharmony_civar INTERSECT_CUBIC_QUAD_4 =  INTERSECT_CUBIC_QUAD_3 + 1;
722cb93a386Sopenharmony_civar INTERSECT_CUBIC_QUAD_NO = INTERSECT_CUBIC_QUAD_4 + 1;
723cb93a386Sopenharmony_civar INTERSECT_CUBIC =         INTERSECT_CUBIC_QUAD_NO + 1;
724cb93a386Sopenharmony_civar INTERSECT_CUBIC_2 =       INTERSECT_CUBIC + 1;
725cb93a386Sopenharmony_civar INTERSECT_CUBIC_3 =       INTERSECT_CUBIC_2 + 1;
726cb93a386Sopenharmony_civar INTERSECT_CUBIC_4 =       INTERSECT_CUBIC_3 + 1;
727cb93a386Sopenharmony_ci// FIXME: add cubic 5- 9
728cb93a386Sopenharmony_civar INTERSECT_CUBIC_NO =      INTERSECT_CUBIC_4 + 1;
729cb93a386Sopenharmony_ci
730cb93a386Sopenharmony_civar SORT_UNARY =              INTERSECT_CUBIC_NO + 1;
731cb93a386Sopenharmony_civar SORT_BINARY =             SORT_UNARY + 1;
732cb93a386Sopenharmony_ci
733cb93a386Sopenharmony_civar OP_DIFFERENCE =           SORT_BINARY + 1;
734cb93a386Sopenharmony_civar OP_INTERSECT =            OP_DIFFERENCE + 1;
735cb93a386Sopenharmony_civar OP_UNION =                OP_INTERSECT + 1;
736cb93a386Sopenharmony_civar OP_XOR =                  OP_UNION + 1;
737cb93a386Sopenharmony_ci
738cb93a386Sopenharmony_civar MARK_LINE =               OP_XOR + 1;
739cb93a386Sopenharmony_civar MARK_QUAD =               MARK_LINE + 1;
740cb93a386Sopenharmony_civar MARK_CONIC =              MARK_QUAD + 1;
741cb93a386Sopenharmony_civar MARK_CUBIC =              MARK_CONIC + 1;
742cb93a386Sopenharmony_civar MARK_DONE_LINE =          MARK_CUBIC + 1;
743cb93a386Sopenharmony_civar MARK_DONE_QUAD =          MARK_DONE_LINE + 1;
744cb93a386Sopenharmony_civar MARK_DONE_CONIC =         MARK_DONE_QUAD + 1;
745cb93a386Sopenharmony_civar MARK_DONE_CUBIC =         MARK_DONE_CONIC + 1;
746cb93a386Sopenharmony_civar MARK_UNSORTABLE_LINE =    MARK_DONE_CUBIC + 1;
747cb93a386Sopenharmony_civar MARK_UNSORTABLE_QUAD =    MARK_UNSORTABLE_LINE + 1;
748cb93a386Sopenharmony_civar MARK_UNSORTABLE_CONIC =   MARK_UNSORTABLE_QUAD + 1;
749cb93a386Sopenharmony_civar MARK_UNSORTABLE_CUBIC =   MARK_UNSORTABLE_CONIC + 1;
750cb93a386Sopenharmony_civar MARK_SIMPLE_LINE =        MARK_UNSORTABLE_CUBIC + 1;
751cb93a386Sopenharmony_civar MARK_SIMPLE_QUAD =        MARK_SIMPLE_LINE + 1;
752cb93a386Sopenharmony_civar MARK_SIMPLE_CONIC =       MARK_SIMPLE_QUAD + 1;
753cb93a386Sopenharmony_civar MARK_SIMPLE_CUBIC =       MARK_SIMPLE_CONIC + 1;
754cb93a386Sopenharmony_civar MARK_SIMPLE_DONE_LINE =   MARK_SIMPLE_CUBIC + 1;
755cb93a386Sopenharmony_civar MARK_SIMPLE_DONE_QUAD =   MARK_SIMPLE_DONE_LINE + 1;
756cb93a386Sopenharmony_civar MARK_SIMPLE_DONE_CONIC =  MARK_SIMPLE_DONE_QUAD + 1;
757cb93a386Sopenharmony_civar MARK_SIMPLE_DONE_CUBIC =  MARK_SIMPLE_DONE_CONIC + 1;
758cb93a386Sopenharmony_civar MARK_DONE_UNARY_LINE =    MARK_SIMPLE_DONE_CUBIC + 1;
759cb93a386Sopenharmony_civar MARK_DONE_UNARY_QUAD =    MARK_DONE_UNARY_LINE + 1;
760cb93a386Sopenharmony_civar MARK_DONE_UNARY_CONIC =   MARK_DONE_UNARY_QUAD + 1;
761cb93a386Sopenharmony_civar MARK_DONE_UNARY_CUBIC =   MARK_DONE_UNARY_CONIC + 1;
762cb93a386Sopenharmony_civar MARK_ANGLE_LAST =         MARK_DONE_UNARY_CUBIC + 1;
763cb93a386Sopenharmony_ci
764cb93a386Sopenharmony_civar COMPUTED_SET_1 =          MARK_ANGLE_LAST + 1;
765cb93a386Sopenharmony_civar COMPUTED_SET_2 =          COMPUTED_SET_1 + 1;
766cb93a386Sopenharmony_ci
767cb93a386Sopenharmony_civar ANGLE_AFTER =             COMPUTED_SET_2 + 1;
768cb93a386Sopenharmony_civar ANGLE_AFTERPART =         ANGLE_AFTER + 1;
769cb93a386Sopenharmony_ci
770cb93a386Sopenharmony_civar ACTIVE_OP =               ANGLE_AFTERPART + 1;
771cb93a386Sopenharmony_ci
772cb93a386Sopenharmony_civar COIN_MAIN_SPAN =          ACTIVE_OP + 1;
773cb93a386Sopenharmony_civar COIN_OPP_SPAN =           COIN_MAIN_SPAN + 1;
774cb93a386Sopenharmony_ci
775cb93a386Sopenharmony_civar FRAG_TYPE_LAST =          COIN_OPP_SPAN;
776cb93a386Sopenharmony_ci
777cb93a386Sopenharmony_civar REC_TYPE_UNKNOWN = -1;
778cb93a386Sopenharmony_civar REC_TYPE_PATH = 0;
779cb93a386Sopenharmony_civar REC_TYPE_PATH2 = 1;
780cb93a386Sopenharmony_civar REC_TYPE_SECT = 2;
781cb93a386Sopenharmony_civar REC_TYPE_ACTIVE = 3;
782cb93a386Sopenharmony_civar REC_TYPE_ADD = 4;
783cb93a386Sopenharmony_civar REC_TYPE_SORT = 5;
784cb93a386Sopenharmony_civar REC_TYPE_OP = 6;
785cb93a386Sopenharmony_civar REC_TYPE_MARK = 7;
786cb93a386Sopenharmony_civar REC_TYPE_COMPUTED = 8;
787cb93a386Sopenharmony_civar REC_TYPE_COIN = 9;
788cb93a386Sopenharmony_civar REC_TYPE_ANGLE = 10;
789cb93a386Sopenharmony_civar REC_TYPE_ACTIVE_OP = 11;
790cb93a386Sopenharmony_civar REC_TYPE_AFTERPART = 12;
791cb93a386Sopenharmony_civar REC_TYPE_TOP = 13;
792cb93a386Sopenharmony_civar REC_TYPE_COINCIDENCE = 14;
793cb93a386Sopenharmony_civar REC_TYPE_ALIGNED = 15;
794cb93a386Sopenharmony_civar REC_TYPE_LAST = REC_TYPE_ALIGNED;
795cb93a386Sopenharmony_ci
796cb93a386Sopenharmony_cifunction strs_to_nums(strs) {
797cb93a386Sopenharmony_ci    var result = [];
798cb93a386Sopenharmony_ci    for (var idx = 1; idx < strs.length; ++idx) {
799cb93a386Sopenharmony_ci        var str = strs[idx];
800cb93a386Sopenharmony_ci        var num = parseFloat(str);
801cb93a386Sopenharmony_ci        if (isNaN(num)) {
802cb93a386Sopenharmony_ci            result.push(str);
803cb93a386Sopenharmony_ci        } else {
804cb93a386Sopenharmony_ci            result.push(num);
805cb93a386Sopenharmony_ci        }
806cb93a386Sopenharmony_ci    }
807cb93a386Sopenharmony_ci    return result;
808cb93a386Sopenharmony_ci}
809cb93a386Sopenharmony_ci
810cb93a386Sopenharmony_cifunction filter_str_by(id, str, regex, array) {
811cb93a386Sopenharmony_ci    if (regex.test(str)) {
812cb93a386Sopenharmony_ci        var strs = regex.exec(str);
813cb93a386Sopenharmony_ci        var result = strs_to_nums(strs);
814cb93a386Sopenharmony_ci        array.push(id);
815cb93a386Sopenharmony_ci        array.push(result);
816cb93a386Sopenharmony_ci        return true;
817cb93a386Sopenharmony_ci    }
818cb93a386Sopenharmony_ci    return false;
819cb93a386Sopenharmony_ci}
820cb93a386Sopenharmony_ci
821cb93a386Sopenharmony_cifunction construct_regexp2(pattern) {
822cb93a386Sopenharmony_ci    var escape = pattern.replace(/[-/\\^$*+?.()|[\]{}]/g, '\\$&');
823cb93a386Sopenharmony_ci    escape = escape.replace(/UNSORTABLE/g, "\\*\\*\\* UNSORTABLE \\*\\*\\*");
824cb93a386Sopenharmony_ci    escape = escape.replace(/CUBIC_VAL/g, "\\(P_VAL P_VAL P_VAL P_VAL\\)");
825cb93a386Sopenharmony_ci    escape = escape.replace(/CONIC_VAL/g, "\\(P_VAL P_VAL P_VAL W_VAL\\)");
826cb93a386Sopenharmony_ci    escape = escape.replace(/QUAD_VAL/g, "\\(P_VAL P_VAL P_VAL\\)");
827cb93a386Sopenharmony_ci    escape = escape.replace(/LINE_VAL/g, "\\(P_VAL P_VAL\\)");
828cb93a386Sopenharmony_ci    escape = escape.replace(/FILL_TYPE/g, "SkPath::k[a-zA-Z]+_FillType");
829cb93a386Sopenharmony_ci    escape = escape.replace(/PTR_VAL/g, "0x[0-9A-F]+");
830cb93a386Sopenharmony_ci    escape = escape.replace(/PT_VAL/g, "\\(P_VAL\\)");
831cb93a386Sopenharmony_ci    escape = escape.replace(/P_VAL/g, "(-?\\d+\\.?\\d*(?:e[+-]?\\d+)?)[Ff]?, ?(-?\\d+\\.?\\d*(?:e[+-]?\\d+)?)[Ff]?");
832cb93a386Sopenharmony_ci    escape = escape.replace(/T_VAL/g, "(-?\\d+\\.?\\d*(?:e[+-]?\\d+)?)");
833cb93a386Sopenharmony_ci    escape = escape.replace(/W_VAL/g, "(-?\\d+\\.?\\d*(?:e[+-]?\\d+)?)[Ff]?");
834cb93a386Sopenharmony_ci    escape = escape.replace(/PATH/g, "pathB?");
835cb93a386Sopenharmony_ci    escape = escape.replace(/IDX/g, "(-?\\d+)");
836cb93a386Sopenharmony_ci    escape = escape.replace(/NUM/g, "(-?\\d+)");
837cb93a386Sopenharmony_ci    escape = escape.replace(/OPT/g, "(\\?|-?\\d+)");
838cb93a386Sopenharmony_ci    return new RegExp(escape, 'i');
839cb93a386Sopenharmony_ci}
840cb93a386Sopenharmony_ci
841cb93a386Sopenharmony_cifunction construct_regexp2c(pattern) {
842cb93a386Sopenharmony_ci    var escape = pattern.replace(/[-/\\^$*+?.()|[\]{}]/g, '\\$&');
843cb93a386Sopenharmony_ci    escape = escape.replace(/UNSORTABLE/g, "\\*\\*\\* UNSORTABLE \\*\\*\\*");
844cb93a386Sopenharmony_ci    escape = escape.replace(/CUBIC_VAL/g, "(?:\\$\\d = )?\\{\\{\\{P_VAL\\}, \\{P_VAL\\}, \\{P_VAL\\}, \\{P_VAL\\}\\}\\}");
845cb93a386Sopenharmony_ci    escape = escape.replace(/CONIC_VAL/g, "(?:\\$\\d = )?\\{\\{\\{\\{P_VAL\\}, \\{P_VAL\\}, \\{P_VAL\\}\\}\\}, W_VAL\\}");
846cb93a386Sopenharmony_ci    escape = escape.replace(/QUAD_VAL/g, "(?:\\$\\d = )?\\{\\{\\{P_VAL\\}, \\{P_VAL\\}, \\{P_VAL\\}\\}\\}");
847cb93a386Sopenharmony_ci    escape = escape.replace(/LINE_VAL/g, "(?:\\$\\d = )?\\{\\{\\{P_VAL\\}, \\{P_VAL\\}\\}\\}");
848cb93a386Sopenharmony_ci    escape = escape.replace(/FILL_TYPE/g, "SkPath::k[a-zA-Z]+_FillType");
849cb93a386Sopenharmony_ci    escape = escape.replace(/PTR_VAL/g, "0x[0-9A-F]+");
850cb93a386Sopenharmony_ci    escape = escape.replace(/PT_VAL/g, "\\{\\{P_VAL\\}\\}");
851cb93a386Sopenharmony_ci    escape = escape.replace(/P_VAL/g, "(?:f?[xX] = )?(-?\\d+\\.?\\d*(?:e[+-]?\\d+)?)[Ff]?, *(?: f?[yY] = )?(-?\\d+\\.?\\d*(?:e[+-]?\\d+)?)[Ff]?");
852cb93a386Sopenharmony_ci    escape = escape.replace(/T_VAL/g, "(-?\\d+\\.?\\d*(?:e[+-]?\\d+)?)");
853cb93a386Sopenharmony_ci    escape = escape.replace(/W_VAL/g, "(-?\\d+\\.?\\d*(?:e[+-]?\\d+)?)[Ff]?");
854cb93a386Sopenharmony_ci    escape = escape.replace(/OPER/g, "[a-z]+");
855cb93a386Sopenharmony_ci    escape = escape.replace(/PATH/g, "pathB?");
856cb93a386Sopenharmony_ci    escape = escape.replace(/T_F/g, "([TF])");
857cb93a386Sopenharmony_ci    escape = escape.replace(/IDX/g, "(-?\\d+)");
858cb93a386Sopenharmony_ci    escape = escape.replace(/NUM/g, "(-?\\d+)");
859cb93a386Sopenharmony_ci    escape = escape.replace(/OPT/g, "(\\?|-?\\d+)");
860cb93a386Sopenharmony_ci    return new RegExp(escape, 'i');
861cb93a386Sopenharmony_ci}
862cb93a386Sopenharmony_ci
863cb93a386Sopenharmony_cifunction match_regexp(str, lineNo, array, id, pattern) {
864cb93a386Sopenharmony_ci    var regex = construct_regexp2(pattern);
865cb93a386Sopenharmony_ci    if (filter_str_by(id, str, regex, array)) {
866cb93a386Sopenharmony_ci        return true;
867cb93a386Sopenharmony_ci    }
868cb93a386Sopenharmony_ci    regex = construct_regexp2c(pattern);
869cb93a386Sopenharmony_ci    return filter_str_by(id, str, regex, array);
870cb93a386Sopenharmony_ci}
871cb93a386Sopenharmony_ci
872cb93a386Sopenharmony_cifunction endsWith(str, suffix) {
873cb93a386Sopenharmony_ci    return str.indexOf(suffix, str.length - suffix.length) !== -1;
874cb93a386Sopenharmony_ci}
875cb93a386Sopenharmony_ci
876cb93a386Sopenharmony_cifunction parse_all(test) {
877cb93a386Sopenharmony_ci    var lines = test.match(/[^\r\n]+/g);
878cb93a386Sopenharmony_ci    var records = []; // a rec can be the original paths, a set of intersections, a set of active spans, a sort, or a path add
879cb93a386Sopenharmony_ci    var record = [];
880cb93a386Sopenharmony_ci    var recType = REC_TYPE_UNKNOWN;
881cb93a386Sopenharmony_ci    var lastLineNo;
882cb93a386Sopenharmony_ci    var moveX, moveY;
883cb93a386Sopenharmony_ci    for (var lineNo = 0; lineNo < lines.length; ++lineNo) {
884cb93a386Sopenharmony_ci        var line = lines[lineNo];
885cb93a386Sopenharmony_ci        if (line.length == 0) {
886cb93a386Sopenharmony_ci            continue;
887cb93a386Sopenharmony_ci        }
888cb93a386Sopenharmony_ci        var opStart = "SkOpSegment::";
889cb93a386Sopenharmony_ci        if (line.lastIndexOf(opStart, 0) === 0) {
890cb93a386Sopenharmony_ci            line = line.substr(opStart.length);
891cb93a386Sopenharmony_ci        }
892cb93a386Sopenharmony_ci        var angleStart = "SkOpAngle::";
893cb93a386Sopenharmony_ci        if (line.lastIndexOf(angleStart, 0) === 0) {
894cb93a386Sopenharmony_ci            line = line.substr(angleStart.length);
895cb93a386Sopenharmony_ci        }
896cb93a386Sopenharmony_ci        var coinStart = "SkOpCoincidence::";
897cb93a386Sopenharmony_ci        if (line.lastIndexOf(coinStart, 0) === 0) {
898cb93a386Sopenharmony_ci            line = line.substr(coinStart.length);
899cb93a386Sopenharmony_ci        }
900cb93a386Sopenharmony_ci        var type = line.lastIndexOf("debugShowActiveSpans", 0) === 0 ? REC_TYPE_ACTIVE
901cb93a386Sopenharmony_ci                : line.lastIndexOf("debugShowCoincidence", 0) === 0 ? REC_TYPE_COINCIDENCE
902cb93a386Sopenharmony_ci                : line.lastIndexOf("((SkOpSegment*)", 0) === 0 ? REC_TYPE_PATH2
903cb93a386Sopenharmony_ci                : line.lastIndexOf("debugShowTs", 0) === 0 ? REC_TYPE_COIN
904cb93a386Sopenharmony_ci                : line.lastIndexOf("afterPart", 0) === 0 ? REC_TYPE_AFTERPART
905cb93a386Sopenharmony_ci                : line.lastIndexOf("debugShow", 0) === 0 ? REC_TYPE_SECT
906cb93a386Sopenharmony_ci                : line.lastIndexOf("activeOp", 0) === 0 ? REC_TYPE_ACTIVE_OP
907cb93a386Sopenharmony_ci                : line.lastIndexOf("computed", 0) === 0 ? REC_TYPE_COMPUTED
908cb93a386Sopenharmony_ci                : line.lastIndexOf("debugOne", 0) === 0 ? REC_TYPE_SORT
909cb93a386Sopenharmony_ci                : line.lastIndexOf("aligned=", 0) === 0 ? REC_TYPE_ALIGNED
910cb93a386Sopenharmony_ci                : line.lastIndexOf("dumpOne", 0) === 0 ? REC_TYPE_SORT
911cb93a386Sopenharmony_ci                : line.lastIndexOf("findTop", 0) === 0 ? REC_TYPE_TOP
912cb93a386Sopenharmony_ci                : line.lastIndexOf("pathB.", 0) === 0 ? REC_TYPE_ADD
913cb93a386Sopenharmony_ci                : line.lastIndexOf("path.", 0) === 0 ? REC_TYPE_ADD
914cb93a386Sopenharmony_ci                : line.lastIndexOf("after", 0) === 0 ? REC_TYPE_ANGLE
915cb93a386Sopenharmony_ci                : line.lastIndexOf("mark", 0) === 0 ? REC_TYPE_MARK
916cb93a386Sopenharmony_ci                : line.lastIndexOf("  {{", 0) === 0 ? REC_TYPE_COMPUTED
917cb93a386Sopenharmony_ci                : line.lastIndexOf("seg=", 0) === 0 ? REC_TYPE_PATH
918cb93a386Sopenharmony_ci                : line.lastIndexOf("op", 0) === 0 ? REC_TYPE_OP
919cb93a386Sopenharmony_ci                : line.lastIndexOf("$", 0) === 0 ? REC_TYPE_PATH
920cb93a386Sopenharmony_ci                : REC_TYPE_UNKNOWN;
921cb93a386Sopenharmony_ci        if (recType != type || recType == REC_TYPE_ADD || recType == REC_TYPE_SECT
922cb93a386Sopenharmony_ci                || recType == REC_TYPE_ACTIVE_OP || recType == REC_TYPE_ANGLE) {
923cb93a386Sopenharmony_ci            if (recType != REC_TYPE_UNKNOWN) {
924cb93a386Sopenharmony_ci                records.push(recType);
925cb93a386Sopenharmony_ci                records.push(lastLineNo);
926cb93a386Sopenharmony_ci                records.push(record);
927cb93a386Sopenharmony_ci            }
928cb93a386Sopenharmony_ci            record = [];
929cb93a386Sopenharmony_ci            recType = type;
930cb93a386Sopenharmony_ci            lastLineNo = lineNo;
931cb93a386Sopenharmony_ci        }
932cb93a386Sopenharmony_ci        var found = false;
933cb93a386Sopenharmony_ci        switch (recType) {
934cb93a386Sopenharmony_ci            case REC_TYPE_ACTIVE:
935cb93a386Sopenharmony_ci                found = match_regexp(line, lineNo, record, ACTIVE_LINE_SPAN, "debugShowActiveSpans" +
936cb93a386Sopenharmony_ci" id=IDX LINE_VAL t=T_VAL tEnd=T_VAL windSum=OPT windValue=IDX"
937cb93a386Sopenharmony_ci                ) || match_regexp(line, lineNo, record, ACTIVE_QUAD_SPAN, "debugShowActiveSpans" +
938cb93a386Sopenharmony_ci" id=IDX QUAD_VAL t=T_VAL tEnd=T_VAL windSum=OPT windValue=IDX"
939cb93a386Sopenharmony_ci                ) || match_regexp(line, lineNo, record, ACTIVE_CONIC_SPAN, "debugShowActiveSpans" +
940cb93a386Sopenharmony_ci" id=IDX CONIC_VAL t=T_VAL tEnd=T_VAL windSum=OPT windValue=IDX"
941cb93a386Sopenharmony_ci                ) || match_regexp(line, lineNo, record, ACTIVE_CUBIC_SPAN, "debugShowActiveSpans" +
942cb93a386Sopenharmony_ci" id=IDX CUBIC_VAL t=T_VAL tEnd=T_VAL windSum=OPT windValue=IDX"
943cb93a386Sopenharmony_ci                ) || match_regexp(line, lineNo, record, ACTIVE_LINE_SPAN, "debugShowActiveSpans" +
944cb93a386Sopenharmony_ci" id=IDX LINE_VAL t=T_VAL tEnd=T_VAL windSum=OPT oppSum=OPT windValue=IDX oppValue=NUM"
945cb93a386Sopenharmony_ci                ) || match_regexp(line, lineNo, record, ACTIVE_QUAD_SPAN, "debugShowActiveSpans" +
946cb93a386Sopenharmony_ci" id=IDX QUAD_VAL t=T_VAL tEnd=T_VAL windSum=OPT oppSum=OPT windValue=IDX oppValue=NUM"
947cb93a386Sopenharmony_ci                ) || match_regexp(line, lineNo, record, ACTIVE_CONIC_SPAN, "debugShowActiveSpans" +
948cb93a386Sopenharmony_ci" id=IDX CONIC_VAL t=T_VAL tEnd=T_VAL windSum=OPT oppSum=OPT windValue=IDX oppValue=NUM"
949cb93a386Sopenharmony_ci                ) || match_regexp(line, lineNo, record, ACTIVE_CUBIC_SPAN, "debugShowActiveSpans" +
950cb93a386Sopenharmony_ci" id=IDX CUBIC_VAL t=T_VAL tEnd=T_VAL windSum=OPT oppSum=OPT windValue=IDX oppValue=NUM"
951cb93a386Sopenharmony_ci                );
952cb93a386Sopenharmony_ci                break;
953cb93a386Sopenharmony_ci            case REC_TYPE_ACTIVE_OP:
954cb93a386Sopenharmony_ci                found = match_regexp(line, lineNo, record, ACTIVE_OP, "activeOp" +
955cb93a386Sopenharmony_ci" id=IDX t=T_VAL tEnd=T_VAL op=OPER miFrom=NUM miTo=NUM suFrom=NUM suTo=NUM result=IDX"
956cb93a386Sopenharmony_ci                );
957cb93a386Sopenharmony_ci                break;
958cb93a386Sopenharmony_ci            case REC_TYPE_ADD:
959cb93a386Sopenharmony_ci                if (match_regexp(line, lineNo, record, ADD_MOVETO, "PATH.moveTo(P_VAL);")) {
960cb93a386Sopenharmony_ci                    moveX = record[1][0];
961cb93a386Sopenharmony_ci                    moveY = record[1][1];
962cb93a386Sopenharmony_ci                    found = true;
963cb93a386Sopenharmony_ci                } else if (match_regexp(line, lineNo, record, ADD_LINETO, "PATH.lineTo(P_VAL);")) {
964cb93a386Sopenharmony_ci                    record[1].unshift(moveY);
965cb93a386Sopenharmony_ci                    record[1].unshift(moveX);
966cb93a386Sopenharmony_ci                    moveX = record[1][2];
967cb93a386Sopenharmony_ci                    moveY = record[1][3];
968cb93a386Sopenharmony_ci                    found = true;
969cb93a386Sopenharmony_ci                } else if (match_regexp(line, lineNo, record, ADD_QUADTO, "PATH.quadTo(P_VAL, P_VAL);")) {
970cb93a386Sopenharmony_ci                    record[1].unshift(moveY);
971cb93a386Sopenharmony_ci                    record[1].unshift(moveX);
972cb93a386Sopenharmony_ci                    moveX = record[1][4];
973cb93a386Sopenharmony_ci                    moveY = record[1][5];
974cb93a386Sopenharmony_ci                    found = true;
975cb93a386Sopenharmony_ci                } else if (match_regexp(line, lineNo, record, ADD_CONICTO, "PATH.conicTo(P_VAL, P_VAL, T_VAL);")) {
976cb93a386Sopenharmony_ci                    record[1].unshift(moveY);
977cb93a386Sopenharmony_ci                    record[1].unshift(moveX);
978cb93a386Sopenharmony_ci                    moveX = record[1][4];
979cb93a386Sopenharmony_ci                    moveY = record[1][5];
980cb93a386Sopenharmony_ci                    found = true;
981cb93a386Sopenharmony_ci                } else if (match_regexp(line, lineNo, record, ADD_CUBICTO, "PATH.cubicTo(P_VAL, P_VAL, P_VAL);")) {
982cb93a386Sopenharmony_ci                    record[1].unshift(moveY);
983cb93a386Sopenharmony_ci                    record[1].unshift(moveX);
984cb93a386Sopenharmony_ci                    moveX = record[1][6];
985cb93a386Sopenharmony_ci                    moveY = record[1][7];
986cb93a386Sopenharmony_ci                    found = true;
987cb93a386Sopenharmony_ci                } else if (match_regexp(line, lineNo, record, ADD_FILL, "PATH.setFillType(FILL_TYPE);")) {
988cb93a386Sopenharmony_ci                    found = true;
989cb93a386Sopenharmony_ci                } else {
990cb93a386Sopenharmony_ci                    found = match_regexp(line, lineNo, record, ADD_CLOSE, "PATH.close();");
991cb93a386Sopenharmony_ci                }
992cb93a386Sopenharmony_ci                break;
993cb93a386Sopenharmony_ci            case REC_TYPE_AFTERPART:
994cb93a386Sopenharmony_ci                found = match_regexp(line, lineNo, record, PATH_LINE, "afterPart LINE_VAL id=IDX")
995cb93a386Sopenharmony_ci                    || match_regexp(line, lineNo, record, PATH_QUAD, "afterPart QUAD_VAL id=IDX")
996cb93a386Sopenharmony_ci                    || match_regexp(line, lineNo, record, PATH_CONIC, "afterPart CONIC_VAL id=IDX")
997cb93a386Sopenharmony_ci                    || match_regexp(line, lineNo, record, PATH_CUBIC, "afterPart CUBIC_VAL id=IDX")
998cb93a386Sopenharmony_ci                break;
999cb93a386Sopenharmony_ci            case REC_TYPE_ALIGNED:
1000cb93a386Sopenharmony_ci                found = match_regexp(line, lineNo, record, PATH_LINE, "aligned=IDX LINE_VAL"
1001cb93a386Sopenharmony_ci                ) || match_regexp(line, lineNo, record, PATH_QUAD, "aligned=IDX QUAD_VAL"
1002cb93a386Sopenharmony_ci                ) || match_regexp(line, lineNo, record, PATH_CONIC, "aligned=IDX CONIC_VAL"
1003cb93a386Sopenharmony_ci                ) || match_regexp(line, lineNo, record, PATH_CUBIC, "aligned=IDX CUBIC_VAL"
1004cb93a386Sopenharmony_ci                );
1005cb93a386Sopenharmony_ci                break;
1006cb93a386Sopenharmony_ci            case REC_TYPE_ANGLE:
1007cb93a386Sopenharmony_ci                found = match_regexp(line, lineNo, record, ANGLE_AFTER, "after " +
1008cb93a386Sopenharmony_ci"[IDX/IDX] NUM/NUM tStart=T_VAL tEnd=T_VAL < [IDX/IDX] NUM/NUM tStart=T_VAL tEnd=T_VAL < [IDX/IDX] NUM/NUM tStart=T_VAL tEnd=T_VAL  T_F IDX");
1009cb93a386Sopenharmony_ci                break;
1010cb93a386Sopenharmony_ci            case REC_TYPE_COIN:
1011cb93a386Sopenharmony_ci                found = true;
1012cb93a386Sopenharmony_ci                break;
1013cb93a386Sopenharmony_ci            case REC_TYPE_COINCIDENCE:
1014cb93a386Sopenharmony_ci                found = match_regexp(line, lineNo, record, COIN_MAIN_SPAN, "debugShowCoincidence" +
1015cb93a386Sopenharmony_ci" + id=IDX t=T_VAL tEnd=T_VAL"
1016cb93a386Sopenharmony_ci                ) || match_regexp(line, lineNo, record, COIN_OPP_SPAN, "debugShowCoincidence" +
1017cb93a386Sopenharmony_ci" - id=IDX t=T_VAL tEnd=T_VAL"
1018cb93a386Sopenharmony_ci                );
1019cb93a386Sopenharmony_ci                break;
1020cb93a386Sopenharmony_ci            case REC_TYPE_COMPUTED:
1021cb93a386Sopenharmony_ci                found = line ==  "computed quadratics given"
1022cb93a386Sopenharmony_ci                  || match_regexp(line, lineNo, record, COMPUTED_SET_1, "computed quadratics set 1"
1023cb93a386Sopenharmony_ci                ) || match_regexp(line, lineNo, record, COMPUTED_SET_2, "computed quadratics set 2"
1024cb93a386Sopenharmony_ci                ) || match_regexp(line, lineNo, record, PATH_QUAD, "  QUAD_VAL,"
1025cb93a386Sopenharmony_ci                ) || match_regexp(line, lineNo, record, PATH_CONIC, "  CONIC_VAL,"
1026cb93a386Sopenharmony_ci                ) || match_regexp(line, lineNo, record, PATH_CUBIC, "  CUBIC_VAL,"
1027cb93a386Sopenharmony_ci                );
1028cb93a386Sopenharmony_ci                break;
1029cb93a386Sopenharmony_ci            case REC_TYPE_PATH:
1030cb93a386Sopenharmony_ci                found = match_regexp(line, lineNo, record, PATH_LINE, "seg=IDX LINE_VAL"
1031cb93a386Sopenharmony_ci                ) || match_regexp(line, lineNo, record, PATH_QUAD, "seg=IDX QUAD_VAL"
1032cb93a386Sopenharmony_ci                ) || match_regexp(line, lineNo, record, PATH_CONIC, "seg=IDX CONIC_VAL"
1033cb93a386Sopenharmony_ci                ) || match_regexp(line, lineNo, record, PATH_CUBIC, "seg=IDX CUBIC_VAL"
1034cb93a386Sopenharmony_ci                );
1035cb93a386Sopenharmony_ci                break;
1036cb93a386Sopenharmony_ci            case REC_TYPE_PATH2:
1037cb93a386Sopenharmony_ci                found = match_regexp(line, lineNo, record, PATH_LINE, "((SkOpSegment*) PTR_VAL) [IDX] {LINE_VAL}"
1038cb93a386Sopenharmony_ci                ) || match_regexp(line, lineNo, record, PATH_QUAD, "((SkOpSegment*) PTR_VAL) [IDX] {QUAD_VAL}"
1039cb93a386Sopenharmony_ci                ) || match_regexp(line, lineNo, record, PATH_CONIC, "((SkOpSegment*) PTR_VAL) [IDX] {CONIC_VAL}"
1040cb93a386Sopenharmony_ci                ) || match_regexp(line, lineNo, record, PATH_CUBIC, "((SkOpSegment*) PTR_VAL) [IDX] {CUBIC_VAL}"
1041cb93a386Sopenharmony_ci                );
1042cb93a386Sopenharmony_ci                break;
1043cb93a386Sopenharmony_ci            case REC_TYPE_SECT:
1044cb93a386Sopenharmony_ci                found = match_regexp(line, lineNo, record, INTERSECT_LINE, "debugShowLineIntersection" +
1045cb93a386Sopenharmony_ci" wtTs[0]=T_VAL LINE_VAL PT_VAL wnTs[0]=T_VAL LINE_VAL"
1046cb93a386Sopenharmony_ci                ) || match_regexp(line, lineNo, record, INTERSECT_LINE_2, "debugShowLineIntersection" +
1047cb93a386Sopenharmony_ci" wtTs[0]=T_VAL LINE_VAL PT_VAL wtTs[1]=T_VAL PT_VAL wnTs[0]=T_VAL LINE_VAL wnTs[1]=T_VAL"
1048cb93a386Sopenharmony_ci                ) || match_regexp(line, lineNo, record, INTERSECT_LINE_NO, "debugShowLineIntersection" +
1049cb93a386Sopenharmony_ci" no intersect LINE_VAL LINE_VAL"
1050cb93a386Sopenharmony_ci                ) || match_regexp(line, lineNo, record, INTERSECT_QUAD_LINE, "debugShowQuadLineIntersection" +
1051cb93a386Sopenharmony_ci" wtTs[0]=T_VAL QUAD_VAL PT_VAL wnTs[0]=T_VAL LINE_VAL"
1052cb93a386Sopenharmony_ci                ) || match_regexp(line, lineNo, record, INTERSECT_QUAD_LINE_2, "debugShowQuadLineIntersection" +
1053cb93a386Sopenharmony_ci" wtTs[0]=T_VAL QUAD_VAL PT_VAL wtTs[1]=T_VAL PT_VAL wnTs[0]=T_VAL LINE_VAL wnTs[1]=T_VAL"
1054cb93a386Sopenharmony_ci                ) || match_regexp(line, lineNo, record, INTERSECT_QUAD_LINE_NO, "debugShowQuadLineIntersection" +
1055cb93a386Sopenharmony_ci" no intersect QUAD_VAL LINE_VAL"
1056cb93a386Sopenharmony_ci                ) || match_regexp(line, lineNo, record, INTERSECT_QUAD, "debugShowQuadIntersection" +
1057cb93a386Sopenharmony_ci" wtTs[0]=T_VAL QUAD_VAL PT_VAL wnTs[0]=T_VAL QUAD_VAL"
1058cb93a386Sopenharmony_ci                ) || match_regexp(line, lineNo, record, INTERSECT_QUAD_2, "debugShowQuadIntersection" +
1059cb93a386Sopenharmony_ci" wtTs[0]=T_VAL QUAD_VAL PT_VAL wtTs[1]=T_VAL PT_VAL wnTs[0]=T_VAL QUAD_VAL wnTs[1]=T_VAL"
1060cb93a386Sopenharmony_ci                ) || match_regexp(line, lineNo, record, INTERSECT_QUAD_NO, "debugShowQuadIntersection" +
1061cb93a386Sopenharmony_ci" no intersect QUAD_VAL QUAD_VAL"
1062cb93a386Sopenharmony_ci
1063cb93a386Sopenharmony_ci                ) || match_regexp(line, lineNo, record, INTERSECT_CONIC_LINE, "debugShowConicLineIntersection" +
1064cb93a386Sopenharmony_ci" wtTs[0]=T_VAL CONIC_VAL PT_VAL wnTs[0]=T_VAL LINE_VAL"
1065cb93a386Sopenharmony_ci                ) || match_regexp(line, lineNo, record, INTERSECT_CONIC_LINE_2, "debugShowConicLineIntersection" +
1066cb93a386Sopenharmony_ci" wtTs[0]=T_VAL CONIC_VAL PT_VAL wtTs[1]=T_VAL PT_VAL wnTs[0]=T_VAL LINE_VAL wnTs[1]=T_VAL"
1067cb93a386Sopenharmony_ci                ) || match_regexp(line, lineNo, record, INTERSECT_CONIC_LINE_NO, "debugShowConicLineIntersection" +
1068cb93a386Sopenharmony_ci" no intersect CONIC_VAL LINE_VAL"
1069cb93a386Sopenharmony_ci
1070cb93a386Sopenharmony_ci                ) || match_regexp(line, lineNo, record, INTERSECT_CONIC_QUAD, "debugShowConicQuadIntersection" +
1071cb93a386Sopenharmony_ci" wtTs[0]=T_VAL CONIC_VAL PT_VAL wnTs[0]=T_VAL QUAD_VAL"
1072cb93a386Sopenharmony_ci                ) || match_regexp(line, lineNo, record, INTERSECT_CONIC_QUAD_2, "debugShowConicQuadIntersection" +
1073cb93a386Sopenharmony_ci" wtTs[0]=T_VAL CONIC_VAL PT_VAL wtTs[1]=T_VAL PT_VAL wnTs[0]=T_VAL QUAD_VAL wnTs[1]=T_VAL"
1074cb93a386Sopenharmony_ci                ) || match_regexp(line, lineNo, record, INTERSECT_CONIC_QUAD_3, "debugShowConicQuadIntersection" +
1075cb93a386Sopenharmony_ci" wtTs[0]=T_VAL CONIC_VAL PT_VAL wtTs[1]=T_VAL PT_VAL wtTs[2]=T_VAL PT_VAL wnTs[0]=T_VAL QUAD_VAL wnTs[1]=T_VAL wnTs[2]=T_VAL"
1076cb93a386Sopenharmony_ci                ) || match_regexp(line, lineNo, record, INTERSECT_CONIC_QUAD_4, "debugShowConicQuadIntersection" +
1077cb93a386Sopenharmony_ci" wtTs[0]=T_VAL CONIC_VAL PT_VAL wtTs[1]=T_VAL PT_VAL wtTs[2]=T_VAL PT_VAL wtTs[3]=T_VAL PT_VAL wnTs[0]=T_VAL QUAD_VAL wnTs[1]=T_VAL wnTs[2]=T_VAL wnTs[3]=T_VAL"
1078cb93a386Sopenharmony_ci                ) || match_regexp(line, lineNo, record, INTERSECT_CONIC_QUAD_NO, "debugShowConicQuadIntersection" +
1079cb93a386Sopenharmony_ci" no intersect CONIC_VAL QUAD_VAL"
1080cb93a386Sopenharmony_ci
1081cb93a386Sopenharmony_ci                ) || match_regexp(line, lineNo, record, INTERSECT_CONIC, "debugShowConicIntersection" +
1082cb93a386Sopenharmony_ci" wtTs[0]=T_VAL CONIC_VAL PT_VAL wnTs[0]=T_VAL CONIC_VAL"
1083cb93a386Sopenharmony_ci                ) || match_regexp(line, lineNo, record, INTERSECT_CONIC_2, "debugShowConicIntersection" +
1084cb93a386Sopenharmony_ci" wtTs[0]=T_VAL CONIC_VAL PT_VAL wtTs[1]=T_VAL PT_VAL wnTs[0]=T_VAL CONIC_VAL wnTs[1]=T_VAL"
1085cb93a386Sopenharmony_ci                ) || match_regexp(line, lineNo, record, INTERSECT_CONIC_NO, "debugShowConicIntersection" +
1086cb93a386Sopenharmony_ci" no intersect CONIC_VAL CONIC_VAL"
1087cb93a386Sopenharmony_ci                ) || match_regexp(line, lineNo, record, INTERSECT_CUBIC_LINE, "debugShowCubicLineIntersection" +
1088cb93a386Sopenharmony_ci" wtTs[0]=T_VAL CUBIC_VAL PT_VAL wnTs[0]=T_VAL LINE_VAL"
1089cb93a386Sopenharmony_ci                ) || match_regexp(line, lineNo, record, INTERSECT_CUBIC_LINE_2, "debugShowCubicLineIntersection" +
1090cb93a386Sopenharmony_ci" wtTs[0]=T_VAL CUBIC_VAL PT_VAL wtTs[1]=T_VAL PT_VAL wnTs[0]=T_VAL LINE_VAL wnTs[1]=T_VAL"
1091cb93a386Sopenharmony_ci                ) || match_regexp(line, lineNo, record, INTERSECT_CUBIC_LINE_3, "debugShowCubicLineIntersection" +
1092cb93a386Sopenharmony_ci" wtTs[0]=T_VAL CUBIC_VAL PT_VAL wtTs[1]=T_VAL PT_VAL wtTs[2]=T_VAL PT_VAL wnTs[0]=T_VAL LINE_VAL wnTs[1]=T_VAL wnTs[2]=T_VAL"
1093cb93a386Sopenharmony_ci                ) || match_regexp(line, lineNo, record, INTERSECT_CUBIC_LINE_NO, "debugShowCubicLineIntersection" +
1094cb93a386Sopenharmony_ci" no intersect CUBIC_VAL LINE_VAL"
1095cb93a386Sopenharmony_ci                ) || match_regexp(line, lineNo, record, INTERSECT_CUBIC_QUAD, "debugShowCubicQuadIntersection" +
1096cb93a386Sopenharmony_ci" wtTs[0]=T_VAL CUBIC_VAL PT_VAL wnTs[0]=T_VAL QUAD_VAL"
1097cb93a386Sopenharmony_ci                ) || match_regexp(line, lineNo, record, INTERSECT_CUBIC_QUAD_2, "debugShowCubicQuadIntersection" +
1098cb93a386Sopenharmony_ci" wtTs[0]=T_VAL CUBIC_VAL PT_VAL wtTs[1]=T_VAL PT_VAL wnTs[0]=T_VAL QUAD_VAL wnTs[1]=T_VAL"
1099cb93a386Sopenharmony_ci                ) || match_regexp(line, lineNo, record, INTERSECT_CUBIC_QUAD_3, "debugShowCubicQuadIntersection" +
1100cb93a386Sopenharmony_ci" wtTs[0]=T_VAL CUBIC_VAL PT_VAL wtTs[1]=T_VAL PT_VAL wtTs[2]=T_VAL PT_VAL wnTs[0]=T_VAL QUAD_VAL wnTs[1]=T_VAL wnTs[2]=T_VAL"
1101cb93a386Sopenharmony_ci                ) || match_regexp(line, lineNo, record, INTERSECT_CUBIC_QUAD_4, "debugShowCubicQuadIntersection" +
1102cb93a386Sopenharmony_ci" wtTs[0]=T_VAL CUBIC_VAL PT_VAL wtTs[1]=T_VAL PT_VAL wtTs[2]=T_VAL wtTs[3]=T_VAL PT_VAL wnTs[0]=T_VAL QUAD_VAL wnTs[1]=T_VAL wnTs[2]=T_VAL wnTs[3]=T_VAL"
1103cb93a386Sopenharmony_ci                ) || match_regexp(line, lineNo, record, INTERSECT_CUBIC_QUAD_NO, "debugShowCubicQuadIntersection" +
1104cb93a386Sopenharmony_ci" no intersect CUBIC_VAL QUAD_VAL"
1105cb93a386Sopenharmony_ci                ) || match_regexp(line, lineNo, record, INTERSECT_CUBIC, "debugShowCubicIntersection" +
1106cb93a386Sopenharmony_ci" wtTs[0]=T_VAL CUBIC_VAL PT_VAL wnTs[0]=T_VAL CUBIC_VAL"
1107cb93a386Sopenharmony_ci                ) || match_regexp(line, lineNo, record, INTERSECT_CUBIC_2, "debugShowCubicIntersection" +
1108cb93a386Sopenharmony_ci" wtTs[0]=T_VAL CUBIC_VAL PT_VAL wtTs[1]=T_VAL PT_VAL wnTs[0]=T_VAL CUBIC_VAL wnTs[1]=T_VAL"
1109cb93a386Sopenharmony_ci                ) || match_regexp(line, lineNo, record, INTERSECT_CUBIC_3, "debugShowCubicIntersection" +
1110cb93a386Sopenharmony_ci" wtTs[0]=T_VAL CUBIC_VAL PT_VAL wtTs[1]=T_VAL PT_VAL wtTs[2]=T_VAL PT_VAL wnTs[0]=T_VAL CUBIC_VAL wnTs[1]=T_VAL wnTs[2]=T_VAL"
1111cb93a386Sopenharmony_ci                ) || match_regexp(line, lineNo, record, INTERSECT_CUBIC_4, "debugShowCubicIntersection" +
1112cb93a386Sopenharmony_ci" wtTs[0]=T_VAL CUBIC_VAL PT_VAL wtTs[1]=T_VAL PT_VAL wtTs[2]=T_VAL PT_VAL wtTs[3]=T_VAL PT_VAL wnTs[0]=T_VAL CUBIC_VAL wnTs[1]=T_VAL wnTs[2]=T_VAL wnTs[3]=T_VAL"
1113cb93a386Sopenharmony_ci                ) || match_regexp(line, lineNo, record, INTERSECT_CUBIC_NO, "debugShowCubicIntersection" +
1114cb93a386Sopenharmony_ci" no intersect CUBIC_VAL CUBIC_VAL"
1115cb93a386Sopenharmony_ci                ) || match_regexp(line, lineNo, record, INTERSECT_SELF_CUBIC, "debugShowCubicIntersection" +
1116cb93a386Sopenharmony_ci" wtTs[0]=T_VAL CUBIC_VAL PT_VAL wtTs[1]=T_VAL"
1117cb93a386Sopenharmony_ci                ) || match_regexp(line, lineNo, record, INTERSECT_SELF_CUBIC_NO, "debugShowCubicIntersection" +
1118cb93a386Sopenharmony_ci" no self intersect CUBIC_VAL"
1119cb93a386Sopenharmony_ci                );
1120cb93a386Sopenharmony_ci                break;
1121cb93a386Sopenharmony_ci            case REC_TYPE_SORT:
1122cb93a386Sopenharmony_ci                var hasDone = / done/.test(line);
1123cb93a386Sopenharmony_ci                var hasUnorderable = / unorderable/.test(line);
1124cb93a386Sopenharmony_ci                var hasSmall = / small/.test(line);
1125cb93a386Sopenharmony_ci                var hasTiny = / tiny/.test(line);
1126cb93a386Sopenharmony_ci                var hasOperand = / operand/.test(line);
1127cb93a386Sopenharmony_ci                var hasStop = / stop/.test(line);
1128cb93a386Sopenharmony_ci                line.replace(/[ a-z]+$/, "");
1129cb93a386Sopenharmony_ci                found = match_regexp(line, lineNo, record, SORT_UNARY, "debugOne" +
1130cb93a386Sopenharmony_ci" [IDX/IDX] next=IDX/IDX sect=IDX/IDX  s=T_VAL [IDX] e=T_VAL [IDX] sgn=NUM windVal=IDX windSum=OPT"
1131cb93a386Sopenharmony_ci                ) || match_regexp(line, lineNo, record, SORT_BINARY, "debugOne" +
1132cb93a386Sopenharmony_ci" [IDX/IDX] next=IDX/IDX sect=IDX/IDX  s=T_VAL [IDX] e=T_VAL [IDX] sgn=NUM windVal=IDX windSum=OPT oppVal=IDX oppSum=OPT"
1133cb93a386Sopenharmony_ci                ) || match_regexp(line, lineNo, record, SORT_UNARY, "dumpOne" +
1134cb93a386Sopenharmony_ci" [IDX/IDX] next=IDX/IDX sect=NUM/NUM  s=T_VAL [IDX] e=T_VAL [IDX] sgn=NUM windVal=IDX windSum=OPT"
1135cb93a386Sopenharmony_ci                ) || match_regexp(line, lineNo, record, SORT_BINARY, "dumpOne" +
1136cb93a386Sopenharmony_ci" [IDX/IDX] next=IDX/IDX sect=NUM/NUM  s=T_VAL [IDX] e=T_VAL [IDX] sgn=NUM windVal=IDX windSum=OPT oppVal=IDX oppSum=OPT"
1137cb93a386Sopenharmony_ci                );
1138cb93a386Sopenharmony_ci                if (found) {
1139cb93a386Sopenharmony_ci                    record[1].push(hasDone);
1140cb93a386Sopenharmony_ci                    record[1].push(hasUnorderable);
1141cb93a386Sopenharmony_ci                    record[1].push(hasSmall);
1142cb93a386Sopenharmony_ci                    record[1].push(hasTiny);
1143cb93a386Sopenharmony_ci                    record[1].push(hasOperand);
1144cb93a386Sopenharmony_ci                    record[1].push(hasStop);
1145cb93a386Sopenharmony_ci                }
1146cb93a386Sopenharmony_ci                break;
1147cb93a386Sopenharmony_ci            case REC_TYPE_TOP:
1148cb93a386Sopenharmony_ci                found = match_regexp(line, lineNo, record, ACTIVE_OP, "findTop" +
1149cb93a386Sopenharmony_ci" id=IDX s=T_VAL e=T_VAL cw=NUM swap=NUM inflections=NUM monotonic=NUM"
1150cb93a386Sopenharmony_ci                ) || match_regexp(line, lineNo, record, ACTIVE_OP, "findTop" +
1151cb93a386Sopenharmony_ci" id=IDX s=T_VAL e=T_VAL (-) cw=NUM swap=NUM inflections=NUM monotonic=NUM"
1152cb93a386Sopenharmony_ci                ) || match_regexp(line, lineNo, record, ACTIVE_OP, "findTop" +
1153cb93a386Sopenharmony_ci" id=IDX s=T_VAL e=T_VAL (+) cw=NUM swap=NUM inflections=NUM monotonic=NUM"
1154cb93a386Sopenharmony_ci                );
1155cb93a386Sopenharmony_ci                break;
1156cb93a386Sopenharmony_ci            case REC_TYPE_MARK:
1157cb93a386Sopenharmony_ci                found = match_regexp(line, lineNo, record, MARK_LINE, "markWinding" +
1158cb93a386Sopenharmony_ci" id=IDX LINE_VAL t=T_VAL [IDX] PT_VAL tEnd=T_VAL newWindSum=NUM newOppSum=OPT oppSum=OPT windSum=OPT windValue=IDX"
1159cb93a386Sopenharmony_ci                ) || match_regexp(line, lineNo, record, MARK_QUAD, "markWinding" +
1160cb93a386Sopenharmony_ci" id=IDX QUAD_VAL t=T_VAL [IDX] PT_VAL tEnd=T_VAL newWindSum=NUM newOppSum=OPT oppSum=OPT windSum=OPT windValue=IDX"
1161cb93a386Sopenharmony_ci                ) || match_regexp(line, lineNo, record, MARK_CONIC, "markWinding" +
1162cb93a386Sopenharmony_ci" id=IDX CONIC_VAL t=T_VAL [IDX] PT_VAL tEnd=T_VAL newWindSum=NUM newOppSum=OPT oppSum=OPT windSum=OPT windValue=IDX"
1163cb93a386Sopenharmony_ci                ) || match_regexp(line, lineNo, record, MARK_CUBIC, "markWinding" +
1164cb93a386Sopenharmony_ci" id=IDX CUBIC_VAL t=T_VAL [IDX] PT_VAL tEnd=T_VAL newWindSum=NUM newOppSum=OPT oppSum=OPT windSum=OPT windValue=IDX"
1165cb93a386Sopenharmony_ci                ) || match_regexp(line, lineNo, record, MARK_DONE_LINE, "markDone" +
1166cb93a386Sopenharmony_ci" id=IDX LINE_VAL t=T_VAL [IDX] PT_VAL tEnd=T_VAL newWindSum=OPT newOppSum=OPT oppSum=OPT windSum=OPT windValue=IDX oppValue=OPT"
1167cb93a386Sopenharmony_ci                ) || match_regexp(line, lineNo, record, MARK_DONE_QUAD, "markDone" +
1168cb93a386Sopenharmony_ci" id=IDX QUAD_VAL t=T_VAL [IDX] PT_VAL tEnd=T_VAL newWindSum=OPT newOppSum=OPT oppSum=OPT windSum=OPT windValue=IDX oppValue=OPT"
1169cb93a386Sopenharmony_ci                ) || match_regexp(line, lineNo, record, MARK_DONE_CONIC, "markDone" +
1170cb93a386Sopenharmony_ci" id=IDX CONIC_VAL t=T_VAL [IDX] PT_VAL tEnd=T_VAL newWindSum=OPT newOppSum=OPT oppSum=OPT windSum=OPT windValue=IDX oppValue=OPT"
1171cb93a386Sopenharmony_ci                ) || match_regexp(line, lineNo, record, MARK_DONE_CUBIC, "markDone" +
1172cb93a386Sopenharmony_ci" id=IDX CUBIC_VAL t=T_VAL [IDX] PT_VAL tEnd=T_VAL newWindSum=OPT newOppSum=OPT oppSum=OPT windSum=OPT windValue=IDX oppValue=OPT"
1173cb93a386Sopenharmony_ci                ) || match_regexp(line, lineNo, record, MARK_SIMPLE_LINE, "markWinding" +
1174cb93a386Sopenharmony_ci" id=IDX LINE_VAL t=T_VAL [IDX] PT_VAL tEnd=T_VAL newWindSum=NUM windSum=OPT windValue=IDX"
1175cb93a386Sopenharmony_ci                ) || match_regexp(line, lineNo, record, MARK_SIMPLE_QUAD, "markWinding" +
1176cb93a386Sopenharmony_ci" id=IDX QUAD_VAL t=T_VAL [IDX] PT_VAL tEnd=T_VAL newWindSum=NUM windSum=OPT windValue=IDX"
1177cb93a386Sopenharmony_ci                ) || match_regexp(line, lineNo, record, MARK_SIMPLE_CONIC, "markWinding" +
1178cb93a386Sopenharmony_ci" id=IDX CONIC_VAL t=T_VAL [IDX] PT_VAL tEnd=T_VAL newWindSum=NUM windSum=OPT windValue=IDX"
1179cb93a386Sopenharmony_ci                ) || match_regexp(line, lineNo, record, MARK_SIMPLE_CUBIC, "markWinding" +
1180cb93a386Sopenharmony_ci" id=IDX CUBIC_VAL t=T_VAL [IDX] PT_VAL tEnd=T_VAL newWindSum=NUM windSum=OPT windValue=IDX"
1181cb93a386Sopenharmony_ci                ) || match_regexp(line, lineNo, record, MARK_ANGLE_LAST, "markAngle" +
1182cb93a386Sopenharmony_ci" last segment=IDX span=IDX"
1183cb93a386Sopenharmony_ci                ) || match_regexp(line, lineNo, record, MARK_ANGLE_LAST, "markAngle" +
1184cb93a386Sopenharmony_ci" last seg=IDX span=IDX"
1185cb93a386Sopenharmony_ci                ) || match_regexp(line, lineNo, record, MARK_ANGLE_LAST, "markAngle" +
1186cb93a386Sopenharmony_ci" last segment=IDX span=IDX windSum=OPT"
1187cb93a386Sopenharmony_ci                ) || match_regexp(line, lineNo, record, MARK_ANGLE_LAST, "markAngle" +
1188cb93a386Sopenharmony_ci" last seg=IDX span=IDX windSum=OPT"
1189cb93a386Sopenharmony_ci                );
1190cb93a386Sopenharmony_ci                break;
1191cb93a386Sopenharmony_ci            case REC_TYPE_OP:
1192cb93a386Sopenharmony_ci                if (line.lastIndexOf("oppSign oppSign=", 0) === 0
1193cb93a386Sopenharmony_ci                        || line.lastIndexOf("operator<", 0) === 0) {
1194cb93a386Sopenharmony_ci                    found = true;
1195cb93a386Sopenharmony_ci                    break;
1196cb93a386Sopenharmony_ci                }
1197cb93a386Sopenharmony_ci                found = match_regexp(line, lineNo, record, OP_DIFFERENCE, "op diff"
1198cb93a386Sopenharmony_ci                ) || match_regexp(line, lineNo, record, OP_INTERSECT, "op intersect"
1199cb93a386Sopenharmony_ci                ) || match_regexp(line, lineNo, record, OP_INTERSECT, "op sect"
1200cb93a386Sopenharmony_ci                ) || match_regexp(line, lineNo, record, OP_UNION, "op union"
1201cb93a386Sopenharmony_ci                ) || match_regexp(line, lineNo, record, OP_XOR, "op xor"
1202cb93a386Sopenharmony_ci                );
1203cb93a386Sopenharmony_ci                break;
1204cb93a386Sopenharmony_ci            case REC_TYPE_UNKNOWN:
1205cb93a386Sopenharmony_ci                found = true;
1206cb93a386Sopenharmony_ci                break;
1207cb93a386Sopenharmony_ci        }
1208cb93a386Sopenharmony_ci        if (!found) {
1209cb93a386Sopenharmony_ci            console.log(line + " [" + lineNo + "] of type " + type + " not found");
1210cb93a386Sopenharmony_ci        }
1211cb93a386Sopenharmony_ci    }
1212cb93a386Sopenharmony_ci    if (recType != REC_TYPE_UNKNOWN) {
1213cb93a386Sopenharmony_ci        records.push(recType);
1214cb93a386Sopenharmony_ci        records.push(lastLineNo);
1215cb93a386Sopenharmony_ci        records.push(record);
1216cb93a386Sopenharmony_ci    }
1217cb93a386Sopenharmony_ci    if (records.length >= 1) {
1218cb93a386Sopenharmony_ci        tests[testIndex] = records;
1219cb93a386Sopenharmony_ci        testLines[testIndex] = lines;
1220cb93a386Sopenharmony_ci    }
1221cb93a386Sopenharmony_ci}
1222cb93a386Sopenharmony_ci
1223cb93a386Sopenharmony_cifunction init(test) {
1224cb93a386Sopenharmony_ci    var canvas = document.getElementById('canvas');
1225cb93a386Sopenharmony_ci    if (!canvas.getContext) return;
1226cb93a386Sopenharmony_ci    ctx = canvas.getContext('2d');
1227cb93a386Sopenharmony_ci    var resScale = retina_scale && window.devicePixelRatio ? window.devicePixelRatio : 1;
1228cb93a386Sopenharmony_ci    var unscaledWidth = window.innerWidth - 20;
1229cb93a386Sopenharmony_ci    var unscaledHeight = window.innerHeight - 20;
1230cb93a386Sopenharmony_ci    screenWidth = unscaledWidth;
1231cb93a386Sopenharmony_ci    screenHeight = unscaledHeight;
1232cb93a386Sopenharmony_ci    canvas.width = unscaledWidth * resScale;
1233cb93a386Sopenharmony_ci    canvas.height = unscaledHeight * resScale;
1234cb93a386Sopenharmony_ci    canvas.style.width = unscaledWidth + 'px';
1235cb93a386Sopenharmony_ci    canvas.style.height = unscaledHeight + 'px';
1236cb93a386Sopenharmony_ci    if (resScale != 1) {
1237cb93a386Sopenharmony_ci        ctx.scale(resScale, resScale);
1238cb93a386Sopenharmony_ci    }
1239cb93a386Sopenharmony_ci    xmin = Infinity;
1240cb93a386Sopenharmony_ci    xmax = -Infinity;
1241cb93a386Sopenharmony_ci    ymin = Infinity;
1242cb93a386Sopenharmony_ci    ymax = -Infinity;
1243cb93a386Sopenharmony_ci    hasPath = hasAlignedPath = hasComputedPath = false;
1244cb93a386Sopenharmony_ci    firstActiveSpan = -1;
1245cb93a386Sopenharmony_ci    for (var tIndex = 0; tIndex < test.length; tIndex += 3) {
1246cb93a386Sopenharmony_ci        var recType = test[tIndex];
1247cb93a386Sopenharmony_ci        if (!typeof recType == 'number' || recType < REC_TYPE_UNKNOWN || recType > REC_TYPE_LAST) {
1248cb93a386Sopenharmony_ci            console.log("unknown rec type: " + recType);
1249cb93a386Sopenharmony_ci            throw "stop execution";
1250cb93a386Sopenharmony_ci        }
1251cb93a386Sopenharmony_ci        var records = test[tIndex + 2];
1252cb93a386Sopenharmony_ci        for (var recordIndex = 0; recordIndex < records.length; recordIndex += 2) {
1253cb93a386Sopenharmony_ci            var fragType = records[recordIndex];
1254cb93a386Sopenharmony_ci            if (!typeof fragType == 'number' || fragType < 1 || fragType > FRAG_TYPE_LAST) {
1255cb93a386Sopenharmony_ci                console.log("unknown in range frag type: " + fragType);
1256cb93a386Sopenharmony_ci                throw "stop execution";
1257cb93a386Sopenharmony_ci            }
1258cb93a386Sopenharmony_ci            var frags = records[recordIndex + 1];
1259cb93a386Sopenharmony_ci            var first = 0;
1260cb93a386Sopenharmony_ci            var last = -1;
1261cb93a386Sopenharmony_ci            var first2 = 0;
1262cb93a386Sopenharmony_ci            var last2 = 0;
1263cb93a386Sopenharmony_ci            switch (recType) {
1264cb93a386Sopenharmony_ci                case REC_TYPE_ALIGNED:
1265cb93a386Sopenharmony_ci                    hasAlignedPath = true;
1266cb93a386Sopenharmony_ci                case REC_TYPE_COMPUTED:
1267cb93a386Sopenharmony_ci                    if (fragType == COMPUTED_SET_1 || fragType == COMPUTED_SET_2) {
1268cb93a386Sopenharmony_ci                        break;
1269cb93a386Sopenharmony_ci                    }
1270cb93a386Sopenharmony_ci                    if (REC_TYPE_COMPUTED == recType) {
1271cb93a386Sopenharmony_ci                        hasComputedPath = true;
1272cb93a386Sopenharmony_ci                    }
1273cb93a386Sopenharmony_ci                case REC_TYPE_PATH:
1274cb93a386Sopenharmony_ci                    first = 1;
1275cb93a386Sopenharmony_ci                    switch (fragType) {
1276cb93a386Sopenharmony_ci                        case PATH_LINE:
1277cb93a386Sopenharmony_ci                            last = 5;
1278cb93a386Sopenharmony_ci                            break;
1279cb93a386Sopenharmony_ci                        case PATH_CONIC:
1280cb93a386Sopenharmony_ci                        case PATH_QUAD:
1281cb93a386Sopenharmony_ci                            last = 7;
1282cb93a386Sopenharmony_ci                            break;
1283cb93a386Sopenharmony_ci                        case PATH_CUBIC:
1284cb93a386Sopenharmony_ci                            last = 9;
1285cb93a386Sopenharmony_ci                            break;
1286cb93a386Sopenharmony_ci                        default:
1287cb93a386Sopenharmony_ci                            console.log("unknown " + (recType == REC_TYPE_PATH ? "REC_TYPE_PATH"
1288cb93a386Sopenharmony_ci                                    : "REC_TYPE_COMPUTED") + " frag type:" + fragType);
1289cb93a386Sopenharmony_ci                            throw "stop execution";
1290cb93a386Sopenharmony_ci                    }
1291cb93a386Sopenharmony_ci                    if (recType == REC_TYPE_PATH) {
1292cb93a386Sopenharmony_ci                        hasPath = true;
1293cb93a386Sopenharmony_ci                    }
1294cb93a386Sopenharmony_ci                    break;
1295cb93a386Sopenharmony_ci                case REC_TYPE_PATH2:
1296cb93a386Sopenharmony_ci                    first = 1;
1297cb93a386Sopenharmony_ci                    switch (fragType) {
1298cb93a386Sopenharmony_ci                        case PATH_LINE:
1299cb93a386Sopenharmony_ci                            last = 5;
1300cb93a386Sopenharmony_ci                            break;
1301cb93a386Sopenharmony_ci                        case PATH_CONIC:
1302cb93a386Sopenharmony_ci                        case PATH_QUAD:
1303cb93a386Sopenharmony_ci                            last = 7;
1304cb93a386Sopenharmony_ci                            break;
1305cb93a386Sopenharmony_ci                        case PATH_CUBIC:
1306cb93a386Sopenharmony_ci                            last = 9;
1307cb93a386Sopenharmony_ci                            break;
1308cb93a386Sopenharmony_ci                        default:
1309cb93a386Sopenharmony_ci                            console.log("unknown " + (recType == REC_TYPE_PATH2 ? "REC_TYPE_PATH2"
1310cb93a386Sopenharmony_ci                                    : "REC_TYPE_COMPUTED") + " frag type:" + fragType);
1311cb93a386Sopenharmony_ci                            throw "stop execution";
1312cb93a386Sopenharmony_ci                    }
1313cb93a386Sopenharmony_ci                    if (recType == REC_TYPE_PATH2) {
1314cb93a386Sopenharmony_ci                        hasPath = true;
1315cb93a386Sopenharmony_ci                    }
1316cb93a386Sopenharmony_ci                    break;
1317cb93a386Sopenharmony_ci                case REC_TYPE_ACTIVE:
1318cb93a386Sopenharmony_ci                    if (firstActiveSpan < 0) {
1319cb93a386Sopenharmony_ci                        firstActiveSpan = tIndex;
1320cb93a386Sopenharmony_ci                    }
1321cb93a386Sopenharmony_ci                    first = 1;
1322cb93a386Sopenharmony_ci                    switch (fragType) {
1323cb93a386Sopenharmony_ci                        case ACTIVE_LINE_SPAN:
1324cb93a386Sopenharmony_ci                            last = 5;
1325cb93a386Sopenharmony_ci                            break;
1326cb93a386Sopenharmony_ci                        case ACTIVE_CONIC_SPAN:
1327cb93a386Sopenharmony_ci                        case ACTIVE_QUAD_SPAN:
1328cb93a386Sopenharmony_ci                            last = 7;
1329cb93a386Sopenharmony_ci                            break;
1330cb93a386Sopenharmony_ci                        case ACTIVE_CUBIC_SPAN:
1331cb93a386Sopenharmony_ci                            last = 9;
1332cb93a386Sopenharmony_ci                            break;
1333cb93a386Sopenharmony_ci                        default:
1334cb93a386Sopenharmony_ci                            console.log("unknown REC_TYPE_ACTIVE frag type: " + fragType);
1335cb93a386Sopenharmony_ci                            throw "stop execution";
1336cb93a386Sopenharmony_ci                    }
1337cb93a386Sopenharmony_ci                    break;
1338cb93a386Sopenharmony_ci                case REC_TYPE_ADD:
1339cb93a386Sopenharmony_ci                    switch (fragType) {
1340cb93a386Sopenharmony_ci                        case ADD_MOVETO:
1341cb93a386Sopenharmony_ci                            break;
1342cb93a386Sopenharmony_ci                        case ADD_LINETO:
1343cb93a386Sopenharmony_ci                            last = 4;
1344cb93a386Sopenharmony_ci                            break;
1345cb93a386Sopenharmony_ci                        case ADD_CONICTO:
1346cb93a386Sopenharmony_ci                        case ADD_QUADTO:
1347cb93a386Sopenharmony_ci                            last = 6;
1348cb93a386Sopenharmony_ci                            break;
1349cb93a386Sopenharmony_ci                        case ADD_CUBICTO:
1350cb93a386Sopenharmony_ci                            last = 8;
1351cb93a386Sopenharmony_ci                            break;
1352cb93a386Sopenharmony_ci                        case ADD_CLOSE:
1353cb93a386Sopenharmony_ci                        case ADD_FILL:
1354cb93a386Sopenharmony_ci                            break;
1355cb93a386Sopenharmony_ci                        default:
1356cb93a386Sopenharmony_ci                            console.log("unknown REC_TYPE_ADD frag type: " + fragType);
1357cb93a386Sopenharmony_ci                            throw "stop execution";
1358cb93a386Sopenharmony_ci                    }
1359cb93a386Sopenharmony_ci                    break;
1360cb93a386Sopenharmony_ci                case REC_TYPE_AFTERPART:
1361cb93a386Sopenharmony_ci                    switch (fragType) {
1362cb93a386Sopenharmony_ci                        case PATH_LINE:
1363cb93a386Sopenharmony_ci                            last = 4;
1364cb93a386Sopenharmony_ci                            break;
1365cb93a386Sopenharmony_ci                        case PATH_CONIC:
1366cb93a386Sopenharmony_ci                        case PATH_QUAD:
1367cb93a386Sopenharmony_ci                            last = 6;
1368cb93a386Sopenharmony_ci                            break;
1369cb93a386Sopenharmony_ci                        case PATH_CUBIC:
1370cb93a386Sopenharmony_ci                            last = 8;
1371cb93a386Sopenharmony_ci                            break;
1372cb93a386Sopenharmony_ci                        default:
1373cb93a386Sopenharmony_ci                            console.log("unknown REC_TYPE_ACTIVEPART frag type: " + fragType);
1374cb93a386Sopenharmony_ci                            throw "stop execution";
1375cb93a386Sopenharmony_ci                    }
1376cb93a386Sopenharmony_ci                    break;
1377cb93a386Sopenharmony_ci                case REC_TYPE_SECT:
1378cb93a386Sopenharmony_ci                    switch (fragType) {
1379cb93a386Sopenharmony_ci                        case INTERSECT_LINE:
1380cb93a386Sopenharmony_ci                            first = 1; last = 5; first2 = 8; last2 = 12;
1381cb93a386Sopenharmony_ci                            break;
1382cb93a386Sopenharmony_ci                        case INTERSECT_LINE_2:
1383cb93a386Sopenharmony_ci                            first = 1; last = 5; first2 = 11; last2 = 15;
1384cb93a386Sopenharmony_ci                            break;
1385cb93a386Sopenharmony_ci                        case INTERSECT_LINE_NO:
1386cb93a386Sopenharmony_ci                            first = 0; last = 4; first2 = 4; last2 = 8;
1387cb93a386Sopenharmony_ci                            break;
1388cb93a386Sopenharmony_ci                        case INTERSECT_CONIC_LINE:
1389cb93a386Sopenharmony_ci                            first = 1; last = 7; first2 = 11; last2 = 15;
1390cb93a386Sopenharmony_ci                            break;
1391cb93a386Sopenharmony_ci                        case INTERSECT_QUAD_LINE:
1392cb93a386Sopenharmony_ci                            first = 1; last = 7; first2 = 10; last2 = 14;
1393cb93a386Sopenharmony_ci                            break;
1394cb93a386Sopenharmony_ci                        case INTERSECT_CONIC_LINE_2:
1395cb93a386Sopenharmony_ci                            first = 1; last = 7; first2 = 14; last2 = 18;
1396cb93a386Sopenharmony_ci                            break;
1397cb93a386Sopenharmony_ci                        case INTERSECT_QUAD_LINE_2:
1398cb93a386Sopenharmony_ci                            first = 1; last = 7; first2 = 13; last2 = 17;
1399cb93a386Sopenharmony_ci                            break;
1400cb93a386Sopenharmony_ci                        case INTERSECT_CONIC_LINE_NO:
1401cb93a386Sopenharmony_ci                            first = 0; last = 6; first2 = 7; last2 = 11;
1402cb93a386Sopenharmony_ci                            break;
1403cb93a386Sopenharmony_ci                        case INTERSECT_QUAD_LINE_NO:
1404cb93a386Sopenharmony_ci                            first = 0; last = 6; first2 = 6; last2 = 10;
1405cb93a386Sopenharmony_ci                            break;
1406cb93a386Sopenharmony_ci                        case INTERSECT_CONIC:
1407cb93a386Sopenharmony_ci                            first = 1; last = 7; first2 = 11; last2 = 17;
1408cb93a386Sopenharmony_ci                            break;
1409cb93a386Sopenharmony_ci                        case INTERSECT_QUAD:
1410cb93a386Sopenharmony_ci                            first = 1; last = 7; first2 = 10; last2 = 16;
1411cb93a386Sopenharmony_ci                            break;
1412cb93a386Sopenharmony_ci                        case INTERSECT_CONIC_2:
1413cb93a386Sopenharmony_ci                            first = 1; last = 7; first2 = 14; last2 = 20;
1414cb93a386Sopenharmony_ci                            break;
1415cb93a386Sopenharmony_ci                        case INTERSECT_QUAD_2:
1416cb93a386Sopenharmony_ci                            first = 1; last = 7; first2 = 13; last2 = 19;
1417cb93a386Sopenharmony_ci                            break;
1418cb93a386Sopenharmony_ci                        case INTERSECT_CONIC_NO:
1419cb93a386Sopenharmony_ci                            first = 0; last = 6; first2 = 7; last2 = 13;
1420cb93a386Sopenharmony_ci                            break;
1421cb93a386Sopenharmony_ci                        case INTERSECT_QUAD_NO:
1422cb93a386Sopenharmony_ci                            first = 0; last = 6; first2 = 6; last2 = 12;
1423cb93a386Sopenharmony_ci                            break;
1424cb93a386Sopenharmony_ci                        case INTERSECT_SELF_CUBIC:
1425cb93a386Sopenharmony_ci                            first = 1; last = 9;
1426cb93a386Sopenharmony_ci                            break;
1427cb93a386Sopenharmony_ci                        case INTERSECT_SELF_CUBIC_NO:
1428cb93a386Sopenharmony_ci                            first = 0; last = 8;
1429cb93a386Sopenharmony_ci                            break;
1430cb93a386Sopenharmony_ci                        case INTERSECT_CUBIC_LINE:
1431cb93a386Sopenharmony_ci                            first = 1; last = 9; first2 = 12; last2 = 16;
1432cb93a386Sopenharmony_ci                            break;
1433cb93a386Sopenharmony_ci                        case INTERSECT_CUBIC_LINE_2:
1434cb93a386Sopenharmony_ci                            first = 1; last = 9; first2 = 15; last2 = 19;
1435cb93a386Sopenharmony_ci                            break;
1436cb93a386Sopenharmony_ci                        case INTERSECT_CUBIC_LINE_3:
1437cb93a386Sopenharmony_ci                            first = 1; last = 9; first2 = 18; last2 = 22;
1438cb93a386Sopenharmony_ci                            break;
1439cb93a386Sopenharmony_ci                        case INTERSECT_CUBIC_LINE_NO:
1440cb93a386Sopenharmony_ci                            first = 0; last = 8; first2 = 8; last2 = 12;
1441cb93a386Sopenharmony_ci                            break;
1442cb93a386Sopenharmony_ci                        case INTERSECT_CONIC_QUAD:
1443cb93a386Sopenharmony_ci                            first = 1; last = 7; first2 = 11; last2 = 17;
1444cb93a386Sopenharmony_ci                            break;
1445cb93a386Sopenharmony_ci                        case INTERSECT_CONIC_QUAD_2:
1446cb93a386Sopenharmony_ci                            first = 1; last = 7; first2 = 14; last2 = 20;
1447cb93a386Sopenharmony_ci                            break;
1448cb93a386Sopenharmony_ci                        case INTERSECT_CONIC_QUAD_3:
1449cb93a386Sopenharmony_ci                            first = 1; last = 7; first2 = 17; last2 = 23;
1450cb93a386Sopenharmony_ci                            break;
1451cb93a386Sopenharmony_ci                        case INTERSECT_CONIC_QUAD_4:
1452cb93a386Sopenharmony_ci                            first = 1; last = 7; first2 = 20; last2 = 26;
1453cb93a386Sopenharmony_ci                            break;
1454cb93a386Sopenharmony_ci                        case INTERSECT_CONIC_QUAD_NO:
1455cb93a386Sopenharmony_ci                            first = 0; last = 6; first2 = 7; last2 = 13;
1456cb93a386Sopenharmony_ci                            break;
1457cb93a386Sopenharmony_ci                        case INTERSECT_CUBIC_QUAD:
1458cb93a386Sopenharmony_ci                            first = 1; last = 9; first2 = 12; last2 = 18;
1459cb93a386Sopenharmony_ci                            break;
1460cb93a386Sopenharmony_ci                        case INTERSECT_CUBIC_QUAD_2:
1461cb93a386Sopenharmony_ci                            first = 1; last = 9; first2 = 15; last2 = 21;
1462cb93a386Sopenharmony_ci                            break;
1463cb93a386Sopenharmony_ci                        case INTERSECT_CUBIC_QUAD_3:
1464cb93a386Sopenharmony_ci                            first = 1; last = 9; first2 = 18; last2 = 24;
1465cb93a386Sopenharmony_ci                            break;
1466cb93a386Sopenharmony_ci                        case INTERSECT_CUBIC_QUAD_4:
1467cb93a386Sopenharmony_ci                            first = 1; last = 9; first2 = 21; last2 = 27;
1468cb93a386Sopenharmony_ci                            break;
1469cb93a386Sopenharmony_ci                        case INTERSECT_CUBIC_QUAD_NO:
1470cb93a386Sopenharmony_ci                            first = 0; last = 8; first2 = 8; last2 = 14;
1471cb93a386Sopenharmony_ci                            break;
1472cb93a386Sopenharmony_ci                        case INTERSECT_CUBIC:
1473cb93a386Sopenharmony_ci                            first = 1; last = 9; first2 = 12; last2 = 20;
1474cb93a386Sopenharmony_ci                            break;
1475cb93a386Sopenharmony_ci                        case INTERSECT_CUBIC_2:
1476cb93a386Sopenharmony_ci                            first = 1; last = 9; first2 = 15; last2 = 23;
1477cb93a386Sopenharmony_ci                            break;
1478cb93a386Sopenharmony_ci                        case INTERSECT_CUBIC_3:
1479cb93a386Sopenharmony_ci                            first = 1; last = 9; first2 = 18; last2 = 26;
1480cb93a386Sopenharmony_ci                            break;
1481cb93a386Sopenharmony_ci                        case INTERSECT_CUBIC_4:
1482cb93a386Sopenharmony_ci                            first = 1; last = 9; first2 = 21; last2 = 29;
1483cb93a386Sopenharmony_ci                            break;
1484cb93a386Sopenharmony_ci                        case INTERSECT_CUBIC_NO:
1485cb93a386Sopenharmony_ci                            first = 0; last = 8; first2 = 8; last2 = 16;
1486cb93a386Sopenharmony_ci                            break;
1487cb93a386Sopenharmony_ci                        default:
1488cb93a386Sopenharmony_ci                            console.log("unknown REC_TYPE_SECT frag type: " + fragType);
1489cb93a386Sopenharmony_ci                            throw "stop execution";
1490cb93a386Sopenharmony_ci                    }
1491cb93a386Sopenharmony_ci                    break;
1492cb93a386Sopenharmony_ci                default:
1493cb93a386Sopenharmony_ci                    continue;
1494cb93a386Sopenharmony_ci            }
1495cb93a386Sopenharmony_ci            for (var idx = first; idx < last; idx += 2) {
1496cb93a386Sopenharmony_ci                xmin = Math.min(xmin, frags[idx]);
1497cb93a386Sopenharmony_ci                xmax = Math.max(xmax, frags[idx]);
1498cb93a386Sopenharmony_ci                ymin = Math.min(ymin, frags[idx + 1]);
1499cb93a386Sopenharmony_ci                ymax = Math.max(ymax, frags[idx + 1]);
1500cb93a386Sopenharmony_ci            }
1501cb93a386Sopenharmony_ci            for (var idx = first2; idx < last2; idx += 2) {
1502cb93a386Sopenharmony_ci                xmin = Math.min(xmin, frags[idx]);
1503cb93a386Sopenharmony_ci                xmax = Math.max(xmax, frags[idx]);
1504cb93a386Sopenharmony_ci                ymin = Math.min(ymin, frags[idx + 1]);
1505cb93a386Sopenharmony_ci                ymax = Math.max(ymax, frags[idx + 1]);
1506cb93a386Sopenharmony_ci            }
1507cb93a386Sopenharmony_ci        }
1508cb93a386Sopenharmony_ci    }
1509cb93a386Sopenharmony_ci    var angleBounds = [Infinity, Infinity, -Infinity, -Infinity];
1510cb93a386Sopenharmony_ci    for (var tIndex = 0; tIndex < test.length; tIndex += 3) {
1511cb93a386Sopenharmony_ci        var recType = test[tIndex];
1512cb93a386Sopenharmony_ci        var records = test[tIndex + 2];
1513cb93a386Sopenharmony_ci        for (var recordIndex = 0; recordIndex < records.length; recordIndex += 2) {
1514cb93a386Sopenharmony_ci            var fragType = records[recordIndex];
1515cb93a386Sopenharmony_ci            var frags = records[recordIndex + 1];
1516cb93a386Sopenharmony_ci            switch (recType) {
1517cb93a386Sopenharmony_ci                case REC_TYPE_ACTIVE_OP:
1518cb93a386Sopenharmony_ci                    if (!draw_op) {
1519cb93a386Sopenharmony_ci                        break;
1520cb93a386Sopenharmony_ci                    }
1521cb93a386Sopenharmony_ci                    {
1522cb93a386Sopenharmony_ci                        var curve = curvePartialByID(test, frags[0], frags[1], frags[2]);
1523cb93a386Sopenharmony_ci                        curve_extremes(curve, angleBounds);
1524cb93a386Sopenharmony_ci                    }
1525cb93a386Sopenharmony_ci                    break;
1526cb93a386Sopenharmony_ci                case REC_TYPE_ANGLE:
1527cb93a386Sopenharmony_ci                    if (!draw_angle) {
1528cb93a386Sopenharmony_ci                        break;
1529cb93a386Sopenharmony_ci                    }
1530cb93a386Sopenharmony_ci                    {
1531cb93a386Sopenharmony_ci                        var curve = curvePartialByID(test, frags[0], frags[4], frags[5]);
1532cb93a386Sopenharmony_ci                        curve_extremes(curve, angleBounds);
1533cb93a386Sopenharmony_ci                        curve = curvePartialByID(test, frags[6], frags[10], frags[11]);
1534cb93a386Sopenharmony_ci                        curve_extremes(curve, angleBounds);
1535cb93a386Sopenharmony_ci                        curve = curvePartialByID(test, frags[12], frags[16], frags[17]);
1536cb93a386Sopenharmony_ci                    }
1537cb93a386Sopenharmony_ci                    break;
1538cb93a386Sopenharmony_ci                case REC_TYPE_COINCIDENCE:
1539cb93a386Sopenharmony_ci                    if (!draw_coincidence) {
1540cb93a386Sopenharmony_ci                        break;
1541cb93a386Sopenharmony_ci                    }
1542cb93a386Sopenharmony_ci                    {
1543cb93a386Sopenharmony_ci                        var curve = curvePartialByID(test, frags[0], frags[1], frags[2]);
1544cb93a386Sopenharmony_ci                        curve_extremes(curve, angleBounds);
1545cb93a386Sopenharmony_ci                    }
1546cb93a386Sopenharmony_ci                    break;
1547cb93a386Sopenharmony_ci                case REC_TYPE_SORT:
1548cb93a386Sopenharmony_ci                    if (!draw_sort) {
1549cb93a386Sopenharmony_ci                        break;
1550cb93a386Sopenharmony_ci                    }
1551cb93a386Sopenharmony_ci                    if (fragType == SORT_UNARY || fragType == SORT_BINARY) {
1552cb93a386Sopenharmony_ci                        var curve = curvePartialByID(test, frags[0], frags[6], frags[8]);
1553cb93a386Sopenharmony_ci                        curve_extremes(curve, angleBounds);
1554cb93a386Sopenharmony_ci                    }
1555cb93a386Sopenharmony_ci                    break;
1556cb93a386Sopenharmony_ci                case REC_TYPE_TOP:
1557cb93a386Sopenharmony_ci                    if (!draw_top) {
1558cb93a386Sopenharmony_ci                        break;
1559cb93a386Sopenharmony_ci                    }
1560cb93a386Sopenharmony_ci                    {
1561cb93a386Sopenharmony_ci                        var curve = curvePartialByID(test, frags[0], frags[1], frags[2]);
1562cb93a386Sopenharmony_ci                        curve_extremes(curve, angleBounds);
1563cb93a386Sopenharmony_ci                    }
1564cb93a386Sopenharmony_ci                    break;
1565cb93a386Sopenharmony_ci            }
1566cb93a386Sopenharmony_ci        }
1567cb93a386Sopenharmony_ci    }
1568cb93a386Sopenharmony_ci    xmin = Math.min(xmin, angleBounds[0]);
1569cb93a386Sopenharmony_ci    ymin = Math.min(ymin, angleBounds[1]);
1570cb93a386Sopenharmony_ci    xmax = Math.max(xmax, angleBounds[2]);
1571cb93a386Sopenharmony_ci    ymax = Math.max(ymax, angleBounds[3]);
1572cb93a386Sopenharmony_ci    setScale(xmin, xmax, ymin, ymax);
1573cb93a386Sopenharmony_ci    if (hasPath == false && hasComputedPath == true && !draw_computed) {
1574cb93a386Sopenharmony_ci        draw_computed = 7; // show quadratics, conics, and cubics
1575cb93a386Sopenharmony_ci    }
1576cb93a386Sopenharmony_ci    if (hasPath == true && hasComputedPath == false && draw_computed) {
1577cb93a386Sopenharmony_ci        draw_computed = 0;
1578cb93a386Sopenharmony_ci    }
1579cb93a386Sopenharmony_ci}
1580cb93a386Sopenharmony_ci
1581cb93a386Sopenharmony_cifunction curveByIDMatch(test, id, recMatch) {
1582cb93a386Sopenharmony_ci    var tIndex = -3;
1583cb93a386Sopenharmony_ci    while ((tIndex += 3) < test.length) {
1584cb93a386Sopenharmony_ci        var recType = test[tIndex];
1585cb93a386Sopenharmony_ci        if (recType == REC_TYPE_OP) {
1586cb93a386Sopenharmony_ci            continue;
1587cb93a386Sopenharmony_ci        }
1588cb93a386Sopenharmony_ci        if (recType != recMatch) {
1589cb93a386Sopenharmony_ci            return [];
1590cb93a386Sopenharmony_ci        }
1591cb93a386Sopenharmony_ci        var records = test[tIndex + 2];
1592cb93a386Sopenharmony_ci        for (var recordIndex = 0; recordIndex < records.length; recordIndex += 2) {
1593cb93a386Sopenharmony_ci            var fragType = records[recordIndex];
1594cb93a386Sopenharmony_ci            var frags = records[recordIndex + 1];
1595cb93a386Sopenharmony_ci            if (frags[0] == id) {
1596cb93a386Sopenharmony_ci                switch (fragType) {
1597cb93a386Sopenharmony_ci                    case PATH_LINE:
1598cb93a386Sopenharmony_ci                        return [frags[1], frags[2], frags[3], frags[4]];
1599cb93a386Sopenharmony_ci                    case PATH_QUAD:
1600cb93a386Sopenharmony_ci                        return [frags[1], frags[2], frags[3], frags[4],
1601cb93a386Sopenharmony_ci                                frags[5], frags[6]];
1602cb93a386Sopenharmony_ci                    case PATH_CONIC:
1603cb93a386Sopenharmony_ci                        return [frags[1], frags[2], frags[3], frags[4],
1604cb93a386Sopenharmony_ci                                frags[5], frags[6], frags[7]];
1605cb93a386Sopenharmony_ci                    case PATH_CUBIC:
1606cb93a386Sopenharmony_ci                        return [frags[1], frags[2], frags[3], frags[4],
1607cb93a386Sopenharmony_ci                                frags[5], frags[6], frags[7], frags[8]];
1608cb93a386Sopenharmony_ci                }
1609cb93a386Sopenharmony_ci            }
1610cb93a386Sopenharmony_ci        }
1611cb93a386Sopenharmony_ci    }
1612cb93a386Sopenharmony_ci    return [];
1613cb93a386Sopenharmony_ci}
1614cb93a386Sopenharmony_ci
1615cb93a386Sopenharmony_cifunction curveByID(test, id) {
1616cb93a386Sopenharmony_ci    var result = draw_path >= 4 ? curveByIDMatch(test, id, REC_TYPE_ALIGNED) : [];
1617cb93a386Sopenharmony_ci    if (!result.length) {
1618cb93a386Sopenharmony_ci        result = curveByIDMatch(test, id, REC_TYPE_PATH);
1619cb93a386Sopenharmony_ci    }
1620cb93a386Sopenharmony_ci    return result;
1621cb93a386Sopenharmony_ci}
1622cb93a386Sopenharmony_ci
1623cb93a386Sopenharmony_cifunction curvePartialByIDMatch(test, id, t0, t1, recMatch) {
1624cb93a386Sopenharmony_ci    var tIndex = -3;
1625cb93a386Sopenharmony_ci    while ((tIndex += 3) < test.length) {
1626cb93a386Sopenharmony_ci        var recType = test[tIndex];
1627cb93a386Sopenharmony_ci        if (recType == REC_TYPE_OP) {
1628cb93a386Sopenharmony_ci            continue;
1629cb93a386Sopenharmony_ci        }
1630cb93a386Sopenharmony_ci        if (recType != recMatch) {
1631cb93a386Sopenharmony_ci            return [];
1632cb93a386Sopenharmony_ci        }
1633cb93a386Sopenharmony_ci        var records = test[tIndex + 2];
1634cb93a386Sopenharmony_ci        for (var recordIndex = 0; recordIndex < records.length; recordIndex += 2) {
1635cb93a386Sopenharmony_ci            var fragType = records[recordIndex];
1636cb93a386Sopenharmony_ci            var frags = records[recordIndex + 1];
1637cb93a386Sopenharmony_ci            if (frags[0] == id) {
1638cb93a386Sopenharmony_ci                switch (fragType) {
1639cb93a386Sopenharmony_ci                    case PATH_LINE:
1640cb93a386Sopenharmony_ci                        return linePartial(frags[1], frags[2], frags[3], frags[4], t0, t1);
1641cb93a386Sopenharmony_ci                    case PATH_QUAD:
1642cb93a386Sopenharmony_ci                        return quadPartial(frags[1], frags[2], frags[3], frags[4],
1643cb93a386Sopenharmony_ci                                frags[5], frags[6], t0, t1);
1644cb93a386Sopenharmony_ci                    case PATH_CONIC:
1645cb93a386Sopenharmony_ci                        return conicPartial(frags[1], frags[2], frags[3], frags[4],
1646cb93a386Sopenharmony_ci                                frags[5], frags[6], frags[7], t0, t1);
1647cb93a386Sopenharmony_ci                    case PATH_CUBIC:
1648cb93a386Sopenharmony_ci                        return cubicPartial(frags[1], frags[2], frags[3], frags[4],
1649cb93a386Sopenharmony_ci                                frags[5], frags[6], frags[7], frags[8], t0, t1);
1650cb93a386Sopenharmony_ci                }
1651cb93a386Sopenharmony_ci            }
1652cb93a386Sopenharmony_ci        }
1653cb93a386Sopenharmony_ci    }
1654cb93a386Sopenharmony_ci    return [];
1655cb93a386Sopenharmony_ci}
1656cb93a386Sopenharmony_ci
1657cb93a386Sopenharmony_cifunction curvePartialByID(test, id, t0, t1) {
1658cb93a386Sopenharmony_ci    var result = draw_path >= 4 ? curvePartialByIDMatch(test, id, t0, t1, REC_TYPE_ALIGNED) : [];
1659cb93a386Sopenharmony_ci    if (!result.length) {
1660cb93a386Sopenharmony_ci        result = curvePartialByIDMatch(test, id, t0, t1, REC_TYPE_PATH);
1661cb93a386Sopenharmony_ci    }
1662cb93a386Sopenharmony_ci    return result;
1663cb93a386Sopenharmony_ci}
1664cb93a386Sopenharmony_ci
1665cb93a386Sopenharmony_cifunction idByCurveIDMatch(test, frag, type, recMatch) {
1666cb93a386Sopenharmony_ci    var tIndex = 0;
1667cb93a386Sopenharmony_ci    while (tIndex < test.length) {
1668cb93a386Sopenharmony_ci        var recType = test[tIndex];
1669cb93a386Sopenharmony_ci        if (recType != recMatch) {
1670cb93a386Sopenharmony_ci            ++tIndex;
1671cb93a386Sopenharmony_ci            continue;
1672cb93a386Sopenharmony_ci        }
1673cb93a386Sopenharmony_ci        var records = test[tIndex + 2];
1674cb93a386Sopenharmony_ci        for (var recordIndex = 0; recordIndex < records.length; recordIndex += 2) {
1675cb93a386Sopenharmony_ci            var fragType = records[recordIndex];
1676cb93a386Sopenharmony_ci            var frags = records[recordIndex + 1];
1677cb93a386Sopenharmony_ci            if (frag.length != frags.length - 1) {
1678cb93a386Sopenharmony_ci                continue;
1679cb93a386Sopenharmony_ci            }
1680cb93a386Sopenharmony_ci            switch (fragType) {
1681cb93a386Sopenharmony_ci                case PATH_LINE:
1682cb93a386Sopenharmony_ci                    if (frag[0] != frags[1] || frag[1] != frags[2]
1683cb93a386Sopenharmony_ci                            || frag[2] != frags[3] || frag[3] != frags[4]) {
1684cb93a386Sopenharmony_ci                        continue;
1685cb93a386Sopenharmony_ci                    }
1686cb93a386Sopenharmony_ci                    return frags[0];
1687cb93a386Sopenharmony_ci                case PATH_QUAD:
1688cb93a386Sopenharmony_ci                    if (frag[0] != frags[1] || frag[1] != frags[2]
1689cb93a386Sopenharmony_ci                            || frag[2] != frags[3] || frag[3] != frags[4]
1690cb93a386Sopenharmony_ci                            || frag[4] != frags[5] || frag[5] != frags[6]) {
1691cb93a386Sopenharmony_ci                        continue;
1692cb93a386Sopenharmony_ci                    }
1693cb93a386Sopenharmony_ci                    return frags[0];
1694cb93a386Sopenharmony_ci                case PATH_CONIC:
1695cb93a386Sopenharmony_ci                    if (frag[0] != frags[1] || frag[1] != frags[2]
1696cb93a386Sopenharmony_ci                            || frag[2] != frags[3] || frag[3] != frags[4]
1697cb93a386Sopenharmony_ci                            || frag[4] != frags[5] || frag[5] != frags[6]
1698cb93a386Sopenharmony_ci                            || frag[6] != frags[7]) {
1699cb93a386Sopenharmony_ci                        continue;
1700cb93a386Sopenharmony_ci                    }
1701cb93a386Sopenharmony_ci                    return frags[0];
1702cb93a386Sopenharmony_ci                case PATH_CUBIC:
1703cb93a386Sopenharmony_ci                    if (frag[0] != frags[1] || frag[1] != frags[2]
1704cb93a386Sopenharmony_ci                            || frag[2] != frags[3] || frag[3] != frags[4]
1705cb93a386Sopenharmony_ci                            || frag[4] != frags[5] || frag[5] != frags[6]
1706cb93a386Sopenharmony_ci                            || frag[6] != frags[7] || frag[7] != frags[8]) {
1707cb93a386Sopenharmony_ci                        continue;
1708cb93a386Sopenharmony_ci                    }
1709cb93a386Sopenharmony_ci                    return frags[0];
1710cb93a386Sopenharmony_ci            }
1711cb93a386Sopenharmony_ci        }
1712cb93a386Sopenharmony_ci        ++tIndex;
1713cb93a386Sopenharmony_ci    }
1714cb93a386Sopenharmony_ci    return -1;
1715cb93a386Sopenharmony_ci}
1716cb93a386Sopenharmony_ci
1717cb93a386Sopenharmony_cifunction idByCurve(test, frag, type) {
1718cb93a386Sopenharmony_ci    var result = draw_path >= 4 ? idByCurveIDMatch(test, frag, type, REC_TYPE_ALIGNED) : [];
1719cb93a386Sopenharmony_ci    if (!result.length) {
1720cb93a386Sopenharmony_ci        result = idByCurveIDMatch(test, frag, type, REC_TYPE_PATH);
1721cb93a386Sopenharmony_ci    }
1722cb93a386Sopenharmony_ci    return result;
1723cb93a386Sopenharmony_ci}
1724cb93a386Sopenharmony_ci
1725cb93a386Sopenharmony_cifunction curve_extremes(curve, bounds) {
1726cb93a386Sopenharmony_ci    var length = curve.length == 7 ? 6 : curve.length;
1727cb93a386Sopenharmony_ci    for (var index = 0; index < length; index += 2) {
1728cb93a386Sopenharmony_ci        var x = curve[index];
1729cb93a386Sopenharmony_ci        var y = curve[index + 1];
1730cb93a386Sopenharmony_ci        bounds[0] = Math.min(bounds[0], x);
1731cb93a386Sopenharmony_ci        bounds[1] = Math.min(bounds[1], y);
1732cb93a386Sopenharmony_ci        bounds[2] = Math.max(bounds[2], x);
1733cb93a386Sopenharmony_ci        bounds[3] = Math.max(bounds[3], y);
1734cb93a386Sopenharmony_ci    }
1735cb93a386Sopenharmony_ci}
1736cb93a386Sopenharmony_ci
1737cb93a386Sopenharmony_cifunction setScale(x0, x1, y0, y1) {
1738cb93a386Sopenharmony_ci    var srcWidth = x1 - x0;
1739cb93a386Sopenharmony_ci    var srcHeight = y1 - y0;
1740cb93a386Sopenharmony_ci    var usableWidth = screenWidth;
1741cb93a386Sopenharmony_ci    var xDigits = Math.ceil(Math.log(Math.abs(xmax)) / Math.log(10));
1742cb93a386Sopenharmony_ci    var yDigits = Math.ceil(Math.log(Math.abs(ymax)) / Math.log(10));
1743cb93a386Sopenharmony_ci    usableWidth -= (xDigits + yDigits) * 10;
1744cb93a386Sopenharmony_ci    usableWidth -= decimal_places * 10;
1745cb93a386Sopenharmony_ci    if (draw_legend) {
1746cb93a386Sopenharmony_ci        usableWidth -= 40;
1747cb93a386Sopenharmony_ci    }
1748cb93a386Sopenharmony_ci    var hscale = usableWidth / srcWidth;
1749cb93a386Sopenharmony_ci    var vscale = screenHeight / srcHeight;
1750cb93a386Sopenharmony_ci    scale = Math.min(hscale, vscale);
1751cb93a386Sopenharmony_ci    var invScale = 1 / scale;
1752cb93a386Sopenharmony_ci    var sxmin = x0 - invScale * 5;
1753cb93a386Sopenharmony_ci    var symin = y0 - invScale * 10;
1754cb93a386Sopenharmony_ci    var sxmax = x1 + invScale * (6 * decimal_places + 10);
1755cb93a386Sopenharmony_ci    var symax = y1 + invScale * 10;
1756cb93a386Sopenharmony_ci    srcWidth = sxmax - sxmin;
1757cb93a386Sopenharmony_ci    srcHeight = symax - symin;
1758cb93a386Sopenharmony_ci    hscale = usableWidth / srcWidth;
1759cb93a386Sopenharmony_ci    vscale = screenHeight / srcHeight;
1760cb93a386Sopenharmony_ci    scale = Math.min(hscale, vscale);
1761cb93a386Sopenharmony_ci    srcLeft = sxmin;
1762cb93a386Sopenharmony_ci    srcTop = symin;
1763cb93a386Sopenharmony_ci}
1764cb93a386Sopenharmony_ci
1765cb93a386Sopenharmony_cifunction drawArc(curve, op, from, to) {
1766cb93a386Sopenharmony_ci    var type = PATH_LINE + (curve.length / 2 - 2);
1767cb93a386Sopenharmony_ci    var pt = pointAtT(curve, type, op ? 0.4 : 0.6);
1768cb93a386Sopenharmony_ci    var dy = pt.y - curve[1];
1769cb93a386Sopenharmony_ci    var dx = pt.x - curve[0];
1770cb93a386Sopenharmony_ci    var dist = Math.sqrt(dy * dy + dx * dx);
1771cb93a386Sopenharmony_ci    var _dist = dist * scale;
1772cb93a386Sopenharmony_ci    var angle = Math.atan2(dy, dx);
1773cb93a386Sopenharmony_ci    var _px = (curve[0] - srcLeft) * scale;
1774cb93a386Sopenharmony_ci    var _py = (curve[1] - srcTop) * scale;
1775cb93a386Sopenharmony_ci    var divisor = 4;
1776cb93a386Sopenharmony_ci    var endDist;
1777cb93a386Sopenharmony_ci    do {
1778cb93a386Sopenharmony_ci        var ends = [];
1779cb93a386Sopenharmony_ci        for (var index = -1; index <= 1; index += 2) {
1780cb93a386Sopenharmony_ci            var px = Math.cos(index * Math.PI / divisor);
1781cb93a386Sopenharmony_ci            var py = Math.sin(index * Math.PI / divisor);
1782cb93a386Sopenharmony_ci            ends.push(px);
1783cb93a386Sopenharmony_ci            ends.push(py);
1784cb93a386Sopenharmony_ci        }
1785cb93a386Sopenharmony_ci        var endDx = (ends[2] - ends[0]) * scale * dist;
1786cb93a386Sopenharmony_ci        var endDy = (ends[3] - ends[1]) * scale * dist;
1787cb93a386Sopenharmony_ci        endDist = Math.sqrt(endDx * endDx + endDy * endDy);
1788cb93a386Sopenharmony_ci        if (endDist < 100) {
1789cb93a386Sopenharmony_ci            break;
1790cb93a386Sopenharmony_ci        }
1791cb93a386Sopenharmony_ci        divisor *= 2;
1792cb93a386Sopenharmony_ci    } while (true);
1793cb93a386Sopenharmony_ci    if (endDist < 30) {
1794cb93a386Sopenharmony_ci        return;
1795cb93a386Sopenharmony_ci    }
1796cb93a386Sopenharmony_ci    if (op) {
1797cb93a386Sopenharmony_ci        divisor *= 2;
1798cb93a386Sopenharmony_ci    }
1799cb93a386Sopenharmony_ci    ctx.strokeStyle = op ? "rgba(210,0,45, 0.4)" : "rgba(90,90,90, 0.5)";
1800cb93a386Sopenharmony_ci    ctx.beginPath();
1801cb93a386Sopenharmony_ci    ctx.arc(_px, _py, _dist, angle - Math.PI / divisor, angle + Math.PI / divisor, false);
1802cb93a386Sopenharmony_ci    ctx.stroke();
1803cb93a386Sopenharmony_ci    var saveAlign = ctx.textAlign;
1804cb93a386Sopenharmony_ci    var saveStyle = ctx.fillStyle;
1805cb93a386Sopenharmony_ci    var saveFont = ctx.font;
1806cb93a386Sopenharmony_ci    ctx.textAlign = "center";
1807cb93a386Sopenharmony_ci    ctx.fillStyle = "black";
1808cb93a386Sopenharmony_ci    ctx.font = "normal 24px Arial";
1809cb93a386Sopenharmony_ci    divisor *= 0.8;
1810cb93a386Sopenharmony_ci    for (var index = -1; index <= 1; index += 2) {
1811cb93a386Sopenharmony_ci        var px = curve[0] + Math.cos(angle + index * Math.PI / divisor) * dist;
1812cb93a386Sopenharmony_ci        var py = curve[1] + Math.sin(angle + index * Math.PI / divisor) * dist;
1813cb93a386Sopenharmony_ci        var _px = (px - srcLeft) * scale;
1814cb93a386Sopenharmony_ci        var _py = (py - srcTop) * scale;
1815cb93a386Sopenharmony_ci        ctx.fillText(index < 0 ? to.toString() : from.toString(), _px, _py + 8);
1816cb93a386Sopenharmony_ci    }
1817cb93a386Sopenharmony_ci    ctx.textAlign = saveAlign;
1818cb93a386Sopenharmony_ci    ctx.fillStyle = saveStyle;
1819cb93a386Sopenharmony_ci    ctx.font = saveFont;
1820cb93a386Sopenharmony_ci}
1821cb93a386Sopenharmony_ci
1822cb93a386Sopenharmony_cifunction drawPoint(px, py, end) {
1823cb93a386Sopenharmony_ci    var length = drawnPts.length == 7 ? 6 : drawnPts.length;
1824cb93a386Sopenharmony_ci    for (var pts = 0; pts < length; pts += 2) {
1825cb93a386Sopenharmony_ci        var x = drawnPts[pts];
1826cb93a386Sopenharmony_ci        var y = drawnPts[pts + 1];
1827cb93a386Sopenharmony_ci        if (px == x && py == y) {
1828cb93a386Sopenharmony_ci            return;
1829cb93a386Sopenharmony_ci        }
1830cb93a386Sopenharmony_ci    }
1831cb93a386Sopenharmony_ci    drawnPts.push(px);
1832cb93a386Sopenharmony_ci    drawnPts.push(py);
1833cb93a386Sopenharmony_ci    var label = px.toFixed(decimal_places) + ", " + py.toFixed(decimal_places);
1834cb93a386Sopenharmony_ci    var _px = (px - srcLeft) * scale;
1835cb93a386Sopenharmony_ci    var _py = (py - srcTop) * scale;
1836cb93a386Sopenharmony_ci    ctx.beginPath();
1837cb93a386Sopenharmony_ci    ctx.arc(_px, _py, 3, 0, Math.PI*2, true);
1838cb93a386Sopenharmony_ci    ctx.closePath();
1839cb93a386Sopenharmony_ci    if (end) {
1840cb93a386Sopenharmony_ci        ctx.fill();
1841cb93a386Sopenharmony_ci    } else {
1842cb93a386Sopenharmony_ci        ctx.stroke();
1843cb93a386Sopenharmony_ci    }
1844cb93a386Sopenharmony_ci    if (debug_xy) {
1845cb93a386Sopenharmony_ci        ctx.textAlign = "left";
1846cb93a386Sopenharmony_ci        ctx.fillText(label, _px + 5, _py);
1847cb93a386Sopenharmony_ci    }
1848cb93a386Sopenharmony_ci}
1849cb93a386Sopenharmony_ci
1850cb93a386Sopenharmony_cifunction coordCount(curveType) {
1851cb93a386Sopenharmony_ci    switch (curveType) {
1852cb93a386Sopenharmony_ci        case PATH_LINE:
1853cb93a386Sopenharmony_ci            return 4;
1854cb93a386Sopenharmony_ci        case PATH_QUAD:
1855cb93a386Sopenharmony_ci            return 6;
1856cb93a386Sopenharmony_ci        case PATH_CONIC:
1857cb93a386Sopenharmony_ci            return 6;
1858cb93a386Sopenharmony_ci        case PATH_CUBIC:
1859cb93a386Sopenharmony_ci            return 8;
1860cb93a386Sopenharmony_ci    }
1861cb93a386Sopenharmony_ci    return -1;
1862cb93a386Sopenharmony_ci}
1863cb93a386Sopenharmony_ci
1864cb93a386Sopenharmony_cifunction drawPoints(ptArray, curveType, drawControls) {
1865cb93a386Sopenharmony_ci    var count = coordCount(curveType);
1866cb93a386Sopenharmony_ci    for (var idx = 0; idx < count; idx += 2) {
1867cb93a386Sopenharmony_ci        if (!drawControls && idx != 0 && idx != count - 2) {
1868cb93a386Sopenharmony_ci            continue;
1869cb93a386Sopenharmony_ci        }
1870cb93a386Sopenharmony_ci        drawPoint(ptArray[idx], ptArray[idx + 1], idx == 0 || idx == count - 2);
1871cb93a386Sopenharmony_ci    }
1872cb93a386Sopenharmony_ci}
1873cb93a386Sopenharmony_ci
1874cb93a386Sopenharmony_cifunction drawControlLines(curve, curveType, drawEnd) {
1875cb93a386Sopenharmony_ci    if (curveType == PATH_LINE) {
1876cb93a386Sopenharmony_ci        return;
1877cb93a386Sopenharmony_ci    }
1878cb93a386Sopenharmony_ci    ctx.strokeStyle = "rgba(0,0,0, 0.3)";
1879cb93a386Sopenharmony_ci    drawLine(curve[0], curve[1], curve[2], curve[3]);
1880cb93a386Sopenharmony_ci    drawLine(curve[2], curve[3], curve[4], curve[5]);
1881cb93a386Sopenharmony_ci    if (curveType == PATH_CUBIC) {
1882cb93a386Sopenharmony_ci        drawLine(curve[4], curve[5], curve[6], curve[7]);
1883cb93a386Sopenharmony_ci        if (drawEnd > 1) {
1884cb93a386Sopenharmony_ci            drawLine(curve[6], curve[7], curve[0], curve[1]);
1885cb93a386Sopenharmony_ci            if (drawEnd > 2) {
1886cb93a386Sopenharmony_ci                drawLine(curve[0], curve[1], curve[4], curve[5]);
1887cb93a386Sopenharmony_ci                drawLine(curve[6], curve[7], curve[2], curve[3]);
1888cb93a386Sopenharmony_ci            }
1889cb93a386Sopenharmony_ci        }
1890cb93a386Sopenharmony_ci    } else if (drawEnd > 1) {
1891cb93a386Sopenharmony_ci        drawLine(curve[4], curve[5], curve[0], curve[1]);
1892cb93a386Sopenharmony_ci    }
1893cb93a386Sopenharmony_ci}
1894cb93a386Sopenharmony_ci
1895cb93a386Sopenharmony_cifunction pointAtT(curve, curveType, t) {
1896cb93a386Sopenharmony_ci    var xy = {};
1897cb93a386Sopenharmony_ci    switch (curveType) {
1898cb93a386Sopenharmony_ci        case PATH_LINE:
1899cb93a386Sopenharmony_ci            var a = 1 - t;
1900cb93a386Sopenharmony_ci            var b = t;
1901cb93a386Sopenharmony_ci            xy.x = a * curve[0] + b * curve[2];
1902cb93a386Sopenharmony_ci            xy.y = a * curve[1] + b * curve[3];
1903cb93a386Sopenharmony_ci            break;
1904cb93a386Sopenharmony_ci        case PATH_QUAD:
1905cb93a386Sopenharmony_ci            var one_t = 1 - t;
1906cb93a386Sopenharmony_ci            var a = one_t * one_t;
1907cb93a386Sopenharmony_ci            var b = 2 * one_t * t;
1908cb93a386Sopenharmony_ci            var c = t * t;
1909cb93a386Sopenharmony_ci            xy.x = a * curve[0] + b * curve[2] + c * curve[4];
1910cb93a386Sopenharmony_ci            xy.y = a * curve[1] + b * curve[3] + c * curve[5];
1911cb93a386Sopenharmony_ci            break;
1912cb93a386Sopenharmony_ci        case PATH_CONIC:
1913cb93a386Sopenharmony_ci            var one_t = 1 - t;
1914cb93a386Sopenharmony_ci            var a = one_t * one_t;
1915cb93a386Sopenharmony_ci            var b = 2 * one_t * t;
1916cb93a386Sopenharmony_ci            var c = t * t;
1917cb93a386Sopenharmony_ci            xy.x = a * curve[0] + b * curve[2] * curve[6] + c * curve[4];
1918cb93a386Sopenharmony_ci            xy.y = a * curve[1] + b * curve[3] * curve[6] + c * curve[5];
1919cb93a386Sopenharmony_ci            var d = a + b * curve[6] + c;
1920cb93a386Sopenharmony_ci            xy.x /= d;
1921cb93a386Sopenharmony_ci            xy.y /= d;
1922cb93a386Sopenharmony_ci            break;
1923cb93a386Sopenharmony_ci        case PATH_CUBIC:
1924cb93a386Sopenharmony_ci            var one_t = 1 - t;
1925cb93a386Sopenharmony_ci            var one_t2 = one_t * one_t;
1926cb93a386Sopenharmony_ci            var a = one_t2 * one_t;
1927cb93a386Sopenharmony_ci            var b = 3 * one_t2 * t;
1928cb93a386Sopenharmony_ci            var t2 = t * t;
1929cb93a386Sopenharmony_ci            var c = 3 * one_t * t2;
1930cb93a386Sopenharmony_ci            var d = t2 * t;
1931cb93a386Sopenharmony_ci            xy.x = a * curve[0] + b * curve[2] + c * curve[4] + d * curve[6];
1932cb93a386Sopenharmony_ci            xy.y = a * curve[1] + b * curve[3] + c * curve[5] + d * curve[7];
1933cb93a386Sopenharmony_ci            break;
1934cb93a386Sopenharmony_ci    }
1935cb93a386Sopenharmony_ci    return xy;
1936cb93a386Sopenharmony_ci}
1937cb93a386Sopenharmony_ci
1938cb93a386Sopenharmony_cifunction drawPointAtT(curve, curveType) {
1939cb93a386Sopenharmony_ci    var x, y;
1940cb93a386Sopenharmony_ci    var xy = pointAtT(curve, curveType, curveT);
1941cb93a386Sopenharmony_ci    drawPoint(xy.x, xy.y, true);
1942cb93a386Sopenharmony_ci    if (!draw_intersectT) {
1943cb93a386Sopenharmony_ci        return;
1944cb93a386Sopenharmony_ci    }
1945cb93a386Sopenharmony_ci    ctx.fillStyle = "red";
1946cb93a386Sopenharmony_ci    drawTAtPointUp(xy.x, xy.y, curveT);
1947cb93a386Sopenharmony_ci}
1948cb93a386Sopenharmony_ci
1949cb93a386Sopenharmony_cifunction drawTAtPointUp(px, py, t) {
1950cb93a386Sopenharmony_ci    var label = t.toFixed(decimal_places);
1951cb93a386Sopenharmony_ci    var _px = (px - srcLeft)* scale;
1952cb93a386Sopenharmony_ci    var _py = (py - srcTop) * scale;
1953cb93a386Sopenharmony_ci    ctx.fillText(label, _px + 5, _py - 10);
1954cb93a386Sopenharmony_ci}
1955cb93a386Sopenharmony_ci
1956cb93a386Sopenharmony_cifunction drawTAtPointDown(px, py, t) {
1957cb93a386Sopenharmony_ci    var label = t.toFixed(decimal_places);
1958cb93a386Sopenharmony_ci    var _px = (px - srcLeft)* scale;
1959cb93a386Sopenharmony_ci    var _py = (py - srcTop) * scale;
1960cb93a386Sopenharmony_ci    ctx.fillText(label, _px + 5, _py + 10);
1961cb93a386Sopenharmony_ci}
1962cb93a386Sopenharmony_ci
1963cb93a386Sopenharmony_cifunction alreadyDrawnLine(x1, y1, x2, y2) {
1964cb93a386Sopenharmony_ci    if (collect_bounds) {
1965cb93a386Sopenharmony_ci        if (focus_enabled) {
1966cb93a386Sopenharmony_ci            focusXmin = Math.min(focusXmin, x1, x2);
1967cb93a386Sopenharmony_ci            focusYmin = Math.min(focusYmin, y1, y2);
1968cb93a386Sopenharmony_ci            focusXmax = Math.max(focusXmax, x1, x2);
1969cb93a386Sopenharmony_ci            focusYmax = Math.max(focusYmax, y1, y2);
1970cb93a386Sopenharmony_ci        }
1971cb93a386Sopenharmony_ci        return true;
1972cb93a386Sopenharmony_ci    }
1973cb93a386Sopenharmony_ci    for (var pts = 0; pts < drawnLines.length; pts += 4) {
1974cb93a386Sopenharmony_ci        if (x1 == drawnLines[pts] && y1 == drawnLines[pts + 1]
1975cb93a386Sopenharmony_ci                && x2 == drawnLines[pts + 2] && y2 == drawnLines[pts + 3]) {
1976cb93a386Sopenharmony_ci            return true;
1977cb93a386Sopenharmony_ci        }
1978cb93a386Sopenharmony_ci    }
1979cb93a386Sopenharmony_ci    drawnLines.push(x1);
1980cb93a386Sopenharmony_ci    drawnLines.push(y1);
1981cb93a386Sopenharmony_ci    drawnLines.push(x2);
1982cb93a386Sopenharmony_ci    drawnLines.push(y2);
1983cb93a386Sopenharmony_ci    return false;
1984cb93a386Sopenharmony_ci}
1985cb93a386Sopenharmony_ci
1986cb93a386Sopenharmony_cifunction drawLine(x1, y1, x2, y2) {
1987cb93a386Sopenharmony_ci    if (alreadyDrawnLine(x1, y1, x2, y2)) {
1988cb93a386Sopenharmony_ci        return;
1989cb93a386Sopenharmony_ci    }
1990cb93a386Sopenharmony_ci    ctx.beginPath();
1991cb93a386Sopenharmony_ci    ctx.moveTo((x1 - srcLeft) * scale,
1992cb93a386Sopenharmony_ci            (y1 - srcTop) * scale);
1993cb93a386Sopenharmony_ci    ctx.lineTo((x2 - srcLeft) * scale,
1994cb93a386Sopenharmony_ci            (y2 - srcTop) * scale);
1995cb93a386Sopenharmony_ci    ctx.stroke();
1996cb93a386Sopenharmony_ci}
1997cb93a386Sopenharmony_ci
1998cb93a386Sopenharmony_cifunction linePartial(x1, y1, x2, y2, t1, t2) {
1999cb93a386Sopenharmony_ci    var dx = x1 - x2;
2000cb93a386Sopenharmony_ci    var dy = y1 - y2;
2001cb93a386Sopenharmony_ci    var array = [
2002cb93a386Sopenharmony_ci        x1 - t1 * dx,
2003cb93a386Sopenharmony_ci        y1 - t1 * dy,
2004cb93a386Sopenharmony_ci        x1 - t2 * dx,
2005cb93a386Sopenharmony_ci        y1 - t2 * dy
2006cb93a386Sopenharmony_ci    ];
2007cb93a386Sopenharmony_ci    return array;
2008cb93a386Sopenharmony_ci}
2009cb93a386Sopenharmony_ci
2010cb93a386Sopenharmony_cifunction drawLinePartial(x1, y1, x2, y2, t1, t2) {
2011cb93a386Sopenharmony_ci    var a = linePartial(x1, y1, x2, y2, t1, t2);
2012cb93a386Sopenharmony_ci    var ax = a[0];
2013cb93a386Sopenharmony_ci    var ay = a[1];
2014cb93a386Sopenharmony_ci    var bx = a[2];
2015cb93a386Sopenharmony_ci    var by = a[3];
2016cb93a386Sopenharmony_ci    if (alreadyDrawnLine(ax, ay, bx, by)) {
2017cb93a386Sopenharmony_ci        return;
2018cb93a386Sopenharmony_ci    }
2019cb93a386Sopenharmony_ci    ctx.beginPath();
2020cb93a386Sopenharmony_ci    ctx.moveTo((ax - srcLeft) * scale,
2021cb93a386Sopenharmony_ci            (ay - srcTop) * scale);
2022cb93a386Sopenharmony_ci    ctx.lineTo((bx - srcLeft) * scale,
2023cb93a386Sopenharmony_ci            (by - srcTop) * scale);
2024cb93a386Sopenharmony_ci    ctx.stroke();
2025cb93a386Sopenharmony_ci}
2026cb93a386Sopenharmony_ci
2027cb93a386Sopenharmony_cifunction alreadyDrawnQuad(x1, y1, x2, y2, x3, y3) {
2028cb93a386Sopenharmony_ci    if (collect_bounds) {
2029cb93a386Sopenharmony_ci        if (focus_enabled) {
2030cb93a386Sopenharmony_ci            focusXmin = Math.min(focusXmin, x1, x2, x3);
2031cb93a386Sopenharmony_ci            focusYmin = Math.min(focusYmin, y1, y2, y3);
2032cb93a386Sopenharmony_ci            focusXmax = Math.max(focusXmax, x1, x2, x3);
2033cb93a386Sopenharmony_ci            focusYmax = Math.max(focusYmax, y1, y2, y3);
2034cb93a386Sopenharmony_ci        }
2035cb93a386Sopenharmony_ci        return true;
2036cb93a386Sopenharmony_ci    }
2037cb93a386Sopenharmony_ci    for (var pts = 0; pts < drawnQuads.length; pts += 6) {
2038cb93a386Sopenharmony_ci        if (x1 == drawnQuads[pts] && y1 == drawnQuads[pts + 1]
2039cb93a386Sopenharmony_ci                && x2 == drawnQuads[pts + 2] && y2 == drawnQuads[pts + 3]
2040cb93a386Sopenharmony_ci                && x3 == drawnQuads[pts + 4] && y3 == drawnQuads[pts + 5]) {
2041cb93a386Sopenharmony_ci            return true;
2042cb93a386Sopenharmony_ci        }
2043cb93a386Sopenharmony_ci    }
2044cb93a386Sopenharmony_ci    drawnQuads.push(x1);
2045cb93a386Sopenharmony_ci    drawnQuads.push(y1);
2046cb93a386Sopenharmony_ci    drawnQuads.push(x2);
2047cb93a386Sopenharmony_ci    drawnQuads.push(y2);
2048cb93a386Sopenharmony_ci    drawnQuads.push(x3);
2049cb93a386Sopenharmony_ci    drawnQuads.push(y3);
2050cb93a386Sopenharmony_ci    return false;
2051cb93a386Sopenharmony_ci}
2052cb93a386Sopenharmony_ci
2053cb93a386Sopenharmony_cifunction drawQuad(x1, y1, x2, y2, x3, y3) {
2054cb93a386Sopenharmony_ci    if (alreadyDrawnQuad(x1, y1, x2, y2, x3, y3)) {
2055cb93a386Sopenharmony_ci        return;
2056cb93a386Sopenharmony_ci    }
2057cb93a386Sopenharmony_ci    ctx.beginPath();
2058cb93a386Sopenharmony_ci    ctx.moveTo((x1 - srcLeft) * scale,
2059cb93a386Sopenharmony_ci            (y1 - srcTop) * scale);
2060cb93a386Sopenharmony_ci    ctx.quadraticCurveTo((x2 - srcLeft) * scale,
2061cb93a386Sopenharmony_ci            (y2 - srcTop) * scale,
2062cb93a386Sopenharmony_ci            (x3 - srcLeft) * scale,
2063cb93a386Sopenharmony_ci            (y3 - srcTop) * scale);
2064cb93a386Sopenharmony_ci    ctx.stroke();
2065cb93a386Sopenharmony_ci}
2066cb93a386Sopenharmony_ci
2067cb93a386Sopenharmony_cifunction interp(A, B, t) {
2068cb93a386Sopenharmony_ci    return A + (B - A) * t;
2069cb93a386Sopenharmony_ci}
2070cb93a386Sopenharmony_ci
2071cb93a386Sopenharmony_cifunction interp_quad_coords(x1, x2, x3, t)
2072cb93a386Sopenharmony_ci{
2073cb93a386Sopenharmony_ci    var ab = interp(x1, x2, t);
2074cb93a386Sopenharmony_ci    var bc = interp(x2, x3, t);
2075cb93a386Sopenharmony_ci    var abc = interp(ab, bc, t);
2076cb93a386Sopenharmony_ci    return abc;
2077cb93a386Sopenharmony_ci}
2078cb93a386Sopenharmony_ci
2079cb93a386Sopenharmony_cifunction quadPartial(x1, y1, x2, y2, x3, y3, t1, t2) {
2080cb93a386Sopenharmony_ci    var ax = interp_quad_coords(x1, x2, x3, t1);
2081cb93a386Sopenharmony_ci    var ay = interp_quad_coords(y1, y2, y3, t1);
2082cb93a386Sopenharmony_ci    var dx = interp_quad_coords(x1, x2, x3, (t1 + t2) / 2);
2083cb93a386Sopenharmony_ci    var dy = interp_quad_coords(y1, y2, y3, (t1 + t2) / 2);
2084cb93a386Sopenharmony_ci    var cx = interp_quad_coords(x1, x2, x3, t2);
2085cb93a386Sopenharmony_ci    var cy = interp_quad_coords(y1, y2, y3, t2);
2086cb93a386Sopenharmony_ci    var bx = 2*dx - (ax + cx)/2;
2087cb93a386Sopenharmony_ci    var by = 2*dy - (ay + cy)/2;
2088cb93a386Sopenharmony_ci    var array = [
2089cb93a386Sopenharmony_ci        ax, ay, bx, by, cx, cy
2090cb93a386Sopenharmony_ci    ];
2091cb93a386Sopenharmony_ci    return array;
2092cb93a386Sopenharmony_ci}
2093cb93a386Sopenharmony_ci
2094cb93a386Sopenharmony_cifunction drawQuadPartial(x1, y1, x2, y2, x3, y3, t1, t2) {
2095cb93a386Sopenharmony_ci    var a = quadPartial(x1, y1, x2, y2, x3, y3, t1, t2);
2096cb93a386Sopenharmony_ci    var ax = a[0];
2097cb93a386Sopenharmony_ci    var ay = a[1];
2098cb93a386Sopenharmony_ci    var bx = a[2];
2099cb93a386Sopenharmony_ci    var by = a[3];
2100cb93a386Sopenharmony_ci    var cx = a[4];
2101cb93a386Sopenharmony_ci    var cy = a[5];
2102cb93a386Sopenharmony_ci    if (alreadyDrawnQuad(ax, ay, bx, by, cx, cy)) {
2103cb93a386Sopenharmony_ci        return;
2104cb93a386Sopenharmony_ci    }
2105cb93a386Sopenharmony_ci    ctx.beginPath();
2106cb93a386Sopenharmony_ci    ctx.moveTo((ax - srcLeft) * scale,
2107cb93a386Sopenharmony_ci            (ay - srcTop) * scale);
2108cb93a386Sopenharmony_ci    ctx.quadraticCurveTo((bx - srcLeft) * scale,
2109cb93a386Sopenharmony_ci            (by - srcTop) * scale,
2110cb93a386Sopenharmony_ci            (cx - srcLeft) * scale,
2111cb93a386Sopenharmony_ci            (cy - srcTop) * scale);
2112cb93a386Sopenharmony_ci    ctx.stroke();
2113cb93a386Sopenharmony_ci}
2114cb93a386Sopenharmony_ci
2115cb93a386Sopenharmony_cifunction alreadyDrawnConic(x1, y1, x2, y2, x3, y3, w) {
2116cb93a386Sopenharmony_ci    if (collect_bounds) {
2117cb93a386Sopenharmony_ci        if (focus_enabled) {
2118cb93a386Sopenharmony_ci            focusXmin = Math.min(focusXmin, x1, x2, x3);
2119cb93a386Sopenharmony_ci            focusYmin = Math.min(focusYmin, y1, y2, y3);
2120cb93a386Sopenharmony_ci            focusXmax = Math.max(focusXmax, x1, x2, x3);
2121cb93a386Sopenharmony_ci            focusYmax = Math.max(focusYmax, y1, y2, y3);
2122cb93a386Sopenharmony_ci        }
2123cb93a386Sopenharmony_ci        return true;
2124cb93a386Sopenharmony_ci    }
2125cb93a386Sopenharmony_ci    for (var pts = 0; pts < drawnConics.length; pts += 8) {
2126cb93a386Sopenharmony_ci        if (x1 == drawnConics[pts] && y1 == drawnCubics[pts + 1]
2127cb93a386Sopenharmony_ci                && x2 == drawnCubics[pts + 2] && y2 == drawnCubics[pts + 3]
2128cb93a386Sopenharmony_ci                && x3 == drawnCubics[pts + 4] && y3 == drawnCubics[pts + 5]
2129cb93a386Sopenharmony_ci                && w == drawnCubics[pts + 6]) {
2130cb93a386Sopenharmony_ci            return true;
2131cb93a386Sopenharmony_ci        }
2132cb93a386Sopenharmony_ci    }
2133cb93a386Sopenharmony_ci    drawnConics.push(x1);
2134cb93a386Sopenharmony_ci    drawnConics.push(y1);
2135cb93a386Sopenharmony_ci    drawnConics.push(x2);
2136cb93a386Sopenharmony_ci    drawnConics.push(y2);
2137cb93a386Sopenharmony_ci    drawnConics.push(x3);
2138cb93a386Sopenharmony_ci    drawnConics.push(y3);
2139cb93a386Sopenharmony_ci    drawnCubics.push(w);
2140cb93a386Sopenharmony_ci    return false;
2141cb93a386Sopenharmony_ci}
2142cb93a386Sopenharmony_ci
2143cb93a386Sopenharmony_civar kMaxConicToQuadPOW2 = 5;
2144cb93a386Sopenharmony_ci
2145cb93a386Sopenharmony_cifunction computeQuadPOW2(curve, tol) {
2146cb93a386Sopenharmony_ci    var a = curve[6] - 1;
2147cb93a386Sopenharmony_ci    var k = a / (4 * (2 + a));
2148cb93a386Sopenharmony_ci    var x = k * (curve[0] - 2 * curve[2] + curve[4]);
2149cb93a386Sopenharmony_ci    var y = k * (curve[1] - 2 * curve[3] + curve[5]);
2150cb93a386Sopenharmony_ci
2151cb93a386Sopenharmony_ci    var error = Math.sqrt(x * x + y * y);
2152cb93a386Sopenharmony_ci    var pow2;
2153cb93a386Sopenharmony_ci    for (pow2 = 0; pow2 < kMaxConicToQuadPOW2; ++pow2) {
2154cb93a386Sopenharmony_ci        if (error <= tol) {
2155cb93a386Sopenharmony_ci            break;
2156cb93a386Sopenharmony_ci        }
2157cb93a386Sopenharmony_ci        error *= 0.25;
2158cb93a386Sopenharmony_ci    }
2159cb93a386Sopenharmony_ci    return pow2;
2160cb93a386Sopenharmony_ci}
2161cb93a386Sopenharmony_ci
2162cb93a386Sopenharmony_cifunction subdivide_w_value(w) {
2163cb93a386Sopenharmony_ci    return Math.sqrt(0.5 + w * 0.5);
2164cb93a386Sopenharmony_ci}
2165cb93a386Sopenharmony_ci
2166cb93a386Sopenharmony_cifunction chop(curve, part1, part2) {
2167cb93a386Sopenharmony_ci    var w = curve[6];
2168cb93a386Sopenharmony_ci    var scale = 1 / (1 + w);
2169cb93a386Sopenharmony_ci    part1[0] = curve[0];
2170cb93a386Sopenharmony_ci    part1[1] = curve[1];
2171cb93a386Sopenharmony_ci    part1[2] = (curve[0] + curve[2] * w) * scale;
2172cb93a386Sopenharmony_ci    part1[3] = (curve[1] + curve[3] * w) * scale;
2173cb93a386Sopenharmony_ci    part1[4] = part2[0] = (curve[0] + (curve[2] * w) * 2 + curve[4]) * scale * 0.5;
2174cb93a386Sopenharmony_ci    part1[5] = part2[1] = (curve[1] + (curve[3] * w) * 2 + curve[5]) * scale * 0.5;
2175cb93a386Sopenharmony_ci    part2[2] = (curve[2] * w + curve[4]) * scale;
2176cb93a386Sopenharmony_ci    part2[3] = (curve[3] * w + curve[5]) * scale;
2177cb93a386Sopenharmony_ci    part2[4] = curve[4];
2178cb93a386Sopenharmony_ci    part2[5] = curve[5];
2179cb93a386Sopenharmony_ci    part1[6] = part2[6] = subdivide_w_value(w);
2180cb93a386Sopenharmony_ci}
2181cb93a386Sopenharmony_ci
2182cb93a386Sopenharmony_cifunction subdivide(curve, level, pts) {
2183cb93a386Sopenharmony_ci    if (0 == level) {
2184cb93a386Sopenharmony_ci        pts.push(curve[2]);
2185cb93a386Sopenharmony_ci        pts.push(curve[3]);
2186cb93a386Sopenharmony_ci        pts.push(curve[4]);
2187cb93a386Sopenharmony_ci        pts.push(curve[5]);
2188cb93a386Sopenharmony_ci    } else {
2189cb93a386Sopenharmony_ci        var part1 = [], part2 = [];
2190cb93a386Sopenharmony_ci        chop(curve, part1, part2);
2191cb93a386Sopenharmony_ci        --level;
2192cb93a386Sopenharmony_ci        subdivide(part1, level, pts);
2193cb93a386Sopenharmony_ci        subdivide(part2, level, pts);
2194cb93a386Sopenharmony_ci    }
2195cb93a386Sopenharmony_ci}
2196cb93a386Sopenharmony_ci
2197cb93a386Sopenharmony_cifunction chopIntoQuadsPOW2(curve, pow2, pts) {
2198cb93a386Sopenharmony_ci    subdivide(curve, pow2, pts);
2199cb93a386Sopenharmony_ci    return 1 << pow2;
2200cb93a386Sopenharmony_ci}
2201cb93a386Sopenharmony_ci
2202cb93a386Sopenharmony_cifunction drawConicWithQuads(x1, y1, x2, y2, x3, y3, w) {
2203cb93a386Sopenharmony_ci    if (alreadyDrawnConic(x1, y1, x2, y2, x3, y3, w)) {
2204cb93a386Sopenharmony_ci        return;
2205cb93a386Sopenharmony_ci    }
2206cb93a386Sopenharmony_ci    ctx.beginPath();
2207cb93a386Sopenharmony_ci    ctx.moveTo((x1 - srcLeft) * scale,
2208cb93a386Sopenharmony_ci            (y1 - srcTop) * scale);
2209cb93a386Sopenharmony_ci    var tol = 1 / scale;
2210cb93a386Sopenharmony_ci    var curve = [x1, y1, x2, y2, x3, y3, w];
2211cb93a386Sopenharmony_ci    var pow2 = computeQuadPOW2(curve, tol);
2212cb93a386Sopenharmony_ci    var pts = [];
2213cb93a386Sopenharmony_ci    chopIntoQuadsPOW2(curve, pow2, pts);
2214cb93a386Sopenharmony_ci    for (var i = 0; i < pts.length; i += 4) {
2215cb93a386Sopenharmony_ci        ctx.quadraticCurveTo(
2216cb93a386Sopenharmony_ci            (pts[i + 0] - srcLeft) * scale, (pts[i + 1] - srcTop) * scale,
2217cb93a386Sopenharmony_ci            (pts[i + 2] - srcLeft) * scale, (pts[i + 3] - srcTop) * scale);
2218cb93a386Sopenharmony_ci    }
2219cb93a386Sopenharmony_ci    ctx.stroke();
2220cb93a386Sopenharmony_ci}
2221cb93a386Sopenharmony_ci
2222cb93a386Sopenharmony_cifunction conic_eval_numerator(x1, x2, x3, w, t) {
2223cb93a386Sopenharmony_ci    var src2w = x2 * w;
2224cb93a386Sopenharmony_ci    var C = x1;
2225cb93a386Sopenharmony_ci    var A = x3 - 2 * src2w + C;
2226cb93a386Sopenharmony_ci    var B = 2 * (src2w - C);
2227cb93a386Sopenharmony_ci    return (A * t + B) * t + C;
2228cb93a386Sopenharmony_ci}
2229cb93a386Sopenharmony_ci
2230cb93a386Sopenharmony_ci
2231cb93a386Sopenharmony_cifunction conic_eval_denominator(w, t) {
2232cb93a386Sopenharmony_ci    var B = 2 * (w - 1);
2233cb93a386Sopenharmony_ci    var C = 1;
2234cb93a386Sopenharmony_ci    var A = -B;
2235cb93a386Sopenharmony_ci    return (A * t + B) * t + C;
2236cb93a386Sopenharmony_ci}
2237cb93a386Sopenharmony_ci
2238cb93a386Sopenharmony_cifunction conicPartial(x1, y1, x2, y2, x3, y3, w, t1, t2) {
2239cb93a386Sopenharmony_ci    var ax = conic_eval_numerator(x1, x2, x3, w, t1);
2240cb93a386Sopenharmony_ci    var ay = conic_eval_numerator(y1, y2, y3, w, t1);
2241cb93a386Sopenharmony_ci    var az = conic_eval_denominator(w, t1);
2242cb93a386Sopenharmony_ci    var midT = (t1 + t2) / 2;
2243cb93a386Sopenharmony_ci    var dx = conic_eval_numerator(x1, x2, x3, w, midT);
2244cb93a386Sopenharmony_ci    var dy = conic_eval_numerator(y1, y2, y3, w, midT);
2245cb93a386Sopenharmony_ci    var dz = conic_eval_denominator(w, midT);
2246cb93a386Sopenharmony_ci    var cx = conic_eval_numerator(x1, x2, x3, w, t2);
2247cb93a386Sopenharmony_ci    var cy = conic_eval_numerator(y1, y2, y3, w, t2);
2248cb93a386Sopenharmony_ci    var cz = conic_eval_denominator(w, t2);
2249cb93a386Sopenharmony_ci    var bx = 2 * dx - (ax + cx) / 2;
2250cb93a386Sopenharmony_ci    var by = 2 * dy - (ay + cy) / 2;
2251cb93a386Sopenharmony_ci    var bz = 2 * dz - (az + cz) / 2;
2252cb93a386Sopenharmony_ci    var dt = t2 - t1;
2253cb93a386Sopenharmony_ci    var dt_1 = 1 - dt;
2254cb93a386Sopenharmony_ci    var array = [
2255cb93a386Sopenharmony_ci        ax / az, ay / az, bx / bz, by / bz, cx / cz, cy / cz, 0
2256cb93a386Sopenharmony_ci    ];
2257cb93a386Sopenharmony_ci    var dMidAC = { x:(array[0] + array[4]) / 2, y:(array[1] + array[5]) / 2 };
2258cb93a386Sopenharmony_ci    var dMid = { x:dx / dz, y:dy / dz };
2259cb93a386Sopenharmony_ci    var dWNumer = { x:dMidAC.x - dMid.x, y:dMidAC.y - dMid.y };
2260cb93a386Sopenharmony_ci    var dWDenom = { x:dMid.x - array[2], y:dMid.y - array[3] };
2261cb93a386Sopenharmony_ci    var partW = Math.sqrt(dWNumer.x * dWNumer.x + dWNumer.y * dWNumer.y)
2262cb93a386Sopenharmony_ci                / Math.sqrt(dWDenom.x * dWDenom.x + dWDenom.y * dWDenom.y);
2263cb93a386Sopenharmony_ci    array[6] = partW;
2264cb93a386Sopenharmony_ci    return array;
2265cb93a386Sopenharmony_ci}
2266cb93a386Sopenharmony_ci
2267cb93a386Sopenharmony_cifunction drawConicPartial(x1, y1, x2, y2, x3, y3, w, t1, t2) {
2268cb93a386Sopenharmony_ci    var a = conicPartial(x1, y1, x2, y2, x3, y3, w, t1, t2);
2269cb93a386Sopenharmony_ci    var ax = a[0];
2270cb93a386Sopenharmony_ci    var ay = a[1];
2271cb93a386Sopenharmony_ci    var bx = a[2];
2272cb93a386Sopenharmony_ci    var by = a[3];
2273cb93a386Sopenharmony_ci    var cx = a[4];
2274cb93a386Sopenharmony_ci    var cy = a[5];
2275cb93a386Sopenharmony_ci    var w_ = a[6];
2276cb93a386Sopenharmony_ci    drawConicWithQuads(ax, ay, bx, by, cx, cy, w_);
2277cb93a386Sopenharmony_ci}
2278cb93a386Sopenharmony_ci
2279cb93a386Sopenharmony_cifunction alreadyDrawnCubic(x1, y1, x2, y2, x3, y3, x4, y4) {
2280cb93a386Sopenharmony_ci    if (collect_bounds) {
2281cb93a386Sopenharmony_ci        if (focus_enabled) {
2282cb93a386Sopenharmony_ci            focusXmin = Math.min(focusXmin, x1, x2, x3, x4);
2283cb93a386Sopenharmony_ci            focusYmin = Math.min(focusYmin, y1, y2, y3, y4);
2284cb93a386Sopenharmony_ci            focusXmax = Math.max(focusXmax, x1, x2, x3, x4);
2285cb93a386Sopenharmony_ci            focusYmax = Math.max(focusYmax, y1, y2, y3, y4);
2286cb93a386Sopenharmony_ci        }
2287cb93a386Sopenharmony_ci        return true;
2288cb93a386Sopenharmony_ci    }
2289cb93a386Sopenharmony_ci    for (var pts = 0; pts < drawnCubics.length; pts += 8) {
2290cb93a386Sopenharmony_ci        if (x1 == drawnCubics[pts] && y1 == drawnCubics[pts + 1]
2291cb93a386Sopenharmony_ci                && x2 == drawnCubics[pts + 2] && y2 == drawnCubics[pts + 3]
2292cb93a386Sopenharmony_ci                && x3 == drawnCubics[pts + 4] && y3 == drawnCubics[pts + 5]
2293cb93a386Sopenharmony_ci                && x4 == drawnCubics[pts + 6] && y4 == drawnCubics[pts + 7]) {
2294cb93a386Sopenharmony_ci            return true;
2295cb93a386Sopenharmony_ci        }
2296cb93a386Sopenharmony_ci    }
2297cb93a386Sopenharmony_ci    drawnCubics.push(x1);
2298cb93a386Sopenharmony_ci    drawnCubics.push(y1);
2299cb93a386Sopenharmony_ci    drawnCubics.push(x2);
2300cb93a386Sopenharmony_ci    drawnCubics.push(y2);
2301cb93a386Sopenharmony_ci    drawnCubics.push(x3);
2302cb93a386Sopenharmony_ci    drawnCubics.push(y3);
2303cb93a386Sopenharmony_ci    drawnCubics.push(x4);
2304cb93a386Sopenharmony_ci    drawnCubics.push(y4);
2305cb93a386Sopenharmony_ci    return false;
2306cb93a386Sopenharmony_ci}
2307cb93a386Sopenharmony_ci
2308cb93a386Sopenharmony_cifunction drawCubic(x1, y1, x2, y2, x3, y3, x4, y4) {
2309cb93a386Sopenharmony_ci    if (alreadyDrawnCubic(x1, y1, x2, y2, x3, y3, x4, y4)) {
2310cb93a386Sopenharmony_ci        return;
2311cb93a386Sopenharmony_ci    }
2312cb93a386Sopenharmony_ci    ctx.beginPath();
2313cb93a386Sopenharmony_ci    ctx.moveTo((x1 - srcLeft) * scale,
2314cb93a386Sopenharmony_ci            (y1 - srcTop) * scale);
2315cb93a386Sopenharmony_ci    ctx.bezierCurveTo((x2 - srcLeft) * scale,
2316cb93a386Sopenharmony_ci            (y2 - srcTop) * scale,
2317cb93a386Sopenharmony_ci            (x3 - srcLeft) * scale,
2318cb93a386Sopenharmony_ci            (y3 - srcTop) * scale,
2319cb93a386Sopenharmony_ci            (x4 - srcLeft) * scale,
2320cb93a386Sopenharmony_ci            (y4 - srcTop) * scale);
2321cb93a386Sopenharmony_ci    ctx.stroke();
2322cb93a386Sopenharmony_ci}
2323cb93a386Sopenharmony_ci
2324cb93a386Sopenharmony_cifunction interp_cubic_coords(x1, x2, x3, x4, t)
2325cb93a386Sopenharmony_ci{
2326cb93a386Sopenharmony_ci    var ab = interp(x1, x2, t);
2327cb93a386Sopenharmony_ci    var bc = interp(x2, x3, t);
2328cb93a386Sopenharmony_ci    var cd = interp(x3, x4, t);
2329cb93a386Sopenharmony_ci    var abc = interp(ab, bc, t);
2330cb93a386Sopenharmony_ci    var bcd = interp(bc, cd, t);
2331cb93a386Sopenharmony_ci    var abcd = interp(abc, bcd, t);
2332cb93a386Sopenharmony_ci    return abcd;
2333cb93a386Sopenharmony_ci}
2334cb93a386Sopenharmony_ci
2335cb93a386Sopenharmony_cifunction cubicPartial(x1, y1, x2, y2, x3, y3, x4, y4, t1, t2) {
2336cb93a386Sopenharmony_ci    var ax = interp_cubic_coords(x1, x2, x3, x4, t1);
2337cb93a386Sopenharmony_ci    var ay = interp_cubic_coords(y1, y2, y3, y4, t1);
2338cb93a386Sopenharmony_ci    var ex = interp_cubic_coords(x1, x2, x3, x4, (t1*2+t2)/3);
2339cb93a386Sopenharmony_ci    var ey = interp_cubic_coords(y1, y2, y3, y4, (t1*2+t2)/3);
2340cb93a386Sopenharmony_ci    var fx = interp_cubic_coords(x1, x2, x3, x4, (t1+t2*2)/3);
2341cb93a386Sopenharmony_ci    var fy = interp_cubic_coords(y1, y2, y3, y4, (t1+t2*2)/3);
2342cb93a386Sopenharmony_ci    var dx = interp_cubic_coords(x1, x2, x3, x4, t2);
2343cb93a386Sopenharmony_ci    var dy = interp_cubic_coords(y1, y2, y3, y4, t2);
2344cb93a386Sopenharmony_ci    var mx = ex * 27 - ax * 8 - dx;
2345cb93a386Sopenharmony_ci    var my = ey * 27 - ay * 8 - dy;
2346cb93a386Sopenharmony_ci    var nx = fx * 27 - ax - dx * 8;
2347cb93a386Sopenharmony_ci    var ny = fy * 27 - ay - dy * 8;
2348cb93a386Sopenharmony_ci    var bx = (mx * 2 - nx) / 18;
2349cb93a386Sopenharmony_ci    var by = (my * 2 - ny) / 18;
2350cb93a386Sopenharmony_ci    var cx = (nx * 2 - mx) / 18;
2351cb93a386Sopenharmony_ci    var cy = (ny * 2 - my) / 18;
2352cb93a386Sopenharmony_ci    var array = [
2353cb93a386Sopenharmony_ci        ax, ay, bx, by, cx, cy, dx, dy
2354cb93a386Sopenharmony_ci    ];
2355cb93a386Sopenharmony_ci    return array;
2356cb93a386Sopenharmony_ci}
2357cb93a386Sopenharmony_ci
2358cb93a386Sopenharmony_cifunction drawCubicPartial(x1, y1, x2, y2, x3, y3, x4, y4, t1, t2) {
2359cb93a386Sopenharmony_ci    var a = cubicPartial(x1, y1, x2, y2, x3, y3, x4, y4, t1, t2);
2360cb93a386Sopenharmony_ci    var ax = a[0];
2361cb93a386Sopenharmony_ci    var ay = a[1];
2362cb93a386Sopenharmony_ci    var bx = a[2];
2363cb93a386Sopenharmony_ci    var by = a[3];
2364cb93a386Sopenharmony_ci    var cx = a[4];
2365cb93a386Sopenharmony_ci    var cy = a[5];
2366cb93a386Sopenharmony_ci    var dx = a[6];
2367cb93a386Sopenharmony_ci    var dy = a[7];
2368cb93a386Sopenharmony_ci    if (alreadyDrawnCubic(ax, ay, bx, by, cx, cy, dx, dy)) {
2369cb93a386Sopenharmony_ci        return;
2370cb93a386Sopenharmony_ci    }
2371cb93a386Sopenharmony_ci    ctx.beginPath();
2372cb93a386Sopenharmony_ci    ctx.moveTo((ax - srcLeft) * scale,
2373cb93a386Sopenharmony_ci            (ay - srcTop) * scale);
2374cb93a386Sopenharmony_ci    ctx.bezierCurveTo((bx - srcLeft) * scale,
2375cb93a386Sopenharmony_ci            (by - srcTop) * scale,
2376cb93a386Sopenharmony_ci            (cx - srcLeft) * scale,
2377cb93a386Sopenharmony_ci            (cy - srcTop) * scale,
2378cb93a386Sopenharmony_ci            (dx - srcLeft) * scale,
2379cb93a386Sopenharmony_ci            (dy - srcTop) * scale);
2380cb93a386Sopenharmony_ci    ctx.stroke();
2381cb93a386Sopenharmony_ci}
2382cb93a386Sopenharmony_ci
2383cb93a386Sopenharmony_cifunction drawCurve(c) {
2384cb93a386Sopenharmony_ci    switch (c.length) {
2385cb93a386Sopenharmony_ci        case 4:
2386cb93a386Sopenharmony_ci            drawLine(c[0], c[1], c[2], c[3]);
2387cb93a386Sopenharmony_ci            break;
2388cb93a386Sopenharmony_ci        case 6:
2389cb93a386Sopenharmony_ci            drawQuad(c[0], c[1], c[2], c[3], c[4], c[5]);
2390cb93a386Sopenharmony_ci            break;
2391cb93a386Sopenharmony_ci        case 7:
2392cb93a386Sopenharmony_ci            drawConicWithQuads(c[0], c[1], c[2], c[3], c[4], c[5], c[6]);
2393cb93a386Sopenharmony_ci            break;
2394cb93a386Sopenharmony_ci        case 8:
2395cb93a386Sopenharmony_ci            drawCubic(c[0], c[1], c[2], c[3], c[4], c[5], c[6], c[7]);
2396cb93a386Sopenharmony_ci            break;
2397cb93a386Sopenharmony_ci    }
2398cb93a386Sopenharmony_ci}
2399cb93a386Sopenharmony_ci
2400cb93a386Sopenharmony_cifunction boundsWidth(pts) {
2401cb93a386Sopenharmony_ci    var min = pts[0];
2402cb93a386Sopenharmony_ci    var max = pts[0];
2403cb93a386Sopenharmony_ci    var length = pts.length == 7 ? 6 : pts.length;
2404cb93a386Sopenharmony_ci    for (var idx = 2; idx < length; idx += 2) {
2405cb93a386Sopenharmony_ci        min = Math.min(min, pts[idx]);
2406cb93a386Sopenharmony_ci        max = Math.max(max, pts[idx]);
2407cb93a386Sopenharmony_ci    }
2408cb93a386Sopenharmony_ci    return max - min;
2409cb93a386Sopenharmony_ci}
2410cb93a386Sopenharmony_ci
2411cb93a386Sopenharmony_cifunction boundsHeight(pts) {
2412cb93a386Sopenharmony_ci    var min = pts[1];
2413cb93a386Sopenharmony_ci    var max = pts[1];
2414cb93a386Sopenharmony_ci    var length = pts.length == 7 ? 6 : pts.length;
2415cb93a386Sopenharmony_ci    for (var idx = 3; idx < length; idx += 2) {
2416cb93a386Sopenharmony_ci        min = Math.min(min, pts[idx]);
2417cb93a386Sopenharmony_ci        max = Math.max(max, pts[idx]);
2418cb93a386Sopenharmony_ci    }
2419cb93a386Sopenharmony_ci    return max - min;
2420cb93a386Sopenharmony_ci}
2421cb93a386Sopenharmony_ci
2422cb93a386Sopenharmony_cifunction tangent(pts) {
2423cb93a386Sopenharmony_ci    var dx = pts[2] - pts[0];
2424cb93a386Sopenharmony_ci    var dy = pts[3] - pts[1];
2425cb93a386Sopenharmony_ci    if (dx == 0 && dy == 0 && pts.length > 4) {
2426cb93a386Sopenharmony_ci        dx = pts[4] - pts[0];
2427cb93a386Sopenharmony_ci        dy = pts[5] - pts[1];
2428cb93a386Sopenharmony_ci        if (dx == 0 && dy == 0 && pts.length == 8) {
2429cb93a386Sopenharmony_ci            dx = pts[6] - pts[0];
2430cb93a386Sopenharmony_ci            dy = pts[7] - pts[1];
2431cb93a386Sopenharmony_ci        }
2432cb93a386Sopenharmony_ci    }
2433cb93a386Sopenharmony_ci    return Math.atan2(-dy, dx);
2434cb93a386Sopenharmony_ci}
2435cb93a386Sopenharmony_ci
2436cb93a386Sopenharmony_cifunction hodograph(cubic) {
2437cb93a386Sopenharmony_ci    var hodo = [];
2438cb93a386Sopenharmony_ci    hodo[0] = 3 * (cubic[2] - cubic[0]);
2439cb93a386Sopenharmony_ci    hodo[1] = 3 * (cubic[3] - cubic[1]);
2440cb93a386Sopenharmony_ci    hodo[2] = 3 * (cubic[4] - cubic[2]);
2441cb93a386Sopenharmony_ci    hodo[3] = 3 * (cubic[5] - cubic[3]);
2442cb93a386Sopenharmony_ci    hodo[4] = 3 * (cubic[6] - cubic[4]);
2443cb93a386Sopenharmony_ci    hodo[5] = 3 * (cubic[7] - cubic[5]);
2444cb93a386Sopenharmony_ci    return hodo;
2445cb93a386Sopenharmony_ci}
2446cb93a386Sopenharmony_ci
2447cb93a386Sopenharmony_cifunction hodograph2(cubic) {
2448cb93a386Sopenharmony_ci    var quad = hodograph(cubic);
2449cb93a386Sopenharmony_ci    var hodo = [];
2450cb93a386Sopenharmony_ci    hodo[0] = 2 * (quad[2] - quad[0]);
2451cb93a386Sopenharmony_ci    hodo[1] = 2 * (quad[3] - quad[1]);
2452cb93a386Sopenharmony_ci    hodo[2] = 2 * (quad[4] - quad[2]);
2453cb93a386Sopenharmony_ci    hodo[3] = 2 * (quad[5] - quad[3]);
2454cb93a386Sopenharmony_ci    return hodo;
2455cb93a386Sopenharmony_ci}
2456cb93a386Sopenharmony_ci
2457cb93a386Sopenharmony_cifunction quadraticRootsReal(A, B, C, s) {
2458cb93a386Sopenharmony_ci    if (A == 0) {
2459cb93a386Sopenharmony_ci        if (B == 0) {
2460cb93a386Sopenharmony_ci            s[0] = 0;
2461cb93a386Sopenharmony_ci            return C == 0;
2462cb93a386Sopenharmony_ci        }
2463cb93a386Sopenharmony_ci        s[0] = -C / B;
2464cb93a386Sopenharmony_ci        return 1;
2465cb93a386Sopenharmony_ci    }
2466cb93a386Sopenharmony_ci    /* normal form: x^2 + px + q = 0 */
2467cb93a386Sopenharmony_ci    var p = B / (2 * A);
2468cb93a386Sopenharmony_ci    var q = C / A;
2469cb93a386Sopenharmony_ci    var p2 = p * p;
2470cb93a386Sopenharmony_ci    if (p2 < q) {
2471cb93a386Sopenharmony_ci        return 0;
2472cb93a386Sopenharmony_ci    }
2473cb93a386Sopenharmony_ci    var sqrt_D = 0;
2474cb93a386Sopenharmony_ci    if (p2 > q) {
2475cb93a386Sopenharmony_ci        sqrt_D = sqrt(p2 - q);
2476cb93a386Sopenharmony_ci    }
2477cb93a386Sopenharmony_ci    s[0] = sqrt_D - p;
2478cb93a386Sopenharmony_ci    s[1] = -sqrt_D - p;
2479cb93a386Sopenharmony_ci    return 1 + s[0] != s[1];
2480cb93a386Sopenharmony_ci}
2481cb93a386Sopenharmony_ci
2482cb93a386Sopenharmony_cifunction add_valid_ts(s, realRoots, t) {
2483cb93a386Sopenharmony_ci    var foundRoots = 0;
2484cb93a386Sopenharmony_ci    for (var index = 0; index < realRoots; ++index) {
2485cb93a386Sopenharmony_ci        var tValue = s[index];
2486cb93a386Sopenharmony_ci        if (tValue >= 0 && tValue <= 1) {
2487cb93a386Sopenharmony_ci            for (var idx2 = 0; idx2 < foundRoots; ++idx2) {
2488cb93a386Sopenharmony_ci                if (t[idx2] != tValue) {
2489cb93a386Sopenharmony_ci                    t[foundRoots++] = tValue;
2490cb93a386Sopenharmony_ci                }
2491cb93a386Sopenharmony_ci            }
2492cb93a386Sopenharmony_ci        }
2493cb93a386Sopenharmony_ci    }
2494cb93a386Sopenharmony_ci    return foundRoots;
2495cb93a386Sopenharmony_ci}
2496cb93a386Sopenharmony_ci
2497cb93a386Sopenharmony_cifunction quadraticRootsValidT(a, b, c, t) {
2498cb93a386Sopenharmony_ci    var s = [];
2499cb93a386Sopenharmony_ci    var realRoots = quadraticRootsReal(A, B, C, s);
2500cb93a386Sopenharmony_ci    var foundRoots = add_valid_ts(s, realRoots, t);
2501cb93a386Sopenharmony_ci    return foundRoots != 0;
2502cb93a386Sopenharmony_ci}
2503cb93a386Sopenharmony_ci
2504cb93a386Sopenharmony_cifunction find_cubic_inflections(cubic, tValues) {
2505cb93a386Sopenharmony_ci    var Ax = src[2] - src[0];
2506cb93a386Sopenharmony_ci    var Ay = src[3] - src[1];
2507cb93a386Sopenharmony_ci    var Bx = src[4] - 2 * src[2] + src[0];
2508cb93a386Sopenharmony_ci    var By = src[5] - 2 * src[3] + src[1];
2509cb93a386Sopenharmony_ci    var Cx = src[6] + 3 * (src[2] - src[4]) - src[0];
2510cb93a386Sopenharmony_ci    var Cy = src[7] + 3 * (src[3] - src[5]) - src[1];
2511cb93a386Sopenharmony_ci    return quadraticRootsValidT(Bx * Cy - By * Cx, (Ax * Cy - Ay * Cx),
2512cb93a386Sopenharmony_ci            Ax * By - Ay * Bx, tValues);
2513cb93a386Sopenharmony_ci}
2514cb93a386Sopenharmony_ci
2515cb93a386Sopenharmony_cifunction dxy_at_t(curve, type, t) {
2516cb93a386Sopenharmony_ci    var dxy = {};
2517cb93a386Sopenharmony_ci    if (type == PATH_LINE) {
2518cb93a386Sopenharmony_ci        dxy.x = curve[2] - curve[0];
2519cb93a386Sopenharmony_ci        dxy.y = curve[3] - curve[1];
2520cb93a386Sopenharmony_ci    } else if (type == PATH_QUAD) {
2521cb93a386Sopenharmony_ci        var a = t - 1;
2522cb93a386Sopenharmony_ci        var b = 1 - 2 * t;
2523cb93a386Sopenharmony_ci        var c = t;
2524cb93a386Sopenharmony_ci        dxy.x = a * curve[0] + b * curve[2] + c * curve[4];
2525cb93a386Sopenharmony_ci        dxy.y = a * curve[1] + b * curve[3] + c * curve[5];
2526cb93a386Sopenharmony_ci    } else if (type == PATH_CONIC) {
2527cb93a386Sopenharmony_ci        var p20x = curve[4] - curve[0];
2528cb93a386Sopenharmony_ci        var p20y = curve[5] - curve[1];
2529cb93a386Sopenharmony_ci        var p10xw = (curve[2] - curve[0]) * curve[6];
2530cb93a386Sopenharmony_ci        var p10yw = (curve[3] - curve[1]) * curve[6];
2531cb93a386Sopenharmony_ci        var coeff0x = curve[6] * p20x - p20x;
2532cb93a386Sopenharmony_ci        var coeff0y = curve[6] * p20y - p20y;
2533cb93a386Sopenharmony_ci        var coeff1x = p20x - 2 * p10xw;
2534cb93a386Sopenharmony_ci        var coeff1y = p20y - 2 * p10yw;
2535cb93a386Sopenharmony_ci        dxy.x = t * (t * coeff0x + coeff1x) + p10xw;
2536cb93a386Sopenharmony_ci        dxy.y = t * (t * coeff0y + coeff1y) + p10yw;
2537cb93a386Sopenharmony_ci    } else if (type == PATH_CUBIC) {
2538cb93a386Sopenharmony_ci        var one_t = 1 - t;
2539cb93a386Sopenharmony_ci        var a = curve[0];
2540cb93a386Sopenharmony_ci        var b = curve[2];
2541cb93a386Sopenharmony_ci        var c = curve[4];
2542cb93a386Sopenharmony_ci        var d = curve[6];
2543cb93a386Sopenharmony_ci        dxy.x = 3 * ((b - a) * one_t * one_t + 2 * (c - b) * t * one_t + (d - c) * t * t);
2544cb93a386Sopenharmony_ci        a = curve[1];
2545cb93a386Sopenharmony_ci        b = curve[3];
2546cb93a386Sopenharmony_ci        c = curve[5];
2547cb93a386Sopenharmony_ci        d = curve[7];
2548cb93a386Sopenharmony_ci        dxy.y = 3 * ((b - a) * one_t * one_t + 2 * (c - b) * t * one_t + (d - c) * t * t);
2549cb93a386Sopenharmony_ci    }
2550cb93a386Sopenharmony_ci    return dxy;
2551cb93a386Sopenharmony_ci}
2552cb93a386Sopenharmony_ci
2553cb93a386Sopenharmony_cifunction dpt_at_t(curve, t) {
2554cb93a386Sopenharmony_ci    var type = PATH_LINE + (curve.length / 2 - 2);
2555cb93a386Sopenharmony_ci    return dxy_at_t(curve, type, t);
2556cb93a386Sopenharmony_ci}
2557cb93a386Sopenharmony_ci
2558cb93a386Sopenharmony_cifunction drawLabel(num, px, py) {
2559cb93a386Sopenharmony_ci    ctx.beginPath();
2560cb93a386Sopenharmony_ci    ctx.arc(px, py, 8, 0, Math.PI*2, true);
2561cb93a386Sopenharmony_ci    ctx.closePath();
2562cb93a386Sopenharmony_ci    ctx.strokeStyle = "rgba(0,0,0, 0.4)";
2563cb93a386Sopenharmony_ci    ctx.lineWidth = num == 0 || num == 3 ? 2 : 1;
2564cb93a386Sopenharmony_ci    ctx.stroke();
2565cb93a386Sopenharmony_ci    ctx.fillStyle = "black";
2566cb93a386Sopenharmony_ci    ctx.font = "normal 10px Arial";
2567cb93a386Sopenharmony_ci  //  ctx.rotate(0.001);
2568cb93a386Sopenharmony_ci    ctx.fillText(num, px - 2, py + 3);
2569cb93a386Sopenharmony_ci  //  ctx.rotate(-0.001);
2570cb93a386Sopenharmony_ci}
2571cb93a386Sopenharmony_ci
2572cb93a386Sopenharmony_cifunction drawLabelX(ymin, num, loc) {
2573cb93a386Sopenharmony_ci    var px = (loc - srcLeft) * scale;
2574cb93a386Sopenharmony_ci    var py = (ymin - srcTop) * scale - 20;
2575cb93a386Sopenharmony_ci    drawLabel(num, px, py);
2576cb93a386Sopenharmony_ci}
2577cb93a386Sopenharmony_ci
2578cb93a386Sopenharmony_cifunction drawLabelY(xmin, num, loc) {
2579cb93a386Sopenharmony_ci    var px = (xmin - srcLeft) * scale - 20;
2580cb93a386Sopenharmony_ci    var py = (loc - srcTop) * scale;
2581cb93a386Sopenharmony_ci    drawLabel(num, px, py);
2582cb93a386Sopenharmony_ci}
2583cb93a386Sopenharmony_ci
2584cb93a386Sopenharmony_cifunction drawHodoOrigin(hx, hy, hMinX, hMinY, hMaxX, hMaxY) {
2585cb93a386Sopenharmony_ci    ctx.beginPath();
2586cb93a386Sopenharmony_ci    ctx.moveTo(hx, hy - 100);
2587cb93a386Sopenharmony_ci    ctx.lineTo(hx, hy);
2588cb93a386Sopenharmony_ci    ctx.strokeStyle = hMinY < 0 ? "green" : "blue";
2589cb93a386Sopenharmony_ci    ctx.stroke();
2590cb93a386Sopenharmony_ci    ctx.beginPath();
2591cb93a386Sopenharmony_ci    ctx.moveTo(hx, hy);
2592cb93a386Sopenharmony_ci    ctx.lineTo(hx, hy + 100);
2593cb93a386Sopenharmony_ci    ctx.strokeStyle = hMaxY > 0 ? "green" : "blue";
2594cb93a386Sopenharmony_ci    ctx.stroke();
2595cb93a386Sopenharmony_ci    ctx.beginPath();
2596cb93a386Sopenharmony_ci    ctx.moveTo(hx - 100, hy);
2597cb93a386Sopenharmony_ci    ctx.lineTo(hx, hy);
2598cb93a386Sopenharmony_ci    ctx.strokeStyle = hMinX < 0 ? "green" : "blue";
2599cb93a386Sopenharmony_ci    ctx.stroke();
2600cb93a386Sopenharmony_ci    ctx.beginPath();
2601cb93a386Sopenharmony_ci    ctx.moveTo(hx, hy);
2602cb93a386Sopenharmony_ci    ctx.lineTo(hx + 100, hy);
2603cb93a386Sopenharmony_ci    ctx.strokeStyle = hMaxX > 0 ? "green" : "blue";
2604cb93a386Sopenharmony_ci    ctx.stroke();
2605cb93a386Sopenharmony_ci}
2606cb93a386Sopenharmony_ci
2607cb93a386Sopenharmony_cifunction scalexy(x, y, mag) {
2608cb93a386Sopenharmony_ci    var length = Math.sqrt(x * x + y * y);
2609cb93a386Sopenharmony_ci    return mag / length;
2610cb93a386Sopenharmony_ci}
2611cb93a386Sopenharmony_ci
2612cb93a386Sopenharmony_cifunction drawArrow(x, y, dx, dy, s) {
2613cb93a386Sopenharmony_ci    var dscale = scalexy(dx, dy, 1 / scale * 100 * s);
2614cb93a386Sopenharmony_ci    dx *= dscale;
2615cb93a386Sopenharmony_ci    dy *= dscale;
2616cb93a386Sopenharmony_ci    ctx.beginPath();
2617cb93a386Sopenharmony_ci    ctx.moveTo((x - srcLeft) * scale, (y - srcTop) * scale);
2618cb93a386Sopenharmony_ci    x += dx;
2619cb93a386Sopenharmony_ci    y += dy;
2620cb93a386Sopenharmony_ci    ctx.lineTo((x - srcLeft) * scale, (y - srcTop) * scale);
2621cb93a386Sopenharmony_ci    dx /= 10;
2622cb93a386Sopenharmony_ci    dy /= 10;
2623cb93a386Sopenharmony_ci    ctx.lineTo((x - dy - srcLeft) * scale, (y + dx - srcTop) * scale);
2624cb93a386Sopenharmony_ci    ctx.lineTo((x + dx * 2 - srcLeft) * scale, (y + dy * 2 - srcTop) * scale);
2625cb93a386Sopenharmony_ci    ctx.lineTo((x + dy - srcLeft) * scale, (y - dx - srcTop) * scale);
2626cb93a386Sopenharmony_ci    ctx.lineTo((x - srcLeft) * scale, (y - srcTop) * scale);
2627cb93a386Sopenharmony_ci    ctx.strokeStyle = "rgba(0,75,0, 0.4)";
2628cb93a386Sopenharmony_ci    ctx.stroke();
2629cb93a386Sopenharmony_ci}
2630cb93a386Sopenharmony_ci
2631cb93a386Sopenharmony_cifunction x_at_t(curve, t) {
2632cb93a386Sopenharmony_ci    var one_t = 1 - t;
2633cb93a386Sopenharmony_ci    if (curve.length == 4) {
2634cb93a386Sopenharmony_ci        return one_t * curve[0] + t * curve[2];
2635cb93a386Sopenharmony_ci    }
2636cb93a386Sopenharmony_ci    var one_t2 = one_t * one_t;
2637cb93a386Sopenharmony_ci    var t2 = t * t;
2638cb93a386Sopenharmony_ci    if (curve.length == 6) {
2639cb93a386Sopenharmony_ci        return one_t2 * curve[0] + 2 * one_t * t * curve[2] + t2 * curve[4];
2640cb93a386Sopenharmony_ci    }
2641cb93a386Sopenharmony_ci    if (curve.length == 7) {
2642cb93a386Sopenharmony_ci        return (one_t2 * curve[0] + 2 * one_t * t * curve[2] * curve[6] + t2 * curve[4])
2643cb93a386Sopenharmony_ci                / (one_t2 +2 * one_t * t * curve[6] + t2);
2644cb93a386Sopenharmony_ci    }
2645cb93a386Sopenharmony_ci    var a = one_t2 * one_t;
2646cb93a386Sopenharmony_ci    var b = 3 * one_t2 * t;
2647cb93a386Sopenharmony_ci    var c = 3 * one_t * t2;
2648cb93a386Sopenharmony_ci    var d = t2 * t;
2649cb93a386Sopenharmony_ci    return a * curve[0] + b * curve[2] + c * curve[4] + d * curve[6];
2650cb93a386Sopenharmony_ci}
2651cb93a386Sopenharmony_ci
2652cb93a386Sopenharmony_cifunction y_at_t(curve, t) {
2653cb93a386Sopenharmony_ci    var one_t = 1 - t;
2654cb93a386Sopenharmony_ci    if (curve.length == 4) {
2655cb93a386Sopenharmony_ci        return one_t * curve[1] + t * curve[3];
2656cb93a386Sopenharmony_ci    }
2657cb93a386Sopenharmony_ci    var one_t2 = one_t * one_t;
2658cb93a386Sopenharmony_ci    var t2 = t * t;
2659cb93a386Sopenharmony_ci    if (curve.length == 6) {
2660cb93a386Sopenharmony_ci        return one_t2 * curve[1] + 2 * one_t * t * curve[3] + t2 * curve[5];
2661cb93a386Sopenharmony_ci    }
2662cb93a386Sopenharmony_ci    if (curve.length == 7) {
2663cb93a386Sopenharmony_ci        return (one_t2 * curve[1] + 2 * one_t * t * curve[3] * curve[6] + t2 * curve[5])
2664cb93a386Sopenharmony_ci                / (one_t2 +2 * one_t * t * curve[6] + t2);
2665cb93a386Sopenharmony_ci    }
2666cb93a386Sopenharmony_ci    var a = one_t2 * one_t;
2667cb93a386Sopenharmony_ci    var b = 3 * one_t2 * t;
2668cb93a386Sopenharmony_ci    var c = 3 * one_t * t2;
2669cb93a386Sopenharmony_ci    var d = t2 * t;
2670cb93a386Sopenharmony_ci    return a * curve[1] + b * curve[3] + c * curve[5] + d * curve[7];
2671cb93a386Sopenharmony_ci}
2672cb93a386Sopenharmony_ci
2673cb93a386Sopenharmony_cifunction pt_at_t(curve, t) {
2674cb93a386Sopenharmony_ci    var pt = {};
2675cb93a386Sopenharmony_ci    pt.x = x_at_t(curve, t);
2676cb93a386Sopenharmony_ci    pt.y = y_at_t(curve, t);
2677cb93a386Sopenharmony_ci    return pt;
2678cb93a386Sopenharmony_ci}
2679cb93a386Sopenharmony_ci
2680cb93a386Sopenharmony_cifunction drawOrder(curve, t, label) {
2681cb93a386Sopenharmony_ci    var px = x_at_t(curve, t);
2682cb93a386Sopenharmony_ci    var py = y_at_t(curve, t);
2683cb93a386Sopenharmony_ci    var _px = (px - srcLeft) * scale;
2684cb93a386Sopenharmony_ci    var _py = (py - srcTop) * scale;
2685cb93a386Sopenharmony_ci    ctx.beginPath();
2686cb93a386Sopenharmony_ci    ctx.arc(_px, _py, 15, 0, Math.PI * 2, true);
2687cb93a386Sopenharmony_ci    ctx.closePath();
2688cb93a386Sopenharmony_ci    ctx.fillStyle = "white";
2689cb93a386Sopenharmony_ci    ctx.fill();
2690cb93a386Sopenharmony_ci    if (label == 'L') {
2691cb93a386Sopenharmony_ci        ctx.strokeStyle = "rgba(255,0,0, 1)";
2692cb93a386Sopenharmony_ci        ctx.fillStyle = "rgba(255,0,0, 1)";
2693cb93a386Sopenharmony_ci    } else {
2694cb93a386Sopenharmony_ci        ctx.strokeStyle = "rgba(0,0,255, 1)";
2695cb93a386Sopenharmony_ci        ctx.fillStyle = "rgba(0,0,255, 1)";
2696cb93a386Sopenharmony_ci    }
2697cb93a386Sopenharmony_ci    ctx.stroke();
2698cb93a386Sopenharmony_ci    ctx.font = "normal 16px Arial";
2699cb93a386Sopenharmony_ci    ctx.textAlign = "center";
2700cb93a386Sopenharmony_ci    ctx.fillText(label, _px, _py + 5);
2701cb93a386Sopenharmony_ci    ctx.font = "normal 10px Arial";
2702cb93a386Sopenharmony_ci}
2703cb93a386Sopenharmony_ci
2704cb93a386Sopenharmony_cifunction drawVisibleOrder(curve, label) {
2705cb93a386Sopenharmony_ci    var s = pt_at_t(curve, 0);
2706cb93a386Sopenharmony_ci    var e = pt_at_t(curve, 1);
2707cb93a386Sopenharmony_ci    var sOn = ptOnScreen(s);
2708cb93a386Sopenharmony_ci    var eOn = ptOnScreen(e);
2709cb93a386Sopenharmony_ci    var defaultT = 0.85;
2710cb93a386Sopenharmony_ci    if (sOn && eOn)
2711cb93a386Sopenharmony_ci        return drawOrder(curve, defaultT, label);
2712cb93a386Sopenharmony_ci    if (sOn || eOn) {
2713cb93a386Sopenharmony_ci        if (eOn) {
2714cb93a386Sopenharmony_ci            defaultT = 1 - defaultT;
2715cb93a386Sopenharmony_ci        }
2716cb93a386Sopenharmony_ci        var step = sOn ? -defaultT / 2 : (1 - defaultT) / 2;
2717cb93a386Sopenharmony_ci        var t = defaultT;
2718cb93a386Sopenharmony_ci        var tries = 16;
2719cb93a386Sopenharmony_ci        do {
2720cb93a386Sopenharmony_ci            var mid = pt_at_t(curve, t);
2721cb93a386Sopenharmony_ci            if (ptOnScreen(mid))
2722cb93a386Sopenharmony_ci                return drawOrder(curve, t, label);
2723cb93a386Sopenharmony_ci            t += step;
2724cb93a386Sopenharmony_ci            step /= 2;
2725cb93a386Sopenharmony_ci        } while (--tries > 0);
2726cb93a386Sopenharmony_ci        drawOrder(curve, defaultT, label);
2727cb93a386Sopenharmony_ci    }
2728cb93a386Sopenharmony_ci    // scattershot until we find a visible point
2729cb93a386Sopenharmony_ci    var denom = 2;  // visit odd number num / denom to hit unique pts
2730cb93a386Sopenharmony_ci    var tries = 6; // tries 1/2, 1/4, 3/4, 1/8, 3/8, 5/8, 7/8, 1/16 ...
2731cb93a386Sopenharmony_ci    do {
2732cb93a386Sopenharmony_ci        for (var numer = 1; numer < denom; numer += 2) {
2733cb93a386Sopenharmony_ci            var t = numer / denom + 0.1;
2734cb93a386Sopenharmony_ci            if (t >= 1) {
2735cb93a386Sopenharmony_ci                break;
2736cb93a386Sopenharmony_ci            }
2737cb93a386Sopenharmony_ci            var mid = pt_at_t(curve, t);
2738cb93a386Sopenharmony_ci            if (ptOnScreen(mid))
2739cb93a386Sopenharmony_ci                return drawOrder(curve, t, label);
2740cb93a386Sopenharmony_ci        }
2741cb93a386Sopenharmony_ci        denom *= 2;
2742cb93a386Sopenharmony_ci    } while (--tries > 0);
2743cb93a386Sopenharmony_ci    drawOrder(curve, defaultT, label);
2744cb93a386Sopenharmony_ci}
2745cb93a386Sopenharmony_ci
2746cb93a386Sopenharmony_cifunction set_length(pt, newLen) {
2747cb93a386Sopenharmony_ci    var len = Math.sqrt(pt.x * pt.x + pt.y * pt.y);
2748cb93a386Sopenharmony_ci    var scale = newLen / len;
2749cb93a386Sopenharmony_ci    var newPt = { x: pt.x * scale, y: pt.y * scale };
2750cb93a386Sopenharmony_ci    return newPt;
2751cb93a386Sopenharmony_ci}
2752cb93a386Sopenharmony_ci
2753cb93a386Sopenharmony_cifunction drawDirection(curve, t) {
2754cb93a386Sopenharmony_ci    var d = dpt_at_t(curve, t);
2755cb93a386Sopenharmony_ci    d = set_length(d, 16);
2756cb93a386Sopenharmony_ci    var pt = localToGlobal(pt_at_t(curve, t));
2757cb93a386Sopenharmony_ci    ctx.beginPath();
2758cb93a386Sopenharmony_ci    ctx.moveTo(pt.x - d.y, pt.y + d.x);
2759cb93a386Sopenharmony_ci    ctx.lineTo(pt.x + d.x, pt.y + d.y);
2760cb93a386Sopenharmony_ci    ctx.lineTo(pt.x + d.y, pt.y - d.x);
2761cb93a386Sopenharmony_ci    ctx.strokeStyle = "rgba(0,75,0, 0.4)";
2762cb93a386Sopenharmony_ci    ctx.stroke();
2763cb93a386Sopenharmony_ci}
2764cb93a386Sopenharmony_ci
2765cb93a386Sopenharmony_cifunction drawVisibleDirection(curve) {
2766cb93a386Sopenharmony_ci    var s = pt_at_t(curve, 0);
2767cb93a386Sopenharmony_ci    var e = pt_at_t(curve, 1);
2768cb93a386Sopenharmony_ci    var sOn = ptOnScreen(s);
2769cb93a386Sopenharmony_ci    var eOn = ptOnScreen(e);
2770cb93a386Sopenharmony_ci    var defaultT = 0.65;
2771cb93a386Sopenharmony_ci    if (sOn && eOn) {
2772cb93a386Sopenharmony_ci        return drawDirection(curve, defaultT);
2773cb93a386Sopenharmony_ci    }
2774cb93a386Sopenharmony_ci    if (sOn || eOn) {
2775cb93a386Sopenharmony_ci        if (eOn) {
2776cb93a386Sopenharmony_ci            defaultT = 1 - defaultT;
2777cb93a386Sopenharmony_ci        }
2778cb93a386Sopenharmony_ci        var step = sOn ? -defaultT / 2 : (1 - defaultT) / 2;
2779cb93a386Sopenharmony_ci        var t = defaultT;
2780cb93a386Sopenharmony_ci        var tries = 16;
2781cb93a386Sopenharmony_ci        do {
2782cb93a386Sopenharmony_ci            var mid = pt_at_t(curve, t);
2783cb93a386Sopenharmony_ci            if (ptOnScreen(mid))
2784cb93a386Sopenharmony_ci                return drawDirection(curve, t);
2785cb93a386Sopenharmony_ci            t += step;
2786cb93a386Sopenharmony_ci            step /= 2;
2787cb93a386Sopenharmony_ci        } while (--tries > 0);
2788cb93a386Sopenharmony_ci        drawDirection(curve, defaultT);
2789cb93a386Sopenharmony_ci    }
2790cb93a386Sopenharmony_ci    // scattershot until we find a visible point
2791cb93a386Sopenharmony_ci    var denom = 2;  // visit odd number num / denom to hit unique pts
2792cb93a386Sopenharmony_ci    var tries = 6; // tries 1/2, 1/4, 3/4, 1/8, 3/8, 5/8, 7/8, 1/16 ...
2793cb93a386Sopenharmony_ci    do {
2794cb93a386Sopenharmony_ci        for (var numer = 1; numer < denom; numer += 2) {
2795cb93a386Sopenharmony_ci            var t = numer / denom + 0.1;
2796cb93a386Sopenharmony_ci            if (t >= 1) {
2797cb93a386Sopenharmony_ci                break;
2798cb93a386Sopenharmony_ci            }
2799cb93a386Sopenharmony_ci            var mid = pt_at_t(curve, t);
2800cb93a386Sopenharmony_ci            if (ptOnScreen(mid))
2801cb93a386Sopenharmony_ci                return drawDirection(curve, t);
2802cb93a386Sopenharmony_ci        }
2803cb93a386Sopenharmony_ci        denom *= 2;
2804cb93a386Sopenharmony_ci    } while (--tries > 0);
2805cb93a386Sopenharmony_ci    drawDirection(curve, defaultT);
2806cb93a386Sopenharmony_ci}
2807cb93a386Sopenharmony_ci
2808cb93a386Sopenharmony_cifunction drawID(curve, t, id) {
2809cb93a386Sopenharmony_ci    var px = x_at_t(curve, t);
2810cb93a386Sopenharmony_ci    var py = y_at_t(curve, t);
2811cb93a386Sopenharmony_ci    var _px = (px - srcLeft) * scale;
2812cb93a386Sopenharmony_ci    var _py = (py - srcTop) * scale;
2813cb93a386Sopenharmony_ci    draw_id_at(id, _px, _py);
2814cb93a386Sopenharmony_ci}
2815cb93a386Sopenharmony_ci
2816cb93a386Sopenharmony_cifunction localToGlobal(local) {
2817cb93a386Sopenharmony_ci    var global = {};
2818cb93a386Sopenharmony_ci    global.x = (local.x - srcLeft) * scale;
2819cb93a386Sopenharmony_ci    global.y = (local.y - srcTop) * scale;
2820cb93a386Sopenharmony_ci    return global;
2821cb93a386Sopenharmony_ci}
2822cb93a386Sopenharmony_ci
2823cb93a386Sopenharmony_cifunction ptOnScreen(local) {
2824cb93a386Sopenharmony_ci    var pt = localToGlobal(local);
2825cb93a386Sopenharmony_ci    return 10 <= pt.x && pt.x <= screenWidth - 10
2826cb93a386Sopenharmony_ci        && 10 <= pt.y && pt.y <= screenHeight - 10;
2827cb93a386Sopenharmony_ci}
2828cb93a386Sopenharmony_ci
2829cb93a386Sopenharmony_cifunction drawVisibleID(curve, defaultT, id) {
2830cb93a386Sopenharmony_ci    // determine if either or both ends are visible
2831cb93a386Sopenharmony_ci    var s = pt_at_t(curve, 0);
2832cb93a386Sopenharmony_ci    var e = pt_at_t(curve, 1);
2833cb93a386Sopenharmony_ci    var sOn = ptOnScreen(s);
2834cb93a386Sopenharmony_ci    var eOn = ptOnScreen(e);
2835cb93a386Sopenharmony_ci    if (sOn && eOn)
2836cb93a386Sopenharmony_ci        return drawID(curve, defaultT, id);
2837cb93a386Sopenharmony_ci    if (sOn || eOn) {
2838cb93a386Sopenharmony_ci        var step = sOn ? -defaultT / 2 : (1 - defaultT) / 2;
2839cb93a386Sopenharmony_ci        var t = defaultT;
2840cb93a386Sopenharmony_ci        var tries = 16;
2841cb93a386Sopenharmony_ci        do {
2842cb93a386Sopenharmony_ci            var mid = pt_at_t(curve, t);
2843cb93a386Sopenharmony_ci            if (ptOnScreen(mid))
2844cb93a386Sopenharmony_ci                return drawID(curve, t, id);
2845cb93a386Sopenharmony_ci            t += step;
2846cb93a386Sopenharmony_ci            step /= 2;
2847cb93a386Sopenharmony_ci        } while (--tries > 0);
2848cb93a386Sopenharmony_ci        drawID(curve, defaultT, id);
2849cb93a386Sopenharmony_ci    }
2850cb93a386Sopenharmony_ci    // scattershot until we find a visible point
2851cb93a386Sopenharmony_ci    var denom = 2;  // visit odd number num / denom to hit unique pts
2852cb93a386Sopenharmony_ci    var tries = 6; // tries 1/2, 1/4, 3/4, 1/8, 3/8, 5/8, 7/8, 1/16 ...
2853cb93a386Sopenharmony_ci    do {
2854cb93a386Sopenharmony_ci        for (var numer = 1; numer < denom; numer += 2) {
2855cb93a386Sopenharmony_ci            var t = numer / denom;
2856cb93a386Sopenharmony_ci            var mid = pt_at_t(curve, t);
2857cb93a386Sopenharmony_ci            if (ptOnScreen(mid))
2858cb93a386Sopenharmony_ci                return drawID(curve, t, id);
2859cb93a386Sopenharmony_ci        }
2860cb93a386Sopenharmony_ci        denom *= 2;
2861cb93a386Sopenharmony_ci    } while (--tries > 0);
2862cb93a386Sopenharmony_ci    drawID(curve, defaultT, id);
2863cb93a386Sopenharmony_ci}
2864cb93a386Sopenharmony_ci
2865cb93a386Sopenharmony_cifunction draw_id_at(id, _px, _py) {
2866cb93a386Sopenharmony_ci    ctx.beginPath();
2867cb93a386Sopenharmony_ci    ctx.arc(_px, _py, 15, 0, Math.PI * 2, true);
2868cb93a386Sopenharmony_ci    ctx.closePath();
2869cb93a386Sopenharmony_ci    ctx.fillStyle = "white";
2870cb93a386Sopenharmony_ci    ctx.fill();
2871cb93a386Sopenharmony_ci    ctx.strokeStyle = "rgba(127,127,0, 1)";
2872cb93a386Sopenharmony_ci    ctx.fillStyle = "rgba(127,127,0, 1)";
2873cb93a386Sopenharmony_ci    ctx.stroke();
2874cb93a386Sopenharmony_ci    ctx.font = "normal 16px Arial";
2875cb93a386Sopenharmony_ci    ctx.textAlign = "center";
2876cb93a386Sopenharmony_ci    ctx.fillText(id, _px, _py + 5);
2877cb93a386Sopenharmony_ci    ctx.font = "normal 10px Arial";
2878cb93a386Sopenharmony_ci}
2879cb93a386Sopenharmony_ci
2880cb93a386Sopenharmony_cifunction drawLinePartialID(id, x1, y1, x2, y2, t1, t2) {
2881cb93a386Sopenharmony_ci    var curve = [x1, y1, x2, y2];
2882cb93a386Sopenharmony_ci    drawCurvePartialID(id, curve, t1, t2);
2883cb93a386Sopenharmony_ci}
2884cb93a386Sopenharmony_ci
2885cb93a386Sopenharmony_cifunction drawLineID(id, x1, y1, x2, y2) {
2886cb93a386Sopenharmony_ci    drawLinePartialID(id, x1, y1, x2, y2, 0, 1);
2887cb93a386Sopenharmony_ci}
2888cb93a386Sopenharmony_ci
2889cb93a386Sopenharmony_cifunction drawQuadPartialID(id, x1, y1, x2, y2, x3, y3, t1, t2) {
2890cb93a386Sopenharmony_ci    var curve = [x1, y1, x2, y2, x3, y3];
2891cb93a386Sopenharmony_ci    drawCurvePartialID(id, curve, t1, t2);
2892cb93a386Sopenharmony_ci}
2893cb93a386Sopenharmony_ci
2894cb93a386Sopenharmony_cifunction drawQuadID(id, x1, y1, x2, y2, x3, y3) {
2895cb93a386Sopenharmony_ci    drawQuadPartialID(id, x1, y1, x2, y2, x3, y3, 0, 1);
2896cb93a386Sopenharmony_ci}
2897cb93a386Sopenharmony_ci
2898cb93a386Sopenharmony_cifunction drawConicPartialID(id, x1, y1, x2, y2, x3, y3, w, t1, t2) {
2899cb93a386Sopenharmony_ci    var curve = [x1, y1, x2, y2, x3, y3, w];
2900cb93a386Sopenharmony_ci    drawCurvePartialID(id, curve, t1, t2);
2901cb93a386Sopenharmony_ci}
2902cb93a386Sopenharmony_ci
2903cb93a386Sopenharmony_cifunction drawConicID(id, x1, y1, x2, y2, x3, y3, w) {
2904cb93a386Sopenharmony_ci    drawConicPartialID(id, x1, y1, x2, y2, x3, y3, w, 0, 1);
2905cb93a386Sopenharmony_ci}
2906cb93a386Sopenharmony_ci
2907cb93a386Sopenharmony_cifunction drawCubicPartialID(id, x1, y1, x2, y2, x3, y3, x4, y4, t1, t2) {
2908cb93a386Sopenharmony_ci    var curve = [x1, y1, x2, y2, x3, y3, x4, y4];
2909cb93a386Sopenharmony_ci    drawCurvePartialID(id, curve, t1, t2);
2910cb93a386Sopenharmony_ci}
2911cb93a386Sopenharmony_ci
2912cb93a386Sopenharmony_cifunction drawCubicID(id, x1, y1, x2, y2, x3, y3, x4, y4) {
2913cb93a386Sopenharmony_ci    drawCubicPartialID(id, x1, y1, x2, y2, x3, y3, x4, y4, 0, 1);
2914cb93a386Sopenharmony_ci}
2915cb93a386Sopenharmony_ci
2916cb93a386Sopenharmony_cifunction  drawCurvePartialID(id, curve, t1, t2) {
2917cb93a386Sopenharmony_ci    drawVisibleID(curve, (t1 + t2) / 2, id);
2918cb93a386Sopenharmony_ci}
2919cb93a386Sopenharmony_ci
2920cb93a386Sopenharmony_cifunction drawCurveSpecials(test, curve, type) {
2921cb93a386Sopenharmony_ci    if (pt_labels) {
2922cb93a386Sopenharmony_ci        drawPoints(curve, type, pt_labels == 2);
2923cb93a386Sopenharmony_ci    }
2924cb93a386Sopenharmony_ci    if (control_lines != 0) {
2925cb93a386Sopenharmony_ci        drawControlLines(curve, type, control_lines);
2926cb93a386Sopenharmony_ci    }
2927cb93a386Sopenharmony_ci    if (curve_t) {
2928cb93a386Sopenharmony_ci        drawPointAtT(curve, type);
2929cb93a386Sopenharmony_ci    }
2930cb93a386Sopenharmony_ci    if (draw_midpoint) {
2931cb93a386Sopenharmony_ci        var mid = pointAtT(curve, type, 0.5);
2932cb93a386Sopenharmony_ci        drawPoint(mid.x, mid.y, true);
2933cb93a386Sopenharmony_ci    }
2934cb93a386Sopenharmony_ci    if (draw_id) {
2935cb93a386Sopenharmony_ci        var id = idByCurve(test, curve, type);
2936cb93a386Sopenharmony_ci        if (id >= 0) {
2937cb93a386Sopenharmony_ci            drawVisibleID(curve, 0.5, id);
2938cb93a386Sopenharmony_ci        }
2939cb93a386Sopenharmony_ci    }
2940cb93a386Sopenharmony_ci    if (draw_direction) {
2941cb93a386Sopenharmony_ci        drawVisibleDirection(curve);
2942cb93a386Sopenharmony_ci    }
2943cb93a386Sopenharmony_ci    if (type == PATH_LINE) {
2944cb93a386Sopenharmony_ci        return;
2945cb93a386Sopenharmony_ci    }
2946cb93a386Sopenharmony_ci    if (draw_deriviatives > 0) {
2947cb93a386Sopenharmony_ci        var d = dxy_at_t(curve, type, 0);
2948cb93a386Sopenharmony_ci        drawArrow(curve[0], curve[1], d.x, d.y, 1);
2949cb93a386Sopenharmony_ci        if (draw_deriviatives == 2) {
2950cb93a386Sopenharmony_ci            d = dxy_at_t(curve, type, 1);
2951cb93a386Sopenharmony_ci            if (type == PATH_CUBIC) {
2952cb93a386Sopenharmony_ci                drawArrow(curve[6], curve[7], d.x, d.y, 1);
2953cb93a386Sopenharmony_ci            } else {
2954cb93a386Sopenharmony_ci                drawArrow(curve[4], curve[5], d.x, d.y, 1);
2955cb93a386Sopenharmony_ci            }
2956cb93a386Sopenharmony_ci        }
2957cb93a386Sopenharmony_ci        if (draw_midpoint) {
2958cb93a386Sopenharmony_ci            var mid = pointAtT(curve, type, 0.5);
2959cb93a386Sopenharmony_ci            d = dxy_at_t(curve, type, 0.5);
2960cb93a386Sopenharmony_ci            drawArrow(mid.x, mid.y, d.x, d.y, 1);
2961cb93a386Sopenharmony_ci        }
2962cb93a386Sopenharmony_ci    }
2963cb93a386Sopenharmony_ci    if (type != PATH_CUBIC) {
2964cb93a386Sopenharmony_ci        return;
2965cb93a386Sopenharmony_ci    }
2966cb93a386Sopenharmony_ci    if (draw_sequence) {
2967cb93a386Sopenharmony_ci        var ymin = Math.min(curve[1], curve[3], curve[5], curve[7]);
2968cb93a386Sopenharmony_ci        for (var i = 0; i < 8; i+= 2) {
2969cb93a386Sopenharmony_ci            drawLabelX(ymin, i >> 1, curve[i]);
2970cb93a386Sopenharmony_ci        }
2971cb93a386Sopenharmony_ci        var xmin = Math.min(curve[0], curve[2], curve[4], curve[6]);
2972cb93a386Sopenharmony_ci        for (var i = 1; i < 8; i+= 2) {
2973cb93a386Sopenharmony_ci            drawLabelY(xmin, i >> 1, curve[i]);
2974cb93a386Sopenharmony_ci        }
2975cb93a386Sopenharmony_ci    }
2976cb93a386Sopenharmony_ci}
2977cb93a386Sopenharmony_ci
2978cb93a386Sopenharmony_cifunction logCurves(test) {
2979cb93a386Sopenharmony_ci    for (curves in test) {
2980cb93a386Sopenharmony_ci        var curve = test[curves];
2981cb93a386Sopenharmony_ci        dumpCurve(curve);
2982cb93a386Sopenharmony_ci    }
2983cb93a386Sopenharmony_ci}
2984cb93a386Sopenharmony_ci
2985cb93a386Sopenharmony_cifunction curveToString(curve) {
2986cb93a386Sopenharmony_ci    var str = "{{";
2987cb93a386Sopenharmony_ci    var length = curve.length == 7 ? 6 : curve.length;
2988cb93a386Sopenharmony_ci    if (curve.length == 7) {
2989cb93a386Sopenharmony_ci        str += "{";
2990cb93a386Sopenharmony_ci    }
2991cb93a386Sopenharmony_ci    for (i = 0; i < length; i += 2) {
2992cb93a386Sopenharmony_ci        str += curve[i].toFixed(decimal_places) + "," + curve[i + 1].toFixed(decimal_places);
2993cb93a386Sopenharmony_ci        if (i < curve.length - 2) {
2994cb93a386Sopenharmony_ci            str += "}, {";
2995cb93a386Sopenharmony_ci        }
2996cb93a386Sopenharmony_ci    }
2997cb93a386Sopenharmony_ci    str += "}";
2998cb93a386Sopenharmony_ci    if (curve.length == 7) {
2999cb93a386Sopenharmony_ci        str += "}, " + curve[6].toFixed(decimal_places);
3000cb93a386Sopenharmony_ci    }
3001cb93a386Sopenharmony_ci    str += "}";
3002cb93a386Sopenharmony_ci    return str;
3003cb93a386Sopenharmony_ci}
3004cb93a386Sopenharmony_ci
3005cb93a386Sopenharmony_cifunction dumpCurve(curve) {
3006cb93a386Sopenharmony_ci    console.log(curveToString(curve));
3007cb93a386Sopenharmony_ci}
3008cb93a386Sopenharmony_ci
3009cb93a386Sopenharmony_cifunction draw(test, lines, title) {
3010cb93a386Sopenharmony_ci    ctx.fillStyle = "rgba(0,0,0, 0.1)";
3011cb93a386Sopenharmony_ci    ctx.font = "normal 50px Arial";
3012cb93a386Sopenharmony_ci    ctx.textAlign = "left";
3013cb93a386Sopenharmony_ci    ctx.fillText(title, 50, 50);
3014cb93a386Sopenharmony_ci    ctx.font = "normal 10px Arial";
3015cb93a386Sopenharmony_ci    ctx.lineWidth = "1.001"; "0.999";
3016cb93a386Sopenharmony_ci    var secondPath = test.length;
3017cb93a386Sopenharmony_ci    var closeCount = 0;
3018cb93a386Sopenharmony_ci    logStart = -1;
3019cb93a386Sopenharmony_ci    logRange = 0;
3020cb93a386Sopenharmony_ci    // find last active rec type at this step
3021cb93a386Sopenharmony_ci    var curType = test[0];
3022cb93a386Sopenharmony_ci    var curStep = 0;
3023cb93a386Sopenharmony_ci    var hasOp = false;
3024cb93a386Sopenharmony_ci    var lastActive = 0;
3025cb93a386Sopenharmony_ci    var lastAdd = 0;
3026cb93a386Sopenharmony_ci    var lastCoin = 0;
3027cb93a386Sopenharmony_ci    var lastSect = 0;
3028cb93a386Sopenharmony_ci    var lastSort = 0;
3029cb93a386Sopenharmony_ci    var lastMark = 0;
3030cb93a386Sopenharmony_ci    var lastTop = 0;
3031cb93a386Sopenharmony_ci    activeCount = 0;
3032cb93a386Sopenharmony_ci    addCount = 0;
3033cb93a386Sopenharmony_ci    angleCount = 0;
3034cb93a386Sopenharmony_ci    opCount = 0;
3035cb93a386Sopenharmony_ci    sectCount = 0;
3036cb93a386Sopenharmony_ci    sortCount = 0;
3037cb93a386Sopenharmony_ci    topCount = 0;
3038cb93a386Sopenharmony_ci    markCount = 0;
3039cb93a386Sopenharmony_ci    activeMax = 0;
3040cb93a386Sopenharmony_ci    addMax = 0;
3041cb93a386Sopenharmony_ci    angleMax = 0;
3042cb93a386Sopenharmony_ci    coinMax = 0;
3043cb93a386Sopenharmony_ci    opMax = 0;
3044cb93a386Sopenharmony_ci    sectMax = 0;
3045cb93a386Sopenharmony_ci    sectMax2 = 0;
3046cb93a386Sopenharmony_ci    sortMax = 0;
3047cb93a386Sopenharmony_ci    topMax = 0;
3048cb93a386Sopenharmony_ci    markMax = 0;
3049cb93a386Sopenharmony_ci    lastIndex = test.length - 3;
3050cb93a386Sopenharmony_ci    for (var tIndex = 0; tIndex < test.length; tIndex += 3) {
3051cb93a386Sopenharmony_ci        var recType = test[tIndex];
3052cb93a386Sopenharmony_ci        if (!typeof recType == 'number' || recType < REC_TYPE_UNKNOWN || recType > REC_TYPE_LAST) {
3053cb93a386Sopenharmony_ci            console.log("unknown rec type: " + recType);
3054cb93a386Sopenharmony_ci            throw "stop execution";
3055cb93a386Sopenharmony_ci        }
3056cb93a386Sopenharmony_ci   //     if (curType == recType && curType != REC_TYPE_ADD) {
3057cb93a386Sopenharmony_ci   //         continue;
3058cb93a386Sopenharmony_ci   //     }
3059cb93a386Sopenharmony_ci        var inStepRange = step_limit == 0 || curStep < step_limit;
3060cb93a386Sopenharmony_ci        curType = recType;
3061cb93a386Sopenharmony_ci        if (recType == REC_TYPE_OP) {
3062cb93a386Sopenharmony_ci            hasOp = true;
3063cb93a386Sopenharmony_ci            continue;
3064cb93a386Sopenharmony_ci        }
3065cb93a386Sopenharmony_ci        if (recType == REC_TYPE_UNKNOWN) {
3066cb93a386Sopenharmony_ci            // these types do not advance step
3067cb93a386Sopenharmony_ci            continue;
3068cb93a386Sopenharmony_ci        }
3069cb93a386Sopenharmony_ci        var bumpStep = false;
3070cb93a386Sopenharmony_ci        var records = test[tIndex + 2];
3071cb93a386Sopenharmony_ci        var fragType = records[0];
3072cb93a386Sopenharmony_ci        if (recType == REC_TYPE_ADD) {
3073cb93a386Sopenharmony_ci            if (records.length != 2) {
3074cb93a386Sopenharmony_ci                console.log("expect only two elements: " + records.length);
3075cb93a386Sopenharmony_ci                throw "stop execution";
3076cb93a386Sopenharmony_ci            }
3077cb93a386Sopenharmony_ci            if (fragType == ADD_MOVETO || fragType == ADD_CLOSE) {
3078cb93a386Sopenharmony_ci                continue;
3079cb93a386Sopenharmony_ci            }
3080cb93a386Sopenharmony_ci            ++addMax;
3081cb93a386Sopenharmony_ci            if (!draw_add || !inStepRange) {
3082cb93a386Sopenharmony_ci                continue;
3083cb93a386Sopenharmony_ci            }
3084cb93a386Sopenharmony_ci            lastAdd = tIndex;
3085cb93a386Sopenharmony_ci            ++addCount;
3086cb93a386Sopenharmony_ci            bumpStep = true;
3087cb93a386Sopenharmony_ci        }
3088cb93a386Sopenharmony_ci        if (recType == REC_TYPE_PATH && hasOp) {
3089cb93a386Sopenharmony_ci            secondPath = tIndex;
3090cb93a386Sopenharmony_ci        }
3091cb93a386Sopenharmony_ci        if (recType == REC_TYPE_PATH2 && hasOp) {
3092cb93a386Sopenharmony_ci            secondPath = tIndex;
3093cb93a386Sopenharmony_ci        }
3094cb93a386Sopenharmony_ci        if (recType == REC_TYPE_ACTIVE) {
3095cb93a386Sopenharmony_ci            ++activeMax;
3096cb93a386Sopenharmony_ci            if (!draw_active || !inStepRange) {
3097cb93a386Sopenharmony_ci                continue;
3098cb93a386Sopenharmony_ci            }
3099cb93a386Sopenharmony_ci            lastActive = tIndex;
3100cb93a386Sopenharmony_ci            ++activeCount;
3101cb93a386Sopenharmony_ci            bumpStep = true;
3102cb93a386Sopenharmony_ci        }
3103cb93a386Sopenharmony_ci        if (recType == REC_TYPE_ACTIVE_OP) {
3104cb93a386Sopenharmony_ci            ++opMax;
3105cb93a386Sopenharmony_ci            if (!draw_op || !inStepRange) {
3106cb93a386Sopenharmony_ci                continue;
3107cb93a386Sopenharmony_ci            }
3108cb93a386Sopenharmony_ci            lastOp = tIndex;
3109cb93a386Sopenharmony_ci            ++opCount;
3110cb93a386Sopenharmony_ci            bumpStep = true;
3111cb93a386Sopenharmony_ci        }
3112cb93a386Sopenharmony_ci        if (recType == REC_TYPE_AFTERPART) {
3113cb93a386Sopenharmony_ci            if (draw_angle != 3 || !inStepRange) {
3114cb93a386Sopenharmony_ci                continue;
3115cb93a386Sopenharmony_ci            }
3116cb93a386Sopenharmony_ci            lastAngle = tIndex;
3117cb93a386Sopenharmony_ci            ++angleCount;
3118cb93a386Sopenharmony_ci            bumpStep = true;
3119cb93a386Sopenharmony_ci        }
3120cb93a386Sopenharmony_ci        if (recType == REC_TYPE_ANGLE) {
3121cb93a386Sopenharmony_ci            ++angleMax;
3122cb93a386Sopenharmony_ci            if (draw_angle == 0 || draw_angle == 3 || !inStepRange) {
3123cb93a386Sopenharmony_ci                continue;
3124cb93a386Sopenharmony_ci            }
3125cb93a386Sopenharmony_ci            lastAngle = tIndex;
3126cb93a386Sopenharmony_ci            ++angleCount;
3127cb93a386Sopenharmony_ci            bumpStep = true;
3128cb93a386Sopenharmony_ci        }
3129cb93a386Sopenharmony_ci        if (recType == REC_TYPE_COINCIDENCE) {
3130cb93a386Sopenharmony_ci            ++coinMax;
3131cb93a386Sopenharmony_ci            if (!draw_coincidence || !inStepRange) {
3132cb93a386Sopenharmony_ci                continue;
3133cb93a386Sopenharmony_ci            }
3134cb93a386Sopenharmony_ci            lastCoin = tIndex;
3135cb93a386Sopenharmony_ci            ++coinCount;
3136cb93a386Sopenharmony_ci            bumpStep = true;
3137cb93a386Sopenharmony_ci        }
3138cb93a386Sopenharmony_ci        if (recType == REC_TYPE_SECT) {
3139cb93a386Sopenharmony_ci            if (records.length != 2) {
3140cb93a386Sopenharmony_ci                console.log("expect only two elements: " + records.length);
3141cb93a386Sopenharmony_ci                throw "stop execution";
3142cb93a386Sopenharmony_ci            }
3143cb93a386Sopenharmony_ci            ++sectMax;
3144cb93a386Sopenharmony_ci            var sectBump = 1;
3145cb93a386Sopenharmony_ci            switch (fragType) {
3146cb93a386Sopenharmony_ci                case INTERSECT_LINE:
3147cb93a386Sopenharmony_ci                case INTERSECT_QUAD_LINE:
3148cb93a386Sopenharmony_ci                case INTERSECT_QUAD:
3149cb93a386Sopenharmony_ci                case INTERSECT_CONIC_LINE:
3150cb93a386Sopenharmony_ci                case INTERSECT_CONIC_QUAD:
3151cb93a386Sopenharmony_ci                case INTERSECT_CONIC:
3152cb93a386Sopenharmony_ci                case INTERSECT_SELF_CUBIC:
3153cb93a386Sopenharmony_ci                case INTERSECT_CUBIC_LINE:
3154cb93a386Sopenharmony_ci                case INTERSECT_CUBIC_QUAD:
3155cb93a386Sopenharmony_ci                case INTERSECT_CUBIC:
3156cb93a386Sopenharmony_ci                    sectBump = 1;
3157cb93a386Sopenharmony_ci                    break;
3158cb93a386Sopenharmony_ci                case INTERSECT_LINE_2:
3159cb93a386Sopenharmony_ci                case INTERSECT_QUAD_LINE_2:
3160cb93a386Sopenharmony_ci                case INTERSECT_QUAD_2:
3161cb93a386Sopenharmony_ci                case INTERSECT_CONIC_LINE_2:
3162cb93a386Sopenharmony_ci                case INTERSECT_CONIC_QUAD_2:
3163cb93a386Sopenharmony_ci                case INTERSECT_CONIC_2:
3164cb93a386Sopenharmony_ci                case INTERSECT_CUBIC_LINE_2:
3165cb93a386Sopenharmony_ci                case INTERSECT_CUBIC_QUAD_2:
3166cb93a386Sopenharmony_ci                case INTERSECT_CUBIC_2:
3167cb93a386Sopenharmony_ci                    sectBump = 2;
3168cb93a386Sopenharmony_ci                    break;
3169cb93a386Sopenharmony_ci                case INTERSECT_LINE_NO:
3170cb93a386Sopenharmony_ci                case INTERSECT_QUAD_LINE_NO:
3171cb93a386Sopenharmony_ci                case INTERSECT_QUAD_NO:
3172cb93a386Sopenharmony_ci                case INTERSECT_CONIC_LINE_NO:
3173cb93a386Sopenharmony_ci                case INTERSECT_CONIC_QUAD_NO:
3174cb93a386Sopenharmony_ci                case INTERSECT_CONIC_NO:
3175cb93a386Sopenharmony_ci                case INTERSECT_SELF_CUBIC_NO:
3176cb93a386Sopenharmony_ci                case INTERSECT_CUBIC_LINE_NO:
3177cb93a386Sopenharmony_ci                case INTERSECT_CUBIC_QUAD_NO:
3178cb93a386Sopenharmony_ci                case INTERSECT_CUBIC_NO:
3179cb93a386Sopenharmony_ci                    sectBump = 0;
3180cb93a386Sopenharmony_ci                    break;
3181cb93a386Sopenharmony_ci                case INTERSECT_CONIC_QUAD_3:
3182cb93a386Sopenharmony_ci                case INTERSECT_CUBIC_LINE_3:
3183cb93a386Sopenharmony_ci                case INTERSECT_CUBIC_QUAD_3:
3184cb93a386Sopenharmony_ci                case INTERSECT_CUBIC_3:
3185cb93a386Sopenharmony_ci                    sectBump = 3;
3186cb93a386Sopenharmony_ci                    break;
3187cb93a386Sopenharmony_ci                case INTERSECT_CONIC_QUAD_4:
3188cb93a386Sopenharmony_ci                case INTERSECT_CUBIC_QUAD_4:
3189cb93a386Sopenharmony_ci                case INTERSECT_CUBIC_4:
3190cb93a386Sopenharmony_ci                    sectBump = 4;
3191cb93a386Sopenharmony_ci                    break;
3192cb93a386Sopenharmony_ci                default:
3193cb93a386Sopenharmony_ci                    console.log("missing case " + records.length);
3194cb93a386Sopenharmony_ci                    throw "stop execution";
3195cb93a386Sopenharmony_ci            }
3196cb93a386Sopenharmony_ci            sectMax2 += sectBump;
3197cb93a386Sopenharmony_ci            if (draw_intersection <= 1 || !inStepRange) {
3198cb93a386Sopenharmony_ci                continue;
3199cb93a386Sopenharmony_ci            }
3200cb93a386Sopenharmony_ci            lastSect = tIndex;
3201cb93a386Sopenharmony_ci            sectCount += sectBump;
3202cb93a386Sopenharmony_ci            bumpStep = true;
3203cb93a386Sopenharmony_ci        }
3204cb93a386Sopenharmony_ci        if (recType == REC_TYPE_SORT) {
3205cb93a386Sopenharmony_ci            ++sortMax;
3206cb93a386Sopenharmony_ci            if (!draw_sort || !inStepRange) {
3207cb93a386Sopenharmony_ci                continue;
3208cb93a386Sopenharmony_ci            }
3209cb93a386Sopenharmony_ci            lastSort = tIndex;
3210cb93a386Sopenharmony_ci            ++sortCount;
3211cb93a386Sopenharmony_ci            bumpStep = true;
3212cb93a386Sopenharmony_ci        }
3213cb93a386Sopenharmony_ci        if (recType == REC_TYPE_TOP) {
3214cb93a386Sopenharmony_ci            ++topMax;
3215cb93a386Sopenharmony_ci            if (!draw_top || !inStepRange) {
3216cb93a386Sopenharmony_ci                continue;
3217cb93a386Sopenharmony_ci            }
3218cb93a386Sopenharmony_ci            lastTop = tIndex;
3219cb93a386Sopenharmony_ci            ++topCount;
3220cb93a386Sopenharmony_ci            bumpStep = true;
3221cb93a386Sopenharmony_ci        }
3222cb93a386Sopenharmony_ci        if (recType == REC_TYPE_MARK) {
3223cb93a386Sopenharmony_ci            ++markMax;
3224cb93a386Sopenharmony_ci            if (!draw_mark || !inStepRange) {
3225cb93a386Sopenharmony_ci                continue;
3226cb93a386Sopenharmony_ci            }
3227cb93a386Sopenharmony_ci            lastMark = tIndex;
3228cb93a386Sopenharmony_ci            ++markCount;
3229cb93a386Sopenharmony_ci            bumpStep = true;
3230cb93a386Sopenharmony_ci        }
3231cb93a386Sopenharmony_ci        if (bumpStep) {
3232cb93a386Sopenharmony_ci            lastIndex = tIndex;
3233cb93a386Sopenharmony_ci            logStart = test[tIndex + 1];
3234cb93a386Sopenharmony_ci            logRange = records.length / 2;
3235cb93a386Sopenharmony_ci            ++curStep;
3236cb93a386Sopenharmony_ci        }
3237cb93a386Sopenharmony_ci    }
3238cb93a386Sopenharmony_ci    stepMax = (draw_add ? addMax : 0)
3239cb93a386Sopenharmony_ci            + (draw_active ? activeMax : 0)
3240cb93a386Sopenharmony_ci            + (draw_angle ? angleMax : 0)
3241cb93a386Sopenharmony_ci            + (draw_coincidence ? coinMax : 0)
3242cb93a386Sopenharmony_ci            + (draw_op ? opMax : 0)
3243cb93a386Sopenharmony_ci            + (draw_sort ? sortMax : 0)
3244cb93a386Sopenharmony_ci            + (draw_top ? topMax : 0)
3245cb93a386Sopenharmony_ci            + (draw_mark ? markMax : 0)
3246cb93a386Sopenharmony_ci            + (draw_intersection == 2 ? sectMax : draw_intersection == 3 ? sectMax2 : 0);
3247cb93a386Sopenharmony_ci    if (stepMax == 0) {
3248cb93a386Sopenharmony_ci        stepMax = addMax + activeMax + angleMax + coinMax + opMax + sortMax + topMax + markMax;
3249cb93a386Sopenharmony_ci    }
3250cb93a386Sopenharmony_ci    drawnPts = [];
3251cb93a386Sopenharmony_ci    drawnLines = [];
3252cb93a386Sopenharmony_ci    drawnQuads = [];
3253cb93a386Sopenharmony_ci    drawnConics = [];
3254cb93a386Sopenharmony_ci    drawnCubics = [];
3255cb93a386Sopenharmony_ci    focusXmin = focusYmin = Infinity;
3256cb93a386Sopenharmony_ci    focusXmax = focusYmax = -Infinity;
3257cb93a386Sopenharmony_ci    var pathIndex = 0;
3258cb93a386Sopenharmony_ci    var opLetter = 'S';
3259cb93a386Sopenharmony_ci    for (var tIndex = lastIndex; tIndex >= 0; tIndex -= 3) {
3260cb93a386Sopenharmony_ci        var recType = test[tIndex];
3261cb93a386Sopenharmony_ci        var records = test[tIndex + 2];
3262cb93a386Sopenharmony_ci        for (var recordIndex = 0; recordIndex < records.length; recordIndex += 2) {
3263cb93a386Sopenharmony_ci            var fragType = records[recordIndex];
3264cb93a386Sopenharmony_ci            if (!typeof fragType == 'number' || fragType < 1 || fragType > FRAG_TYPE_LAST) {
3265cb93a386Sopenharmony_ci                console.log("unknown in range frag type: " + fragType);
3266cb93a386Sopenharmony_ci                throw "stop execution";
3267cb93a386Sopenharmony_ci            }
3268cb93a386Sopenharmony_ci            var frags = records[recordIndex + 1];
3269cb93a386Sopenharmony_ci            focus_enabled = false;
3270cb93a386Sopenharmony_ci            switch (recType) {
3271cb93a386Sopenharmony_ci                case REC_TYPE_COMPUTED:
3272cb93a386Sopenharmony_ci                    if (draw_computed == 0) {
3273cb93a386Sopenharmony_ci                        continue;
3274cb93a386Sopenharmony_ci                    }
3275cb93a386Sopenharmony_ci                    ctx.lineWidth = 1;
3276cb93a386Sopenharmony_ci                    ctx.strokeStyle = pathIndex == 0 ? "black" : "red";
3277cb93a386Sopenharmony_ci                    ctx.fillStyle = "blue";
3278cb93a386Sopenharmony_ci                    var drawThis = false;
3279cb93a386Sopenharmony_ci                    switch (fragType) {
3280cb93a386Sopenharmony_ci                        case PATH_QUAD:
3281cb93a386Sopenharmony_ci                            if ((draw_computed & 0x9) == 1 || ((draw_computed & 8) != 0
3282cb93a386Sopenharmony_ci                                    && (draw_computed & 7) == pathIndex)) {
3283cb93a386Sopenharmony_ci                                drawQuad(frags[0], frags[1], frags[2], frags[3],
3284cb93a386Sopenharmony_ci                                        frags[4], frags[5]);
3285cb93a386Sopenharmony_ci                                drawThis = true;
3286cb93a386Sopenharmony_ci                            }
3287cb93a386Sopenharmony_ci                            break;
3288cb93a386Sopenharmony_ci                        case PATH_CONIC:
3289cb93a386Sopenharmony_ci                            if ((draw_computed & 0xA) == 2 || ((draw_computed & 8) != 0
3290cb93a386Sopenharmony_ci                                    && (draw_computed & 7) == pathIndex)) {
3291cb93a386Sopenharmony_ci                                drawConicWithQuads(frags[0], frags[1], frags[2], frags[3],
3292cb93a386Sopenharmony_ci                                        frags[4], frags[5], frags[6]);
3293cb93a386Sopenharmony_ci                                drawThis = true;
3294cb93a386Sopenharmony_ci                            }
3295cb93a386Sopenharmony_ci                            break;
3296cb93a386Sopenharmony_ci                        case PATH_CUBIC:
3297cb93a386Sopenharmony_ci                            if ((draw_computed & 0xC) == 4 || ((draw_computed & 8) != 0
3298cb93a386Sopenharmony_ci                                     && (draw_computed & 7) == pathIndex)) {
3299cb93a386Sopenharmony_ci                                drawCubic(frags[0], frags[1], frags[2], frags[3],
3300cb93a386Sopenharmony_ci                                        frags[4], frags[5], frags[6], frags[7]);
3301cb93a386Sopenharmony_ci                                drawThis = true;
3302cb93a386Sopenharmony_ci                            }
3303cb93a386Sopenharmony_ci                            ++pathIndex;
3304cb93a386Sopenharmony_ci                            break;
3305cb93a386Sopenharmony_ci                        case COMPUTED_SET_1:
3306cb93a386Sopenharmony_ci                            pathIndex = 0;
3307cb93a386Sopenharmony_ci                            break;
3308cb93a386Sopenharmony_ci                        case COMPUTED_SET_2:
3309cb93a386Sopenharmony_ci                            pathIndex = 1;
3310cb93a386Sopenharmony_ci                            break;
3311cb93a386Sopenharmony_ci                        default:
3312cb93a386Sopenharmony_ci                            console.log("unknown REC_TYPE_COMPUTED frag type: " + fragType);
3313cb93a386Sopenharmony_ci                            throw "stop execution";
3314cb93a386Sopenharmony_ci                    }
3315cb93a386Sopenharmony_ci                    if (!drawThis || collect_bounds) {
3316cb93a386Sopenharmony_ci                        break;
3317cb93a386Sopenharmony_ci                    }
3318cb93a386Sopenharmony_ci                    drawCurveSpecials(test, frags, fragType);
3319cb93a386Sopenharmony_ci                    break;
3320cb93a386Sopenharmony_ci                case REC_TYPE_ALIGNED:
3321cb93a386Sopenharmony_ci                    if (draw_path < 4) {
3322cb93a386Sopenharmony_ci                        continue;
3323cb93a386Sopenharmony_ci                    }
3324cb93a386Sopenharmony_ci                case REC_TYPE_PATH:
3325cb93a386Sopenharmony_ci                case REC_TYPE_PATH2:
3326cb93a386Sopenharmony_ci                    if (REC_TYPE_ALIGNED != recType && draw_path >= 4) {
3327cb93a386Sopenharmony_ci                        continue;
3328cb93a386Sopenharmony_ci                    }
3329cb93a386Sopenharmony_ci                    if (!draw_path) {
3330cb93a386Sopenharmony_ci                        continue;
3331cb93a386Sopenharmony_ci                    }
3332cb93a386Sopenharmony_ci                    var firstPath = tIndex < secondPath;
3333cb93a386Sopenharmony_ci                    if ((draw_path & (firstPath ? 1 : 2)) == 0) {
3334cb93a386Sopenharmony_ci                        continue;
3335cb93a386Sopenharmony_ci                    }
3336cb93a386Sopenharmony_ci                    ctx.lineWidth = 1;
3337cb93a386Sopenharmony_ci                    ctx.strokeStyle = firstPath ? "black" : "red";
3338cb93a386Sopenharmony_ci                    ctx.fillStyle = "blue";
3339cb93a386Sopenharmony_ci                    var frags2 = [];
3340cb93a386Sopenharmony_ci                    switch (fragType) {
3341cb93a386Sopenharmony_ci                        case PATH_LINE:
3342cb93a386Sopenharmony_ci                            for (var i = 0; i < 4; ++ i) { frags2[i] = frags[i + 1]; }
3343cb93a386Sopenharmony_ci                            drawLine(frags2[0], frags2[1], frags2[2], frags2[3]);
3344cb93a386Sopenharmony_ci                            break;
3345cb93a386Sopenharmony_ci                        case PATH_QUAD:
3346cb93a386Sopenharmony_ci                            for (var i = 0; i < 6; ++ i) { frags2[i] = frags[i + 1]; }
3347cb93a386Sopenharmony_ci                            drawQuad(frags2[0], frags2[1], frags2[2], frags2[3],
3348cb93a386Sopenharmony_ci                                    frags2[4], frags2[5]);
3349cb93a386Sopenharmony_ci                            break;
3350cb93a386Sopenharmony_ci                        case PATH_CONIC:
3351cb93a386Sopenharmony_ci                            for (var i = 0; i < 7; ++ i) { frags2[i] = frags[i + 1]; }
3352cb93a386Sopenharmony_ci                            drawConicWithQuads(frags2[0], frags2[1], frags2[2], frags2[3],
3353cb93a386Sopenharmony_ci                                    frags2[4], frags2[5], frags2[6]);
3354cb93a386Sopenharmony_ci                            break;
3355cb93a386Sopenharmony_ci                        case PATH_CUBIC:
3356cb93a386Sopenharmony_ci                            for (var i = 0; i < 8; ++ i) { frags2[i] = frags[i + 1]; }
3357cb93a386Sopenharmony_ci                            drawCubic(frags2[0], frags2[1], frags2[2], frags2[3],
3358cb93a386Sopenharmony_ci                                    frags2[4], frags2[5], frags2[6], frags2[7]);
3359cb93a386Sopenharmony_ci                            break;
3360cb93a386Sopenharmony_ci                        default:
3361cb93a386Sopenharmony_ci                            console.log("unknown " + recType + " frag type: " + fragType);
3362cb93a386Sopenharmony_ci                            throw "stop execution";
3363cb93a386Sopenharmony_ci                    }
3364cb93a386Sopenharmony_ci                    if (collect_bounds) {
3365cb93a386Sopenharmony_ci                        break;
3366cb93a386Sopenharmony_ci                    }
3367cb93a386Sopenharmony_ci                    drawCurveSpecials(test, frags2, fragType);
3368cb93a386Sopenharmony_ci                    break;
3369cb93a386Sopenharmony_ci                case REC_TYPE_OP:
3370cb93a386Sopenharmony_ci                    switch (fragType) {
3371cb93a386Sopenharmony_ci                        case OP_INTERSECT: opLetter = 'I'; break;
3372cb93a386Sopenharmony_ci                        case OP_DIFFERENCE: opLetter = 'D'; break;
3373cb93a386Sopenharmony_ci                        case OP_UNION: opLetter = 'U'; break;
3374cb93a386Sopenharmony_ci                        case OP_XOR: opLetter = 'X'; break;
3375cb93a386Sopenharmony_ci                        default:
3376cb93a386Sopenharmony_ci                            console.log("unknown REC_TYPE_OP frag type: " + fragType);
3377cb93a386Sopenharmony_ci                            throw "stop execution";
3378cb93a386Sopenharmony_ci                    }
3379cb93a386Sopenharmony_ci                    break;
3380cb93a386Sopenharmony_ci                case REC_TYPE_ACTIVE:
3381cb93a386Sopenharmony_ci                    if (!draw_active || (step_limit > 0 && tIndex < lastActive)) {
3382cb93a386Sopenharmony_ci                        continue;
3383cb93a386Sopenharmony_ci                    }
3384cb93a386Sopenharmony_ci                    var x1 = frags[SPAN_X1];
3385cb93a386Sopenharmony_ci                    var y1 = frags[SPAN_Y1];
3386cb93a386Sopenharmony_ci                    var x2 = frags[SPAN_X2];
3387cb93a386Sopenharmony_ci                    var y2 = frags[SPAN_Y2];
3388cb93a386Sopenharmony_ci                    var x3, y3, x3, y4, w;
3389cb93a386Sopenharmony_ci                    ctx.lineWidth = 3;
3390cb93a386Sopenharmony_ci                    ctx.strokeStyle = "rgba(0,0,255, 0.3)";
3391cb93a386Sopenharmony_ci                    focus_enabled = true;
3392cb93a386Sopenharmony_ci                    switch (fragType) {
3393cb93a386Sopenharmony_ci                        case ACTIVE_LINE_SPAN:
3394cb93a386Sopenharmony_ci                            drawLine(x1, y1, x2, y2);
3395cb93a386Sopenharmony_ci                            if (draw_id) {
3396cb93a386Sopenharmony_ci                                drawLineID(frags[0], x1, y1, x2, y2);
3397cb93a386Sopenharmony_ci                            }
3398cb93a386Sopenharmony_ci                            if (pt_labels) {
3399cb93a386Sopenharmony_ci                                var curve = [x1, y1, x2, y2];
3400cb93a386Sopenharmony_ci                                ctx.fillStyle = "blue";
3401cb93a386Sopenharmony_ci                                drawPoints(curve, PATH_LINE, pt_labels == 2);
3402cb93a386Sopenharmony_ci                            }
3403cb93a386Sopenharmony_ci                             break;
3404cb93a386Sopenharmony_ci                        case ACTIVE_QUAD_SPAN:
3405cb93a386Sopenharmony_ci                            x3 = frags[SPAN_X3];
3406cb93a386Sopenharmony_ci                            y3 = frags[SPAN_Y3];
3407cb93a386Sopenharmony_ci                            drawQuad(x1, y1, x2, y2, x3, y3);
3408cb93a386Sopenharmony_ci                            if (draw_id) {
3409cb93a386Sopenharmony_ci                                drawQuadID(frags[0], x1, y1, x2, y2, x3, y3);
3410cb93a386Sopenharmony_ci                            }
3411cb93a386Sopenharmony_ci                            if (pt_labels) {
3412cb93a386Sopenharmony_ci                                var curve = [x1, y1, x2, y2, x3, y3];
3413cb93a386Sopenharmony_ci                                ctx.fillStyle = "blue";
3414cb93a386Sopenharmony_ci                                drawPoints(curve, PATH_QUAD, pt_labels == 2);
3415cb93a386Sopenharmony_ci                            }
3416cb93a386Sopenharmony_ci                            break;
3417cb93a386Sopenharmony_ci                        case ACTIVE_CONIC_SPAN:
3418cb93a386Sopenharmony_ci                            x3 = frags[SPAN_X3];
3419cb93a386Sopenharmony_ci                            y3 = frags[SPAN_Y3];
3420cb93a386Sopenharmony_ci                            w = frags[SPAN_K_W];
3421cb93a386Sopenharmony_ci                            drawConicWithQuads(x1, y1, x2, y2, x3, y3, w);
3422cb93a386Sopenharmony_ci                            if (draw_id) {
3423cb93a386Sopenharmony_ci                                drawConicID(frags[0], x1, y1, x2, y2, x3, y3, w);
3424cb93a386Sopenharmony_ci                            }
3425cb93a386Sopenharmony_ci                            if (pt_labels) {
3426cb93a386Sopenharmony_ci                                var curve = [x1, y1, x2, y2, x3, y3, w];
3427cb93a386Sopenharmony_ci                                ctx.fillStyle = "blue";
3428cb93a386Sopenharmony_ci                                drawPoints(curve, PATH_CONIC, pt_labels == 2);
3429cb93a386Sopenharmony_ci                            }
3430cb93a386Sopenharmony_ci                            break;
3431cb93a386Sopenharmony_ci                        case ACTIVE_CUBIC_SPAN:
3432cb93a386Sopenharmony_ci                            x3 = frags[SPAN_X3];
3433cb93a386Sopenharmony_ci                            y3 = frags[SPAN_Y3];
3434cb93a386Sopenharmony_ci                            x4 = frags[SPAN_X4];
3435cb93a386Sopenharmony_ci                            y4 = frags[SPAN_Y4];
3436cb93a386Sopenharmony_ci                            drawCubic(x1, y1, x2, y2, x3, y3, x4, y4);
3437cb93a386Sopenharmony_ci                            if (draw_id) {
3438cb93a386Sopenharmony_ci                                drawCubicID(frags[0], x1, y1, x2, y2, x3, y3, x4, y4);
3439cb93a386Sopenharmony_ci                            }
3440cb93a386Sopenharmony_ci                            if (pt_labels) {
3441cb93a386Sopenharmony_ci                                var curve = [x1, y1, x2, y2, x3, y3, x4, y4];
3442cb93a386Sopenharmony_ci                                ctx.fillStyle = "blue";
3443cb93a386Sopenharmony_ci                                drawPoints(curve, PATH_CUBIC, pt_labels == 2);
3444cb93a386Sopenharmony_ci                            }
3445cb93a386Sopenharmony_ci                            break;
3446cb93a386Sopenharmony_ci                        default:
3447cb93a386Sopenharmony_ci                            console.log("unknown REC_TYPE_ACTIVE frag type: " + fragType);
3448cb93a386Sopenharmony_ci                            throw "stop execution";
3449cb93a386Sopenharmony_ci                    }
3450cb93a386Sopenharmony_ci                    break;
3451cb93a386Sopenharmony_ci                case REC_TYPE_ACTIVE_OP:
3452cb93a386Sopenharmony_ci                    if (!draw_op || (step_limit > 0 && tIndex < lastOp)) {
3453cb93a386Sopenharmony_ci                        continue;
3454cb93a386Sopenharmony_ci                    }
3455cb93a386Sopenharmony_ci                    focus_enabled = true;
3456cb93a386Sopenharmony_ci                    ctx.lineWidth = 3;
3457cb93a386Sopenharmony_ci                    var activeSpan = frags[7] == "1";
3458cb93a386Sopenharmony_ci                    ctx.strokeStyle = activeSpan ? "rgba(45,160,0, 0.3)" : "rgba(255,45,0, 0.5)";
3459cb93a386Sopenharmony_ci                    var curve = curvePartialByID(test, frags[0], frags[1], frags[2]);
3460cb93a386Sopenharmony_ci                    drawCurve(curve);
3461cb93a386Sopenharmony_ci                    if (draw_op > 1) {
3462cb93a386Sopenharmony_ci                        drawArc(curve, false, frags[3], frags[4]);
3463cb93a386Sopenharmony_ci                        drawArc(curve, true, frags[5], frags[6]);
3464cb93a386Sopenharmony_ci                    }
3465cb93a386Sopenharmony_ci                    break;
3466cb93a386Sopenharmony_ci                case REC_TYPE_ADD:
3467cb93a386Sopenharmony_ci                    if (!draw_add) {
3468cb93a386Sopenharmony_ci                        continue;
3469cb93a386Sopenharmony_ci                    }
3470cb93a386Sopenharmony_ci                    ctx.lineWidth = 3;
3471cb93a386Sopenharmony_ci                    ctx.strokeStyle = closeCount == 0 ? "rgba(0,0,255, 0.3)"
3472cb93a386Sopenharmony_ci                            : closeCount == 1 ? "rgba(0,127,0, 0.3)"
3473cb93a386Sopenharmony_ci                            : closeCount == 2 ? "rgba(0,127,127, 0.3)"
3474cb93a386Sopenharmony_ci                            : closeCount == 3 ? "rgba(127,127,0, 0.3)"
3475cb93a386Sopenharmony_ci                            : "rgba(127,0,127, 0.3)";
3476cb93a386Sopenharmony_ci                    focus_enabled = true;
3477cb93a386Sopenharmony_ci                    switch (fragType) {
3478cb93a386Sopenharmony_ci                        case ADD_MOVETO:
3479cb93a386Sopenharmony_ci                            break;
3480cb93a386Sopenharmony_ci                        case ADD_LINETO:
3481cb93a386Sopenharmony_ci                            if (step_limit == 0 || tIndex >= lastAdd) {
3482cb93a386Sopenharmony_ci                                drawLine(frags[0], frags[1], frags[2], frags[3]);
3483cb93a386Sopenharmony_ci                            }
3484cb93a386Sopenharmony_ci                            break;
3485cb93a386Sopenharmony_ci                        case ADD_QUADTO:
3486cb93a386Sopenharmony_ci                            if (step_limit == 0 || tIndex >= lastAdd) {
3487cb93a386Sopenharmony_ci                                drawQuad(frags[0], frags[1], frags[2], frags[3], frags[4], frags[5]);
3488cb93a386Sopenharmony_ci                            }
3489cb93a386Sopenharmony_ci                            break;
3490cb93a386Sopenharmony_ci                        case ADD_CONICTO:
3491cb93a386Sopenharmony_ci                            if (step_limit == 0 || tIndex >= lastAdd) {
3492cb93a386Sopenharmony_ci                                drawConicWithQuads(frags[0], frags[1], frags[2], frags[3],
3493cb93a386Sopenharmony_ci                                        frags[4], frags[5], frags[6]);
3494cb93a386Sopenharmony_ci                            }
3495cb93a386Sopenharmony_ci                            break;
3496cb93a386Sopenharmony_ci                        case ADD_CUBICTO:
3497cb93a386Sopenharmony_ci                            if (step_limit == 0 || tIndex >= lastAdd) {
3498cb93a386Sopenharmony_ci                                drawCubic(frags[0], frags[1], frags[2], frags[3],
3499cb93a386Sopenharmony_ci                                        frags[4], frags[5], frags[6], frags[7]);
3500cb93a386Sopenharmony_ci                            }
3501cb93a386Sopenharmony_ci                            break;
3502cb93a386Sopenharmony_ci                        case ADD_CLOSE:
3503cb93a386Sopenharmony_ci                            ++closeCount;
3504cb93a386Sopenharmony_ci                            break;
3505cb93a386Sopenharmony_ci                        case ADD_FILL:
3506cb93a386Sopenharmony_ci                            break;
3507cb93a386Sopenharmony_ci                        default:
3508cb93a386Sopenharmony_ci                            console.log("unknown REC_TYPE_ADD frag type: " + fragType);
3509cb93a386Sopenharmony_ci                            throw "stop execution";
3510cb93a386Sopenharmony_ci                    }
3511cb93a386Sopenharmony_ci                    break;
3512cb93a386Sopenharmony_ci                case REC_TYPE_ANGLE:
3513cb93a386Sopenharmony_ci                    angleBetween = frags[18] == "T";
3514cb93a386Sopenharmony_ci                    afterIndex = 0;
3515cb93a386Sopenharmony_ci                    if (draw_angle == 0 || draw_angle == 3 || (step_limit > 0 && tIndex < lastAngle)) {
3516cb93a386Sopenharmony_ci                        continue;
3517cb93a386Sopenharmony_ci                    }
3518cb93a386Sopenharmony_ci                    focus_enabled = true;
3519cb93a386Sopenharmony_ci                    ctx.lineWidth = 3;
3520cb93a386Sopenharmony_ci                    ctx.strokeStyle = "rgba(127,45,127, 0.3)";
3521cb93a386Sopenharmony_ci                    var leftCurve = curvePartialByID(test, frags[0], frags[4], frags[5]);
3522cb93a386Sopenharmony_ci                    var midCurve = curvePartialByID(test, frags[6], frags[10], frags[11]);
3523cb93a386Sopenharmony_ci                    var rightCurve = curvePartialByID(test, frags[12], frags[16], frags[17]);
3524cb93a386Sopenharmony_ci                    drawCurve(leftCurve);
3525cb93a386Sopenharmony_ci                    drawCurve(rightCurve);
3526cb93a386Sopenharmony_ci                    ctx.strokeStyle = angleBetween ? "rgba(0,160,45, 0.3)" : "rgba(255,0,45, 0.5)";
3527cb93a386Sopenharmony_ci                    drawCurve(midCurve);
3528cb93a386Sopenharmony_ci                    if (draw_angle > 1) {
3529cb93a386Sopenharmony_ci                        drawVisibleOrder(leftCurve, 'L');
3530cb93a386Sopenharmony_ci                        drawVisibleOrder(rightCurve, 'R');
3531cb93a386Sopenharmony_ci                    }
3532cb93a386Sopenharmony_ci                    if (draw_id) {
3533cb93a386Sopenharmony_ci                        drawVisibleID(leftCurve, 0.5, frags[0]);
3534cb93a386Sopenharmony_ci                        drawVisibleID(midCurve, 0.5, frags[6]);
3535cb93a386Sopenharmony_ci                        drawVisibleID(rightCurve, 0.5, frags[12]);
3536cb93a386Sopenharmony_ci                    }
3537cb93a386Sopenharmony_ci                    break;
3538cb93a386Sopenharmony_ci                case REC_TYPE_AFTERPART:
3539cb93a386Sopenharmony_ci                    if (draw_angle != 3 || (step_limit > 0 && tIndex < lastAngle)) {
3540cb93a386Sopenharmony_ci                        continue;
3541cb93a386Sopenharmony_ci                    }
3542cb93a386Sopenharmony_ci                    ctx.strokeStyle = afterIndex == 0 ? "rgba(255,0,0, 1.0)"
3543cb93a386Sopenharmony_ci                            : (afterIndex == 1) == angleBetween ? "rgba(0,128,0, 1.0)"
3544cb93a386Sopenharmony_ci                            : "rgba(0,0,255, 1.0)";
3545cb93a386Sopenharmony_ci                    var curve;
3546cb93a386Sopenharmony_ci                    var id;
3547cb93a386Sopenharmony_ci                    switch (fragType) {
3548cb93a386Sopenharmony_ci                        case PATH_LINE:
3549cb93a386Sopenharmony_ci                            curve = [ frags[0], frags[1], frags[2], frags[3] ];
3550cb93a386Sopenharmony_ci                            id = frags[4];
3551cb93a386Sopenharmony_ci                            break;
3552cb93a386Sopenharmony_ci                        case PATH_QUAD:
3553cb93a386Sopenharmony_ci                            curve = [ frags[0], frags[1], frags[2], frags[3],
3554cb93a386Sopenharmony_ci                                     frags[4], frags[5] ];
3555cb93a386Sopenharmony_ci                            id = frags[6];
3556cb93a386Sopenharmony_ci                            break;
3557cb93a386Sopenharmony_ci                        case PATH_CONIC:
3558cb93a386Sopenharmony_ci                            curve = [ frags[0], frags[1], frags[2], frags[3],
3559cb93a386Sopenharmony_ci                                     frags[4], frags[5], frags[6] ];
3560cb93a386Sopenharmony_ci                            id = frags[7];
3561cb93a386Sopenharmony_ci                            break;
3562cb93a386Sopenharmony_ci                        case PATH_CUBIC:
3563cb93a386Sopenharmony_ci                            curve = [ frags[0], frags[1], frags[2], frags[3],
3564cb93a386Sopenharmony_ci                                     frags[4], frags[5], frags[6], frags[7] ];
3565cb93a386Sopenharmony_ci                            id = frags[8];
3566cb93a386Sopenharmony_ci                            break;
3567cb93a386Sopenharmony_ci                        default:
3568cb93a386Sopenharmony_ci                            console.log("unknown REC_TYPE_AFTERPART frag type: " + fragType);
3569cb93a386Sopenharmony_ci                            throw "stop execution";
3570cb93a386Sopenharmony_ci                    }
3571cb93a386Sopenharmony_ci                    drawCurve(curve);
3572cb93a386Sopenharmony_ci                    if (draw_id) {
3573cb93a386Sopenharmony_ci                        drawVisibleID(curve, 0.5, id);
3574cb93a386Sopenharmony_ci                    }
3575cb93a386Sopenharmony_ci                    ++afterIndex;
3576cb93a386Sopenharmony_ci                    break;
3577cb93a386Sopenharmony_ci                case REC_TYPE_COINCIDENCE:
3578cb93a386Sopenharmony_ci                    if (!draw_coincidence || (step_limit > 0 && tIndex < lastCoin)) {
3579cb93a386Sopenharmony_ci                        continue;
3580cb93a386Sopenharmony_ci                    }
3581cb93a386Sopenharmony_ci                    focus_enabled = true;
3582cb93a386Sopenharmony_ci                    ctx.lineWidth = 3;
3583cb93a386Sopenharmony_ci                    ctx.strokeStyle = "rgba(127,45,63, 0.3)";
3584cb93a386Sopenharmony_ci                    var curve = curvePartialByID(test, frags[0], frags[1], frags[2]);
3585cb93a386Sopenharmony_ci                    drawCurve(curve);
3586cb93a386Sopenharmony_ci                    break;
3587cb93a386Sopenharmony_ci                case REC_TYPE_SECT:
3588cb93a386Sopenharmony_ci                    if (!draw_intersection) {
3589cb93a386Sopenharmony_ci                        continue;
3590cb93a386Sopenharmony_ci                    }
3591cb93a386Sopenharmony_ci                    if (draw_intersection != 1 && (step_limit > 0 && tIndex < lastSect)) {
3592cb93a386Sopenharmony_ci                        continue;
3593cb93a386Sopenharmony_ci                    }
3594cb93a386Sopenharmony_ci                    // draw_intersection == 1 : show all
3595cb93a386Sopenharmony_ci                    // draw_intersection == 2 : step == 0 ? show all : show intersection line #step
3596cb93a386Sopenharmony_ci                    // draw_intersection == 3 : step == 0 ? show all : show intersection #step
3597cb93a386Sopenharmony_ci                    ctx.lineWidth = 1;
3598cb93a386Sopenharmony_ci                    ctx.strokeStyle = "rgba(0,0,255, 0.3)";
3599cb93a386Sopenharmony_ci                    ctx.fillStyle = "blue";
3600cb93a386Sopenharmony_ci                    focus_enabled = true;
3601cb93a386Sopenharmony_ci                    var f = [];
3602cb93a386Sopenharmony_ci                    var c1s;
3603cb93a386Sopenharmony_ci                    var c1l;
3604cb93a386Sopenharmony_ci                    var c2s;
3605cb93a386Sopenharmony_ci                    var c2l;
3606cb93a386Sopenharmony_ci                    switch (fragType) {
3607cb93a386Sopenharmony_ci                        case INTERSECT_LINE:
3608cb93a386Sopenharmony_ci                            f.push(5, 6, 0, 7);
3609cb93a386Sopenharmony_ci                            c1s = 1; c1l = 4; c2s = 8; c2l = 4;
3610cb93a386Sopenharmony_ci                            break;
3611cb93a386Sopenharmony_ci                        case INTERSECT_LINE_2:
3612cb93a386Sopenharmony_ci                            f.push(5, 6, 0, 10);
3613cb93a386Sopenharmony_ci                            f.push(8, 9, 7, 15);
3614cb93a386Sopenharmony_ci                            c1s = 1; c1l = 4; c2s = 11; c2l = 4;
3615cb93a386Sopenharmony_ci                            break;
3616cb93a386Sopenharmony_ci                        case INTERSECT_LINE_NO:
3617cb93a386Sopenharmony_ci                            c1s = 0; c1l = 4; c2s = 4; c2l = 4;
3618cb93a386Sopenharmony_ci                            break;
3619cb93a386Sopenharmony_ci                        case INTERSECT_QUAD_LINE:
3620cb93a386Sopenharmony_ci                            f.push(7, 8, 0, 9);
3621cb93a386Sopenharmony_ci                            c1s = 1; c1l = 6; c2s = 10; c2l = 4;
3622cb93a386Sopenharmony_ci                            break;
3623cb93a386Sopenharmony_ci                        case INTERSECT_QUAD_LINE_2:
3624cb93a386Sopenharmony_ci                            f.push(7, 8, 0, 12);
3625cb93a386Sopenharmony_ci                            f.push(10, 11, 9, 17);
3626cb93a386Sopenharmony_ci                            c1s = 1; c1l = 6; c2s = 13; c2l = 4;
3627cb93a386Sopenharmony_ci                            break;
3628cb93a386Sopenharmony_ci                        case INTERSECT_QUAD_LINE_NO:
3629cb93a386Sopenharmony_ci                            c1s = 0; c1l = 6; c2s = 6; c2l = 4;
3630cb93a386Sopenharmony_ci                            break;
3631cb93a386Sopenharmony_ci                        case INTERSECT_QUAD:
3632cb93a386Sopenharmony_ci                            f.push(7, 8, 0, 9);
3633cb93a386Sopenharmony_ci                            c1s = 1; c1l = 6; c2s = 10; c2l = 6;
3634cb93a386Sopenharmony_ci                            break;
3635cb93a386Sopenharmony_ci                        case INTERSECT_QUAD_2:
3636cb93a386Sopenharmony_ci                            f.push(7, 8, 0, 12);
3637cb93a386Sopenharmony_ci                            f.push(10, 11, 9, 19);
3638cb93a386Sopenharmony_ci                            c1s = 1; c1l = 6; c2s = 13; c2l = 6;
3639cb93a386Sopenharmony_ci                            break;
3640cb93a386Sopenharmony_ci                        case INTERSECT_QUAD_NO:
3641cb93a386Sopenharmony_ci                            c1s = 0; c1l = 6; c2s = 6; c2l = 6;
3642cb93a386Sopenharmony_ci                            break;
3643cb93a386Sopenharmony_ci                        case INTERSECT_CONIC_LINE:
3644cb93a386Sopenharmony_ci                            f.push(8, 9, 0, 10);
3645cb93a386Sopenharmony_ci                            c1s = 1; c1l = 7; c2s = 11; c2l = 4;
3646cb93a386Sopenharmony_ci                            break;
3647cb93a386Sopenharmony_ci                        case INTERSECT_CONIC_LINE_2:
3648cb93a386Sopenharmony_ci                            f.push(8, 9, 0, 12);
3649cb93a386Sopenharmony_ci                            f.push(11, 12, 10, 18);
3650cb93a386Sopenharmony_ci                            c1s = 1; c1l = 7; c2s = 14; c2l = 4;
3651cb93a386Sopenharmony_ci                            break;
3652cb93a386Sopenharmony_ci                        case INTERSECT_CONIC_LINE_NO:
3653cb93a386Sopenharmony_ci                            c1s = 0; c1l = 7; c2s = 7; c2l = 4;
3654cb93a386Sopenharmony_ci                            break;
3655cb93a386Sopenharmony_ci                        case INTERSECT_CONIC_QUAD:
3656cb93a386Sopenharmony_ci                            f.push(8, 9, 0, 10);
3657cb93a386Sopenharmony_ci                            c1s = 1; c1l = 7; c2s = 11; c2l = 6;
3658cb93a386Sopenharmony_ci                            break;
3659cb93a386Sopenharmony_ci                        case INTERSECT_CONIC_QUAD_2:
3660cb93a386Sopenharmony_ci                            f.push(8, 9, 0, 12);
3661cb93a386Sopenharmony_ci                            f.push(11, 12, 10, 18);
3662cb93a386Sopenharmony_ci                            c1s = 1; c1l = 7; c2s = 14; c2l = 6;
3663cb93a386Sopenharmony_ci                            break;
3664cb93a386Sopenharmony_ci                        case INTERSECT_CONIC_QUAD_3:
3665cb93a386Sopenharmony_ci                            f.push(8, 9, 0, 15);
3666cb93a386Sopenharmony_ci                            f.push(11, 12, 10, 21);
3667cb93a386Sopenharmony_ci                            f.push(14, 15, 13, 22);
3668cb93a386Sopenharmony_ci                            c1s = 1; c1l = 7; c2s = 17; c2l = 6;
3669cb93a386Sopenharmony_ci                            break;
3670cb93a386Sopenharmony_ci                        case INTERSECT_CONIC_QUAD_4:
3671cb93a386Sopenharmony_ci                            f.push(8, 9, 0, 18);
3672cb93a386Sopenharmony_ci                            f.push(11, 12, 10, 24);
3673cb93a386Sopenharmony_ci                            f.push(14, 15, 13, 25);
3674cb93a386Sopenharmony_ci                            f.push(17, 18, 16, 26);
3675cb93a386Sopenharmony_ci                            c1s = 1; c1l = 7; c2s = 20; c2l = 6;
3676cb93a386Sopenharmony_ci                            break;
3677cb93a386Sopenharmony_ci                        case INTERSECT_CONIC_QUAD_NO:
3678cb93a386Sopenharmony_ci                            c1s = 0; c1l = 7; c2s = 7; c2l = 6;
3679cb93a386Sopenharmony_ci                            break;
3680cb93a386Sopenharmony_ci                        case INTERSECT_CONIC:
3681cb93a386Sopenharmony_ci                            f.push(8, 9, 0, 10);
3682cb93a386Sopenharmony_ci                            c1s = 1; c1l = 7; c2s = 11; c2l = 7;
3683cb93a386Sopenharmony_ci                            break;
3684cb93a386Sopenharmony_ci                        case INTERSECT_CONIC_2:
3685cb93a386Sopenharmony_ci                            f.push(8, 9, 0, 13);
3686cb93a386Sopenharmony_ci                            f.push(11, 12, 10, 21);
3687cb93a386Sopenharmony_ci                            c1s = 1; c1l = 7; c2s = 14; c2l = 7;
3688cb93a386Sopenharmony_ci                            break;
3689cb93a386Sopenharmony_ci                        case INTERSECT_CONIC_NO:
3690cb93a386Sopenharmony_ci                            c1s = 0; c1l = 7; c2s = 7; c2l = 7;
3691cb93a386Sopenharmony_ci                            break;
3692cb93a386Sopenharmony_ci                        case INTERSECT_SELF_CUBIC:
3693cb93a386Sopenharmony_ci                            f.push(9, 10, 0, 11);
3694cb93a386Sopenharmony_ci                            c1s = 1; c1l = 8; c2s = 0; c2l = 0;
3695cb93a386Sopenharmony_ci                            break;
3696cb93a386Sopenharmony_ci                        case INTERSECT_SELF_CUBIC_NO:
3697cb93a386Sopenharmony_ci                            c1s = 0; c1l = 8; c2s = 0; c2l = 0;
3698cb93a386Sopenharmony_ci                            break;
3699cb93a386Sopenharmony_ci                        case INTERSECT_CUBIC_LINE:
3700cb93a386Sopenharmony_ci                            f.push(9, 10, 0, 11);
3701cb93a386Sopenharmony_ci                            c1s = 1; c1l = 8; c2s = 12; c2l = 4;
3702cb93a386Sopenharmony_ci                            break;
3703cb93a386Sopenharmony_ci                        case INTERSECT_CUBIC_LINE_2:
3704cb93a386Sopenharmony_ci                            f.push(9, 10, 0, 14);
3705cb93a386Sopenharmony_ci                            f.push(12, 13, 11, 19);
3706cb93a386Sopenharmony_ci                            c1s = 1; c1l = 8; c2s = 15; c2l = 4;
3707cb93a386Sopenharmony_ci                            break;
3708cb93a386Sopenharmony_ci                        case INTERSECT_CUBIC_LINE_3:
3709cb93a386Sopenharmony_ci                            f.push(9, 10, 0, 17);
3710cb93a386Sopenharmony_ci                            f.push(12, 13, 11, 22);
3711cb93a386Sopenharmony_ci                            f.push(15, 16, 14, 23);
3712cb93a386Sopenharmony_ci                            c1s = 1; c1l = 8; c2s = 18; c2l = 4;
3713cb93a386Sopenharmony_ci                            break;
3714cb93a386Sopenharmony_ci                        case INTERSECT_CUBIC_QUAD_NO:
3715cb93a386Sopenharmony_ci                            c1s = 0; c1l = 8; c2s = 8; c2l = 6;
3716cb93a386Sopenharmony_ci                            break;
3717cb93a386Sopenharmony_ci                        case INTERSECT_CUBIC_QUAD:
3718cb93a386Sopenharmony_ci                            f.push(9, 10, 0, 11);
3719cb93a386Sopenharmony_ci                            c1s = 1; c1l = 8; c2s = 12; c2l = 6;
3720cb93a386Sopenharmony_ci                            break;
3721cb93a386Sopenharmony_ci                        case INTERSECT_CUBIC_QUAD_2:
3722cb93a386Sopenharmony_ci                            f.push(9, 10, 0, 14);
3723cb93a386Sopenharmony_ci                            f.push(12, 13, 11, 21);
3724cb93a386Sopenharmony_ci                            c1s = 1; c1l = 8; c2s = 15; c2l = 6;
3725cb93a386Sopenharmony_ci                            break;
3726cb93a386Sopenharmony_ci                        case INTERSECT_CUBIC_QUAD_3:
3727cb93a386Sopenharmony_ci                            f.push(9, 10, 0, 17);
3728cb93a386Sopenharmony_ci                            f.push(12, 13, 11, 24);
3729cb93a386Sopenharmony_ci                            f.push(15, 16, 14, 25);
3730cb93a386Sopenharmony_ci                            c1s = 1; c1l = 8; c2s = 18; c2l = 6;
3731cb93a386Sopenharmony_ci                            break;
3732cb93a386Sopenharmony_ci                        case INTERSECT_CUBIC_QUAD_4:
3733cb93a386Sopenharmony_ci                            f.push(9, 10, 0, 20);
3734cb93a386Sopenharmony_ci                            f.push(12, 13, 11, 27);
3735cb93a386Sopenharmony_ci                            f.push(15, 16, 14, 28);
3736cb93a386Sopenharmony_ci                            f.push(18, 19, 17, 29);
3737cb93a386Sopenharmony_ci                            c1s = 1; c1l = 8; c2s = 21; c2l = 6;
3738cb93a386Sopenharmony_ci                            break;
3739cb93a386Sopenharmony_ci                        case INTERSECT_CUBIC_LINE_NO:
3740cb93a386Sopenharmony_ci                            c1s = 0; c1l = 8; c2s = 8; c2l = 4;
3741cb93a386Sopenharmony_ci                            break;
3742cb93a386Sopenharmony_ci                        case INTERSECT_CUBIC:
3743cb93a386Sopenharmony_ci                            f.push(9, 10, 0, 11);
3744cb93a386Sopenharmony_ci                            c1s = 1; c1l = 8; c2s = 12; c2l = 8;
3745cb93a386Sopenharmony_ci                            break;
3746cb93a386Sopenharmony_ci                        case INTERSECT_CUBIC_2:
3747cb93a386Sopenharmony_ci                            f.push(9, 10, 0, 14);
3748cb93a386Sopenharmony_ci                            f.push(12, 13, 11, 23);
3749cb93a386Sopenharmony_ci                            c1s = 1; c1l = 8; c2s = 15; c2l = 8;
3750cb93a386Sopenharmony_ci                            break;
3751cb93a386Sopenharmony_ci                        case INTERSECT_CUBIC_3:
3752cb93a386Sopenharmony_ci                            f.push(9, 10, 0, 17);
3753cb93a386Sopenharmony_ci                            f.push(12, 13, 11, 26);
3754cb93a386Sopenharmony_ci                            f.push(15, 16, 14, 27);
3755cb93a386Sopenharmony_ci                            c1s = 1; c1l = 8; c2s = 18; c2l = 8;
3756cb93a386Sopenharmony_ci                            break;
3757cb93a386Sopenharmony_ci                        case INTERSECT_CUBIC_4:
3758cb93a386Sopenharmony_ci                            f.push(9, 10, 0, 20);
3759cb93a386Sopenharmony_ci                            f.push(12, 13, 11, 29);
3760cb93a386Sopenharmony_ci                            f.push(15, 16, 14, 30);
3761cb93a386Sopenharmony_ci                            f.push(18, 19, 17, 31);
3762cb93a386Sopenharmony_ci                            c1s = 1; c1l = 8; c2s = 21; c2l = 8;
3763cb93a386Sopenharmony_ci                            break;
3764cb93a386Sopenharmony_ci                        case INTERSECT_CUBIC_NO:
3765cb93a386Sopenharmony_ci                            c1s = 0; c1l = 8; c2s = 8; c2l = 8;
3766cb93a386Sopenharmony_ci                            break;
3767cb93a386Sopenharmony_ci                        default:
3768cb93a386Sopenharmony_ci                            console.log("unknown REC_TYPE_SECT frag type: " + fragType);
3769cb93a386Sopenharmony_ci                            throw "stop execution";
3770cb93a386Sopenharmony_ci                    }
3771cb93a386Sopenharmony_ci                    if (draw_intersection != 1) {
3772cb93a386Sopenharmony_ci                        var id = -1;
3773cb93a386Sopenharmony_ci                        var curve;
3774cb93a386Sopenharmony_ci                        switch (c1l) {
3775cb93a386Sopenharmony_ci                            case 4:
3776cb93a386Sopenharmony_ci                                drawLine(frags[c1s], frags[c1s + 1], frags[c1s + 2], frags[c1s + 3]);
3777cb93a386Sopenharmony_ci                                if (draw_id) {
3778cb93a386Sopenharmony_ci                                    curve = [frags[c1s], frags[c1s + 1], frags[c1s + 2], frags[c1s + 3]];
3779cb93a386Sopenharmony_ci                                    id = idByCurve(test, curve, PATH_LINE);
3780cb93a386Sopenharmony_ci                                }
3781cb93a386Sopenharmony_ci                                break;
3782cb93a386Sopenharmony_ci                            case 6:
3783cb93a386Sopenharmony_ci                                drawQuad(frags[c1s], frags[c1s + 1], frags[c1s + 2], frags[c1s + 3],
3784cb93a386Sopenharmony_ci                                        frags[c1s + 4], frags[c1s + 5]);
3785cb93a386Sopenharmony_ci                                if (draw_id) {
3786cb93a386Sopenharmony_ci                                    curve = [frags[c1s], frags[c1s + 1], frags[c1s + 2], frags[c1s + 3],
3787cb93a386Sopenharmony_ci                                            frags[c1s + 4], frags[c1s + 5]];
3788cb93a386Sopenharmony_ci                                    id = idByCurve(test, curve, PATH_QUAD);
3789cb93a386Sopenharmony_ci                                }
3790cb93a386Sopenharmony_ci                                break;
3791cb93a386Sopenharmony_ci                            case 7:
3792cb93a386Sopenharmony_ci                                drawConicWithQuads(frags[c1s], frags[c1s + 1], frags[c1s + 2], frags[c1s + 3],
3793cb93a386Sopenharmony_ci                                        frags[c1s + 4], frags[c1s + 5], frags[c1s + 6]);
3794cb93a386Sopenharmony_ci                                if (draw_id) {
3795cb93a386Sopenharmony_ci                                    curve = [frags[c1s], frags[c1s + 1], frags[c1s + 2], frags[c1s + 3],
3796cb93a386Sopenharmony_ci                                            frags[c1s + 4], frags[c1s + 5], frags[c1s + 6]];
3797cb93a386Sopenharmony_ci                                    id = idByCurve(test, curve, PATH_CONIC);
3798cb93a386Sopenharmony_ci                                }
3799cb93a386Sopenharmony_ci                                break;
3800cb93a386Sopenharmony_ci                            case 8:
3801cb93a386Sopenharmony_ci                                drawCubic(frags[c1s], frags[c1s + 1], frags[c1s + 2], frags[c1s + 3],
3802cb93a386Sopenharmony_ci                                        frags[c1s + 4], frags[c1s + 5], frags[c1s + 6], frags[c1s + 7]);
3803cb93a386Sopenharmony_ci                                if (draw_id) {
3804cb93a386Sopenharmony_ci                                    curve = [frags[c1s], frags[c1s + 1], frags[c1s + 2], frags[c1s + 3],
3805cb93a386Sopenharmony_ci                                            frags[c1s + 4], frags[c1s + 5], frags[c1s + 6], frags[c1s + 7]];
3806cb93a386Sopenharmony_ci                                    id = idByCurve(test, curve, PATH_CUBIC);
3807cb93a386Sopenharmony_ci                                }
3808cb93a386Sopenharmony_ci                                break;
3809cb93a386Sopenharmony_ci                        }
3810cb93a386Sopenharmony_ci                        if (id >= 0) {
3811cb93a386Sopenharmony_ci                            drawVisibleID(curve, 0.5, id);
3812cb93a386Sopenharmony_ci                        }
3813cb93a386Sopenharmony_ci                        id = -1;
3814cb93a386Sopenharmony_ci                        switch (c2l) {
3815cb93a386Sopenharmony_ci                            case 0:
3816cb93a386Sopenharmony_ci                                break;
3817cb93a386Sopenharmony_ci                            case 4:
3818cb93a386Sopenharmony_ci                                drawLine(frags[c2s], frags[c2s + 1], frags[c2s + 2], frags[c2s + 3]);
3819cb93a386Sopenharmony_ci                                if (draw_id) {
3820cb93a386Sopenharmony_ci                                    curve = [frags[c2s], frags[c2s + 1], frags[c2s + 2], frags[c2s + 3]];
3821cb93a386Sopenharmony_ci                                    id = idByCurve(test, curve, PATH_LINE);
3822cb93a386Sopenharmony_ci                                }
3823cb93a386Sopenharmony_ci                                break;
3824cb93a386Sopenharmony_ci                            case 6:
3825cb93a386Sopenharmony_ci                                drawQuad(frags[c2s], frags[c2s + 1], frags[c2s + 2], frags[c2s + 3],
3826cb93a386Sopenharmony_ci                                        frags[c2s + 4], frags[c2s + 5]);
3827cb93a386Sopenharmony_ci                                if (draw_id) {
3828cb93a386Sopenharmony_ci                                    curve = [frags[c2s], frags[c2s + 1], frags[c2s + 2], frags[c2s + 3],
3829cb93a386Sopenharmony_ci                                            frags[c2s + 4], frags[c2s + 5]];
3830cb93a386Sopenharmony_ci                                    id = idByCurve(test, curve, PATH_QUAD);
3831cb93a386Sopenharmony_ci                                }
3832cb93a386Sopenharmony_ci                                break;
3833cb93a386Sopenharmony_ci                            case 7:
3834cb93a386Sopenharmony_ci                                drawConicWithQuads(frags[c2s], frags[c2s + 1], frags[c2s + 2], frags[c2s + 3],
3835cb93a386Sopenharmony_ci                                        frags[c2s + 4], frags[c2s + 5], frags[c2s + 6]);
3836cb93a386Sopenharmony_ci                                if (draw_id) {
3837cb93a386Sopenharmony_ci                                    curve = [frags[c2s], frags[c2s + 1], frags[c2s + 2], frags[c2s + 3],
3838cb93a386Sopenharmony_ci                                            frags[c2s + 4], frags[c2s + 5], frags[c2s + 6]];
3839cb93a386Sopenharmony_ci                                    id = idByCurve(test, curve, PATH_CONIC);
3840cb93a386Sopenharmony_ci                                }
3841cb93a386Sopenharmony_ci                                break;
3842cb93a386Sopenharmony_ci                            case 8:
3843cb93a386Sopenharmony_ci                                drawCubic(frags[c2s], frags[c2s + 1], frags[c2s + 2], frags[c2s + 3],
3844cb93a386Sopenharmony_ci                                        frags[c2s + 4], frags[c2s + 5], frags[c2s + 6], frags[c2s + 7]);
3845cb93a386Sopenharmony_ci                                if (draw_id) {
3846cb93a386Sopenharmony_ci                                    curve = [frags[c2s], frags[c2s + 1], frags[c2s + 2], frags[c2s + 3],
3847cb93a386Sopenharmony_ci                                            frags[c2s + 4], frags[c2s + 5], frags[c2s + 6], frags[c2s + 7]];
3848cb93a386Sopenharmony_ci                                    id = idByCurve(test, curve, PATH_CUBIC);
3849cb93a386Sopenharmony_ci                                }
3850cb93a386Sopenharmony_ci                                break;
3851cb93a386Sopenharmony_ci                        }
3852cb93a386Sopenharmony_ci                        if (id >= 0) {
3853cb93a386Sopenharmony_ci                            drawVisibleID(curve, 0.5, id);
3854cb93a386Sopenharmony_ci                        }
3855cb93a386Sopenharmony_ci                    }
3856cb93a386Sopenharmony_ci                    if (collect_bounds) {
3857cb93a386Sopenharmony_ci                        break;
3858cb93a386Sopenharmony_ci                    }
3859cb93a386Sopenharmony_ci                    if (draw_intersection != 3 || step_limit == 0 || tIndex >= lastSect) {
3860cb93a386Sopenharmony_ci                        for (var idx = 0; idx < f.length; idx += 4) {
3861cb93a386Sopenharmony_ci                            drawPoint(frags[f[idx]], frags[f[idx + 1]], true);
3862cb93a386Sopenharmony_ci                        }
3863cb93a386Sopenharmony_ci                    }
3864cb93a386Sopenharmony_ci                    if (!draw_intersectT) {
3865cb93a386Sopenharmony_ci                        break;
3866cb93a386Sopenharmony_ci                    }
3867cb93a386Sopenharmony_ci                    ctx.fillStyle = "red";
3868cb93a386Sopenharmony_ci                    if (draw_intersection != 3 || step_limit == 0 || tIndex >= lastSect) {
3869cb93a386Sopenharmony_ci                        for (var idx = 0; idx < f.length; idx += 4) {
3870cb93a386Sopenharmony_ci                            drawTAtPointUp(frags[f[idx]], frags[f[idx + 1]], frags[f[idx + 2]]);
3871cb93a386Sopenharmony_ci                            drawTAtPointDown(frags[f[idx]], frags[f[idx + 1]], frags[f[idx + 3]]);
3872cb93a386Sopenharmony_ci                        }
3873cb93a386Sopenharmony_ci                    }
3874cb93a386Sopenharmony_ci                    break;
3875cb93a386Sopenharmony_ci                case REC_TYPE_SORT:
3876cb93a386Sopenharmony_ci                    if (!draw_sort || (step_limit > 0 && tIndex < lastSort)) {
3877cb93a386Sopenharmony_ci                        continue;
3878cb93a386Sopenharmony_ci                    }
3879cb93a386Sopenharmony_ci                    ctx.lineWidth = 3;
3880cb93a386Sopenharmony_ci                    ctx.strokeStyle = "rgba(127,127,0, 0.5)";
3881cb93a386Sopenharmony_ci                    focus_enabled = true;
3882cb93a386Sopenharmony_ci                    switch (fragType) {
3883cb93a386Sopenharmony_ci                        case SORT_UNARY:
3884cb93a386Sopenharmony_ci                        case SORT_BINARY:
3885cb93a386Sopenharmony_ci                            var curve = curvePartialByID(test, frags[0], frags[6], frags[8]);
3886cb93a386Sopenharmony_ci                            drawCurve(curve);
3887cb93a386Sopenharmony_ci                            break;
3888cb93a386Sopenharmony_ci                        default:
3889cb93a386Sopenharmony_ci                            console.log("unknown REC_TYPE_SORT frag type: " + fragType);
3890cb93a386Sopenharmony_ci                            throw "stop execution";
3891cb93a386Sopenharmony_ci                    }
3892cb93a386Sopenharmony_ci                    break;
3893cb93a386Sopenharmony_ci                case REC_TYPE_TOP:
3894cb93a386Sopenharmony_ci                    if (!draw_top || (step_limit > 0 && tIndex < lastTop)) {
3895cb93a386Sopenharmony_ci                        continue;
3896cb93a386Sopenharmony_ci                    }
3897cb93a386Sopenharmony_ci                    ctx.lineWidth = 3;
3898cb93a386Sopenharmony_ci                    ctx.strokeStyle = "rgba(127,127,0, 0.5)";
3899cb93a386Sopenharmony_ci                    focus_enabled = true;
3900cb93a386Sopenharmony_ci                    {
3901cb93a386Sopenharmony_ci                        var curve = curvePartialByID(test, frags[0], frags[1], frags[2]);
3902cb93a386Sopenharmony_ci                        drawCurve(curve);
3903cb93a386Sopenharmony_ci                        var type = PATH_LINE + (curve.length / 2 - 2);
3904cb93a386Sopenharmony_ci                        var mid = pointAtT(curve, type, 0.5);
3905cb93a386Sopenharmony_ci                        var d = dxy_at_t(curve, type, 0.5);
3906cb93a386Sopenharmony_ci                        drawArrow(mid.x, mid.y, d.x, d.y, 0.3);
3907cb93a386Sopenharmony_ci                    }
3908cb93a386Sopenharmony_ci                    break;
3909cb93a386Sopenharmony_ci                case REC_TYPE_MARK:
3910cb93a386Sopenharmony_ci                    if (!draw_mark || (step_limit > 0 && tIndex < lastMark)) {
3911cb93a386Sopenharmony_ci                        continue;
3912cb93a386Sopenharmony_ci                    }
3913cb93a386Sopenharmony_ci                    ctx.lineWidth = 3;
3914cb93a386Sopenharmony_ci                    ctx.strokeStyle = fragType >= MARK_DONE_LINE ?
3915cb93a386Sopenharmony_ci                            "rgba(127,0,127, 0.5)" : "rgba(127,127,0, 0.5)";
3916cb93a386Sopenharmony_ci                    focus_enabled = true;
3917cb93a386Sopenharmony_ci                    switch (fragType) {
3918cb93a386Sopenharmony_ci                        case MARK_LINE:
3919cb93a386Sopenharmony_ci                        case MARK_DONE_LINE:
3920cb93a386Sopenharmony_ci                        case MARK_UNSORTABLE_LINE:
3921cb93a386Sopenharmony_ci                        case MARK_SIMPLE_LINE:
3922cb93a386Sopenharmony_ci                        case MARK_SIMPLE_DONE_LINE:
3923cb93a386Sopenharmony_ci                        case MARK_DONE_UNARY_LINE:
3924cb93a386Sopenharmony_ci                            drawLinePartial(frags[1], frags[2], frags[3], frags[4],
3925cb93a386Sopenharmony_ci                                frags[5], frags[9]);
3926cb93a386Sopenharmony_ci                            if (draw_id) {
3927cb93a386Sopenharmony_ci                                drawLinePartialID(frags[0], frags[1], frags[2], frags[3], frags[4],
3928cb93a386Sopenharmony_ci                                frags[5], frags[9]);
3929cb93a386Sopenharmony_ci                            }
3930cb93a386Sopenharmony_ci                            break;
3931cb93a386Sopenharmony_ci                        case MARK_QUAD:
3932cb93a386Sopenharmony_ci                        case MARK_DONE_QUAD:
3933cb93a386Sopenharmony_ci                        case MARK_UNSORTABLE_QUAD:
3934cb93a386Sopenharmony_ci                        case MARK_SIMPLE_QUAD:
3935cb93a386Sopenharmony_ci                        case MARK_SIMPLE_DONE_QUAD:
3936cb93a386Sopenharmony_ci                        case MARK_DONE_UNARY_QUAD:
3937cb93a386Sopenharmony_ci                            drawQuadPartial(frags[1], frags[2], frags[3], frags[4],
3938cb93a386Sopenharmony_ci                                frags[5], frags[6], frags[7], frags[11]);
3939cb93a386Sopenharmony_ci                            if (draw_id) {
3940cb93a386Sopenharmony_ci                                drawQuadPartialID(frags[0], frags[1], frags[2], frags[3], frags[4],
3941cb93a386Sopenharmony_ci                                frags[5], frags[6], frags[7], frags[11]);
3942cb93a386Sopenharmony_ci                            }
3943cb93a386Sopenharmony_ci                            break;
3944cb93a386Sopenharmony_ci                        case MARK_CUBIC:
3945cb93a386Sopenharmony_ci                        case MARK_DONE_CUBIC:
3946cb93a386Sopenharmony_ci                        case MARK_UNSORTABLE_CUBIC:
3947cb93a386Sopenharmony_ci                        case MARK_SIMPLE_CUBIC:
3948cb93a386Sopenharmony_ci                        case MARK_SIMPLE_DONE_CUBIC:
3949cb93a386Sopenharmony_ci                        case MARK_DONE_UNARY_CUBIC:
3950cb93a386Sopenharmony_ci                            drawCubicPartial(frags[1], frags[2], frags[3], frags[4],
3951cb93a386Sopenharmony_ci                                frags[5], frags[6], frags[7], frags[8], frags[9], frags[13]);
3952cb93a386Sopenharmony_ci                            if (draw_id) {
3953cb93a386Sopenharmony_ci                                drawCubicPartialID(frags[0], frags[1], frags[2], frags[3], frags[4],
3954cb93a386Sopenharmony_ci                                frags[5], frags[6], frags[7], frags[8], frags[9], frags[13]);
3955cb93a386Sopenharmony_ci                            }
3956cb93a386Sopenharmony_ci                            break;
3957cb93a386Sopenharmony_ci                        case MARK_ANGLE_LAST:
3958cb93a386Sopenharmony_ci                            // FIXME: ignored for now
3959cb93a386Sopenharmony_ci                            break;
3960cb93a386Sopenharmony_ci                        default:
3961cb93a386Sopenharmony_ci                            console.log("unknown REC_TYPE_MARK frag type: " + fragType);
3962cb93a386Sopenharmony_ci                            throw "stop execution";
3963cb93a386Sopenharmony_ci                    }
3964cb93a386Sopenharmony_ci                    break;
3965cb93a386Sopenharmony_ci                default:
3966cb93a386Sopenharmony_ci                    continue;
3967cb93a386Sopenharmony_ci            }
3968cb93a386Sopenharmony_ci        }
3969cb93a386Sopenharmony_ci        switch (recType) {
3970cb93a386Sopenharmony_ci            case REC_TYPE_SORT:
3971cb93a386Sopenharmony_ci                if (!draw_sort || (step_limit > 0 && tIndex < lastSort)) {
3972cb93a386Sopenharmony_ci                    break;
3973cb93a386Sopenharmony_ci                }
3974cb93a386Sopenharmony_ci                var angles = []; // use tangent lines to describe arcs
3975cb93a386Sopenharmony_ci                var windFrom = [];
3976cb93a386Sopenharmony_ci                var windTo = [];
3977cb93a386Sopenharmony_ci                var opp = [];
3978cb93a386Sopenharmony_ci                var minXY = Number.MAX_VALUE;
3979cb93a386Sopenharmony_ci                var partial;
3980cb93a386Sopenharmony_ci                focus_enabled = true;
3981cb93a386Sopenharmony_ci                var someUnsortable = false;
3982cb93a386Sopenharmony_ci                for (var recordIndex = 0; recordIndex < records.length; recordIndex += 2) {
3983cb93a386Sopenharmony_ci                    var fragType = records[recordIndex];
3984cb93a386Sopenharmony_ci                    var frags = records[recordIndex + 1];
3985cb93a386Sopenharmony_ci                    var unsortable = (fragType == SORT_UNARY && frags[14]) ||
3986cb93a386Sopenharmony_ci                            (fragType == SORT_BINARY && frags[16]);
3987cb93a386Sopenharmony_ci                    someUnsortable |= unsortable;
3988cb93a386Sopenharmony_ci                    switch (fragType) {
3989cb93a386Sopenharmony_ci                        case SORT_UNARY:
3990cb93a386Sopenharmony_ci                        case SORT_BINARY:
3991cb93a386Sopenharmony_ci                            partial = curvePartialByID(test, frags[0], frags[6], frags[8]);
3992cb93a386Sopenharmony_ci                            break;
3993cb93a386Sopenharmony_ci                        default:
3994cb93a386Sopenharmony_ci                            console.log("unknown REC_TYPE_SORT frag type: " + fragType);
3995cb93a386Sopenharmony_ci                            throw "stop execution";
3996cb93a386Sopenharmony_ci                    }
3997cb93a386Sopenharmony_ci                    var dx = boundsWidth(partial);
3998cb93a386Sopenharmony_ci                    var dy = boundsHeight(partial);
3999cb93a386Sopenharmony_ci                    minXY = Math.min(minXY, dx * dx + dy * dy);
4000cb93a386Sopenharmony_ci                    if (collect_bounds) {
4001cb93a386Sopenharmony_ci                        continue;
4002cb93a386Sopenharmony_ci                    }
4003cb93a386Sopenharmony_ci                    angles.push(tangent(partial));
4004cb93a386Sopenharmony_ci                    var from = frags[12];
4005cb93a386Sopenharmony_ci                    var to = frags[12];
4006cb93a386Sopenharmony_ci                    var sgn = frags[10];
4007cb93a386Sopenharmony_ci                    if (sgn < 0) {
4008cb93a386Sopenharmony_ci                        from -= frags[11];
4009cb93a386Sopenharmony_ci                    } else if (sgn > 0) {
4010cb93a386Sopenharmony_ci                        to -= frags[11];
4011cb93a386Sopenharmony_ci                    }
4012cb93a386Sopenharmony_ci                    windFrom.push(from + (unsortable ? "!" : ""));
4013cb93a386Sopenharmony_ci                    windTo.push(to + (unsortable ? "!" : ""));
4014cb93a386Sopenharmony_ci                    opp.push(fragType == SORT_BINARY);
4015cb93a386Sopenharmony_ci                    if (draw_sort == 1) {
4016cb93a386Sopenharmony_ci                        drawVisibleOrder(partial, frags[12]);
4017cb93a386Sopenharmony_ci                    } else {
4018cb93a386Sopenharmony_ci                        drawVisibleOrder(partial, (recordIndex / 2) + 1);
4019cb93a386Sopenharmony_ci                    }
4020cb93a386Sopenharmony_ci                }
4021cb93a386Sopenharmony_ci                var radius = Math.sqrt(minXY) / 2 * scale;
4022cb93a386Sopenharmony_ci                radius = Math.min(50, radius);
4023cb93a386Sopenharmony_ci                var scaledRadius = radius / scale;
4024cb93a386Sopenharmony_ci                var centerX = partial[0];
4025cb93a386Sopenharmony_ci                var centerY = partial[1];
4026cb93a386Sopenharmony_ci                if (collect_bounds) {
4027cb93a386Sopenharmony_ci                    if (focus_enabled) {
4028cb93a386Sopenharmony_ci                        focusXmin = Math.min(focusXmin, centerX - scaledRadius);
4029cb93a386Sopenharmony_ci                        focusYmin = Math.min(focusYmin, centerY - scaledRadius);
4030cb93a386Sopenharmony_ci                        focusXmax = Math.max(focusXmax, centerX + scaledRadius);
4031cb93a386Sopenharmony_ci                        focusYmax = Math.max(focusYmax, centerY + scaledRadius);
4032cb93a386Sopenharmony_ci                    }
4033cb93a386Sopenharmony_ci                    break;
4034cb93a386Sopenharmony_ci                }
4035cb93a386Sopenharmony_ci                break;
4036cb93a386Sopenharmony_ci            default:
4037cb93a386Sopenharmony_ci                break;
4038cb93a386Sopenharmony_ci        }
4039cb93a386Sopenharmony_ci    }
4040cb93a386Sopenharmony_ci    if (collect_bounds) {
4041cb93a386Sopenharmony_ci        return;
4042cb93a386Sopenharmony_ci    }
4043cb93a386Sopenharmony_ci    if (draw_log && logStart >= 0) {
4044cb93a386Sopenharmony_ci        ctx.font = "normal 10px Arial";
4045cb93a386Sopenharmony_ci        ctx.textAlign = "left";
4046cb93a386Sopenharmony_ci        ctx.beginPath();
4047cb93a386Sopenharmony_ci        var top = screenHeight - 20 - (logRange + 2) * 10;
4048cb93a386Sopenharmony_ci        ctx.rect(50, top, screenWidth - 100, (logRange + 2) * 10);
4049cb93a386Sopenharmony_ci        ctx.fillStyle = "white";
4050cb93a386Sopenharmony_ci        ctx.fill();
4051cb93a386Sopenharmony_ci        ctx.fillStyle = "rgba(0,0,0, 0.5)";
4052cb93a386Sopenharmony_ci        if (logStart > 0) {
4053cb93a386Sopenharmony_ci            ctx.fillText(lines[logStart - 1], 50, top + 8);
4054cb93a386Sopenharmony_ci        }
4055cb93a386Sopenharmony_ci        ctx.fillStyle = "black";
4056cb93a386Sopenharmony_ci        for (var idx = 0; idx < logRange; ++idx) {
4057cb93a386Sopenharmony_ci            ctx.fillText(lines[logStart + idx], 50, top + 18 + 10 * idx);
4058cb93a386Sopenharmony_ci        }
4059cb93a386Sopenharmony_ci        ctx.fillStyle = "rgba(0,0,0, 0.5)";
4060cb93a386Sopenharmony_ci        if (logStart + logRange < lines.length) {
4061cb93a386Sopenharmony_ci            ctx.fillText(lines[logStart + logRange], 50, top + 18 + 10 * logRange);
4062cb93a386Sopenharmony_ci        }
4063cb93a386Sopenharmony_ci    }
4064cb93a386Sopenharmony_ci    if (draw_legend) {
4065cb93a386Sopenharmony_ci        var pos = 0;
4066cb93a386Sopenharmony_ci        var drawSomething = draw_add | draw_active | draw_angle | draw_coincidence | draw_sort | draw_mark;
4067cb93a386Sopenharmony_ci   //     drawBox(pos++, "yellow", "black", opLetter, true, '');
4068cb93a386Sopenharmony_ci        drawBox(pos++, "rgba(0,0,255, 0.3)", "black", draw_intersection > 1 ? sectCount : sectMax2, draw_intersection, intersectionKey);
4069cb93a386Sopenharmony_ci        drawBox(pos++, "rgba(0,0,255, 0.3)", "black", draw_add ? addCount : addMax, draw_add, addKey);
4070cb93a386Sopenharmony_ci        drawBox(pos++, "rgba(0,0,255, 0.3)", "black", draw_active ? activeCount : activeMax, draw_active, activeKey);
4071cb93a386Sopenharmony_ci        drawBox(pos++, "rgba(127,127,0, 0.3)", "black", draw_angle ? angleCount : angleMax, draw_angle, angleKey);
4072cb93a386Sopenharmony_ci        drawBox(pos++, "rgba(127,127,0, 0.3)", "black", draw_coincidence ? coinCount : coinMax, draw_coincidence, coincidenceKey);
4073cb93a386Sopenharmony_ci        drawBox(pos++, "rgba(127,127,0, 0.3)", "black", draw_op ? opCount : opMax, draw_op, opKey);
4074cb93a386Sopenharmony_ci        drawBox(pos++, "rgba(127,127,0, 0.3)", "black", draw_sort ? sortCount : sortMax, draw_sort, sortKey);
4075cb93a386Sopenharmony_ci        drawBox(pos++, "rgba(127,127,0, 0.3)", "black", draw_top ? topCount : topMax, draw_top, topKey);
4076cb93a386Sopenharmony_ci        drawBox(pos++, "rgba(127,0,127, 0.3)", "black", draw_mark ? markCount : markMax, draw_mark, markKey);
4077cb93a386Sopenharmony_ci        drawBox(pos++, "black", "white",
4078cb93a386Sopenharmony_ci                (new Array('P', 'P1', 'P2', 'P', 'p', 'p1', 'p2'))[draw_path], draw_path != 0, pathKey);
4079cb93a386Sopenharmony_ci        drawBox(pos++, "rgba(0,63,0, 0.7)", "white",
4080cb93a386Sopenharmony_ci                (new Array('Q', 'Q', 'C', 'QC', 'Qc', 'Cq'))[draw_computed],
4081cb93a386Sopenharmony_ci                draw_computed != 0, computedKey);
4082cb93a386Sopenharmony_ci        drawBox(pos++, "green", "black", step_limit, drawSomething, '');
4083cb93a386Sopenharmony_ci        drawBox(pos++, "green", "black", stepMax, drawSomething, '');
4084cb93a386Sopenharmony_ci        drawBox(pos++, "rgba(255,0,0, 0.6)", "black", lastIndex, drawSomething & draw_log, '');
4085cb93a386Sopenharmony_ci        drawBox(pos++, "rgba(255,0,0, 0.6)", "black", test.length - 1, drawSomething & draw_log, '');
4086cb93a386Sopenharmony_ci        if (curve_t) {
4087cb93a386Sopenharmony_ci            drawCurveTControl();
4088cb93a386Sopenharmony_ci        }
4089cb93a386Sopenharmony_ci        ctx.font = "normal 20px Arial";
4090cb93a386Sopenharmony_ci        ctx.fillStyle = "rgba(0,0,0, 0.3)";
4091cb93a386Sopenharmony_ci        ctx.textAlign = "right";
4092cb93a386Sopenharmony_ci        ctx.fillText(scale.toFixed(decimal_places) + 'x' , screenWidth - 10, screenHeight - 5);
4093cb93a386Sopenharmony_ci    }
4094cb93a386Sopenharmony_ci    if (draw_hints) {
4095cb93a386Sopenharmony_ci        ctx.font = "normal 10px Arial";
4096cb93a386Sopenharmony_ci        ctx.fillStyle = "rgba(0,0,0, 0.5)";
4097cb93a386Sopenharmony_ci        ctx.textAlign = "right";
4098cb93a386Sopenharmony_ci        var y = 4;
4099cb93a386Sopenharmony_ci        ctx.fillText("control lines : " +  controlLinesKey, ctx.screenWidthwidth - 10, pos * 50 + y++ * 10);
4100cb93a386Sopenharmony_ci        ctx.fillText("curve t : " +  curveTKey, screenWidth - 10, pos * 50 + y++ * 10);
4101cb93a386Sopenharmony_ci        ctx.fillText("deriviatives : " +  deriviativesKey, screenWidth - 10, pos * 50 + y++ * 10);
4102cb93a386Sopenharmony_ci        ctx.fillText("intersect t : " +  intersectTKey, screenWidth - 10, pos * 50 + y++ * 10);
4103cb93a386Sopenharmony_ci        ctx.fillText("log : " +  logKey, screenWidth - 10, pos * 50 + y++ * 10);
4104cb93a386Sopenharmony_ci        ctx.fillText("log curve : " +  logCurvesKey, screenWidth - 10, pos * 50 + y++ * 10);
4105cb93a386Sopenharmony_ci        ctx.fillText("mid point : " +  midpointKey, screenWidth - 10, pos * 50 + y++ * 10);
4106cb93a386Sopenharmony_ci        ctx.fillText("points : " +  ptsKey, screenWidth - 10, pos * 50 + y++ * 10);
4107cb93a386Sopenharmony_ci        ctx.fillText("sequence : " +  sequenceKey, screenWidth - 10, pos * 50 + y++ * 10);
4108cb93a386Sopenharmony_ci        ctx.fillText("xy : " +  xyKey, screenWidth - 10, pos * 50 + y++ * 10);
4109cb93a386Sopenharmony_ci    }
4110cb93a386Sopenharmony_ci}
4111cb93a386Sopenharmony_ci
4112cb93a386Sopenharmony_cifunction drawBox(y, backC, foreC, str, enable, label) {
4113cb93a386Sopenharmony_ci    ctx.beginPath();
4114cb93a386Sopenharmony_ci    ctx.fillStyle = backC;
4115cb93a386Sopenharmony_ci    ctx.rect(screenWidth - 40, y * 50 + 10, 40, 30);
4116cb93a386Sopenharmony_ci    ctx.fill();
4117cb93a386Sopenharmony_ci    ctx.font = "normal 16px Arial";
4118cb93a386Sopenharmony_ci    ctx.fillStyle = foreC;
4119cb93a386Sopenharmony_ci    ctx.textAlign = "center";
4120cb93a386Sopenharmony_ci    ctx.fillText(str, screenWidth - 20, y * 50 + 32);
4121cb93a386Sopenharmony_ci    if (!enable) {
4122cb93a386Sopenharmony_ci        ctx.fillStyle = "rgba(255,255,255, 0.5)";
4123cb93a386Sopenharmony_ci        ctx.fill();
4124cb93a386Sopenharmony_ci    }
4125cb93a386Sopenharmony_ci    if (label != '') {
4126cb93a386Sopenharmony_ci        ctx.font = "normal 9px Arial";
4127cb93a386Sopenharmony_ci        ctx.fillStyle = "black";
4128cb93a386Sopenharmony_ci        ctx.fillText(label, screenWidth - 47, y * 50 + 40);
4129cb93a386Sopenharmony_ci    }
4130cb93a386Sopenharmony_ci}
4131cb93a386Sopenharmony_ci
4132cb93a386Sopenharmony_cifunction drawCurveTControl() {
4133cb93a386Sopenharmony_ci    ctx.lineWidth = 2;
4134cb93a386Sopenharmony_ci    ctx.strokeStyle = "rgba(0,0,0, 0.3)";
4135cb93a386Sopenharmony_ci    ctx.beginPath();
4136cb93a386Sopenharmony_ci    ctx.rect(screenWidth - 80, 40, 28, screenHeight - 80);
4137cb93a386Sopenharmony_ci    ctx.stroke();
4138cb93a386Sopenharmony_ci    var ty = 40 + curveT * (screenHeight - 80);
4139cb93a386Sopenharmony_ci    ctx.beginPath();
4140cb93a386Sopenharmony_ci    ctx.moveTo(screenWidth - 80, ty);
4141cb93a386Sopenharmony_ci    ctx.lineTo(screenWidth - 85, ty - 5);
4142cb93a386Sopenharmony_ci    ctx.lineTo(screenWidth - 85, ty + 5);
4143cb93a386Sopenharmony_ci    ctx.lineTo(screenWidth - 80, ty);
4144cb93a386Sopenharmony_ci    ctx.fillStyle = "rgba(0,0,0, 0.6)";
4145cb93a386Sopenharmony_ci    ctx.fill();
4146cb93a386Sopenharmony_ci    var num = curveT.toFixed(decimal_places);
4147cb93a386Sopenharmony_ci    ctx.font = "normal 10px Arial";
4148cb93a386Sopenharmony_ci    ctx.textAlign = "left";
4149cb93a386Sopenharmony_ci    ctx.fillText(num, screenWidth - 78, ty);
4150cb93a386Sopenharmony_ci}
4151cb93a386Sopenharmony_ci
4152cb93a386Sopenharmony_cifunction ptInTControl() {
4153cb93a386Sopenharmony_ci    var e = window.event;
4154cb93a386Sopenharmony_ci    var tgt = e.target || e.srcElement;
4155cb93a386Sopenharmony_ci    var left = tgt.offsetLeft;
4156cb93a386Sopenharmony_ci    var top = tgt.offsetTop;
4157cb93a386Sopenharmony_ci    var x = (e.clientX - left);
4158cb93a386Sopenharmony_ci    var y = (e.clientY - top);
4159cb93a386Sopenharmony_ci    if (x < screenWidth - 80 || x > screenWidth - 50) {
4160cb93a386Sopenharmony_ci        return false;
4161cb93a386Sopenharmony_ci    }
4162cb93a386Sopenharmony_ci    if (y < 40 || y > screenHeight - 80) {
4163cb93a386Sopenharmony_ci        return false;
4164cb93a386Sopenharmony_ci    }
4165cb93a386Sopenharmony_ci    curveT = (y - 40) / (screenHeight - 120);
4166cb93a386Sopenharmony_ci    if (curveT < 0 || curveT > 1) {
4167cb93a386Sopenharmony_ci        throw "stop execution";
4168cb93a386Sopenharmony_ci    }
4169cb93a386Sopenharmony_ci    return true;
4170cb93a386Sopenharmony_ci}
4171cb93a386Sopenharmony_ci
4172cb93a386Sopenharmony_cifunction drawTop() {
4173cb93a386Sopenharmony_ci    if (tests[testIndex] == null) {
4174cb93a386Sopenharmony_ci        var str = testDivs[testIndex].textContent;
4175cb93a386Sopenharmony_ci        parse_all(str);
4176cb93a386Sopenharmony_ci        var title = testDivs[testIndex].id.toString();
4177cb93a386Sopenharmony_ci        testTitles[testIndex] = title;
4178cb93a386Sopenharmony_ci    }
4179cb93a386Sopenharmony_ci    init(tests[testIndex]);
4180cb93a386Sopenharmony_ci    redraw();
4181cb93a386Sopenharmony_ci}
4182cb93a386Sopenharmony_ci
4183cb93a386Sopenharmony_cifunction redraw() {
4184cb93a386Sopenharmony_ci    if (focus_on_selection) {
4185cb93a386Sopenharmony_ci        collect_bounds = true;
4186cb93a386Sopenharmony_ci        draw(tests[testIndex], testLines[testIndex], testTitles[testIndex]);
4187cb93a386Sopenharmony_ci        collect_bounds = false;
4188cb93a386Sopenharmony_ci        if (focusXmin < focusXmax && focusYmin < focusYmax) {
4189cb93a386Sopenharmony_ci            setScale(focusXmin, focusXmax, focusYmin, focusYmax);
4190cb93a386Sopenharmony_ci        }
4191cb93a386Sopenharmony_ci    }
4192cb93a386Sopenharmony_ci    ctx.beginPath();
4193cb93a386Sopenharmony_ci    ctx.fillStyle = "white";
4194cb93a386Sopenharmony_ci    ctx.rect(0, 0, screenWidth, screenHeight);
4195cb93a386Sopenharmony_ci    ctx.fill();
4196cb93a386Sopenharmony_ci    draw(tests[testIndex], testLines[testIndex], testTitles[testIndex]);
4197cb93a386Sopenharmony_ci}
4198cb93a386Sopenharmony_ci
4199cb93a386Sopenharmony_cifunction dumpCurvePartial(test, id, t0, t1) {
4200cb93a386Sopenharmony_ci    var curve = curveByID(test, id);
4201cb93a386Sopenharmony_ci    var name = ["line", "quad", "cubic"][curve.length / 2 - 2];
4202cb93a386Sopenharmony_ci    console.log("id=" + id + " " + name + "=" +  curveToString(curve)
4203cb93a386Sopenharmony_ci        + " t0=" + t0 + " t1=" + t1
4204cb93a386Sopenharmony_ci        + " partial=" + curveToString(curvePartialByID(test, id, t0, t1)));
4205cb93a386Sopenharmony_ci}
4206cb93a386Sopenharmony_ci
4207cb93a386Sopenharmony_cifunction dumpAngleTest(test, id, t0, t1) {
4208cb93a386Sopenharmony_ci    var curve = curveByID(test, id);
4209cb93a386Sopenharmony_ci    console.log("    { {" + curveToString(curve) + "}, "
4210cb93a386Sopenharmony_ci            + curve.length / 2 + ", " + t0 + ", " + t1 + ", {} }, //");
4211cb93a386Sopenharmony_ci}
4212cb93a386Sopenharmony_ci
4213cb93a386Sopenharmony_cifunction dumpLogToConsole() {
4214cb93a386Sopenharmony_ci    if (logStart < 0) {
4215cb93a386Sopenharmony_ci        return;
4216cb93a386Sopenharmony_ci    }
4217cb93a386Sopenharmony_ci    var test = tests[testIndex];
4218cb93a386Sopenharmony_ci    var recType = REC_TYPE_UNKNOWN;
4219cb93a386Sopenharmony_ci    var records;
4220cb93a386Sopenharmony_ci    for (var index = 0; index < test.length; index += 3) {
4221cb93a386Sopenharmony_ci        var lastLineNo = test[index + 1];
4222cb93a386Sopenharmony_ci        if (lastLineNo >= logStart && lastLineNo < logStart + logRange) {
4223cb93a386Sopenharmony_ci            recType = test[index];
4224cb93a386Sopenharmony_ci            records = test[index + 2];
4225cb93a386Sopenharmony_ci            break;
4226cb93a386Sopenharmony_ci        }
4227cb93a386Sopenharmony_ci    }
4228cb93a386Sopenharmony_ci    if (recType == REC_TYPE_UNKNOWN) {
4229cb93a386Sopenharmony_ci        return;
4230cb93a386Sopenharmony_ci    }
4231cb93a386Sopenharmony_ci    var lines = testLines[testIndex];
4232cb93a386Sopenharmony_ci    for (var idx = 0; idx < logRange; ++idx) {
4233cb93a386Sopenharmony_ci        var line = lines[logStart + idx];
4234cb93a386Sopenharmony_ci        console.log(line);
4235cb93a386Sopenharmony_ci        for (var recordIndex = 0; recordIndex < records.length; recordIndex += 2) {
4236cb93a386Sopenharmony_ci            var fragType = records[recordIndex];
4237cb93a386Sopenharmony_ci            var frags = records[recordIndex + 1];
4238cb93a386Sopenharmony_ci            if (recType == REC_TYPE_ANGLE && fragType == ANGLE_AFTER) {
4239cb93a386Sopenharmony_ci                dumpCurvePartial(test, frags[0], frags[4], frags[5]);
4240cb93a386Sopenharmony_ci                dumpCurvePartial(test, frags[6], frags[10], frags[11]);
4241cb93a386Sopenharmony_ci                dumpCurvePartial(test, frags[12], frags[16], frags[17]);
4242cb93a386Sopenharmony_ci                console.log("\nstatic IntersectData intersectDataSet[] = { //");
4243cb93a386Sopenharmony_ci                dumpAngleTest(test, frags[0], frags[4], frags[5]);
4244cb93a386Sopenharmony_ci                dumpAngleTest(test, frags[6], frags[10], frags[11]);
4245cb93a386Sopenharmony_ci                dumpAngleTest(test, frags[12], frags[16], frags[17]);
4246cb93a386Sopenharmony_ci                console.log("}; //");
4247cb93a386Sopenharmony_ci            }
4248cb93a386Sopenharmony_ci        }
4249cb93a386Sopenharmony_ci    }
4250cb93a386Sopenharmony_ci}
4251cb93a386Sopenharmony_ci
4252cb93a386Sopenharmony_civar activeKey = 'a';
4253cb93a386Sopenharmony_civar pathKey = 'b';
4254cb93a386Sopenharmony_civar pathBackKey = 'B';
4255cb93a386Sopenharmony_civar centerKey = 'c';
4256cb93a386Sopenharmony_civar coincidenceKey = 'C';
4257cb93a386Sopenharmony_civar addKey = 'd';
4258cb93a386Sopenharmony_civar deriviativesKey = 'f';
4259cb93a386Sopenharmony_civar angleKey = 'g';
4260cb93a386Sopenharmony_civar angleBackKey = 'G';
4261cb93a386Sopenharmony_civar intersectionKey = 'i';
4262cb93a386Sopenharmony_civar intersectionBackKey = 'I';
4263cb93a386Sopenharmony_civar sequenceKey = 'j';
4264cb93a386Sopenharmony_civar midpointKey = 'k';
4265cb93a386Sopenharmony_civar logKey = 'l';
4266cb93a386Sopenharmony_civar logToConsoleKey = 'L';
4267cb93a386Sopenharmony_civar markKey = 'm';
4268cb93a386Sopenharmony_civar sortKey = 'o';
4269cb93a386Sopenharmony_civar opKey = 'p';
4270cb93a386Sopenharmony_civar opBackKey = 'P';
4271cb93a386Sopenharmony_civar computedKey = 'q';
4272cb93a386Sopenharmony_civar computedBackKey = 'Q';
4273cb93a386Sopenharmony_civar directionKey = 'r';
4274cb93a386Sopenharmony_civar stepKey = 's';
4275cb93a386Sopenharmony_civar stepBackKey = 'S';
4276cb93a386Sopenharmony_civar intersectTKey = 't';
4277cb93a386Sopenharmony_civar topKey = 'T';
4278cb93a386Sopenharmony_civar curveTKey = 'u';
4279cb93a386Sopenharmony_civar controlLinesBackKey = 'V';
4280cb93a386Sopenharmony_civar controlLinesKey = 'v';
4281cb93a386Sopenharmony_civar ptsKey = 'x';
4282cb93a386Sopenharmony_civar xyKey = 'y';
4283cb93a386Sopenharmony_civar logCurvesKey = 'z';
4284cb93a386Sopenharmony_civar focusKey = '`';
4285cb93a386Sopenharmony_civar idKey = '.';
4286cb93a386Sopenharmony_civar retinaKey = '\\';
4287cb93a386Sopenharmony_ci
4288cb93a386Sopenharmony_cifunction doKeyPress(evt) {
4289cb93a386Sopenharmony_ci    var char = String.fromCharCode(evt.charCode);
4290cb93a386Sopenharmony_ci    var focusWasOn = false;
4291cb93a386Sopenharmony_ci    switch (char) {
4292cb93a386Sopenharmony_ci    case '0':
4293cb93a386Sopenharmony_ci    case '1':
4294cb93a386Sopenharmony_ci    case '2':
4295cb93a386Sopenharmony_ci    case '3':
4296cb93a386Sopenharmony_ci    case '4':
4297cb93a386Sopenharmony_ci    case '5':
4298cb93a386Sopenharmony_ci    case '6':
4299cb93a386Sopenharmony_ci    case '7':
4300cb93a386Sopenharmony_ci    case '8':
4301cb93a386Sopenharmony_ci    case '9':
4302cb93a386Sopenharmony_ci        decimal_places = char - '0';
4303cb93a386Sopenharmony_ci        redraw();
4304cb93a386Sopenharmony_ci        break;
4305cb93a386Sopenharmony_ci    case activeKey:
4306cb93a386Sopenharmony_ci        draw_active ^= true;
4307cb93a386Sopenharmony_ci        redraw();
4308cb93a386Sopenharmony_ci        break;
4309cb93a386Sopenharmony_ci    case addKey:
4310cb93a386Sopenharmony_ci        draw_add ^= true;
4311cb93a386Sopenharmony_ci        redraw();
4312cb93a386Sopenharmony_ci        break;
4313cb93a386Sopenharmony_ci    case angleKey:
4314cb93a386Sopenharmony_ci        draw_angle = (draw_angle + 1) % 4;
4315cb93a386Sopenharmony_ci        redraw();
4316cb93a386Sopenharmony_ci        break;
4317cb93a386Sopenharmony_ci    case angleBackKey:
4318cb93a386Sopenharmony_ci        draw_angle = (draw_angle + 2) % 3;
4319cb93a386Sopenharmony_ci        redraw();
4320cb93a386Sopenharmony_ci        break;
4321cb93a386Sopenharmony_ci    case centerKey:
4322cb93a386Sopenharmony_ci        setScale(xmin, xmax, ymin, ymax);
4323cb93a386Sopenharmony_ci        redraw();
4324cb93a386Sopenharmony_ci        break;
4325cb93a386Sopenharmony_ci    case coincidenceKey:
4326cb93a386Sopenharmony_ci        draw_coincidence ^= true;
4327cb93a386Sopenharmony_ci        redraw();
4328cb93a386Sopenharmony_ci        break;
4329cb93a386Sopenharmony_ci    case controlLinesBackKey:
4330cb93a386Sopenharmony_ci        control_lines = (control_lines + 3) % 4;
4331cb93a386Sopenharmony_ci        redraw();
4332cb93a386Sopenharmony_ci        break;
4333cb93a386Sopenharmony_ci    case controlLinesKey:
4334cb93a386Sopenharmony_ci        control_lines = (control_lines + 1) % 4;
4335cb93a386Sopenharmony_ci        redraw();
4336cb93a386Sopenharmony_ci        break;
4337cb93a386Sopenharmony_ci    case computedBackKey:
4338cb93a386Sopenharmony_ci        draw_computed = (draw_computed + 5) % 6;
4339cb93a386Sopenharmony_ci        redraw();
4340cb93a386Sopenharmony_ci        break;
4341cb93a386Sopenharmony_ci    case computedKey:
4342cb93a386Sopenharmony_ci        draw_computed = (draw_computed + 1) % 6;
4343cb93a386Sopenharmony_ci        redraw();
4344cb93a386Sopenharmony_ci        break;
4345cb93a386Sopenharmony_ci    case curveTKey:
4346cb93a386Sopenharmony_ci        curve_t ^= true;
4347cb93a386Sopenharmony_ci        if (curve_t) {
4348cb93a386Sopenharmony_ci            draw_legend = true;
4349cb93a386Sopenharmony_ci        }
4350cb93a386Sopenharmony_ci        redraw();
4351cb93a386Sopenharmony_ci        break;
4352cb93a386Sopenharmony_ci    case deriviativesKey:
4353cb93a386Sopenharmony_ci        draw_deriviatives = (draw_deriviatives + 1) % 3;
4354cb93a386Sopenharmony_ci        redraw();
4355cb93a386Sopenharmony_ci        break;
4356cb93a386Sopenharmony_ci    case directionKey:
4357cb93a386Sopenharmony_ci        draw_direction ^= true;
4358cb93a386Sopenharmony_ci        redraw();
4359cb93a386Sopenharmony_ci        break;
4360cb93a386Sopenharmony_ci    case focusKey:
4361cb93a386Sopenharmony_ci        focus_on_selection ^= true;
4362cb93a386Sopenharmony_ci        setScale(xmin, xmax, ymin, ymax);
4363cb93a386Sopenharmony_ci        redraw();
4364cb93a386Sopenharmony_ci        break;
4365cb93a386Sopenharmony_ci    case idKey:
4366cb93a386Sopenharmony_ci        draw_id ^= true;
4367cb93a386Sopenharmony_ci        redraw();
4368cb93a386Sopenharmony_ci        break;
4369cb93a386Sopenharmony_ci    case intersectionBackKey:
4370cb93a386Sopenharmony_ci        draw_intersection = (draw_intersection + 3) % 4;
4371cb93a386Sopenharmony_ci        redraw();
4372cb93a386Sopenharmony_ci        break;
4373cb93a386Sopenharmony_ci    case intersectionKey:
4374cb93a386Sopenharmony_ci        draw_intersection = (draw_intersection + 1) % 4;
4375cb93a386Sopenharmony_ci        redraw();
4376cb93a386Sopenharmony_ci        break;
4377cb93a386Sopenharmony_ci    case intersectTKey:
4378cb93a386Sopenharmony_ci        draw_intersectT ^= true;
4379cb93a386Sopenharmony_ci        redraw();
4380cb93a386Sopenharmony_ci        break;
4381cb93a386Sopenharmony_ci    case logCurvesKey:
4382cb93a386Sopenharmony_ci        logCurves(tests[testIndex]);
4383cb93a386Sopenharmony_ci        break;
4384cb93a386Sopenharmony_ci    case logKey:
4385cb93a386Sopenharmony_ci        draw_log ^= true;
4386cb93a386Sopenharmony_ci        redraw();
4387cb93a386Sopenharmony_ci        break;
4388cb93a386Sopenharmony_ci    case logToConsoleKey:
4389cb93a386Sopenharmony_ci        if (draw_log) {
4390cb93a386Sopenharmony_ci            dumpLogToConsole();
4391cb93a386Sopenharmony_ci        }
4392cb93a386Sopenharmony_ci        break;
4393cb93a386Sopenharmony_ci    case markKey:
4394cb93a386Sopenharmony_ci        draw_mark ^= true;
4395cb93a386Sopenharmony_ci        redraw();
4396cb93a386Sopenharmony_ci        break;
4397cb93a386Sopenharmony_ci    case midpointKey:
4398cb93a386Sopenharmony_ci        draw_midpoint ^= true;
4399cb93a386Sopenharmony_ci        redraw();
4400cb93a386Sopenharmony_ci        break;
4401cb93a386Sopenharmony_ci    case opKey:
4402cb93a386Sopenharmony_ci        draw_op = (draw_op + 1) % 3;
4403cb93a386Sopenharmony_ci        redraw();
4404cb93a386Sopenharmony_ci        break;
4405cb93a386Sopenharmony_ci    case opBackKey:
4406cb93a386Sopenharmony_ci        draw_op = (draw_op + 2) % 3;
4407cb93a386Sopenharmony_ci        redraw();
4408cb93a386Sopenharmony_ci        break;
4409cb93a386Sopenharmony_ci    case pathKey:
4410cb93a386Sopenharmony_ci        draw_path = (draw_path + 1) % (4 + (hasAlignedPath ? 3 : 0));
4411cb93a386Sopenharmony_ci        redraw();
4412cb93a386Sopenharmony_ci        break;
4413cb93a386Sopenharmony_ci    case pathBackKey:
4414cb93a386Sopenharmony_ci        draw_path = (draw_path + 3 + (hasAlignedPath ? 3 : 0)) % (4 + (hasAlignedPath ? 3 : 0));
4415cb93a386Sopenharmony_ci        redraw();
4416cb93a386Sopenharmony_ci        break;
4417cb93a386Sopenharmony_ci    case ptsKey:
4418cb93a386Sopenharmony_ci        pt_labels = (pt_labels + 1) % 3;
4419cb93a386Sopenharmony_ci        redraw();
4420cb93a386Sopenharmony_ci        break;
4421cb93a386Sopenharmony_ci    case retinaKey:
4422cb93a386Sopenharmony_ci        retina_scale ^= true;
4423cb93a386Sopenharmony_ci        drawTop();
4424cb93a386Sopenharmony_ci        break;
4425cb93a386Sopenharmony_ci    case sequenceKey:
4426cb93a386Sopenharmony_ci        draw_sequence ^= true;
4427cb93a386Sopenharmony_ci        redraw();
4428cb93a386Sopenharmony_ci        break;
4429cb93a386Sopenharmony_ci    case sortKey:
4430cb93a386Sopenharmony_ci        draw_sort = (draw_sort + 1) % 3;
4431cb93a386Sopenharmony_ci        drawTop();
4432cb93a386Sopenharmony_ci        break;
4433cb93a386Sopenharmony_ci    case stepKey:
4434cb93a386Sopenharmony_ci        step_limit++;
4435cb93a386Sopenharmony_ci        if (step_limit > stepMax) {
4436cb93a386Sopenharmony_ci            step_limit = stepMax;
4437cb93a386Sopenharmony_ci        }
4438cb93a386Sopenharmony_ci        redraw();
4439cb93a386Sopenharmony_ci        break;
4440cb93a386Sopenharmony_ci    case stepBackKey:
4441cb93a386Sopenharmony_ci        step_limit--;
4442cb93a386Sopenharmony_ci        if (step_limit < 0) {
4443cb93a386Sopenharmony_ci            step_limit = 0;
4444cb93a386Sopenharmony_ci        }
4445cb93a386Sopenharmony_ci        redraw();
4446cb93a386Sopenharmony_ci        break;
4447cb93a386Sopenharmony_ci    case topKey:
4448cb93a386Sopenharmony_ci        draw_top ^= true;
4449cb93a386Sopenharmony_ci        redraw();
4450cb93a386Sopenharmony_ci        break;
4451cb93a386Sopenharmony_ci    case xyKey:
4452cb93a386Sopenharmony_ci        debug_xy = (debug_xy + 1) % 3;
4453cb93a386Sopenharmony_ci        redraw();
4454cb93a386Sopenharmony_ci        break;
4455cb93a386Sopenharmony_ci    case '-':
4456cb93a386Sopenharmony_ci        focusWasOn = focus_on_selection;
4457cb93a386Sopenharmony_ci        if (focusWasOn) {
4458cb93a386Sopenharmony_ci            focus_on_selection = false;
4459cb93a386Sopenharmony_ci            scale /= 1.2;
4460cb93a386Sopenharmony_ci        } else {
4461cb93a386Sopenharmony_ci            scale /= 2;
4462cb93a386Sopenharmony_ci            calcLeftTop();
4463cb93a386Sopenharmony_ci        }
4464cb93a386Sopenharmony_ci        redraw();
4465cb93a386Sopenharmony_ci        focus_on_selection = focusWasOn;
4466cb93a386Sopenharmony_ci        break;
4467cb93a386Sopenharmony_ci    case '=':
4468cb93a386Sopenharmony_ci    case '+':
4469cb93a386Sopenharmony_ci        focusWasOn = focus_on_selection;
4470cb93a386Sopenharmony_ci        if (focusWasOn) {
4471cb93a386Sopenharmony_ci            focus_on_selection = false;
4472cb93a386Sopenharmony_ci            scale *= 1.2;
4473cb93a386Sopenharmony_ci        } else {
4474cb93a386Sopenharmony_ci            scale *= 2;
4475cb93a386Sopenharmony_ci            calcLeftTop();
4476cb93a386Sopenharmony_ci        }
4477cb93a386Sopenharmony_ci        redraw();
4478cb93a386Sopenharmony_ci        focus_on_selection = focusWasOn;
4479cb93a386Sopenharmony_ci        break;
4480cb93a386Sopenharmony_ci    case '?':
4481cb93a386Sopenharmony_ci        draw_hints ^= true;
4482cb93a386Sopenharmony_ci        if (draw_hints && !draw_legend) {
4483cb93a386Sopenharmony_ci            draw_legend = true;
4484cb93a386Sopenharmony_ci        }
4485cb93a386Sopenharmony_ci        redraw();
4486cb93a386Sopenharmony_ci        break;
4487cb93a386Sopenharmony_ci    case '/':
4488cb93a386Sopenharmony_ci        draw_legend ^= true;
4489cb93a386Sopenharmony_ci        redraw();
4490cb93a386Sopenharmony_ci        break;
4491cb93a386Sopenharmony_ci    }
4492cb93a386Sopenharmony_ci}
4493cb93a386Sopenharmony_ci
4494cb93a386Sopenharmony_cifunction doKeyDown(evt) {
4495cb93a386Sopenharmony_ci    var char = evt.keyCode;
4496cb93a386Sopenharmony_ci    var preventDefault = false;
4497cb93a386Sopenharmony_ci    switch (char) {
4498cb93a386Sopenharmony_ci    case 37: // left arrow
4499cb93a386Sopenharmony_ci        if (evt.shiftKey) {
4500cb93a386Sopenharmony_ci            testIndex -= 9;
4501cb93a386Sopenharmony_ci        }
4502cb93a386Sopenharmony_ci        if (--testIndex < 0)
4503cb93a386Sopenharmony_ci            testIndex = tests.length - 1;
4504cb93a386Sopenharmony_ci        drawTop();
4505cb93a386Sopenharmony_ci        preventDefault = true;
4506cb93a386Sopenharmony_ci        break;
4507cb93a386Sopenharmony_ci    case 39: // right arrow
4508cb93a386Sopenharmony_ci        if (evt.shiftKey) {
4509cb93a386Sopenharmony_ci            testIndex += 9;
4510cb93a386Sopenharmony_ci        }
4511cb93a386Sopenharmony_ci        if (++testIndex >= tests.length)
4512cb93a386Sopenharmony_ci            testIndex = 0;
4513cb93a386Sopenharmony_ci        drawTop();
4514cb93a386Sopenharmony_ci        preventDefault = true;
4515cb93a386Sopenharmony_ci        break;
4516cb93a386Sopenharmony_ci    }
4517cb93a386Sopenharmony_ci    if (preventDefault) {
4518cb93a386Sopenharmony_ci          evt.preventDefault();
4519cb93a386Sopenharmony_ci          return false;
4520cb93a386Sopenharmony_ci    }
4521cb93a386Sopenharmony_ci    return true;
4522cb93a386Sopenharmony_ci}
4523cb93a386Sopenharmony_ci
4524cb93a386Sopenharmony_ci(function() {
4525cb93a386Sopenharmony_ci    var hidden = "hidden";
4526cb93a386Sopenharmony_ci
4527cb93a386Sopenharmony_ci    // Standards:
4528cb93a386Sopenharmony_ci    if (hidden in document)
4529cb93a386Sopenharmony_ci        document.addEventListener("visibilitychange", onchange);
4530cb93a386Sopenharmony_ci    else if ((hidden = "mozHidden") in document)
4531cb93a386Sopenharmony_ci        document.addEventListener("mozvisibilitychange", onchange);
4532cb93a386Sopenharmony_ci    else if ((hidden = "webkitHidden") in document)
4533cb93a386Sopenharmony_ci        document.addEventListener("webkitvisibilitychange", onchange);
4534cb93a386Sopenharmony_ci    else if ((hidden = "msHidden") in document)
4535cb93a386Sopenharmony_ci        document.addEventListener("msvisibilitychange", onchange);
4536cb93a386Sopenharmony_ci    // IE 9 and lower:
4537cb93a386Sopenharmony_ci    else if ('onfocusin' in document)
4538cb93a386Sopenharmony_ci        document.onfocusin = document.onfocusout = onchange;
4539cb93a386Sopenharmony_ci    // All others:
4540cb93a386Sopenharmony_ci    else
4541cb93a386Sopenharmony_ci        window.onpageshow = window.onpagehide
4542cb93a386Sopenharmony_ci            = window.onfocus = window.onblur = onchange;
4543cb93a386Sopenharmony_ci
4544cb93a386Sopenharmony_ci    function onchange (evt) {
4545cb93a386Sopenharmony_ci        var v = 'visible', h = 'hidden',
4546cb93a386Sopenharmony_ci            evtMap = {
4547cb93a386Sopenharmony_ci                focus:v, focusin:v, pageshow:v, blur:h, focusout:h, pagehide:h
4548cb93a386Sopenharmony_ci            };
4549cb93a386Sopenharmony_ci
4550cb93a386Sopenharmony_ci        evt = evt || window.event;
4551cb93a386Sopenharmony_ci        if (evt.type in evtMap)
4552cb93a386Sopenharmony_ci            document.body.className = evtMap[evt.type];
4553cb93a386Sopenharmony_ci        else
4554cb93a386Sopenharmony_ci            document.body.className = this[hidden] ? "hidden" : "visible";
4555cb93a386Sopenharmony_ci    }
4556cb93a386Sopenharmony_ci})();
4557cb93a386Sopenharmony_ci
4558cb93a386Sopenharmony_cifunction calcXY() {
4559cb93a386Sopenharmony_ci    var e = window.event;
4560cb93a386Sopenharmony_ci    var tgt = e.target || e.srcElement;
4561cb93a386Sopenharmony_ci    var left = tgt.offsetLeft;
4562cb93a386Sopenharmony_ci    var top = tgt.offsetTop;
4563cb93a386Sopenharmony_ci    mouseX = (e.clientX - left) / scale + srcLeft;
4564cb93a386Sopenharmony_ci    mouseY = (e.clientY - top) / scale + srcTop;
4565cb93a386Sopenharmony_ci}
4566cb93a386Sopenharmony_ci
4567cb93a386Sopenharmony_cifunction calcLeftTop() {
4568cb93a386Sopenharmony_ci    srcLeft = mouseX - screenWidth / 2 / scale;
4569cb93a386Sopenharmony_ci    srcTop = mouseY - screenHeight / 2 / scale;
4570cb93a386Sopenharmony_ci}
4571cb93a386Sopenharmony_ci
4572cb93a386Sopenharmony_civar disableClick = false;
4573cb93a386Sopenharmony_ci
4574cb93a386Sopenharmony_cifunction handleMouseClick() {
4575cb93a386Sopenharmony_ci    if (disableClick) {
4576cb93a386Sopenharmony_ci        return;
4577cb93a386Sopenharmony_ci    }
4578cb93a386Sopenharmony_ci    if (!curve_t || !ptInTControl()) {
4579cb93a386Sopenharmony_ci        calcXY();
4580cb93a386Sopenharmony_ci        calcLeftTop();
4581cb93a386Sopenharmony_ci    }
4582cb93a386Sopenharmony_ci    redraw();
4583cb93a386Sopenharmony_ci//    if (!curve_t || !ptInTControl()) {
4584cb93a386Sopenharmony_ci//        mouseX = screenWidth / 2 / scale + srcLeft;
4585cb93a386Sopenharmony_ci//        mouseY = screenHeight / 2 / scale + srcTop;
4586cb93a386Sopenharmony_ci//    }
4587cb93a386Sopenharmony_ci}
4588cb93a386Sopenharmony_ci
4589cb93a386Sopenharmony_cifunction handleMouseOver() {
4590cb93a386Sopenharmony_ci    calcXY();
4591cb93a386Sopenharmony_ci    if (debug_xy != 2) {
4592cb93a386Sopenharmony_ci        return;
4593cb93a386Sopenharmony_ci    }
4594cb93a386Sopenharmony_ci    var num = mouseX.toFixed(decimal_places) + ", " + mouseY.toFixed(decimal_places);
4595cb93a386Sopenharmony_ci    ctx.beginPath();
4596cb93a386Sopenharmony_ci    ctx.rect(300,100,num.length * 6,10);
4597cb93a386Sopenharmony_ci    ctx.fillStyle="white";
4598cb93a386Sopenharmony_ci    ctx.fill();
4599cb93a386Sopenharmony_ci    ctx.font = "normal 10px Arial";
4600cb93a386Sopenharmony_ci    ctx.fillStyle="black";
4601cb93a386Sopenharmony_ci    ctx.textAlign = "left";
4602cb93a386Sopenharmony_ci    ctx.fillText(num, 300, 108);
4603cb93a386Sopenharmony_ci}
4604cb93a386Sopenharmony_ci
4605cb93a386Sopenharmony_cifunction start() {
4606cb93a386Sopenharmony_ci    for (var i = 0; i < testDivs.length; ++i) {
4607cb93a386Sopenharmony_ci        tests[i] = null;
4608cb93a386Sopenharmony_ci    }
4609cb93a386Sopenharmony_ci    testIndex = 0;
4610cb93a386Sopenharmony_ci    drawTop();
4611cb93a386Sopenharmony_ci    window.addEventListener('keypress', doKeyPress, true);
4612cb93a386Sopenharmony_ci    window.addEventListener('keydown', doKeyDown, true);
4613cb93a386Sopenharmony_ci    window.onresize = function() {
4614cb93a386Sopenharmony_ci        drawTop();
4615cb93a386Sopenharmony_ci    }
4616cb93a386Sopenharmony_ci    /*
4617cb93a386Sopenharmony_ci    window.onpagehide = function() {
4618cb93a386Sopenharmony_ci        disableClick = true;
4619cb93a386Sopenharmony_ci    }
4620cb93a386Sopenharmony_ci    */
4621cb93a386Sopenharmony_ci    window.onpageshow = function () {
4622cb93a386Sopenharmony_ci        disableClick = false;
4623cb93a386Sopenharmony_ci    }
4624cb93a386Sopenharmony_ci}
4625cb93a386Sopenharmony_ci
4626cb93a386Sopenharmony_ci</script>
4627cb93a386Sopenharmony_ci</head>
4628cb93a386Sopenharmony_ci
4629cb93a386Sopenharmony_ci<body onLoad="start();">
4630cb93a386Sopenharmony_ci<canvas id="canvas" width="750" height="500"
4631cb93a386Sopenharmony_ci    onmousemove="handleMouseOver()"
4632cb93a386Sopenharmony_ci    onclick="handleMouseClick()"
4633cb93a386Sopenharmony_ci    ></canvas >
4634cb93a386Sopenharmony_ci</body>
4635cb93a386Sopenharmony_ci</html>
4636