858 lines
24 KiB
C++
858 lines
24 KiB
C++
#include "stdafx.h"
|
|
#include "AecDbMText.h"
|
|
#include "GeRectAngle.h"
|
|
#include "globalFunc.h"
|
|
|
|
const Adesk::UInt8 AecXDbMText::g_nVersion = 1;
|
|
|
|
|
|
ACRX_DXF_DEFINE_MEMBERS(AecXDbMText, AecXDbText, AcDb::kDHL_CURRENT, AcDb::kMReleaseCurrent,
|
|
1, AEC_DUOHTEXT, "AEC_DUOHTEXT||图形无法解析, 请下载上华软件|网址: www.shanghuasoft.com");
|
|
|
|
AecXDbMText::AecXDbMText()
|
|
{
|
|
m_nAlignment = AcGiDraw::kTextFit;
|
|
m_nPageWidth = 0.0;
|
|
m_nLineSpace = 0.0;
|
|
}
|
|
|
|
|
|
AecXDbMText::~AecXDbMText()
|
|
{
|
|
}
|
|
|
|
// 只支持4种对齐方式
|
|
//BOOL AecXDbMText::IsValid() const
|
|
//{
|
|
// BOOL bRet = TDbEntity::IsValid();
|
|
// if (!bRet)
|
|
// return bRet;
|
|
// bRet = !!m_sText;
|
|
// if (bRet) {
|
|
// switch (m_nAlignment) {
|
|
// case XExplodeDraw::kLeft:
|
|
// case XExplodeDraw::kRight:
|
|
// case XExplodeDraw::kCenter:
|
|
// case XExplodeDraw::kTextFit:
|
|
// bRet = TRUE;
|
|
// break;
|
|
// default:
|
|
// bRet = FALSE;
|
|
// break;
|
|
// }
|
|
// }
|
|
// return bRet;
|
|
//}
|
|
|
|
// 提供对格式刷的支持
|
|
void AecXDbMText::CopyPropertiesFrom(AcDbEntity *pSrcEntity, unsigned gMatchFlag)
|
|
{
|
|
assertWriteEnabled();
|
|
AecXDbText::CopyPropertiesFrom(pSrcEntity, gMatchFlag);
|
|
AecXDbMText *pSrc = AecXDbMText::cast(pSrcEntity);
|
|
if (pSrc) {
|
|
//m_nPageWidth; //段落宽度
|
|
m_nPageWidth = pSrc->m_nPageWidth;
|
|
m_nLineSpace = pSrc->m_nLineSpace; //行间距
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
// 返回发现的位置,同时posStart往前移动(以便继续找下一个使用),
|
|
TextPosition
|
|
AecXDbMText::FindSubText(const TCHAR *sSubText, TextPosition &posStart, TextRange *pRange) const
|
|
{
|
|
TextPosition posFind = AecXDbText::FindSubText(sSubText, posStart);
|
|
if (!posFind || !pRange)
|
|
return posFind;
|
|
|
|
// 求pRange位置
|
|
AecXDbMText *pClone = (AecXDbMText *)clone();
|
|
pClone->m_sText[posFind.m_nTextPos] = EOS;
|
|
|
|
//起始位置
|
|
ADSGePoint3d ptTopLeft = pClone->m_ptText;
|
|
PtrList<TextLine> lstLines;
|
|
pClone->GetTextLines(lstLines);
|
|
int numLine = lstLines.Length();
|
|
if (numLine == 0)
|
|
numLine = 1;
|
|
double nYOffset = numLine * GetHeight(FALSE) + (numLine - 1) * GetLineSpace(FALSE);
|
|
|
|
double nAngWcs = GlobalFunc::AngleRangeTo2PI(m_nLayoutRotation + m_nRotation);
|
|
ADSGePoint3d ptLineStart;
|
|
ads_polar(m_ptText, nAngWcs - PI / 2, nYOffset, ptLineStart);
|
|
|
|
ADSGePoint3d vtExt;
|
|
if (lstLines.Tail())
|
|
vtExt = lstLines.Tail()->GetExtents();
|
|
ADSGePoint3d ptRangeStart;
|
|
ads_polar(ptLineStart, nAngWcs, vtExt.x, ptRangeStart);
|
|
|
|
pClone->m_sText << sSubText; //合上查找的串
|
|
lstLines.Reset();
|
|
pClone->GetTextLines(lstLines);
|
|
int numLineNew = lstLines.Length();
|
|
if (numLineNew == 0)
|
|
numLineNew = 1;
|
|
|
|
ADSGePoint3d ptLineStart2;
|
|
nYOffset = numLineNew * GetHeight(FALSE) + (numLineNew - 1) * GetLineSpace(FALSE);
|
|
ads_polar(m_ptText, nAngWcs - PI / 2, nYOffset, ptLineStart2);
|
|
ADSGePoint3d vtExt1;
|
|
if (lstLines.Tail())
|
|
vtExt1 = lstLines.Tail()->GetExtents();
|
|
ADSGePoint3d ptRangeEnd;
|
|
ads_polar(ptLineStart2, nAngWcs, vtExt1.x, ptRangeEnd);
|
|
|
|
pRange->m_lstRanges.Reset();
|
|
if (numLine == numLineNew) {
|
|
GePoly2D *pPoly = new GePoly2D(1);
|
|
pPoly->AppendNode(ptRangeStart);
|
|
pPoly->AppendNode(ptRangeEnd);
|
|
ADSGePoint3d ptTemp;
|
|
ads_polar(ptRangeEnd, nAngWcs + PI / 2, GetHeight(FALSE), ptTemp);
|
|
pPoly->AppendNode(ptTemp);
|
|
ads_polar(ptRangeStart, nAngWcs + PI / 2, GetHeight(FALSE), ptTemp);
|
|
pPoly->AppendNode(ptTemp);
|
|
pRange->m_lstRanges.Append(pPoly);
|
|
}
|
|
else {
|
|
double nPageWidth = GetPageWidth(FALSE);
|
|
ADSGePoint3d ptLineEnd;
|
|
ads_polar(ptLineStart, nAngWcs, nPageWidth, ptLineEnd);
|
|
|
|
GePoly2D *pPoly = new GePoly2D(1);
|
|
ADSGePoint3d ptTemp;
|
|
if (ptRangeStart.Distance2d(ptLineEnd) < g_Option::instance()._DIST_SNAP)
|
|
delete pPoly;
|
|
else {
|
|
pPoly->AppendNode(ptRangeStart);
|
|
pPoly->AppendNode(ptLineEnd);
|
|
ads_polar(ptLineEnd, nAngWcs + PI / 2, GetHeight(FALSE), ptTemp);
|
|
pPoly->AppendNode(ptTemp);
|
|
ads_polar(ptRangeStart, nAngWcs + PI / 2, GetHeight(FALSE), ptTemp);
|
|
pPoly->AppendNode(ptTemp);
|
|
pRange->m_lstRanges.Append(pPoly);
|
|
}
|
|
|
|
// 中间行
|
|
for (int n = 1; n < (numLineNew - numLine); n++) {
|
|
ADSGePoint3d ptLineStart1, ptLineEnd1;
|
|
ads_polar(ptLineStart, nAngWcs - PI / 2, n * (GetHeight(FALSE) + GetLineSpace(FALSE)), ptLineStart1);
|
|
ads_polar(ptLineStart1, nAngWcs, nPageWidth, ptLineEnd1);
|
|
GePoly2D *pPoly = new GePoly2D(1);
|
|
pPoly->AppendNode(ptLineStart1);
|
|
pPoly->AppendNode(ptLineEnd1);
|
|
ADSGePoint3d ptTemp;
|
|
ads_polar(ptLineEnd1, nAngWcs + PI / 2, GetHeight(FALSE), ptTemp);
|
|
pPoly->AppendNode(ptTemp);
|
|
ads_polar(ptLineStart1, nAngWcs + PI / 2, GetHeight(FALSE), ptTemp);
|
|
pPoly->AppendNode(ptTemp);
|
|
pRange->m_lstRanges.Append(pPoly);
|
|
}
|
|
|
|
// 最后一行
|
|
pPoly = new GePoly2D(1);
|
|
pPoly->AppendNode(ptLineStart2);
|
|
pPoly->AppendNode(ptRangeEnd);
|
|
ads_polar(ptRangeEnd, nAngWcs + PI / 2, GetHeight(FALSE), ptTemp);
|
|
pPoly->AppendNode(ptTemp);
|
|
ads_polar(ptLineStart2, nAngWcs + PI / 2, GetHeight(FALSE), ptTemp);
|
|
pPoly->AppendNode(ptTemp);
|
|
pRange->m_lstRanges.Append(pPoly);
|
|
}
|
|
|
|
delete pClone;
|
|
|
|
return posFind;
|
|
}
|
|
|
|
// 返回下一次查找的开始位置
|
|
TextPosition
|
|
AecXDbMText::ReplaceSubText(const TextPosition &posRep, const TCHAR *sRepText, TextRange *pRange)
|
|
{
|
|
TextPosition posNext = AecXDbText::ReplaceSubText(posRep, sRepText);
|
|
if (!posRep || !pRange)
|
|
return posNext;
|
|
|
|
// 求pRange位置
|
|
AecXDbMText *pClone = (AecXDbMText *)clone();
|
|
pClone->m_sText[posRep.m_nTextPos] = EOS;
|
|
|
|
//起始位置
|
|
ADSGePoint3d ptTopLeft = pClone->m_ptText;
|
|
PtrList<TextLine> lstLines;
|
|
pClone->GetTextLines(lstLines);
|
|
int numLine = lstLines.Length();
|
|
if (numLine == 0)
|
|
numLine = 1;
|
|
double nYOffset = numLine * GetHeight(FALSE) + (numLine - 1) * GetLineSpace(FALSE);
|
|
|
|
double nAngWcs = GlobalFunc::AngleRangeTo2PI(m_nLayoutRotation + m_nRotation);
|
|
ADSGePoint3d ptLineStart;
|
|
ads_polar(m_ptText, nAngWcs - PI / 2, nYOffset, ptLineStart);
|
|
|
|
ADSGePoint3d vtExt;
|
|
if (lstLines.Tail())
|
|
vtExt = lstLines.Tail()->GetExtents();
|
|
ADSGePoint3d ptRangeStart;
|
|
ads_polar(ptLineStart, nAngWcs, vtExt.x, ptRangeStart);
|
|
|
|
CString csText = (const TCHAR *)pClone->GetText();
|
|
csText += sRepText;
|
|
pClone->SetText(csText);
|
|
|
|
lstLines.Reset();
|
|
pClone->GetTextLines(lstLines);
|
|
int numLineNew = lstLines.Length();
|
|
if (numLineNew == 0)
|
|
numLineNew = 0;
|
|
ADSGePoint3d ptLineStart2;
|
|
nYOffset = numLineNew * GetHeight(FALSE) + (numLineNew - 1) * GetLineSpace(FALSE);
|
|
ads_polar(m_ptText, nAngWcs - PI / 2, nYOffset, ptLineStart2);
|
|
ADSGePoint3d vtExt1;
|
|
if (lstLines.Tail())
|
|
vtExt1 = lstLines.Tail()->GetExtents();
|
|
ADSGePoint3d ptRangeEnd;
|
|
ads_polar(ptLineStart2, nAngWcs, vtExt1.x, ptRangeEnd);
|
|
|
|
pRange->m_lstRanges.Reset();
|
|
if (numLine == numLineNew) {
|
|
GePoly2D *pPoly = new GePoly2D(1);
|
|
if (ptRangeStart.Distance2d(ptRangeEnd) < g_Option::instance()._DIST_SNAP)
|
|
delete pPoly;
|
|
else {
|
|
pPoly->AppendNode(ptRangeStart);
|
|
pPoly->AppendNode(ptRangeEnd);
|
|
ADSGePoint3d ptTemp;
|
|
ads_polar(ptRangeEnd, nAngWcs + PI / 2, GetHeight(FALSE), ptTemp);
|
|
pPoly->AppendNode(ptTemp);
|
|
ads_polar(ptRangeStart, nAngWcs + PI / 2, GetHeight(FALSE), ptTemp);
|
|
pPoly->AppendNode(ptTemp);
|
|
pRange->m_lstRanges.Append(pPoly);
|
|
}
|
|
}
|
|
else {
|
|
double nPageWidth = GetPageWidth(FALSE);
|
|
ADSGePoint3d ptLineEnd;
|
|
ads_polar(ptLineStart, nAngWcs, nPageWidth, ptLineEnd);
|
|
|
|
GePoly2D *pPoly = new GePoly2D(1);
|
|
ADSGePoint3d ptTemp;
|
|
if (ptRangeStart.Distance2d(ptLineEnd) < g_Option::instance()._DIST_SNAP)
|
|
delete pPoly;
|
|
else {
|
|
pPoly->AppendNode(ptRangeStart);
|
|
pPoly->AppendNode(ptLineEnd);
|
|
ads_polar(ptLineEnd, nAngWcs + PI / 2, GetHeight(FALSE), ptTemp);
|
|
pPoly->AppendNode(ptTemp);
|
|
ads_polar(ptRangeStart, nAngWcs + PI / 2, GetHeight(FALSE), ptTemp);
|
|
pPoly->AppendNode(ptTemp);
|
|
pRange->m_lstRanges.Append(pPoly);
|
|
}
|
|
|
|
// 中间行
|
|
for (int n = 1; n < (numLineNew - numLine); n++) {
|
|
ADSGePoint3d ptLineStart1, ptLineEnd1;
|
|
ads_polar(ptLineStart, nAngWcs - PI / 2, n * (GetHeight(FALSE) + GetLineSpace(FALSE)), ptLineStart1);
|
|
ads_polar(ptLineStart1, nAngWcs, nPageWidth, ptLineEnd1);
|
|
GePoly2D *pPoly = new GePoly2D(1);
|
|
pPoly->AppendNode(ptLineStart1);
|
|
pPoly->AppendNode(ptLineEnd1);
|
|
ADSGePoint3d ptTemp;
|
|
ads_polar(ptLineEnd1, nAngWcs + PI / 2, GetHeight(FALSE), ptTemp);
|
|
pPoly->AppendNode(ptTemp);
|
|
ads_polar(ptLineStart1, nAngWcs + PI / 2, GetHeight(FALSE), ptTemp);
|
|
pPoly->AppendNode(ptTemp);
|
|
pRange->m_lstRanges.Append(pPoly);
|
|
}
|
|
|
|
// 最后一行
|
|
pPoly = new GePoly2D(1);
|
|
pPoly->AppendNode(ptLineStart2);
|
|
pPoly->AppendNode(ptRangeEnd);
|
|
ads_polar(ptRangeEnd, nAngWcs + PI / 2, GetHeight(FALSE), ptTemp);
|
|
pPoly->AppendNode(ptTemp);
|
|
ads_polar(ptLineStart2, nAngWcs + PI / 2, GetHeight(FALSE), ptTemp);
|
|
pPoly->AppendNode(ptTemp);
|
|
pRange->m_lstRanges.Append(pPoly);
|
|
}
|
|
|
|
delete pClone;
|
|
|
|
return posNext;
|
|
}
|
|
|
|
|
|
//Acad::ErrorStatus
|
|
//AecXDbMText::subGetClassID(CLSID* pClsid) const
|
|
//{
|
|
// *pClsid = CLSID_ComMutiText;
|
|
// return Acad::eOk;
|
|
//}
|
|
|
|
// 从DWG读入数据:
|
|
Acad::ErrorStatus AecXDbMText::dwgInFields(AcDbDwgFiler* pFiler)
|
|
{
|
|
assertWriteEnabled();
|
|
|
|
Acad::ErrorStatus es = AecXDbText::dwgInFields(pFiler);
|
|
if (es != Acad::eOk) return es;
|
|
Adesk::UInt8 nVer;
|
|
pFiler->readItem(&nVer);
|
|
if (nVer > g_nVersion) {// Version is too new
|
|
return Acad::eMakeMeProxy;
|
|
}
|
|
|
|
pFiler->readItem(&m_nPageWidth);
|
|
pFiler->readItem(&m_nLineSpace);
|
|
return pFiler->filerStatus();
|
|
}
|
|
|
|
Acad::ErrorStatus AecXDbMText::dwgOutFields(AcDbDwgFiler* pFiler) const
|
|
{
|
|
assertReadEnabled();
|
|
Acad::ErrorStatus es = AecXDbText::dwgOutFields(pFiler);
|
|
if (es != Acad::eOk) return es;
|
|
|
|
pFiler->writeItem(g_nVersion);
|
|
pFiler->writeItem(m_nPageWidth);
|
|
pFiler->writeItem(m_nLineSpace);
|
|
return pFiler->filerStatus();
|
|
}
|
|
|
|
Acad::ErrorStatus AecXDbMText::dxfInFields(AcDbDxfFiler* pFiler)
|
|
{
|
|
assertWriteEnabled();
|
|
|
|
Acad::ErrorStatus es = AecXDbText::dxfInFields(pFiler);
|
|
if (es != Acad::eOk)
|
|
return es;
|
|
|
|
if (!pFiler->atSubclassData(_T("AecXDbMText"))) {
|
|
return Acad::eBadDxfSequence;
|
|
}
|
|
|
|
|
|
double r1, r2;
|
|
Adesk::UInt32 fieldsFlags = 0;
|
|
resbuf rb;
|
|
while ((es == Acad::eOk)
|
|
&& ((es = pFiler->readResBuf(&rb)) == Acad::eOk)) {
|
|
switch (rb.restype) {
|
|
case AcDb::kDxfReal + 1:
|
|
r1 = rb.resval.rreal;
|
|
fieldsFlags |= 0x01;
|
|
break;
|
|
case AcDb::kDxfReal + 2:
|
|
fieldsFlags |= 0x02;
|
|
r2 = rb.resval.rreal;
|
|
break;
|
|
//fall through intentional
|
|
default:
|
|
// An unrecognized group. Push it back so that
|
|
// the subclass can read it again.
|
|
pFiler->pushBackItem();
|
|
es = Acad::eEndOfFile;
|
|
break;
|
|
}
|
|
}
|
|
|
|
// At this point the es variable must contain eEndOfFile
|
|
// - either from readResBuf() or from pushback. If not,
|
|
// it indicates that an error happened and we should
|
|
// return immediately.
|
|
//
|
|
if (es != Acad::eEndOfFile)
|
|
return Acad::eInvalidResBuf;
|
|
if (!(fieldsFlags & 0x01)) {
|
|
pFiler->setError(Acad::eMissingDxfField,
|
|
_T("\nMissing DXF group code: 41"));
|
|
return Acad::eMissingDxfField;
|
|
}
|
|
|
|
m_nPageWidth = r1;
|
|
if (fieldsFlags & 0x02)
|
|
m_nLineSpace = r2;
|
|
return pFiler->filerStatus();
|
|
}
|
|
|
|
Acad::ErrorStatus AecXDbMText::dxfOutFields(AcDbDxfFiler* pFiler) const
|
|
{
|
|
assertReadEnabled();
|
|
Acad::ErrorStatus es = AecXDbText::dxfOutFields(pFiler);
|
|
assert(es == Acad::eOk);
|
|
|
|
es = pFiler->writeItem(AcDb::kDxfSubclass, _T("AecXDbMText"));
|
|
assert(es == Acad::eOk);
|
|
pFiler->writeDouble(AcDb::kDxfReal + 1, m_nPageWidth);
|
|
pFiler->writeDouble(AcDb::kDxfReal + 2, m_nLineSpace);
|
|
return es;
|
|
}
|
|
|
|
// Active when being rotated, scaled, moved, etc.
|
|
// Scale is disabled here
|
|
Acad::ErrorStatus AecXDbMText::subTransformBy(const AcGeMatrix3d& xform)
|
|
{
|
|
assertWriteEnabled();
|
|
AecXDbText::subTransformBy(xform);
|
|
|
|
ads_matrix mat;
|
|
GlobalFunc::AsAdsMatrix(xform, mat);
|
|
|
|
if (!g_Option::instance().g_bLayoutRotate)
|
|
{
|
|
double nAngWcs = GlobalFunc::AngleRangeTo2PI(m_nLayoutRotation + m_nRotation);
|
|
AcGeVector3d vt(cos(nAngWcs), sin(nAngWcs), 0.0);
|
|
vt.transformBy(xform);
|
|
|
|
m_nRotation = Wcs2Layout(ads_angle(ADSGePoint3d(), ADSGePoint3d(vt[0], vt[1])));
|
|
// sg delete 101217,根据8.5需求,解决多行文字的转角在某些范围内时,move移动或copy复制文字则反向的问题
|
|
if (GlobalFunc::IsMirrorMatrix(mat))
|
|
{
|
|
m_nRotation = GlobalFunc::ChangeAngleTo1_4(m_nRotation);
|
|
}
|
|
}
|
|
|
|
m_ptText.TransformBy(mat);
|
|
|
|
return Acad::eOk;
|
|
}
|
|
|
|
Acad::ErrorStatus
|
|
AecXDbMText::subGetGripPoints(AcGePoint3dArray& gripPoints,
|
|
AcDbIntArray& osnapModes,
|
|
AcDbIntArray& geomIds) const
|
|
{
|
|
assertReadEnabled();
|
|
gripPoints.append(m_ptText);
|
|
ADSGePoint3d ptRight;
|
|
ads_polar(m_ptText, Layout2Wcs(m_nRotation), GetPageWidth(FALSE), ptRight);
|
|
gripPoints.append(ptRight);
|
|
return Acad::eOk;
|
|
}
|
|
|
|
Acad::ErrorStatus
|
|
AecXDbMText::subMoveGripPointsAt(const AcDbIntArray& indices,
|
|
const AcGeVector3d& offset)
|
|
{
|
|
assertWriteEnabled();
|
|
ADSGePoint3d vtOffset(offset[0], offset[1]);
|
|
ADSGePoint3d ptRight;
|
|
ads_polar(m_ptText, Layout2Wcs(m_nRotation), GetPageWidth(FALSE), ptRight);
|
|
int nLen = indices.length();
|
|
for (int i = 0; i < nLen; i++) {
|
|
int idx = indices[i];
|
|
if (idx == 0) {
|
|
m_ptText += vtOffset;
|
|
}
|
|
else {
|
|
ptRight += vtOffset;
|
|
SetPageWidth(m_ptText.Distance2d(ptRight), FALSE);
|
|
//m_nRotation=ads_angle(m_ptText, ptRight);
|
|
}
|
|
}
|
|
return Acad::eOk;
|
|
}
|
|
|
|
// 取得夹点说明
|
|
Acad::ErrorStatus AecXDbMText::GetGripText(int i, CString &cs) const
|
|
{
|
|
Acad::ErrorStatus es = Acad::eOk;
|
|
switch (i) {
|
|
case 0:
|
|
cs = _T("移动文字");
|
|
break;
|
|
case 1:
|
|
cs = _T("改页宽");
|
|
break;
|
|
default:
|
|
es = Acad::eInvalidInput;
|
|
}
|
|
return es;
|
|
}
|
|
|
|
void AecXDbMText::GetTips(PtrList<ObjInfoUnit> &lstInfo) const
|
|
{
|
|
// sg modify 100322,根据8.5新需求修改,标述更准确
|
|
// lstInfo.Append(new ObjInfoUnit(_T("对象类型"), _T("文章")));
|
|
lstInfo.Append(new ObjInfoUnit(_T("对象类型"), _T("多行文字")));
|
|
// lstInfo.Append(new ObjInfoUnit(_T("文章内容"), m_sText));
|
|
lstInfo.Append(new ObjInfoUnit(_T("内容"), m_sText));
|
|
TCString sTextStyle = GlobalFunc::GetSymbolName(m_idStyle);
|
|
lstInfo.Append(new ObjInfoUnit(_T("文字样式"), sTextStyle));
|
|
TCString sWidth;
|
|
GlobalFunc::ftoa(m_nPageWidth, 1, sWidth);
|
|
sWidth << _T("P");
|
|
lstInfo.Append(new ObjInfoUnit(_T("页宽"), sWidth));
|
|
TCString sHeight;
|
|
GlobalFunc::ftoa(m_nHeight, 1, sHeight);
|
|
sHeight << _T("P");
|
|
lstInfo.Append(new ObjInfoUnit(_T("文字高度"), sHeight));
|
|
lstInfo.Append(new ObjInfoUnit(_T("旋转角度"), GlobalFunc::Angle2Str(m_nRotation * 180 / PI)));
|
|
TCString sLineSpace;
|
|
GlobalFunc::ftoa(m_nLineSpace, 1, sLineSpace);
|
|
sLineSpace << _T("P");
|
|
lstInfo.Append(new ObjInfoUnit(_T("行间距"), sLineSpace));
|
|
}
|
|
|
|
|
|
// 没有考虑转角
|
|
ADSGePoint3d AecXDbMText::GetExtents() const
|
|
{
|
|
PtrList<TextLine> lstLines;
|
|
GetTextLines(lstLines);
|
|
double nHeight = lstLines.Length() * GetHeight(FALSE) + (lstLines.Length() - 1) * GetLineSpace(FALSE);
|
|
double nWidth = GetPageWidth(FALSE);
|
|
return ADSGePoint3d(nWidth, nHeight);
|
|
}
|
|
|
|
|
|
void AecXDbMText::GetTextLines(PtrList<TextLine> &lstLines) const
|
|
{
|
|
PtrList<TextPart> lstTextParts;
|
|
if (!GetTextParts(lstTextParts))
|
|
return;
|
|
|
|
double nPageWidth = GetPageWidth(FALSE);
|
|
double nLineSpace = GetLineSpace(FALSE);
|
|
double nLineHeight = GetHeight(FALSE);
|
|
double nAngWcs = Layout2Wcs(m_nRotation);
|
|
|
|
double nWidth = 0.0;
|
|
ADSGePoint3d ptTopLeft = m_ptText;
|
|
int nCount = lstTextParts.Length();
|
|
|
|
TextLine textLine; //一行
|
|
double nOffsetY = nLineHeight;
|
|
for (int i = 0; i < nCount; i++) {
|
|
TextPart *pText = lstTextParts[i];
|
|
BOOL bExportLine = FALSE;
|
|
if (pText->IsParagraph()) {
|
|
bExportLine = TRUE;
|
|
}
|
|
else if (nPageWidth < g_Option::instance()._DIST_SNAP) {
|
|
textLine.Append(new TextPart(*pText));
|
|
nWidth += pText->GetWidth();
|
|
}
|
|
else if (nWidth > nPageWidth) {
|
|
ASSERT(0);
|
|
}
|
|
else if (nWidth + pText->GetWidth() > nPageWidth) { //自动换行
|
|
//判断多一词还是少一词
|
|
if (pText->IsSpacer() || pText->IsPunctuation()) {
|
|
//多一词, 或者是空格, 或者是标点
|
|
textLine.Append(new TextPart(*pText));
|
|
nWidth += pText->GetWidth();
|
|
}
|
|
else if (!pText->m_bChinese) { //英文单词或控制符
|
|
if (textLine.Length() == 0 || //无法容纳一个单词, 也没有办法
|
|
(m_nAlignment == AcGiDraw::kTextFit &&
|
|
fabs(nWidth - nPageWidth) > fabs(nWidth + pText->GetWidth() - nPageWidth)
|
|
) //与其少一词还不如多一词
|
|
) {
|
|
textLine.Append(new TextPart(*pText));
|
|
nWidth += pText->GetWidth();
|
|
}
|
|
else
|
|
i--;
|
|
}
|
|
else { //中文字序列, 假设中文字都是等宽
|
|
double nWidthLeft = nPageWidth - nWidth; //还剩下的未满一行的宽度
|
|
double nFactor = nWidthLeft / pText->GetWidth(); //需要往上一行的比例
|
|
int nUnit = _tcslen(_T("我"));
|
|
int nCharNum = pText->m_sText.Length() / nUnit;
|
|
int nCharNumPrev = AS_INT(nFactor * nCharNum);
|
|
if (nCharNumPrev == 0 && textLine.Length() == 0)
|
|
nCharNumPrev++; //至少要一个汉字
|
|
if (nCharNumPrev == nCharNum) { //全部上
|
|
textLine.Append(new TextPart(*pText));
|
|
nWidth += pText->GetWidth();
|
|
}
|
|
else if (nCharNumPrev == 0) {//全部下
|
|
i--;
|
|
}
|
|
else { //部分上, 部分下
|
|
nFactor = double(nCharNumPrev) / double(nCharNum);
|
|
TextPart *pNewText = new TextPart(*pText);
|
|
pNewText->m_nSizeX *= nFactor;
|
|
pText->m_sText = &(pNewText->m_sText[nCharNumPrev * nUnit]);
|
|
pNewText->m_sText[nCharNumPrev * nUnit] = EOS;
|
|
textLine.Append(pNewText);
|
|
pText->m_nSizeX -= pNewText->m_nSizeX;
|
|
pText->m_ptLowLeft.x += pNewText->m_nSizeX;
|
|
nWidth += pNewText->GetWidth();
|
|
i--;
|
|
}
|
|
}
|
|
if (m_nAlignment == AcGiDraw::kTextFit)
|
|
textLine.AdjustWidthFactor(nPageWidth / nWidth);
|
|
if (i < nCount - 1 && lstTextParts[i + 1]->IsParagraph()) //
|
|
; //下一个是硬回车, 则软硬回车同时输出
|
|
else
|
|
bExportLine = TRUE;
|
|
}
|
|
else {
|
|
textLine.Append(new TextPart(*pText));
|
|
nWidth += pText->GetWidth();
|
|
if (i == nCount - 1) {
|
|
bExportLine = TRUE;
|
|
}
|
|
}
|
|
|
|
if (bExportLine) {
|
|
if (textLine.Length()) {
|
|
ADSGePoint3d ptBase;
|
|
ads_polar(ptTopLeft, nAngWcs - PI / 2, nOffsetY, ptBase);
|
|
textLine.AdjustBasePoint(-textLine[0]->m_ptLowLeft.x);
|
|
if (m_nAlignment == AcGiDraw::kCenter) {
|
|
ADSGePoint3d ptAlign = AcGiDraw::Base2Align(m_nAlignment, textLine[0]->m_ptLowLeft, textLine.GetExtents());
|
|
ads_polar(ADSGePoint3d(ptBase), nAngWcs, nPageWidth / 2.0 - ptAlign.x, ptBase);
|
|
}
|
|
else if (m_nAlignment == AcGiDraw::kRight) {
|
|
ADSGePoint3d ptAlign = AcGiDraw::Base2Align(m_nAlignment, textLine[0]->m_ptLowLeft, textLine.GetExtents());
|
|
ads_polar(ADSGePoint3d(ptBase), nAngWcs, nPageWidth - ptAlign.x, ptBase);
|
|
}
|
|
|
|
//OutputTextLine(dc, ptBase, textLine);
|
|
textLine.SetDelFlag(FALSE);
|
|
TextLine *pTextLine = new TextLine;
|
|
int nNumText = textLine.Length();
|
|
for (int n = 0; n < nNumText; n++)
|
|
pTextLine->Append(textLine[n]);
|
|
lstLines.Append(pTextLine);
|
|
textLine.Reset();
|
|
textLine.SetDelFlag(TRUE);
|
|
}
|
|
else {
|
|
//空行
|
|
lstLines.Append(new TextLine);
|
|
}
|
|
|
|
nWidth = 0.0;
|
|
nOffsetY += nLineHeight + nLineSpace;
|
|
}
|
|
}
|
|
}
|
|
|
|
Acad::ErrorStatus
|
|
AecXDbMText::Draw2d(AcGiDraw &dc) const
|
|
{
|
|
assertReadEnabled();
|
|
|
|
//20160919 wlw CAD2015以上平台,绘制时出现形文件未定义
|
|
AcDbObjectId idst = GlobalFunc::GetTextStyleId(_T("standard"));
|
|
if (idst.isValid())
|
|
{
|
|
dc.SetTextStyle(idst);
|
|
}
|
|
|
|
// sg add 120516,只要在导出T3的时候,才不分解中英文文字,其他情况一律分解
|
|
BOOL bSplitEAndC = TRUE;//!(dc.IsFullExplode() && dc.IsExportTch4()) || g_bDownloadT3Split;
|
|
|
|
PtrList<TextPart> lstTextParts;
|
|
// if(!GetTextParts(lstTextParts))
|
|
if (!GetTextParts(lstTextParts, bSplitEAndC))
|
|
return Acad::eInvalidInput;
|
|
|
|
AcDbObjectId idOwner = ownerId();
|
|
double nPageWidth = GetPageWidth(FALSE);
|
|
double nLineSpace = GetLineSpace(FALSE);
|
|
double nLineHeight = GetHeight(FALSE);
|
|
double nAngWcs = Layout2Wcs(m_nRotation);
|
|
|
|
dc.SetTextStyle(m_idStyle);
|
|
//dc.SetRotation(nAngWcs);
|
|
|
|
|
|
double nWidth = 0.0;
|
|
ADSGePoint3d ptTopLeft = m_ptText;
|
|
int nCount = lstTextParts.Length();
|
|
|
|
TextLine textLine; //一行
|
|
double nOffsetY = nLineHeight;
|
|
int nMark = 1;
|
|
for (int i = 0; i < nCount; i++)
|
|
{
|
|
TextPart *pText = lstTextParts[i];
|
|
BOOL bExportLine = FALSE;
|
|
if (pText->IsParagraph())
|
|
{
|
|
bExportLine = TRUE;
|
|
}
|
|
else if (nPageWidth < g_Option::instance()._DIST_SNAP)
|
|
{
|
|
textLine.Append(new TextPart(*pText));
|
|
nWidth += pText->GetWidth();
|
|
}
|
|
else if (nWidth > nPageWidth)
|
|
{
|
|
ASSERT(0);
|
|
//textLine.AdjustWidthFactor(nPageWidth/nWidth);
|
|
//bExportLine=TRUE;
|
|
}
|
|
else if (nWidth + pText->GetWidth() > nPageWidth) //自动换行
|
|
{
|
|
//判断多一词还是少一词
|
|
if (pText->IsSpacer() || pText->IsPunctuation())
|
|
{
|
|
//多一词, 或者是空格, 或者是标点
|
|
textLine.Append(new TextPart(*pText));
|
|
nWidth += pText->GetWidth();
|
|
}
|
|
else if (!pText->m_bChinese) //英文单词或控制符
|
|
{
|
|
if (textLine.Length() == 0 || //无法容纳一个单词, 也没有办法
|
|
(m_nAlignment == AcGiDraw::kTextFit &&
|
|
fabs(nWidth - nPageWidth) > fabs(nWidth + pText->GetWidth() - nPageWidth)
|
|
) //与其少一词还不如多一词
|
|
)
|
|
{
|
|
textLine.Append(new TextPart(*pText));
|
|
nWidth += pText->GetWidth();
|
|
}
|
|
else
|
|
i--;
|
|
}
|
|
else //中文字序列, 假设中文字都是等宽
|
|
{
|
|
double nWidthLeft = nPageWidth - nWidth; //还剩下的未满一行的宽度
|
|
double nFactor = nWidthLeft / pText->GetWidth(); //需要往上一行的比例
|
|
int nUnit = _tcslen(_T("我"));
|
|
int nCharNum = pText->m_sText.Length() / nUnit;
|
|
int nCharNumPrev = AS_INT(nFactor * nCharNum);
|
|
if (nCharNumPrev == 0 && textLine.Length() == 0)
|
|
nCharNumPrev++; //至少要一个汉字
|
|
|
|
if (nCharNumPrev == nCharNum)
|
|
{ //全部上
|
|
textLine.Append(new TextPart(*pText));
|
|
nWidth += pText->GetWidth();
|
|
}
|
|
else if (nCharNumPrev == 0)
|
|
{//全部下
|
|
i--;
|
|
}
|
|
else
|
|
{ //部分上, 部分下
|
|
nFactor = double(nCharNumPrev) / double(nCharNum);
|
|
TextPart *pNewText = new TextPart(*pText);
|
|
pNewText->m_nSizeX *= nFactor;
|
|
pText->m_sText = &(pNewText->m_sText[nCharNumPrev * nUnit]);
|
|
pNewText->m_sText[nCharNumPrev * nUnit] = EOS;
|
|
textLine.Append(pNewText);
|
|
pText->m_nSizeX -= pNewText->m_nSizeX;
|
|
pText->m_ptLowLeft.x += pNewText->m_nSizeX;
|
|
nWidth += pNewText->GetWidth();
|
|
i--;
|
|
}
|
|
}
|
|
|
|
if (m_nAlignment == AcGiDraw::kTextFit)
|
|
textLine.AdjustWidthFactor(nPageWidth / nWidth);
|
|
if (i < nCount - 1 && lstTextParts[i + 1]->IsParagraph()) //
|
|
; //下一个是硬回车, 则软硬回车同时输出
|
|
else
|
|
bExportLine = TRUE;
|
|
}
|
|
else
|
|
{
|
|
textLine.Append(new TextPart(*pText));
|
|
nWidth += pText->GetWidth();
|
|
if (i == nCount - 1)
|
|
{
|
|
bExportLine = TRUE;
|
|
}
|
|
}
|
|
|
|
if (bExportLine)
|
|
{
|
|
if (textLine.Length())
|
|
{
|
|
ADSGePoint3d ptBase;
|
|
ads_polar(ptTopLeft, nAngWcs - PI / 2, nOffsetY, ptBase);
|
|
dc.SetSelectionMarker(nMark);
|
|
textLine.AdjustBasePoint(-textLine[0]->m_ptLowLeft.x);
|
|
if (m_nAlignment == AcGiDraw::kCenter)
|
|
{
|
|
ADSGePoint3d ptAlign = AcGiDraw::Base2Align(m_nAlignment, textLine[0]->m_ptLowLeft, textLine.GetExtents());
|
|
ads_polar(ADSGePoint3d(ptBase), nAngWcs, nPageWidth / 2.0 - ptAlign.x, ptBase);
|
|
}
|
|
else if (m_nAlignment == AcGiDraw::kRight)
|
|
{
|
|
ADSGePoint3d ptAlign = AcGiDraw::Base2Align(m_nAlignment, textLine[0]->m_ptLowLeft, textLine.GetExtents());
|
|
ads_polar(ADSGePoint3d(ptBase), nAngWcs, nPageWidth - ptAlign.x, ptBase);
|
|
}
|
|
|
|
//if (_tcsicmp(dc.Desc(), XAcGiViewDraw::Descriptor()) == 0 &&
|
|
// ((XAcGiViewDraw&)dc).GetCommonDraw()->isDragging()
|
|
// && g_bQuickDragMText)//add by whl on 090324
|
|
//{
|
|
// ADSGePoint3d vtExt = textLine.GetExtents();
|
|
// ADSGePoint3d ptOther = ptBase + ADSGePoint3d(vtExt.x, vtExt.z);
|
|
// GeRectAngle rect(ptBase, ptOther);
|
|
// GePoly2D poly(1);
|
|
// rect.AsPoly2D(poly);
|
|
|
|
// //add by whl on 050704
|
|
// ads_matrix mat;
|
|
// ptBase.GetRotationMatrix(nAngWcs, mat);
|
|
// poly.TransformBy(GlobalFunc::AsAcGeMatrix3d(mat));
|
|
|
|
// dc << poly;
|
|
//}
|
|
//else
|
|
//{
|
|
OutputTextLine(dc, ptBase, textLine, nAngWcs);
|
|
//}
|
|
textLine.Reset();
|
|
}
|
|
else
|
|
{
|
|
//空行
|
|
}
|
|
nWidth = 0.0;
|
|
nOffsetY += nLineHeight + nLineSpace;
|
|
nMark++;
|
|
}
|
|
}
|
|
|
|
return Acad::eOk;
|
|
}
|
|
|
|
double AecXDbMText::GetPageWidth(BOOL bAsPaperUnit) const
|
|
{
|
|
double nVal = m_nPageWidth;
|
|
if (!bAsPaperUnit)
|
|
nVal *= GetPScale();
|
|
return nVal;
|
|
}
|
|
|
|
void AecXDbMText::SetPageWidth(double nWidth, BOOL bAsPaperUnit)
|
|
{
|
|
assertWriteEnabled();
|
|
m_nPageWidth = nWidth;
|
|
if (!bAsPaperUnit)
|
|
m_nPageWidth /= GetPScale();
|
|
}
|
|
|
|
double AecXDbMText::GetLineSpace(BOOL bAsPaperUnit) const
|
|
{
|
|
double nVal = m_nLineSpace;
|
|
if (!bAsPaperUnit)
|
|
nVal *= GetPScale();
|
|
return nVal;
|
|
}
|
|
|
|
void AecXDbMText::SetLineSpace(double nWidth, BOOL bAsPaperUnit)
|
|
{
|
|
assertWriteEnabled();
|
|
m_nLineSpace = nWidth;
|
|
if (!bAsPaperUnit)
|
|
m_nLineSpace /= GetPScale();
|
|
}
|
|
|