⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 glyph.c

📁 windows环境下的一套汉字处理引擎,可以对汉字进行相应的处理
💻 C
字号:
/***********************************************************************
    Name:
	Glyph.c
    Module:
	ENGINE
    Discription:
	Provide a Bezier Poly Line Processing
    Date:
	Dec. 1993
    Created By:
	Wang Zhidong
    Exports:
	WseGlyphToPoly
	WsePolyBezier
***********************************************************************/

#include <Windows.h>
#include <Mate.h>
#include "engine.h"

UINT  wGlyphDeep = 12;

#ifndef DEMO
UINT ExpandOneGlyphToPoly (POINT, POINT, POINT, LPPOINT, int);
UINT ExpandGlyph3ToPoly   (POINT, POINT, POINT, POINT, LPPOINT, int);
UINT ExpandGP (int, int, int, int, int, int, LPPOINT, int, int);
UINT ExpandBP (int, int, int, int, int, int, int, int, LPPOINT, int, int);
UINT Glyph3ToPoly (POINT, POINT, LPPOINT, UINT, LPPOINT, UINT);

#define WseDrawBezier2(hDC,p1,p2,p3)	DrawBezier2(hDC,p1.x,p1.y,p2.x,p2.y,p3.x,p3.y,wGlyphDeep)
#define WseDrawBezier3(hDC,p1,p2,p3,p4) DrawBezier3(hDC,p1.x,p1.y,p2.x,p2.y,p3.x,p3.y,p4.x,p4.y,wGlyphDeep)

BOOL DrawBezier2 (HDC, int, int, int, int, int, int, int);
BOOL DrawBezier3 (HDC, int, int, int, int, int, int, int, int, int);
#endif

extern HANDLE hInst;

int MyAbs(int i)
{
    return (i < 0) ? -i : i;
}

POINT GetMidPoint (LPPOINT lpPt)
{
    POINT pt;
    pt.x = (lpPt[0].x+lpPt[1].x)>>1;
    pt.y = (lpPt[0].y+lpPt[1].y)>>1;
    return pt;
}

UINT ExpandGP (X1, Y1, X2, Y2, X3, Y3, lpPoly, wCnt, i)
int X1, Y1, X2, Y2, X3, Y3;
LPPOINT lpPoly;
int wCnt, i;
{
    UINT ii;

    if (i <= 0 || wCnt < 2)
	return NULL;

    else if (i == 1 ||
	     MyAbs(X2-X1)+MyAbs(Y2-Y1) < 4 || MyAbs(X3-X2)+MyAbs(Y3-Y2) < 4)
	{
	lpPoly->x = X2;
	lpPoly->y = Y2;
	return 1;
	}
    else if (i == 2)
	{
	lpPoly[0].x = (X1+X2)>>1;
	lpPoly[0].y = (Y1+Y2)>>1;
	lpPoly[1].x = (X3+X2)>>1;
	lpPoly[1].y = (Y3+Y2)>>1;
	return 2;
	}

    ii	= ExpandGP ( X1,	      Y1,
		    (X1+  X2   )>>1, (Y1+  Y2	)>>1,
		    (X1+2*X2+X3)>>2, (Y1+2*Y2+Y3)>>2,
		    lpPoly, wCnt, i-1);

    ii += ExpandGP ((X1+2*X2+X3+2)>>2,(Y1+2*Y2+Y3+2)>>2,
		    (	  X2+X3+1)>>1,	   (Y2+Y3+1)>>1,
			     X3,	     Y3,
		    lpPoly+ii, wCnt-ii, i-1);

    return ii;
}

UINT ExpandOneGlyphToPoly (Pt1, Pt2, Pt3, lpPoly, wCnt)
POINT	Pt1, Pt2, Pt3;
LPPOINT lpPoly;
int	wCnt;
{
    if (wCnt <= 0)
		return NULL;

    return ExpandGP (Pt1.x, Pt1.y, Pt2.x, Pt2.y, Pt3.x, Pt3.y,
		     lpPoly, wCnt, wGlyphDeep);
}

