PlotterHMI/datafile/hpgl/vectorfont.cpp
2024-02-06 14:19:53 +08:00

919 lines
32 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters

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.

#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;
}