919 lines
32 KiB
C++
919 lines
32 KiB
C++
|
#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;
|
|||
|
}
|
|||
|
|