#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 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 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 &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 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 &lstLines) const { PtrList 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 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(); }