UINT WINAPI WseGlyphToPoly (
  POINT		BegPoint,
  POINT		EndPoint,
  LPPOINT 	lpGlyph,
  UINT		wGlyph,
  LPPOINT	lpPoly,
  UINT		wCnt,
  UINT		wType )
{
    UINT	i;
    UINT  	wPoly;
    POINT 	pt1, pt2;

    if (wCnt < wGlyph)
		return NULL;

#ifndef DEMO
    if (wType == PT_BEZIER3)
		return Glyph3ToPoly (BegPoint, EndPoint, lpGlyph, wGlyph, lpPoly, wCnt);

    if (wType != PT_BEZIER2 || wCnt == wGlyph || wGlyph < 1)
#endif
		{
		WseRepMovsb ((LPSTR)lpPoly, (LPSTR)lpGlyph, wGlyph*sizeof(POINT));
		return wGlyph;
		}
#ifndef DEMO
    if (wGlyph == 1)
		return ExpandOneGlyphToPoly (BegPoint, *lpGlyph, EndPoint,
					     lpPoly, wCnt);
    else
		{
		pt1 = GetMidPoint (lpGlyph);
		wPoly  = ExpandOneGlyphToPoly (BegPoint, *lpGlyph, pt1,
					       lpPoly, wCnt);
		for (i = 1; wPoly < wCnt && i < wGlyph-1; i++)
		    {
		    pt2 = GetMidPoint (lpGlyph+i);

		    wPoly += ExpandOneGlyphToPoly (pt1, lpGlyph[i], pt2,
						   lpPoly+wPoly, wCnt-wPoly);

		    lpPoly[wPoly] = lpGlyph[i];
		    wPoly++;
		    pt1 = pt2;
		    }
		if (wPoly < wCnt)
		    wPoly += ExpandOneGlyphToPoly (pt1, lpGlyph[i], EndPoint,
						    lpPoly+wPoly, wCnt-wPoly);
		return wPoly;
		}
#endif
}

#ifndef DEMO
UINT ExpandBP (X1, Y1, X2, Y2, X3, Y3, X4, Y4, lpPoly, wCnt, i)
int X1, Y1, X2, Y2, X3, Y3, X4, Y4;
LPPOINT lpPoly;
int wCnt, i;
{
    UINT ii;

    if (i <= 0 || wCnt < 4)
	return NULL;
    else if (i == 1 ||
	     MyAbs(X2-X1)+MyAbs(Y2-Y1)+MyAbs(X3-X2)+MyAbs(Y3-Y2)+
	     MyAbs(X4-X3)+MyAbs(Y4-Y3) < 10)
	{
	lpPoly[0].x = (X1+X2+1)/2;
	lpPoly[0].y = (Y1+Y2+1)/2;
	lpPoly[1].x = (X1+2*X2+X3+2)/4;
	lpPoly[1].y = (Y1+2*Y2+Y3+2)/4;
	lpPoly[2].x = (X2+2*X3+X4+2)/4;
	lpPoly[2].y = (Y2+2*Y3+Y4+2)/4;
	lpPoly[3].x = (X3+X4+1)/2;
	lpPoly[3].y = (Y3+Y4+1)/2;
	return 4;
	}

    ii	= ExpandBP (X1, 		   Y1,
		    (X1+X2+1)/2,	   (Y1+Y2+1)/2,
		    (X1+2*X2+X3+2)/4,	   (Y1+2*Y2+Y3+2)/4,
		    (X1+3*X2+3*X3+X4+4)/8, (Y1+3*Y2+3*Y3+Y4+4)/8,
		    lpPoly, wCnt, i-1);

    ii += ExpandBP ((X1+3*X2+3*X3+X4+4)/8, (Y1+3*Y2+3*Y3+Y4+4)/8,
		    (X2+2*X3+X4+2)/4, (Y2+2*Y3+Y4+2)/4,
		    (X3+X4+1)/2, (Y3+Y4+1)/2,
		    X4, Y4,
		    lpPoly+ii, wCnt-ii, i-1);
    return ii;
}

UINT ExpandGlyph3ToPoly (Pt1, Pt2, Pt3, Pt4, lpPoly, wCnt)
POINT	Pt1, Pt2, Pt3, Pt4;
LPPOINT lpPoly;
int	wCnt;
{
    if (!wCnt)
		return NULL;
    return ExpandBP (Pt1.x, Pt1.y, Pt2.x, Pt2.y, Pt3.x, Pt3.y, Pt4.x, Pt4.y,
		     lpPoly, wCnt, wGlyphDeep);
}

