1328 lines
32 KiB
C++
1328 lines
32 KiB
C++
//
|
||
// Copyright (c) 1997-1999 Microsoft Corporation.
|
||
//
|
||
|
||
#include "stdafx.h"
|
||
|
||
#include "vdata.h"
|
||
#include "extfunc.h"
|
||
#include "ttfstruc.h"
|
||
|
||
/* Smooth sort */
|
||
#define SMOOTH 0x8000
|
||
#define NOSMOOTH 0x4000
|
||
#define BACKWARD 0x2000 /* NOSMOOTH is forward vector */
|
||
#define FOREWARD 0x1000 /* NOSMOOTH is backward vector*/
|
||
|
||
/* Curve Type */
|
||
#define SPLINE_ATR 0x0001
|
||
|
||
/* Smoothing anchor Point */
|
||
#define SMOOTHANCHOR 0x0080
|
||
/* Smoothing anchor point is based 90degree Rule */
|
||
/* for turning */
|
||
#define TURN_OU 1 /* ‰š */
|
||
#define TURN_TOTSU 2 /* “Ê */
|
||
|
||
#define sign(n) (n < 0 ? 1 : 0)
|
||
|
||
#define LONGMIN 5
|
||
|
||
|
||
int SmoothVector(int lstHdl,int tmpLst,int xinMesh,int yinMesh, int outMesh,struct SMOOTHPRM *prm,int fp);
|
||
static int BindVector(int inLst,int outLst);
|
||
static int BindPoint(int inLst,int outLst);
|
||
static int DetectNoSmooth(int lsthdl);
|
||
static void turnsort(struct VDATA *vp);
|
||
static void generalsmooth(struct VDATA *vp);
|
||
static int isturn(struct VDATA *vp);
|
||
static int islong(struct VDATA *vp);
|
||
static void longline(struct VDATA *vp);
|
||
static int ZoomPoint(int lstHdl,int xinMesh,int yinMesh, int outMesh,int uFp);
|
||
static int preproc1(int inLst,int outLst);
|
||
static int diveachside(struct VDATA *vp,int outLst);
|
||
static int divoneside(struct VDATA *vp,int outLst);
|
||
static int divVec( int ilst, int olst, int divN);
|
||
static int Smooth1(int inLst,int outLst,int weight1,int weight2,int weight3);
|
||
static int Smooth2(int inLst,int outLst);
|
||
int searchanchor(int sn,struct VDATA *sp,struct VDATA * *ep,int lim);
|
||
static int smooth1sub(struct VDATA *vp,int np,int outLst,int w1,int w2,int w3);
|
||
static int smooth2sub(struct VDATA *vp,int np,int outLst);
|
||
int RemoveFp(int lstHdl,int outMesh,int uFp);
|
||
static int BindLinears(int inLst,int outLst);
|
||
static int DelZeroVec(int inLst,int outLst);
|
||
int toTTFFrame(int lstH,struct BBX *bbx);
|
||
static int lightSub(int inLst,int outLst);
|
||
int SmoothLight(int ioLst,int tmpLst,int width,int height, int oWidth,int ufpVal);
|
||
int ConvMesh(int lstH,int inMesh,int outMesh);
|
||
static int
|
||
straightCurve( int iLst, int oLst)
|
||
{
|
||
struct VHEAD *vhd;
|
||
struct VDATA *vp;
|
||
struct vecdata rel, nxtrel;
|
||
int np;
|
||
int sts;
|
||
struct vecdata svd;
|
||
|
||
if ( (sts = VDGetHead( iLst, &vhd))!=0)
|
||
goto RET;
|
||
VDNew(oLst);
|
||
|
||
while ( vhd->next!=NIL) {
|
||
/* No point data is not Allowed */
|
||
/* Set Origin */
|
||
vp = vhd->headp;
|
||
if ((sts = VDSetData(oLst, &vp->vd))!=0)
|
||
goto RET;
|
||
vp=vp->next;
|
||
for ( np = 1; np < vhd->nPoints; np++,vp = vp->next) {
|
||
if ( vp->vd.atr & SPLINE_ATR) {
|
||
rel.x = vp->vd.x - vp->prev->vd.x;
|
||
rel.y = vp->vd.y - vp->prev->vd.y;
|
||
nxtrel.x= vp->next->vd.x - vp->vd.x;
|
||
nxtrel.y= vp->next->vd.y - vp->vd.y;
|
||
if ((long)rel.x*nxtrel.y==(long)rel.y*nxtrel.x){
|
||
vp = vp->next;
|
||
np++;
|
||
svd = vp->vd;
|
||
svd.atr &= ~SPLINE_ATR;
|
||
if ((sts = VDSetData(oLst, &svd))!=0)
|
||
goto RET;
|
||
}
|
||
else {
|
||
if ((sts = VDSetData(oLst, &vp->vd))!=0)
|
||
goto RET;
|
||
vp = vp->next;
|
||
np++;
|
||
if ( np >= vhd->nPoints)
|
||
break;
|
||
if ((sts = VDSetData(oLst, &vp->vd))!=0)
|
||
goto RET;
|
||
}
|
||
}
|
||
else {
|
||
if ((sts = VDSetData(oLst, &vp->vd))!=0)
|
||
goto RET;
|
||
}
|
||
}
|
||
if(VDClose( oLst))
|
||
goto RET;
|
||
vhd = vhd->next;
|
||
}
|
||
return 0;
|
||
RET:
|
||
return -1;
|
||
}
|
||
/***********************************************************************
|
||
* Smoothing Main
|
||
*/
|
||
/* */ int
|
||
/* */ SmoothVector(
|
||
/* */ int lstHdl,
|
||
/* */ int tmpLst,
|
||
/* */ int xinMesh, /* Input Mesh Size*/
|
||
/* */ int yinMesh,
|
||
/* */ int outMesh, /* Output Mesh size */
|
||
/* */ struct SMOOTHPRM *prm,
|
||
/* */ int fp) /* Fixed Point sft-val */
|
||
/*
|
||
* reuturns : 0, -1
|
||
* Remarks : ‚±‚̃‚ƒWƒ…<C692>[ƒ‹‚Ì“ü—Í‚Í<E2809A>A—ÖŠs’Š<E28099>o‚ÌŒ‹‰Ê‚̃xƒNƒ^—ñ‚Å
|
||
* <09>@Œ´“_‚ð<E2809A>¶<EFBFBD>ã‚Æ‚·‚é<E2809A>B
|
||
* <09>@<40>o—Í‚Í<E2809A>A<EFBFBD>o—̓<C38D>ƒbƒVƒ…‚É<E2809A>‡‚킹‚邪<E2809A>AŒ´“_‚Í<E2809A>¶<EFBFBD>ã‚Å<E2809A>A
|
||
* <09>@ƒx<C692>[ƒXƒ‰ƒCƒ“<C692>A<EFBFBD>¶‘¤ƒxƒAƒŠƒ“ƒO‚Í’²<E28099>®‚³‚ê‚È‚¢
|
||
***********************************************************************/
|
||
{
|
||
int sts;
|
||
|
||
if ( (sts = BindPoint( lstHdl, tmpLst))<0)
|
||
goto RET;
|
||
|
||
if ( (sts = DetectNoSmooth( tmpLst))<0)
|
||
goto RET;
|
||
|
||
if ( (sts = ZoomPoint( tmpLst, xinMesh, yinMesh, outMesh, fp))<0)
|
||
goto RET;
|
||
|
||
if ( (sts = preproc1( tmpLst, lstHdl))<0)
|
||
goto RET;
|
||
/* */
|
||
if ( prm->UseConic) {
|
||
if ( sts = divVec( lstHdl, tmpLst, 2))
|
||
goto RET;
|
||
if ( (sts = Smooth1( tmpLst, lstHdl, 1, 2, 1))<0)
|
||
goto RET;
|
||
|
||
if ( (sts = Smooth2( lstHdl, tmpLst))<0)
|
||
goto RET;
|
||
|
||
if ( sts = FitConic(tmpLst,lstHdl, prm->SmoothLevel, fp))
|
||
goto RET;
|
||
}
|
||
else {
|
||
if ( (sts = Smooth1( lstHdl, tmpLst, 1, 2, 1))<0)
|
||
goto RET;
|
||
if ( (sts = Smooth2( tmpLst, lstHdl))<0)
|
||
goto RET;
|
||
}
|
||
if ( (sts = DelZeroVec( lstHdl, tmpLst))<0)
|
||
goto RET;
|
||
|
||
if ( (sts = straightCurve( tmpLst, lstHdl))<0)
|
||
goto RET;
|
||
|
||
if ( (sts = DelZeroVec( lstHdl, tmpLst))<0)
|
||
goto RET;
|
||
sts = BindLinears( tmpLst, lstHdl);
|
||
|
||
|
||
RET:
|
||
return sts;
|
||
}
|
||
/***********************************************************************
|
||
* Bind Same Direction Unit Vector
|
||
*/
|
||
/* */ static int
|
||
/* */ BindVector(
|
||
/* */ int inLst, /* Absolute Coordinate */
|
||
/* */ int outLst) /* Relative one */
|
||
/*
|
||
* reuturns : 0, -1
|
||
***********************************************************************/
|
||
{
|
||
struct VHEAD *vhd;
|
||
struct VDATA *vp;
|
||
struct vecdata rel, nxtrel;
|
||
int np;
|
||
int sts;
|
||
|
||
if ( (sts = VDGetHead( inLst, &vhd))!=0)
|
||
goto RET;
|
||
VDNew(outLst);
|
||
|
||
nxtrel.atr = 1;
|
||
while ( vhd->next!=NIL) {
|
||
/* No point data is not Allowed */
|
||
/* Set Origin */
|
||
vp = vhd->headp;
|
||
if ((sts = VDSetData(outLst, &vp->vd))!=0)
|
||
goto RET;
|
||
rel.x = rel.y = 0;
|
||
for ( np = 0; np < vhd->nPoints; np++,vp = vp->next) {
|
||
nxtrel.x = vp->next->vd.x - vp->vd.x;
|
||
nxtrel.y = vp->next->vd.y - vp->vd.y;
|
||
if ( rel.x==0 && rel.y ==0)
|
||
rel = nxtrel;
|
||
else {
|
||
if ( rel.y==0 && nxtrel.y==0)
|
||
rel.x += nxtrel.x;
|
||
else if ( rel.x == 0 && nxtrel.x==0)
|
||
rel.y += nxtrel.y;
|
||
else {
|
||
if ((sts=VDSetData(outLst, &rel))!=0)
|
||
goto RET;
|
||
rel = nxtrel;
|
||
}
|
||
}
|
||
}
|
||
if ( rel.x!=0 || rel.y!=0) {
|
||
if ((sts=VDSetData(outLst, &rel))!=0)
|
||
goto RET;
|
||
}
|
||
vhd = vhd->next;
|
||
if ((sts = VDClose(outLst))!=0)
|
||
goto RET;
|
||
}
|
||
RET:
|
||
return( sts);
|
||
|
||
}
|
||
/***********************************************************************
|
||
* Bind Same Direction Unit Vector(Absolute Coodinate Version)
|
||
* Only for short vector ( dont care SPLINE )
|
||
*/
|
||
/* */ static int
|
||
/* */ BindPoint(
|
||
/* */ int inLst, /* Absolute Coordinate */
|
||
/* */ int outLst) /* .. */
|
||
/*
|
||
* reuturns : 0, -1
|
||
***********************************************************************/
|
||
{
|
||
struct VHEAD *vhd;
|
||
struct VDATA *vp;
|
||
struct vecdata lastvd;
|
||
int np;
|
||
int sts;
|
||
|
||
if ( (sts = VDGetHead( inLst, &vhd))!=0)
|
||
goto RET;
|
||
VDNew(outLst);
|
||
|
||
while ( vhd->next!=NIL) {
|
||
/* No point data is not Allowed */
|
||
/* Set Origin */
|
||
vp = vhd->headp;
|
||
if ((sts = VDSetData(outLst, &vp->vd))!=0)
|
||
goto RET;
|
||
lastvd = vp->vd;
|
||
for ( np = 0; np < vhd->nPoints; np++,vp = vp->next) {
|
||
if (vp->next->vd.x != lastvd.x && vp->next->vd.y != lastvd.y) {
|
||
if ((sts=VDSetData(outLst, &vp->vd))!=0)
|
||
goto RET;
|
||
lastvd = vp->vd;
|
||
}
|
||
}
|
||
vhd = vhd->next;
|
||
if ((sts = VDClose(outLst))!=0)
|
||
goto RET;
|
||
}
|
||
RET:
|
||
return( sts);
|
||
|
||
}
|
||
/***********************************************************************
|
||
* Detect Corner and edge
|
||
*/
|
||
/* */ static int
|
||
/* */ DetectNoSmooth(
|
||
/* */ int lsthdl) /* Absolute Coordinate */
|
||
/*
|
||
* returns : 0, -1
|
||
***********************************************************************/
|
||
{
|
||
struct VHEAD *vhd;
|
||
int sts;
|
||
struct VDATA *vp;
|
||
int np;
|
||
|
||
|
||
if ( (sts = VDGetHead( lsthdl, &vhd))!=0)
|
||
goto RET;
|
||
while ( vhd->next != NIL) {
|
||
vp = vhd->headp;
|
||
for ( np = 0; np < vhd->nPoints; np++, vp = vp->next) {
|
||
if ( isturn( vp) )
|
||
turnsort(vp);
|
||
else if (islong (vp))
|
||
longline( vp);
|
||
else /* based on general rule */
|
||
generalsmooth(vp);
|
||
}
|
||
vhd = vhd->next;
|
||
}
|
||
RET:
|
||
return sts;
|
||
}
|
||
/***********************************************************************
|
||
* Judge smooth or not at Turning Part
|
||
*/
|
||
/* */ static void
|
||
/* */ turnsort(
|
||
/* */ struct VDATA *vp)
|
||
/*
|
||
* returns : none
|
||
***********************************************************************/
|
||
{
|
||
struct vecdata cur, prev1, prev2, next1, next2;
|
||
|
||
cur.x = vp->vd.x-vp->prev->vd.x;
|
||
cur.y = vp->vd.y-vp->prev->vd.y;
|
||
prev1.x = vp->prev->vd.x-vp->prev->prev->vd.x;
|
||
prev1.y = vp->prev->vd.y-vp->prev->prev->vd.y;
|
||
prev2.x = vp->prev->prev->vd.x-vp->prev->prev->prev->vd.x;
|
||
prev2.y = vp->prev->prev->vd.y-vp->prev->prev->prev->vd.y;
|
||
next1.x = vp->next->vd.x - vp->vd.x;
|
||
next1.y = vp->next->vd.y - vp->vd.y;
|
||
next2.x = vp->next->next->vd.x - vp->next->vd.x;
|
||
next2.y = vp->next->next->vd.y - vp->next->vd.y;
|
||
|
||
if ( cur.x) {
|
||
if ( abs(next1.y) > 1)
|
||
vp->vd.atr |= NOSMOOTH ;
|
||
else if ( sign( cur.x) == sign( next2.x))
|
||
vp->vd.atr |= SMOOTH | BACKWARD;
|
||
else
|
||
vp->vd.atr |= NOSMOOTH;
|
||
if ( abs(prev1.y) > 1)
|
||
vp->prev->vd.atr |= NOSMOOTH ;
|
||
else if (sign(cur.x)==sign(prev2.x))
|
||
vp->prev->vd.atr |= SMOOTH | FOREWARD;
|
||
else
|
||
vp->prev->vd.atr |= NOSMOOTH ;
|
||
}
|
||
else {
|
||
if ( abs(next1.x) > 1)
|
||
vp->vd.atr |= NOSMOOTH ;
|
||
else if ( sign( cur.y) == sign( next2.y))
|
||
vp->vd.atr |= SMOOTH | BACKWARD;
|
||
else
|
||
vp->vd.atr |= NOSMOOTH;
|
||
if ( abs(prev1.x) > 1)
|
||
vp->prev->vd.atr |= NOSMOOTH ;
|
||
else if (sign(cur.y)==sign(prev2.y))
|
||
vp->prev->vd.atr |= SMOOTH | FOREWARD;
|
||
else
|
||
vp->prev->vd.atr |= NOSMOOTH;
|
||
}
|
||
return;
|
||
}
|
||
/***********************************************************************
|
||
* Judge Smooth or not with general rule
|
||
*/
|
||
/* */ static void
|
||
/* */ generalsmooth( struct VDATA *vp)
|
||
/*
|
||
* returns : none
|
||
***********************************************************************/
|
||
{
|
||
struct vecdata prev2, prev1, cur, next1, next2, next3;
|
||
|
||
cur.x = vp->vd.x- vp->prev->vd.x;
|
||
cur.y = vp->vd.y- vp->prev->vd.y;
|
||
prev1.x = vp->prev->vd.x - vp->prev->prev->vd.x;
|
||
prev1.y = vp->prev->vd.y - vp->prev->prev->vd.y;
|
||
prev2.x = vp->prev->prev->vd.x - vp->prev->prev->prev->vd.x;
|
||
prev2.y = vp->prev->prev->vd.y - vp->prev->prev->prev->vd.y;
|
||
next1.x = vp->next->vd.x - vp->vd.x;
|
||
next1.y = vp->next->vd.y - vp->vd.y;
|
||
next2.x = vp->next->next->vd.x - vp->next->vd.x;
|
||
next2.y = vp->next->next->vd.y - vp->next->vd.y;
|
||
next3.x = vp->next->next->next->vd.x - vp->next->next->vd.x;
|
||
next3.y = vp->next->next->next->vd.y - vp->next->next->vd.y;
|
||
|
||
if ( cur.y) {
|
||
if ( abs(next1.x)>1 && abs(cur.y)>1) {
|
||
if ( sign(cur.y) == sign(next1.x)
|
||
&& abs(next2.y)==1
|
||
&& abs(prev1.x)==1
|
||
&& sign(cur.y)==sign(prev2.y)
|
||
&& sign(next1.x)==sign( next3.x))
|
||
;
|
||
else
|
||
vp->vd.atr |= NOSMOOTH;
|
||
}
|
||
}
|
||
else {
|
||
if ( abs(next1.y)>1 && abs(cur.x)>1) {
|
||
if ( sign(cur.x) != sign(next1.y)
|
||
&& abs(next2.x)==1
|
||
&& abs(prev1.y)==1
|
||
&& sign(cur.x)==sign(prev2.x)
|
||
&& sign(next1.y)==sign( next3.y))
|
||
;
|
||
else
|
||
vp->vd.atr |= NOSMOOTH;
|
||
}
|
||
}
|
||
return;
|
||
}
|
||
/***********************************************************************
|
||
* Judge turning
|
||
*/
|
||
/* */ static int
|
||
/* */ isturn( struct VDATA *vp) /* Absolute */
|
||
/*
|
||
* retuns
|
||
***********************************************************************/
|
||
{
|
||
int turnSort;
|
||
struct vecdata prev, cur, next;
|
||
|
||
prev.x = vp->prev->vd.x - vp->prev->prev->vd.x;
|
||
prev.y = vp->prev->vd.y - vp->prev->prev->vd.y;
|
||
cur.x = vp->vd.x - vp->prev->vd.x;
|
||
cur.y = vp->vd.y - vp->prev->vd.y;
|
||
next.x = vp->next->vd.x - vp->vd.x;
|
||
next.y = vp->next->vd.y - vp->vd.y;
|
||
|
||
if ( prev.x !=0) {
|
||
if ( sign(prev.x )!=sign(next.x )) {
|
||
if (sign(next.x ) ==sign(cur.y))
|
||
turnSort = TURN_TOTSU;
|
||
else
|
||
turnSort = TURN_OU;
|
||
}
|
||
else turnSort = 0;
|
||
}
|
||
else {
|
||
if ( sign(prev.y )!=sign(next.y )) {
|
||
if (sign(next.y ) ==sign(cur.x))
|
||
turnSort = TURN_OU;
|
||
else
|
||
turnSort = TURN_TOTSU;
|
||
}
|
||
else turnSort = 0;
|
||
}
|
||
return turnSort;
|
||
}
|
||
|
||
/***********************************************************************
|
||
* judge Long Line or Not
|
||
*/
|
||
/* */ static int
|
||
/* */ islong( struct VDATA *vp)
|
||
/*
|
||
* returns : 0, 1
|
||
***********************************************************************/
|
||
{
|
||
struct vecdata cur, prev1, prev2, next1, next2;
|
||
int sts;
|
||
|
||
cur.x = vp->vd.x - vp->prev->vd.x;
|
||
cur.y = vp->vd.y - vp->prev->vd.y;
|
||
if ( abs(cur.x)<= LONGMIN && abs(cur.y) <= LONGMIN)
|
||
return( 0);
|
||
prev2.x = vp->prev->prev->vd.x - vp->prev->prev->prev->vd.x;
|
||
prev2.y = vp->prev->prev->vd.y - vp->prev->prev->prev->vd.y;
|
||
prev1.x = vp->prev->vd.x - vp->prev->prev->vd.x;
|
||
prev1.y = vp->prev->vd.y - vp->prev->prev->vd.y;
|
||
next1.x = vp->next->vd.x - vp->vd.x;
|
||
next1.y = vp->next->vd.y - vp->vd.y;
|
||
next2.x = vp->next->next->vd.x - vp->next->vd.x;
|
||
next2.y = vp->next->next->vd.y - vp->next->vd.y;
|
||
if ( cur.x) {
|
||
if ( (sign(cur.x) != sign(next2.x)
|
||
|| abs(next1.y)>1
|
||
|| ( abs(next1.y)==1 && abs(cur.x)/2 > abs(next2.x)))
|
||
&& (sign(cur.x) != sign(prev2.x)
|
||
|| abs(prev1.y)>1
|
||
|| ( abs(prev1.y)==1 && abs(cur.x)/2 > abs(prev2.x))))
|
||
sts = 1;
|
||
/* 94.11.09 */
|
||
else if ( abs(cur.x) > 2 && (abs(next1.y)>2 || abs(prev1.y)>2))
|
||
sts = 1;
|
||
/* */
|
||
else sts = 0;
|
||
}
|
||
else {
|
||
if ( (sign(cur.y) != sign(next2.y)
|
||
|| abs(next1.x)>1
|
||
|| ( abs(next1.x)==1 && abs(cur.y)/2 > abs(next2.y)))
|
||
&& (sign(cur.y) != sign(prev2.y)
|
||
|| abs(prev1.x)>1
|
||
|| ( abs(prev1.x)==1 && abs(cur.y)/2 > abs(prev2.y))))
|
||
sts = 1;
|
||
/* 94.11.09 */
|
||
else if ( abs(cur.y) > 2 && (abs(next1.x)>2 || abs(prev1.x)>2))
|
||
sts = 1;
|
||
/* */
|
||
else sts = 0;
|
||
}
|
||
return sts;
|
||
}
|
||
/***********************************************************************
|
||
* judge Long Line or Not
|
||
*/
|
||
/* */ static void
|
||
/* */ longline( struct VDATA *vp)
|
||
/*
|
||
* returns : 0, 1
|
||
***********************************************************************/
|
||
{
|
||
struct vecdata cur, prev1, prev2, next1, next2;
|
||
|
||
prev2.x = vp->prev->prev->vd.x - vp->prev->prev->prev->vd.x;
|
||
prev2.y = vp->prev->prev->vd.y - vp->prev->prev->prev->vd.y;
|
||
prev1.x = vp->prev->vd.x - vp->prev->prev->vd.x;
|
||
prev1.y = vp->prev->vd.y - vp->prev->prev->vd.y;
|
||
cur.x = vp->vd.x - vp->prev->vd.x;
|
||
cur.y = vp->vd.y - vp->prev->vd.y;
|
||
next1.x = vp->next->vd.x - vp->vd.x;
|
||
next1.y = vp->next->vd.y - vp->vd.y;
|
||
next2.x = vp->next->next->vd.x - vp->next->vd.x;
|
||
next2.y = vp->next->next->vd.y - vp->next->vd.y;
|
||
|
||
if ( cur.x) {
|
||
/* ‘O•û */
|
||
if ( abs(next1.y)!=1 || sign(cur.x)!=sign(next2.x))
|
||
vp->vd.atr |= NOSMOOTH;
|
||
else if ( abs( next2.x) ==1 && sign(cur.x)==sign(next1.y))
|
||
vp->vd.atr |= NOSMOOTH;
|
||
else
|
||
vp->vd.atr |= NOSMOOTH | BACKWARD;
|
||
/* Œã•û */
|
||
if ( abs(prev1.y)!=1 || sign(cur.x)!=sign(prev2.x))
|
||
vp->prev->vd.atr |= NOSMOOTH;
|
||
else if ( abs( prev2.x) ==1&& sign(cur.x)!=sign(prev1.y))
|
||
vp->prev->vd.atr |= NOSMOOTH;
|
||
else
|
||
vp->prev->vd.atr |= NOSMOOTH | FOREWARD;
|
||
}
|
||
else {
|
||
/* ‘O•û */
|
||
if ( abs(next1.x)!=1 || sign(cur.y)!=sign(next2.y))
|
||
vp->vd.atr |= NOSMOOTH;
|
||
else if ( abs( next2.y) ==1 && sign(cur.y)!=sign(next1.x))
|
||
vp->vd.atr |= NOSMOOTH;
|
||
else
|
||
vp->vd.atr |= NOSMOOTH | BACKWARD;
|
||
/* Œã•û */
|
||
if ( abs(prev1.x)!=1 || sign(cur.y)!=sign(prev2.y))
|
||
vp->prev->vd.atr |= NOSMOOTH;
|
||
else if ( abs( prev2.y) ==1&& sign(cur.y)==sign(prev1.x))
|
||
vp->prev->vd.atr |= NOSMOOTH;
|
||
else
|
||
vp->prev->vd.atr |= NOSMOOTH | FOREWARD;
|
||
}
|
||
}
|
||
/***********************************************************************
|
||
* Zoom for fixed point
|
||
*/
|
||
/* */ static int
|
||
/* */ ZoomPoint(
|
||
/* */ int lstHdl, /* List Handle to proccess */
|
||
/* */ int xinMesh, /* INPut Dot Mesh */
|
||
/* */ int yinMesh,
|
||
/* */ int outMesh, /* output mesh (256) */
|
||
/* */ int uFp) /* Under Fixed Point Value */
|
||
/*
|
||
* returns : none
|
||
* remarks : <20>ˆ—<CB86>Œ‹‰Ê‚Ì<E2809A>À•WŒn‚Í<E2809A>A(128,128)[=outMesh/2]‚ðŒ´“_‚Ɉړ®‚µ<E2809A>A
|
||
* <09>@UFp‚ðŠ|‚¯‚½’l‚Å‚ ‚é
|
||
***********************************************************************/
|
||
{
|
||
struct VHEAD *vhd;
|
||
int sts;
|
||
struct VDATA *vp;
|
||
int np;
|
||
int center;
|
||
|
||
center = outMesh/2*uFp;
|
||
|
||
if ( (sts = VDGetHead( lstHdl, &vhd))!=0)
|
||
goto RET;
|
||
while ( vhd->next != NIL) {
|
||
vp = vhd->headp;
|
||
for ( np = 0; np < vhd->nPoints; np++, vp = vp->next) {
|
||
vp->vd.x =(short)((long)vp->vd.x*outMesh*uFp/xinMesh)-center;
|
||
vp->vd.y =(short)((long)vp->vd.y*outMesh*uFp/yinMesh)-center;
|
||
}
|
||
vhd = vhd->next;
|
||
}
|
||
RET:
|
||
return sts;
|
||
}
|
||
/***********************************************************************
|
||
* Pre-Proc1 of smoothing( divide long vector )
|
||
*/
|
||
/* */ static int
|
||
/* */ preproc1( int inLst, int outLst)
|
||
/*
|
||
* returns : 0. -1
|
||
***********************************************************************/
|
||
{
|
||
struct VHEAD *vhd;
|
||
int sts;
|
||
struct VDATA *vp;
|
||
int np;
|
||
struct vecdata vd;
|
||
|
||
if ( (sts = VDGetHead( inLst, &vhd))!=0)
|
||
goto RET;
|
||
VDNew( outLst);
|
||
while ( vhd->next != NIL) {
|
||
vp = vhd->headp;
|
||
for ( np = 0; np < vhd->nPoints; ) {
|
||
if ( vp->vd.atr & FOREWARD) {
|
||
if ( vp->next->vd.atr& BACKWARD) {
|
||
if ((sts = diveachside( vp, outLst))<0)
|
||
goto RET;
|
||
np++;
|
||
vp = vp->next;
|
||
}
|
||
else {
|
||
if ((sts=divoneside(vp, outLst))<0)
|
||
goto RET;
|
||
}
|
||
}
|
||
else if ((vp->vd.atr & BACKWARD)
|
||
&& (vp->prev->vd.atr & FOREWARD)==0){
|
||
|
||
if ( (sts = divoneside( vp, outLst))<0)
|
||
goto RET;
|
||
|
||
}
|
||
else { /* only copy */
|
||
vd = vp->vd;
|
||
if ( vp->vd.atr & NOSMOOTH)
|
||
vd.atr = SMOOTHANCHOR;
|
||
if ((sts=VDSetData( outLst, &vd))<0)
|
||
goto RET;
|
||
|
||
}
|
||
np++;
|
||
vp = vp->next;
|
||
}
|
||
|
||
if ( (sts = VDClose( outLst))<0)
|
||
break;
|
||
|
||
vhd = vhd->next;
|
||
}
|
||
RET:
|
||
return sts;
|
||
}
|
||
/***********************************************************************
|
||
* Divide Vector from each side( for PreProc)
|
||
*/
|
||
/* */ static int
|
||
/* */ diveachside( struct VDATA *vp, int outLst)
|
||
/*
|
||
* returns : 0, -1
|
||
***********************************************************************/
|
||
{
|
||
struct vecdata prev, cur, next1, next2, next3;
|
||
struct vecdata div1, div2;
|
||
int sts;
|
||
|
||
prev.x = vp->prev->vd.x - vp->prev->prev->vd.x;
|
||
prev.y = vp->prev->vd.y - vp->prev->prev->vd.y;
|
||
cur.x = vp->vd.x - vp->prev->vd.x;
|
||
cur.y = vp->vd.y - vp->prev->vd.y;
|
||
next1.x = vp->next->vd.x - vp->vd.x;
|
||
next1.y = vp->next->vd.y - vp->vd.y;
|
||
next2.x = vp->next->next->vd.x - vp->next->vd.x;
|
||
next2.y = vp->next->next->vd.y - vp->next->vd.y;
|
||
next3.x = vp->next->next->next->vd.x - vp->next->next->vd.x;
|
||
next3.y = vp->next->next->next->vd.y - vp->next->next->vd.y;
|
||
sts = 0;
|
||
if ( next1.x) {
|
||
if ( (sts = VDSetData( outLst, &vp->vd))<0)
|
||
goto RET;
|
||
div1.y = vp->vd.y;
|
||
div2.y = vp->vd.y;
|
||
div1.atr = SMOOTHANCHOR;
|
||
div2.atr = SMOOTHANCHOR;
|
||
if ( abs(prev.x) + abs( next3.x) <= abs(next1.x)) {
|
||
div1.x = vp->vd.x + prev.x;
|
||
if ( (sts = VDSetData( outLst, &div1))<0)
|
||
goto RET;
|
||
div2.x = vp->next->vd.x - next3.x;
|
||
if ( (sts = VDSetData( outLst, &div2))<0)
|
||
goto RET;
|
||
if ( (sts = VDSetData( outLst, &vp->next->vd))<0)
|
||
goto RET;
|
||
}
|
||
else {
|
||
div1.x = (short)((long)next1.x*abs(prev.x)/abs(prev.x + next3.x));
|
||
if ( div1.x != 0) {
|
||
div1.x += vp->vd.x;
|
||
if ( (sts = VDSetData( outLst, &div1))<0)
|
||
goto RET;
|
||
if ( (sts = VDSetData( outLst, &vp->next->vd))<0)
|
||
goto RET;
|
||
}
|
||
else {
|
||
div1.x = vp->next->vd.x;
|
||
div1.y = vp->next->vd.y;
|
||
if ( (sts = VDSetData( outLst, &div1))<0)
|
||
goto RET;
|
||
}
|
||
}
|
||
}
|
||
else {
|
||
div1.x = vp->vd.x;
|
||
div2.x = vp->vd.x;
|
||
div1.atr = SMOOTHANCHOR;
|
||
div2.atr = SMOOTHANCHOR;
|
||
if ( (sts = VDSetData( outLst, &vp->vd))<0)
|
||
goto RET;
|
||
if ( abs(prev.y) + abs( next3.y) <= abs(next1.y)) {
|
||
// div1.y = vp->vd.y + prev.y;
|
||
div1.y = vp->vd.y + prev.y/2;
|
||
if ( (sts = VDSetData( outLst, &div1))<0)
|
||
goto RET;
|
||
// div2.y = vp->next->vd.y - next3.y;
|
||
div2.y = vp->next->vd.y - next3.y/2;
|
||
if ( (sts = VDSetData( outLst, &div2))<0)
|
||
goto RET;
|
||
if ( (sts = VDSetData( outLst, &vp->next->vd))<0)
|
||
goto RET;
|
||
}
|
||
else {
|
||
div1.y = (short)((long)next1.y*abs(prev.y)/abs(prev.y + next3.y));
|
||
if ( div1.y!=0) {
|
||
div1.y += vp->vd.y;
|
||
if ( (sts = VDSetData( outLst, &div1))<0)
|
||
goto RET;
|
||
if ( (sts = VDSetData( outLst, &vp->next->vd))<0)
|
||
goto RET;
|
||
}
|
||
else {
|
||
div1.x = vp->next->vd.x;
|
||
div1.y = vp->next->vd.y;
|
||
if ( (sts = VDSetData( outLst, &div1))<0)
|
||
goto RET;
|
||
}
|
||
}
|
||
}
|
||
RET:
|
||
return( sts);
|
||
}
|
||
/***********************************************************************
|
||
*
|
||
*/
|
||
/* */ static int
|
||
/* */ divoneside(
|
||
/* */ struct VDATA *vp,
|
||
/* */ int outLst)
|
||
/*
|
||
*
|
||
***********************************************************************/
|
||
{
|
||
struct vecdata prev, cur, next1, next2;
|
||
struct vecdata div1;
|
||
int sts;
|
||
|
||
sts = 0;
|
||
div1.atr = SMOOTHANCHOR;
|
||
if ( vp->vd.atr & FOREWARD) {
|
||
if ( (sts = VDSetData( outLst, &vp->vd))<0)
|
||
goto RET;
|
||
prev.x = vp->prev->vd.x - vp->prev->prev->vd.x;
|
||
prev.y = vp->prev->vd.y - vp->prev->prev->vd.y;
|
||
cur.x = vp->vd.x - vp->prev->vd.x;
|
||
cur.y = vp->vd.y - vp->prev->vd.y;
|
||
next1.x = vp->next->vd.x - vp->vd.x;
|
||
next1.y = vp->next->vd.y - vp->vd.y;
|
||
|
||
if ( vp->vd.x == vp->prev->vd.x) {
|
||
if ( abs(prev.x) < abs(next1.x)) {
|
||
div1.y = vp->vd.y;
|
||
// div1.x = vp->vd.x + prev.x;
|
||
div1.x = vp->vd.x + prev.x/2;
|
||
if ( (sts = VDSetData( outLst, &div1))<0)
|
||
goto RET;
|
||
}
|
||
}
|
||
else {
|
||
if ( abs(prev.y) < abs(next1.y)) {
|
||
div1.x = vp->vd.x;
|
||
// div1.y = vp->vd.y + prev.y;
|
||
div1.y = vp->vd.y + prev.y/2;
|
||
if ( (sts = VDSetData( outLst, &div1))<0)
|
||
goto RET;
|
||
}
|
||
}
|
||
}
|
||
else {
|
||
cur.x = vp->vd.x - vp->prev->vd.x;
|
||
cur.y = vp->vd.y - vp->prev->vd.y;
|
||
next2.x = vp->next->next->vd.x - vp->next->vd.x;
|
||
next2.y = vp->next->next->vd.y - vp->next->vd.y;
|
||
if ( vp->vd.x == vp->next->vd.x) {
|
||
if ( abs(cur.x) > abs(next2.x)) {
|
||
// div1.x = vp->vd.x - next2.x;
|
||
div1.x = vp->vd.x - next2.x/2;
|
||
div1.y = vp->vd.y;
|
||
if ( (sts = VDSetData( outLst, &div1))<0)
|
||
goto RET;
|
||
}
|
||
}
|
||
else {
|
||
if ( abs(cur.y) > abs(next2.y)) {
|
||
div1.x = vp->vd.x;
|
||
// div1.y = vp->vd.y - next2.y;
|
||
div1.y = vp->vd.y - next2.y/2;
|
||
if ( (sts = VDSetData( outLst, &div1))<0)
|
||
goto RET;
|
||
}
|
||
}
|
||
if ( (sts = VDSetData( outLst, &vp->vd))<0)
|
||
goto RET;
|
||
}
|
||
RET:
|
||
return( sts);
|
||
}
|
||
/***********************************************************************
|
||
* Smoothing 1
|
||
*/
|
||
/* */ static int
|
||
/* */ Smooth1( int inLst,
|
||
/* */ int outLst,
|
||
/* */ int weight1, /* Waight of Smoothing Form.*/
|
||
/* */ int weight2,
|
||
/* */ int weight3 )
|
||
/*
|
||
* returns : 0, -1
|
||
***********************************************************************/
|
||
{
|
||
struct VHEAD *vhd;
|
||
int sts;
|
||
struct VDATA *svp, *evp;
|
||
int sp, ep;
|
||
|
||
if ( (sts = VDGetHead( inLst, &vhd))!=0)
|
||
goto RET;
|
||
VDNew( outLst);
|
||
while ( vhd->next != NIL) {
|
||
svp = vhd->headp;
|
||
if ((sp=searchanchor(0,svp,&svp,vhd->nPoints))<vhd->nPoints){
|
||
|
||
while(sp <vhd->nPoints) {
|
||
ep = searchanchor(sp+1, svp->next,&evp, vhd->nPoints);
|
||
if ((sts=smooth1sub( svp, ep-sp,outLst,weight1, weight2, weight3))<0)
|
||
goto RET;
|
||
if ( ep >= vhd->nPoints)
|
||
break;
|
||
sp = ep;
|
||
svp = evp;
|
||
}
|
||
}
|
||
vhd = vhd->next;
|
||
if ( (sts = VDClose( outLst)) < 0)
|
||
break;
|
||
}
|
||
RET:
|
||
return sts;
|
||
}
|
||
/***********************************************************************
|
||
* Smoothing 2 ( mabiki)
|
||
*/
|
||
/* */ static int
|
||
/* */ Smooth2( int inLst, int outLst )
|
||
/*
|
||
* returns : 0, -1
|
||
***********************************************************************/
|
||
{
|
||
struct VHEAD *vhd;
|
||
int sts;
|
||
struct VDATA *svp, *evp;
|
||
int sp, ep;
|
||
|
||
if ( (sts = VDGetHead( inLst, &vhd))!=0)
|
||
goto RET;
|
||
VDNew( outLst);
|
||
while ( vhd->next != NIL) {
|
||
svp = vhd->headp;
|
||
if ((sp=searchanchor(0,svp,&svp,vhd->nPoints))<vhd->nPoints){
|
||
|
||
while(sp <vhd->nPoints) {
|
||
ep = searchanchor(sp+1, svp->next,&evp, vhd->nPoints);
|
||
if ((sts=smooth2sub( svp, ep-sp,outLst))<0)
|
||
goto RET;
|
||
if ( ep >= vhd->nPoints)
|
||
break;
|
||
sp = ep;
|
||
svp = evp;
|
||
}
|
||
}
|
||
vhd = vhd->next;
|
||
if ( (sts = VDClose( outLst)) < 0)
|
||
break;
|
||
}
|
||
RET:
|
||
return sts;
|
||
}
|
||
/***********************************************************************
|
||
* Search Smoothing Anchor Point
|
||
*/
|
||
/* */ int
|
||
/* */ searchanchor(
|
||
/* */ int sn,
|
||
/* */ struct VDATA *sp,
|
||
/* */ struct VDATA **ep,
|
||
/* */ int lim)
|
||
/*
|
||
*
|
||
***********************************************************************/
|
||
{
|
||
while ( lim-- > 0) {
|
||
if (sp->vd.atr & SMOOTHANCHOR) {
|
||
*ep = sp;
|
||
return sn;
|
||
}
|
||
sp = sp->next;
|
||
sn++;
|
||
}
|
||
return( sn);
|
||
}
|
||
/***********************************************************************
|
||
* Smooth1 body
|
||
*/
|
||
/* */ static int
|
||
/* */ smooth1sub(
|
||
/* */ struct VDATA *vp,
|
||
/* */ int np,
|
||
/* */ int outLst,
|
||
/* */ int w1, /* Waight of Smoothing Form.*/
|
||
/* */ int w2,
|
||
/* */ int w3)
|
||
/*
|
||
* returns : 0, -1
|
||
***********************************************************************/
|
||
{
|
||
int pcnt,
|
||
sts;
|
||
struct vecdata vd;
|
||
int base;
|
||
|
||
if ( (sts = VDSetData( outLst, &vp->vd))<0)
|
||
goto RET;
|
||
np--;
|
||
vp = vp->next;
|
||
base = w1 + w2 + w3;
|
||
for ( pcnt = 0; pcnt < np; pcnt++, vp= vp->next) {
|
||
vd.x = (vp->prev->vd.x*w1 + vp->vd.x*w2 + vp->next->vd.x*w3)/base;
|
||
vd.y = (vp->prev->vd.y*w1 + vp->vd.y*w2 + vp->next->vd.y*w3)/base;
|
||
vd.atr = vp->vd.atr;
|
||
if ( (sts = VDSetData( outLst, &vd))<0)
|
||
break;
|
||
}
|
||
RET:
|
||
return( sts);
|
||
}
|
||
/***********************************************************************
|
||
* Smooth2 body ( mabiki body)
|
||
*/
|
||
/* */ static int
|
||
/* */ smooth2sub(
|
||
/* */ struct VDATA *vp,
|
||
/* */ int np,
|
||
/* */ int outLst)
|
||
/*
|
||
* returns : 0, -1
|
||
***********************************************************************/
|
||
{
|
||
int pcnt,
|
||
sts;
|
||
|
||
if ( (sts = VDSetData( outLst, &vp->vd))<0)
|
||
goto RET;
|
||
np--;
|
||
vp = vp->next;
|
||
for ( pcnt = 0; pcnt < np; pcnt++, vp= vp->next) {
|
||
if ( np < 3 || pcnt % 2 == 0) {
|
||
if ( (sts = VDSetData( outLst, &vp->vd))<0)
|
||
break;
|
||
}
|
||
}
|
||
RET:
|
||
return( sts);
|
||
}
|
||
/***********************************************************************
|
||
* Remove Fixed Point
|
||
*/
|
||
/* */ int
|
||
/* */ RemoveFp(
|
||
/* */ int lstHdl, /* List Handle to proccess */
|
||
/* */ int outMesh, /* output mesh */
|
||
/* */ int uFp) /* Under Fixed Point Value */
|
||
/*
|
||
* returns : none
|
||
* remarks : ƒXƒ€<C692>[ƒYƒBƒ“ƒO‚Ì<E2809A>ˆ—<CB86>Œ‹‰Ê‚Ì<E2809A>À•WŒn‚Í<E2809A>AUFp‚ÅŠ„‚Á‚ÄŒ´“_‚ð
|
||
* (128,128) [=outMesh/2]‚Ɉړ®‚µ‚½’l‚Å‚ ‚é
|
||
***********************************************************************/
|
||
{
|
||
struct VHEAD *vhd;
|
||
int sts;
|
||
struct VDATA *vp;
|
||
int center;
|
||
int np;
|
||
|
||
center = outMesh/2;
|
||
|
||
if ( (sts = VDGetHead( lstHdl, &vhd))!=0)
|
||
goto RET;
|
||
while ( vhd->next != NIL) {
|
||
vp = vhd->headp;
|
||
for ( np = 0; np < vhd->nPoints; np++, vp = vp->next) {
|
||
vp->vd.x = vp->vd.x / uFp+center;
|
||
if ( vp->vd.x < 0) vp->vd.x = 0;
|
||
else if ( vp->vd.x >= outMesh) vp->vd.x = outMesh-1;
|
||
|
||
vp->vd.y = vp->vd.y / uFp+center;
|
||
if ( vp->vd.y < 0) vp->vd.y = 0;
|
||
else if ( vp->vd.y >= outMesh) vp->vd.y = outMesh-1;
|
||
}
|
||
vhd = vhd->next;
|
||
}
|
||
RET:
|
||
return sts;
|
||
}
|
||
|
||
/***********************************************************************
|
||
* Bind same direction vector
|
||
*/
|
||
/* */ static int
|
||
/* */ BindLinears( int inLst, int outLst)
|
||
/*
|
||
***********************************************************************/
|
||
{
|
||
struct VHEAD *vhd;
|
||
int sts;
|
||
struct VDATA *vp;
|
||
int np;
|
||
struct vecdata rel1, rel2;
|
||
|
||
VDNew( outLst);
|
||
if ( (sts = VDGetHead( inLst, &vhd))!=0)
|
||
goto RET;
|
||
while ( vhd->next != NIL) {
|
||
vp = vhd->headp;
|
||
/* Origin */
|
||
if ( (sts = VDSetData( outLst, &vp->vd))<0)
|
||
goto RET;
|
||
vp = vp->next;
|
||
for ( np = 1; np < vhd->nPoints; np++, vp = vp->next) {
|
||
if ( np+1 >= vhd->nPoints) {
|
||
if ((sts=VDSetData( outLst, &vp->vd))<0)
|
||
goto RET;
|
||
break;
|
||
}
|
||
else if ( vp->vd.atr&SPLINE_ATR) {
|
||
|
||
if ((sts=VDSetData( outLst, &vp->vd))<0)
|
||
goto RET;
|
||
/* End Point */
|
||
vp = vp->next;
|
||
np++;
|
||
if ( np >= vhd->nPoints)
|
||
break;
|
||
if ( (sts = VDSetData( outLst, &vp->vd))<0)
|
||
goto RET;
|
||
}
|
||
else {
|
||
rel1.x = vp->next->vd.x - vp->vd.x;
|
||
rel1.y = vp->next->vd.y - vp->vd.y;
|
||
rel2.x = vp->vd.x - vp->prev->vd.x;
|
||
rel2.y = vp->vd.y - vp->prev->vd.y;
|
||
if ( (vp->next->vd.atr & SPLINE_ATR )
|
||
|| (long)rel1.x*rel2.y != (long)rel1.y*rel2.x) {
|
||
if ( (sts = VDSetData( outLst, &vp->vd))<0)
|
||
goto RET;
|
||
}
|
||
}
|
||
}
|
||
if ( (sts = VDClose( outLst))<0)
|
||
goto RET;
|
||
vhd = vhd->next;
|
||
}
|
||
RET:
|
||
return( sts);
|
||
}
|
||
/***********************************************************************
|
||
* Deleate Zero Vector ( about Non Curve Part)
|
||
*/
|
||
/* */ static int
|
||
/* */ DelZeroVec( int inLst, int outLst)
|
||
/*
|
||
***********************************************************************/
|
||
{
|
||
struct VHEAD *vhd;
|
||
int sts;
|
||
struct VDATA *vp;
|
||
int np;
|
||
|
||
VDNew( outLst);
|
||
if ( (sts = VDGetHead( inLst, &vhd))!=0)
|
||
goto RET;
|
||
while ( vhd->next != NIL) {
|
||
vp = vhd->headp;
|
||
/* Origin */
|
||
if ( (sts = VDSetData( outLst, &vp->vd))<0)
|
||
goto RET;
|
||
vp = vp->next;
|
||
for ( np = 1; np < vhd->nPoints; np++, vp = vp->next) {
|
||
if ( vp->vd.atr&SPLINE_ATR) {
|
||
/* Control Point */
|
||
if ( (sts = VDSetData( outLst, &vp->vd))<0)
|
||
goto RET;
|
||
/* End Point */
|
||
vp = vp->next;
|
||
np++;
|
||
if ( np >= vhd->nPoints)
|
||
break;
|
||
if ( (sts = VDSetData( outLst, &vp->vd))<0)
|
||
goto RET;
|
||
}
|
||
else {
|
||
if ( vp->vd.x != vp->prev->vd.x
|
||
|| vp->vd.y != vp->prev->vd.y) {
|
||
if ((sts=VDSetData( outLst, &vp->vd))<0)
|
||
goto RET;
|
||
}
|
||
}
|
||
}
|
||
if ( (sts = VDClose( outLst))<0)
|
||
goto RET;
|
||
vhd = vhd->next;
|
||
}
|
||
RET:
|
||
return( sts);
|
||
}
|
||
/* X |Y
|
||
* O------------ +-|------+
|
||
* | | | | |
|
||
* | | ---> | | |
|
||
* | | -----+-------------X
|
||
* |-------+ O-|------+
|
||
* |Y |
|
||
*/
|
||
int
|
||
toTTFFrame( int lstH, struct BBX *bbx)
|
||
{
|
||
struct VHEAD *vhd;
|
||
struct VDATA *vp;
|
||
int np;
|
||
int sts;
|
||
short mesh;
|
||
|
||
if ( (sts = VDGetHead( lstH, &vhd))!=0)
|
||
goto RET;
|
||
if ( (sts = VDGetNCont( lstH))<=0)
|
||
goto RET;
|
||
mesh = bbx->xMax - bbx->xMin+1;
|
||
if ( mesh > bbx->yMax - bbx->yMin)
|
||
mesh = bbx->yMax - bbx->yMin+1;
|
||
while ( vhd->next != NIL) {
|
||
vp = vhd->headp;
|
||
np = vhd->nPoints;
|
||
while ( np-->0) {
|
||
vp->vd.x += (short)bbx->xMin;
|
||
vp->vd.y = (mesh - 1) - vp->vd.y + bbx->yMin;
|
||
/* Limit in BBX */
|
||
if ( vp->vd.x > bbx->xMax)
|
||
vp->vd.x = (short)bbx->xMax;
|
||
else if (vp->vd.x < bbx->xMin)
|
||
vp->vd.x = (short)bbx->xMin;
|
||
if ( vp->vd.y > bbx->yMax)
|
||
vp->vd.y = (short)bbx->yMax;
|
||
else if (vp->vd.y < bbx->yMin)
|
||
vp->vd.y = (short)bbx->yMin;
|
||
vp = vp->next;
|
||
}
|
||
vhd = vhd->next;
|
||
}
|
||
sts = 0;
|
||
RET:
|
||
return sts;
|
||
}
|
||
static int
|
||
lightSub( int inLst, int outLst)
|
||
{
|
||
struct VHEAD *vhd;
|
||
int sts;
|
||
struct VDATA *svp, *evp;
|
||
int sp, ep;
|
||
if ( (sts = VDGetHead( inLst, &vhd))!=0)
|
||
goto RET;
|
||
VDNew( outLst);
|
||
while ( vhd->next != NIL) {
|
||
svp = vhd->headp;
|
||
if ((sp=searchanchor(0,svp,&svp,vhd->nPoints))<vhd->nPoints){
|
||
|
||
while(sp <vhd->nPoints) {
|
||
ep = searchanchor(sp+1, svp->next,&evp, vhd->nPoints);
|
||
if ((sts=smooth1sub( svp, ep-sp,outLst,1, 2, 1))<0)
|
||
goto RET;
|
||
if ( ep >= vhd->nPoints)
|
||
break;
|
||
sp = ep;
|
||
svp = evp;
|
||
}
|
||
}
|
||
vhd = vhd->next;
|
||
if ( (sts = VDClose( outLst)) < 0)
|
||
break;
|
||
}
|
||
RET:
|
||
return sts;
|
||
}
|
||
static int
|
||
divVec( int ilst, int olst, int divN)
|
||
{
|
||
struct VHEAD *vhd;
|
||
struct VDATA *vp;
|
||
struct vecdata rel, vd;
|
||
int np;
|
||
int n;
|
||
|
||
if ( VDGetHead( ilst, &vhd)!=0)
|
||
goto RET;
|
||
VDNew( olst);
|
||
while ( vhd->next != NIL) {
|
||
vp = vhd->headp;
|
||
np = vhd->nPoints;
|
||
while ( np-->0) {
|
||
if (VDSetData(olst, &vp->vd))
|
||
goto RET;
|
||
rel.x = vp->next->vd.x - vp->vd.x;
|
||
rel.y = vp->next->vd.y - vp->vd.y;
|
||
vd.atr = 0;
|
||
for ( n=1; n<divN; n++) {
|
||
vd.x = vp->vd.x+rel.x*n/divN;
|
||
vd.y = vp->vd.y+rel.y*n/divN;
|
||
if (VDSetData(olst, &vd))
|
||
goto RET;
|
||
}
|
||
vp = vp->next;
|
||
}
|
||
vhd = vhd->next;
|
||
VDClose( olst);
|
||
}
|
||
return 0;
|
||
RET:
|
||
return -1;
|
||
}
|
||
int
|
||
SmoothLight( int ioLst, int tmpLst, int width, int height, int oWidth, int ufpVal)
|
||
{
|
||
int sts;
|
||
|
||
if ( (sts = BindPoint( ioLst, tmpLst))<0)
|
||
goto RET;
|
||
if ( (sts = DetectNoSmooth( tmpLst))<0)
|
||
goto RET;
|
||
if ( (sts = ZoomPoint( tmpLst, width, height, oWidth, ufpVal))<0)
|
||
goto RET;
|
||
if ( (sts = preproc1( tmpLst, ioLst))<0)
|
||
goto RET;
|
||
|
||
|
||
if ( sts = divVec( ioLst, tmpLst, 2))
|
||
goto RET;
|
||
if ( lightSub( tmpLst, ioLst))
|
||
goto RET;
|
||
if ( lightSub( ioLst, tmpLst))
|
||
goto RET;
|
||
|
||
if ( RemoveFp( tmpLst, oWidth, ufpVal))
|
||
goto RET;
|
||
if ( (sts = DelZeroVec( tmpLst, ioLst))<0)
|
||
goto RET;
|
||
return 0;
|
||
RET:
|
||
return -1;
|
||
}
|
||
int
|
||
ConvMesh( int lstH, int inMesh, int outMesh)
|
||
{
|
||
struct VHEAD *vhd;
|
||
struct VDATA *vp;
|
||
int np;
|
||
int sts;
|
||
if ( inMesh==outMesh)
|
||
return 0;
|
||
if ( (sts = VDGetHead( lstH, &vhd))!=0)
|
||
goto RET;
|
||
if ( (sts = VDGetNCont( lstH))<=0)
|
||
goto RET;
|
||
while ( vhd->next != NIL) {
|
||
vp = vhd->headp;
|
||
np = vhd->nPoints;
|
||
while ( np-->0) {
|
||
vp->vd.x = (int)((long)vp->vd.x*outMesh/inMesh);
|
||
vp->vd.y = (int)((long)vp->vd.y*outMesh/inMesh);
|
||
vp = vp->next;
|
||
}
|
||
vhd = vhd->next;
|
||
}
|
||
sts = 0;
|
||
RET:
|
||
return sts;
|
||
}
|
||
/* EOF */
|