Files
gjm 164968b62e chore
把非utf8-bom编码的cpp/h文件改为 utf8 bom 编码, msvc识别utf8编码时,如果不是bom格式的,会使用当前cp_oem来解码.
2026-10-04 00:04:20 +08:00

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();
}