QuiltingHMI/datafile/hpgl/vectorfont.cpp

919 lines
32 KiB
C++
Raw Normal View History

2024-02-06 07:10:48 +00:00
#include "vectorfont.h"
#include <QFile>
#include <qmath.h>
#include "main.h"
VectorFont::VectorFont(QObject *parent) :
QObject(parent)
{
m_iDPMM = 40;
m_pChinese_char = NULL;
m_pEnglish_char = NULL;
m_nChinese_char_count = 0;
m_nEnglish_char_count = 0;
IniVectorFont();
}
VectorFont::~VectorFont()
{
if(m_pChinese_char != NULL)
{
delete []m_pChinese_char;
m_pChinese_char = NULL;
}
if(m_pEnglish_char != NULL)
{
delete []m_pEnglish_char;
m_pEnglish_char = NULL;
}
}
void VectorFont::IniVectorFont()
{
QFile fntFile;
QString strCharFileName;
BYTE byte[10];
int nCharCount_C;
int nCharCount_E;
CChinese_char Chinese_char1;
CEnglish_char English_char1;
int nCountChar;
QString appPath = QCoreApplication::applicationDirPath();
QChar separator = QChar('/');
if(!appPath.contains(separator)) // 判断分隔符
{
separator = QChar('\\');
}
m_workPath = appPath + separator;
strCharFileName = m_workPath + "english.fnt";
//qDebug()<< "strCharFileName" << strCharFileName;
fntFile.setFileName(strCharFileName);
if(!fntFile.open(QIODevice::ReadOnly))
{
qDebug() <<"english file open failed";
return;
}
fntFile.seek(0);
fntFile.read((char*)byte,10);
m_nInternalLeading_E=(int)((WORD)byte[0] | ((WORD)byte[1] << 8));
m_nHeight_E=(int)((WORD)byte[2] | ((WORD)byte[3] << 8));
m_nDescent_E=(int)((WORD)byte[4] | ((WORD)byte[5] << 8));
nCharCount_E=(int)((DWORD)byte[6] | ((DWORD)byte[7] << 8) | ((DWORD)byte[9] << 16) | ((DWORD)byte[9] << 24));
//m_aEnglish_char.clear();
m_pEnglish_char = new CEnglish_char[nCharCount_E];
m_nEnglish_char_count = nCharCount_E;
fntFile.seek(10);
nCountChar=nCharCount_E;
while (nCountChar > 0)
{
fntFile.read((char*)byte,10);
English_char1.m_wCharCode=(WORD)byte[0] | ((WORD)byte[1] << 8);
English_char1.m_wBytes=(WORD)byte[2] | ((WORD)byte[3] << 8);
English_char1.m_wWidth=(WORD)byte[4] | ((WORD)byte[5] << 8);
English_char1.m_dwPosition=(DWORD)byte[6] | ((DWORD)byte[7] << 8) | ((DWORD)byte[9] << 16) | ((DWORD)byte[9] << 24);
m_pEnglish_char[nCharCount_E-nCountChar] = English_char1;
//m_aEnglish_char.append(English_char1);
nCountChar--;
}
fntFile.close();
strCharFileName = m_workPath + "Hz.fnt";
//qDebug()<< "strCharFileName" << strCharFileName;
fntFile.setFileName(strCharFileName);
if(!fntFile.open(QIODevice::ReadOnly))
{
qDebug() <<"chinese file open failed";
return;
}
fntFile.seek(0);
fntFile.read((char*)byte,8);
m_nWidth_C=(int)((WORD)byte[0] | ((WORD)byte[1] << 8));
m_nHeight_C=(int)((WORD)byte[2] | ((WORD)byte[3] << 8));
nCharCount_C=(int)((DWORD)byte[4] | ((DWORD)byte[5] << 8) | ((DWORD)byte[6] << 16) | ((DWORD)byte[7] << 24));
//m_aChinese_char.clear();
m_pChinese_char = new CChinese_char[nCharCount_C];
m_nChinese_char_count = nCharCount_C;
fntFile.seek(8);
nCountChar=nCharCount_C;
while (nCountChar > 0)
{
fntFile.read((char*)byte,8);
Chinese_char1.m_wCharCode=(WORD)byte[0] | ((WORD)byte[1] << 8);
Chinese_char1.m_wBytes=(WORD)byte[2] | ((WORD)byte[3] << 8);
Chinese_char1.m_dwPosition=(DWORD)byte[4] | ((DWORD)byte[5] << 8) | ((DWORD)byte[6] << 16) | ((DWORD)byte[7] << 24);
m_pChinese_char[nCharCount_C-nCountChar] = Chinese_char1;
//m_aChinese_char.append(Chinese_char1);
nCountChar--;
}
fntFile.close();
m_dFontAngle = 0;
m_dFontHeight = 0.375 * 10 * m_iDPMM;
}
//输入参数:
// ptPointLU 显示字符串的左上角坐标(即TextOut(...)的x,y值)
// pbyData 字符的描述数据
// wBytes 字符的描述数据个数
// nLeft,nDown 字符的左下角坐标(即以英汉字库的公共单位及坐标水平绘制字符串时,字符的的左下角坐标)
// nFontScale 字库的长度比例
void VectorFont::PlotChar(QPoint ptPointLU,BYTE *pbyData,WORD wBytes,int nLeft,int nDown,int nFontScale)
{
BYTE byByteX,byByteY;
QPoint ptCurrentPos,ptCenter,ptPointS,ptPointE;
QPoint ptPoint1;
WORD wIndex1;
WORD wDirection,wLength;
BOOL bPenUp,bVerTextCommand,bClockwise;
WORD wRadius,wArcS,wSpan;
int nRadius;
double dAngleS,dAngleE,dAngleOffsetS,dAngleOffsetE;
double dx1,dy1,dx2,dy2,dxc,dyc,dr,dD,dH,dBulge;
double dCos,dSin;
double dLToDScale;
int nHeight;
if (wBytes == 0) return;
nHeight=(m_nInternalLeading_E + m_nHeight_E) * m_nHeight_E;
//nHeight=(m_nInternalLeading_E + m_nHeight_E) * m_nHeight_C; //之前
dLToDScale=(double)nHeight / m_dFontHeight;
m_dRake = m_dFontAngle/180.0*PI;
dCos=cos(m_dRake);
dSin=sin(m_dRake);
ptCurrentPos=QPoint(nLeft,nDown);
ptPoint1=CPToLP(ptCurrentPos,nHeight,ptPointLU,dSin,dCos,dLToDScale);
MoveTo(ptPoint1);
bVerTextCommand=false;
bPenUp=false;
wIndex1=0;
while (wIndex1 < wBytes) {
switch (pbyData[wIndex1]) {
case 0x0:
wIndex1++;
break;
case 0x1:
wIndex1++;
bPenUp=false;
break;
case 0x2:
wIndex1++;
bPenUp=true;
break;
case 0x3:
wIndex1++;
wIndex1++;
bVerTextCommand=false;
break;
case 0x4:
wIndex1++;
wIndex1++;
bVerTextCommand=false;
break;
case 0x5:
wIndex1++;
bPenUp=true;
break;
case 0x6:
wIndex1++;
bPenUp=true;
break;
case 0x7:
wIndex1++;
wIndex1++;
bPenUp=true;
break;
case 0x8:
if (bVerTextCommand) {
wIndex1=wIndex1+3;
}
else {
wIndex1++;
ptCurrentPos.setX(ptCurrentPos.x() + (char)pbyData[wIndex1] * nFontScale);
wIndex1++;
ptCurrentPos.setY(ptCurrentPos.y() + (char)pbyData[wIndex1] * nFontScale);
ptPoint1=CPToLP(ptCurrentPos,nHeight,ptPointLU,dSin,dCos,dLToDScale);
if (bPenUp)
MoveTo(ptPoint1);
else
LineTo(ptPoint1);
wIndex1++;
}
bVerTextCommand=false;
break;
case 0x9:
if (bVerTextCommand) {
wIndex1++;
byByteX=pbyData[wIndex1];
wIndex1++;
byByteY=pbyData[wIndex1];
while ((byByteX != 0) || (byByteY != 0)) {
wIndex1++;
byByteX=pbyData[wIndex1];
wIndex1++;
byByteY=pbyData[wIndex1];
}
wIndex1++;
}
else {
wIndex1++;
byByteX=pbyData[wIndex1];
wIndex1++;
byByteY=pbyData[wIndex1];
while ((byByteX != 0) || (byByteY != 0)) {
ptCurrentPos.setX(ptCurrentPos.x() + (char)byByteX * nFontScale);
ptCurrentPos.setY(ptCurrentPos.y() + (char)byByteY * nFontScale);
ptPoint1=CPToLP(ptCurrentPos,nHeight,ptPointLU,dSin,dCos,dLToDScale);
if (bPenUp)
MoveTo(ptPoint1);
else
LineTo(ptPoint1);
wIndex1++;
byByteX=pbyData[wIndex1];
wIndex1++;
byByteY=pbyData[wIndex1];
}
wIndex1++;
}
bVerTextCommand=false;
break;
case 0xA:
if (bVerTextCommand) {
wIndex1=wIndex1+3;
}
else {
wIndex1++;
wRadius=(WORD)pbyData[wIndex1];
wIndex1++;
if (((char)pbyData[wIndex1]) < 0) bClockwise=true;
else bClockwise=false;
wArcS=(WORD)pbyData[wIndex1];
wArcS=wArcS & 0x70;
wArcS=wArcS >> 4;
wSpan=(WORD)pbyData[wIndex1];
wSpan=wSpan & 0x7;
//计算圆心
ptCenter=ptCurrentPos;
ptCenter.setX(ptCenter.x() - ((double)wRadius * (double)nFontScale * cos((double)wArcS * 45.0 / 180.0 * 3.14159265359))+0.5);
ptCenter.setY(ptCenter.y() - ((double)wRadius * (double)nFontScale * sin((double)wArcS * 45.0 / 180.0 * 3.14159265359))+0.5);
dAngleS=(double)wArcS * 45.0 / 180.0 * 3.14159265359;
if (bClockwise) dAngleE=dAngleS - (double)wSpan * 45.0 / 180.0 * 3.14159265359;
else dAngleE=dAngleS + (double)wSpan * 45.0 / 180.0 * 3.14159265359;
if (bClockwise) {
ptPointS.setX(ptCenter.x() + (double)wRadius * (double)nFontScale * cos(dAngleE)+0.5);
ptPointS.setY(ptCenter.y() + (double)wRadius * (double)nFontScale * sin(dAngleE)+0.5);
ptPointE.setX(ptCenter.x() + (double)wRadius * (double)nFontScale * cos(dAngleS)+0.5);
ptPointE.setY(ptCenter.y() + (double)wRadius * (double)nFontScale * sin(dAngleS)+0.5);
ptCurrentPos=ptPointS;
}
else {
ptPointS.setX(ptCenter.x() + (double)wRadius * (double)nFontScale * cos(dAngleS)+0.5);
ptPointS.setY(ptCenter.y() + (double)wRadius * (double)nFontScale * sin(dAngleS)+0.5);
ptPointE.setX(ptCenter.x() + (double)wRadius * (double)nFontScale * cos(dAngleE)+0.5);
ptPointE.setY(ptCenter.y() + (double)wRadius * (double)nFontScale * sin(dAngleE)+0.5);
ptCurrentPos=ptPointE;
}
ptCenter=CPToLP(ptCenter,nHeight,ptPointLU,dSin,dCos,dLToDScale);
ptPointS=CPToLP(ptPointS,nHeight,ptPointLU,dSin,dCos,dLToDScale);
ptPointE=CPToLP(ptPointE,nHeight,ptPointLU,dSin,dCos,dLToDScale);
nRadius=(double)wRadius * (double)nFontScale / dLToDScale + 0.5;
Arc(ptCenter.x() - nRadius,ptCenter.y() - nRadius,
ptCenter.x() + nRadius,ptCenter.y() + nRadius,
ptPointS.x(),ptPointS.y(),ptPointE.x(),ptPointE.y());
ptPoint1=CPToLP(ptCurrentPos,nHeight,ptPointLU,dSin,dCos,dLToDScale);
MoveTo(ptPoint1);
wIndex1++;
}
bVerTextCommand=false;
break;
case 0xB:
if (bVerTextCommand) {
wIndex1=wIndex1+6;
}
else {
wIndex1++;
dAngleOffsetS=(double)((WORD)pbyData[wIndex1]);
wIndex1++;
dAngleOffsetE=(double)((WORD)pbyData[wIndex1]);
wIndex1++;
wRadius=(WORD)pbyData[wIndex1];
wRadius=wRadius << 8;
wIndex1++;
wRadius=wRadius | (WORD)pbyData[wIndex1];
wIndex1++;
if (((char)pbyData[wIndex1]) < 0) bClockwise=true;
else bClockwise=false;
wArcS=(WORD)pbyData[wIndex1];
wArcS=wArcS & 0x70;
wArcS=wArcS >> 4;
wSpan=(WORD)pbyData[wIndex1];
wSpan=wSpan & 0x7;
//计算圆心
ptCenter=ptCurrentPos;
ptCenter.setX(ptCenter.x() - (double)wRadius * (double)nFontScale * cos((double)wArcS * 45.0 / 180.0 * 3.14159265359)+0.5);
ptCenter.setY(ptCenter.y() - (double)wRadius * (double)nFontScale * sin((double)wArcS * 45.0 / 180.0 * 3.14159265359)+0.5);
dAngleS=(double)wArcS * 45.0;
dAngleS=dAngleOffsetS * 45.0 / 256.0 + dAngleS;
if (bClockwise) dAngleE=-(double)wSpan * 45.0;
else dAngleE=(double)wSpan * 45.0;
dAngleE=dAngleOffsetE * 45.0 / 256.0 + dAngleE;
dAngleE=dAngleOffsetE * 45.0 / 256.0 + dAngleE;
dAngleS=dAngleS / 180.0 * 3.14159265359;
dAngleE=dAngleE / 180.0 * 3.14159265359;
if (bClockwise) {
ptPointS.setX(ptCenter.x() + (double)wRadius * (double)nFontScale * cos(dAngleE)+0.5);
ptPointS.setY(ptCenter.y() + (double)wRadius * (double)nFontScale * sin(dAngleE)+0.5);
ptPointE.setX(ptCenter.x() + (double)wRadius * (double)nFontScale * cos(dAngleS)+0.5);
ptPointE.setY(ptCenter.y() + (double)wRadius * (double)nFontScale * sin(dAngleS)+0.5);
ptCurrentPos=ptPointS;
}
else {
ptPointS.setX(ptCenter.x() + (double)wRadius * (double)nFontScale * cos(dAngleS)+0.5);
ptPointS.setY(ptCenter.y() + (double)wRadius * (double)nFontScale * sin(dAngleS)+0.5);
ptPointE.setX(ptCenter.x() + (double)wRadius * (double)nFontScale * cos(dAngleE)+0.5);
ptPointE.setY(ptCenter.y() + (double)wRadius * (double)nFontScale * sin(dAngleE)+0.5);
ptCurrentPos=ptPointE;
}
ptCenter=CPToLP(ptCenter,nHeight,ptPointLU,dSin,dCos,dLToDScale);
ptPointS=CPToLP(ptPointS,nHeight,ptPointLU,dSin,dCos,dLToDScale);
ptPointE=CPToLP(ptPointE,nHeight,ptPointLU,dSin,dCos,dLToDScale);
nRadius=(double)wRadius * (double)nFontScale / dLToDScale + 0.5;
Arc(ptCenter.x() - nRadius,ptCenter.y() - nRadius,
ptCenter.x() + nRadius,ptCenter.y() + nRadius,
ptPointS.x(),ptPointS.y(),ptPointE.x(),ptPointE.y());
ptPoint1=CPToLP(ptCurrentPos,nHeight,ptPointLU,dSin,dCos,dLToDScale);
MoveTo(ptPoint1);
wIndex1++;
}
bVerTextCommand=false;
break;
case 0xC:
if (bVerTextCommand) {
wIndex1=wIndex1+4;
}
else {
wIndex1++;
dx1=(double)((char)pbyData[wIndex1]) * (double)nFontScale;
wIndex1++;
dy1=(double)((char)pbyData[wIndex1]) * (double)nFontScale;
wIndex1++;
dBulge=(double)((char)pbyData[wIndex1]);
if (((char)pbyData[wIndex1]) < 0) bClockwise=true;
else bClockwise=false;
dD=sqrt(dx1*dx1 + dy1*dy1);
dH=fabs(dBulge) * dD / 127.0 / 2.0;
if (((char)pbyData[wIndex1]) == 0) {
ptCurrentPos.setX(ptCurrentPos.x() + (int)dx1);
ptCurrentPos.setY(ptCurrentPos.y() - (int)dy1);
ptPoint1=CPToLP(ptCurrentPos,nHeight,ptPointLU,dSin,dCos,dLToDScale);
if (bPenUp) MoveTo(ptPoint1);
else LineTo(ptPoint1);
}
else {
if (bClockwise) {
dx2=-dy1;
dy2=dx1;
}
else {
dx2=dy1;
dy2=-dx1;
}
dx2=dx2 / dD * dH + dx1 / 2.0;
dy2=dy2 / dD * dH + dy1 / 2.0;
CircleCR(0.0,0.0,dx2,dy2,dx1,dy1,dxc,dyc,dr);
ptCenter.setX(ptCurrentPos.x() + dxc + 0.5);
ptCenter.setY(ptCurrentPos.y() + dyc + 0.5);
if (bClockwise)
{
ptPointS.setX(ptCurrentPos.x() + dx1 + 0.5);
ptPointS.setY(ptCurrentPos.y() + dy1 + 0.5 );
ptPointE=ptCurrentPos;
ptCurrentPos=ptPointS;
}
else
{
ptPointS=ptCurrentPos;
ptPointE.setX(ptCurrentPos.x() + dx1 + 0.5);
ptPointE.setY(ptCurrentPos.y() + dy1 + 0.5);
ptCurrentPos=ptPointE;
}
ptCenter=CPToLP(ptCenter,nHeight,ptPointLU,dSin,dCos,dLToDScale);
ptPointS=CPToLP(ptPointS,nHeight,ptPointLU,dSin,dCos,dLToDScale);
ptPointE=CPToLP(ptPointE,nHeight,ptPointLU,dSin,dCos,dLToDScale);
nRadius=dr / dLToDScale + 0.5;
Arc(ptCenter.x() - nRadius,ptCenter.y() - nRadius,ptCenter.x() + nRadius,ptCenter.y() + nRadius,
ptPointS.x(),ptPointS.y(),ptPointE.x(),ptPointE.y());
ptPoint1=CPToLP(ptCurrentPos,nHeight,ptPointLU,dSin,dCos,dLToDScale);
MoveTo(ptPoint1);
}
wIndex1++;
}
bVerTextCommand=false;
break;
case 0xD:
if (bVerTextCommand) {
wIndex1=wIndex1+4;
}
else {
wIndex1++;
while ((pbyData[wIndex1] != 0) || (pbyData[wIndex1+1] != 0)) {
dx1=(double)((char)pbyData[wIndex1]) * (double)nFontScale;
wIndex1++;
dy1=(double)((char)pbyData[wIndex1]) * (double)nFontScale;
wIndex1++;
dBulge=(double)((char)pbyData[wIndex1]);
if (((char)pbyData[wIndex1]) < 0) bClockwise=true;
else bClockwise=false;
dD=sqrt(dx1*dx1 + dy1*dy1);
dH=fabs(dBulge) * dD / 127.0 / 2.0;
if (((char)pbyData[wIndex1]) == 0) {
ptCurrentPos.setX(ptCurrentPos.x() + (int)dx1);
ptCurrentPos.setY(ptCurrentPos.y() - (int)dy1);
ptPoint1=CPToLP(ptCurrentPos,nHeight,ptPointLU,dSin,dCos,dLToDScale);
if (bPenUp)
MoveTo(ptPoint1);
else
LineTo(ptPoint1);
}
else {
if (bClockwise) {
dx2=-dy1;
dy2=dx1;
}
else {
dx2=dy1;
dy2=-dx1;
}
dx2=dx2 / dD * dH + dx1 / 2.0;
dy2=dy2 / dD * dH + dy1 / 2.0;
CircleCR(0.0,0.0,dx2,dy2,dx1,dy1,dxc,dyc,dr);
ptCenter.setX(ptCurrentPos.x() + dxc + 0.5);
ptCenter.setY(ptCurrentPos.y() + dyc + 0.5);
if (bClockwise)
{
ptPointS.setX(ptCurrentPos.x() + dx1 + 0.5);
ptPointS.setY(ptCurrentPos.y() + dy1 + 0.5);
ptPointE=ptCurrentPos;
ptCurrentPos=ptPointS;
}
else
{
ptPointS=ptCurrentPos;
ptPointE.setX(ptCurrentPos.x() + dx1 + 0.5);
ptPointE.setY(ptCurrentPos.y() + dy1 + 0.5);
ptCurrentPos=ptPointE;
}
ptCenter=CPToLP(ptCenter,nHeight,ptPointLU,dSin,dCos,dLToDScale);
ptPointS=CPToLP(ptPointS,nHeight,ptPointLU,dSin,dCos,dLToDScale);
ptPointE=CPToLP(ptPointE,nHeight,ptPointLU,dSin,dCos,dLToDScale);
nRadius=dr / dLToDScale + 0.5;
Arc(ptCenter.x() - nRadius,ptCenter.y() - nRadius,ptCenter.x() + nRadius,ptCenter.y() + nRadius,
ptPointS.x(),ptPointS.y(),ptPointE.x(),ptPointE.y());
ptPoint1=CPToLP(ptCurrentPos,nHeight,ptPointLU,dSin,dCos,dLToDScale);
MoveTo(ptPoint1);
}
wIndex1++;
}
}
bVerTextCommand=false;
break;
case 0xE:
bVerTextCommand=true;
wIndex1++;
break;
default:
if (bVerTextCommand) {
wIndex1++;
}
else {
wDirection=(WORD)(pbyData[wIndex1] % 16);
wLength=(WORD)(pbyData[wIndex1] / 16) * (WORD)nFontScale;
ptCurrentPos=GetNextCoodinate(wDirection,wLength,ptCurrentPos);
ptPoint1=CPToLP(ptCurrentPos,nHeight,ptPointLU,dSin,dCos,dLToDScale);
if (bPenUp) MoveTo(ptPoint1);
else LineTo(ptPoint1);
wIndex1++;
}
bVerTextCommand=false;
break;
}
}
}
QPoint VectorFont::CPToLP(QPoint ptCP,int nHeight,QPoint ptPointLU,double dSin,double dCos,double dScale)
{
double dx,dy;
QPoint ptPoint1;
dx=(double)ptCP.x();
dy=(double)ptCP.y()-(double)nHeight;
ptPoint1.setX(ptPointLU.x() + ((dx*dCos - dy*dSin) / dScale + 0.5));
ptPoint1.setY(ptPointLU.y() + ((dx*dSin + dy*dCos) / dScale + 0.5));
return ptPoint1;
}
//抬笔移动到点(x,y)
void VectorFont::MoveTo(long x, long y)
{
if(x == 0){}
if(y == 0){}
}
//抬笔移动到点ptPoint
void VectorFont::MoveTo(QPoint ptPoint)
{
emit siMoveTo(true,ptPoint);
}
//从当前位置画线到点(x,y)
void VectorFont::LineTo(long x, long y)
{
if(x == 0){}
if(y == 0){}
}
//从当前位置画线到点ptPoint
void VectorFont::LineTo(QPoint ptPoint)
{
emit siLineTo(false,ptPoint);
}
//从(x,y)点开始写字nCount为字节数
void VectorFont::TextOutString(int x, int y, const char* lpszString, int nCount)
{
QString strEnglish,strChinese;
QFile fileEnglish,fileChinese;
BYTE *pbyData;
int nLeft;
BYTE byByte1,byByte2;
WORD wCharCode;
int nIndex1,nIndex2,nIndex3,nIndex4;
bool bEnglishChar;
strEnglish = m_workPath + "english.fnt";
strChinese = m_workPath + "Hz.fnt";
fileEnglish.setFileName(strEnglish);
if(!fileEnglish.open(QIODevice::ReadOnly))
{
qDebug() <<"file open failed";
return;
}
fileChinese.setFileName(strChinese);
if(!fileChinese.open(QIODevice::ReadOnly))
{
qDebug() <<"file open failed";
return;
}
nLeft=0;
nIndex1=0;
while (nIndex1 < nCount)
{
pbyData=NULL;
byByte1=(BYTE)lpszString[nIndex1];
if ((byByte1 >= 128) && ((nIndex1+1) < nCount))
{
bEnglishChar=false;
nIndex1++;
byByte2=(BYTE)lpszString[nIndex1];
wCharCode=(((WORD)byByte1) << 8) | (WORD)byByte2;
nIndex2=0;
nIndex3=m_nChinese_char_count - 1;
if (m_pChinese_char[nIndex2].m_wCharCode == wCharCode) nIndex4=nIndex2;
else if (m_pChinese_char[nIndex3].m_wCharCode == wCharCode) nIndex4=nIndex3;
else nIndex4=(nIndex2 + nIndex3) / 2;
while (((nIndex3 - nIndex2) > 1) &&
(m_pChinese_char[nIndex4].m_wCharCode != wCharCode))
{
if (m_pChinese_char[nIndex4].m_wCharCode > wCharCode)
{
nIndex3=nIndex4;
if (nIndex2 > nIndex3) break;
nIndex4=(nIndex2 + nIndex3) / 2;
}
else
{
nIndex2=nIndex4;
if (nIndex2 > nIndex3) break;
nIndex4=(nIndex2 + nIndex3) / 2;
}
}
if ((m_pChinese_char[nIndex4].m_wCharCode == wCharCode) &&
(m_pChinese_char[nIndex4].m_wBytes > 0))
{
pbyData=new BYTE[m_pChinese_char[nIndex4].m_wBytes + 1];
fileChinese.seek(m_pChinese_char[nIndex4].m_dwPosition);
fileChinese.read((char*)pbyData,m_pChinese_char[nIndex4].m_wBytes);
}
}
else
{
bEnglishChar=true;
wCharCode=(WORD)byByte1;
nIndex2=0;
nIndex3=m_nEnglish_char_count - 1;
if (m_pEnglish_char[nIndex2].m_wCharCode == wCharCode) nIndex4=nIndex2;
else if (m_pEnglish_char[nIndex3].m_wCharCode == wCharCode) nIndex4=nIndex3;
else nIndex4=(nIndex2 + nIndex3) / 2;
while (((nIndex3 - nIndex2) > 1) &&
(m_pEnglish_char[nIndex4].m_wCharCode != wCharCode))
{
if (m_pEnglish_char[nIndex4].m_wCharCode > wCharCode)
{
nIndex3=nIndex4;
if (nIndex2 > nIndex3) break;
nIndex4=(nIndex2 + nIndex3) / 2;
}
else
{
nIndex2=nIndex4;
if (nIndex2 > nIndex3) break;
nIndex4=(nIndex2 + nIndex3) / 2;
}
}
if ((m_pEnglish_char[nIndex4].m_wCharCode == wCharCode) &&
(m_pEnglish_char[nIndex4].m_wBytes > 0)) {
pbyData=new BYTE[m_pEnglish_char[nIndex4].m_wBytes + 1];
fileEnglish.seek(m_pEnglish_char[nIndex4].m_dwPosition);
fileEnglish.read((char*)pbyData,m_pEnglish_char[nIndex4].m_wBytes);
}
}
if (pbyData != NULL)
{
if (bEnglishChar)
{
PlotChar(QPoint(x,y),pbyData,m_pEnglish_char[nIndex4].m_wBytes,nLeft,0,m_nHeight_C);
}
else
{
PlotChar(QPoint(x,y),pbyData,m_pChinese_char[nIndex4].m_wBytes,nLeft,0,m_nInternalLeading_E + m_nHeight_E);
}
delete []pbyData;
if (bEnglishChar) nLeft=nLeft + m_pEnglish_char[nIndex4].m_wWidth * m_nHeight_C;
else nLeft=nLeft + m_nWidth_C * (m_nInternalLeading_E + m_nHeight_E);
}
else
{
if (bEnglishChar) nLeft=nLeft + m_pEnglish_char[0].m_wWidth * m_nHeight_C;
else nLeft=nLeft + m_nWidth_C * (m_nInternalLeading_E + m_nHeight_E);
}
nIndex1++;
}
fileEnglish.close();
fileChinese.close();
}
//画弧从Start逆时针画到End
void VectorFont::Arc(int nLeftRect,int nTopRect,int nRightRect,int nBottomRect,
int nXStartArc,int nYStartArc,int nXEndArc,int nYEndArc)
{
double dXC,dYC,dRadius;
double dx,dy;
double dAngleS,dAngleE,dAngle,dStep;
double dCos,dSin;
int nCount;
dXC=((double)nLeftRect + (double)nRightRect) / 2.0;
dYC=((double)nTopRect + (double)nBottomRect) / 2.0;
dRadius=((double)nRightRect - (double)nLeftRect) / 2.0;
dAngleS=angle_2(dXC,dYC,(double)nXStartArc,(double)nYStartArc);
dAngleE=angle_2(dXC,dYC,(double)nXEndArc,(double)nYEndArc);
while (dAngleE >= dAngleS) dAngleE=dAngleE - 2.0 * PI;
if ((nXStartArc == nXEndArc) && (nYStartArc == nYEndArc))
{
dAngleS=0.0;
dAngleE=-2.0 * PI;
}
dSin=qSin(dAngleS);
dCos=qCos(dAngleS);
dx=dRadius * dCos + dXC;
dy=dRadius * dSin + dYC;
MoveTo(dx+0.5,dy+0.5);
nCount=120;
dStep=PI / 180.0 * (360.0 / (double)nCount); //3度
dAngle=dAngleS;
while (dAngle > dAngleE)
{
dAngle=dAngle - dStep;
if (dAngle < dAngleE) dAngle=dAngleE;
dSin=qSin(dAngle);
dCos=qCos(dAngle);
dx=dRadius * dCos + dXC;
dy=dRadius * dSin + dYC;
LineTo(dx+0.5,dy+0.5);
}
}
QPoint VectorFont::GetNextCoodinate(WORD wDirection,WORD wLength,QPoint ptPoint)
{
QPoint ptPoint1;
switch (wDirection) {
case 0:
ptPoint1.setX( ptPoint.x() + (int)wLength);
ptPoint1.setY(ptPoint.y());
break;
case 1:
ptPoint1.setX(ptPoint.x() + (int)wLength);
ptPoint1.setY(ptPoint.y() + (int)wLength/2);
break;
case 2:
ptPoint1.setX(ptPoint.x() + (int)wLength);
ptPoint1.setY(ptPoint.y() + (int)wLength);
break;
case 3:
ptPoint1.setX(ptPoint.x() + (int)wLength/2);
ptPoint1.setY(ptPoint.y() + (int)wLength);
break;
case 4:
ptPoint1.setX(ptPoint.x());
ptPoint1.setY(ptPoint.y() + (int)wLength);
break;
case 5:
ptPoint1.setX(ptPoint.x() - (int)wLength/2);
ptPoint1.setY(ptPoint.y() + (int)wLength);
break;
case 6:
ptPoint1.setX(ptPoint.x() - (int)wLength);
ptPoint1.setY(ptPoint.y() + (int)wLength);
break;
case 7:
ptPoint1.setX(ptPoint.x() - (int)wLength);
ptPoint1.setY(ptPoint.y() + (int)wLength/2);
break;
case 8:
ptPoint1.setX(ptPoint.x() - (int)wLength);
ptPoint1.setY(ptPoint.y());
break;
case 9:
ptPoint1.setX(ptPoint.x() - (int)wLength);
ptPoint1.setY(ptPoint.y() - (int)wLength/2);
break;
case 10:
ptPoint1.setX(ptPoint.x() - (int)wLength);
ptPoint1.setY(ptPoint.y() - (int)wLength);
break;
case 11:
ptPoint1.setX(ptPoint.x() - (int)wLength/2);
ptPoint1.setY(ptPoint.y() - (int)wLength);
break;
case 12:
ptPoint1.setX(ptPoint.x());
ptPoint1.setY(ptPoint.y() - (int)wLength);
break;
case 13:
ptPoint1.setX(ptPoint.x() + (int)wLength/2);
ptPoint1.setY(ptPoint.y() - (int)wLength);
break;
case 14:
ptPoint1.setX(ptPoint.x() + (int)wLength);
ptPoint1.setY(ptPoint.y() - (int)wLength);
break;
case 15:
ptPoint1.setX(ptPoint.x() + (int)wLength);
ptPoint1.setY(ptPoint.y() - (int)wLength/2);
break;
}
return ptPoint1;
}
//求两点确定的直线与X轴的夹角,在[0,2pi)之间
//输入参数:
// (startx,starty) 起点
// (endx,endy) 终点
//返回值:
// 夹角
double VectorFont::angle_2(int startx,int starty,int endx,int endy)
{
//直线与X轴之间的夹角 X轴向量OE(1,0)
double dAngle = 0;
if((endx == startx) && (endy == starty))
{
return dAngle;
}
//求直线的向量坐标
double dX = endx - startx;
double dY = endy - starty;
dAngle = qAcos((dX)/(qSqrt(dX*dX + dY*dY)));
return dAngle;
}
///////////////////////// 计算三点定圆时的圆心和半径 ///////////////////////////
// 输入参数:三个样点(x1,y1),(x2,y2),(x3,y3)
// 算法描述:
// 过(x1,y1),(x2,y2)的中点作垂线L1,
// 过(x2,y2),(x3,y3)的中点作垂线L2,
// 求L1,L2的交点.
// 输出参数:
// 如果不能形成圆返回false,
// 否则返回true其中圆心为(cx,cy),半径=cr.
// 按逆时针方向画弧时,如cr>0 则(x1,y1)是起点,(x3,y3)是终点,
// 如cr<0 则(x3,y3)是起点,(x1,y1)是终点.
// 特别说明:此处所说的逆时针是指显示器而言,如果对于对X向右为正,
// Y向上为正的坐标系来说此处是顺时针
//bool CircleCR(int x1,int y1,int x2,int y2,int x3,int y3,int& cx,int& cy,int& cr);
////////////////////////////////////////////////////////////////////////////////
bool VectorFont::CircleCR(double x1,double y1,double x2,double y2,double x3,double y3,double& cx,double& cy,double& cr)
{
double a1,b1,c1,a2,b2,c2;
if(((x1 ==x2) && (y1==y2)) || ((x1 ==x3) && (y1==y3)) || ((x2 ==x3) && (y2==y3)))
{
return false;
}
a1 = x1 - x2;
b1 = y1 - y2;
c1 = -a1 * (x1 + x2) / 2.0 - b1 * (y1 + y2)/2.0;
a2 = x3 - x2;
b2 = y3 - y2;
c2 = -a2 * (x2 + x3) / 2.0 - b2 * (y2 + y3)/2.0;
double D = a1*b2 - a2*b1;
if(D == 0)//两直线平行
{
return false;
}
cx = (b1*c2 - b2*c1)/D;
cy = (c1*a2 - c2*a1)/D;
//用圆心和其中一个点求距离得到半径:
cr = qSqrt((cx - x1)*(cx - x1) + (cy - y1)*(cy - y1));
return true;
}