windows-nt/Source/XPSP1/NT/shell/osshell/accesory/eudcedit/smooth.cpp
2020-09-26 16:20:57 +08:00

1328 lines
32 KiB
C++
Raw Permalink Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

//
// 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>´“_Í<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 */