#include "stdafx.h" #include "AcGiUtil.h" #include "rxregsvc.h" #include "imgdef.h" // AcDbRasterImageDef and reactors, #include "imgent.h" #include "FindParser.h" extern int g_bTextAdjust; //extern AcDbObjectId GetTempEntityId(AcRxClass *pClass, const TCHAR *szBlock, BOOL *bFirstNew=NULL); extern AcDbObjectId InitWipeout(); //extern BOOL g_bLayoutRotate; extern BOOL g_bQuickDragMText; static BOOL g_bPenups = FALSE; extern TARCH_IMPEXP BOOL g_bDownloadT3Split; // sg add 120516,文字导出T3版本时候,是否断开 static bool IsControlChar(TCHAR c) { // sg add 120609,增加对9.0新增三角形标高符号的注写功能 // return (c==_T('1') || c==_T('2') || c==_T('3') || c==_T('4') || c==_T('L') || c==_T('U') || c==_T('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')); } BOOL IsSpacer(TCHAR c) { return (c == _T(' ') || c == _T('\t') || c == _T('\n')); } BOOL IsPunctuation(TCHAR c) { BOOL bRet; switch (c) { case _T(','): case _T(';'): case _T('.'): case _T('?'): bRet = TRUE; break; default: bRet = FALSE; break; } return bRet; } const TCHAR * GetAlignString(XExplodeDraw::TextAlignment m_nAlignment) { const TCHAR *str = _T("未知"); switch (m_nAlignment) { case XExplodeDraw::kTopLeft: str = _T("左上"); break; case XExplodeDraw::kTopCenter: str = _T("中上"); break; case XExplodeDraw::kTopRight: str = _T("右上"); break; case XExplodeDraw::kMiddleLeft: str = _T("左中"); break; case XExplodeDraw::kMiddleCenter: str = _T("正中"); break; case XExplodeDraw::kMiddleRight: str = _T("右中"); break; case XExplodeDraw::kBottomLeft: str = _T("左下"); break; case XExplodeDraw::kBottomCenter: str = _T("中下"); break; case XExplodeDraw::kBottomRight: str = _T("右下"); break; case XExplodeDraw::kLeft: str = _T("左"); break; case XExplodeDraw::kCenter: str = _T("中心"); break; case XExplodeDraw::kRight: str = _T("右"); break; case XExplodeDraw::kMiddle: str = _T("中间"); break; default: break; } return str; } ////////////////////////////////////////////////////////////////////// // TTextPart BOOL TTextPart::IsSpacer() const { int nLen = _tcslen(m_sText); for (int i = 0; i < nLen; i++) if (!::IsSpacer(m_sText[i])) return FALSE; return TRUE; } BOOL TTextPart::IsPunctuation() const { int nLen = _tcslen(m_sText); BOOL bFind = FALSE; for (int i = 0; i < nLen; i++) { if (::IsSpacer(m_sText[i])); else if (::IsPunctuation(m_sText[i])) bFind = TRUE; else return FALSE; } return bFind; } int TTextPart::GetControlCode() const // ^2==2, ^3=3, ^4=4 { int nRet = 0; size_t nCount = _tcslen(m_sText); if (m_sText[0] == _T('^') && nCount == 2) { nRet = _ttoi(&m_sText[1]); // sg add 120609,增加对9.0新增三角形标高符号的注写功能 // if(nRet<1 || nRet>4) if (nRet < 1 || nRet>6) nRet = 0; } return nRet; } TTextPart & TTextPart::operator= (const TTextPart &src) { m_ptLowLeft = src.m_ptLowLeft; //基点 m_bChinese = src.m_bChinese; m_sText = src.m_sText; m_nSizeX = src.m_nSizeX; m_nSizeY = src.m_nSizeY; //总宽, 总高 m_nHeight = src.m_nHeight; m_nHeightReal = src.m_nHeightReal; m_nWidthFactor = src.m_nWidthFactor; //字高 m_iType = src.m_iType; return *this; } //TTextParser::TParserStatus TTextParser::GetNext(XString &sNext) //{ // TParserStatus nStatus; // char szOut[1024] = ""; // const char *p = m_pCurrent; // char *q = szOut; // if (!p || !*p) // nStatus = TTextParser::kEndBuffer; // else // { // BOOL bEng = TRUE; // BOOL bBody = FALSE; // while(*p) // { // if (*p == 13) // 跳过回车符, 后续还有换行符号 // { // p++; // continue; // } // // if (*p>0 && *p<128) // { // if (*p == ' ' || *p == '\t' || *p == '\n') // { // if (bBody) // 有英文或中文在前 // break; // // *q = *p; // if (*p == '\n') // { // p++; // 作为单独的一个文字单位 // q++; // break; // } // } // else if (*p == '^' && IsControlChar(*(p+1))) // { // // 控制符开始 // if (q!=szOut) // 有字符在前 // break; // // if (*(p+1) == 'L' || *(p+1) == 'U') // { // 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? TTextParser::kLowerText : TTextParser::kUpperText; // 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 = TTextParser::kCircleText; // return nStatus; // } // else // { // *q = *p; // p++; // q++; // *q = *p; // q++; // p++; // *q = EOS; // m_pCurrent = p; // sNext = (LPCTSTR)TString(szOut); // return TTextParser::kControlCode; // } // } // else // { // if (bBody && !bEng) // break; // else if (!bBody && q!=szOut) // 有空格 // break; // *q = *p; // bBody = TRUE; // } // bEng = TRUE; // } // else // 汉字 // { // if (bBody && bEng) // break; // else if (!bBody && q!=szOut) // 有空格 // break; // bEng = FALSE; // bBody = TRUE; // *q = *p; // p++; // q++; // ASSERT(*p); // *q = *p; // } // p++; // q++; // } // *q = EOS; // // sNext = (LPCTSTR)TString(szOut); // m_pCurrent = p; // if (szOut[0] == '\n') // nStatus = TTextParser::kParagragh; // else // nStatus = bEng? TTextParser::kNormalEnglish : TTextParser::kNormalChinese; // } // return nStatus; //} TTextParser::TParserStatus TTextParser::GetNext(XString &sNext, BOOL bSplitEAndC) { TParserStatus nStatus; char szOut[1024] = ""; const char *p = m_pCurrent; char *q = szOut; if (!p || !*p) nStatus = TTextParser::kEndBuffer; else { BOOL bEng = TRUE; BOOL bBody = FALSE; BOOL bMix = FALSE; // sg add 120516,标记是否中英文混合 while (*p) { 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 (*(p + 1) == 'L' || *(p + 1) == 'U') // 上下标文字 { 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 ? TTextParser::kLowerText : TTextParser::kUpperText; 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 = TTextParser::kCircleText; return nStatus; } else // 钢筋符号、三角形标高符号 { *q = *p; p++; q++; *q = *p; q++; p++; *q = EOS; m_pCurrent = p; sNext = (LPCTSTR)TString(szOut); return TTextParser::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++; } *q = EOS; sNext = (LPCTSTR)TString(szOut); m_pCurrent = p; if (szOut[0] == '\n') nStatus = TTextParser::kParagragh; else { nStatus = bEng ? TTextParser::kNormalEnglish : TTextParser::kNormalChinese; // sg modify 120516,导出T3时,允许中英文联排,而不管字高 nStatus = bMix ? TTextParser::kT3NormalText : nStatus; } } return nStatus; } BOOL TTextLine::IsEmpty() const { const TTextLine &lines = *this; BOOL bEmpty = TRUE; for (int i = 0; i < lines.Length(); i++) { const TTextPart &part = lines[i]; if (part.IsParagraph() || part.IsSpacer()) ; else { bEmpty = FALSE; break; } } return bEmpty; } double TTextLine::GetHeight(BOOL bFromBase) const { XPoint ptExt = GetExtents(); return (bFromBase ? ptExt.y : ptExt.z); } double TTextLine::GetWidth() const { return GetExtents().x; } void TTextLine::AdjustWidthFactor(double nFactor) { int nCount = Length(); for (int i = 0; i < nCount; i++) { TTextPart *pText = (*this)[i]; pText->m_nSizeX *= nFactor; pText->m_nWidthFactor *= nFactor; pText->m_ptLowLeft.x *= nFactor; } } void TTextLine::AdjustBasePoint(double x) { int nCount = Length(); for (int i = 0; i < nCount; i++) { TTextPart *pText = (*this)[i]; pText->m_ptLowLeft.x += x; } } // 宽度, 基线上的高度, 总高度 XPoint TTextLine::GetExtents() const { double nWidth = 0.0; int nCount = Length(); double nYMin = 0.0, nYMax = 0.0; for (int i = 0; i < nCount; i++) { const TTextPart *pText = &(*this)[i]; nWidth += pText->GetWidth(); nYMin = min(pText->GetYMin(), nYMin); nYMax = max(pText->GetYMax(), nYMax); } XPoint vtExt = XPoint(nWidth, nYMax, nYMax - nYMin); //ASSERT(vtExt.x>0.0 && vtExt.y>0.0 && vtExt.z>0.0); return vtExt; } ///////////////////////////////////////////////////////////// // 文字对象类 ///////////////////////////////////////////////////////////// const Adesk::UInt8 TDbText::g_nVersion = 2; ACRX_DXF_DEFINE_MEMBERS(ATSText, ATSEntity, AcDb::kDHL_CURRENT, AcDb::kMReleaseCurrent, 1, ATS_TEXT, "ATS_TEXT图形无法解析, 请下载上华软件|网址: www.shanghuasoft.com"); IMPLEMENT_TENTBASE(TDbText); TDbText::TDbText() { m_nHeight = 3.5; m_nRotation = 0.0; m_nAlignment = XExplodeDraw::kLeft; m_nMaskFlag = 0; } TDbText::~TDbText() { } Acad::ErrorStatus TDbText::audit(AcDbAuditInfo* pAuditInfo) { //modified by whl on 070613,不再将空的单行文字视为错误,原来这里有重大错误! //BOOL bEmptyText=!m_sText; //BOOL bEmptyText=FALSE; //BOOL bInvalidStyle=!m_idStyle; // if (!bEmptyText || !bInvalidStyle) { // pAuditInfo->errorsFound(bEmptyText+bInvalidStyle); // if (pAuditInfo->fixErrors() == Adesk::kTrue) { // if(bEmptyText) { // pAuditInfo->printError(_T("单行文字"), _T("内容"), _T("不能为空"), _T("")); // m_sText=_T("请输入合适的文字或删除文字"); // } // if(bInvalidStyle) { // pAuditInfo->printError(_T("单行文字"), _T("样式"), _T("不能为空"), _T("")); // m_idStyle=database()->textstyle(); // } // pAuditInfo->errorsFixed(bEmptyText+bInvalidStyle); // return Acad::eFixedAllErrors; // } else // return Acad::eLeftErrorsUnfixed; // } else // return Acad::eOk; // sg add 090806,解决高版本下修复02图纸,对象丢失的问题 Acad::ErrorStatus es = Acad::eOk; es = TDbEntity::audit(pAuditInfo); if (es != Acad::eOk) return es; BOOL bInvalidStyle = !m_idStyle; if (bInvalidStyle) { pAuditInfo->errorsFound(1); if (pAuditInfo->fixErrors() == Adesk::kTrue) { pAuditInfo->printError(_T("单行文字"), _T("样式"), _T("不能为空"), _T("")); m_idStyle = database()->textstyle(); pAuditInfo->errorsFixed(1); return Acad::eFixedAllErrors; } else return Acad::eLeftErrorsUnfixed; } else return es; // return Acad::eOk; } BOOL TDbText::IsValid() const { BOOL bRet = TDbEntity::IsValid(); if (!bRet) return bRet; bRet = (!!m_sText && !!m_idStyle); return bRet; } // 提供对格式刷的支持 void TDbText::CopyPropertiesFrom(AcDbEntity *pSrcEntity, unsigned gMatchFlag) { assertWriteEnabled(); TDbEntity::CopyPropertiesFrom(pSrcEntity, gMatchFlag); TDbText *pSrc = TDbText::cast(pSrcEntity); if (pSrc) { m_nHeight = pSrc->m_nHeight; if (database() == NULL || pSrcEntity->database() == NULL || database() == pSrcEntity->database())//add by whl on 060317 { m_idStyle = pSrc->m_idStyle; //文字样式 } m_nAlignment = pSrc->m_nAlignment; m_nMaskFlag = pSrc->m_nMaskFlag; m_nRotation = pSrc->m_nRotation; } } Acad::ErrorStatus TDbText::subGetClassID(CLSID* pClsid) const { return Acad::eOk; } Acad::ErrorStatus TDbText::DownGradeSave(int nDrawMode, AcDbVoidPtrArray &entSet, BOOL *bErase) { Acad::ErrorStatus es = Acad::eOk; CString sText = m_sText.cs(); if (g_nSaveTArchVer < 7 && sText.Find(_T("^C")) != -1)//7.0开始才有圆圈文字 { XExplodeStream dc(entSet); if (!OnExplodeOrDraw(dc)) return es; dc.SetPropertiesFrom(this);//add by whl on 060218 if (nDrawMode == DRAW_2D) es = ExplodeOrDraw2d(dc); else es = ExplodeOrDraw3d(dc); if (bErase) *bErase = TRUE; } else es = TDbEntity::DownGradeSave(nDrawMode, entSet, bErase); return es; } // 从DWG读入数据: Acad::ErrorStatus TDbText::dwgInFields(AcDbDwgFiler* pFiler) { assertWriteEnabled(); Acad::ErrorStatus es = TDbEntity::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_idStyle); ReadString(pFiler, m_sText); pFiler->readItem((AcGePoint3d *)&m_ptText); pFiler->readItem(&m_nHeight); pFiler->readItem(&m_nRotation); Adesk::UInt8 nAlign; pFiler->readItem(&nAlign); m_nAlignment = (XExplodeDraw::TextAlignment)nAlign; if (nVer > 1) pFiler->readItem(&m_nMaskFlag); return pFiler->filerStatus(); } Acad::ErrorStatus TDbText::dwgOutFields(AcDbDwgFiler* pFiler) const { assertReadEnabled(); Acad::ErrorStatus es = TDbEntity::dwgOutFields(pFiler); if (es != Acad::eOk) return es; pFiler->writeItem(g_nVersion); pFiler->writeItem(m_idStyle); pFiler->writeString(m_sText); pFiler->writeItem((const AcGePoint3d &)m_ptText); pFiler->writeItem(m_nHeight); pFiler->writeItem(m_nRotation); pFiler->writeItem((Adesk::UInt8)m_nAlignment); pFiler->writeItem(m_nMaskFlag); return pFiler->filerStatus(); } Acad::ErrorStatus TDbText::dxfInFields(AcDbDxfFiler* pFiler) { assertWriteEnabled(); Acad::ErrorStatus es = TDbEntity::dxfInFields(pFiler); if (es != Acad::eOk) return es; if (!pFiler->atSubclassData(_T("TDbText"))) { return Acad::eBadDxfSequence; } XString sText, sName; double nHeight; double nRot; int flag1, flag2; XPoint pt; Adesk::UInt32 fieldsFlags = 0; resbuf rb; while ((es == Acad::eOk) && ((es = pFiler->readResBuf(&rb)) == Acad::eOk)) { switch (rb.restype) { case AcDb::kDxfXCoord: pt = rb.resval.rpoint; fieldsFlags |= 0x01; break; case AcDb::kDxfReal: nHeight = rb.resval.rreal; fieldsFlags |= 0x02; break; case AcDb::kDxfText: sText = rb.resval.rstring; fieldsFlags |= 0x04; free(rb.resval.rstring); break; case AcDb::kDxfAngle: nRot = rb.resval.rreal; fieldsFlags |= 0x08; break; case AcDb::kDxfTextStyleName: sName = rb.resval.rstring; fieldsFlags |= 0x10; free(rb.resval.rstring); break; case AcDb::kDxfInt16: fieldsFlags |= 0x20; flag1 = rb.resval.rint; break; case AcDb::kDxfInt16 + 2: fieldsFlags |= 0x40; flag2 = rb.resval.rint; 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: 10")); return Acad::eMissingDxfField; } if (!(fieldsFlags & 0x04)) { pFiler->setError(Acad::eMissingDxfField, _T("\nMissing DXF group code: 1")); return Acad::eMissingDxfField; } if (fieldsFlags & 0x02) m_nHeight = nHeight; if (fieldsFlags & 0x04) m_sText = sText; if (fieldsFlags & 0x08) m_nRotation = nRot; AcDbObjectId id; if (fieldsFlags & 0x10) { id = TchExport::GetTextStyleId(sName, database()); } if (!id) { XString style; if (database()) { m_idStyle = database()->textstyle(); } else { xg_getvar(_T("TEXTSTYLE"), style); m_idStyle = TchExport::GetTextStyleId(style, database()); } } else m_idStyle = id; if (fieldsFlags & 0x20) m_nMaskFlag = flag1; if (fieldsFlags & 0x20) m_nAlignment = (XExplodeDraw::TextAlignment)flag2; return pFiler->filerStatus(); } Acad::ErrorStatus TDbText::dxfOutFields(AcDbDxfFiler* pFiler) const { assertReadEnabled(); Acad::ErrorStatus es = TDbEntity::dxfOutFields(pFiler); assert(es == Acad::eOk); es = pFiler->writeItem(AcDb::kDxfSubclass, _T("TDbText")); assert(es == Acad::eOk); XString sName = GetSymbolName(m_idStyle); pFiler->writePoint2d(AcDb::kDxfXCoord, m_ptText.AsAcGePoint2d()); pFiler->writeDouble(AcDb::kDxfReal, m_nHeight); pFiler->writeString(AcDb::kDxfText, (const TCHAR *)m_sText); pFiler->writeDouble(AcDb::kDxfAngle, m_nRotation); pFiler->writeString(AcDb::kDxfTextStyleName, (const TCHAR *)sName); //7 pFiler->writeInt16(AcDb::kDxfInt16, (Adesk::Int16)m_nMaskFlag); pFiler->writeInt16(AcDb::kDxfInt16 + 2, (Adesk::Int16)m_nAlignment); return es; } // ----------------------------------------------------------------------- Acad::ErrorStatus TDbText::subGetOsnapPoints(AcDb::OsnapMode osnapMode, INT_PTR gsSelectionMark, const AcGePoint3d& pickPoint, const AcGePoint3d& lastPoint, const AcGeMatrix3d& viewXform, AcGePoint3dArray& snapPoints, AcDbIntArray& geomIds) const { assertReadEnabled(); Acad::ErrorStatus es = Acad::eOk; switch (osnapMode) { case AcDb::kOsModeIns: snapPoints.append(m_ptText); break; default: es = Acad::eNotApplicable; } return es; } Acad::ErrorStatus TDbText::subIntersectWith(const AcDbEntity* ent, AcDb::Intersect intType, AcGePoint3dArray& points, INT_PTR thisGsMarker, INT_PTR otherGsMarker) const { return Acad::eNotApplicable; } Acad::ErrorStatus TDbText::subIntersectWith(const AcDbEntity* ent, AcDb::Intersect intType, const AcGePlane& projPlane, AcGePoint3dArray& points, INT_PTR thisGsMarker, INT_PTR otherGsMarker) const { return Acad::eNotApplicable; } // Overriden functions for edit // to do: // 允许通过夹点改变边界 Acad::ErrorStatus TDbText::subGetGripPoints(AcGePoint3dArray& gripPoints, AcDbIntArray& osnapModes, AcDbIntArray& geomIds) const { assertReadEnabled(); gripPoints.append(m_ptText); //0 return Acad::eOk; } // stretch points is diffrent from grep points, with no midpoint included Acad::ErrorStatus TDbText::subGetStretchPoints(AcGePoint3dArray & stretchPoints) const { assertReadEnabled(); AcDbIntArray osnapModes; AcDbIntArray geomIds; return subGetGripPoints(stretchPoints, osnapModes, geomIds); } // Active when being rotated, scaled, moved, etc. // Scale is disabled here Acad::ErrorStatus TDbText::subTransformBy(const AcGeMatrix3d& xform) { assertWriteEnabled(); TDbEntity::subTransformBy(xform); ads_matrix mat; AsAdsMatrix(xform, mat); BOOL bMirror = IsMirrorMatrix(mat); if (bMirror || g_bTextAdjust) { //镜像或角度自调 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(); } 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(); } m_ptText.TransformBy(mat); } return Acad::eOk; } void TDbText::UnionScale(double nScale) { assertWriteEnabled(); AcGeMatrix3d mat; mat.setToScaling(nScale); m_ptText.TransformBy(mat); } // 功能: 夹点操作 Acad::ErrorStatus TDbText::subMoveGripPointsAt( const AcDbIntArray& indices, const AcGeVector3d& offset) { assertWriteEnabled(); XPoint vtOffset(offset[0], offset[1]); for (int i = 0; i < indices.length(); i++) { int idx = indices[i]; switch (idx) { case 0: m_ptText += vtOffset; break; default: break; } } return Acad::eOk; } // 功能: 夹点操作 Acad::ErrorStatus TDbText::subMoveStretchPointsAt( const AcDbIntArray& indices, const AcGeVector3d& offset) { return subMoveGripPointsAt(indices, offset); } // 取得夹点说明 Acad::ErrorStatus TDbText::GetGripText(int i, CString &cs) const { Acad::ErrorStatus es = Acad::eOk; switch (i) { case 0: cs = _T("移动文字"); break; default: es = Acad::eInvalidInput; } return es; } int TDbText::ConvertText(TConvertTextPtr ptr, void *pData) { XString sText; int nRet = ptr(m_sText, sText, pData); if (nRet == RTNORM) { assertWriteEnabled(); m_sText = sText; } return nRet; } void TDbText::GetMaskPoly(std::vector &polys) { XPoint ext = GetExtents(); XPoint origin = Align2Base(GetLocation(), ext); ext.x += ext.y*0.3; ext.y *= 1.3; double xDir = GetRotation() + m_nLayoutRotation; // sg modify 081226,增加了布局转角 double yDir = xDir + PI / 2.0; XVector3D u(cos(xDir), sin(xDir), 0), v(cos(yDir), sin(yDir), 0); u.x *= ext.x; u.y *= ext.x; v.x *= ext.y; v.y *= ext.y; XPoly2D poly2d(1); XPoint ptOldOrg = origin; ads_polar(XPoint(origin), xDir + PI, ext.y*0.1, origin); ads_polar(XPoint(origin), yDir + PI, ext.y*0.2, origin); poly2d.AppendNode(origin); poly2d.AppendNode(origin + u); poly2d.AppendNode(origin + u + v); poly2d.AppendNode(origin + v); polys.push_back(poly2d); } Acad::ErrorStatus TDbText::ExplodeOrDraw2d(XExplodeDraw &dc) const { //TPushProperty vProp(this, dc); assertReadEnabled(); //20160919 wlw CAD2015以上平台,绘制时出现形文件未定义 AcDbObjectId idst = GetTextStyleId(_T("standard")); if (idst.isValid()) { dc.SetStyle(idst); } if (m_nMaskFlag && _tcscmp(dc.Desc(), XAcGiViewDraw::Descriptor()) == 0) { XPoint ext = GetExtents(); XPoint origin = Align2Base(GetLocation(), ext); // origin.y -= ext.y*0.2; // origin.x -= ext.y*0.1; // ext.x += ext.y*0.2; // sg modify 081229,屏蔽不能完全遮盖住文字 ext.x += ext.y*0.3; ext.y *= 1.3; /// double xDir = GetRotation(); double xDir = GetRotation() + m_nLayoutRotation; // sg modify 081226,增加了布局转角 double yDir = xDir + PI / 2.0; XVector3D u(cos(xDir), sin(xDir), 0), v(cos(yDir), sin(yDir), 0); u.x *= ext.x; u.y *= ext.x; v.x *= ext.y; v.y *= ext.y; XPoly2D poly2d(1); XPoint ptOldOrg = origin; ads_polar(XPoint(origin), xDir + PI, ext.y*0.1, origin); ads_polar(XPoint(origin), yDir + PI, ext.y*0.2, origin); poly2d.AppendNode(origin); poly2d.AppendNode(origin + u); poly2d.AppendNode(origin + u + v); poly2d.AppendNode(origin + v); COLORREF colorImage; AcColorSettings setAcadColor; acedGetCurrentColors(&setAcadColor); int tilemode; xg_getvar(_T("TILEMODE"), &tilemode); colorImage = tilemode ? setAcadColor.dwGfxModelBkColor : setAcadColor.dwGfxLayoutBkColor; AcCmEntityColor color; if (colorImage == RGB(255, 255, 255)) { color.setColorIndex(255); } else { //color.setTrueColor(); color.setRGB(GetRValue(colorImage), GetGValue(colorImage), GetBValue(colorImage)); } AcGiCommonDraw *dcCommon = ((XAcGiViewDraw &)dc).GetCommonDraw(); if (!dcCommon->context()->isPlotGeneration()) { AcGiFillType nFillType = dcCommon->subEntityTraits().fillType(); AcCmEntityColor cmColor = dcCommon->subEntityTraits().trueColor(); dcCommon->subEntityTraits().setFillType(kAcGiFillAlways); dcCommon->subEntityTraits().setTrueColor(color); dc << XSolid(poly2d); dcCommon->subEntityTraits().setFillType(nFillType); dcCommon->subEntityTraits().setTrueColor(cmColor); } } // XString sTextStyle=GetSymbolName(m_idStyle); // sg add 120516,只要在导出T3的时候,才不分解中英文文字,其他情况一律分解 BOOL bSplitEAndC = !(dc.IsFullExplode() && dc.IsExportTch4()) || g_bDownloadT3Split; TTextLine lstTextParts; // if (!GetTextParts(lstTextParts)) if (!GetTextParts(lstTextParts, bSplitEAndC)) return Acad::eInvalidInput; XPoint ptBase = Align2Base(m_ptText, lstTextParts.GetExtents()); dc.SetStyle(m_idStyle); dc.SetRotation(Layout2Wcs(m_nRotation)); OutputTextLine(dc, ptBase, lstTextParts); return Acad::eOk; } /* Adesk::Boolean TDbText::worldDraw(AcGiWorldDraw *pWd) { Adesk::Boolean bDraw=TDbEntity::worldDraw(pWd); if(m_nMaskFlag) { AcGiContext* pContext=pWd->context(); if(pContext && pContext->isPlotGeneration()) { } else if(pWd->regenType()==kAcGiStandardDisplay) { bDraw=Adesk::kFalse; } } return bDraw; } void TDbText::viewportDraw(AcGiViewportDraw* pMode) { if(m_nMaskFlag) { AcGiContext* pContext=pMode->context(); if(pContext && pContext->isPlotGeneration()) { } else if(pMode->regenType()==kAcGiStandardDisplay) { AcDbObjectId idImage=InitWipeout(); OPENOBJ_BEGIN(idImage, AcDb::kForWrite, AcDbRasterImage, pImage); if(pImage) { pImage->viewportDraw(pMode); } OPENOBJ_END(); } } TDbEntity::viewportDraw(pMode); } */ void TDbText::OutputTextLine(XExplodeDraw &dc, XPoint ptBase, const DList &lineText) 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; i < nCount; i++) { const TTextPart *pTextPart = &lineText[i]; if (bExpl && pTextPart->IsSpacer()) continue; int nCtrlCode = pTextPart->GetControlCode(); if (!nCtrlCode) { switch (pTextPart->m_iType) { case 0://文字 { // 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); //add by xlc on 101105 解决楼梯中的文字和箭头不同层的问题 //modify by xlc on 110628 04平台文字颜色ByBlock时打印崩溃 //dc.SetColor(colorIndex()); //dc.SetLayer(layerId()); if (!(g_bPrinting && colorIndex() == 0 && g_nAcadVer > 15.0 && g_nAcadVer < 16.01)) { dc.SetColor(colorIndex()); dc.SetLayer(layerId()); } dc.DrawText(pTextPart->m_sText); } break; case 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); index.ExplodeOrDraw2d(dc); } break; } } 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 << XSolid(polySolid); } continue; } // 输出钢筋符号 XPoint ptCen; ads_polar(ptBase, nRotWcs, pTextPart->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); } } } } } // 没有考虑转角 BOOL TDbText::GetExtents(double *pWidth, double *pHeight, double *pHeight1) const { TTextLine lstTextParts; if (!GetTextParts(lstTextParts)) return FALSE; XPoint ext = lstTextParts.GetExtents(); if (pWidth) *pWidth = ext.x; if (pHeight) *pHeight = ext.y; if (pHeight1) *pHeight1 = ext.z; return TRUE; } // 没有考虑转角 XPoint TDbText::GetExtents() const { XPoint ext; TTextLine lstTextParts; if (!GetTextParts(lstTextParts)) return ext; ext = lstTextParts.GetExtents(); return ext; } const TCHAR *TDbText::GetDefaultLayer() const { return LAY_TEXT; } TEntityBase::DrawType TDbText::GetDrawType() const { return TEntityBase::k2DOnly; } /* * * * * * * * * * 取 动 态 属 性 显 示 数 据 的 函 数 * * * * * * * * * */ void TDbText::GetTips(DList &lstInfo) const { lstInfo.Append(new TObjInfoUnit(_T("对象类型"), _T("文字"))); lstInfo.Append(new TObjInfoUnit(_T("文字内容"), m_sText)); XString sTextStyle = GetSymbolName(m_idStyle); lstInfo.Append(new TObjInfoUnit(_T("文字样式"), sTextStyle)); lstInfo.Append(new TObjInfoUnit(_T("对正方式"), GetAlignString(m_nAlignment))); XString sHeight; ftoa(m_nHeight, 1, sHeight); sHeight << _T("P"); lstInfo.Append(new TObjInfoUnit(_T("文字高度"), sHeight)); lstInfo.Append(new TObjInfoUnit(_T("旋转角度"), Angle2Str(m_nRotation * 180 / PI))); } // 下面两个变量未使用 BOOL TARCH_IMPEXP g_bUseTextMatchRule = FALSE;//使用通配符 BOOL TARCH_IMPEXP g_bIgnoreCaps = FALSE; //忽略大小写 TARCH_IMPEXP XFindParser g_FindParser; // 返回发现的位置,同时posStart往前移动(以便继续找下一个使用), TTextPosition TDbText::FindSubText(const TCHAR *sSubText, TTextPosition &posStart, TTextRange *pRange) const { XPushMemVar bPenups(g_bPenups, TRUE); TTextPosition pos; // if(!sSubText || !sSubText[0]) // 支持查找空字符串 if (!sSubText) return pos; CString csText = (const TCHAR *)GetText(); // Zyu add on 101105,根据搜索设置对字符串进行一次分析 CString csSubText; // 搜索的字符串 // 不能匹配到则直接返回 if (!g_FindParser.Find(sSubText, csText, posStart.m_nTextPos)) { return pos; } // 得到匹配结果 else { csSubText = g_FindParser.GetResult(); } size_t nPos = 0; if (!posStart) ; else nPos = posStart.m_nTextPos; size_t nCharByte = _tcslen(csText); if (nPos >= nCharByte) return pos; pos = posStart; //int nFindPos=csText.Find(sSubText, nPos); int nFindPos = csText.Find(csSubText, nPos); pos.m_nTextPos = nFindPos; //pos.m_nBufLen=_tcslen(sSubText); pos.m_nBufLen = csSubText.GetLength(); if (pRange && !!pos) { XString sPrefix(nCharByte + 1); StrCpy(sPrefix, csText, &((const TCHAR *)csText)[nFindPos]); //前面的字符串 XPoint ptExt = GetExtents(); //x, y方向的尺寸 XPoint ptTextBase = Align2Base(GetLocation(), ptExt); //左下角 double nRot = GetRotation(); //转角 XPoint ptLowLeft; TDbText *pClone = (TDbText *)this->clone(); pClone->SetText(sPrefix); XPoint extTemp = pClone->GetExtents(); ads_polar(ptTextBase, nRot, extTemp.x, ptLowLeft); //pClone->SetText(sSubText); pClone->SetText(csSubText); extTemp = pClone->GetExtents(); delete pClone; // 求找到的位置范围 XPoly2D *pPoly = new XPoly2D(1); XPoly2D &polyExt = *pPoly; polyExt.AppendNode(ptLowLeft); XPoint ptTemp; ads_polar(ptLowLeft, nRot, extTemp.x, ptTemp); polyExt.AppendNode(ptTemp); ads_polar(ptTemp, nRot + PI / 2, extTemp.y, ptTemp); polyExt.AppendNode(ptTemp); ads_polar(ptLowLeft, nRot + PI / 2, extTemp.y, ptTemp); polyExt.AppendNode(ptTemp); pRange->m_lstRanges.Reset(); pRange->m_lstRanges.Append(pPoly); } //posStart.m_nTextPos = nFindPos + _tcslen(sSubText); posStart.m_nTextPos = nFindPos + csSubText.GetLength(); return pos; } // 返回下一次查找的开始位置 TTextPosition TDbText::ReplaceSubText(const TTextPosition &posRep, const TCHAR *sRepText, TTextRange *pRange) { assertWriteEnabled(); XPushMemVar bPenups(g_bPenups, TRUE); TTextPosition pos; pos.m_nBufLen = _tcslen(sRepText); pos.m_nCookies = posRep.m_nCookies; if (!posRep) return pos; size_t nFindPos = posRep.m_nTextPos; CString csText = (const TCHAR *)GetText(); size_t nCharByte = _tcslen(csText); if (nFindPos + posRep.m_nBufLen > nCharByte) return pos; XString sPrefix(nCharByte + 1), sSuffix(nCharByte + 1); StrCpy(sPrefix, csText, &((const TCHAR *)csText)[nFindPos]); //前面的字符串 StrCpy(sSuffix, &((const TCHAR *)csText)[nFindPos + posRep.m_nBufLen], NULL); CString csNewString; csNewString += (const TCHAR *)sPrefix; csNewString += (const TCHAR *)sRepText; csNewString += (const TCHAR *)sSuffix; size_t nPos = posRep.m_nTextPos + _tcslen(sRepText); SetText(csNewString); // Zyu modify on 101105,继续查找的位置始终为nPos //if(nPos>=nCharByte) //不需要继续查找 // pos.m_nTextPos=-1; // else // pos.m_nTextPos=nPos; pos.m_nTextPos = nPos; if (pRange) { XPoint ptExt = GetExtents(); //x, y方向的尺寸 XPoint ptTextBase = Align2Base(GetLocation(), ptExt); //左下角 double nRot = GetRotation(); //转角 XPoint ptLowLeft; TDbText *pClone = (TDbText *)this->clone(); pClone->SetText(sPrefix); XPoint extTemp = pClone->GetExtents(); ads_polar(ptTextBase, nRot, extTemp.x, ptLowLeft); pClone->SetText(sRepText); extTemp = pClone->GetExtents(); delete pClone; // 求找到的位置范围 XPoly2D *pPoly = new XPoly2D(1); XPoly2D &polyExt = *pPoly; polyExt.AppendNode(ptLowLeft); XPoint ptTemp; ads_polar(ptLowLeft, nRot, extTemp.x, ptTemp); polyExt.AppendNode(ptTemp); ads_polar(ptTemp, nRot + PI / 2, extTemp.y, ptTemp); polyExt.AppendNode(ptTemp); ads_polar(ptLowLeft, nRot + PI / 2, extTemp.y, ptTemp); polyExt.AppendNode(ptTemp); pRange->m_lstRanges.Reset(); pRange->m_lstRanges.Append(pPoly); } return pos; } // Helper Method XPoint TDbText::Align2Base(XPoint ptAlign, XPoint ext) const { XPoint ptBase = XExplodeDraw::Align2Base(m_nAlignment, ptAlign, ext); ads_matrix mat; ptAlign.GetRotationMatrix(m_nLayoutRotation + m_nRotation, mat); ptBase.TransformBy(mat); return ptBase; } XPoint TDbText::Base2Align(XPoint ptBase, XPoint ext) const { XPoint ptAlign = XExplodeDraw::Base2Align(m_nAlignment, ptBase, ext); ads_matrix mat; ptBase.GetRotationMatrix(m_nLayoutRotation + m_nRotation, mat); ptAlign.TransformBy(mat); return ptAlign; } AcDbEntity * TDbText::CreateWipeOut() const { if (m_nMaskFlag) { AcDbObjectId idImage = InitWipeout(); OPENOBJ_BEGIN(idImage, AcDb::kForRead, AcDbEntity, pImage); if (pImage) return (AcDbEntity *)pImage->clone(); OPENOBJ_END(); } return NULL; } AcDbObjectId TDbText::InitWipeout() const { #if (ADS<16) if(!AT_loaded(_T("wipeout"))) { int nRet=acrxLoadModule(_T("wipeout.arx"), Adesk::kFalse, true); if(!nRet) { adsout << _T("\n请事先安装AutoCAD快捷工具!"); return FALSE; } } //LH 2013-2-27 修改原因当ADS=19时不执行下面代码 //#else if (ADS<19) #endif #if (16at(_T("AcDbWipeout"))); if (pClass == NULL) { return FALSE; } BOOL bFirstNew = FALSE; AcDbObjectId idEnt = GetTempEntityId(pClass, _T("_$TMP_BLOCK"), &bFirstNew); OPENOBJ_BEGIN(idEnt, AcDb::kForWrite, AcDbRasterImage, pAcDbRasterImage); if (pAcDbRasterImage) { if (bFirstNew) pAcDbRasterImage->setDatabaseDefaults(); SetupImageInfo(pAcDbRasterImage); } OPENOBJ_END(); return idEnt; } void TDbText::SetupImageInfo(AcDbRasterImage *pAcDbRasterImage) const { // pAcDbRasterImage->setFade(100); // double xDir = GetRotation(); // sg modify 081226,增加了布局转角 double xDir = GetRotation() + m_nLayoutRotation; double yDir = xDir + PI / 2.0; AcGeVector3d u(cos(xDir), sin(xDir), 0), v(cos(yDir), sin(yDir), 0); XPoint ext = GetExtents(); XPoint origin = Align2Base(GetLocation(), ext); // origin.y -= ext.y*0.2; // origin.x -= ext.y*0.1; XPoint ptOldOrg = origin; ads_polar(XPoint(origin), xDir + PI, ext.y*0.1, origin); ads_polar(XPoint(origin), yDir + PI, ext.y*0.2, origin); // ext.x += ext.y*0.2; // sg modify 081229,屏蔽不能完全遮盖住文字 ext.x += ext.y*0.3; ext.y *= 1.3; u *= ext.x; v *= ext.y; pAcDbRasterImage->setOrientation(origin, u, v); pAcDbRasterImage->setClipBoundaryToWholeImage(); } // ___ end createAcDbRasterImage extern BOOL g_bDClickInplaceEdit; TSubText* TDbText::HitTestText(XPoint pt)const { return g_bDClickInplaceEdit ? GetSubText(0) : NULL; } BOOL TDbText::ConvertFrom(const AcDbText *pText) { assertWriteEnabled(); if (pText->isMirroredInX() || pText->isMirroredInY()) return FALSE; AcDbObjectId idStyle = pText->textStyle(); double dotVec = pText->normal().dotProduct(AcGeVector3d(0, 0, 1)); if (fabs(dotVec - 1.0) > 1.0E-6 || !idStyle) return FALSE; AcDb::TextHorzMode nHorMode = pText->horizontalMode(); AcDb::TextVertMode nVerMode = pText->verticalMode(); m_nAlignment = XExplodeDraw::GetTextAlignment(nHorMode, nVerMode); if (!m_nAlignment) //return FALSE; //m_nAlignment=XExplodeDraw::kLeft;//modified by whl on 040923 m_nAlignment = XExplodeDraw::kBottomLeft;//modified by whl on 070108 setPropertiesFrom(pText); m_idStyle = idStyle; m_ptText = m_nAlignment == XExplodeDraw::kLeft ? pText->position() : pText->alignmentPoint(); m_nHeight = pText->height() / GetPScale(); m_sText = pText->textString(); m_nRotation = Wcs2Layout(pText->rotation()); //add by whl on 041216,属性不执行以下操作 if (pText->isKindOf(AcDbAttributeDefinition::desc()) || pText->isKindOf(AcDbAttribute::desc())) return TRUE; //保持原有尺寸,add by whl on 040908 AcDbExtents ext; pText->getGeomExtents(ext); XPoint ptLow, ptUp; GetExtents2d(ptLow, ptUp); double w0 = ext.maxPoint().x - ext.minPoint().x; double h0 = ext.maxPoint().y - ext.minPoint().y; double w1 = ptUp.x - ptLow.x; double h1 = ptUp.y - ptLow.y; ads_matrix mat; //add by whl on 041216 if (w1 < 1E-6 || h1 < 1E-6 || w0 < 1E-6 || h0 < 1E-6) return TRUE; m_ptText.GetScaleMatrix(w0 / w1, h0 / h1, 1, mat); subTransformBy(AsAcGeMatrix3d(mat)); return TRUE; } //最小元素 // 待改进penups //BOOL TDbText::GetTextParts(DList &lstTextParts) 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; // // int nRetFlag = txtStyle.loadStyleRec(); // TCHAR *pWinFont = NULL; // const TCHAR *pBigFont = NULL; // BOOL bold, italic; // int charset, pitch; // BOOL bWinFont = FALSE; // BOOL bBigFont = FALSE; // BOOL penups = TRUE; // FALSE则测量正确,TRUE则中英文衔接顺畅 // if (txtStyle.font(pWinFont, bold, italic, charset, pitch)==Acad::eOk && pWinFont && pWinFont[0]) // { // delete [] pWinFont; // bWinFont = TRUE; // } // // if ((pBigFont = txtStyle.bigFontFileName())!=NULL && pBigFont[0]) // bBigFont = TRUE; // // double nPScale = GetPScale(); // double nHeightC = 3.5, // nHeightE = 3.5; // double nWidthFactorC = 1.0, // nWidthFactorE = 1.0; // if (!GetStyleParam1(&nHeightC, &nWidthFactorC)) // return FALSE; // // if (bWinFont || !GetStyleParam2(&nHeightE, &nWidthFactorE)) // { // nHeightE = nHeightC; // nWidthFactorE = nWidthFactorC; // } // // lstTextParts.Reset(); // 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; // } // // // XPoint ptLowLeft; // TTextParser parser1(m_sText); // XString sWord1; // TTextParser::TParserStatus nStatus1; // double nSizeScale = 0.5; // double nHeight1 = nHeightC; // while((nStatus1=parser1.GetNext(sWord1)) != TTextParser::kEndBuffer) // { // if (nStatus1 == TTextParser::kParagragh) // { // ptLowLeft = XPoint(); // lstTextParts.Append(new TTextPart(sWord1, ptLowLeft, FALSE, 0.0, 0.0, 0.0, 0.0, 0.0)); // } // else if (nStatus1==TTextParser::kNormalEnglish || nStatus1==TTextParser::kNormalChinese // || nStatus1==TTextParser::kControlCode) // { // nHeight1 = (nStatus1==TTextParser::kNormalEnglish ? nHeightE : nHeightC); // double nScale1 = (nStatus1==TTextParser::kNormalEnglish ? nWidthFactorE : nWidthFactorC); // txtStyle.setTextSize((bWinFont || nStatus1==TTextParser::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; // // lstTextParts.Append(new TTextPart(sWord1, ptLowLeft, // nStatus1==TTextParser::kNormalChinese, nHeight1, // ((bWinFont || nStatus1==TTextParser::kNormalChinese)? nHeight1*nSize2Real : nHeight1), // nScale1, ext1[0], ext1[1])); // ptLowLeft.x += ext1.x; // } // else if (nStatus1 == TTextParser::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)) != 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); // // lstTextParts.Append(new TTextPart(sWord2, ptLowLeft, // nStatus2==TTextParser::kNormalChinese, // nSizeScale*nHeight2, nAcadSize, // nScale2, ext2[0], ext2[1])); // ptLowLeft.x += ext2.x; // } // } // } // return TRUE; //} BOOL TDbText::GetTextParts(DList &lstTextParts, BOOL bSplitEAndC) 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; int nRetFlag = txtStyle.loadStyleRec(); TCHAR *pWinFont = NULL; const TCHAR *pBigFont = NULL; BOOL bWinFont = FALSE; BOOL bBigFont = FALSE; BOOL penups = TRUE; // FALSE则测量正确,TRUE则中英文衔接顺畅 #if ADS < 21 BOOL bold, italic; int charset, pitch; if (txtStyle.font(pWinFont, bold, italic, charset, pitch) == Acad::eOk && pWinFont && pWinFont[0]) #else bool bold, italic; Autodesk::AutoCAD::PAL::FontUtils::FontPitch pitch; Autodesk::AutoCAD::PAL::FontUtils::FontFamily family; Charset charset; if (txtStyle.font(pWinFont, bold, italic, charset, pitch, family) == Acad::eOk && pWinFont && pWinFont[0]) #endif { delete[] pWinFont; bWinFont = TRUE; } if ((pBigFont = txtStyle.bigFontFileName()) != NULL && pBigFont[0]) bBigFont = TRUE; double nPScale = GetPScale(); double nHeightC = 3.5, nHeightE = 3.5; double nWidthFactorC = 1.0, nWidthFactorE = 1.0; if (!GetStyleParam1(&nHeightC, &nWidthFactorC)) return FALSE; if (bWinFont || !GetStyleParam2(&nHeightE, &nWidthFactorE)) { nHeightE = nHeightC; nWidthFactorE = nWidthFactorC; } lstTextParts.Reset(); 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; } XPoint ptLowLeft; #ifdef TASD //mod my xlc on 140326 添加钢筋符号 //TTextParser parser1(m_sText); CString strText(m_sText); strText.Replace(_T("^1"), _T("")); strText.Replace(_T("^2"), _T("")); strText.Replace(_T("^3"), _T("")); strText.Replace(_T("^4"), _T("")); strText.Replace(_T("^5"), _T("")); strText.Replace(_T("^6"), _T("")); strText.Replace(_T("^7"), _T("")); strText.Replace(_T("^8"), _T("")); strText.Replace(_T("^9"), _T("")); TTextParser parser1(strText); #else TTextParser parser1(m_sText); #endif XString sWord1; TTextParser::TParserStatus nStatus1; double nSizeScale = 0.5; double nHeight1 = nHeightC; while ((nStatus1 = parser1.GetNext(sWord1, bSplitEAndC)) != TTextParser::kEndBuffer) { if (nStatus1 == TTextParser::kParagragh) { ptLowLeft = XPoint(); lstTextParts.Append(new TTextPart(sWord1, ptLowLeft, FALSE, 0.0, 0.0, 0.0, 0.0, 0.0)); } else if (nStatus1 == TTextParser::kNormalEnglish || nStatus1 == TTextParser::kNormalChinese || nStatus1 == TTextParser::kControlCode) { nHeight1 = (nStatus1 == TTextParser::kNormalEnglish ? nHeightE : nHeightC); double nScale1 = (nStatus1 == TTextParser::kNormalEnglish ? nWidthFactorE : nWidthFactorC); txtStyle.setTextSize((bWinFont || nStatus1 == TTextParser::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; lstTextParts.Append(new TTextPart(sWord1, ptLowLeft, nStatus1 == TTextParser::kNormalChinese, nHeight1, ((bWinFont || nStatus1 == TTextParser::kNormalChinese) ? nHeight1*nSize2Real : nHeight1), nScale1, ext1[0], ext1[1])); ptLowLeft.x += ext1.x; } else if (nStatus1 == TTextParser::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; lstTextParts.Append(new TTextPart(sWord1, ptLowLeft, TRUE, nHeight1, nHeight1*nSize2Real, nScale1, ext1[0], ext1[1])); ptLowLeft.x += ext1.x; } else if (nStatus1 == TTextParser::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); lstTextParts.Append(new TTextPart(sWord2, ptLowLeft, nStatus2 == TTextParser::kNormalChinese, nSizeScale*nHeight2, nAcadSize, nScale2, ext2[0], ext2[1])); ptLowLeft.x += ext2.x; } } } return TRUE; } // Properties BOOL TDbText::GetStyleParam1(double *nHeight, double *nWidthFactor) const { *nHeight = m_nHeight; OPENOBJ_BEGIN(m_idStyle, AcDb::kForRead, AcDbTextStyleTableRecord, pStyle); ASSERT(pStyle); if (!pStyle) return FALSE; *nWidthFactor = pStyle->xScale(); OPENOBJ_END(); return TRUE; } BOOL TDbText::GetStyleParam2(double *nHeight, double *nWidthFactor) const { extern BOOL g_bTextStyleEx; if (!g_bTextStyleEx) return FALSE; // Add 2002/8/20,支持TEXT的查找定位 double h1 = 3.5, x1 = 1.0; if (!GetStyleParam1(&h1, &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(); *nHeight = h1*sh; *nWidthFactor = x1*sw / sh; return TRUE; } XPoint TDbText::GetLocation() const { return m_ptText; } double TDbText::GetRotation() const { return m_nRotation; } double TDbText::GetHeight(BOOL bAsPaperUnit) const { double nVal = m_nHeight; if (!bAsPaperUnit) nVal *= GetPScale(); return nVal; } Adesk::UInt8 TDbText::GetMaskFlag() const { return m_nMaskFlag; } XExplodeDraw::TextAlignment TDbText::GetAlignment() const { return m_nAlignment; } AcDbObjectId TDbText::GetStyleId() const { return m_idStyle; } const TCHAR* TDbText::GetText() const { return (const TCHAR*)m_sText; } void TDbText::SetLocation(XPoint pt) { assertWriteEnabled(); m_ptText = pt; } void TDbText::SetRotation(double nRot) { assertWriteEnabled(); m_nRotation = nRot; } void TDbText::SetHeight(double nHeight, BOOL bAsPaperUnit) { assertWriteEnabled(); m_nHeight = nHeight; if (!bAsPaperUnit) m_nHeight /= GetPScale(); } void TDbText::SetAlignment(XExplodeDraw::TextAlignment nAlign) { assertWriteEnabled(); m_nAlignment = nAlign; } void TDbText::SetStyleId(AcDbObjectId id) { assertWriteEnabled(); m_idStyle = id; } void TDbText::SetText(const TCHAR *pszText) { assertWriteEnabled(); m_sText = pszText; } void TDbText::SetMaskFlag(Adesk::UInt8 nFlag) { assertWriteEnabled(); m_nMaskFlag = nFlag; } BOOL TDbText::TBaseConvertFrom(const AcDbText *pText) { return ConvertFrom(pText); } AcDbEntity* TDbText::TBaseCreateWipeOut() { return CreateWipeOut(); } const TCHAR * TDbText::TBaseGetText() const { return (const TCHAR *)GetText(); } void TDbText::TBaseSetText(const TCHAR *pszText) { SetText(pszText); } TADSGePoint3d TDbText::TBaseGetLocation() const { return GetLocation(); } void TDbText::TBaseSetLocation(TADSGePoint3d pt) { SetLocation(pt); } void TDbText::TBaseSetRotation(double nRot) { SetRotation(nRot); } double TDbText::TBaseGetRotation() const { return GetRotation(); } // sg add 101116,支持统一标高 bool TDbText::UnifyElevation(double dElevation) { assertWriteEnabled(); m_ptText.z = dElevation; return true; } ///////////////////////////////////////////////////////////////////////// const Adesk::UInt8 TDbMText::g_nVersion = 1; ACRX_DXF_DEFINE_MEMBERS(ATSMText, ATSText, AcDb::kDHL_CURRENT, AcDb::kMReleaseCurrent, 1, ATS_MTEXT, "ATS_MTEXT图形无法解析, 请下载上华软件|网址: www.shanghuasoft.com"); IMPLEMENT_TENTBASE(TDbMText); TDbMText::TDbMText() { m_nAlignment = XExplodeDraw::kTextFit; m_nPageWidth = 0.0; m_nLineSpace = 0.0; } TDbMText::~TDbMText() { } // 只支持4种对齐方式 BOOL TDbMText::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 TDbMText::CopyPropertiesFrom(AcDbEntity *pSrcEntity, unsigned gMatchFlag) { assertWriteEnabled(); TDbText::CopyPropertiesFrom(pSrcEntity, gMatchFlag); TDbMText *pSrc = TDbMText::cast(pSrcEntity); if (pSrc) { //m_nPageWidth; //段落宽度 m_nPageWidth = pSrc->m_nPageWidth; m_nLineSpace = pSrc->m_nLineSpace; //行间距 } } // 返回发现的位置,同时posStart往前移动(以便继续找下一个使用), TTextPosition TDbMText::FindSubText(const TCHAR *sSubText, TTextPosition &posStart, TTextRange *pRange) const { TTextPosition posFind = TDbText::FindSubText(sSubText, posStart); if (!posFind || !pRange) return posFind; // 求pRange位置 TDbMText *pClone = (TDbMText *)clone(); pClone->m_sText[posFind.m_nTextPos] = EOS; //起始位置 XPoint ptTopLeft = pClone->m_ptText; DList lstLines; pClone->GetTextLines(lstLines); int numLine = lstLines.Length(); if (numLine == 0) numLine = 1; double nYOffset = numLine*GetHeight(FALSE) + (numLine - 1)*GetLineSpace(FALSE); double nAngWcs = AngleRangeTo2PI(m_nLayoutRotation + m_nRotation); XPoint ptLineStart; ads_polar(m_ptText, nAngWcs - PI / 2, nYOffset, ptLineStart); XPoint vtExt; if (lstLines.Tail()) vtExt = lstLines.Tail()->GetExtents(); XPoint 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; XPoint ptLineStart2; nYOffset = numLineNew*GetHeight(FALSE) + (numLineNew - 1)*GetLineSpace(FALSE); ads_polar(m_ptText, nAngWcs - PI / 2, nYOffset, ptLineStart2); XPoint vtExt1; if (lstLines.Tail()) vtExt1 = lstLines.Tail()->GetExtents(); XPoint ptRangeEnd; ads_polar(ptLineStart2, nAngWcs, vtExt1.x, ptRangeEnd); pRange->m_lstRanges.Reset(); if (numLine == numLineNew) { XPoly2D *pPoly = new XPoly2D(1); pPoly->AppendNode(ptRangeStart); pPoly->AppendNode(ptRangeEnd); XPoint 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); XPoint ptLineEnd; ads_polar(ptLineStart, nAngWcs, nPageWidth, ptLineEnd); XPoly2D *pPoly = new XPoly2D(1); XPoint ptTemp; if (ptRangeStart.Distance2d(ptLineEnd) < _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++) { XPoint ptLineStart1, ptLineEnd1; ads_polar(ptLineStart, nAngWcs - PI / 2, n*(GetHeight(FALSE) + GetLineSpace(FALSE)), ptLineStart1); ads_polar(ptLineStart1, nAngWcs, nPageWidth, ptLineEnd1); XPoly2D *pPoly = new XPoly2D(1); pPoly->AppendNode(ptLineStart1); pPoly->AppendNode(ptLineEnd1); XPoint 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 XPoly2D(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; } // 返回下一次查找的开始位置 TTextPosition TDbMText::ReplaceSubText(const TTextPosition &posRep, const TCHAR *sRepText, TTextRange *pRange) { TTextPosition posNext = TDbText::ReplaceSubText(posRep, sRepText); if (!posRep || !pRange) return posNext; // 求pRange位置 TDbMText *pClone = (TDbMText *)clone(); pClone->m_sText[posRep.m_nTextPos] = EOS; //起始位置 XPoint ptTopLeft = pClone->m_ptText; DList lstLines; pClone->GetTextLines(lstLines); int numLine = lstLines.Length(); if (numLine == 0) numLine = 1; double nYOffset = numLine*GetHeight(FALSE) + (numLine - 1)*GetLineSpace(FALSE); double nAngWcs = AngleRangeTo2PI(m_nLayoutRotation + m_nRotation); XPoint ptLineStart; ads_polar(m_ptText, nAngWcs - PI / 2, nYOffset, ptLineStart); XPoint vtExt; if (lstLines.Tail()) vtExt = lstLines.Tail()->GetExtents(); XPoint 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; XPoint ptLineStart2; nYOffset = numLineNew*GetHeight(FALSE) + (numLineNew - 1)*GetLineSpace(FALSE); ads_polar(m_ptText, nAngWcs - PI / 2, nYOffset, ptLineStart2); XPoint vtExt1; if (lstLines.Tail()) vtExt1 = lstLines.Tail()->GetExtents(); XPoint ptRangeEnd; ads_polar(ptLineStart2, nAngWcs, vtExt1.x, ptRangeEnd); pRange->m_lstRanges.Reset(); if (numLine == numLineNew) { XPoly2D *pPoly = new XPoly2D(1); if (ptRangeStart.Distance2d(ptRangeEnd) < _DIST_SNAP) delete pPoly; else { pPoly->AppendNode(ptRangeStart); pPoly->AppendNode(ptRangeEnd); XPoint 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); XPoint ptLineEnd; ads_polar(ptLineStart, nAngWcs, nPageWidth, ptLineEnd); XPoly2D *pPoly = new XPoly2D(1); XPoint ptTemp; if (ptRangeStart.Distance2d(ptLineEnd) < _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++) { XPoint ptLineStart1, ptLineEnd1; ads_polar(ptLineStart, nAngWcs - PI / 2, n*(GetHeight(FALSE) + GetLineSpace(FALSE)), ptLineStart1); ads_polar(ptLineStart1, nAngWcs, nPageWidth, ptLineEnd1); XPoly2D *pPoly = new XPoly2D(1); pPoly->AppendNode(ptLineStart1); pPoly->AppendNode(ptLineEnd1); XPoint 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 XPoly2D(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 TDbMText::subGetClassID(CLSID* pClsid) const { return Acad::eOk; } // 从DWG读入数据: Acad::ErrorStatus TDbMText::dwgInFields(AcDbDwgFiler* pFiler) { assertWriteEnabled(); Acad::ErrorStatus es = TDbText::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 TDbMText::dwgOutFields(AcDbDwgFiler* pFiler) const { assertReadEnabled(); Acad::ErrorStatus es = TDbText::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 TDbMText::dxfInFields(AcDbDxfFiler* pFiler) { assertWriteEnabled(); Acad::ErrorStatus es = TDbText::dxfInFields(pFiler); if (es != Acad::eOk) return es; if (!pFiler->atSubclassData(_T("TDbMText"))) { 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 TDbMText::dxfOutFields(AcDbDxfFiler* pFiler) const { assertReadEnabled(); Acad::ErrorStatus es = TDbText::dxfOutFields(pFiler); assert(es == Acad::eOk); es = pFiler->writeItem(AcDb::kDxfSubclass, _T("TDbMText")); 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 TDbMText::subTransformBy(const AcGeMatrix3d& xform) { assertWriteEnabled(); TDbEntity::subTransformBy(xform); ads_matrix mat; AsAdsMatrix(xform, mat); if (!g_bLayoutRotate) { double nAngWcs = AngleRangeTo2PI(m_nLayoutRotation + m_nRotation); AcGeVector3d vt(cos(nAngWcs), sin(nAngWcs), 0.0); vt.transformBy(xform); m_nRotation = Wcs2Layout(ads_angle(XPoint(), XPoint(vt[0], vt[1]))); // sg delete 101217,根据8.5需求,解决多行文字的转角在某些范围内时,move移动或copy复制文字则反向的问题 if (IsMirrorMatrix(mat)) { m_nRotation = xg_angle(m_nRotation); } } m_ptText.TransformBy(mat); return Acad::eOk; } Acad::ErrorStatus TDbMText::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); return Acad::eOk; } Acad::ErrorStatus TDbMText::subMoveGripPointsAt(const AcDbIntArray& indices, const AcGeVector3d& offset) { assertWriteEnabled(); XPoint vtOffset(offset[0], offset[1]); XPoint 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 TDbMText::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 TDbMText::GetTips(DList &lstInfo) const { // sg modify 100322,根据8.5新需求修改,标述更准确 // lstInfo.Append(new TObjInfoUnit(_T("对象类型"), _T("文章"))); lstInfo.Append(new TObjInfoUnit(_T("对象类型"), _T("多行文字"))); // lstInfo.Append(new TObjInfoUnit(_T("文章内容"), m_sText)); lstInfo.Append(new TObjInfoUnit(_T("内容"), m_sText)); XString sTextStyle = GetSymbolName(m_idStyle); lstInfo.Append(new TObjInfoUnit(_T("文字样式"), sTextStyle)); XString sWidth; ftoa(m_nPageWidth, 1, sWidth); sWidth << _T("P"); lstInfo.Append(new TObjInfoUnit(_T("页宽"), sWidth)); XString sHeight; ftoa(m_nHeight, 1, sHeight); sHeight << _T("P"); lstInfo.Append(new TObjInfoUnit(_T("文字高度"), sHeight)); lstInfo.Append(new TObjInfoUnit(_T("旋转角度"), Angle2Str(m_nRotation * 180 / PI))); XString sLineSpace; ftoa(m_nLineSpace, 1, sLineSpace); sLineSpace << _T("P"); lstInfo.Append(new TObjInfoUnit(_T("行间距"), sLineSpace)); } // 没有考虑转角 XPoint TDbMText::GetExtents() const { DList lstLines; GetTextLines(lstLines); double nHeight = lstLines.Length()*GetHeight(FALSE) + (lstLines.Length() - 1)*GetLineSpace(FALSE); double nWidth = GetPageWidth(FALSE); return XPoint(nWidth, nHeight); } void TDbMText::GetTextLines(DList &lstLines) const { DList 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; XPoint ptTopLeft = m_ptText; int nCount = lstTextParts.Length(); TTextLine textLine; //一行 double nOffsetY = nLineHeight; for (int i = 0; i < nCount; i++) { TTextPart *pText = lstTextParts[i]; BOOL bExportLine = FALSE; if (pText->IsParagraph()) { bExportLine = 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); if (i < nCount - 1 && lstTextParts[i + 1]->IsParagraph()) // ; //下一个是硬回车, 则软硬回车同时输出 else bExportLine = TRUE; } else { textLine.Append(new TTextPart(*pText)); nWidth += pText->GetWidth(); if (i == nCount - 1) { bExportLine = TRUE; } } if (bExportLine) { if (textLine.Length()) { XPoint ptBase; ads_polar(ptTopLeft, nAngWcs - PI / 2, nOffsetY, 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); } //OutputTextLine(dc, ptBase, textLine); textLine.SetDelFlag(FALSE); TTextLine *pTextLine = new TTextLine; 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 TTextLine); } nWidth = 0.0; nOffsetY += nLineHeight + nLineSpace; } } } Acad::ErrorStatus TDbMText::ExplodeOrDraw2d(XExplodeDraw &dc) const { assertReadEnabled(); //20160919 wlw CAD2015以上平台,绘制时出现形文件未定义 AcDbObjectId idst = GetTextStyleId(_T("standard")); if (idst.isValid()) { dc.SetStyle(idst); } // sg add 120516,只要在导出T3的时候,才不分解中英文文字,其他情况一律分解 BOOL bSplitEAndC = !(dc.IsFullExplode() && dc.IsExportTch4()) || g_bDownloadT3Split; DList 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.SetStyle(m_idStyle); dc.SetRotation(nAngWcs); double nWidth = 0.0; XPoint ptTopLeft = m_ptText; int nCount = lstTextParts.Length(); TTextLine textLine; //一行 double nOffsetY = nLineHeight; int nMark = 1; for (int i = 0; i < nCount; i++) { TTextPart *pText = lstTextParts[i]; BOOL bExportLine = FALSE; if (pText->IsParagraph()) { bExportLine = TRUE; } else if (nPageWidth < _DIST_SNAP) { textLine.Append(new TTextPart(*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 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 (i < nCount - 1 && lstTextParts[i + 1]->IsParagraph()) // ; //下一个是硬回车, 则软硬回车同时输出 else bExportLine = TRUE; } else { textLine.Append(new TTextPart(*pText)); nWidth += pText->GetWidth(); if (i == nCount - 1) { bExportLine = TRUE; } } if (bExportLine) { if (textLine.Length()) { XPoint ptBase; ads_polar(ptTopLeft, nAngWcs - PI / 2, nOffsetY, ptBase); dc.SetSelectionMarker(nMark); 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 { OutputTextLine(dc, ptBase, textLine); } textLine.Reset(); } else { //空行 } nWidth = 0.0; nOffsetY += nLineHeight + nLineSpace; nMark++; } } return Acad::eOk; } double TDbMText::GetPageWidth(BOOL bAsPaperUnit) const { double nVal = m_nPageWidth; if (!bAsPaperUnit) nVal *= GetPScale(); return nVal; } void TDbMText::SetPageWidth(double nWidth, BOOL bAsPaperUnit) { assertWriteEnabled(); m_nPageWidth = nWidth; if (!bAsPaperUnit) m_nPageWidth /= GetPScale(); } double TDbMText::GetLineSpace(BOOL bAsPaperUnit) const { double nVal = m_nLineSpace; if (!bAsPaperUnit) nVal *= GetPScale(); return nVal; } void TDbMText::SetLineSpace(double nWidth, BOOL bAsPaperUnit) { assertWriteEnabled(); m_nLineSpace = nWidth; if (!bAsPaperUnit) m_nLineSpace /= GetPScale(); } void InitDbText(BOOL bTrue) { if (bTrue) { TDbText::rxInit(); TDbMText::rxInit(); acrxBuildClassHierarchy(); TDbText::InitMatchProtocol(TRUE); TDbMText::InitMatchProtocol(TRUE); } else { TDbText::InitMatchProtocol(FALSE); TDbMText::InitMatchProtocol(FALSE); deleteAcRxClass(TDbMText::desc()); deleteAcRxClass(TDbText::desc()); } }