Leaked source code of windows server 2003
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.

513 lines
12 KiB

  1. //
  2. // Copyright (c) 1997-1999 Microsoft Corporation.
  3. //
  4. #include "stdafx.h"
  5. #include "vdata.h"
  6. #include "extfunc.h"
  7. #define sign(n) (n < 0 ? 1 : 0)
  8. #define fpow(f) ((double)f*f)
  9. #define lpow(f) ((long)f*f)
  10. #define SPLINE_ATR 0x0001
  11. #define SMOOTHANCHOR 0x80
  12. #define SABUNMIN (1*16)
  13. int FitConic(int inLst,int outLst,int level,int ufp);
  14. static int SetConic(struct VDATA *svp,int nElm,int outLst,int level);
  15. static int CurvTerm(struct VDATA *svp,int nElm,struct VDATA * *term,int level);
  16. static void sabun2(struct VDATA *vp,struct vecdata *vd);
  17. static int Fitting(struct VDATA *sp,struct VDATA *ep,int nElm,int outLst);
  18. static void onecurve(struct VDATA *sp,struct VDATA *midp,struct VDATA *ep,struct vecdata *cp);
  19. static int twocurve(struct VDATA *sp,struct VDATA *ep,int nElm,struct vecdata *cp,struct vecdata *mid,struct vecdata *cp2);
  20. static long getdist(struct vecdata *lp1,struct vecdata *lp2,struct vecdata *p);
  21. static int CrsPnt(struct vecdata *p1,struct vecdata *p2,struct vecdata *p3,struct vecdata *p4,struct vecdata *crsp);
  22. static long plen(struct vecdata *p1,struct vecdata *p2);
  23. static int isbind(struct vecdata *v1,struct vecdata *v2,struct vecdata *v3);
  24. static long GetCurveHeight(struct VDATA *sp,struct VDATA *ep,int nelm,struct VDATA * *rvp,int *pos);
  25. static int underFP;
  26. /***********************************************************************
  27. * Fit Conic Spline to Short Vector
  28. */
  29. /* */ int
  30. /* */ FitConic(
  31. /* */ int inLst,
  32. /* */ int outLst,
  33. /* */ int level, /* Smoothing Level 0-SMOOTHLEVELMAX-1 */
  34. /* */ int ufp)
  35. /*
  36. * returns : 0, -1
  37. ***********************************************************************/
  38. {
  39. struct VHEAD *vhd;
  40. int sts;
  41. struct VDATA *svp, *evp;
  42. int sp, ep;
  43. int ncont;
  44. underFP = ufp;
  45. if ( (sts = VDGetHead( inLst, &vhd))!=0)
  46. goto RET;
  47. VDNew( outLst);
  48. ncont=0;
  49. while ( vhd->next != NIL) {
  50. svp = vhd->headp;
  51. if ((sp=searchanchor(0,svp,&svp,vhd->nPoints))<vhd->nPoints){
  52. while(sp<vhd->nPoints) {
  53. ep = searchanchor(sp+1, svp->next,&evp, vhd->nPoints);
  54. if ((sts = SetConic( svp, ep-sp, outLst, level))<0)
  55. goto RET;
  56. if ( ep >= vhd->nPoints)
  57. break;
  58. sp = ep;
  59. svp = evp;
  60. }
  61. }
  62. ncont++;
  63. if ((sts = VDClose( outLst))<0)
  64. goto RET;
  65. vhd = vhd->next;
  66. }
  67. RET:
  68. return( sts);
  69. }
  70. /***********************************************************************
  71. * Set Conic Curves to specified category
  72. */
  73. /* */ static int
  74. /* */ SetConic ( struct VDATA *svp, int nElm, int outLst, int level)
  75. /*
  76. * returns : 0, -1
  77. ***********************************************************************/
  78. {
  79. struct VDATA *vp;
  80. int nPart;
  81. int sts;
  82. if (!svp)
  83. {
  84. return -1;
  85. }
  86. sts = 0;
  87. while ( nElm > 0) {
  88. /* Divide non contigus */
  89. nPart = CurvTerm( svp, nElm, &vp , level);
  90. sts = Fitting( svp, vp, nPart, outLst);
  91. svp = vp;
  92. nElm -= nPart;
  93. }
  94. return sts;
  95. }
  96. /***********************************************************************
  97. * Determine the part which is described with one Conic
  98. */
  99. /* */ static int
  100. /* */ CurvTerm(
  101. /* */ struct VDATA *svp,
  102. /* */ int nElm,
  103. /* */ struct VDATA **term,
  104. /* */ int level)
  105. /*
  106. * returns: none
  107. ***********************************************************************/
  108. {
  109. struct vecdata sub1, sub2;
  110. int ecnt;
  111. if (!svp)
  112. {
  113. goto RET;
  114. }
  115. if ( nElm < 3) {
  116. for ( ecnt=0; ecnt < nElm; ecnt++)
  117. svp = svp->next;
  118. *term = svp;
  119. return( nElm);
  120. }
  121. sabun2( svp, &sub1);
  122. for ( ecnt = 2; ecnt < nElm; ecnt++) {
  123. svp = svp->next;
  124. sabun2( svp, &sub2);
  125. if ((sign(sub1.x)!=sign(sub2.x)
  126. && abs(sub1.x)+abs(sub2.x)> SABUNMIN*(level+1))
  127. || (sign(sub1.y)!=sign(sub2.y)
  128. &&abs(sub1.y)+abs(sub2.y)> SABUNMIN*(level+1))) {
  129. *term = svp->next;
  130. return ecnt;
  131. }
  132. sub1 = sub2;
  133. }
  134. *term = svp->next->next;
  135. RET:
  136. return nElm;
  137. }
  138. /***********************************************************************
  139. * 2nd Sabun
  140. */
  141. /* */ static void
  142. /* */ sabun2( struct VDATA *vp, struct vecdata *vd)
  143. /*
  144. * returns : none
  145. ***********************************************************************/
  146. {
  147. if ((!vp) || (!vd))
  148. {
  149. return;
  150. }
  151. vd->x = vp->vd.x - vp->next->vd.x*2 + vp->next->next->vd.x;
  152. vd->y = vp->vd.y - vp->next->vd.y*2 + vp->next->next->vd.y;
  153. return;
  154. }
  155. /***********************************************************************
  156. * Curve fit and set data
  157. */
  158. /* */ static int
  159. /* */ Fitting(
  160. /* */ struct VDATA *sp, /* Conic Start Point */
  161. /* */ struct VDATA *ep, /* Conic End Point */
  162. /* */ int nElm,
  163. /* */ int outLst)
  164. /*
  165. * returns : 0, -1
  166. ***********************************************************************/
  167. {
  168. struct vecdata vd;
  169. struct vecdata cp, mid, cp2;
  170. int sts;
  171. if ((!sp) || (!ep))
  172. {
  173. sts = -1;
  174. goto RET;
  175. }
  176. if ( nElm==0)
  177. return 0;
  178. else if ( nElm == 1) {
  179. vd = sp->vd;
  180. if ((sts = VDSetData( outLst, &vd))<0)
  181. goto RET;
  182. }
  183. else if ( nElm == 2) {
  184. onecurve( sp , sp->next, ep, &cp );
  185. vd = sp->vd;
  186. if ((sts = VDSetData( outLst, &vd))<0)
  187. goto RET;
  188. cp.atr = SPLINE_ATR;
  189. if ((sts = VDSetData( outLst, &cp))<0)
  190. goto RET;
  191. }
  192. else {
  193. if ( twocurve( sp, ep, nElm, &cp, &mid, &cp2)) {
  194. vd = sp->vd;
  195. if ((sts = VDSetData( outLst, &vd))<0)
  196. goto RET;
  197. cp.atr = SPLINE_ATR;
  198. if ((sts = VDSetData( outLst, &cp))<0)
  199. goto RET;
  200. mid.atr = 0;
  201. if ((sts = VDSetData( outLst, &mid))<0)
  202. goto RET;
  203. cp2.atr = SPLINE_ATR;
  204. if ((sts = VDSetData( outLst, &cp2))<0)
  205. goto RET;
  206. }
  207. else {
  208. vd = sp->vd;
  209. if ((sts = VDSetData( outLst, &vd))<0)
  210. goto RET;
  211. cp.atr = SPLINE_ATR;
  212. if ((sts = VDSetData( outLst, &cp))<0)
  213. goto RET;
  214. }
  215. }
  216. RET:
  217. return sts;
  218. }
  219. /***********************************************************************
  220. * Fit One Curve
  221. */
  222. /* */ static void
  223. /* */ onecurve(
  224. /* */ struct VDATA *sp,
  225. /* */ struct VDATA *midp,
  226. /* */ struct VDATA *ep,
  227. /* */ struct vecdata *cp)
  228. /*
  229. * returns : none
  230. ***********************************************************************/
  231. {
  232. struct vecdata p;
  233. if ((!sp) || (!midp) || (!ep) || (!cp))
  234. {
  235. return;
  236. }
  237. p.x = (midp->vd.x*4 - sp->vd.x - ep->vd.x)/2;
  238. p.y = (midp->vd.y*4 - sp->vd.y - ep->vd.y)/2;
  239. if ( sp->vd.x < ep->vd.x) {
  240. if ( p.x > ep->vd.x) p.x = ep->vd.x;
  241. if ( p.x < sp->vd.x) p.x = sp->vd.x;
  242. }
  243. else {
  244. if ( p.x < ep->vd.x) p.x = ep->vd.x;
  245. if ( p.x > sp->vd.x) p.x = sp->vd.x;
  246. }
  247. if ( sp->vd.y < ep->vd.y) {
  248. if ( p.y > ep->vd.y) p.y = ep->vd.y;
  249. if ( p.y < sp->vd.y) p.y = sp->vd.y;
  250. }
  251. else {
  252. if ( p.y < ep->vd.y) p.y = ep->vd.y;
  253. if ( p.y > sp->vd.y) p.y = sp->vd.y;
  254. }
  255. *cp = p;
  256. }
  257. /**********************************************************************
  258. * Fit with a pair of Conic
  259. */
  260. /* */ static int
  261. /* */ twocurve(
  262. /* */ struct VDATA *sp,
  263. /* */ struct VDATA *ep,
  264. /* */ int nElm,
  265. /* */ struct vecdata *cp,
  266. /* */ struct vecdata *mid,
  267. /* */ struct vecdata *cp2)
  268. /*
  269. * returns : 0, 1( pair)
  270. **********************************************************************/
  271. {
  272. struct VDATA *midvp, *maxvp;
  273. long maxlen;
  274. int twin=0;
  275. long sclen, eclen;
  276. int pos;
  277. int cp1pos, cp2pos;
  278. if ((!sp) || (!ep) || (!cp) || (!mid) || (!cp2) )
  279. {
  280. goto RET;
  281. }
  282. /* Get Curve Peak */
  283. maxlen = GetCurveHeight( sp, ep, nElm, &maxvp, &pos);
  284. /*
  285. if ( plen( &sp->vd, &ep->vd)/25 > maxlen) {
  286. onecurve( sp , maxvp, ep, cp );
  287. twin = 0;
  288. }
  289. else {
  290. */
  291. onecurve( sp , maxvp, ep, cp );
  292. sclen = plen( &sp->vd, cp);
  293. eclen = plen( &ep->vd, cp);
  294. midvp = maxvp;
  295. if ( sclen > eclen*4
  296. || sclen*4 < eclen
  297. || (long)(maxvp->vd.x - sp->vd.x)*(cp->x-sp->vd.x)<0L
  298. || (long)(maxvp->vd.y - sp->vd.y)*(cp->y-sp->vd.y)<0L
  299. || ( plen( &sp->vd, &ep->vd)>25L*25*underFP
  300. && plen( &sp->vd, &ep->vd)<maxlen*64)) {
  301. maxlen=GetCurveHeight(sp, midvp, pos, &maxvp, &cp1pos);
  302. onecurve( sp, maxvp, midvp, cp );
  303. maxlen=GetCurveHeight(midvp,ep,nElm-pos,&maxvp,&cp2pos);
  304. onecurve( midvp , maxvp, ep, cp2 );
  305. *mid = midvp->vd;
  306. twin = 1;
  307. }
  308. else {
  309. twin = 0;
  310. }
  311. /*
  312. }
  313. */
  314. RET:
  315. return( twin);
  316. }
  317. /**********************************************************************
  318. * distance of point from line
  319. */
  320. /* */ static long
  321. /* */ getdist(
  322. /* */ struct vecdata *lp1,
  323. /* */ struct vecdata *lp2, /* Line p1, p2 */
  324. /* */ struct vecdata *p) /* Point */
  325. /*
  326. * return : Disttance 2nd Value
  327. **********************************************************************/
  328. {
  329. long a, b, c;
  330. long height;
  331. if ((!lp1) || (!lp2) || (!p))
  332. {
  333. return 0;
  334. }
  335. a = - ( lp2->y - lp1->y);
  336. b = lp2->x - lp1->x;
  337. c = (long)(-lp1->y) * lp2->x + (long)(lp1->x) * lp2->y;
  338. if ( a==0 && b==0)
  339. height = c;
  340. else {
  341. height = a*p->x + b*p->y+c;
  342. if ( labs(height)>46340L)
  343. height = (long)(fpow(height)/(fpow(a)+fpow(b)));
  344. else
  345. height = lpow(height)/(lpow(a)+lpow(b));
  346. }
  347. return( height);
  348. }
  349. /**********************************************************************
  350. * Cross Point
  351. */
  352. /* */ static int
  353. /* */ CrsPnt(
  354. /* */ struct vecdata *p1, /* vector point p1 to p2 */
  355. /* */ struct vecdata *p2,
  356. /* */ struct vecdata *p3, /* vector point p3 to p4 */
  357. /* */ struct vecdata *p4,
  358. /* */ struct vecdata *crsp)
  359. /*
  360. * returns : 0, -1(no cross)
  361. **********************************************************************/
  362. {
  363. int rel1x, rel1y, rel2x, rel2y;
  364. long cmul, cmul2;
  365. int sts;
  366. if ( (!p1) || (!p2) || (!p3) || (!p4) || (!crsp) )
  367. {
  368. sts = -1;
  369. goto RET;
  370. }
  371. rel1x = p2->x - p1->x;
  372. rel1y = p2->y - p1->y;
  373. rel2x = p4->x - p3->x;
  374. rel2y = p4->y - p3->y;
  375. cmul = (long)rel1y*rel2x - (long)rel2y*rel1x;
  376. if (cmul == 0L)
  377. sts = -1;
  378. else {
  379. cmul2 = (long)rel2x * (p3->y - p1->y) -
  380. (long)rel2y * (p3->x - p1->x);
  381. crsp->x = (int)(cmul2*rel1x/cmul) + p1->x;
  382. crsp->y = (int)(cmul2*rel1y/cmul) + p1->y;
  383. if ( (long)rel1x*(crsp->x-p1->x)<0
  384. || (long)rel1y*(crsp->y-p1->y)<0
  385. || (long)rel2x*(crsp->x-p4->x)<0
  386. || (long)rel2y*(crsp->y-p4->y)<0)
  387. sts = -1;
  388. else sts = 0;
  389. }
  390. RET:
  391. return sts;
  392. }
  393. /**********************************************************************
  394. * distance of points
  395. */
  396. /* */ static long
  397. /* */ plen(
  398. /* */ struct vecdata *p1,
  399. /* */ struct vecdata *p2)
  400. /*
  401. * return : Disttance 2nd Value
  402. **********************************************************************/
  403. {
  404. if ((!p1) || (!p2))
  405. {
  406. return 0;
  407. }
  408. return( lpow((long)(p2->x-p1->x)) + lpow((long)(p2->y - p1->y)));
  409. }
  410. /**********************************************************************
  411. * bind two conic to one
  412. */
  413. /* */ static int
  414. /* */ isbind(
  415. /* */ struct vecdata *v1,
  416. /* */ struct vecdata *v2,
  417. /* */ struct vecdata *v3)
  418. /*
  419. * returns : 0, 1
  420. **********************************************************************/
  421. {
  422. int l12, l23;
  423. if ((!v1) || (!v2) || (!v3))
  424. {
  425. goto NORET;
  426. }
  427. l12 = v1->x - v2->x;
  428. l23 = v2->x - v3->x;
  429. if ( sign( l12)!=sign(l23))
  430. goto NORET;
  431. l12 = abs( l12);
  432. l23 = abs( l23);
  433. if ( (l12-l23)!=0) {
  434. if ( l12 / abs(l12 - l23) <10)
  435. goto NORET;
  436. }
  437. l12 = v1->y - v2->y;
  438. l23 = v2->y - v3->y;
  439. if ( sign( l12)!=sign(l23))
  440. goto NORET;
  441. l12 = abs( l12);
  442. l23 = abs( l23);
  443. if ( (l12-l23)!=0) {
  444. if ( l12 / abs(l12 - l23) <10)
  445. goto NORET;
  446. }
  447. return 1;
  448. NORET:
  449. return 0;
  450. }
  451. /**********************************************************************
  452. * Get Curve liaison Peak height
  453. */
  454. /* */ static long
  455. /* */ GetCurveHeight(
  456. /* */ struct VDATA *sp,
  457. /* */ struct VDATA *ep,
  458. /* */ int nelm,
  459. /* */ struct VDATA * * rvp,
  460. /* */ int *pos)
  461. /*
  462. * returns : maxlength( 2nd value)
  463. **********************************************************************/
  464. {
  465. int ecnt;
  466. struct VDATA *vp, *maxvp;
  467. long maxlen=0, len;
  468. int maxpos;
  469. if ((!sp) || (!ep) || (!rvp) || (!pos))
  470. {
  471. goto RET;
  472. }
  473. /* Get Curve Peak */
  474. vp = sp->next;
  475. maxvp = vp;
  476. maxlen = 0;
  477. maxpos = 0;
  478. for ( ecnt = 0; ecnt < nelm-1; ecnt++, vp = vp->next) {
  479. len = getdist( &sp->vd, &ep->vd, &vp->vd);
  480. if ( len > maxlen) {
  481. maxlen = len;
  482. maxvp = vp;
  483. maxpos = ecnt;
  484. }
  485. }
  486. *rvp = maxvp;
  487. *pos = maxpos;
  488. RET:
  489. return maxlen;
  490. }
  491. /* EOF */