#include "StdAfx.h" #include "AcDbObjectPtr.h" #include "AecDbSymbElevation.h" #include "globalFunc.h" #include "PushMemVar.h" #include "PushProperty.h" #include "AecDbText.h" #include "AecDbMText.h" #include "DimOptionData.h" const Adesk::UInt8 AecXDbSymbElevation::g_nVersion = 4; // sg modify 120608 ACRX_DXF_DEFINE_MEMBERS(AecXDbSymbElevation, AecXDbSymbWithText, AcDb::kDHL_CURRENT, AcDb::kMReleaseCurrent, 1, AEC_BIAOGAOBIAOZHU, "AEC_BIAOGAOBIAOZHU|缺乏上华解释器, 请下载上华软件|网址: www.shanghuasoft.com"); AecXDbSymbElevation::AecXDbSymbElevation() { m_nFlag = 0; m_nTextBaseLen = 15.0; m_nLeaderLen = 7.0; m_nBaseLen = 7.0; if (g_Option::instance().g_bCoordPrec2) { m_nFlag |= SEF_PREC2; } m_dText2BaseRatio = -1000; // 使用GlobalFunc::DocGetText2BaseRatio,sg add 081111 SetAtLineSide(TRUE); // sg add 090220,默认文字齐线端 SetArchElev(TRUE); // sg add 090223,默认为建筑标高 SetUpDownTextElev(TRUE); // sg add 090301,默认为上下排列 SetFloorsOnRightSide(g_DimOption::instance().g_bElevFloorsOnRight); // sg add 110125,默认多层标高符号中的楼层注释在右侧 m_nFlag3 = 0; } AecXDbSymbElevation::~AecXDbSymbElevation() { } BOOL AecXDbSymbElevation::IsValid() const { //BOOL bRet = AecXDbSymbWithText::IsValid(); //if (!bRet) // return bRet; BOOL bRet = (m_nTextBaseLen > 0.0); return bRet; } const TCHAR* AecXDbSymbElevation::GetDefaultLayer()const { extern TCHAR* LAY_ELEV_DIM; return LAY_ELEV_DIM; } //Acad::ErrorStatus //AecXDbSymbElevation::subGetClassID(CLSID* pClsid) const //{ // *pClsid = CLSID_ComSymbElev; // return Acad::eOk; //} // 提供对格式刷的支持 void AecXDbSymbElevation::CopyPropertiesFrom(AcDbEntity *pSrcEntity, unsigned gMatchFlag) { AssertWriteEnabled(); AecXDbSymbWithText::CopyPropertiesFrom(pSrcEntity, gMatchFlag); AecXDbSymbElevation *pSrc = AecXDbSymbElevation::cast(pSrcEntity); if (pSrc != NULL) { m_nFlag = pSrc->m_nFlag; // 控制标记 m_dText2BaseRatio = pSrc->m_dText2BaseRatio; // 文字距基线系数,sg add 081111 m_nFlag2 = pSrc->m_nFlag2; // 控制标记2,sg add 090204 m_nTextBaseLen = pSrc->m_nTextBaseLen; // sg add 090205,解决需求平台问题215 m_nLeaderLen = pSrc->m_nLeaderLen; m_nBaseLen = pSrc->m_nBaseLen; m_nFlag3 = pSrc->m_nFlag3; // sg add 090728 CString csSrcLow = pSrc->GetLowText(), csThisLow = GetLowText(), csThisText = GetText(); BOOL bSrc = csSrcLow.IsEmpty(), bThis = csThisLow.IsEmpty(); if (!IsArchElev()) // 总图标高 { if (bSrc && !bThis) // 由上下排列变为左右排列文字 { csThisText = csThisText + _T("&") + csThisLow; // 原线上文字一定只有一行,合并上下线文字 csThisLow = _T(""); SetText(csThisText); SetLowText(csThisLow); } else if (!bSrc && bThis) // 上下排列文字 { // sg modify 120608,9.0起修改区分多层标高的分隔符号,由“/”变成“$” // int nRet = csThisText.Find(_T('/'), 0); int nRet = csThisText.Find(_T('$'), 0); if (nRet < 0) // 不支持将多行文字转化为线下文字 { nRet = csThisText.Find(_T('&'), 0); if (nRet > -1) // 存在相对标高或说明文字 { // 将&后的文字转化为线下文字 csThisLow = csThisText.Right(csThisText.GetLength() - nRet - 1); csThisText = csThisText.Left(nRet); SetText(csThisText); SetLowText(csThisLow); } } } } else // 建筑标高 { if (!bThis) // 建筑标高不支持线下文字 { csThisText = csThisText + _T("&") + csThisLow; // 原线上文字一定只有一行,合并上下线文字 csThisLow = _T(""); SetLowText(csThisLow); SetText(csThisText); } } } } Adesk::Boolean AecXDbSymbElevation::subCloneMeForDragging() { return AecXDbSymbWithText::subCloneMeForDragging(); } // sg add 091116,打开T7对象后,对标注内容进行检查,如果是类似"9(%%P0.00)",则将文字拆分成两部分 void AecXDbSymbElevation::CheckAndModifyT7String() { // 获取标注内容 CString csText = GetText(); // 检查是否有括号 int nRet1 = csText.Find(_T("("), 0); if (nRet1 < 0) return; int nRet2 = csText.Find(_T(")"), nRet1); if (nRet2 < nRet1) return; CString csLeft = csText.Left(nRet1), // 9 csRight = csText.Mid(nRet1, nRet2 + 1 - nRet1); // (%%p0.00) // 通过对csRight的类型进行判断,确定是总图标高或建筑标高 int nLength = csRight.GetLength(); CString csTmp = csRight.Mid(1, nLength - 2); // %%p0.00 if (IsDigitEle(csTmp)) // 全部数字 { csText = csLeft + _T("&") + csTmp; // 9&5 SetArchElev(FALSE); // 设置为总图标高 // 如果是普通样式标高,设置为左右排列 if (!IsFilled()) { SetUpDownTextElev(FALSE); } } else { // 检查是否是正负0的情况 CString csFormat1 = IsPrec2() ? _T("%%P0.00") : _T("%%P0.000"), csFormat2 = IsPrec2() ? _T("%%p0.00") : _T("%%p0.000"); if (csTmp == csFormat1 || csTmp == csFormat2) { csText = csLeft + _T("&0"); // 9&0 SetArchElev(FALSE); // 设置为总图标高 // 如果是普通样式标高,设置为左右排列 if (!IsFilled()) { SetUpDownTextElev(FALSE); } } else { csText = csLeft + _T("&") + csRight; // 含文字的情况 } } // 重新设置标注内容 SetText(csText); } // 从DWG读入数据: Acad::ErrorStatus AecXDbSymbElevation::dwgInFields(AcDbDwgFiler* pFiler) { AssertWriteEnabled(); Acad::ErrorStatus es = AecXDbSymbWithText::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_nFlag); pFiler->readItem((AcGePoint2d *)&m_ptLocation); GlobalFunc::ReadString(pFiler, m_sText); pFiler->readItem(&m_nTextBaseLen); if (m_nFlag & SEF_BASELINE) pFiler->readItem(&m_nBaseLen); if (m_nFlag & SEF_LEADER) pFiler->readItem(&m_nLeaderLen); if (nVer > 1) // sg add 081111,sg modify 090318,8.0版本为2 { pFiler->readItem(&m_dText2BaseRatio); pFiler->readItem(&m_nFlag2); ADSGePoint3d ptText, ptLowText; pFiler->readItem((AcGePoint2d *)&ptText); pFiler->readItem((AcGePoint2d *)&ptLowText); GlobalFunc::ReadString(pFiler, m_sLowText); if (nVer == 2) // 8.0的BETA1版本号为2 { SetTextPoint(ptText); // 转化为ECS SetLowTextPt(ptLowText); m_nLayoutRotation = m_nLayoutRotation + m_nTextRotation; // 全部转化为布局转角 m_nTextRotation = 0; } else // 8.0的BETA2版本号为3 { m_ptText = ptText; m_ptLowText = ptLowText; } } else { m_dText2BaseRatio = -1000; // 随TDbConfig SetStandard(TRUE); // 规范样式 SetAtLineSide(TRUE); // sg add 090220,文字齐线端 SetArchElev(!IsFilled()); // sg add 090223,建筑标高 SetUpDownTextElev(TRUE); // sg add 090301,上下排列 SetTextPoint(GetDefaultTextLocation()); SetLowTextPt(GetDefaultTextLocation2()); m_nLayoutRotation = m_nLayoutRotation + m_nTextRotation; // 全部转化为布局转角 m_nTextRotation = 0; // sg add 091116,对标注内容进行检查,如果是类似"9(%%P0.00)",则将文字拆分成两部分 CheckAndModifyT7String(); } if (nVer < 4) // sg add 120608,如果是9.0以前版本,打开以后,需要将对象内的“/”符号转化为“$” { Change2T9ElevText(); m_nFlag3 = 0; } else // 9.0 { pFiler->readItem(&m_nFlag3); } return pFiler->filerStatus(); } Acad::ErrorStatus AecXDbSymbElevation::dwgOutFields(AcDbDwgFiler* pFiler) const { assertReadEnabled(); Acad::ErrorStatus es = AecXDbSymbWithText::dwgOutFields(pFiler); if (es != Acad::eOk) return es; pFiler->writeItem(g_nVersion); // sg add 120608,如果是9.0以前版本,保存的时候,再转化为原来的“/”符号 // modify by gjm 解决多层标高层数太多崩溃问题 2013/08/16 CString szText(m_sText); //if (g_nSaveTArchVer < 9) //{ // szText = Change2OldElevText(); //} pFiler->writeItem(m_nFlag); pFiler->writeItem((const AcGePoint2d &)m_ptLocation); // pFiler->writeString(m_sText); pFiler->writeString((LPCTSTR)szText); pFiler->writeItem(m_nTextBaseLen); if (m_nFlag & SEF_BASELINE) pFiler->writeItem(m_nBaseLen); if (m_nFlag & SEF_LEADER) pFiler->writeItem(m_nLeaderLen); pFiler->writeItem(m_dText2BaseRatio); pFiler->writeItem(m_nFlag2); pFiler->writeItem((const AcGePoint2d &)m_ptText); pFiler->writeItem((const AcGePoint2d &)m_ptLowText); pFiler->writeString(m_sLowText); pFiler->writeItem(m_nFlag3); return pFiler->filerStatus(); } Acad::ErrorStatus AecXDbSymbElevation::dxfInFields(AcDbDxfFiler* pFiler) { return AecXDbSymbWithText::dxfInFields(pFiler); } Acad::ErrorStatus AecXDbSymbElevation::dxfOutFields(AcDbDxfFiler* pFiler) const { return AecXDbSymbWithText::dxfOutFields(pFiler); } // ----------------------------------------------------------------------- // Active when being rotated, scaled, moved, etc. // Scale is disabled here Acad::ErrorStatus AecXDbSymbElevation::subTransformBy(const AcGeMatrix3d& xform) { AssertWriteEnabled(); ADSGePoint3d ptVerts[7]; GetVertexes(ptVerts); // sg delete 090317,非镜像时,也不应该修改文字转角,如:CAD旋转命令 // if (!GlobalFunc::IsMirrorMatrix(xform)) // 镜像时不改变文字转角 // AecXDbSymbWithText::transformBy(xform); // else AecXDbSymbWithText::subTransformBy(xform); // sg delete 100322,根据林工反馈,建筑专业,也支持旋转 // sg add 090605,根据sr提出的特殊需求,如果是水、电、暖专业,标高对象旋转时,修改布局转角 // if (g_nProductId==8 || g_nProductId==3 || g_nProductId==6) // { if (!GlobalFunc::IsMirrorMatrix(xform)) { if (!g_Option::instance().g_bLayoutRotate) { double dAngle(0.0); AcGeVector3d vt(cos(dAngle), sin(dAngle), 0.0); vt.transformBy(xform); dAngle = ads_angle(ADSGePoint3d(), ADSGePoint3d(vt[0], vt[1])); dAngle = Layout2Wcs(dAngle); m_nLayoutRotation = dAngle; } } // } // sg modify 120609,解决在UCS下,动态标注错误的问题 ADSGePoint3d ptUCSOld = m_ptLocation; GlobalFunc::WCS2UCS(ptUCSOld); double elev, // elev0 = m_ptLocation.y; elev0 = ptUCSOld.y; // sg modify 120608,9.0起修改区分多层标高的分隔符号,由“/”变成“$” // BOOL bStdElev = (_tcschr(m_sText, _T('/'))==NULL && g_Option::instance().g_bDynamicCoord && GetElev1(elev)); BOOL bStdElev = (_tcschr(m_sText, _T('$')) == NULL && g_Option::instance().g_bDynamicCoord && GetElev1(elev)); ads_matrix mat; GlobalFunc::AsAdsMatrix(xform, mat); m_ptLocation.TransformBy(mat); m_ptLocation.z = 0; for (int i = 0; i < 7; i++) ptVerts[i].TransformBy(mat); // ADSGePoint3d ptTemp; // sg delete 090317,本函数中,未使用 // Midpoint(ptVerts[1], ptVerts[2], ptTemp); ADSGePoint3d ptLoc = m_ptLocation; // ads_matrix matRot, matRot1; ads_matrix matRot; ptLoc.GetRotationMatrix(-m_nLayoutRotation, matRot); ADSGePoint3d ptVert1 = ptVerts[1]; ADSGePoint3d ptVert4 = ptVerts[4]; // sg add 090323 // sg delete 090318,8.0的BETA2版起,全部使用布局转角 // ptLoc.GetRotationMatrix(-m_nTextRotation, matRot1); // ptVert1.TransformBy(matRot1); ptVert1.TransformBy(matRot); ptVert4.TransformBy(matRot); // sg add 090323 if (IsCross()) // jsx add 160530 { ADSGePoint3d ptTmp = ptVert4; if (ptTmp.x > ptLoc.x) m_nFlag |= SEF_LEFT; else m_nFlag &= ~SEF_LEFT; if (ptVert1.y < ptLoc.y) m_nFlag |= SEF_DOWN; else m_nFlag &= ~SEF_DOWN; } else { ADSGePoint3d ptTmp = IsDote() ? ptVert4 : ptVert1; // if (ptVert1.x > ptLoc.x) // sg modify 090323 if (ptTmp.x > ptLoc.x) m_nFlag |= SEF_LEFT; else m_nFlag &= ~SEF_LEFT; if (ptVert1.y < ptLoc.y) m_nFlag |= SEF_DOWN; else m_nFlag &= ~SEF_DOWN; } // double nStdSize = 3.0; // sg delete 090212,本函数中,未使用 // double nPScale = GetPScale(); if (bStdElev) { // sg modify 120609,解决在UCS下,动态标注错误的问题 ADSGePoint3d ptUCS = m_ptLocation; GlobalFunc::WCS2UCS(ptUCS); //AddElev(m_ptLocation.y - elev0); // 动态标注 AddElev(ptUCS.y - elev0); // 动态标注 } return Acad::eOk; } // Overriden functions for edit // to do: // 允许通过夹点改变边界 Acad::ErrorStatus AecXDbSymbElevation::subGetGripPoints(AcGePoint3dArray& gripPoints, AcDbIntArray& osnapModes, AcDbIntArray& geomIds) const { assertReadEnabled(); return subGetStretchPoints(gripPoints); } Acad::ErrorStatus AecXDbSymbElevation::subGetGripPoints(AcDbGripDataPtrArray & grips, const double curViewUnitSize, const int gripSize, const AcGeVector3d & curViewDir, const int bitflags) const { return Acad::eNotImplementedYet; } // stretch points is diffrent from grep points, with no midpoint included Acad::ErrorStatus AecXDbSymbElevation::subGetStretchPoints(AcGePoint3dArray &stretchPoints) const { assertReadEnabled(); ADSGePoint3d ptVerts[7]; GetVertexes(ptVerts); stretchPoints.append(ptVerts[0]);//标高位置 // sg add 090319,圆点,左右排列,ptTmp改变方向;其他情况,2改变方向 if (IsDote() && !IsUpDownTextElev()) { ADSGePoint3d ptTmp = ptVerts[0]; double dSize = GlobalFunc::DocGetEleDoteSize() * GetPScale(), // 圆点大小 dAngle = ads_angle(ptVerts[4], ptVerts[5]); ads_polar(ptVerts[0], dAngle, dSize, ptTmp); stretchPoints.append(ptTmp); } else if (IsCross()) { if (!IsUpDownTextElev()) stretchPoints.append(ptVerts[5]);//左右改变方向 else stretchPoints.append(ptVerts[1]);//上下改变方向 } else stretchPoints.append(ptVerts[2]);//改变方向 //新添加的标高样式,没有文字基线 if (!IsCross() && !IsDote() && !IsFilled() && !IsHollowTriangle()) stretchPoints.append(ptVerts[3]);//改变文字基线 if (m_nFlag & SEF_BASELINE) stretchPoints.append(ptVerts[4]); // 3 or NULL if (m_nFlag & SEF_LEADER) stretchPoints.append(ptVerts[6]); // 3 or 4 or NULL ADSGePoint3d ptText = GetTextPoint(FALSE); stretchPoints.append(ptText); // sg add 090210,基线上方文字位置点,WCS if (!!m_sLowText) { ptText = GetLowTextPt(FALSE); stretchPoints.append(ptText); // sg add 090223,基线下方文字位置点,WCS } return Acad::eOk; } // 功能: 夹点操作 Acad::ErrorStatus AecXDbSymbElevation::subMoveGripPointsAt(const AcDbIntArray& indices, const AcGeVector3d& offset) { AssertWriteEnabled(); ADSGePoint3d ptVerts[7]; GetVertexes(ptVerts); // WCS // sg modify 120609,解决UCS下,动态标注错误的问题 ADSGePoint3d ptUcsOld = m_ptLocation; GlobalFunc::WCS2UCS(ptUcsOld); // sg modify 090318,8.0BETA2起,全部使用布局转角 // ads_matrix mat, mat1; // m_ptLocation.GetRotationMatrix(Layout2Wcs(m_nTextRotation), mat); ads_matrix mat; m_ptLocation.GetRotationMatrix(m_nLayoutRotation, mat); AcGeMatrix3d mat3d = GlobalFunc::AsAcGeMatrix3d(mat); mat3d.invert(); // sg delete 090318,8.0BETA2起,全部使用布局转角 // m_ptLocation.GetRotationMatrix(m_nLayoutRotation, mat1); // 处理“动态标注”使用 // AcGeMatrix3d matLayout = GlobalFunc::AsAcGeMatrix3d(mat1); // matLayout.invert(); ADSGePoint3d vtOffset(offset[0], offset[1]); // ADSGePoint3d vtOffset1 = vtOffset; ((AcGeVector3d &)vtOffset).transformBy(mat3d); ADSGePoint3d ptLoc = AcGePoint3d(m_ptLocation).transformBy(mat3d); // ADSGePoint3d ptLoc1 = AcGePoint3d(m_ptLocation).transformBy(matLayout); // 处理“动态标注”使用 // ((AcGeVector3d &)vtOffset1).transformBy(matLayout); for (int n = 0; n < 7; n++) ptVerts[n].TransformBy(mat3d); BOOL bLocChange = FALSE; // add by xly on 101228 判断文字基线的夹点是否被拉伸 bool bIsHasTextBasePt = false, bIsHasText2BasePt = false; for (int i = 0; i < indices.length(); i++) { int idx = indices[i]; if (idx == 0) // 整体移动 { double elev, dElev0 = ptUcsOld.y; // sg modify 120608,9.0起修改区分多层标高的分隔符号,由“/”变成“$” // BOOL bStdElev = (_tcschr(m_sText, _T('/'))==NULL && g_Option::instance().g_bDynamicCoord && GetElev1(elev)); BOOL bStdElev = (_tcschr(m_sText, _T('$')) == NULL && g_Option::instance().g_bDynamicCoord && GetElev1(elev)); // ptLoc1 += vtOffset1; ptLoc += vtOffset; ptVerts[0] += vtOffset; if (bStdElev) { // sg modify 120609,解决UCS下,动态标注错误的问题 // AddElev(vtOffset1.y); // AddElev(vtOffset.y); ADSGePoint3d ptUcs = ptVerts[0]; ptUcs = ptUcs.TransformAs(mat); GlobalFunc::WCS2UCS(ptUcs); AddElev(ptUcs.y - dElev0); } bLocChange = TRUE; } else if (idx == 1) // 改方向 { ptVerts[2] += vtOffset; if (ptVerts[2].x < ptLoc.x) m_nFlag |= SEF_LEFT; else m_nFlag &= ~SEF_LEFT; if (ptVerts[2].y < ptLoc.y) m_nFlag |= SEF_DOWN; else m_nFlag &= ~SEF_DOWN; } else if (idx == 2) // 拉文字基线 { //新添加的标高样式没有文字基线 if (!IsCross() && !IsDote() && !IsFilled() && !IsHollowTriangle()) { ptVerts[3] += vtOffset; if (m_nFlag & SEF_LEFT) m_nTextBaseLen = ptVerts[0].x - ptVerts[3].x; else m_nTextBaseLen = ptVerts[3].x - ptVerts[0].x; m_nTextBaseLen /= GetPScale(); // if (m_nTextBaseLen < 3.0) // sg modify 090212 // m_nTextBaseLen = 3.0; double dSize = GlobalFunc::DocGetEleTriangleSize(); if (m_nTextBaseLen < dSize - 1.0E-5) m_nTextBaseLen = dSize; // 标记文字文字基线夹点被操作 bIsHasTextBasePt = true; bIsHasText2BasePt = true; } else { int iVert = 2; if (m_nFlag & SEF_BASELINE) // 拉基线 { if (iVert == idx) { ptVerts[4] += vtOffset; if (m_nFlag & SEF_LEFT) m_nBaseLen = ptVerts[4].x - ptVerts[0].x; else m_nBaseLen = ptVerts[0].x - ptVerts[4].x; m_nBaseLen /= GetPScale(); if (m_nBaseLen < 0.0) m_nBaseLen = 0.0; } iVert++; } if (m_nFlag & SEF_LEADER) // 拉引线 { if (iVert == idx) { ptVerts[6] += vtOffset; if (m_nFlag & SEF_DOWN) m_nLeaderLen = ptVerts[0].y - ptVerts[6].y; else m_nLeaderLen = ptVerts[6].y - ptVerts[0].y; m_nLeaderLen /= GetPScale(); // if (m_nLeaderLen < 3.0) // sg modify 090212 // m_nLeaderLen = 3.0; double dSize = GlobalFunc::DocGetEleTriangleSize(); if (m_nLeaderLen < dSize) m_nLeaderLen = dSize; } iVert++; } if (iVert == idx) // sg add 090210,移动文字位置 { // modify by xly on 101228 修改如果文字基线夹点与文字位置点同时拉伸,文字位置点不正确 //ADSGePoint3d ptWcsText = GetWcsTextPt(FALSE); //ptWcsText += Vector3D(offset[0], offset[1]); // 任意位置拖动 //SetTextPoint(ptWcsText); // 内部再将其转化为ECS if (!bIsHasTextBasePt)// 文字基线没有被操作 { ADSGePoint3d ptWcsText = GetWcsTextPt(FALSE); ptWcsText += Vector3D(offset[0], offset[1]); // 任意位置拖动 SetTextPoint(ptWcsText); // 内部再将其转化为ECS } bIsHasTextBasePt = false; } else if (idx == iVert + 1) // sg add 090223,移动文字位置2 { // modify by xly on 101228 修改如果文字基线夹点与文字位置点同时拉伸,文字位置点不正确 //ADSGePoint3d ptWcsText = GetWcsTextPt(TRUE); //ptWcsText += Vector3D(offset[0], offset[1]); // 任意位置拖动 //SetLowTextPt(ptWcsText); // 内部转化为ECS if (!bIsHasText2BasePt)// 文字基线没有被操作 { ADSGePoint3d ptWcsText = GetWcsTextPt(TRUE); ptWcsText += Vector3D(offset[0], offset[1]); // 任意位置拖动 SetLowTextPt(ptWcsText); // 内部转化为ECS } bIsHasText2BasePt = false; } } } else { int iVert = 3; if (m_nFlag & SEF_BASELINE) // 拉基线 { if (iVert == idx) { ptVerts[4] += vtOffset; if (m_nFlag & SEF_LEFT) m_nBaseLen = ptVerts[4].x - ptVerts[0].x; else m_nBaseLen = ptVerts[0].x - ptVerts[4].x; m_nBaseLen /= GetPScale(); if (m_nBaseLen < 0.0) m_nBaseLen = 0.0; } iVert++; } if (m_nFlag & SEF_LEADER) // 拉引线 { if (iVert == idx) { ptVerts[6] += vtOffset; if (m_nFlag & SEF_DOWN) m_nLeaderLen = ptVerts[0].y - ptVerts[6].y; else m_nLeaderLen = ptVerts[6].y - ptVerts[0].y; m_nLeaderLen /= GetPScale(); // if (m_nLeaderLen < 3.0) // sg modify 090212 // m_nLeaderLen = 3.0; double dSize = GlobalFunc::DocGetEleTriangleSize(); if (m_nLeaderLen < dSize) m_nLeaderLen = dSize; } iVert++; } if (iVert == idx) // sg add 090210,移动文字位置 { // modify by xly on 101228 修改如果文字基线夹点与文字位置点同时拉伸,文字位置点不正确 //ADSGePoint3d ptWcsText = GetWcsTextPt(FALSE); //ptWcsText += Vector3D(offset[0], offset[1]); // 任意位置拖动 //SetTextPoint(ptWcsText); // 内部再将其转化为ECS if (!bIsHasTextBasePt)// 文字基线没有被操作 { ADSGePoint3d ptWcsText = GetWcsTextPt(FALSE); ptWcsText += Vector3D(offset[0], offset[1]); // 任意位置拖动 SetTextPoint(ptWcsText); // 内部再将其转化为ECS } bIsHasTextBasePt = false; } else if (idx == iVert + 1) // sg add 090223,移动文字位置2 { // modify by xly on 101228 修改如果文字基线夹点与文字位置点同时拉伸,文字位置点不正确 //ADSGePoint3d ptWcsText = GetWcsTextPt(TRUE); //ptWcsText += Vector3D(offset[0], offset[1]); // 任意位置拖动 //SetLowTextPt(ptWcsText); // 内部转化为ECS if (!bIsHasText2BasePt)// 文字基线没有被操作 { ADSGePoint3d ptWcsText = GetWcsTextPt(TRUE); ptWcsText += Vector3D(offset[0], offset[1]); // 任意位置拖动 SetLowTextPt(ptWcsText); // 内部转化为ECS } bIsHasText2BasePt = false; } } } if (bLocChange) m_ptLocation = ptVerts[0].TransformAs(mat); return Acad::eOk; } // 功能: 夹点操作 Acad::ErrorStatus AecXDbSymbElevation::subMoveStretchPointsAt( const AcDbIntArray& indices, const AcGeVector3d& offset) { AssertWriteEnabled(); // modified by whl on 060109,解决整体拉抻时基线等消失问题 DualPtrList indices1; for (long i = 0; i < indices.length(); i++) indices1[i] = indices[i]; indices1.Arrange(); AcDbIntArray indices2; if (!indices1.IsEmpty() && indices1[0] == 0) indices2.append(0); // 整体拉伸时忽略所有其它 else for (i = 0; i < indices1.GetLength(); i++) indices2.append(indices1[i]); return subMoveGripPointsAt(indices2, offset); // modified by whl on 040907,解决运行stretch命令时引伸线消失的问题 // return AecXDbSymbWithText::moveStretchPointsAt(indices, offset); // return moveGripPointsAt(indices, offset); } // 取得夹点说明 Acad::ErrorStatus AecXDbSymbElevation::GetGripText(int idx, CString &cs) const { //判断当前是否有文字基线,如果有则进行添加 if (!IsCross() && !IsDote() && !IsFilled() && !IsHollowTriangle()) { Acad::ErrorStatus es = Acad::eOk; if (idx == 0) cs = _T("移动标高"); else if (idx == 1) cs = _T("改变方向"); else if (idx == 2) cs = _T("移动文字基线"); else { int iVert = 3; if (m_nFlag & SEF_BASELINE) { if (iVert == idx) cs = _T("移动基线"); iVert++; } if (m_nFlag & SEF_LEADER) { if (iVert == idx) cs = _T("移动引线"); iVert++; } if (iVert == idx) // sg add 090210 cs = _T("移动文字位置"); else if (idx == iVert + 1) // sg add 090223 cs = _T("移动文字2位置"); } return es; } else { Acad::ErrorStatus es = Acad::eOk; if (idx == 0) cs = _T("移动标高"); else if (idx == 1) cs = _T("改变方向"); else { int iVert = 2; if (m_nFlag & SEF_BASELINE) { if (iVert == idx) cs = _T("移动基线"); iVert++; } if (m_nFlag & SEF_LEADER) { if (iVert == idx) cs = _T("移动引线"); iVert++; } if (iVert == idx) // sg add 090210 cs = _T("移动文字位置"); else if (idx == iVert + 1) // sg add 090223 cs = _T("移动文字2位置"); } return es; } } // sg modify 090204,增加了圆点的样式 void AecXDbSymbElevation::GetVertexes(ADSGePoint3d pt[7]) const { for (int i = 0; i < 7; i++) pt[i] = m_ptLocation; double DwgScl = GetPScale(), nStdSize = GlobalFunc::DocGetEleTriangleSize() * DwgScl; // 三角形高度,一般为3mm double ry = (m_nFlag & SEF_LEADER) ? (m_nLeaderLen * DwgScl) : nStdSize; double dTextBaseLen = IsFilled() ? nStdSize : (m_nTextBaseLen * DwgScl); // sg add 090219 if (IsDote()) // sg add,圆点样式 { nStdSize = GlobalFunc::DocGetEleDoteSize() * DwgScl; // 如果是圆点,取内切圆 ry = nStdSize; if ((m_nFlag & SEF_LEFT) != 0) // 左 { pt[4].x += nStdSize * 0.5; pt[5].x -= nStdSize * 0.5; } else // 右 { pt[4].x -= nStdSize * 0.5; pt[5].x += nStdSize * 0.5; } } else if (IsCross()) // 十字样式 { nStdSize = GlobalFunc::DocGetEleCrossSize() * DwgScl; // 如果是十字 ry = nStdSize * 0.5; nStdSize = nStdSize * 0.5; if ((m_nFlag & SEF_LEFT) != 0) //左 { pt[4].x += nStdSize; pt[5].x -= nStdSize; } else // 右 { pt[4].x -= nStdSize; pt[5].x += nStdSize; } } else if (m_nFlag & SEF_LEFT) // 左 { pt[1].x += nStdSize; pt[2].x -= nStdSize; // pt[3].x -= m_nTextBaseLen*DwgScl; // sg modify 090219 pt[3].x -= dTextBaseLen; pt[4].x += m_nBaseLen * DwgScl; pt[5].x -= nStdSize; } else // 右 { pt[1].x -= nStdSize; pt[2].x += nStdSize; // pt[3].x += m_nTextBaseLen*DwgScl; // sg modify 090219 pt[3].x += dTextBaseLen; pt[4].x -= m_nBaseLen * DwgScl; pt[5].x += nStdSize; } if (IsCross()) { if ((m_nFlag & SEF_DOWN)) // 下 { pt[1].y -= nStdSize; pt[2].y += nStdSize; pt[3].y -= ry; pt[6].y -= ry; } else // 上 { pt[1].y += nStdSize; pt[2].y -= nStdSize; pt[3].y += ry; pt[6].y += ry; } } else { if ((m_nFlag & SEF_DOWN)) // 下 { pt[1].y -= nStdSize; pt[2].y -= nStdSize; pt[3].y -= ry; pt[6].y -= ry; } else // 上 { pt[1].y += nStdSize; pt[2].y += nStdSize; pt[3].y += ry; pt[6].y += ry; } } // sg modify 090318,8.0BETA2起,全部只用布局转角 // if (fabs(Layout2Wcs(m_nTextRotation))>g_Option::instance()._angSnap) if (fabs(m_nLayoutRotation) > g_DimOption::instance()._angSnap) { ads_matrix mat; // m_ptLocation.GetRotationMatrix(Layout2Wcs(m_nTextRotation), mat); m_ptLocation.GetRotationMatrix(m_nLayoutRotation, mat); for (int i = 0; i < 7; i++) pt[i].TransformBy(mat); } } void GetElevSymbolTxtBaseLen() { EntitySet ent; RBList rb(RTDXF0, _T("TCH_ELEVATION"), NULL); if (GlobalFunc::SelectEntity(_T("\n选择标高符号<退出>:"), ent, rb) != RTNORM) return; OPENOBJ_BEGIN(ent, AcDb::kForRead, AecXDbSymbElevation, pEnt) if (pEnt) acutPrintf(_T("\n%d"), pEnt->GetTextBaseLen(TRUE)); OPENOBJ_END() } void GetElevSymbolInfomation() { EntitySet ent; RBList rb(RTDXF0, _T("TCH_ELEVATION"), NULL); if (GlobalFunc::SelectEntity(_T("\n选择标高符号<退出>:"), ent, rb) != RTNORM) return; OPENOBJ_BEGIN(ent, AcDb::kForRead, AecXDbSymbElevation, pEnt) if (pEnt) { DWORD dw = pEnt->GetFlag(); DWORD dw2 = pEnt->GetFlag2(); DWORD dw3 = pEnt->GetFlag3(); acutPrintf(_T("\nSEF_DOWN : %s"), dw & SEF_DOWN ? _T("yes") : _T("no")); acutPrintf(_T("\nSEF_LEFT : %s"), dw & SEF_LEFT ? _T("yes") : _T("no")); acutPrintf(_T("\nSEF_BASELINE : %s"), dw & SEF_BASELINE ? _T("yes") : _T("no")); acutPrintf(_T("\nSEF_LEADER : %s"), dw & SEF_LEADER ? _T("yes") : _T("no")); acutPrintf(_T("\nSEF_PREC2 : %s"), dw & SEF_PREC2 ? _T("yes") : _T("no")); acutPrintf(_T("\nSEF_FILLED : %s"), dw & SEF_FILLED ? _T("yes") : _T("no")); acutPrintf(_T("\nSEF_DOTE : %s"), dw & SEF_DOTE ? _T("yes") : _T("no")); acutPrintf(_T("\nSEF_STANDARD : %s"), dw & SEF_STANDARD ? _T("yes") : _T("no")); acutPrintf(_T("\nSEF_PARENTHESES : %s"), dw2 & SEF_PARENTHESES ? _T("yes") : _T("no")); acutPrintf(_T("\nSEF_ATSIDE : %s"), dw2 & SEF_ATSIDE ? _T("yes") : _T("no")); acutPrintf(_T("\nSEF_ARCHELEV : %s"), dw2 & SEF_ARCHELEV ? _T("yes") : _T("no")); acutPrintf(_T("\nSEF_UPDOWNTEXT : %s"), dw2 & SEF_UPDOWNTEXT ? _T("yes") : _T("no")); acutPrintf(_T("\nSEF_TRIANGLE : %s"), dw3 & SEF_TRIANGLE ? _T("yes") : _T("no")); acutPrintf(_T("\nSEF_NEWELEV : %s"), dw3 & SEF_NEWELEV ? _T("yes") : _T("no")); acutPrintf(_T("\nSEF_CROSS : %s"), dw3 & SEF_CROSS ? _T("yes") : _T("no")); } OPENOBJ_END() } // sg modify 090204,满足8.0的新需求 Acad::ErrorStatus AecXDbSymbElevation::Draw2d(AcGiDraw &dc) const { // sg add 090324,增加多行文字JIG时的预览效果 PushMemVar vTemp(g_Option::instance().g_bQuickDragMText, FALSE); // sg add 090324,增加是否是炸开状态的判断 BOOL bExplode = FALSE;// (_tcscmp(dc.Desc(), XExplodeStream::Descriptor()) == 0); GlobalFunc::_LoadConfig(); assertReadEnabled(); if (Has2DBuffer() && !dc.IsDragging()) { dc.SetColor(colorIndex()); dc.SetLayer(layerId()); BaseEx::_Draw2DBuffers(dc, true); return Acad::eOk; } if (!IsValid()) return Acad::eInvalidInput; BOOL bDynamic = FALSE; if (g_Option::instance().g_bDynamicCoord /*&& _tcscmp(dc.Desc(), XAcGiViewDraw::Descriptor()) == 0*/) { AcGiCommonDraw *pDraw = dc.GetCommonDraw(); pDraw->context()->disableFastMoveDrag(); bDynamic = TRUE; } if (bDynamic && !objectId().isValid()) dc.SetColor(1); ADSGePoint3d pt[7]; GetVertexes(pt); // 获取符号部分,各个点的位置 if (IsDote()) // 圆点样式,sg add { double dDoteRadius = GlobalFunc::DocGetEleDoteSize() * GetPScale(); AcDbPolyline pline; pline.addVertexAt(0, pt[5], 1.0); pline.addVertexAt(1, pt[4], 1.0); //if (_tcscmp(dc.Desc(), XAcGiViewDraw::Descriptor()) == 0 && !objectId()) // ; //else // pline.setConstantWidth(dDoteRadius); pline.setClosed(Adesk::kTrue); pline.setPropertiesFrom(this); //dc.Polyline(pline); DrawPline(dc, pline); } else if (IsCross()) { double dCrossLineLength = GlobalFunc::DocGetEleCrossSize() * GetPScale(); AcDbPolyline polylineHori, polyLineVeri; ADSGePoint3d ptStartHori, ptEndHori, ptStartVeri, ptEndVert; polylineHori.addVertexAt(0, pt[4]); polylineHori.addVertexAt(1, pt[5]); polyLineVeri.addVertexAt(0, pt[1]); polyLineVeri.addVertexAt(1, pt[2]); //if (_tcscmp(dc.Desc(), XAcGiViewDraw::Descriptor()) == 0 && !objectId()) // ; //else //{ // polylineHori.setConstantWidth(dCrossLineLength / 5.0); // polyLineVeri.setConstantWidth(dCrossLineLength / 5.0); //} polylineHori.setPropertiesFrom(this); polyLineVeri.setPropertiesFrom(this); //dc.Polyline(polylineHori); //dc.Polyline(polyLineVeri); DrawPline(dc, polylineHori); DrawPline(dc, polyLineVeri); } else // 非圆点样式 { PtrList lnSet; lnSet.Append(new GeLine(pt[0], pt[1])); lnSet.Append(new GeLine(pt[0], pt[2])); if (m_nFlag & SEF_BASELINE) // 基线 lnSet.Append(new GeLine(pt[4], pt[5])); if (m_nFlag & SEF_LEADER) // 引线 { lnSet.Append(new GeLine(pt[1], pt[2])); lnSet.Append(new GeLine(pt[0], pt[6])); lnSet.Append(new GeLine(pt[6], pt[3])); } else lnSet.Append(new GeLine(pt[1], pt[3])); for (int i = 0; i < lnSet.Length(); i++) { //dc << *lnSet[i]; // 绘制 DrawLine(dc, *lnSet[i]); } if (IsFilled()) // 填充 { GePoly2D polySolid(1); polySolid.AppendNode(pt[0]); polySolid.AppendNode(pt[1]); polySolid.AppendNode(pt[2]); //dc << XSolid(polySolid); AcGiFillType fillType = dc.GetFillType(); dc.SetFillType(kAcGiFillAlways); DrawPoly2D(dc, polySolid); dc.SetFillType(fillType); } } TCStringList lstElevs1, lstElevs2, lstFloors; GetTexts(lstElevs1, lstElevs2, lstFloors); BOOL bDown = (m_nFlag & SEF_DOWN) != 0; if (!bDown) // 在符号上方,颠倒文字顺序 { lstElevs1.Reverse(); lstElevs2.Reverse(); // sg add 090211 lstFloors.Reverse(); } //TCString sText1(1024); // (绝对)标高,小数点前半部分 CString sText1(_T("")); for (int i = 0; i < lstElevs1.Length(); i++) { if (i != 0) sText1 += _T("\n"); sText1 += lstElevs1[i]; // sg add 090324,当前状态是炸开,合并两段标高 if (bExplode && i < lstElevs2.Length()) sText1 += lstElevs2[i]; } //TCString sText2(1024); // (绝对)标高,小数点及后半部分,sg add 090212,单行文字无lstElev2 CString sText2(_T("")); if (!bExplode) // sg add 090324,当前状态是炸开 { for (i = 0; i < lstElevs2.Length(); i++) { if (i != 0) sText2 += _T("\n"); sText2 += lstElevs2[i]; } } //TCString szFloors(1024); // 楼层号/相对标高,sg add 090211 CString szFloors(_T("")); // 楼层号/相对标高,sg add 090211 for (i = 0; i < lstFloors.Length(); i++) { if (i != 0) szFloors += _T("\n"); szFloors += lstFloors[i]; } ADSGePoint3d ptText1 = GetElev1DrawPt(lstElevs1, lstElevs2), // 文字绘制位置点 ptFloor = GetFloorDrawPt(ptText1, lstElevs1, lstElevs2, lstFloors); // if (lstElevs1.Length() > 1) // sg delete 090309,全部改为绘制多行文字 // { AecXDbMText text; text.SetPScale(GetPScale()); text.setPropertiesFrom(this); if (bDynamic && !objectId().isValid()) text.setColorIndex(1); text.SetPScale(GetPScale()); text.SetHeight(m_nTextHeight); text.SetLineSpace(GetText2BaseRatio(TRUE, TRUE), TRUE); // 未乘比例 text.SetStyleId(m_idTextStyle); //if (dc.IsExportTch4()) // sg modify 090608 //{ // // sg add 120313,分解出来的文字的图层和颜色要随“高级选项”中的设置来处理 // // if (!!m_idTextLayer) // if (g_nSymbTextT3Layer == 1 && !!m_idTextLayer) // text.setLayer(m_idTextLayer); // 文字层 // else // text.setColorIndex(m_colorText); // 文字和标注放在同一层,文字的颜色为白色 //} //else text.setColorIndex(m_colorText); // sg add 090608,将文字和标注放在同一层,文字的颜色为白色 AcGiDraw::TextAlignment align = AcGiDraw::kLeft; if (!!sText2) align = AcGiDraw::kRight; else if ((IsFilled() || IsDote() || IsCross()) && (m_nFlag & SEF_LEFT) != 0) align = AcGiDraw::kRight; else if (IsRightText()) align = AcGiDraw::kRight; //if (IsCross()) //{ // if (!IsUpDownTextElev() && (m_nFlag&SEF_LEFT)==0)//在右侧时,文字对齐方式为左对齐 // align = AcGiDraw::kLeft; // if (IsNewSitePlanElev() && (m_nFlag&SEF_LEFT)==0 )//右上 // align = AcGiDraw::kLeft; //} text.SetAlignment(align); text.SetText(sText1); // 100 text.SetLocation(ptText1); double dWidth = GetMinTextBaseLen(lstElevs1, TRUE); if (bExplode) // sg add 090324,炸开状态下,两段标高合并 dWidth += GetMinTextBaseLen(lstElevs2, TRUE); text.SetPageWidth(dWidth, TRUE); // 未乘比例 PushProperty vProp(&text, dc); //if (dc.IsFullExplode()) // text.ExplodeOrDraw2d(dc); //else // dc.DrawEntity(text); DrawBaseEx(dc, text); if (!!sText2) // .000,sg add 090212 { text.SetText(sText2); ADSGePoint3d ptText2 = GetElev2DrawPt(ptText1, dWidth * GetPScale()); text.SetLocation(ptText2); text.SetAlignment(AcGiDraw::kLeft); text.SetPageWidth(GetMinTextBaseLen(lstElevs2, TRUE), TRUE); // 未乘比例 //if (dc.IsFullExplode()) // text.ExplodeOrDraw2d(dc); //else // dc.DrawEntity(text); DrawBaseEx(dc, text); } if (!!szFloors) // 1F,sg add 090212 { text.SetText(szFloors); text.SetLocation(ptFloor); text.SetAlignment(AcGiDraw::kLeft); text.SetPageWidth(GetMinTextBaseLen(lstFloors, TRUE), TRUE); // 未乘比例 //if (dc.IsFullExplode()) // text.ExplodeOrDraw2d(dc); //else // dc.DrawEntity(text); DrawBaseEx(dc, text); } // sg add 090223,基线下方有文字,只会出现在单行文字中,暗含上下排列 if (!!m_sLowText) { AecXDbText text2; text2.setPropertiesFrom(this); if (bDynamic && !objectId().isValid()) text2.setColorIndex(1); text2.SetPScale(GetPScale()); text2.SetHeight(m_nTextHeight); text2.SetStyleId(m_idTextStyle); //if (dc.IsExportTch4()) // sg modify 090608 //{ // // sg add 120313,分解出来的文字的图层和颜色要随“高级选项”中的设置来处理 // // if (!!m_idTextLayer) // if (g_nSymbTextT3Layer == 1 && !!m_idTextLayer) // text2.setLayer(m_idTextLayer); // 文字层 // else // text2.setColorIndex(m_colorText); // 文字和标注放在同一层,文字的颜色为白色 //} //else text2.setColorIndex(m_colorText); // sg add 090608,将文字和标注放在同一层,文字的颜色为白色 if (!IsRightText()) // 左对齐 align = bDown ? AcGiDraw::kBottomLeft : AcGiDraw::kTopLeft; else // 右对齐 align = bDown ? AcGiDraw::kBottomRight : AcGiDraw::kTopRight; text2.SetAlignment(align); // 设置对齐方式 ADSGePoint3d ptLowText = GetWcsTextPt(TRUE); text2.SetLocation(ptLowText); CString csDrawText = FormatLowText(); // 输出格式,自动加括号,控制小数位数 text2.SetText(csDrawText); //if (dc.IsFullExplode()) // text2.ExplodeOrDraw2d(dc); //else // dc.DrawEntity(text2); DrawBaseEx(dc, text2); } return Acad::eOk; } // add by whl on 040922 // void AecXDbSymbElevation::GetTexts(TCStringList &lstTexts)const // sg modify 090211,8.0修改了算法,增加了“楼号/标注说明”信息的标注 void AecXDbSymbElevation::GetTexts(TCStringList &lstElevs1, TCStringList &lstElevs2, TCStringList &lstFloors)const { // 数字输出格式设置 const TCHAR *szFormat01 = IsPrec2() ? _T("(%%P0.00)") : _T("(%%P0.000)"); // 规范样式 const TCHAR *szFormat02 = IsPrec2() ? _T("(%.2f)") : _T("(%.3f)"); const TCHAR *szFormat03 = IsPrec2() ? _T("%%P0.00") : _T("%%P0.000"); // 传统样式 const TCHAR *szFormat04 = IsPrec2() ? _T("%.2f") : _T("%.3f"); // sg add 090211,楼层部分输出格式 const TCHAR *szFormat05 = _T("%s"); const TCHAR *szFormat06 = _T("(%s)"); BOOL bFlag(TRUE), // 是否全是数字 bHasFloor(FALSE); // 是否含有楼层号/相对标高,sg add 090224 CString csTexts = (LPCTSTR)m_sText; while (!csTexts.IsEmpty()) { // sg modify 120608,9.0起修改区分多层标高的分隔符号,由“/”变成“$” // int nResult = csTexts.Find(_T('/')), int nResult = csTexts.Find(_T('$')), nLength = csTexts.GetLength(); nResult = (nResult < 0) ? nLength : nResult; CString csRow = csTexts.Left(nResult); // (绝对)标高 int nRight = nLength - nResult - 1; if (nRight > 0) csTexts = csTexts.Right(nRight); // 本行以后的文字 else csTexts = _T(""); int nRet = csRow.Find(_T('&'), 0); if (nRet > 0) // 含有楼层号/相对标高,解析后存入lstFloors { if (!bHasFloor) // 首次含有楼号信息 { bHasFloor = TRUE; lstElevs1.Reset(); lstElevs2.Reset(); lstFloors.Reset(); csTexts = m_sText; continue; // 重新循环,防止只有部分含有楼层号/相对标高 } bHasFloor = TRUE; CString csFloor = csRow.Right(csRow.GetLength() - nRet - 1); // 楼层号/相对标高 csRow = csRow.Left(nRet); // (绝对)标高 CString csWriteFloor; if (!IsArchElev()) // 总图,左右排列,不分楼层,一律加括号 { if (IsDigitEle(csFloor)) // 相对标高 { double dElev = _tstof(csFloor); if (fabs(dElev) < 1.0E-3) csWriteFloor = szFormat01; // (±0.00) else csWriteFloor.Format(szFormat02, dElev); // (10.00) } else // 注释 csWriteFloor.Format(szFormat06, csFloor); // (池底) } else if (IsParentheses() && !IsStandard()) // 加括号的传统样式,(1F) csWriteFloor.Format(szFormat06, csFloor); else // 规范样式,不加括号的传统样式,1F csWriteFloor.Format(szFormat05, csFloor); lstFloors.Append(tstrnew(csWriteFloor)); } else if (bHasFloor) // sg add 090224,防止有的有,有的没有楼层号/相对标高,不对应 lstFloors.Append(tstrnew(_T(""))); if (bFlag && IsDigitEle(csRow)) // 全部是数字 { // sg add 101229,进一步判断是否全部是小数点,如:省略号 bool bAllDote(true); { int nLen = csRow.GetLength(); for (int i = 0; i < nLen; i++) { if (csRow[i] == _T('.')) // 小数点 continue; bAllDote = false; break; } } CString csWriteEle; double dElev = _tstof(csRow); if (lstElevs1.Length() > 0 && IsStandard()) // 规范样式,二层起加括号 { if (bAllDote) { csWriteEle = csRow; } else if (fabs(dElev) < 1.0E-3) csWriteEle = szFormat01; // (±0.000) else csWriteEle.Format(szFormat02, dElev); // (10.000) } else // 传统样式或第一行 { if (bAllDote) { csWriteEle = csRow; } else if (fabs(dElev) < 1.0E-3) csWriteEle = szFormat03; // ±0.000 else csWriteEle.Format(szFormat04, dElev); // 10.000 } BOOL bTmp = csTexts.IsEmpty() && lstElevs1.Length() == 0; // 单行文字,不需要小数点对齐 int nRowLen = csWriteEle.GetLength(), // 以小数点为分界限,处理对齐问题 nDoteRet = bTmp ? nRowLen : csWriteEle.Find(_T('.')); nDoteRet = bAllDote ? 0 : nDoteRet; nDoteRet = (nDoteRet < 0) ? nRowLen : nDoteRet; CString csLeft = csWriteEle.Left(nDoteRet), // 小数点之前部分 csRight = csWriteEle.Right(nRowLen - nDoteRet); // 小数点及之后部分 lstElevs1.Append(tstrnew(csLeft)); if (!csRight.IsEmpty()) lstElevs2.Append(tstrnew(csRight)); } else if (bFlag) // 首次出现含有字符串的行 { // sg add 101229,进一步判断是否是中文省略号,只识别中文3个点或6个点的省略号 if (csRow == _T("…") || csRow == _T("……")) { CString csTmpString = _T(""); lstElevs1.Append(tstrnew(csTmpString)); lstElevs2.Append(tstrnew(csRow)); continue; } bFlag = FALSE; lstElevs1.Reset(); lstElevs2.Reset(); lstFloors.Reset(); csTexts = m_sText; // 重新循环,防止有的是全数字,有的带字符 } else // bFlag = FALSE lstElevs1.Append(tstrnew(csRow)); } } /* * * * * * * * * * 取 动 态 属 性 显 示 数 据 的 函 数 * * * * * * * * * */ void AecXDbSymbElevation::GetTips(PtrList &lstInfo) const { lstInfo.Append(new ObjInfoUnit(_T("对象类型"), _T("标高标注"))); lstInfo.Append(new ObjInfoUnit(_T("文字内容"), m_sText)); TCString sTextStyle = GlobalFunc::GetSymbolName(m_idTextStyle); lstInfo.Append(new ObjInfoUnit(_T("文字样式"), sTextStyle)); TCString sHeight; GlobalFunc::ftoa(m_nTextHeight, 1, sHeight); sHeight << _T("P"); lstInfo.Append(new ObjInfoUnit(_T("文字高度"), sHeight)); lstInfo.Append(new ObjInfoUnit(_T("引线"), HasLeader() ? _T("有") : _T("无"))); lstInfo.Append(new ObjInfoUnit(_T("基线"), HasBaseLine() ? _T("有") : _T("无"))); } // sg add 090326,处理右键在位编辑错误 SubText* AecXDbSymbElevation::GetSubText(long iText) const { TCStringList lstElevs1, lstElevs2, lstFloors; GetTexts(lstElevs1, lstElevs2, lstFloors); // 除单行文字外,都不支持在位编辑 if (!m_sText || lstElevs1.Length() > 1 || lstFloors.Length() != 0 || !!m_sLowText) return NULL; SubText *pSubText = AecXDbSymbWithText::GetSubText(iText); if (pSubText != NULL) pSubText->SetMultiLine(false); // 不支持回车操作,固定为单行文字 return pSubText; } SubText* AecXDbSymbElevation::HitTestText(ADSGePoint3d pt) const { TCStringList lstElevs1, lstElevs2, lstFloors; GetTexts(lstElevs1, lstElevs2, lstFloors); // 除单行文字外,都不支持在位编辑 if (!m_sText || lstElevs1.Length() > 1 || lstFloors.Length() != 0 || !!m_sLowText) return NULL; // sg add 090326,不支持回车操作,固定为单行文字 SubText *pSubText = AecXDbSymbWithText::HitTestText(pt); if (pSubText != NULL) pSubText->SetMultiLine(false); // return TDbEntity::HitTestText(pt); return pSubText; } int AecXDbSymbElevation::ConvertText(TConvertTextPtr ptr, void *pData) { TCString sText; int nRet = ptr(m_sText, sText, pData); if (nRet == RTNORM) { AssertWriteEnabled(); m_sText = sText; } return nRet; } // sg add 090204,支持查找替换 BOOL AecXDbSymbElevation::GetText(Adesk::UInt32 cookies, AecXDbText &text, double &dPageWidth) const { TCStringList lstElevs1, lstElevs2, lstFloors; GetTexts(lstElevs1, lstElevs2, lstFloors); // 获取标注内容 if ((m_nFlag & SEF_DOWN) == 0) // 颠倒文字顺序 { lstElevs1.Reverse(); lstElevs2.Reverse(); lstFloors.Reverse(); } int nLength1 = lstElevs1.Length(), nLength2 = lstElevs2.Length(); if (nLength2 != 0 && nLength1 != nLength2) return FALSE; TCString sElev(1024); // (绝对)标高 for (int i = 0; i < nLength1; i++) { if (i != 0) sElev << "\n"; sElev << lstElevs1[i]; if (nLength2 != 0) sElev << lstElevs2[i]; } TCString szFloors(1024); // 楼层号/相对标高 nLength1 = lstFloors.Length(); for (i = 0; i < nLength1; i++) { if (i != 0) szFloors << "\n"; szFloors << lstFloors[i]; } int nNum = (!!sElev) ? 0 : -1; nNum = (!!szFloors) ? (nNum + 1) : nNum; nNum = (!!m_sLowText) ? (nNum + 1) : nNum; if ((int)cookies > nNum) // 确保文字数量正确,最多2段文字 return FALSE; TCString szRetText; ADSGePoint3d ptText; AcGiDraw::TextAlignment align = AcGiDraw::kLeft; if (cookies == 0) // 100.000、1-05 { szRetText = sElev; ptText = GetElev1DrawPt(lstElevs1, lstElevs2); dPageWidth = GetMinTextBaseLen(lstElevs1, TRUE) + GetMinTextBaseLen(lstElevs2, TRUE); if (nLength2 != 0) align = AcGiDraw::kRight; else if ((IsFilled() || IsDote()) && (m_nFlag & SEF_LEFT) != 0) align = AcGiDraw::kRight; else if (IsRightText()) align = AcGiDraw::kRight; } else if (!!szFloors && cookies == 1) // 1F { szRetText = szFloors; ptText = GetFloorDrawPt(ADSGePoint3d(), lstElevs1, lstElevs2, lstFloors, FALSE); dPageWidth = GetMinTextBaseLen(lstFloors, TRUE); } else if (!!m_sLowText && cookies == 1) // 线下文字 { szRetText = GetLowText(); // 去掉括号 ptText = GetWcsTextPt(TRUE); dPageWidth = GetLowTextXExtents(TRUE); if (IsRightText()) { align = AcGiDraw::kRight; // sg add 090320,将原单行文字,转化为多行文字位置,尽量使红框位置正确 ads_polar(ptText, m_nLayoutRotation, -dPageWidth * GetPScale(), ptText); } // sg add 090320,将原单行文字,转化为多行文字位置,尽量使红框位置正确 if ((m_nFlag & SEF_DOWN) != 0) // 文字在符号之下 ads_polar(ptText, m_nLayoutRotation + PI / 2, m_nTextHeight * GetPScale(), ptText); } text.SetText(szRetText); text.SetAlignment(align); text.SetLocation(ptText); return TRUE; } // 返回发现的位置,同时posStart往前移动(以便继续找下一个使用) TextPosition AecXDbSymbElevation::FindSubText(const TCHAR *sSubText, TextPosition &posStart, TextRange *pRange) const { assertReadEnabled(); TextPosition pos; if (!sSubText || !sSubText[0]) return pos; TextPosition posNext = posStart; while (1) { AecXDbMText text; text.SetPScale(GetPScale()); double dPageWidth(0.0); // 页宽,未乘比例 if (!GetText(posNext.m_nCookies, text, dPageWidth)) break; text.SetStyleId(m_idTextStyle); text.SetRotation(m_nLayoutRotation); text.SetHeight(m_nTextHeight); double dLineSpace = GetText2BaseRatio(TRUE, TRUE); // 未乘比例 ((AecXDbMText &)text).SetLineSpace(dLineSpace, TRUE); ((AecXDbMText &)text).SetPageWidth(dPageWidth, TRUE); TextPosition posFind = text.FindSubText(sSubText, posNext, pRange); if (!posFind) { posNext.m_nCookies++; posNext.m_nTextPos = 0; } else { posStart = posNext; if (!posStart) { posStart.m_nCookies++; posStart.m_nTextPos = 0; } posFind.m_nCookies = posNext.m_nCookies; pos = posFind; break; } } return pos; } // 返回下一次查找的开始位置 TextPosition AecXDbSymbElevation::ReplaceSubText(const TextPosition &posRep, const TCHAR *sRepText, TextRange *pRange) { AssertWriteEnabled(); AecXDbMText text; text.SetPScale(GetPScale()); text.SetStyleId(m_idTextStyle); text.SetHeight(m_nTextHeight); text.SetRotation(m_nLayoutRotation); TextPosition posNext; double dPageWidth(0.0); // 未乘比例 if (!sRepText || !GetText(posRep.m_nCookies, text, dPageWidth)) return posNext; double dLineSpace = GetText2BaseRatio(TRUE, TRUE); // 未乘比例 ((AecXDbMText &)text).SetLineSpace(dLineSpace, TRUE); ((AecXDbMText &)text).SetPageWidth(dPageWidth, TRUE); posNext = text.ReplaceSubText(posRep, sRepText, pRange); TCStringList lstTmps; CString csGetText = text.GetText(), csTmp = csGetText; while (!csGetText.IsEmpty()) { int nResult = csGetText.Find(_T("\n")); nResult = (nResult < 0) ? csGetText.GetLength() : nResult; CString csRow = csGetText.Left(nResult); int nRight = csGetText.GetLength() - nResult - 1; if (nRight > 0) csGetText = csGetText.Right(nRight); else csGetText = _T(""); lstTmps.Append(tstrnew(csRow)); } if (lstTmps.Length() == 0) lstTmps.Append(tstrnew(_T(""))); if ((m_nFlag & SEF_DOWN) == 0) // sg add 090216,颠倒文字顺序 lstTmps.Reverse(); TCStringList lstElevs1, lstElevs2, lstFloors; GetTexts(lstElevs1, lstElevs2, lstFloors); // 处理文字 int nLen1 = lstElevs1.Length(), nLen2 = lstElevs2.Length(), nLen3 = lstFloors.Length(), nLen4 = lstTmps.Length(); if (nLen2 != 0 && nLen2 != nLen1) // 保证几个数组数量相等 return posNext; if (nLen3 != 0 && nLen3 != nLen1) return posNext; if (nLen4 != 0 && nLen4 != nLen1) return posNext; if (posRep.m_nCookies == 0) // 100.000 { TString sRes; for (int i = 0; i < nLen1; i++) { if (i != 0) // sg modify 120608,9.0起修改区分多层标高的分隔符号,由“/”变成“$” // sRes << _T("/"); sRes << _T("$"); CString csElev = lstTmps[i]; if (nLen1 > 1 && i != 0 && IsStandard()) // 多行文字,规范样式 csElev = csElev.Mid(1, csElev.GetLength() - 2); // 第二行起,去括号 CString csFormat = IsPrec2() ? _T("%%P0.00") : _T("%%P0.000"); if (csElev == csFormat) csElev = _T("0"); sRes << csElev; if (nLen3 > 0) { CString csFloor = lstFloors[i]; if (!IsStandard() && IsParentheses()) // 传统样式,加括号 csFloor = csFloor.Mid(1, csFloor.GetLength() - 2); sRes << _T("&") << csFloor; } } SetText(sRes); } else if (posRep.m_nCookies == 1 && nLen3 > 0) // 1F { TString sRes; for (int i = 0; i < nLen1; i++) { if (i != 0) // sg modify 120608,9.0起修改区分多层标高的分隔符号,由“/”变成“$” //sRes << _T("/"); sRes << _T("$"); CString csElev = lstElevs1[i]; sRes << csElev; if (nLen2 > 0) { csElev = lstElevs2[i]; sRes << csElev; } if (nLen4 > 0) { CString csFloor = lstTmps[i]; if (!IsStandard() && IsParentheses()) csFloor = csFloor.Mid(1, csFloor.GetLength() - 2); sRes << _T("&") << csFloor; } } SetText(sRes); } else if (posRep.m_nCookies == 1 && m_sLowText) // 基线下文字 SetLowText(csTmp); if (!posNext) { posNext.m_nCookies = posRep.m_nCookies + 1; posNext.m_nTextPos = 0; } return posNext; } bool AecXDbSymbElevation::GetElev1(double &res)const { // sg add 090507,如:5.000(1F)、5.000(1.000)类标高标注,要支持动态标高 CString csTexts = (LPCTSTR)m_sText; // sg modify 120608,9.0起修改区分多层标高的分隔符号,由“/”变成“$” // if (csTexts.Find(_T('/')) > -1) // 多行标高,不支持动态 if (csTexts.Find(_T('$')) > -1) // 多行标高,不支持动态 return false; int nRet = csTexts.Find(_T('&')), nLength = csTexts.GetLength(); nRet = (nRet < 0) ? nLength : nRet; // if (isdigit(m_sText[0]) || (m_sText[0]==_T('-') && isdigit(m_sText[1]))) CString csElev = csTexts.Left(nRet); // 标高 if (IsDigitEle(csElev)) // sg modify 090204,判断全部内容是否是数字,而不仅是首位 { // res = _tstof(m_sText); res = _tstof(csElev); return true; } CString csFormat = IsPrec2() ? _T("%%P0.00") : _T("%%P0.000"); // 0.000 if (csElev == csFormat) { res = 0.0; return true; } return false; } CString AecXDbSymbElevation::GetNoteString()const { CString temp(m_sText); int i = temp.Find(_T('(')); if (i < 0) return _T(""); return temp.Right(temp.GetLength() - i - 1); } bool AecXDbSymbElevation::GetElev2(double &res)const { // CString sNote = GetNoteString(); // if (sNote.GetLength() < 1) // return false; // if (isdigit(sNote[0]) || (sNote[0]==_T('-') && isdigit(sNote[1]))) // { // res = _tstof(sNote); // return true; // } // return false; // sg modify 090507,如:5.000(1.000)类标高标注,支持动态标高 TCStringList lstElev1, lstElev2, lstFloor; GetTexts(lstElev1, lstElev2, lstFloor); if (lstElev1.Length() != 1) // 多行标高,不支持动态 return false; if (lstFloor.Length() == 1) // 5.000(1.000) { TCString szFloor = lstFloor[0]; CString csTemp(szFloor); int nRet = csTemp.Find(_T('(')), nLength = csTemp.GetLength() - 2; if (nRet > -1 && nLength > nRet) csTemp = csTemp.Mid(nRet + 1, nLength - nRet); if (IsDigitEle(csTemp)) // 全数字 { res = _tstof(csTemp); return true; } CString csFormat = IsPrec2() ? _T("%%P0.00") : _T("%%P0.000"); // 0.000 if (csTemp == csFormat) { res = 0.0; return true; } return false; } return false; } // 用于动态标高 void AecXDbSymbElevation::AddElev(double elev) { // sg add 090508,总图标高、空标高符号不支持动态标高 if (!IsArchElev() || !m_sText) return; double e1, e2; if (!GetElev1(e1)) return; e1 += elev / 1000; if (GetElev2(e2)) { e2 += elev / 1000; // sg modify 090507,如:5.000(1.000)类标高标注,支持动态标高 // const TCHAR *szFormat = IsPrec2() ? _T("%.2f(%.2f)") : _T("%.3f(%.3f)"); // m_sText = TCString(szFormat, e1, e2); const TCHAR* szFormat = IsPrec2() ? _T("%.2f&%.2f") : _T("%.3f&%.3f"); m_sText = TCString(szFormat, e1, e2); return; } // CString sNote = GetNoteString(); // if (sNote.GetLength() > 0) // { // const TCHAR *szFormat = IsPrec2() ? _T("%.2f(%s") : _T("%.3f(%s"); // m_sText = TCString(szFormat, e1, sNote); // } // else // { // const TCHAR *szFormat = IsPrec2() ? _T("%.2f") : _T("%.3f"); // m_sText = TCString(szFormat, e1); // } TCStringList lstElev1, lstElev2, lstFloor; GetTexts(lstElev1, lstElev2, lstFloor); if (lstFloor.Length() == 1) // 5.000(1F) { TCString szFloor = lstFloor[0]; CString csTemp(szFloor); int nRet = csTemp.Find(_T('(')), nLength = csTemp.GetLength() - 2; if (nRet > -1 && nLength > nRet) csTemp = csTemp.Mid(nRet + 1, nLength - nRet); const TCHAR *szFormat = IsPrec2() ? _T("%.2f&%s") : _T("%.3f&%s"); m_sText = TCString(szFormat, e1, csTemp); return; } const TCHAR *szFormat = IsPrec2() ? _T("%.2f") : _T("%.3f"); // 5.000 m_sText = TCString(szFormat, e1); } BOOL AecXDbSymbElevation::HasBaseLine() const // 是否带基线 { return ((m_nFlag & SEF_BASELINE) != 0); } void AecXDbSymbElevation::SetBaseLine(BOOL bTrue) { AssertWriteEnabled(); if (bTrue) { m_nFlag |= SEF_BASELINE; if (m_nBaseLen < 1.0E-3) m_nBaseLen = 7.0; } else m_nFlag &= ~SEF_BASELINE; } BOOL AecXDbSymbElevation::HasLeader() const // 是否带引线 { return ((m_nFlag & SEF_LEADER) != 0); } void AecXDbSymbElevation::SetLeader(BOOL bTrue) { AssertWriteEnabled(); if (bTrue) { m_nFlag |= SEF_LEADER; if (m_nLeaderLen < 1.0E-3) m_nLeaderLen = 7.0; } else m_nFlag &= ~SEF_LEADER; } ADSGePoint3d AecXDbSymbElevation::GetLocation() const // 整体符号位置点 { return m_ptLocation; // WCS点 } void AecXDbSymbElevation::SetLocation(ADSGePoint3d pt) { AssertWriteEnabled(); m_ptLocation = pt; // WCS点 } const TCHAR * AecXDbSymbElevation::GetText() const // 文字内容 { return (const TCHAR *)m_sText; } void AecXDbSymbElevation::SetText(const TCHAR *pszText) { AssertWriteEnabled(); m_sText = pszText; } double AecXDbSymbElevation::GetTextBaseLen(BOOL bAsPaperUnit) const // 文字基线长 { double val = m_nTextBaseLen; if (!bAsPaperUnit) val *= GetPScale(); return val; } void AecXDbSymbElevation::SetTextBaseLen(double val, BOOL bAsPaperUnit) { AssertWriteEnabled(); m_nTextBaseLen = val; if (!bAsPaperUnit) m_nTextBaseLen /= GetPScale(); } double AecXDbSymbElevation::GetBaseLen(BOOL bAsPaperUnit) const // 基线长 { double val = m_nBaseLen; if (!bAsPaperUnit) val *= GetPScale(); return val; } void AecXDbSymbElevation::SetBaseLen(double val, BOOL bAsPaperUnit) { AssertWriteEnabled(); m_nBaseLen = val; if (!bAsPaperUnit) m_nBaseLen /= GetPScale(); } double AecXDbSymbElevation::GetLeaderLen(BOOL bAsPaperUnit) const // 引线长 { double val = m_nLeaderLen; if (!bAsPaperUnit) val *= GetPScale(); return val; } void AecXDbSymbElevation::SetLeaderLen(double val, BOOL bAsPaperUnit) { AssertWriteEnabled(); m_nLeaderLen = val; if (!bAsPaperUnit) m_nLeaderLen /= GetPScale(); } BOOL AecXDbSymbElevation::IsPrec2() const // 精确度 { return ((m_nFlag & SEF_PREC2) != 0); } void AecXDbSymbElevation::SetPrec2(BOOL bTrue) { AssertWriteEnabled(); if (bTrue) m_nFlag |= SEF_PREC2; else m_nFlag &= ~SEF_PREC2; } // sg add 081111,文字距基线距离 double AecXDbSymbElevation::GetText2BaseRatio(BOOL bAsPaperUnit, BOOL bRealDist) const { double dVal = m_dText2BaseRatio; // 系数 if (fabs(dVal + 1000) < 1.0E-5) dVal = GlobalFunc::DocGetText2BaseRatio(); // 使用全局变量GlobalFunc::DocGetText2BaseRatio的值 if (bRealDist) dVal *= m_nTextHeight; // 将“系数”转为“实际值” if (!bAsPaperUnit) // 处理出图比例 dVal *= GetPScale(); return dVal; } void AecXDbSymbElevation::SetText2BaseRatio(double dVal, BOOL bAsPaperUnit) { AssertWriteEnabled(); m_dText2BaseRatio = dVal; // 系数 if (!bAsPaperUnit) m_dText2BaseRatio /= GetPScale(); } // sg add 090204 ADSGePoint3d AecXDbSymbElevation::GetTextPoint(BOOL bEcsPoint) const // 文字位置点 { ADSGePoint3d ptResult = m_ptText; // ECS点 if (!bEcsPoint) ptResult = GetWcsTextPt(FALSE); // WCS点 return ptResult; } void AecXDbSymbElevation::SetTextPoint(ADSGePoint3d pt) // WCS点 { AssertWriteEnabled(); AcGePoint2d ptOrigin = GetEcsOriginPt(); // 获得ECS原点 AcGeVector2d xAxis, yAxis; GetEcsAxisVector(xAxis, yAxis); // 获得ECS坐标轴方向 AcGeMatrix2d mat2d; mat2d = mat2d.alignCoordSys(ptOrigin, xAxis, yAxis, AcGePoint2d(0, 0), AcGeVector2d(1, 0), AcGeVector2d(0, 1)); // 构造转化矩阵 AcGePoint2d ptResult(pt.x, pt.y); ptResult.transformBy(mat2d); // WCS2ECS m_ptText.x = ptResult.x / GetPScale(); m_ptText.y = ptResult.y / GetPScale(); // 用图纸比例保存 } BOOL AecXDbSymbElevation::IsCross() const // 十字 { return ((m_nFlag3 & SEF_CROSS) != 0); } void AecXDbSymbElevation::SetCross(BOOL bTrue) { AssertWriteEnabled(); if (bTrue) m_nFlag3 |= SEF_CROSS; else m_nFlag3 &= ~SEF_CROSS; } BOOL AecXDbSymbElevation::IsDote() const // 圆点 { return ((m_nFlag & SEF_DOTE) != 0); } void AecXDbSymbElevation::SetDote(BOOL bTrue) { AssertWriteEnabled(); if (bTrue) m_nFlag |= SEF_DOTE; else m_nFlag &= ~SEF_DOTE; } BOOL AecXDbSymbElevation::IsStandard() const // 规范样式 { return ((m_nFlag & SEF_STANDARD) != 0); } void AecXDbSymbElevation::SetStandard(BOOL bTrue) { AssertWriteEnabled(); if (bTrue) m_nFlag |= SEF_STANDARD; else m_nFlag &= ~SEF_STANDARD; } // sg add 090211,总图中,基线下文字位置 void AecXDbSymbElevation::SetLowText(const TCHAR *pszText) { AssertWriteEnabled(); m_sLowText = pszText; } const TCHAR* AecXDbSymbElevation::GetLowText() const { return m_sLowText; } void AecXDbSymbElevation::SetLowTextPt(ADSGePoint3d pt) // WCS点 { AssertWriteEnabled(); ADSGePoint3d ptDefault = GetDefaultTextLocation2(); // 基线下方文字的ECS原点 AcGePoint2d ptOrigin = ptDefault.AsAcGePoint2d(); AcGeVector2d xAxis, yAxis; GetEcsAxisVector(xAxis, yAxis); // 获得ECS坐标轴方向 AcGeMatrix2d mat2d; mat2d = mat2d.alignCoordSys(ptOrigin, xAxis, yAxis, AcGePoint2d(0, 0), AcGeVector2d(1, 0), AcGeVector2d(0, 1)); // 构造转化矩阵 AcGePoint2d ptResult(pt.x, pt.y); ptResult.transformBy(mat2d); // WCS2ECS m_ptLowText.x = ptResult.x / GetPScale(); m_ptLowText.y = ptResult.y / GetPScale(); // 用图纸比例保存 } ADSGePoint3d AecXDbSymbElevation::GetLowTextPt(BOOL bEcsPoint) const { ADSGePoint3d ptResult = m_ptLowText; // ECS点 if (!bEcsPoint) ptResult = GetWcsTextPt(TRUE); // WCS点 return ptResult; } // sg add 090212,传统样式,楼层是否增加括号 BOOL AecXDbSymbElevation::IsParentheses() const { return ((m_nFlag2 & SEF_PARENTHESES) != 0); } void AecXDbSymbElevation::SetParentheses(BOOL bTrue) { AssertWriteEnabled(); if (bTrue) m_nFlag2 |= SEF_PARENTHESES; else m_nFlag2 &= ~SEF_PARENTHESES; } BOOL AecXDbSymbElevation::IsRightText() const // 文字相对基线的位置(左、右) { BOOL bRet = IsAtLineSide(); if ((m_nFlag & SEF_LEFT) != 0) // 文字在符号左侧 bRet = !bRet; return bRet; } // sg add 090220,增加文字是否齐线端的接口 BOOL AecXDbSymbElevation::IsAtLineSide() const { return ((m_nFlag2 & SEF_ATSIDE) != 0); } void AecXDbSymbElevation::SetAtLineSide(BOOL bTrue) { AssertWriteEnabled(); if (bTrue) m_nFlag2 |= SEF_ATSIDE; else m_nFlag2 &= ~SEF_ATSIDE; } // sg add 090223,设置标高类型,普通标高、总图标高 BOOL AecXDbSymbElevation::IsArchElev() const { return ((m_nFlag2 & SEF_ARCHELEV) != 0); } void AecXDbSymbElevation::SetArchElev(BOOL bTrue) { AssertWriteEnabled(); if (bTrue) m_nFlag2 |= SEF_ARCHELEV; else m_nFlag2 &= ~SEF_ARCHELEV; } // sg add 090301,地坪标高是否上下排列 BOOL AecXDbSymbElevation::IsUpDownTextElev() const { return ((m_nFlag2 & SEF_UPDOWNTEXT) != 0); } void AecXDbSymbElevation::SetUpDownTextElev(BOOL bTrue) { AssertWriteEnabled(); if (bTrue) m_nFlag2 |= SEF_UPDOWNTEXT; else m_nFlag2 &= ~SEF_UPDOWNTEXT; } double AecXDbSymbElevation::GetDefaultTextBaseLen(BOOL bAsPaperUnit) const { // 此行以上的代码非sg删除,也无任何将返回值改为15.0的注释 // return 15.0; // sg delete 090205,解决需求平台问题1761,默认文字基线太长 // sg add 090421,解决普通样式,空标注,无文字基线的问题 if (!m_sText) return g_DimOption::instance().g_dElevTextBaseLen; TCStringList lstElevs1, lstElevs2, lstFloors; GetTexts(lstElevs1, lstElevs2, lstFloors); if ((m_nFlag & SEF_DOWN) == 0) // 颠倒文字顺序 { lstElevs1.Reverse(); lstElevs2.Reverse(); } double dRet = GetMinTextBaseLen(lstElevs1, bAsPaperUnit), // FALSE,则乘过比例 dStdSize = GlobalFunc::DocGetEleTriangleSize(); // 三角形高度 if (!bAsPaperUnit) // FALSE,则乘比例 dStdSize *= GetPScale(); if (lstElevs2.Length() > 0) dRet += GetMinTextBaseLen(lstElevs2, bAsPaperUnit); // FALSE,则乘过比例 else if (!IsArchElev() && IsUpDownTextElev() && !!m_sLowText) // 总图,普通样式,上下排列 { double dVal = GetLowTextXExtents(bAsPaperUnit) * 1.15 + dStdSize; // FALSE,则乘过比例 dRet = max(dVal, dRet); } if (dRet < dStdSize - 1.0E-5) dRet = dStdSize; return dRet; } // sg add 090204,基线上方文字默认位置点,夹点所在位置 ADSGePoint3d AecXDbSymbElevation::GetDefaultTextLocation() const { ADSGePoint3d ptText = GetEcsOriginPt(); return ptText; // WCS点 } // sg add 090216,基线下方文字默认位置点 ADSGePoint3d AecXDbSymbElevation::GetDefaultTextLocation2() const { ADSGePoint3d pt[7]; GetVertexes(pt); // 沿与“布局转角”垂直的方向,偏移“文字距基线距离” double dRotation = m_nLayoutRotation - PI / 2; if ((m_nFlag & SEF_DOWN) != 0) dRotation = m_nLayoutRotation + PI / 2; ADSGePoint3d ptText = pt[3]; double dLineSpace = GetText2BaseRatio(FALSE, TRUE); // 距基线距离,乘过比例、字高 ads_polar(ptText, dRotation, dLineSpace, ptText); return ptText; // WCS点 } // 判断sText是否是数字,允许输入小数点、负号及数字 BOOL AecXDbSymbElevation::IsDigitEle(const TCString &sText) const { BOOL bRet = TRUE; CString csText = (LPCTSTR)sText; int nLen = csText.GetLength(); for (int i = 0; i < nLen; i++) { if (_istdigit(csText[i]) || csText[i] == _T('.')) // 数字、小数点 continue; if (i == 0 && csText[i] == _T('-')) // 负号 continue; bRet = FALSE; break; } return bRet; } // sg add 090212,获取一组文字的最小页宽 double AecXDbSymbElevation::GetMinTextBaseLen(TCStringList &lstTexts, BOOL bAsPaperUnit) const { AecXDbText text; text.SetPScale(GetPScale()); text.setPropertiesFrom(this); text.SetHeight(m_nTextHeight); text.SetStyleId(m_idTextStyle); double dVal(0.0); int nLength = lstTexts.Length(); for (int i = 0; i < nLength; i++) { text.SetText(lstTexts[i]); ADSGePoint3d ptExt = text.GetExtents(); // 扩大页宽,防止一行无法完全显示,也使文字距基线右端留一定空间 double dTmp = ptExt.x * 1.15; dVal = max(dVal, dTmp); } if (bAsPaperUnit) dVal /= GetPScale(); return dVal; } // sg add 090223,sg modify 090318,获取基线下方文字,在X方向的宽度(相当于页宽) double AecXDbSymbElevation::GetLowTextXExtents(BOOL bAsPaperUnit) const { AecXDbText text; text.SetPScale(GetPScale()); text.setPropertiesFrom(this); // 布局转角已被复制 text.SetHeight(m_nTextHeight); text.SetStyleId(m_idTextStyle); AcGiDraw::TextAlignment align = AcGiDraw::kLeft; if (IsRightText()) align = AcGiDraw::kRight; text.SetAlignment(align); CString csLowText = FormatLowText(); // 获取基线下方文字内容 text.SetText(csLowText); ADSGePoint3d ptExt = text.GetExtents(); double dVal = ptExt.x; if (bAsPaperUnit) dVal /= GetPScale(); return dVal; } // sg add 090216,获取各个多行文字的绘制点 // ADSGePoint3d AecXDbSymbElevation::GetElev1DrawPt() const // 标高1绘制位置点 ADSGePoint3d AecXDbSymbElevation::GetElev1DrawPt(TCStringList &lstElevs1, TCStringList &lstElevs2) const // 标高1绘制位置点 { ADSGePoint3d pt = GetWcsTextPt(FALSE); // 文字夹点位置,WCS int nLength = lstElevs1.Length(); if (nLength < 1) // 无文字 return pt; double dPage1 = GetMinTextBaseLen(lstElevs1, FALSE), // 页宽,乘过比例 dPage2 = GetMinTextBaseLen(lstElevs2, FALSE); if ((IsFilled() || IsCross()) && IsNewSitePlanElev()) // 右上侧标注的三角形填充标高 { if ((m_nFlag & SEF_LEFT) == 0) ads_polar(pt, m_nLayoutRotation, -dPage1 - dPage2, pt); } // if (IsFilled() || IsDote()) // 地坪标高 else if (IsFilled() || IsDote() || IsHollowTriangle() || IsCross()) // 填充三角形、填充圆点、空心三角形 { if (IsUpDownTextElev()) // 上下排列 ads_polar(pt, m_nLayoutRotation, -0.5 * dPage1 - 0.5 * dPage2, pt); else if ((m_nFlag & SEF_LEFT) == 0) // 左右排列,右 ads_polar(pt, m_nLayoutRotation, -dPage1 - dPage2, pt); } else if (IsRightText()) // 右对齐 ads_polar(pt, m_nLayoutRotation, -dPage1 - dPage2, pt); // sg add 090303,防止1把小数点遮挡住 ads_polar(pt, m_nLayoutRotation, -0.3 * GetPScale(), pt); //TCString sText(1024); // 多行标高中,小数点前半部分,文字内容 CString sText(_T("")); // 多行标高中,小数点前半部分,文字内容 for (int i = 0; i < nLength; i++) { if (i != 0) sText += _T("\n"); sText += lstElevs1[i]; } AecXDbMText mText; mText.SetPScale(GetPScale()); mText.setPropertiesFrom(this); mText.SetText(sText); mText.SetHeight(m_nTextHeight); mText.SetStyleId(m_idTextStyle); double dLineSpace = GetText2BaseRatio(TRUE, TRUE); // 未乘比例 ((AecXDbMText &)mText).SetLineSpace(dLineSpace, TRUE); ((AecXDbMText &)mText).SetPageWidth(dPage1, FALSE); AcGiDraw::TextAlignment align = AcGiDraw::kLeft; if (lstElevs2.Length() != 0) align = AcGiDraw::kRight; // else if ((IsFilled() || IsDote()) && (m_nFlag&SEF_LEFT)!=0) else if ((IsFilled() || IsDote() || IsHollowTriangle() || IsCross()) && (m_nFlag & SEF_LEFT) != 0) // 填充三角形、填充圆点、空心三角形 align = AcGiDraw::kRight; else if (IsRightText()) align = AcGiDraw::kRight; mText.SetAlignment(align); ADSGePoint3d extText = mText.GetExtents(); if ((m_nFlag & SEF_DOWN) == 0) // 文字在符号上方 ads_polar(pt, m_nLayoutRotation + PI / 2, extText.y, pt); return pt; } //ADSGePoint3d AecXDbSymbElevation::GetElev2DrawPt() const // 标高2绘制位置点 ADSGePoint3d AecXDbSymbElevation::GetElev2DrawPt(const ADSGePoint3d &pt1, const double &dPage) const // 标高2绘制位置点 { ADSGePoint3d pt; ads_polar(pt1, m_nLayoutRotation, dPage + 0.3 * GetPScale(), pt); return pt; } // sg add 110125,判断是否是需要知道楼层注释在左侧或右侧的特殊标高 BOOL AecXDbSymbElevation::HasKnowFloorsLoc() const { if ((m_nFlag & SEF_LEFT) == 0 || IsDote() || IsFilled()) // 文字在三角符号右侧,或者地坪标高 { return FALSE; } CString csTexts = (LPCTSTR)m_sText; if (csTexts.Find(_T('&'), 0) < 0) { return FALSE; } return TRUE; } // ADSGePoint3d AecXDbSymbElevation::GetFloorDrawPt() const // 楼号绘制位置点 ADSGePoint3d AecXDbSymbElevation::GetFloorDrawPt(const ADSGePoint3d &pt1, TCStringList &lstElevs1, TCStringList &lstElevs2, TCStringList &lstFloors, BOOL bHasPt1) const // 楼号绘制位置点 { ADSGePoint3d pt = pt1; // 多行标高中,“小数点前半部分”的文字位置点 if (!bHasPt1) // 标记是否需要重新计算标高1的位置 { pt = GetElev1DrawPt(lstElevs1, lstElevs2); } double dSpace = GetPScale(); // 楼号、标高之间,留一段距离 if (lstFloors.Length() == 1 && !IsArchElev()) // 总图 dSpace *= 0.3; if (HasKnowFloorsLoc() && !IsFloorsOnRightSide()) // 注释在标高值左侧 { double dPage = GetMinTextBaseLen(lstFloors, FALSE); // 页宽,乘过比例 dSpace = -dPage - dSpace; } else { double dPage1 = GetMinTextBaseLen(lstElevs1, FALSE), // 页宽,乘过比例 dPage2 = GetMinTextBaseLen(lstElevs2, FALSE); dSpace += dPage1 + 0.3 * GetPScale() + dPage2; } ads_polar(pt, m_nLayoutRotation, dSpace, pt); return pt; } // sg add 090223,对基线下方文字进行格式化 CString AecXDbSymbElevation::FormatLowText() const { const TCHAR *szFormat1 = IsPrec2() ? _T("(%%P0.00)") : _T("(%%P0.000)"); const TCHAR *szFormat2 = IsPrec2() ? _T("(%.2f)") : _T("(%.3f)"); const TCHAR *szFormat3 = _T("(%s)"); CString csTemp = (LPCTSTR)m_sLowText, csResult; if (IsDigitEle(csTemp)) // 数字 { double dElev = _tstof(csTemp); if (fabs(dElev) < 1.0E-3) // ±0.00 csResult = szFormat1; else // 100.00 csResult.Format(szFormat2, dElev); } else // 文字 csResult.Format(szFormat3, csTemp); return csResult; } // sg add 090318,将8.0的BETA1中的WCS文字位置点,转化为ECS点使用 AcGePoint2d AecXDbSymbElevation::GetEcsOriginPt() const // 获取ECS原点,文字位置参考点 { ADSGePoint3d pt[7]; GetVertexes(pt); ADSGePoint3d ptOrigin = pt[6]; double dLineSpace = GetText2BaseRatio(FALSE, TRUE); // 距基线距离,乘过比例、字高 //if (IsCross()) //{ // dLineSpace = GlobalFunc::DocGetEleCrossSize() * GetPScale() * 0.6; // 乘比例 //} if ((IsFilled() || IsCross()) && IsNewSitePlanElev()) // 右上侧标注的三角形填充标高,十字标高支持右上侧标注 { TCStringList lstElevs1, lstElevs2, lstFloors; GetTexts(lstElevs1, lstElevs2, lstFloors); if ((m_nFlag & SEF_DOWN) == 0) // 颠倒文字顺序 { lstElevs1.Reverse(); lstElevs2.Reverse(); lstFloors.Reverse(); } ADSGePoint3d ptTmp = pt[6]; double dPage1 = GetMinTextBaseLen(lstElevs1, FALSE), // 页宽,乘过比例 dPage2 = GetMinTextBaseLen(lstElevs2, FALSE); double dSize = GlobalFunc::DocGetEleTriangleSize() * GetPScale(), // 乘比例 dX = dPage1 + dPage2; if (IsCross()) // 十字 { dSize = GlobalFunc::DocGetEleCrossSize() * GetPScale() * 0.5; // 乘比例 } if ((m_nFlag & SEF_LEFT) != 0) // 左 { ads_polar(ptTmp, m_nLayoutRotation, -dSize - dLineSpace - dX, ptOrigin); if (lstFloors.Length() > 0) // 有楼层号 { dPage1 = GetMinTextBaseLen(lstFloors, FALSE); // 乘过比例 dX = GetPScale() * 0.3; // 楼号、标高之间留一段距离,乘过比例 ads_polar(ptOrigin, m_nLayoutRotation, -dPage1 - dX, ptOrigin); } } else // 右 ads_polar(ptTmp, m_nLayoutRotation, dSize + dLineSpace + dX, ptOrigin); /*if (IsCross()) { dLineSpace -= m_nTextHeight*GetPScale()*0.5; }*/ } // if (IsFilled() || IsDote()) // 填充三角形、填充圆点 else if (IsFilled() || IsDote() || IsHollowTriangle() || IsCross()) // 填充三角形、填充圆点、空心三角形 { if (!IsUpDownTextElev()) // 左右排列 { TCStringList lstElevs1, lstElevs2, lstFloors; GetTexts(lstElevs1, lstElevs2, lstFloors); if ((m_nFlag & SEF_DOWN) == 0) // 颠倒文字顺序 { lstElevs1.Reverse(); lstElevs2.Reverse(); lstFloors.Reverse(); } ADSGePoint3d ptTmp = pt[0]; double dPage1 = GetMinTextBaseLen(lstElevs1, FALSE), // 页宽,乘过比例 dPage2 = GetMinTextBaseLen(lstElevs2, FALSE); double dSize = GlobalFunc::DocGetEleTriangleSize() * GetPScale(), // 乘比例 dX = dPage1 + dPage2; if (IsDote()) // 圆点 { dSize = GlobalFunc::DocGetEleDoteSize() * GetPScale(); // 乘比例 m_ptLocation.Mirror(pt[6], ptTmp); } if (IsCross()) // 十字 { dSize = GlobalFunc::DocGetEleCrossSize() * GetPScale() * 0.5; // 乘比例 m_ptLocation.Mirror(pt[6], ptTmp); } if ((m_nFlag & SEF_LEFT) != 0) // 左 { ads_polar(ptTmp, m_nLayoutRotation, -dSize - dLineSpace - dX, ptOrigin); if (lstFloors.Length() > 0) // 有楼层号 { dPage1 = GetMinTextBaseLen(lstFloors, FALSE); // 乘过比例 dX = GetPScale(); // 楼号、标高之间留一段距离,乘过比例 if (lstElevs1.Length() == 1 && !IsArchElev()) // 总图 dX *= 0.3; ads_polar(ptOrigin, m_nLayoutRotation, -dPage1 - dX, ptOrigin); } } else // 右 ads_polar(ptTmp, m_nLayoutRotation, dSize + dLineSpace + dX, ptOrigin); dLineSpace = (dSize - m_nTextHeight * GetPScale()) * 0.5; if (IsDote()) // 圆点 dLineSpace = (dSize * 2 - m_nTextHeight * GetPScale()) * 0.5; if (IsCross()) // 十字 dLineSpace = (dSize * 2 - m_nTextHeight * GetPScale()) * 0.5;//垂直方向 } } else if (IsAtLineSide()) // 齐线端 ptOrigin = pt[3]; else if (!HasLeader()) // 其他 ptOrigin = pt[1]; // 沿与“布局转角”垂直的方向,偏移“文字距基线距离” double dRotation = m_nLayoutRotation + PI / 2; if ((m_nFlag & SEF_DOWN) != 0) dRotation = m_nLayoutRotation - PI / 2; ads_polar(ptOrigin, dRotation, dLineSpace, ptOrigin); return ptOrigin.AsAcGePoint2d(); } // 获得ECS坐标轴方向 void AecXDbSymbElevation::GetEcsAxisVector(AcGeVector2d &xAxis, AcGeVector2d &yAxis) const { ADSGePoint3d pt[7]; GetVertexes(pt); yAxis = pt[6].AsAcGePoint2d() - pt[0].AsAcGePoint2d(); // 0——>6 // if (IsFilled() || IsDote()) // 填充三角形、填充圆点 if (IsFilled() || IsDote() || IsHollowTriangle() || IsCross()) // 填充三角形、填充圆点、空心三角形 xAxis = pt[5].AsAcGePoint2d() - pt[4].AsAcGePoint2d(); // 4——>5 else if (HasLeader()) // 带引线 { xAxis = pt[6].AsAcGePoint2d() - pt[3].AsAcGePoint2d(); // 3——>6 if (IsAtLineSide()) xAxis = pt[3].AsAcGePoint2d() - pt[6].AsAcGePoint2d(); // 6——>3 } else // 其他样式 { xAxis = pt[3].AsAcGePoint2d() - pt[1].AsAcGePoint2d(); // 1——>3 if (IsAtLineSide()) xAxis = pt[1].AsAcGePoint2d() - pt[3].AsAcGePoint2d(); // 3——>1 } xAxis.normalize(); yAxis.normalize(); } // 将文字位置由ECS转化为WCS,形参为TRUE,处理线下文字,否则处理线上文字 ADSGePoint3d AecXDbSymbElevation::GetWcsTextPt(BOOL bLowText) const { AcGePoint2d ptOrigin = GetEcsOriginPt(), // 获得ECS原点 ptResult(m_ptText.x * GetPScale(), m_ptText.y * GetPScale()); if (bLowText) { ptOrigin = GetDefaultTextLocation2().AsAcGePoint2d(); ptResult.x = m_ptLowText.x * GetPScale(); ptResult.y = m_ptLowText.y * GetPScale(); } AcGeVector2d xAxis, yAxis; GetEcsAxisVector(xAxis, yAxis); // 获得ECS坐标轴方向 AcGeMatrix2d mat2d; mat2d = mat2d.alignCoordSys(AcGePoint2d(0, 0), AcGeVector2d(1, 0), AcGeVector2d(0, 1), ptOrigin, xAxis, yAxis); // 构造转化矩阵 ptResult.transformBy(mat2d); // ECS2WCS return ADSGePoint3d(ptResult.x, ptResult.y); } // sg add 101116,支持统一标高 bool AecXDbSymbElevation::UnifyElevation(double dElevation) { AssertWriteEnabled(); m_ptLocation.z = dElevation; m_ptText.z = dElevation; m_ptLowText.z = dElevation; return true; } // sg add 090301,多层标高符号中的楼层是否在标高值左侧 BOOL AecXDbSymbElevation::IsFloorsOnRightSide() const { assertReadEnabled(); //BOOL bTrue = g_Option::instance().g_bElevFloorsOnRight; BOOL bTrue = TRUE; // sg modify 110301,读取8.0及以前版本的标高符号,默认注释在右侧 const EntityFields &fd = GetFields(); //fd.GFD(_T("标高注释在左侧"), bTrue); fd.GFD(_T("标高注释在右侧"), bTrue); return bTrue; } void AecXDbSymbElevation::SetFloorsOnRightSide(BOOL bTrue) { AssertWriteEnabled(); EntityFields &fd = Fields(); //fd.SFD(_T("标高注释在左侧"), bTrue); fd.SFD(_T("标高注释在右侧"), bTrue); } // sg add 120608,9.0新增加的总图右上侧标注的三角形填充标高 BOOL AecXDbSymbElevation::IsNewSitePlanElev() const { return ((m_nFlag3 & SEF_NEWELEV) != 0); } void AecXDbSymbElevation::SetNewSitePlanElev(BOOL bTrue) { AssertWriteEnabled(); if (bTrue) m_nFlag3 |= SEF_NEWELEV; else m_nFlag3 &= ~SEF_NEWELEV; } // sg add 120608,9.0新增加的空心三角形总图标高 BOOL AecXDbSymbElevation::IsHollowTriangle() const { return ((m_nFlag3 & SEF_TRIANGLE) != 0); } void AecXDbSymbElevation::SetHollowTriangle(BOOL bTrue) { AssertWriteEnabled(); if (bTrue) m_nFlag3 |= SEF_TRIANGLE; else m_nFlag3 &= ~SEF_TRIANGLE; } // sg add 120608,将T9格式标高内容与原来的标高格式内容相互转化 void AecXDbSymbElevation::Change2T9ElevText() { AssertWriteEnabled(); // 获取标注内容 CString csText = GetText(); int nRet = csText.Find(_T("/"), 0), nLength = csText.GetLength(); while (nRet >= 0) { if (nRet < nLength - 1) { CString csNext = csText.Mid(nRet + 1, 1); if (csNext == _T("F") || csNext == _T("f")) // 忽略1/F { nRet = csText.Find(_T("/"), nRet + 1); continue; } } CString csLeft = csText.Left(nRet), csRight = _T(""); if (nRet + 1 < nLength) csRight = csText.Mid(nRet + 1, nLength - nRet - 1); csText = csLeft + _T("$") + csRight; nRet = csText.Find(_T("/"), nRet); } // 重新设置标注内容 SetText(csText); } CString AecXDbSymbElevation::Change2OldElevText() const { CString csText = GetText(); csText.Replace(_T("/"), _T("/")); // 1/F转化为1/F csText.Replace(_T("$"), _T("/")); // modify by gjm 解决多层标高层数太多崩溃问题 2013/08/16 return csText; }