#include "StdAfx.h" #include "DbMTextNew.h" #include "FindParser.h" TARCH_IMPEXP XFindParser g_FindParser; ACRX_DXF_DEFINE_MEMBERS(ATSMTextNew, ATSMText, AcDb::kDHL_CURRENT, AcDb::kMReleaseCurrent, 1, ATS_MTEXTNEW, "ATS_MTEXTNEW图形无法解析, 请下载上华软件|网址: www.shanghuasoft.com"); IMPLEMENT_TENTBASE(TDbMTextNew); const Adesk::UInt8 TDbMTextNew::g_nVersion = 1; extern TARCH_IMPEXP BOOL g_bDownloadT3Split; TDbMTextNew::TDbMTextNew() { m_dPageHeight = 200; m_dPageDist = 7; m_nPageStyle = 0; } TDbMTextNew::~TDbMTextNew() { m_mapPos.clear(); m_vecHeight.clear(); m_vecUnderLine.clear(); m_vecCol.clear(); } double TDbMTextNew::GetPageHeight(BOOL bAsPaperUnit) const { double nVal = m_dPageHeight; if(!bAsPaperUnit) nVal *= GetPScale(); return nVal; } void TDbMTextNew::SetPageHeight(double nHeight, BOOL bAsPaperUnit) { assertWriteEnabled(); m_dPageHeight = nHeight; if(!bAsPaperUnit) m_dPageHeight /= GetPScale(); } double TDbMTextNew::GetPageDist(BOOL bAsPaperUnit) const { double nVal = m_dPageDist; if(!bAsPaperUnit) nVal *= GetPScale(); return nVal; } void TDbMTextNew::SetPageDist(double nDist, BOOL bAsPaperUnit) { assertWriteEnabled(); m_dPageDist = nDist; if(!bAsPaperUnit) m_dPageDist /= GetPScale(); } int TDbMTextNew::GetPageStyle() const { return m_nPageStyle; } // 打印格式, 0为横排,1为竖排 void TDbMTextNew::SetPageStyle(int nStyle) { assertWriteEnabled(); m_nPageStyle = nStyle; } // zxl 2013.01.28 add 获取字符个数(区分汉字) int GetTextLength(const XString xsText) { int nLen = 0; int nCount = (int)_tcslen(xsText); for(int idx = 0; idx < nCount; idx++) { TCHAR c=xsText[idx]; if (c < 0)// 汉字 { idx++; } nLen++; } return nLen; } bool FindChar(XString &str, const TCHAR *pCh, double &nPos) { CString sText = str.cs(); int nLength = sText.GetLength(); g_FindParser.SetFindOption(FP_WORD_WIDTH); int nSPos = 0; if (g_FindParser.Find(pCh, sText, nSPos)) { CString csSubText = g_FindParser.GetResult(); nPos = sText.Find(csSubText, 0); // 解决高平台不兼容的问题 zxl 2013.01.22 add int nNumDel = 1; #if (ADS < 17) nNumDel = 2; #endif sText.Delete(nPos,nNumDel); str = sText; nPos = nPos / nLength; return true; } return false; } static bool IsControlChar(TCHAR c) { return (c==_T('1') || c==_T('2') || c==_T('3') || c==_T('4') || c==_T('5') || c==_T('6') || c==_T('L') || c==_T('U') || c==_T('C')); } TTextParserNew::TParserStatus TTextParserNew::GetNext(XString &sNext, BOOL bSplitEAndC, const std::vector &vec, int &nPos, double &dHeight) { TParserStatus nStatus; //char szOut[1024] = ""; int nMax = vec.size() * 2 + 1; char *szOut = new char [nMax]; const char *p = m_pCurrent; char *q = szOut; double dHeightCur = dHeight; double dHeightE = dHeight; if (!p || !*p) nStatus = TTextParserNew::kEndBuffer; else { BOOL bEng = TRUE; BOOL bBody = FALSE; BOOL bMix = FALSE; // sg add 120516,标记是否中英文混合 int i = 0; while(*p) { if (nPos < vec.size()) { dHeightCur = vec[nPos]; if (i == 0) { dHeightE = dHeightCur; } i++; } if (fabs(dHeightE - dHeightCur) > 0.001)// 字高不同 { break; } if (*p == 13) // 跳过回车符, 后续还有换行符号 { p++; continue; } if (*p>0 && *p<128) { if (*p == ' ' || *p == '\t' || *p == '\n') // 换行符号 { if (bBody) // 有英文或中文在前 { // sg modify 120516,根据当前的状态是否是在导出T3,决定是否中英文混合处理 if (bSplitEAndC || *p!= ' ') { break; } } *q = *p; if (*p == '\n') { p++; // 作为单独的一个文字单位 q++; break; } } else if (*p == '^' && IsControlChar(*(p+1))) // 控制符开始 { if (q != szOut) // 有字符在前 break; if (nPos < vec.size()) { dHeightCur = vec[nPos++]; } if (*(p+1) == 'L' || *(p+1) == 'U') // 上下标文字 { nPos+=3; BOOL bLow = (*(p+1)) == 'L'; const char *pSubStr = bLow? "^L" : "^U"; char *pFind = (char*)strstr(p+1, pSubStr); StrCpy(szOut, p+2, pFind); if (pFind) m_pCurrent = pFind+2; else m_pCurrent = NULL; sNext = (LPCTSTR)TString(szOut); nStatus = bLow? TTextParserNew::kLowerText : TTextParserNew::kUpperText; CString sText = szOut; nPos += GetTextLength(sText); delete []szOut; return nStatus; } else if (*(p+1) == 'C') // 圆圈文字 { const char *pSubStr = "^C"; char *pFind = (char*)strstr(p+1, pSubStr); StrCpy(szOut, p+2, pFind); if (pFind) m_pCurrent = pFind+2; else m_pCurrent = NULL; sNext = (LPCTSTR)TString(szOut); nStatus = TTextParserNew::kCircleText; CString sText = szOut; nPos += GetTextLength(sText); delete []szOut; return nStatus; } else // 钢筋符号、三角形标高符号 { *q = *p; p++; q++; *q = *p; q++; p++; *q = EOS; m_pCurrent = p; sNext = (LPCTSTR)TString(szOut); nPos += 1; delete []szOut; return TTextParserNew::kControlCode; } } else // 英文字母、数字 { // sg modify 120516,根据当前的状态是否是在导出T3,决定是否中英文混合处理 if (bBody && !bEng) { if (bSplitEAndC) break; bMix = TRUE; } else if (!bBody && q!=szOut) // 有空格 break; *q = *p; bBody = TRUE; } bEng = TRUE; } else // 汉字 { // sg modify 120516,根据当前的状态是否是在导出T3,决定是否中英文混合处理 if (bBody && bEng) { if (bSplitEAndC) break; bMix = TRUE; } else if (!bBody && q!=szOut) // 有空格 break; bEng = FALSE; bBody = TRUE; *q = *p; p++; q++; // ASSERT(*p); *q = *p; } p++; q++; nPos++; dHeightE = dHeightCur; } *q = EOS; dHeight = dHeightE; sNext = (LPCTSTR)TString(szOut); m_pCurrent = p; if (szOut[0] == '\n') nStatus = TTextParserNew::kParagragh; else { nStatus = bEng ? TTextParserNew::kNormalEnglish : TTextParserNew::kNormalChinese; // sg modify 120516,导出T3时,允许中英文联排,而不管字高 nStatus = bMix ? TTextParserNew::kT3NormalText : nStatus; if (!bSplitEAndC) { nStatus = TTextParserNew::kNormalChinese; } } } delete []szOut; return nStatus; } BOOL TDbMTextNew::GetStyleParam1(double *nWidthFactor) const { OPENOBJ_BEGIN(m_idStyle, AcDb::kForRead, AcDbTextStyleTableRecord, pStyle); ASSERT(pStyle); if(!pStyle) return FALSE; *nWidthFactor=pStyle->xScale(); OPENOBJ_END(); return TRUE; } BOOL TDbMTextNew::GetStyleParam2(double *nWidthFactor) const { double h1=3.5, x1=1.0; if(!GetStyleParam1(&x1)) return FALSE; double sw, sh; OPENOBJ_BEGIN(m_idStyle, AcDb::kForRead, AcDbTextStyleTableRecord, pStyle); // sg add 110118,放置因为文字样式不存在导致崩溃 // ASSERT(pStyle); if (pStyle == NULL) return FALSE; resbuf *pxData=pStyle->xData(TCHXD); if(pxData) { resbuf *pNext=pxData->rbnext; if(pNext && pNext->restype==1040) { sh = pNext->resval.rreal; pNext=pNext->rbnext; if(pNext && pNext->restype==1040) { sw = pNext->resval.rreal; } } ads_relrb(pxData); } else return FALSE; OPENOBJ_END(); *nWidthFactor = x1*sw/sh; return TRUE; } // 根据字符串中的标签属性,设定每个文字的属性 void TDbMTextNew::SetTextProp(CString &sText) const { m_vecCol.clear(); m_vecHeight.clear(); m_vecUnderLine.clear(); CString sColor, sHeight, sUnderline; COLORREF cf; double dHeight = 3.5; bool bUnderline = false; XString xsText = sText; CString sTextShow; int nCount = xsText.Length(); for(int idx = 0; idx < nCount; idx++) { TCHAR c=xsText[idx]; if (c == _T('$')) { sColor = _T(""), sHeight = _T(""), sUnderline = _T(""); while(xsText[++idx] != _T('|')) { sColor += xsText[idx]; } while(xsText[++idx] != _T('|')) { sHeight += xsText[idx]; } while(xsText[++idx] != _T('$')) { sUnderline += xsText[idx]; } cf = _tstof(sColor); dHeight = _tstof(sHeight); if (_tstof(sUnderline) > 0) { bUnderline = true; } else { bUnderline = false; } continue; } sTextShow += c; if (c < 0)// 汉字 { idx++; sTextShow += xsText[idx]; } if (c == _T('\n')) { continue; } m_vecCol.push_back(cf); m_vecHeight.push_back(dHeight); m_vecUnderLine.push_back(bUnderline); } sText = sTextShow; } static BOOL g_bPenups=FALSE; BOOL TDbMTextNew::GetTextParts(DList &lstTextParts, BOOL bSplitEAndC, double &dH) const { AcGiTextStyle txtStyle; if (!m_idStyle.isValid()) return FALSE; Acad::ErrorStatus es = fromAcDbTextStyle(txtStyle, m_idStyle); // sg add 110118,放置因为文字样式不存在导致崩溃 // ASSERT(es==Acad::eOk); if (es != Acad::eOk) return FALSE; lstTextParts.Reset(); int nRetFlag = txtStyle.loadStyleRec(); TCHAR *pWinFont = NULL; const TCHAR *pBigFont = NULL; BOOL bWinFont = FALSE; BOOL bBigFont = FALSE; BOOL penups = TRUE; // FALSE则测量正确,TRUE则中英文衔接顺畅 #if ADS > 20 // modify by cq 2017-01-04 支持CAD2017 Adesk::Boolean bold, italic; Charset charset; Autodesk::AutoCAD::PAL::FontUtils::FontPitch pitch; Autodesk::AutoCAD::PAL::FontUtils::FontFamily family; if (txtStyle.font(pWinFont, bold, italic, charset, pitch, family) == Acad::eOk && pWinFont && pWinFont[0]) #else BOOL bold, italic; int charset, pitch; if (txtStyle.font(pWinFont, bold, italic, charset, pitch)==Acad::eOk && pWinFont && pWinFont[0]) #endif { delete [] pWinFont; bWinFont = TRUE; } if ((pBigFont = txtStyle.bigFontFileName())!=NULL && pBigFont[0]) bBigFont = TRUE; double nPScale = GetPScale(); double nSize2Real = 1.0; XPoint ptLowLeft; // 获取文字属性 // TTextParserNew parser1(m_sText); CString sText = m_sText.cs(); SetTextProp(sText); m_csTextReal = sText; TTextParserNew parser1(sText); XString sWord1; TTextParserNew::TParserStatus nStatus1; double nSizeScale = 0.5; int nParag = 0;// 当前段落 int nPos = 0; double dHeight = 3.5; double dLen = 0.0; while((nStatus1=parser1.GetNext(sWord1, bSplitEAndC, m_vecHeight, nPos, dHeight)) != TTextParserNew::kEndBuffer) { double nHeightC = dHeight, nHeightE = dHeight; double nWidthFactorC = 1.0, nWidthFactorE = 0.6; if (!GetStyleParam1(&nWidthFactorC)) return FALSE; if (bWinFont || !GetStyleParam2(&nWidthFactorE)) { nHeightE = nHeightC; nWidthFactorE = nWidthFactorC; } nHeightC *= nPScale; nHeightE *= nPScale; double nSize2Real = 1.0; if (bBigFont || bWinFont) { txtStyle.setTextSize(nHeightC); AcGePoint2d ext0 = txtStyle.extents(_T("高度"), penups, -1, Adesk::kFalse); nSize2Real = nHeightC/ext0.y; } double nHeight1 = nHeightC; if (nStatus1 == TTextParserNew::kParagragh || sWord1[sWord1.Length()-1] == _T('\n')) { nParag ++; ptLowLeft = XPoint(); lstTextParts.Append(new TTextPart(sWord1, ptLowLeft, FALSE, 0.0, 0.0, 0.0, 0.0, 0.0)); } else if (nStatus1==TTextParserNew::kNormalEnglish || nStatus1==TTextParserNew::kNormalChinese || nStatus1==TTextParserNew::kControlCode) { nHeight1 = (nStatus1==TTextParserNew::kNormalEnglish ? nHeightE : nHeightC); double nScale1 = (nStatus1==TTextParserNew::kNormalEnglish ? nWidthFactorE : nWidthFactorC); txtStyle.setTextSize((bWinFont || nStatus1==TTextParserNew::kNormalChinese) ? nHeight1*nSize2Real : nHeight1); txtStyle.setXScale(nScale1); const TCHAR *pszBigFont = txtStyle.bigFontFileName(); BOOL bPenups = parser1.IsEOS()? g_bPenups : TRUE; AcGePoint2d ext1 = nStatus1==TTextParser::kControlCode?AcGePoint2d(nHeight1*nScale1, nHeight1):txtStyle.extents(sWord1, bPenups, -1, Adesk::kFalse); ptLowLeft.y = 0.0; dLen = nHeight1; lstTextParts.Append(new TTextPart(sWord1, ptLowLeft, nStatus1==TTextParserNew::kNormalChinese, nHeight1, ((bWinFont || nStatus1==TTextParserNew::kNormalChinese)? nHeight1*nSize2Real : nHeight1), nScale1, ext1[0], ext1[1])); ptLowLeft.x += ext1.x; } else if (nStatus1==TTextParserNew::kT3NormalText) // sg add 120516,导出T3文字时,中英文文字不拆开,全部混排,有关字高和比例,暂时使用同kNormalChinese { nHeight1 = nHeightC; double nScale1 = nWidthFactorC; txtStyle.setTextSize(nHeight1*nSize2Real); txtStyle.setXScale(nScale1); const TCHAR *pszBigFont = txtStyle.bigFontFileName(); BOOL bPenups = parser1.IsEOS()? g_bPenups : TRUE; AcGePoint2d ext1 = txtStyle.extents(sWord1, bPenups, -1, Adesk::kFalse); ptLowLeft.y = 0.0; dLen = nHeight1; lstTextParts.Append(new TTextPart(sWord1, ptLowLeft, TRUE, nHeight1, nHeight1*nSize2Real, nScale1, ext1[0], ext1[1])); ptLowLeft.x += ext1.x; } else if (nStatus1 == TTextParserNew::kCircleText) { ptLowLeft.y = 0.0; lstTextParts.Append(new TTextPart(sWord1, ptLowLeft, GetHeight()*GetPScale())); ptLowLeft.x += GetHeight()*GetPScale(); } else { TTextParser parser2(sWord1); TTextParser::TParserStatus nStatus2; XString sWord2; while((nStatus2=parser2.GetNext(sWord2, bSplitEAndC)) != TTextParser::kEndBuffer) { double nHeight2 = (nStatus2==TTextParser::kNormalEnglish ? nHeightE : nHeightC); double nScale2 = (nStatus2==TTextParser::kNormalEnglish ? nWidthFactorE : nWidthFactorC); double nAcadSize = nSizeScale*((bWinFont || nStatus2==TTextParser::kNormalChinese) ? nHeight2*nSize2Real : nHeight2); txtStyle.setTextSize(nAcadSize); txtStyle.setXScale(nScale2); BOOL bPenups = parser2.IsEOS()? g_bPenups : TRUE; AcGePoint2d ext2 = txtStyle.extents(sWord2, bPenups, -1, Adesk::kFalse); if (nStatus1==TTextParser::kLowerText) ptLowLeft.y = 0.0; //-nHeight1*nSizeScale; else ptLowLeft.y = nHeightC*(1.0-nSizeScale); dLen = nHeight2; TTextPart *pText = new TTextPart(sWord2, ptLowLeft, nStatus2==TTextParser::kNormalChinese, nSizeScale*nHeight2, nAcadSize, nScale2, ext2[0], ext2[1]); pText->m_iType = 2; lstTextParts.Append(pText); ptLowLeft.x += ext2.x; } } dH = dLen > dH ? dLen : dH; } return TRUE; } extern int g_bTextAdjust; // 没有考虑转角 BOOL TDbMTextNew::GetExtents(double *pWidth, double *pHeight, double *pHeight1) const { TTextLine lstTextParts; double dHeight = 0.0; if(!GetTextParts(lstTextParts, g_bDownloadT3Split, dHeight)) return FALSE; XPoint ext=lstTextParts.GetExtents(); if(pWidth) *pWidth=ext.x; if(pHeight) *pHeight=ext.y; if(pHeight1) *pHeight1=ext.z; return TRUE; } // Active when being rotated, scaled, moved, etc. // Scale is disabled here Acad::ErrorStatus TDbMTextNew::subTransformBy(const AcGeMatrix3d& xform) { assertWriteEnabled(); TDbEntity::subTransformBy(xform); ads_matrix mat; AsAdsMatrix(xform, mat); BOOL bMirror=IsMirrorMatrix(mat); if(bMirror) { //镜像 double nWidth, nHeight, nHeight1; if(GetExtents(&nWidth, &nHeight, &nHeight1)) { XPoint ext(nWidth, nHeight, nHeight1); XPoint ptBase=Align2Base(m_ptText, ext); XExplodeDraw::TextAlignment nOldAlign=m_nAlignment; m_nAlignment=XExplodeDraw::kMiddleCenter; XPoint ptCen=Base2Align(ptBase, ext); if(!g_bLayoutRotate) { //布局旋转时,局部不旋转 AcGeVector3d vt(cos(m_nRotation+m_nLayoutRotation), sin(m_nRotation+m_nLayoutRotation), 0.0); vt.transformBy(xform); m_nRotation=ads_angle(XPoint(), XPoint(vt[0], vt[1])); m_nRotation=AsViewAngle(Wcs2Layout(m_nRotation)); ptCen.TransformBy(mat); m_nHeight *= vt.length(); nWidth *= vt.length(); // nHeight *= vt.length(); std::vector::iterator it; for (it = m_vecHeight.begin(); it != m_vecHeight.end(); it++) { *it *= vt.length(); } if (m_vecHeight.size() > 0) { SetDefaultTextProp(); } } ptBase=Align2Base(ptCen, ext); m_nAlignment=nOldAlign; m_ptText=Base2Align(ptBase, ext); } } else { if(!g_bLayoutRotate) { AcGeVector3d vt(cos(m_nRotation+m_nLayoutRotation), sin(m_nRotation+m_nLayoutRotation), 0.0); vt.transformBy(xform); m_nRotation=Wcs2Layout(ads_angle(XPoint(), XPoint(vt[0], vt[1]))); // m_nHeight *= vt.length(); std::vector::iterator it; for (it = m_vecHeight.begin(); it != m_vecHeight.end(); it++) { *it *= vt.length(); } if (m_vecHeight.size() > 0) { SetDefaultTextProp(); } } m_ptText.TransformBy(mat); } return Acad::eOk; } // 设定文字属性标签 void TDbMTextNew::SetDefaultTextProp() { CString csText; XString xsText; xsText=m_csTextReal; int nCount = (int)_tcslen(xsText); COLORREF cfBefor = 0; double dHeightBefor = 0.0; bool bUnderLineBefor = false; int nIndex = 0; CString sTextShow; for(int idx = 0; idx < nCount; idx++) { TCHAR c=xsText[idx]; CString sWord; sWord +=c; if (c < 0 )// 汉字 { idx++; sWord += xsText[idx]; } if (c == _T('\n')) { sTextShow += c; continue; } double dHeight = m_vecHeight[nIndex]; if (m_vecCol[nIndex] != cfBefor || dHeight != dHeightBefor || m_vecUnderLine[nIndex] != bUnderLineBefor) { CString sProp; int nBool = 0; if (m_vecUnderLine[nIndex]) { nBool = 1; } sProp.Format(_T("$%.0d|%.1f|%d$"), m_vecCol[nIndex], dHeight, nBool); sTextShow += sProp; } sTextShow += sWord; cfBefor = m_vecCol[nIndex]; dHeightBefor = dHeight; bUnderLineBefor = m_vecUnderLine[nIndex]; nIndex++; } m_sText = sTextShow; } BOOL IsPunctuation(TCHAR c) { BOOL bRet; switch(c) { case _T(','): case _T(';'): case _T('.'): case _T('?'): case _T('"'): case _T('>'): case _T('!'): bRet=TRUE; break; default: bRet=FALSE; break; } return bRet; } BOOL IsPunctuation(CString sPunc) { BOOL bRet = FALSE; if (sPunc.Compare(_T(",")) == 0) { bRet = TRUE; } else if (sPunc.Compare(_T(";")) == 0) { bRet = TRUE; } else if (sPunc.Compare(_T("。")) == 0) { bRet = TRUE; } else if (sPunc.Compare(_T("?")) == 0) { bRet = TRUE; } else if (sPunc.Compare(_T("”")) == 0) { bRet = TRUE; } else if (sPunc.Compare(_T("》")) == 0) { bRet = TRUE; } else if (sPunc.Compare(_T("!")) == 0) { bRet = TRUE; } else if (sPunc.Compare(_T(":")) == 0) { bRet = TRUE; } return bRet; } // zxl 2013.12.25 add double GetMinNum(const std::vector vec) { double dNum = 0.0; std::vector::const_iterator it; for (it = vec.begin(); it != vec.end(); it++) { if (it == vec.begin() || *it < dNum) { dNum = *it; } } return dNum; } Acad::ErrorStatus TDbMTextNew::DownGradeSave(int nDrawMode, AcDbVoidPtrArray &entSet, BOOL *bErase) { Acad::ErrorStatus es = Acad::eOk; if (g_nSaveTArchVer < 10 && g_nSaveTArchVer > 3) { std::vector > vec; AcDbObjectId idStyle; double dHeight = 0.0; double dLineSpace = 0.0; double dPageWidth = 0.0; XExplodeDraw::TextAlignment alignType; Transform2OldMText(vec); idStyle = GetStyleId(); dHeight = GetMinNum(m_vecHeight); dLineSpace = m_nLineSpace; dPageWidth = GetPageWidth(); alignType = GetAlignment(); std::vector >::iterator it; for (it = vec.begin(); it != vec.end(); it++) { TDbMText *pMText = new TDbMText; pMText->SetText(it->first); pMText->SetLocation(it->second); pMText->SetStyleId(idStyle); pMText->SetHeight(dHeight); pMText->SetAlignment(alignType); pMText->SetLineSpace(dLineSpace); pMText->SetPageWidth(dPageWidth,TRUE); pMText->setLayer(layerId()); entSet.append(pMText); if(bErase) *bErase=TRUE; } } return es; } void TDbMTextNew::Transform2OldMText(std::vector > &vec) { DList lstTextParts; double dH = 0.0; if(!GetTextParts(lstTextParts, TRUE, dH)) return; double nLineHeightPre = 0.0; double nLineSpace=GetLineSpace(FALSE); double nLineHeight=0.0; double nAngWcs=Layout2Wcs(m_nRotation); double nWidth=0.0; double nHeight = 0.0; XPoint ptTopLeft=m_ptText; int nCount=lstTextParts.Length(); TTextLine textLine; //一行 double nOffsetY = nLineHeight; int nMark=1; bool bFindMark = false;//是否找到标记位 bool bFirstLine = true;//第一行不用偏移 double dMarkLen = 0.0; int nIndex = 0; double dDistDel = 0.0; bool bSpecialChar = false;// 换行符前有空格 BOOL bChangeLine = FALSE; CString csText; for(int i=0; im_nHeight; nLineHeight = nLineHeight > dH ? nLineHeight : dH; if (nLineHeight < 1.0) { nLineHeight = nLineHeightPre; } int nLen = pText->m_sText.Length(); if (!bFindMark && bFirstLine) { dMarkLen = nWidth; double nPos = 0; bFindMark = FindChar(pText->m_sText, _T("↓"), nPos); if (bFindMark) { dMarkLen += (nPos) * pText->GetWidth(); // 删除下箭头位置和长度 dDistDel = (pText->GetWidth() / nLen); #if (ADS < 17) dDistDel *= 2; #endif pText->m_nSizeX -= dDistDel; nIndex++; } } // 调整后续行基点位置 if (bFindMark && nLen == pText->m_sText.Length() && textLine.GetWidth() > 0.0) { pText->m_ptLowLeft.x -= dDistDel; } BOOL bExportLine=FALSE; double nPageWidth=GetPageWidth(FALSE); if (!bFirstLine && bFindMark && dMarkLen < GetPageWidth(FALSE)) { nPageWidth -= dMarkLen; } int nLength = pText->m_sText.Length(); if(nLength > 0 && pText->m_sText[nLength - 1] == _T('\n') && !pText->m_bChinese) { bExportLine=TRUE; bChangeLine = TRUE; if (nLength > 1) { CString sText = pText->m_sText.cs(); sText = sText.Left(sText.GetLength() - 1); pText->m_sText = sText; textLine.Append(new TTextPart(*pText)); nWidth += pText->GetWidth(); bSpecialChar = true; } } else if(nPageWidth<_DIST_SNAP) { textLine.Append(new TTextPart(*pText)); nWidth += pText->GetWidth(); } else if(nWidth>nPageWidth) { ASSERT(0); } else if(nWidth+pText->GetWidth()>nPageWidth) //自动换行 { //判断多一词还是少一词 if((pText->IsSpacer() || pText->IsPunctuation()) && pText->m_sText.Length() == 1) { //多一词, 或者是空格, 或者是标点 textLine.Append(new TTextPart(*pText)); nWidth += pText->GetWidth(); } else if(!pText->m_bChinese) //英文单词或控制符 { if(textLine.Length()==0 || //无法容纳一个单词, 也没有办法 (m_nAlignment==XExplodeDraw::kTextFit && fabs(nWidth-nPageWidth)>fabs(nWidth+pText->GetWidth()-nPageWidth) ) //与其少一词还不如多一词 ) { textLine.Append(new TTextPart(*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 TTextPart(*pText)); nWidth += pText->GetWidth(); } else if(nCharNumPrev==0) {//全部下 i--; } else { //部分上, 部分下 nFactor = double(nCharNumPrev)/double(nCharNum); TTextPart *pNewText=new TTextPart(*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==XExplodeDraw::kTextFit) textLine.AdjustWidthFactor(nPageWidth/nWidth); if(iIsParagraph()) // ; //下一个是硬回车, 则软硬回车同时输出 else bExportLine=TRUE; } else { if (pText->m_sText.Length() > 0) { textLine.Append(new TTextPart(*pText)); nWidth += pText->GetWidth(); } if(i==nCount-1) { bExportLine=TRUE; } } if(bExportLine) { if(textLine.Length() || i == nCount-1) { if (nHeight >= GetPageHeight(FALSE) || i == nCount-1) { if (i == nCount - 1) { for (int n = 0; n < textLine.Length(); n++) { TTextPart *pTextP = textLine[n]; csText += pTextP->m_sText; } csText += _T("\r\n"); } XPoint pt; ads_polar(ptTopLeft, nAngWcs - PI / 2, nLineSpace, pt); vec.push_back(std::make_pair(csText, pt)); csText = _T(""); if (GetPageStyle() == 0) { ads_polar(ptTopLeft, nAngWcs, GetPageWidth(FALSE) + GetPageDist(FALSE), ptTopLeft); nOffsetY = (nLineHeight + nLineSpace); nHeight = (nLineHeight + nLineSpace); } else { nOffsetY += GetPageDist(FALSE); nHeight = (nLineHeight + nLineSpace); ads_polar(ptTopLeft, nAngWcs - PI / 2, GetPageHeight(FALSE) + GetPageDist(FALSE), ptTopLeft); } } else { nOffsetY += (nLineHeight + nLineSpace); nHeight += (nLineHeight + nLineSpace); } for (int n = 0; n < textLine.Length(); n++) { TTextPart *pTextP = textLine[n]; csText += pTextP->m_sText; } if (bChangeLine) { csText.TrimRight(); csText += _T("\r\n"); bChangeLine = FALSE; } textLine.Reset(); } else { csText += _T("\r\n"); nOffsetY += (nLineHeightPre + nLineSpace); nHeight += (nLineHeightPre + nLineSpace); } nWidth=0.0; nMark++; nLineHeightPre = nLineHeight; nLineHeight = 0.0; } nLength = pText->m_sText.Length(); if((nLength > 0 && pText->m_sText[nLength - 1] == _T('\n') && !pText->m_bChinese) || bSpecialChar) { bFirstLine = true; bFindMark = false; dMarkLen = 0.0; bSpecialChar = false; dDistDel = 0.0; } } } Acad::ErrorStatus TDbMTextNew::ExplodeOrDraw2d(XExplodeDraw &dc) const { // cet 2016.10.17 add 图层关闭时,实体不显示,不进行绘制(打印时,也不会绘制) AcDbLayerTableRecordPointer player(this->layerId(), AcDb::kForRead); if (player.openStatus() == Acad::eOk && player->isOff()) { return Acad::eOk; } assertReadEnabled(); DList lstTextParts; double dH = 0.0; if(!GetTextParts(lstTextParts, g_bDownloadT3Split, dH)) return Acad::eInvalidInput; double nLineHeightPre = 0.0; AcDbObjectId idOwner=ownerId(); double nLineSpace=GetLineSpace(FALSE); double nLineHeight=0.0; double nAngWcs=Layout2Wcs(m_nRotation); dc.SetStyle(m_idStyle); dc.SetRotation(nAngWcs); double nWidth=0.0; double nHeight = 0.0; XPoint ptTopLeft=m_ptText; ads_polar(ptTopLeft, nAngWcs+PI/2, nLineSpace, ptTopLeft); int nCount=lstTextParts.Length(); TTextLine textLine; //一行 double nOffsetY = nLineHeight; int nMark=1; bool bFindMark = false;//是否找到标记位 bool bFirstLine = true;//第一行不用偏移 double dMarkLen = 0.0; int nIndex = 0; double dDistDel = 0.0; // COLORREF cf; bool bSpecialChar = false;// 换行符前有空格 for(int i=0; im_nHeight; nLineHeight = nLineHeight > dH ? nLineHeight : dH; if (nLineHeight < 1.0) { nLineHeight = nLineHeightPre; } int nLen = pText->m_sText.Length(); if (!bFindMark && bFirstLine) { dMarkLen = nWidth; double nPos = 0; bFindMark = FindChar(pText->m_sText, _T("↓"), nPos); if (bFindMark) { dMarkLen += (nPos) * pText->GetWidth(); // 删除下箭头位置和长度 dDistDel = (pText->GetWidth() / nLen); #if (ADS < 17) dDistDel *= 2; #endif pText->m_nSizeX -= dDistDel; nIndex++; } } // 调整后续行基点位置 if (bFindMark && nLen == pText->m_sText.Length() && textLine.GetWidth() > 0.0) { pText->m_ptLowLeft.x -= dDistDel; } BOOL bExportLine=FALSE; double nPageWidth=GetPageWidth(FALSE); if (!bFirstLine && bFindMark && dMarkLen < GetPageWidth(FALSE)) { nPageWidth -= dMarkLen; } int nLength = pText->m_sText.Length(); if(nLength > 0 && pText->m_sText[nLength - 1] == _T('\n') && !pText->m_bChinese) { bExportLine=TRUE; if (nLength > 1) { CString sText = pText->m_sText.cs(); sText = sText.Left(sText.GetLength() - 1); pText->m_sText = sText; textLine.Append(new TTextPart(*pText)); nWidth += pText->GetWidth(); bSpecialChar = true; } } else if(nPageWidth<_DIST_SNAP) { textLine.Append(new TTextPart(*pText)); nWidth += pText->GetWidth(); } else if(nWidth>nPageWidth) { ASSERT(0); } else if(nWidth+pText->GetWidth()>nPageWidth) //自动换行 { //判断多一词还是少一词 if((pText->IsSpacer() || pText->IsPunctuation()) && pText->m_sText.Length() == 1) { //多一词, 或者是空格, 或者是标点 textLine.Append(new TTextPart(*pText)); nWidth += pText->GetWidth(); } else if(!pText->m_bChinese) //英文单词或控制符 { if(textLine.Length()==0 || //无法容纳一个单词, 也没有办法 (m_nAlignment==XExplodeDraw::kTextFit && fabs(nWidth-nPageWidth)>fabs(nWidth+pText->GetWidth()-nPageWidth) ) //与其少一词还不如多一词 ) { textLine.Append(new TTextPart(*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 TTextPart(*pText)); nWidth += pText->GetWidth(); } else if(nCharNumPrev==0) {//全部下 i--; } else { //部分上, 部分下 nFactor = double(nCharNumPrev)/double(nCharNum); TTextPart *pNewText=new TTextPart(*pText); pNewText->m_nSizeX *= nFactor; int nNumE = 0;// 英文字符个数 for (int l = 0; l <= nCharNumPrev*nUnit; l++) { TCHAR c = pNewText->m_sText[l]; if (c < 0 || c > 127)// 汉字 { l++; } else { nNumE++; } } if (nNumE % 2 != 0) { pText->m_sText=&(pNewText->m_sText[nCharNumPrev*nUnit + 1]); pNewText->m_sText[nCharNumPrev*nUnit + 1]=EOS; } else { 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==XExplodeDraw::kTextFit) textLine.AdjustWidthFactor(nPageWidth/nWidth); if(iIsParagraph()) // ; //下一个是硬回车, 则软硬回车同时输出 else bExportLine=TRUE; } else { if (pText->m_sText.Length() > 0) { textLine.Append(new TTextPart(*pText)); nWidth += pText->GetWidth(); } if(i==nCount-1) { bExportLine=TRUE; } } if(bExportLine) { if(textLine.Length()) { XPoint ptBase; if (nHeight >= GetPageHeight(FALSE)) { if (GetPageStyle() == 0) { ads_polar(ptTopLeft, nAngWcs, GetPageWidth(FALSE) + GetPageDist(FALSE), ptTopLeft); nOffsetY = (nLineHeight + nLineSpace); nHeight = (nLineHeight + nLineSpace); } else { nOffsetY += GetPageDist(FALSE); nHeight = (nLineHeight + nLineSpace); } } else { nOffsetY += (nLineHeight + nLineSpace); nHeight += (nLineHeight + nLineSpace); } ads_polar(ptTopLeft, nAngWcs-PI/2, nOffsetY, ptBase); dc.SetSelectionMarker(nMark); if (!bFirstLine && bFindMark && dMarkLen < GetPageWidth(FALSE)) { ads_polar(ptBase, nAngWcs, dMarkLen, ptBase); } bFirstLine = false; textLine.AdjustBasePoint(-textLine[0]->m_ptLowLeft.x); if(m_nAlignment==XExplodeDraw::kCenter) { XPoint ptAlign=XExplodeDraw::Base2Align(m_nAlignment, textLine[0]->m_ptLowLeft, textLine.GetExtents()); ads_polar(XPoint(ptBase), nAngWcs, nPageWidth/2.0-ptAlign.x, ptBase); } else if(m_nAlignment==XExplodeDraw::kRight) { XPoint ptAlign=XExplodeDraw::Base2Align(m_nAlignment, textLine[0]->m_ptLowLeft, textLine.GetExtents()); ads_polar(XPoint(ptBase), nAngWcs, nPageWidth-ptAlign.x, ptBase); } if(_tcsicmp(dc.Desc(), XAcGiViewDraw::Descriptor())==0 && ((XAcGiViewDraw&)dc).GetCommonDraw()->isDragging() /*&&g_bQuickDragMText*/)//add by whl on 090324 { XPoint vtExt=textLine.GetExtents(); XPoint ptOther=ptBase+XPoint(vtExt.x, vtExt.z); XRectAngle rect(ptBase, ptOther); XPoly2D poly(1); rect.AsPoly2D(poly); //add by whl on 050704 ads_matrix mat; ptBase.GetRotationMatrix(nAngWcs,mat); poly.TransformBy(AsAcGeMatrix3d(mat)); dc << poly; } else { // 处理下一行行首为标点符号的情况,标点放在上一行行尾 if ( lstTextParts.Length() > i+1) { TTextPart *pTextNext=lstTextParts[i+1]; CString sText = pTextNext->m_sText.cs(); if (sText.GetLength() > 0) { CString sChar1, sChar2; int nNum = 2; #if (ADS >= 17) nNum = 1; #endif TCHAR c1 = pTextNext->m_sText[0]; sChar1 = c1; if (c1 < 0 && sText.GetLength() > 1) { sChar1 += pTextNext->m_sText[1]; } if (IsPunctuation(sChar1) || IsPunctuation(c1)) { TTextPart TextPrev = *textLine[textLine.Length() - 1]; int nLen = TextPrev.m_sText.Length(); CString sTextPrev = TextPrev.m_sText.cs(); TCHAR c2 = TextPrev.m_sText[nLen - 1]; sChar2 = c2; if (c2 < 0 && sTextPrev.GetLength() > 1) { sChar2 = TextPrev.m_sText[nLen - 2]; sChar2 += c2; } if (!IsPunctuation(sChar2) && !IsPunctuation(c2)) { sTextPrev += sChar1; textLine.Remove(textLine.Length() - 1); TextPrev.m_sText = sTextPrev; double dFact2 = (1.0 + (double)nNum / TextPrev.m_sText.Length()); TextPrev.m_nSizeX = dFact2 * TextPrev.m_nSizeX; textLine.Append(new TTextPart(TextPrev)); TTextPart *pTextNext = lstTextParts[i + 1]; CString sTextNext = pTextNext->m_sText.cs(); int nFind = sTextNext.Find(sChar1, 0); sTextNext = sTextNext.Right(sTextNext.GetLength() - nFind - nNum); if (sTextNext.IsEmpty() && lstTextParts.Length() > i+2)//标点独占一行,后为换行符,跳过改行和回车行 { if ((*lstTextParts[i + 2]).m_sText == _T("\n")) { i += 2; bSpecialChar = true; } } else { pTextNext->m_sText = sTextNext; double dFact = (1.0 - (double)nNum / pTextNext->m_sText.Length()); pTextNext->m_nSizeX = dFact * pTextNext->m_nSizeX; pTextNext->m_ptLowLeft.x += ((1 - dFact) * pTextNext->m_nSizeX); } } } } } OutputTextLine(dc, ptBase, textLine, nIndex); } textLine.Reset(); } else { nOffsetY += (nLineHeight + nLineSpace); nHeight += (nLineHeight + nLineSpace); } nWidth=0.0; nMark++; nLineHeightPre = nLineHeight; nLineHeight = 0.0; } nLength = pText->m_sText.Length(); if((nLength > 0 && pText->m_sText[nLength - 1] == _T('\n') && !pText->m_bChinese) || bSpecialChar) { bFirstLine = true; bFindMark = false; dMarkLen = 0.0; bSpecialChar = false; dDistDel = 0.0; } } return Acad::eOk; } int TDbMTextNew::InitTextPos(const AcGePoint3d &ptCur) { assertReadEnabled(); DList lstTextParts; double dH = 0.0; if(!GetTextParts(lstTextParts, g_bDownloadT3Split, dH)) return 0; AcDbObjectId idOwner=ownerId(); double nLineSpace=GetLineSpace(FALSE); double nLineHeight=0.0; double nAngWcs=Layout2Wcs(m_nRotation); double nWidth=0.0; double nHeight = 0.0; XPoint ptTopLeft=m_ptText; int nCount=lstTextParts.Length(); TTextLine textLine; //一行 double nOffsetY = nLineHeight; int nMark=1; double nLineHeightPre = 0.0; bool bFindMark = false;//是否找到标记位 bool bFirstLine = true;//第一行不用偏移 double dMarkLen = 0.0; bool bEnd = false; int nPosStart = 0; for(int i=0; im_nHeight; nLineHeight = nLineHeight > dH ? nLineHeight : dH; double dDistDel = 0.0; int nLen = pText->m_sText.Length(); if (!bFindMark && bFirstLine) { dMarkLen = nWidth; double nPos = 0; bFindMark = FindChar(pText->m_sText, _T("↓"), nPos); if (bFindMark) {//zxl modify 2013.05.20 nPosStart+=2; dMarkLen += (nPos) * pText->GetWidth(); // 删除下箭头位置和长度 dDistDel = (pText->GetWidth() / nLen); #if (ADS < 17) dDistDel *= 2; #endif pText->m_nSizeX -= dDistDel; } } // 调整后续行基点位置 //zxl modify 2013.05.20 if (bFindMark && nLen == pText->m_sText.Length() && textLine.GetWidth() > 0.0) { pText->m_ptLowLeft.x -= dDistDel; } double nPageWidth=GetPageWidth(FALSE); if (!bFirstLine && bFindMark && dMarkLen < GetPageWidth(FALSE)) { nPageWidth -= dMarkLen; } int nLength = pText->m_sText.Length(); if(nLength > 0 && pText->m_sText[nLength - 1] == _T('\n') && !pText->m_bChinese)// 回车换行 { bExportLine=TRUE; if(i==nCount-1) { bEnd = true; } } else if(nPageWidth<_DIST_SNAP) { textLine.Append(new TTextPart(*pText)); nWidth += pText->GetWidth(); } else if(nWidth>nPageWidth) { ASSERT(0); } else if(nWidth+pText->GetWidth()>nPageWidth) //自动换行 { //判断多一词还是少一词 if(pText->IsSpacer() || pText->IsPunctuation()) { //多一词, 或者是空格, 或者是标点 textLine.Append(new TTextPart(*pText)); nWidth += pText->GetWidth(); } else if(!pText->m_bChinese) //英文单词或控制符 { if(textLine.Length()==0 || //无法容纳一个单词, 也没有办法 (m_nAlignment==XExplodeDraw::kTextFit && fabs(nWidth-nPageWidth)>fabs(nWidth+pText->GetWidth()-nPageWidth) ) //与其少一词还不如多一词 ) { textLine.Append(new TTextPart(*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 TTextPart(*pText)); nWidth += pText->GetWidth(); } else if(nCharNumPrev==0) {//全部下 i--; } else { //部分上, 部分下 nFactor = double(nCharNumPrev)/double(nCharNum); TTextPart *pNewText=new TTextPart(*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==XExplodeDraw::kTextFit) textLine.AdjustWidthFactor(nPageWidth/nWidth); else bExportLine=TRUE; } else if(!bEnd) { textLine.Append(new TTextPart(*pText)); nWidth += pText->GetWidth(); if(i==nCount-1) { bExportLine=TRUE; bEnd = true; } } if(bExportLine) { if(textLine.Length()) { XPoint ptBase; if (nHeight >= GetPageHeight(FALSE)) { if (GetPageStyle() == 0) { ads_polar(ptTopLeft, nAngWcs, GetPageWidth(FALSE) + GetPageDist(FALSE), ptTopLeft); nOffsetY = nLineHeight; nHeight = 0.0; } else { nOffsetY += GetPageDist(FALSE); nHeight = 0.0; } } nOffsetY += nLineHeight + nLineSpace; nHeight += nLineHeight + nLineSpace; ads_polar(ptTopLeft, nAngWcs-PI/2, nOffsetY, ptBase); if (!bFirstLine && bFindMark && dMarkLen < GetPageWidth(FALSE)) { ads_polar(ptBase, nAngWcs, dMarkLen, ptBase); } textLine.AdjustBasePoint(-textLine[0]->m_ptLowLeft.x); if(m_nAlignment==XExplodeDraw::kCenter) { XPoint ptAlign=XExplodeDraw::Base2Align(m_nAlignment, textLine[0]->m_ptLowLeft, textLine.GetExtents()); ads_polar(XPoint(ptBase), nAngWcs, nPageWidth/2.0-ptAlign.x, ptBase); } else if(m_nAlignment==XExplodeDraw::kRight) { XPoint ptAlign=XExplodeDraw::Base2Align(m_nAlignment, textLine[0]->m_ptLowLeft, textLine.GetExtents()); ads_polar(XPoint(ptBase), nAngWcs, nPageWidth-ptAlign.x, ptBase); } //zxl modify 2013.05.20 // 处理下一行行首为标点符号的情况,标点放在上一行行尾 if ( lstTextParts.Length() > i+1) { TTextPart *pTextNext=lstTextParts[i+1]; CString sText = pTextNext->m_sText.cs(); if (sText.GetLength() > 0) { CString sChar1, sChar2; int nNum = 2; #if (ADS >= 17) nNum = 1; #endif TCHAR c1 = pTextNext->m_sText[0]; sChar1 = c1; if (c1 < 0 && sText.GetLength() > 1) { sChar1 += pTextNext->m_sText[1]; } if (IsPunctuation(sChar1) || IsPunctuation(c1)) { TTextPart TextPrev = *textLine[textLine.Length() - 1]; int nLen = TextPrev.m_sText.Length(); CString sTextPrev = TextPrev.m_sText.cs(); TCHAR c2 = TextPrev.m_sText[nLen - 1]; sChar2 = c2; if (c2 < 0 && sTextPrev.GetLength() > 1) { sChar2 = TextPrev.m_sText[nLen - 2]; sChar2 += c2; } if (!IsPunctuation(sChar2) && !IsPunctuation(c2)) { sTextPrev += sChar1; textLine.Remove(textLine.Length() - 1); TextPrev.m_sText = sTextPrev; double dFact2 = (1.0 + (double)nNum / TextPrev.m_sText.Length()); TextPrev.m_nSizeX = dFact2 * TextPrev.m_nSizeX; textLine.Append(new TTextPart(TextPrev)); TTextPart *pTextNext = lstTextParts[i + 1]; CString sTextNext = pTextNext->m_sText.cs(); int nFind = sTextNext.Find(sChar1, 0); sTextNext = sTextNext.Right(sTextNext.GetLength() - nFind - nNum); if (sTextNext.IsEmpty() && lstTextParts.Length() > i+2)//标点独占一行,后为换行符,跳过改行和回车行 { if ((*lstTextParts[i + 2]).m_sText == _T("\n")) { i += 2; } } else { pTextNext->m_sText = sTextNext; double dFact = (1.0 - (double)nNum / pTextNext->m_sText.Length()); pTextNext->m_nSizeX = dFact * pTextNext->m_nSizeX; pTextNext->m_ptLowLeft.x += ((1 - dFact) * pTextNext->m_nSizeX); } } } } } if (InitTextRowPos(textLine, ptBase, nPosStart, ptCur)) { return nPosStart; } bFirstLine = false; if (bEnd) { return 0; } } else { nOffsetY += nLineHeightPre + nLineSpace; nHeight += nLineHeightPre + nLineSpace; } textLine.Reset(); nWidth=0.0; nLineHeightPre = nLineHeight; nLineHeight = 0.0; } nLength = pText->m_sText.Length(); if(nLength > 0 && pText->m_sText[nLength - 1] == _T('\n') && !pText->m_bChinese) { bFirstLine = true; bFindMark = false; dMarkLen = 0.0; nPosStart++; if (nLength > 1) { nPosStart += nLength -1; } } } return 0; } // 从DWG读入数据: Acad::ErrorStatus TDbMTextNew::dwgInFields (AcDbDwgFiler* pFiler) { assertWriteEnabled(); Acad::ErrorStatus es = TDbMText::dwgInFields(pFiler); if(es != Acad::eOk) return es; // cet 2017.8.10 modify 20平台调用readItem(Adesk::Boolean* pVal), 21平台调用readItem(Adesk::Int32* pVal) // pFiler->readItem(&m_nPageStyle); BOOL bVal = m_nPageStyle; FilerRead(pFiler, bVal); m_nPageStyle = bVal ? 1 : 0; pFiler->readItem(&m_dPageHeight); pFiler->readItem(&m_dPageDist); return pFiler->filerStatus(); } Acad::ErrorStatus TDbMTextNew::dwgOutFields(AcDbDwgFiler* pFiler) const { assertReadEnabled(); Acad::ErrorStatus es = TDbMText::dwgOutFields(pFiler); if(es != Acad::eOk) return es; // cet 2017.8.10 modify 20平台调用writeItem(Adesk::Boolean val),21平台调用writeItem(Adesk::Int32 val) // pFiler->writeItem(m_nPageStyle); BOOL bVal = m_nPageStyle; FilerWrite(pFiler, bVal); pFiler->writeItem(m_dPageHeight); pFiler->writeItem(m_dPageDist); return pFiler->filerStatus(); } Acad::ErrorStatus TDbMTextNew::dxfInFields (AcDbDxfFiler* pFiler) { assertWriteEnabled(); Acad::ErrorStatus es = TDbMText::dxfInFields(pFiler); if(es!=Acad::eOk) return es; if (!pFiler->atSubclassData(_T("TDbMTextNew"))) { 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; } } if (es != Acad::eEndOfFile) return Acad::eInvalidResBuf; if (!(fieldsFlags & 0x01)) { pFiler->setError(Acad::eMissingDxfField, _T("\nMissing DXF group code: 41")); return Acad::eMissingDxfField; } m_dPageHeight=r1; if(fieldsFlags&0x02) m_dPageDist=r2; return pFiler->filerStatus(); } Acad::ErrorStatus TDbMTextNew::dxfOutFields(AcDbDxfFiler* pFiler) const { assertReadEnabled(); Acad::ErrorStatus es=TDbMText::dxfOutFields(pFiler); assert(es == Acad::eOk); es = pFiler->writeItem(AcDb::kDxfSubclass,_T("TDbMTextNew")); assert(es == Acad::eOk); pFiler->writeDouble(AcDb::kDxfReal+1, m_dPageHeight); pFiler->writeDouble(AcDb::kDxfReal+2, m_dPageDist); // pFiler->writeInt16(Adesk::Int16(m_nPageStyle)); return es; } void InitDbMTextNew(BOOL bTrue) { if(bTrue) { TDbMTextNew::rxInit(); TDbMTextNew::InitMatchProtocol(TRUE); } else { TDbMTextNew::InitMatchProtocol(FALSE); deleteAcRxClass(TDbMTextNew::desc()); } } Acad::ErrorStatus TDbMTextNew::subGetGripPoints(AcGePoint3dArray& gripPoints, AcDbIntArray& osnapModes, AcDbIntArray& geomIds) const { assertReadEnabled(); gripPoints.append(m_ptText); XPoint ptRight; ads_polar(m_ptText, Layout2Wcs(m_nRotation), GetPageWidth(FALSE), ptRight); gripPoints.append(ptRight); XPoint ptLow; ads_polar(ptRight, Layout2Wcs(m_nRotation) - PI/2, GetPageHeight(FALSE), ptLow); gripPoints.append(ptLow); XPoint ptPageDist; if (GetPageStyle() == 0) { ads_polar(ptRight, Layout2Wcs(m_nRotation), GetPageDist(FALSE), ptPageDist); } else { ads_polar(ptLow, Layout2Wcs(m_nRotation) - PI/2, GetPageDist(FALSE), ptPageDist); } gripPoints.append(ptPageDist); return Acad::eOk; } Acad::ErrorStatus TDbMTextNew::subMoveGripPointsAt(const AcDbIntArray& indices, const AcGeVector3d& offset) { assertWriteEnabled(); XPoint vtOffset(offset[0], offset[1]); XPoint ptRight, ptLow, ptPageDist; ads_polar(m_ptText, Layout2Wcs(m_nRotation), GetPageWidth(FALSE), ptRight); ads_polar(ptRight, Layout2Wcs(m_nRotation) - PI/2, GetPageHeight(FALSE), ptLow); if (GetPageStyle() == 0) { ads_polar(ptRight, Layout2Wcs(m_nRotation), GetPageDist(FALSE), ptPageDist); } else { ads_polar(ptLow, Layout2Wcs(m_nRotation) - PI/2, GetPageDist(FALSE), ptPageDist); } int nLen=indices.length(); for(int i=0; i 20 // modify by cq 2017-01-04 支持CAD2017 Adesk::Boolean bold, italic; Charset charset; Autodesk::AutoCAD::PAL::FontUtils::FontPitch pitch; Autodesk::AutoCAD::PAL::FontUtils::FontFamily family; if (txtStyle.font(pWinFont, bold, italic, charset, pitch, family) == Acad::eOk && pWinFont && pWinFont[0]) #else BOOL bold, italic; int charset, pitch; if (txtStyle.font(pWinFont, bold, italic, charset, pitch) == Acad::eOk && pWinFont && pWinFont[0]) #endif { delete [] pWinFont; bWinFont = TRUE; } if ((pBigFont = txtStyle.bigFontFileName())!=NULL && pBigFont[0]) bBigFont = TRUE; double nPScale = DocGetPScale(); double nHeightC = m_nHeight, nHeightE = m_nHeight; double nWidthFactorC = 1.0, nWidthFactorE = 1.0; if (!GetStyleParam1(&nWidthFactorC)) return FALSE; if (bWinFont || !GetStyleParam2(&nWidthFactorE)) { nHeightE = nHeightC; nWidthFactorE = nWidthFactorC; } nHeightC *= nPScale; nHeightE *= nPScale; double nSize2Real = 1.0; if (bBigFont || bWinFont) { txtStyle.setTextSize(nHeightC); AcGePoint2d ext0 = txtStyle.extents(_T("高度"), penups, -1, Adesk::kFalse); nSize2Real = nHeightC/ext0.y; } AcGePoint2d ext1 = txtStyle.extents(csWord, Adesk::kFalse, -1, Adesk::kFalse); return ext1[0]; } double TDbMTextNew::GetAngleRangeTo2PI() { return AngleRangeTo2PI(m_nLayoutRotation + m_nRotation); } bool TDbMTextNew::InitTextRowPos(const DList &textLine,const AcGePoint3d &ptBase, int &nPosStart, const AcGePoint3d &ptCur) { double dAng = AngleRangeTo2PI(m_nLayoutRotation + m_nRotation); double dWidth = 0.0; double dHeight = 0.0; int nCount = textLine.Length(); XPoint ptS = ptBase; for (int i=0; im_sText; for (int n = 0; n < sText.Length(); n++) { TCHAR c=sText[n]; dHeight = pTextPart->m_nHeight > dHeight ? pTextPart->m_nHeight : dHeight; dWidth = pTextPart->GetWidth() / sText.Length(); if(c < 0 || c > 127) { if (c < 0) { dWidth *= 2; n++; } pos++; } pos++; XPoint ptE; XPoly2D Poly; ads_polar(ptS, dAng, dWidth, ptE); Poly.AppendNode(ptS); Poly.AppendNode(ptE); XPoint ptTemp; ads_polar(ptE, dAng+PI/2, dHeight * 1.2, ptTemp); Poly.AppendNode(ptTemp); ads_polar(ptS, dAng+PI/2, dHeight * 1.2, ptTemp); Poly.AppendNode(ptTemp); int ret = ptCur&Poly; if (ret == PR_INSIDE) { nPosStart += pos; return true; } ptS = ptE; } nPosStart += pos; } return false; } // RGB颜色转化为AUTOCAD颜色 zxl 2013.01.28 add int RGBToCADColor(const long red, const long green, const long blue) { long acirgb, r,g,b; long mindst = 2147483647L; long dst = 0; int minndx = 0; for (int i = 1; i < 255; i++) { acirgb = acedGetRGB (i); r = (acirgb & 0xffL); g = (acirgb & 0xff00L) >> 8; b = acirgb >> 16; dst = abs (r - red) + abs (g - green) + abs (b - blue); if (dst < mindst) { minndx = i; mindst = dst; } } return minndx; } // RGB颜色转化为AUTOCAD颜色 zxl 2013.01.28 add int RGBToCADColor(const unsigned long rgb) { long r = (rgb & 0xffL ); long g = (rgb & 0xff00L) >> 8; long b = rgb >> 16;; return RGBToCADColor(r, g, b); } // 设置当前输出颜色 zxl 2013.01.28 add void TDbMTextNew::SetOutputColor(XExplodeDraw &dc, const COLORREF &cfPre) const { if (cfPre == 0 || cfPre == 0X212121)//颜色随块或随层 { dc.SetColor(colorIndex()); } else { Adesk::UInt16 col; col = RGBToCADColor(cfPre); dc.SetColor(col); } } void TDbMTextNew::OutputTextLine(XExplodeDraw &dc, XPoint ptBase, const DList &lineText, int &nIndex) const { BOOL bExpl = (_tcscmp(dc.Desc(), XExplodeStream::Descriptor())==0); dc.SetAlignment(XExplodeDraw::kLeft); int nCount = lineText.Length(); double nRotWcs = Layout2Wcs(m_nRotation); for (int i=0; iIsSpacer()) // { // nIndex++; // continue; // } int nCtrlCode = pTextPart->GetControlCode(); if (!nCtrlCode) { { if (pTextPart->m_iType == 0 || pTextPart->m_iType == 2)//文字 { // mod by xlc on 110826 解决水暖电发布命令时文字图层关闭不起作用的问题 // add by xlc on 110406 解决打印时文字图层关闭或冻结不起作用的问题 //if (g_bPrinting) // sg delete 111017,各专业都要考了发布输出的问题 // if (g_bPrinting || g_nProductId == kTELEC || g_nProductId == kTHVAC || g_nProductId == kTWT) { OPENOBJ_BEGIN(layerId(), AcDb::kForRead, AcDbLayerTableRecord, pLayer); if (pLayer != NULL) { if(pLayer->isOff() || pLayer->isFrozen()) { continue; } // sg add 120513,增加判断,如果图层不可打印、视口冻结,并且当前是在打印状态下时,不显示文字 if (_tcscmp(dc.Desc(), XAcGiViewDraw::Descriptor())==0 && dc.IsPlotGeneration()) { if (!pLayer->isPlottable()) continue; AcDbObjectId idViewport = acedGetCurViewportObjectId(); OPENOBJ_BEGIN(idViewport, AcDb::kForRead, AcDbViewport, pViewport); if (pViewport != NULL) { if (pViewport->isLayerFrozenInViewport(layerId())) { continue; } } OPENOBJ_END(); } } OPENOBJ_END(); } dc.SetHeight(pTextPart->m_nHeight); dc.SetWidthFactor(pTextPart->m_nWidthFactor); XPoint ptLoc; ads_polar(ptBase, nRotWcs, pTextPart->m_ptLowLeft.x, ptLoc); ads_polar(XPoint(ptLoc), nRotWcs+PI/2, pTextPart->m_ptLowLeft.y, ptLoc); dc.SetLocation(ptLoc); // 逐字添加文字颜色和下划线 zxl 2013.01.28 modify // dc.DrawText(pTextPart->m_sText); double dTextHeight = pTextPart->m_nHeight; double dHeight = m_nHeight * GetPScale(); if (pTextPart->m_iType == 2)// 上标或下标文字 { nIndex+=2; } XString xsText = pTextPart->m_sText; int nCount = (int)_tcslen(xsText); // 获取当前颜色 COLORREF cfPre = 0; if (nIndex < m_vecCol.size()) { cfPre = m_vecCol[nIndex]; } bool bUnderLine = false; CString sOutText; XPoint ptS, ptE; double nFact = 1.0; CString sTextAll; double dLenAll = 0.0; for(int idx = 0; idx < nCount; idx++) { TCHAR c=xsText[idx]; CString sText = c; if (sText.IsEmpty()) { continue; } double dDst = pTextPart->GetWidth() / nCount; if(c < 0) //汉字 { idx++; sText += xsText[idx]; nFact = 2; } else if (c == _T('%') && xsText[idx + 1] == _T('%'))// 防止控制符号输出乱码(控制符号要一起输出) { sText += xsText[idx+1]; sText += xsText[idx+2]; idx += 2; nIndex += 2; nFact = 3; } sTextAll += sText; COLORREF cf = 0; if (nIndex < m_vecCol.size()) { cf = m_vecCol[nIndex]; } if (g_bDownloadT3Split) { dDst *= nFact; } else { AcGePoint2d ext1; XString s = sTextAll; AcGiTextStyle txtStyle; fromAcDbTextStyle(txtStyle, m_idStyle); int nRetFlag = txtStyle.loadStyleRec(); txtStyle.setTextSize(pTextPart->m_nHeight); // cet 2015.5.13 modify 考虑宽高比 // txtStyle.setXScale(1); txtStyle.setXScale(pTextPart->m_nWidthFactor); ext1 = txtStyle.extents(s, true, -1, Adesk::kFalse); dDst = ext1.x - dLenAll; dLenAll = ext1.x; } SetOutputColor(dc, cfPre); dc.SetLayer(layerId()); // 文字属性变化,输出文字 bool bUnderLineOut = false; if (cf != cfPre || idx == nCount - 1) { if (idx == nCount - 1 && cf == cfPre) { sOutText += sText; } dc.DrawText(sOutText); SetOutputColor(dc, cfPre); if (cf != cfPre && bUnderLine) { ptE = ptLoc; // cet 2015.5.13 modify 考虑宽高比 // ads_polar(XPoint(ptE), nRotWcs-PI/2, m_nHeight * GetPScale() / 10, ptE); ads_polar(XPoint(ptE), nRotWcs-PI/2, m_nHeight * pTextPart->m_nWidthFactor * GetPScale() / 10, ptE); TGGeLine line(ptS, ptE); dc.DrawLine(line); bUnderLine = false; } dc.SetLocation(ptLoc); if (idx == nCount - 1 && cf != cfPre)//处理最后一个字符属性不同的情况 { SetOutputColor(dc, cf); dc.DrawText(sText); if (nIndex < m_vecUnderLine.size() && m_vecUnderLine[nIndex]) { bUnderLineOut = true; ptS = ptLoc; SetOutputColor(dc, cf); // cet 2015.5.13 modify 考虑宽高比 ads_polar(XPoint(ptS), nRotWcs-PI/2, m_nHeight * GetPScale() / 10, ptS); ads_polar(XPoint(ptS), nRotWcs-PI/2, m_nHeight * pTextPart->m_nWidthFactor * GetPScale() / 10, ptS); ads_polar(ptS, nRotWcs, dDst, ptE); TGGeLine line(ptS, ptE); dc.DrawLine(line); } ads_polar(ptLoc, nRotWcs, dDst, ptLoc); dc.SetLocation(ptLoc); } sOutText.Empty(); } XPoint ptLocPre = ptLoc; ads_polar(ptLoc, nRotWcs, dDst, ptLoc); sOutText += sText; // zxl 2013.02.22 add 下划线开始 if (nIndex < m_vecUnderLine.size() && m_vecUnderLine[nIndex++] && !bUnderLine && !bUnderLineOut) { ptS = ptLocPre; SetOutputColor(dc, cf); // ads_polar(XPoint(ptS), nRotWcs-PI/2, m_nHeight * GetPScale() / 10, ptS); ads_polar(XPoint(ptS), nRotWcs-PI/2, m_nHeight * pTextPart->m_nWidthFactor * GetPScale() / 10, ptS); bUnderLine = true; } // 下划线结束 if (bUnderLine && ((nIndex < m_vecUnderLine.size() && !m_vecUnderLine[nIndex]) || idx == nCount - 1) && !bUnderLineOut) { ptE = ptLoc; // ads_polar(XPoint(ptE), nRotWcs-PI/2, m_nHeight * GetPScale() / 10, ptE); ads_polar(XPoint(ptE), nRotWcs-PI/2, m_nHeight * pTextPart->m_nWidthFactor * GetPScale() / 10, ptE); TGGeLine line(ptS, ptE); dc.DrawLine(line); bUnderLine = false; } cfPre = cf; } if (pTextPart->m_iType == 2)// 上标或下标文字 { nIndex+=2; } } else if (pTextPart->m_iType == 1)//圆字 { TDbSymbDrawingIndex index; index.CopyPropertiesFrom((AcDbEntity*)this,0); index.SetSymbText(FALSE); // sg add 090729,解决了圆圈文字中的文字图层及颜色错误的BUG XPoint ptLoc; ads_polar(ptBase, nRotWcs, pTextPart->m_ptLowLeft.x+GetHeight(FALSE)/2, ptLoc); ads_polar(XPoint(ptLoc), nRotWcs+PI/2, pTextPart->m_ptLowLeft.y+GetHeight(FALSE)*0.4, ptLoc); index.SetCenter(ptLoc); index.SetRadius(GetHeight()*0.45); //index.SetLineWidth(GetHeight()/30); index.SetIndexLabel(pTextPart->m_sText); index.SetTextStyleId(GetStyleId()); index.SetLayoutRotation(nRotWcs); // zxl 2013.01.28 add int nLen = GetTextLength(pTextPart->m_sText); COLORREF cf = 0; if (nIndex < m_vecCol.size()) { cf = m_vecCol[nIndex+2]; } if (cf == 0) { dc.SetColor(colorIndex()); } else { Adesk::UInt16 col; col = RGBToCADColor(cf); dc.SetColor(col); } nIndex += 4; nIndex += nLen; index.ExplodeOrDraw2d(dc); } } } else { // sg add 120609,增加对9.0新增三角形标高符号的注写功能 if (nCtrlCode==5 || nCtrlCode==6) { XPoint ptTriangle1, ptTriangle2, ptTriangle3, ptTmp; double nRadius = min(pTextPart->GetWidth(), pTextPart->GetHeightReal())*0.3; ads_polar(ptBase, nRotWcs, pTextPart->m_ptLowLeft.x+pTextPart->GetWidth()/2.0, ptTriangle1); ads_polar(ptTriangle1, nRotWcs+PI/2, pTextPart->m_ptLowLeft.y+nRadius*0.5, ptTriangle1); ads_polar(ptTriangle1, nRotWcs+PI/2, pTextPart->m_ptLowLeft.y+nRadius*1.5, ptTmp); ads_polar(ptTmp, nRotWcs, nRadius*1.5, ptTriangle2); ads_polar(ptTmp, nRotWcs, -nRadius*1.5, ptTriangle3); dc << XLine(ptTriangle3, ptTriangle2); dc << XLine(ptTriangle1, ptTriangle3); dc << XLine(ptTriangle1, ptTriangle2); if (nCtrlCode == 5) // 填充 { XPoly2D polySolid(1); polySolid.AppendNode(ptTriangle1); polySolid.AppendNode(ptTriangle2); polySolid.AppendNode(ptTriangle3); dc<m_ptLowLeft.x+pTextPart->GetWidth()/2.0, ptCen); ads_polar(XPoint(ptCen), nRotWcs+PI/2, pTextPart->m_ptLowLeft.y+pTextPart->GetHeightReal()/2.0, ptCen); double nRadius=min(pTextPart->GetWidth(), pTextPart->GetHeightReal())*0.3; dc << XCircle(ptCen, nRadius); if (nCtrlCode==1 || nCtrlCode==2) { XPoint pt1, pt2; ads_polar(ptCen, nRotWcs+PI/2, pTextPart->GetHeightReal()*0.45, pt1); ads_polar(ptCen, nRotWcs-PI/2, pTextPart->GetHeightReal()*0.5, pt2); dc << XLine(pt1, pt2); if (nCtrlCode == 2) { XPoint pta, ptb; ads_polar(pt2, nRotWcs-PI, nRadius, pta); ads_polar(pt2, nRotWcs, nRadius, ptb); dc << XLine(pta, ptb); } } else if (nCtrlCode==3 || nCtrlCode==4) { XPoint pt1, pt2; ads_polar(ptCen, nRotWcs+PI/2, pTextPart->GetHeightReal()*0.45, pt1); ads_polar(ptCen, nRotWcs-PI/2, pTextPart->GetHeightReal()*0.5, pt2); XLine lnMid(pt1, pt2); dc << lnMid.Offset(nRadius*0.3) << lnMid.Offset(-nRadius*0.3); XPoint pta, ptb; ads_polar(pt2, nRotWcs-PI, nRadius, pta); ads_polar(pt2, nRotWcs, nRadius, ptb); dc << XLine(pta, ptb); if (nCtrlCode==4) { ads_polar(pt1, nRotWcs-PI, nRadius, pta); ads_polar(pt1, nRotWcs, nRadius, ptb); dc << XLine(pta, ptb); } } } } }