UINT Glyph3ToPoly (BegPoint, EndPoint, lpGlyph, wGlyph, lpPoly, wCnt)
POINT	BegPoint, EndPoint;
LPPOINT lpGlyph, lpPoly;
UINT	wGlyph, wCnt;
{
    UINT  i;
    UINT  wPoly;
    POINT pt1, pt2, pt3;

    if (wCnt < wGlyph)
		return NULL;

    if (wCnt == wGlyph || wGlyph < 2)
		{
		WseRepMovsb ((LPSTR)lpPoly, (LPSTR)lpGlyph, wGlyph*sizeof(POINT));
		return wGlyph;
		}

    switch (wGlyph)
		{
		case 2:
		    wPoly = ExpandGlyph3ToPoly (BegPoint, lpGlyph[0],
						lpGlyph[1], EndPoint,
						lpPoly, wCnt);
		    break;

		default:
		    pt1 = GetMidPoint (lpGlyph+1);
		    wPoly  = ExpandGlyph3ToPoly (BegPoint, lpGlyph[0], lpGlyph[1],
										 pt1, lpPoly, wCnt);
		    for (i = 2; wPoly < wCnt && i < wGlyph-2; i+=2)
				{
				pt2 = GetMidPoint (lpGlyph+i+1);
				wPoly += ExpandGlyph3ToPoly (pt1, lpGlyph[i], lpGlyph[i+1], pt2,
							     lpPoly+wPoly, wCnt-wPoly);
				pt1 = pt2;
				}
		    if (wPoly < wCnt)
				{
				if (wGlyph & 1)
				    {
				    pt2.x = (pt1.x+lpGlyph[i].x+1)/2;
				    pt2.y = (pt1.y+lpGlyph[i].y+1)/2;
				    pt3.x = (EndPoint.x+lpGlyph[i].x+1)/2;
				    pt3.y = (EndPoint.y+lpGlyph[i].y+1)/2;
				    wPoly += ExpandGlyph3ToPoly (pt1, pt2, pt3, EndPoint,
								 lpPoly+wPoly, wCnt-wPoly);
				    }
				else
				    wPoly += ExpandGlyph3ToPoly (pt1, lpGlyph[i],
								 lpGlyph[i+1], EndPoint,
								 lpPoly+wPoly, wCnt-wPoly);
				}
		}
    return wPoly;
}

BOOL DrawBezier2 (hDC, X1, Y1, X2, Y2, X3, Y3, wDeep)
HDC hDC;
int X1, Y1, X2, Y2, X3, Y3;
int wDeep;
{
    if (wDeep <= 0)
		{
		LineTo (hDC, X2, Y2);
		return FALSE;
		}

    if (wDeep == 1 ||
		MyAbs(X2-X1)+MyAbs(Y2-Y1)+MyAbs(X3-X2)+MyAbs(Y3-Y2) < 10)
		{
		LineTo (hDC, (X1+X2+1)/2, (Y1+Y2+1)/2);
		LineTo (hDC, (X2+X3+1)/2, (Y2+Y3+1)/2);
		return TRUE;
		}
    DrawBezier2 (hDC,
				 X1, Y1,
				 (X1+X2+1)/2, (Y1+Y2+1)/2,
				 (X1+2*X2+X3+2)/4, (Y1+2*Y2+Y3+2)/4,
				 wDeep-1);

    DrawBezier2 (hDC,
				 (X1+2*X2+X3+2)/4, (Y1+2*Y2+Y3+2)/4,
				 (X2+X3+1)/2, (Y2+Y3+1)/2,
				 X3, Y3,
				 wDeep-1);
    return TRUE;
}

