Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

674 lines
18 KiB

  1. #include "common.h"
  2. #include "crane.h"
  3. // Convert 0-360 angle to absolute angle from Positive X axis.
  4. __inline int Angle2XAngle(int angle)
  5. {
  6. return angle <= 180 ? angle : 360 - angle;
  7. }
  8. // Convert 0-360 angle to absolute angle from Positive Y axis.
  9. __inline int Angle2YAngle(int angle)
  10. {
  11. // Convert to angle from Y axis.
  12. angle = (angle + 90) % 360;
  13. return Angle2XAngle(angle);
  14. }
  15. // Find scaled perpendiculare distance from stroke (end points) to a point.
  16. // Note that cStroke is the point number of the start of the stroke.
  17. int FindPerpDist(int cStoke, int cPoint, short *pX, short *pY)
  18. {
  19. int dX, dY;
  20. int away;
  21. // Get delta X and delta Y of (end - start of stroke) for our calculations.
  22. dX = pX[cStoke + 1] - pX[cStoke];
  23. dY = pY[cStoke + 1] - pY[cStoke];
  24. // If both dX and dY are 0, force an X distance of 1.
  25. if (dX == 0 && dY == 0) {
  26. dX = 1;
  27. }
  28. // First calculate the away offset.
  29. away = pY[cPoint] * dX - pX[cPoint] * dY;
  30. // Then normalize the offset.
  31. away -= pY[cStoke] * dX - pX[cStoke] * dY;
  32. // Finally normalize the scale.
  33. away *= 1000;
  34. away /= dX * dX + dY * dY;
  35. return away;
  36. }
  37. // Build up a bounding rectangle from a list of bounding rectangles.
  38. void
  39. BuildBoundingBox(RECTS *pRectsOut, RECTS *pRectsList, int first, int last)
  40. {
  41. short x1, x2, y1, y2;
  42. ASSERT (first <= last);
  43. // Always grab the first rect
  44. x1 = pRectsList[first].x1;
  45. x2 = pRectsList[first].x2;
  46. if (x1 <= x2) {
  47. pRectsOut->x1 = x1;
  48. pRectsOut->x2 = x2;
  49. } else {
  50. pRectsOut->x1 = x2;
  51. pRectsOut->x2 = x1;
  52. }
  53. y1 = pRectsList[first].y1;
  54. y2 = pRectsList[first].y2;
  55. if (y1 <= y2) {
  56. pRectsOut->y1 = y1;
  57. pRectsOut->y2 = y2;
  58. } else {
  59. pRectsOut->y1 = y2;
  60. pRectsOut->y2 = y1;
  61. }
  62. // Now add in any additional rects
  63. for (++first ; first <= last; ++first) {
  64. x1 = pRectsList[first].x1;
  65. x2 = pRectsList[first].x2;
  66. if (x1 <= x2) {
  67. if (pRectsOut->x1 > x1) {
  68. pRectsOut->x1 = x1;
  69. }
  70. if (pRectsOut->x2 < x2) {
  71. pRectsOut->x2 = x2;
  72. }
  73. } else {
  74. if (pRectsOut->x1 > x2) {
  75. pRectsOut->x1 = x2;
  76. }
  77. if (pRectsOut->x2 < x1) {
  78. pRectsOut->x2 = x1;
  79. }
  80. }
  81. y1 = pRectsList[first].y1;
  82. y2 = pRectsList[first].y2;
  83. if (y1 <= y2) {
  84. if (pRectsOut->y1 > y1) {
  85. pRectsOut->y1 = y1;
  86. }
  87. if (pRectsOut->y2 < y2) {
  88. pRectsOut->y2 = y2;
  89. }
  90. } else {
  91. if (pRectsOut->y1 > y1) {
  92. pRectsOut->y1 = y1;
  93. }
  94. if (pRectsOut->y2 < y2) {
  95. pRectsOut->y2 = y2;
  96. }
  97. }
  98. }
  99. }
  100. // Answer a question
  101. // Check if the answer to a question on the sample is Greater.
  102. void AnswerQuestion(
  103. WORD questionType, // What type of question, delta X, delta Y current choices
  104. WORD part1, // Question constant part 1
  105. WORD part2, // Question constant part 2
  106. SAMPLE_INFO *pSamples,
  107. int cSamples)
  108. {
  109. int ii;
  110. int deltaX, deltaY;
  111. int cStrokes, cPoints;
  112. short *pByPointsX, *pByPointsY;
  113. END_POINTS *pendX, *pendY;
  114. SAMPLE_INFO *pLimit;
  115. RECTS rects;
  116. cStrokes = pSamples->pSample->cstrk; // All samples have the same stroke count
  117. cPoints = cStrokes * 2;
  118. pLimit = pSamples + cSamples;
  119. switch (questionType)
  120. {
  121. case questionX:
  122. for ( ; pSamples < pLimit; ++pSamples)
  123. {
  124. pSamples->iAnswer = (int) ((short *)(pSamples->pSample->apfeat[FEATURE_XPOS]->data))[part1];
  125. }
  126. break;
  127. case questionY:
  128. for ( ; pSamples < pLimit; ++pSamples)
  129. {
  130. pSamples->iAnswer = (int) ((short *)(pSamples->pSample->apfeat[FEATURE_YPOS]->data))[part1];
  131. }
  132. break;
  133. case questionXDelta:
  134. for ( ; pSamples < pLimit; ++pSamples)
  135. {
  136. pByPointsX = ((short *) pSamples->pSample->apfeat[FEATURE_XPOS]->data);
  137. pSamples->iAnswer = (int) pByPointsX[part1] - (int) pByPointsX[part2];
  138. }
  139. break;
  140. case questionYDelta:
  141. for ( ; pSamples < pLimit; ++pSamples)
  142. {
  143. pByPointsY = ((short *) pSamples->pSample->apfeat[FEATURE_YPOS]->data);
  144. pSamples->iAnswer = (int)pByPointsY[part1] - (int)pByPointsY[part2];
  145. }
  146. break;
  147. case questionXAngle:
  148. for ( ; pSamples < pLimit; ++pSamples)
  149. {
  150. pByPointsX = ((short *) pSamples->pSample->apfeat[FEATURE_XPOS]->data);
  151. pByPointsY = ((short *) pSamples->pSample->apfeat[FEATURE_YPOS]->data);
  152. deltaX = (int)pByPointsX[part2] - (int)pByPointsX[part1];
  153. deltaY = (int)pByPointsY[part2] - (int)pByPointsY[part1];
  154. pSamples->iAnswer = Angle2XAngle(Arctan2(deltaY, deltaX));
  155. }
  156. break;
  157. case questionYAngle:
  158. for ( ; pSamples < pLimit; ++pSamples)
  159. {
  160. pByPointsX = ((short *) pSamples->pSample->apfeat[FEATURE_XPOS]->data);
  161. pByPointsY = ((short *) pSamples->pSample->apfeat[FEATURE_YPOS]->data);
  162. deltaX = (int)pByPointsX[part2] - (int)pByPointsX[part1];
  163. deltaY = (int)pByPointsY[part2] - (int)pByPointsY[part1];
  164. pSamples->iAnswer = Angle2YAngle(Arctan2(deltaY, deltaX));
  165. }
  166. break;
  167. case questionDelta:
  168. for ( ; pSamples < pLimit; ++pSamples)
  169. {
  170. pByPointsX = ((short *) pSamples->pSample->apfeat[FEATURE_XPOS]->data);
  171. pByPointsY = ((short *) pSamples->pSample->apfeat[FEATURE_YPOS]->data);
  172. deltaX = (int)pByPointsX[part2] - (int)pByPointsX[part1];
  173. deltaY = (int)pByPointsY[part2] - (int)pByPointsY[part1];
  174. pSamples->iAnswer = Distance(deltaX, deltaY);
  175. }
  176. break;
  177. case questionDakuTen:
  178. for ( ; pSamples < pLimit; ++pSamples)
  179. {
  180. pSamples->iAnswer = pSamples->pSample->fDakuten;
  181. }
  182. break;
  183. case questionNetAngle:
  184. for ( ; pSamples < pLimit; ++pSamples)
  185. {
  186. pSamples->iAnswer = ((short *) (pSamples->pSample->apfeat[FEATURE_ANGLE_NET]->data))[part1];
  187. }
  188. break;
  189. case questionCnsAngle :
  190. for ( ; pSamples < pLimit; ++pSamples) {
  191. int iAbsNetAngle, iAbsAngle;
  192. // Get absolute value of net angle
  193. iAbsNetAngle = ((SHORT *) (pSamples->pSample->apfeat[FEATURE_ANGLE_NET]->data))[part1];
  194. if (iAbsNetAngle < 0) {
  195. iAbsNetAngle = -iAbsNetAngle;
  196. }
  197. // Get absolute angle.
  198. iAbsAngle = ((USHORT *) (pSamples->pSample->apfeat[FEATURE_ANGLE_ABS]->data))[part1];
  199. // Answer is the difference
  200. pSamples->iAnswer = iAbsAngle - iAbsNetAngle;
  201. }
  202. break;
  203. case questionAbsAngle:
  204. for ( ; pSamples < pLimit; ++pSamples)
  205. {
  206. pSamples->iAnswer = ((USHORT *) (pSamples->pSample->apfeat[FEATURE_ANGLE_ABS]->data))[part1];
  207. }
  208. break;
  209. case questionCSteps:
  210. for ( ; pSamples < pLimit; ++pSamples)
  211. {
  212. pSamples->iAnswer = ((BYTE *) (pSamples->pSample->apfeat[FEATURE_STEPS]->data))[part1];
  213. }
  214. break;
  215. case questionCFeatures:
  216. for ( ; pSamples < pLimit; ++pSamples)
  217. {
  218. pSamples->iAnswer = ((BYTE *) (pSamples->pSample->apfeat[FEATURE_FEATURES]->data))[part1];
  219. }
  220. break;
  221. case questionXPointsRight:
  222. for ( ; pSamples < pLimit; ++pSamples)
  223. {
  224. pByPointsX = ((short *) pSamples->pSample->apfeat[FEATURE_XPOS]->data);
  225. pSamples->iAnswer = 0;
  226. for (ii = 0; ii < cPoints; ++ii)
  227. {
  228. if (pByPointsX[ii] > pByPointsX[part1])
  229. {
  230. ++pSamples->iAnswer;
  231. }
  232. }
  233. }
  234. break;
  235. case questionYPointsBelow:
  236. for ( ; pSamples < pLimit; ++pSamples)
  237. {
  238. pByPointsY = ((short *) pSamples->pSample->apfeat[FEATURE_YPOS]->data);
  239. pSamples->iAnswer = 0;
  240. for (ii = 0; ii < cPoints; ++ii)
  241. {
  242. if (pByPointsY[ii] > pByPointsY[part1])
  243. {
  244. ++pSamples->iAnswer;
  245. }
  246. }
  247. }
  248. break;
  249. case questionPerpDist:
  250. for ( ; pSamples < pLimit; ++pSamples)
  251. {
  252. pSamples->iAnswer =
  253. FindPerpDist(part1, part2,
  254. ((short *) pSamples->pSample->apfeat[FEATURE_XPOS]->data),
  255. ((short *) pSamples->pSample->apfeat[FEATURE_YPOS]->data));
  256. }
  257. break;
  258. case questionSumXDelta:
  259. for ( ; pSamples < pLimit; ++pSamples)
  260. {
  261. pByPointsX = ((short *) pSamples->pSample->apfeat[FEATURE_XPOS]->data);
  262. pSamples->iAnswer = 0;
  263. for (ii = 0; ii < cPoints; ii += 2)
  264. {
  265. pSamples->iAnswer += (int) pByPointsX[ii + 1] - (int) pByPointsX[ii];
  266. }
  267. }
  268. break;
  269. case questionSumYDelta:
  270. for ( ; pSamples < pLimit; ++pSamples)
  271. {
  272. pByPointsY = ((short *) pSamples->pSample->apfeat[FEATURE_YPOS]->data);
  273. pSamples->iAnswer = 0;
  274. for (ii = 0; ii < cPoints; ii += 2)
  275. {
  276. pSamples->iAnswer += (int) pByPointsY[ii + 1] - (int) pByPointsY[ii];
  277. }
  278. }
  279. break;
  280. case questionSumDelta:
  281. for ( ; pSamples < pLimit; ++pSamples)
  282. {
  283. pByPointsX = ((short *) pSamples->pSample->apfeat[FEATURE_XPOS]->data);
  284. pByPointsY = ((short *) pSamples->pSample->apfeat[FEATURE_YPOS]->data);
  285. pSamples->iAnswer = 0;
  286. for (ii = 0; ii < cPoints; ii += 2)
  287. {
  288. deltaX = (int) pByPointsX[ii + 1] - (int) pByPointsX[ii];
  289. deltaY = (int) pByPointsY[ii + 1] - (int) pByPointsY[ii];
  290. pSamples->iAnswer += Distance(deltaX, deltaY);
  291. }
  292. }
  293. break;
  294. case questionSumNetAngle:
  295. for ( ; pSamples < pLimit; ++pSamples)
  296. {
  297. short *pNetAngle;
  298. pNetAngle = (short *) pSamples->pSample->apfeat[FEATURE_ANGLE_NET]->data;
  299. pSamples->iAnswer = 0;
  300. for (ii = 0; ii < cStrokes; ++ii)
  301. {
  302. pSamples->iAnswer += (int) pNetAngle[ii];
  303. }
  304. }
  305. break;
  306. case questionSumAbsAngle:
  307. for ( ; pSamples < pLimit; ++pSamples)
  308. {
  309. WORD *pAbsAngle;
  310. pAbsAngle = (WORD *) pSamples->pSample->apfeat[FEATURE_ANGLE_ABS]->data;
  311. pSamples->iAnswer = 0;
  312. for (ii = 0; ii < cStrokes; ++ii)
  313. {
  314. pSamples->iAnswer += (int)pAbsAngle[ii];
  315. }
  316. }
  317. break;
  318. case questionCompareXDelta:
  319. for ( ; pSamples < pLimit; ++pSamples)
  320. {
  321. pByPointsX = ((short *) pSamples->pSample->apfeat[FEATURE_XPOS]->data);
  322. deltaX = (int) pByPointsX[part1 + 1] - (int) pByPointsX[part1];
  323. pSamples->iAnswer = (deltaX >= 0) ? deltaX : - deltaX;
  324. deltaX = (int) pByPointsX[part2 + 1] - (int) pByPointsX[part2];
  325. pSamples->iAnswer -= (deltaX >= 0) ? deltaX : - deltaX;
  326. }
  327. break;
  328. case questionCompareYDelta:
  329. for ( ; pSamples < pLimit; ++pSamples)
  330. {
  331. pByPointsY = ((short *) pSamples->pSample->apfeat[FEATURE_YPOS]->data);
  332. deltaY = (int) pByPointsY[part1 + 1] - (int) pByPointsY[part1];
  333. pSamples->iAnswer = (deltaY >= 0) ? deltaY : - deltaY;
  334. deltaY = (int) pByPointsY[part2 + 1] - (int) pByPointsY[part2];
  335. pSamples->iAnswer -= (deltaY >= 0) ? deltaY : - deltaY;
  336. }
  337. break;
  338. case questionCompareDelta:
  339. for ( ; pSamples < pLimit; ++pSamples)
  340. {
  341. pByPointsX = ((short *) pSamples->pSample->apfeat[FEATURE_XPOS]->data);
  342. pByPointsY = ((short *) pSamples->pSample->apfeat[FEATURE_YPOS]->data);
  343. deltaX = (int) pByPointsX[part1 + 1] - (int) pByPointsX[part1];
  344. deltaY = (int) pByPointsY[part1 + 1] - (int) pByPointsY[part1];
  345. pSamples->iAnswer = Distance(deltaX, deltaY);
  346. deltaX = (int) pByPointsX[part2 + 1] - (int) pByPointsX[part2];
  347. deltaY = (int) pByPointsY[part2 + 1] - (int) pByPointsY[part2];
  348. pSamples->iAnswer -= Distance(deltaX, deltaY);
  349. }
  350. break;
  351. case questionCompareAngle:
  352. for ( ; pSamples < pLimit; ++pSamples) {
  353. pByPointsX = ((short *) pSamples->pSample->apfeat[FEATURE_XPOS]->data);
  354. pByPointsY = ((short *) pSamples->pSample->apfeat[FEATURE_YPOS]->data);
  355. deltaX = (int) pByPointsX[part1 + 1] - (int) pByPointsX[part1];
  356. deltaY = (int) pByPointsY[part1 + 1] - (int) pByPointsY[part1];
  357. pSamples->iAnswer = Arctan2(deltaY, deltaX);
  358. deltaX = (int) pByPointsX[part1 + 1] - (int) pByPointsX[part1];
  359. deltaY = (int) pByPointsY[part1 + 1] - (int) pByPointsY[part1];
  360. pSamples->iAnswer -= Arctan2(deltaY, deltaX);
  361. if (pSamples->iAnswer < -180)
  362. {
  363. pSamples->iAnswer += 180;
  364. }
  365. else if (pSamples->iAnswer > 180)
  366. {
  367. pSamples->iAnswer -= 180;
  368. }
  369. }
  370. break;
  371. case questionPointsInBBox:
  372. for ( ; pSamples < pLimit; ++pSamples)
  373. {
  374. int lowerX, upperX, lowerY, upperY;
  375. pByPointsX = ((short *) pSamples->pSample->apfeat[FEATURE_XPOS]->data);
  376. pByPointsY = ((short *) pSamples->pSample->apfeat[FEATURE_YPOS]->data);
  377. if (pByPointsX[part1] <= pByPointsX[part2])
  378. {
  379. lowerX = pByPointsX[part1];
  380. upperX = pByPointsX[part2];
  381. }
  382. else
  383. {
  384. lowerX = pByPointsX[part2];
  385. upperX = pByPointsX[part1];
  386. }
  387. if (pByPointsY[part1] <= pByPointsY[part2])
  388. {
  389. lowerY = pByPointsY[part1];
  390. upperY = pByPointsY[part2];
  391. }
  392. else
  393. {
  394. lowerY = pByPointsY[part2];
  395. upperY = pByPointsY[part1];
  396. }
  397. pSamples->iAnswer = 0;
  398. for (ii = 0; ii < cPoints; ++ii)
  399. {
  400. if ((lowerX <= pByPointsX[ii]) &&
  401. (pByPointsX[ii] <= upperX) &&
  402. (lowerY <= pByPointsY[ii]) &&
  403. (pByPointsY[ii] <= upperY))
  404. {
  405. ++pSamples->iAnswer;
  406. }
  407. }
  408. }
  409. break;
  410. case questionCharLeft:
  411. for ( ; pSamples < pLimit; ++pSamples)
  412. {
  413. pSamples->iAnswer = pSamples->pSample->drcs.x;
  414. }
  415. break;
  416. case questionCharTop:
  417. for ( ; pSamples < pLimit; ++pSamples)
  418. {
  419. pSamples->iAnswer = pSamples->pSample->drcs.y;
  420. }
  421. break;
  422. case questionCharWidth:
  423. for ( ; pSamples < pLimit; ++pSamples)
  424. {
  425. pSamples->iAnswer = pSamples->pSample->drcs.w;
  426. }
  427. break;
  428. case questionCharHeight:
  429. for ( ; pSamples < pLimit; ++pSamples)
  430. {
  431. pSamples->iAnswer = pSamples->pSample->drcs.h;
  432. }
  433. break;
  434. case questionCharDiagonal:
  435. for ( ; pSamples < pLimit; ++pSamples)
  436. {
  437. pSamples->iAnswer = Distance(pSamples->pSample->drcs.w, pSamples->pSample->drcs.h);
  438. }
  439. break;
  440. case questionCharTheta:
  441. for ( ; pSamples < pLimit; ++pSamples)
  442. {
  443. pSamples->iAnswer = Arctan2(pSamples->pSample->drcs.h, pSamples->pSample->drcs.w);
  444. }
  445. break;
  446. case questionStrokeLeft:
  447. for ( ; pSamples < pLimit; ++pSamples)
  448. {
  449. BuildBoundingBox(&rects,
  450. (RECTS *)(pSamples->pSample->apfeat[FEATURE_STROKE_BBOX]->data), part1, part2
  451. );
  452. pSamples->iAnswer = rects.x1;
  453. }
  454. break;
  455. case questionStrokeTop:
  456. for ( ; pSamples < pLimit; ++pSamples)
  457. {
  458. BuildBoundingBox(&rects,
  459. (RECTS *)(pSamples->pSample->apfeat[FEATURE_STROKE_BBOX]->data), part1, part2
  460. );
  461. pSamples->iAnswer = rects.y1;
  462. }
  463. break;
  464. case questionStrokeWidth:
  465. for ( ; pSamples < pLimit; ++pSamples)
  466. {
  467. BuildBoundingBox(&rects,
  468. (RECTS *)(pSamples->pSample->apfeat[FEATURE_STROKE_BBOX]->data), part1, part2
  469. );
  470. pSamples->iAnswer = rects.x2 - rects.x1;
  471. }
  472. break;
  473. case questionStrokeHeight:
  474. for ( ; pSamples < pLimit; ++pSamples)
  475. {
  476. BuildBoundingBox(&rects,
  477. (RECTS *)(pSamples->pSample->apfeat[FEATURE_STROKE_BBOX]->data), part1, part2
  478. );
  479. pSamples->iAnswer = rects.y2 - rects.y1;
  480. }
  481. break;
  482. case questionStrokeDiagonal:
  483. for ( ; pSamples < pLimit; ++pSamples)
  484. {
  485. short w, h;
  486. BuildBoundingBox(&rects,
  487. (RECTS *)(pSamples->pSample->apfeat[FEATURE_STROKE_BBOX]->data), part1, part2
  488. );
  489. w = rects.x2 - rects.x1;
  490. h = rects.y2 - rects.y1;
  491. pSamples->iAnswer = Distance(w, h);
  492. }
  493. break;
  494. case questionStrokeTheta:
  495. for ( ; pSamples < pLimit; ++pSamples)
  496. {
  497. short w, h;
  498. BuildBoundingBox(&rects,
  499. (RECTS *)(pSamples->pSample->apfeat[FEATURE_STROKE_BBOX]->data), part1, part2
  500. );
  501. w = rects.x2 - rects.x1;
  502. h = rects.y2 - rects.y1;
  503. pSamples->iAnswer = Arctan2(h, w);
  504. }
  505. break;
  506. case questionStrokeRight:
  507. for ( ; pSamples < pLimit; ++pSamples)
  508. {
  509. BuildBoundingBox(&rects,
  510. (RECTS *)(pSamples->pSample->apfeat[FEATURE_STROKE_BBOX]->data), part1, part2
  511. );
  512. pSamples->iAnswer = rects.x2;
  513. }
  514. break;
  515. case questionStrokeBottom:
  516. for ( ; pSamples < pLimit; ++pSamples)
  517. {
  518. BuildBoundingBox(&rects,
  519. (RECTS *)(pSamples->pSample->apfeat[FEATURE_STROKE_BBOX]->data), part1, part2
  520. );
  521. pSamples->iAnswer = rects.y2;
  522. }
  523. break;
  524. case questionStrokeLength:
  525. for ( ; pSamples < pLimit; ++pSamples)
  526. {
  527. pSamples->iAnswer = ((USHORT *)(pSamples->pSample->apfeat[FEATURE_LENGTH]->data))[part1];
  528. }
  529. break;
  530. case questionStrokeCurve:
  531. for ( ; pSamples < pLimit; ++pSamples)
  532. {
  533. pendX = ((END_POINTS *) pSamples->pSample->apfeat[FEATURE_XPOS]->data);
  534. pendY = ((END_POINTS *) pSamples->pSample->apfeat[FEATURE_YPOS]->data);
  535. deltaX = pendX[part1].end - pendX[part1].start;
  536. deltaY = pendY[part1].end - pendY[part1].start;
  537. pSamples->iAnswer = ((USHORT *)(pSamples->pSample->apfeat[FEATURE_LENGTH]->data))[part1] - Distance(deltaX, deltaY);
  538. }
  539. break;
  540. case questionCharLength:
  541. for ( ; pSamples < pLimit; ++pSamples)
  542. {
  543. pSamples->iAnswer = 0;
  544. for (ii = 0; ii < cStrokes; ii++)
  545. pSamples->iAnswer += ((USHORT *)(pSamples->pSample->apfeat[FEATURE_LENGTH]->data))[ii];
  546. }
  547. break;
  548. case questionCharCurve:
  549. for ( ; pSamples < pLimit; ++pSamples)
  550. {
  551. pSamples->iAnswer = 0;
  552. pendX = ((END_POINTS *) pSamples->pSample->apfeat[FEATURE_XPOS]->data);
  553. pendY = ((END_POINTS *) pSamples->pSample->apfeat[FEATURE_YPOS]->data);
  554. for (ii = 0; ii < cStrokes; ii++)
  555. {
  556. deltaX = pendX[ii].end - pendX[ii].start;
  557. deltaY = pendY[ii].end - pendY[ii].start;
  558. pSamples->iAnswer += ((USHORT *)(pSamples->pSample->apfeat[FEATURE_LENGTH]->data))[ii] - Distance(deltaX, deltaY);
  559. }
  560. }
  561. break;
  562. case questionAltList :
  563. for ( ; pSamples < pLimit; ++pSamples)
  564. {
  565. pSamples->iAnswer = MAX_RECOG_ALTS * 2;
  566. for (ii = 0; ii < MAX_RECOG_ALTS; ++ii) {
  567. if (pSamples->pSample->awchAlts[ii] == (wchar_t)part1) {
  568. pSamples->iAnswer = ii;
  569. break;
  570. }
  571. }
  572. }
  573. break;
  574. default:
  575. ASSERT(FALSE); // Should never get here.
  576. for ( ; pSamples < pLimit; ++pSamples)
  577. {
  578. pSamples->iAnswer = 0;
  579. }
  580. break;
  581. }
  582. }