📄 glyph.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 + -