BOOL DrawBezier3 (hDC, X1, Y1, X2, Y2, X3, Y3, X4, Y4, wDeep)
HDC hDC;
int X1, Y1, X2, Y2, X3, Y3, X4, Y4;
int wDeep;
{
    if (wDeep <= 0)
		{
		LineTo (hDC, X2, Y2);
		LineTo (hDC, X3, Y3);
		return FALSE;
		}

    if (wDeep == 1 ||
		MyAbs(X2-X1)+MyAbs(Y2-Y1)+MyAbs(X3-X2)+MyAbs(Y3-Y2)+
		MyAbs(X4-X3)+MyAbs(Y4-Y3) < 10)
		{
		LineTo (hDC, (X1+X2+1)/2, (Y1+Y2+1)/2);
		LineTo (hDC, (X1+2*X2+X3+2)/4, (Y1+2*Y2+Y3+2)/4);
		LineTo (hDC, (X2+2*X3+X4+2)/4, (Y2+2*Y3+Y4+2)/4);
		LineTo (hDC, (X3+X4+1)/2, (Y3+Y4+1)/2);
		return TRUE;
		}

    DrawBezier3 (hDC,
				 X1, Y1,
				 (X1+X2+1)/2, (Y1+Y2+1)/2,
				 (X1+2*X2+X3+2)/4, (Y1+2*Y2+Y3+2)/4,
				 (X1+3*X2+3*X3+X4+4)/8, (Y1+3*Y2+3*Y3+Y4+4)/8,
				 wDeep-1);
    DrawBezier3 (hDC,
				 (X1+3*X2+3*X3+X4+4)/8, (Y1+3*Y2+3*Y3+Y4+4)/8,
				 (X2+2*X3+X4+2)/4, (Y2+2*Y3+Y4+2)/4,
				 (X3+X4+1)/2, (Y3+Y4+1)/2,
				 X4, Y4,
				 wDeep-1);
    return TRUE;
}
#endif

BOOL WINAPI WsePolyBezier (HDC hDC, POINT BegP, POINT EndP, LPPOINT lpPoint, UINT wPtCnt, UINT wType)
{
    UINT i;
    POINT pt1, pt2, pt3;

    MoveTo (hDC, BegP.x, BegP.y);
    if (wPtCnt == 0)
		{
		LineTo (hDC, EndP.x, EndP.y);
		return TRUE;
		}

#ifndef DEMO
    if (wType == PT_BEZIER2)
		{
		if (wPtCnt == 1)
		    WseDrawBezier2 (hDC, BegP, lpPoint[0], EndP);
		else
		    {
		    pt1 = GetMidPoint (lpPoint);
		    WseDrawBezier2 (hDC, BegP, lpPoint[0], pt1);
		    for (i = 1; i < wPtCnt-1; i++)
				{
				pt2 = GetMidPoint (lpPoint+i);
				WseDrawBezier2 (hDC, pt1, lpPoint[i], pt2);
				pt1 = pt2;
				}
		    WseDrawBezier2 (hDC, pt1, lpPoint[i], EndP);
		    }
		}
    else if (wType == PT_BEZIER3)
		{
		switch (wPtCnt)
		    {
		    case 1:
				pt1.x = (BegP.x+lpPoint->x+1)/2;
				pt1.y = (BegP.y+lpPoint->y+1)/2;
				pt2.x = (EndP.x+lpPoint->x+1)/2;
				pt2.y = (EndP.y+lpPoint->y+1)/2;
				WseDrawBezier3 (hDC, BegP, pt1, pt2, EndP);
			break;

		    case 2:
				WseDrawBezier3 (hDC, BegP, lpPoint[0],
						lpPoint[1], EndP);
			break;

		    default:
				pt1 = GetMidPoint (lpPoint+1);
				WseDrawBezier3 (hDC, BegP, lpPoint[0],
						lpPoint[1], pt1);
				for (i = 2; i < wPtCnt-2; i+=2)
				    {
				    pt2 = GetMidPoint (lpPoint+i+1);
				    WseDrawBezier3 (hDC, pt1, lpPoint[i],
						    lpPoint[i+1], pt2);
				    pt1 = pt2;
				    }
			if (i == wPtCnt-2)
			    WseDrawBezier3 (hDC, pt1, lpPoint[i],
					    lpPoint[i+1], EndP);
			else
			    {
			    pt2.x = (pt1.x+lpPoint[i].x+1)/2;
			    pt2.y = (pt1.y+lpPoint[i].y+1)/2;
			    pt3.x = (EndP.x+lpPoint[i].x+1)/2;
			    pt3.y = (EndP.y+lpPoint[i].y+1)/2;
			    WseDrawBezier3 (hDC, pt1, pt2, pt3, EndP);
			    }
		    }
		}
    else
#endif
		{
		for (i = 0; i < wPtCnt; i++)
		    LineTo (hDC, lpPoint[i].x, lpPoint[i].y);
		}
    LineTo (hDC, EndP.x, EndP.y);
    return TRUE;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -