#include "stdafx.h" #include "AcGiUtil.h" #include "rxregsvc.h" #include "imgdef.h" // AcDbRasterImageDef and reactors, #include "imgent.h" #include "dbtext.h" #include "FindParser.h" #include "XGeLibInc.h" #define TCHXD _T("_TCH") //扩展实体数据的应用程序名称 #define TCHXD_AEC _T("AEC") //扩展实体数据的应用程序名称 int g_bTextAdjust = TRUE; extern AcDbObjectId InitWipeout(); //extern BOOL g_bLayoutRotate; extern BOOL g_bQuickDragMText; static BOOL g_bPenups=FALSE; static bool IsControlChar(TCHAR c) { return (c==_T('1') || c==_T('2') || c==_T('3') || c==_T('4') || 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; i4) 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; } BOOL TTextLine::IsEmpty() const { const TTextLine &lines=*this; BOOL bEmpty=TRUE; for(int i=0; im_nSizeX *= nFactor; pText->m_nWidthFactor *= nFactor; pText->m_ptLowLeft.x *= nFactor; } } void TTextLine::AdjustBasePoint(double x) { int nCount=Length(); for(int i=0; im_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; iGetWidth(); 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 AecDbText::g_nVersion = 2; ACRX_DXF_DEFINE_MEMBERS(AecDbText,AecEntity, AcDb::kDHL_CURRENT, AcDb::kMReleaseCurrent, 1, AEC_TEXT,"AEC_KERNAL|缺乏图形解释器, 请下载插件"); IMPLEMENT_TENTBASE(AecDbText); AecDbText::AecDbText() { m_nHeight=3.5; m_nRotation=0.0; m_nAlignment=XExplodeDraw::kLeft; m_nMaskFlag=0; } AecDbText::~AecDbText() { } Acad::ErrorStatus AecDbText::audit(AcDbAuditInfo* pAuditInfo) { //modified by aec 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; // aec add 090806,解决高版本下修复02图纸,对象丢失的问题 Acad::ErrorStatus es = Acad::eOk; es = AecEntity::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 AecDbText::IsValid() const { BOOL bRet=AecEntity::IsValid(); if(!bRet) return bRet; bRet=(!!m_sText && !!m_idStyle); return bRet; } // 提供对格式刷的支持 void AecDbText::CopyPropertiesFrom(AcDbEntity *pSrcEntity, unsigned gMatchFlag) { assertWriteEnabled(); AecEntity::CopyPropertiesFrom(pSrcEntity, gMatchFlag); AecDbText *pSrc=AecDbText::cast(pSrcEntity); if(pSrc) { m_nHeight=pSrc->m_nHeight; if(database()==NULL|| pSrcEntity->database()==NULL|| database()==pSrcEntity->database())//add by aec on 060317 { m_idStyle=pSrc->m_idStyle; //文字样式 } m_nAlignment=pSrc->m_nAlignment; m_nMaskFlag=pSrc->m_nMaskFlag; m_nRotation=pSrc->m_nRotation; } } Acad::ErrorStatus AecDbText::subGetClassID(CLSID* pClsid) const { return AcDbEntity::subGetClassID(pClsid); } Acad::ErrorStatus AecDbText::DownGradeSave(int nDrawMode, AcDbVoidPtrArray &entSet, BOOL *bErase) { Acad::ErrorStatus es=Acad::eOk; CString sText=(LPCTSTR)m_sText; if(g_nSaveTArchVer<7&&sText.Find(_T("^C"))!=-1)//7.0开始才有圆圈文字 { XExplodeStream dc(entSet); if(!OnExplodeOrDraw(dc)) return es; dc.SetPropertiesFrom(this);//add by aec on 060218 if(nDrawMode==DRAW_2D) es=ExplodeOrDraw2d(dc); else es=ExplodeOrDraw3d(dc); if(bErase) *bErase=TRUE; } else es=AecEntity::DownGradeSave(nDrawMode,entSet,bErase); return es; } // 从DWG读入数据: Acad::ErrorStatus AecDbText::dwgInFields (AcDbDwgFiler* pFiler) { assertWriteEnabled(); Acad::ErrorStatus es = AecEntity::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 AecDbText::dwgOutFields(AcDbDwgFiler* pFiler) const { assertReadEnabled(); Acad::ErrorStatus es = AecEntity::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 AecDbText::dxfInFields (AcDbDxfFiler* pFiler) { assertWriteEnabled(); Acad::ErrorStatus es = AecEntity::dxfInFields(pFiler); if(es!=Acad::eOk) return es; if (!pFiler->atSubclassData(_T("AecDbText"))) { 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=XExport::GetTextStyleId(sName, database()); } if(!id) { XString style; if(database()) { m_idStyle=database()->textstyle(); } else { xg_getvar(_T("TEXTSTYLE"), style); m_idStyle = XExport::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 AecDbText::dxfOutFields(AcDbDxfFiler* pFiler) const { assertReadEnabled(); Acad::ErrorStatus es=AecEntity::dxfOutFields(pFiler); assert(es == Acad::eOk); es = pFiler->writeItem(AcDb::kDxfSubclass,_T("AecDbText")); 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 AecDbText::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 AecDbText::subIntersectWith(const AcDbEntity* ent, AcDb::Intersect intType, AcGePoint3dArray& points, INT_PTR thisGsMarker, INT_PTR otherGsMarker) const { return Acad::eNotApplicable; } Acad::ErrorStatus AecDbText::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 AecDbText::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 AecDbText::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 AecDbText::subTransformBy(const AcGeMatrix3d& xform) { assertWriteEnabled(); AecEntity::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 AecDbText::UnionScale(double nScale) { assertWriteEnabled(); AcGeMatrix3d mat; mat.setToScaling(nScale); m_ptText.TransformBy(mat); } // 功能: 夹点操作 Acad::ErrorStatus AecDbText::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 AecDbText::subMoveStretchPointsAt( const AcDbIntArray& indices, const AcGeVector3d& offset) { return subMoveGripPointsAt(indices, offset); } // 取得夹点说明 Acad::ErrorStatus AecDbText::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 AecDbText::ConvertText(TConvertTextPtr ptr, void *pData) { XString sText; int nRet=ptr(m_sText, sText, pData); if(nRet==RTNORM) { assertWriteEnabled(); m_sText=sText; } return nRet; } Acad::ErrorStatus AecDbText::ExplodeOrDraw2d(XExplodeDraw &dc) const { //PushProperty vProp(this, dc); assertReadEnabled(); //acutPrintf(_T("\nText draw2d begin")); if (m_nMaskFlag && _tcscmp(dc.Desc(), XAcGiViewDraw::Descriptor())==0) { //acutPrintf(_T("\nText draw2d start")); 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; // aec modify 081229,屏蔽不能完全遮盖住文字 ext.x += ext.y*0.3; ext.y *= 1.3; /// double xDir = GetRotation(); double xDir = GetRotation() + m_nLayoutRotation; // aec 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 { #if ARX < 24 color.setTrueColor(); #endif 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<subEntityTraits().setFillType(nFillType); dcCommon->subEntityTraits().setTrueColor(cmColor); } } // XString sTextStyle=GetSymbolName(m_idStyle); TTextLine lstTextParts; if (!GetTextParts(lstTextParts)) 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 AecDbText::worldDraw(AcGiWorldDraw *pWd) { Adesk::Boolean bDraw=AecEntity::worldDraw(pWd); if(m_nMaskFlag) { AcGiContext* pContext=pWd->context(); if(pContext && pContext->isPlotGeneration()) { } else if(pWd->regenType()==kAcGiStandardDisplay) { bDraw=Adesk::kFalse; } } return bDraw; } void AecDbText::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(); } } AecEntity::viewportDraw(pMode); } */ void AecDbText::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; iIsSpacer()) continue; int nCtrlCode=pTextPart->GetControlCode(); if(!nCtrlCode) { switch(pTextPart->m_iType) { case 0://文字 { // mod by aec on 110826 解决水暖电发布命令时文字图层关闭不起作用的问题 // add by aec on 110406 解决打印时文字图层关闭或冻结不起作用的问题 //if (g_bPrinting) if (g_bPrinting ) { OPENOBJ_BEGIN(layerId(), AcDb::kForRead, AcDbLayerTableRecord, pLayer); if (pLayer != NULL) { if(pLayer->isOff() || pLayer->isFrozen()) { continue; } } 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 aec on 101105 解决楼梯中的文字和箭头不同层的问题 //modify by aec 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://圆字 { } break; } } else { //输出钢筋符号 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 AecDbText::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 AecDbText::GetExtents() const { XPoint ext; TTextLine lstTextParts; if(!GetTextParts(lstTextParts)) return ext; ext=lstTextParts.GetExtents(); return ext; } const TCHAR *AecDbText::GetDefaultLayer() const { return _T("0"); } AEntityBase::DrawType AecDbText::GetDrawType() const { return AEntityBase::k2DOnly; } /* * * * * * * * * * 取 动 态 属 性 显 示 数 据 的 函 数 * * * * * * * * * */ void AecDbText::GetTips(DList &lstInfo) const { lstInfo.Append(new ObjInfoUnit(_T("对象类型"), _T("文字"))); lstInfo.Append(new ObjInfoUnit(_T("文字内容"), m_sText)); XString sTextStyle=GetSymbolName(m_idStyle); lstInfo.Append(new ObjInfoUnit(_T("文字样式"), sTextStyle)); lstInfo.Append(new ObjInfoUnit(_T("对正方式"), GetAlignString(m_nAlignment))); XString sHeight; ftoa(m_nHeight, 1, sHeight); sHeight << _T("P"); lstInfo.Append(new ObjInfoUnit(_T("文字高度"), sHeight)); lstInfo.Append(new ObjInfoUnit(_T("旋转角度"), Angle2Str(m_nRotation*180/PI))); } // 下面两个变量未使用 BOOL g_bUseTextMatchRule=FALSE;//使用通配符 BOOL g_bIgnoreCaps=FALSE; //忽略大小写 XFindParser g_FindParser; // 返回发现的位置,同时posStart往前移动(以便继续找下一个使用), TextPosition AecDbText::FindSubText(const TCHAR *sSubText, TextPosition &posStart, TextRange *pRange) const { XPushMemVar bPenups(g_bPenups, TRUE); TextPosition 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; AecDbText *pClone=(AecDbText *)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; } // 返回下一次查找的开始位置 TextPosition AecDbText::ReplaceSubText(const TextPosition &posRep, const TCHAR *sRepText, TextRange *pRange) { assertWriteEnabled(); XPushMemVar bPenups(g_bPenups, TRUE); TextPosition 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; AecDbText *pClone=(AecDbText *)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 AecDbText::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 AecDbText::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 * AecDbText::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 AecDbText::InitWipeout() const { AcDbObjectId idEnt; AcRxClass* pClass = AcRxClass::cast(acrxClassDictionary->at(_T("AcDbWipeout"))); if (pClass != NULL) { BOOL bFirstNew=FALSE; 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 AecDbText::SetupImageInfo(AcDbRasterImage *pAcDbRasterImage) const { // pAcDbRasterImage->setFade(100); // double xDir = GetRotation(); // aec 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; // aec 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 BOOL g_bDClickInplaceEdit = FALSE; SubText* AecDbText::HitTestText(XPoint pt)const { return g_bDClickInplaceEdit?GetSubText(0):NULL; } BOOL AecDbText::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 aec on 040923 m_nAlignment=XExplodeDraw::kBottomLeft;//modified by aec 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 aec on 041216,属性不执行以下操作 if(pText->isKindOf(AcDbAttributeDefinition::desc())|| pText->isKindOf(AcDbAttribute::desc())) return TRUE; //保持原有尺寸,add by aec 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 aec 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 AecDbText::GetTextParts(DList &lstTextParts) const { AcGiTextStyle txtStyle; if(!m_idStyle.isValid()) return FALSE; Acad::ErrorStatus es=fromAcDbTextStyle(txtStyle, m_idStyle); // aec 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 ARX < 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; //nWidthFactorC *= 0.8;//ZWCAD 的计算有误差 if(bWinFont || !GetStyleParam2(&nHeightE, &nWidthFactorE)) { nHeightE=nHeightC; nWidthFactorE=nWidthFactorC; //nWidthFactorE *= 0.8;//ZWCAD 的计算有误差 } 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; } // Properties BOOL AecDbText::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 AecDbText::GetStyleParam2(double *nHeight, double *nWidthFactor) const { BOOL g_bTextStyleEx = TRUE; 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); // aec add 110118,放置因为文字样式不存在导致崩溃 // ASSERT(pStyle); if (pStyle == NULL) return FALSE; resbuf *pxData=pStyle->xData(TCHXD); if (pxData == NULL) pxData = pStyle->xData(_T("_TCH")); 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 AecDbText::GetLocation() const { return m_ptText; } double AecDbText::GetRotation() const { return m_nRotation; } double AecDbText::GetHeight(BOOL bAsPaperUnit) const { double nVal=m_nHeight; if(!bAsPaperUnit) nVal *= GetPScale(); return nVal; } Adesk::UInt8 AecDbText::GetMaskFlag() const { return m_nMaskFlag; } XExplodeDraw::TextAlignment AecDbText::GetAlignment() const { return m_nAlignment; } AcDbObjectId AecDbText::GetStyleId() const { return m_idStyle; } const TCHAR* AecDbText::GetText() const { return (const TCHAR*)m_sText; } void AecDbText::SetLocation(XPoint pt) { assertWriteEnabled(); m_ptText=pt; } void AecDbText::SetRotation(double nRot) { assertWriteEnabled(); m_nRotation=nRot; } void AecDbText::SetHeight(double nHeight, BOOL bAsPaperUnit) { assertWriteEnabled(); m_nHeight=nHeight; if(!bAsPaperUnit) m_nHeight /= GetPScale(); } void AecDbText::SetAlignment(XExplodeDraw::TextAlignment nAlign) { assertWriteEnabled(); m_nAlignment=nAlign; } void AecDbText::SetStyleId(AcDbObjectId id) { assertWriteEnabled(); m_idStyle=id; } void AecDbText::SetText(const TCHAR *pszText) { assertWriteEnabled(); m_sText=pszText; } void AecDbText::SetMaskFlag(Adesk::UInt8 nFlag) { assertWriteEnabled(); m_nMaskFlag=nFlag; } BOOL AecDbText::TBaseConvertFrom(const AcDbText *pText) { return ConvertFrom(pText); } AcDbEntity* AecDbText::TBaseCreateWipeOut() { return CreateWipeOut(); } const TCHAR * AecDbText::TBaseGetText() const { return (const TCHAR *)GetText(); } void AecDbText::TBaseSetText(const TCHAR *pszText) { SetText(pszText); } XPoint AecDbText::TBaseGetLocation() const { return GetLocation(); } void AecDbText::TBaseSetLocation(XPoint pt) { SetLocation(pt); } void AecDbText::TBaseSetRotation(double nRot) { SetRotation(nRot); } double AecDbText::TBaseGetRotation() const { return GetRotation(); } // aec add 101116,支持统一标高 bool AecDbText::UnifyElevation(double dElevation) { assertWriteEnabled(); m_ptText.z = dElevation; return true; } ///////////////////////////////////////////////////////////////////////// const Adesk::UInt8 AecDbMText::g_nVersion = 1; ACRX_DXF_DEFINE_MEMBERS(AecDbMText,AecDbText, AcDb::kDHL_CURRENT, AcDb::kMReleaseCurrent, 1, AEC_DBMTEXT,"AEC_KERNAL|缺乏图形解释器, 请下载插件"); IMPLEMENT_TENTBASE(AecDbMText); AecDbMText::AecDbMText() { m_nAlignment=XExplodeDraw::kTextFit; m_nPageWidth=0.0; m_nLineSpace=0.0; } AecDbMText::~AecDbMText() { } // 只支持4种对齐方式 BOOL AecDbMText::IsValid() const { BOOL bRet=AecEntity::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 AecDbMText::CopyPropertiesFrom(AcDbEntity *pSrcEntity, unsigned gMatchFlag) { assertWriteEnabled(); AecDbText::CopyPropertiesFrom(pSrcEntity, gMatchFlag); AecDbMText *pSrc=AecDbMText::cast(pSrcEntity); if(pSrc) { //m_nPageWidth; //段落宽度 m_nLineSpace=pSrc->m_nLineSpace; //行间距 } } // 返回发现的位置,同时posStart往前移动(以便继续找下一个使用), TextPosition AecDbMText::FindSubText(const TCHAR *sSubText, TextPosition &posStart, TextRange *pRange) const { TextPosition posFind=AecDbText::FindSubText(sSubText, posStart); if(!posFind || !pRange) return posFind; // 求pRange位置 AecDbMText *pClone=(AecDbMText *)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=CT_std_angle(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; } // 返回下一次查找的开始位置 TextPosition AecDbMText::ReplaceSubText(const TextPosition &posRep, const TCHAR *sRepText, TextRange *pRange) { TextPosition posNext=AecDbText::ReplaceSubText(posRep, sRepText); if(!posRep || !pRange) return posNext; // 求pRange位置 AecDbMText *pClone=(AecDbMText *)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=CT_std_angle(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 AecDbMText::subGetClassID(CLSID* pClsid) const { return AcDbEntity::subGetClassID(pClsid); } // 从DWG读入数据: Acad::ErrorStatus AecDbMText::dwgInFields (AcDbDwgFiler* pFiler) { assertWriteEnabled(); Acad::ErrorStatus es = AecDbText::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 AecDbMText::dwgOutFields(AcDbDwgFiler* pFiler) const { assertReadEnabled(); Acad::ErrorStatus es = AecDbText::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 AecDbMText::dxfInFields (AcDbDxfFiler* pFiler) { assertWriteEnabled(); Acad::ErrorStatus es = AecDbText::dxfInFields(pFiler); if(es!=Acad::eOk) return es; if (!pFiler->atSubclassData(_T("AecDbMText"))) { 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 AecDbMText::dxfOutFields(AcDbDxfFiler* pFiler) const { assertReadEnabled(); Acad::ErrorStatus es=AecDbText::dxfOutFields(pFiler); assert(es == Acad::eOk); es = pFiler->writeItem(AcDb::kDxfSubclass,_T("AecDbMText")); 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 AecDbMText::subTransformBy(const AcGeMatrix3d& xform) { assertWriteEnabled(); AecEntity::subTransformBy(xform); ads_matrix mat; AsAdsMatrix(xform, mat); if (!g_bLayoutRotate) { double nAngWcs = CT_std_angle(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]))); // aec delete 101217,根据8.5需求,解决多行文字的转角在某些范围内时,move移动或copy复制文字则反向的问题 if (IsMirrorMatrix(mat)) { m_nRotation = xg_angle(m_nRotation); } } m_ptText.TransformBy(mat); return Acad::eOk; } Acad::ErrorStatus AecDbMText::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 AecDbMText::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 &lstInfo) const { // aec modify 100322,根据8.5新需求修改,标述更准确 // lstInfo.Append(new ObjInfoUnit(_T("对象类型"), _T("文章"))); lstInfo.Append(new ObjInfoUnit(_T("对象类型"), _T("多行文字"))); // lstInfo.Append(new ObjInfoUnit(_T("文章内容"), m_sText)); lstInfo.Append(new ObjInfoUnit(_T("内容"), m_sText)); XString sTextStyle=GetSymbolName(m_idStyle); lstInfo.Append(new ObjInfoUnit(_T("文字样式"), sTextStyle)); XString sWidth; ftoa(m_nPageWidth, 1, sWidth); sWidth << _T("P"); lstInfo.Append(new ObjInfoUnit(_T("页宽"), sWidth)); XString sHeight; ftoa(m_nHeight, 1, sHeight); sHeight << _T("P"); lstInfo.Append(new ObjInfoUnit(_T("文字高度"), sHeight)); lstInfo.Append(new ObjInfoUnit(_T("旋转角度"), Angle2Str(m_nRotation*180/PI))); XString sLineSpace; ftoa(m_nLineSpace, 1, sLineSpace); sLineSpace << _T("P"); lstInfo.Append(new ObjInfoUnit(_T("行间距"), sLineSpace)); } // 没有考虑转角 XPoint AecDbMText::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 AecDbMText::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; iIsParagraph()) { 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(iIsParagraph()) // ; //下一个是硬回车, 则软硬回车同时输出 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; nAppend(textLine[n]); lstLines.Append(pTextLine); textLine.Reset(); textLine.SetDelFlag(TRUE); } else { //空行 lstLines.Append(new TTextLine); } nWidth=0.0; nOffsetY += nLineHeight + nLineSpace; } } } Acad::ErrorStatus AecDbMText::ExplodeOrDraw2d(XExplodeDraw &dc) const { assertReadEnabled(); DList lstTextParts; if(!GetTextParts(lstTextParts)) 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; iIsParagraph()) { 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) > _DIST_SNAP) //自动换行 { //判断多一词还是少一词 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(iIsParagraph()) // ; //下一个是硬回车, 则软硬回车同时输出 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 aec 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 aec 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 AecDbMText::GetPageWidth(BOOL bAsPaperUnit) const { double nVal=m_nPageWidth; if(!bAsPaperUnit) nVal *= GetPScale(); return nVal; } void AecDbMText::SetPageWidth(double nWidth, BOOL bAsPaperUnit) { assertWriteEnabled(); m_nPageWidth=nWidth; if(!bAsPaperUnit) m_nPageWidth /= GetPScale(); } double AecDbMText::GetLineSpace(BOOL bAsPaperUnit) const { double nVal=m_nLineSpace; if(!bAsPaperUnit) nVal *= GetPScale(); return nVal; } void AecDbMText::SetLineSpace(double nWidth, BOOL bAsPaperUnit) { assertWriteEnabled(); m_nLineSpace=nWidth; if(!bAsPaperUnit) m_nLineSpace /= GetPScale(); } //AecDbMTextNew--------------------------------------------------------------------- ///////////////////////////////////////////////////////////////////////// const Adesk::UInt8 AecDbMTextNew::g_nVersion = 1; ACRX_DXF_DEFINE_MEMBERS(AecDbMTextNew,AecDbText, AcDb::kDHL_CURRENT, AcDb::kMReleaseCurrent, 1, AEC_MTEXTNEW,"AEC_KERNAL|缺乏图形解释器, 请下载插件"); IMPLEMENT_TENTBASE(AecDbMTextNew); AecDbMTextNew::AecDbMTextNew() { m_nAlignment=XExplodeDraw::kTextFit; m_nPageWidth=0.0; m_nPageSpace=0.0; //-------------------------------- m_nLineSpace = 1.0;//行距系数 m_bDir = Adesk::kFalse;//排版 //-------------------------------- m_nPagHeight = 0;//行高 } AecDbMTextNew::~AecDbMTextNew() { } // 只支持4种对齐方式 BOOL AecDbMTextNew::IsValid() const { BOOL bRet=AecEntity::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 AecDbMTextNew::CopyPropertiesFrom(AcDbEntity *pSrcEntity, unsigned gMatchFlag) { assertWriteEnabled(); AecDbText::CopyPropertiesFrom(pSrcEntity, gMatchFlag); AecDbMTextNew *pSrc=AecDbMTextNew::cast(pSrcEntity); if(pSrc) { //m_nPageWidth; //段落宽度 m_nLineSpace=pSrc->m_nLineSpace; //行间距 } } // 返回发现的位置,同时posStart往前移动(以便继续找下一个使用), TextPosition AecDbMTextNew::FindSubText(const TCHAR *sSubText, TextPosition &posStart, TextRange *pRange) const { TextPosition posFind=AecDbText::FindSubText(sSubText, posStart); if(!posFind || !pRange) return posFind; // 求pRange位置 AecDbMTextNew *pClone=(AecDbMTextNew *)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=CT_std_angle(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; } // 返回下一次查找的开始位置 TextPosition AecDbMTextNew::ReplaceSubText(const TextPosition &posRep, const TCHAR *sRepText, TextRange *pRange) { TextPosition posNext=AecDbText::ReplaceSubText(posRep, sRepText); if(!posRep || !pRange) return posNext; // 求pRange位置 AecDbMTextNew *pClone=(AecDbMTextNew *)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=CT_std_angle(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 AecDbMTextNew::subGetClassID(CLSID* pClsid) const { return AcDbEntity::subGetClassID(pClsid); } static void SplitStrintToArray(LPCTSTR pszDescr,CStringArray& arInfo,TCHAR tcSpace) { if (pszDescr == NULL) return; CString sDescr = pszDescr; int nLen = sDescr.GetLength(); int i = 0; CString sText = _T(""); TCHAR tchar = _T('\0'); for(i = 0;i < nLen;i++) { tchar = sDescr.GetAt(i); if(tchar == tcSpace) { arInfo.Add(sText); sText = _T(""); } else { sText += tchar; } if(i == nLen - 1 && !sText.IsEmpty()) { arInfo.Add(sText); } } } // 从DWG读入数据: Acad::ErrorStatus AecDbMTextNew::dwgInFields (AcDbDwgFiler* pFiler) { assertWriteEnabled(); Acad::ErrorStatus es = AecDbText::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; } m_sTextBk = m_sText; //分解m_sText; CStringArray arText; SplitStrintToArray(m_sText,arText,_T('|')); CString sText,sTextAll = _T(""); for (int i= 0;i < arText.GetSize();i++) { sText = arText.GetAt(i); if (sText.Find(_T("0$")) != -1 ) { sText.TrimLeft(_T("0$")); sText.TrimRight(_T("$")); if (!sText.IsEmpty()) { sTextAll += sText; } } } m_sText = sTextAll; //-------------------------------- pFiler->readItem(&m_nPageWidth); pFiler->readItem(&m_nLineSpace); pFiler->readItem(&m_bDir); //-------------------------------- pFiler->readItem(&m_nPagHeight); pFiler->readItem(&m_nPageSpace); return pFiler->filerStatus(); } Acad::ErrorStatus AecDbMTextNew::dwgOutFields(AcDbDwgFiler* pFiler) const { assertReadEnabled(); Acad::ErrorStatus es = AecEntity::dwgOutFields(pFiler); if(es != Acad::eOk) return es; Adesk::UInt8 nVer = 2; pFiler->writeItem(nVer); pFiler->writeItem(m_idStyle); pFiler->writeString((LPCTSTR)m_sTextBk); pFiler->writeItem((const AcGePoint3d &)m_ptText); pFiler->writeItem(m_nHeight); pFiler->writeItem(m_nRotation); pFiler->writeItem((Adesk::UInt8)m_nAlignment); pFiler->writeItem(m_nMaskFlag); pFiler->writeItem(g_nVersion); //-------------------------------- pFiler->writeItem(m_nPageWidth); pFiler->writeItem(m_nLineSpace); pFiler->writeItem(m_bDir); //-------------------------------- pFiler->writeItem(m_nPagHeight); pFiler->writeItem(m_nPageSpace); return pFiler->filerStatus(); } Acad::ErrorStatus AecDbMTextNew::dxfInFields (AcDbDxfFiler* pFiler) { assertWriteEnabled(); Acad::ErrorStatus es = AecDbText::dxfInFields(pFiler); if(es!=Acad::eOk) return es; if (!pFiler->atSubclassData(_T("AecDbMTextNew"))) { 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 AecDbMTextNew::dxfOutFields(AcDbDxfFiler* pFiler) const { assertReadEnabled(); Acad::ErrorStatus es=AecDbText::dxfOutFields(pFiler); assert(es == Acad::eOk); es = pFiler->writeItem(AcDb::kDxfSubclass,_T("AecDbMTextNew")); 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 AecDbMTextNew::subTransformBy(const AcGeMatrix3d& xform) { assertWriteEnabled(); AecEntity::subTransformBy(xform); ads_matrix mat; AsAdsMatrix(xform, mat); if (!g_bLayoutRotate) { double nAngWcs = CT_std_angle(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]))); // aec delete 101217,根据8.5需求,解决多行文字的转角在某些范围内时,move移动或copy复制文字则反向的问题 if (IsMirrorMatrix(mat)) { m_nRotation = xg_angle(m_nRotation); } } m_ptText.TransformBy(mat); return Acad::eOk; } Acad::ErrorStatus AecDbMTextNew::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 AecDbMTextNew::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 &lstInfo) const { // aec modify 100322,根据8.5新需求修改,标述更准确 // lstInfo.Append(new ObjInfoUnit(_T("对象类型"), _T("文章"))); lstInfo.Append(new ObjInfoUnit(_T("对象类型"), _T("多行文字"))); // lstInfo.Append(new ObjInfoUnit(_T("文章内容"), m_sText)); lstInfo.Append(new ObjInfoUnit(_T("内容"), m_sText)); XString sTextStyle=GetSymbolName(m_idStyle); lstInfo.Append(new ObjInfoUnit(_T("文字样式"), sTextStyle)); XString sWidth; ftoa(m_nPageWidth, 1, sWidth); sWidth << _T("P"); lstInfo.Append(new ObjInfoUnit(_T("页宽"), sWidth)); XString sHeight; ftoa(m_nHeight, 1, sHeight); sHeight << _T("P"); lstInfo.Append(new ObjInfoUnit(_T("文字高度"), sHeight)); lstInfo.Append(new ObjInfoUnit(_T("旋转角度"), Angle2Str(m_nRotation*180/PI))); XString sLineSpace; ftoa(m_nLineSpace, 1, sLineSpace); sLineSpace << _T("P"); lstInfo.Append(new ObjInfoUnit(_T("行间距"), sLineSpace)); } // 没有考虑转角 XPoint AecDbMTextNew::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 AecDbMTextNew::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; iIsParagraph()) { 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(iIsParagraph()) // ; //下一个是硬回车, 则软硬回车同时输出 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; nAppend(textLine[n]); lstLines.Append(pTextLine); textLine.Reset(); textLine.SetDelFlag(TRUE); } else { //空行 lstLines.Append(new TTextLine); } nWidth=0.0; nOffsetY += nLineHeight + nLineSpace; } } } Acad::ErrorStatus AecDbMTextNew::ExplodeOrDraw2d(XExplodeDraw &dc) const { assertReadEnabled(); DList lstTextParts; if(!GetTextParts(lstTextParts)) 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; iIsParagraph()) { 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) > _DIST_SNAP) //自动换行 { //判断多一词还是少一词 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(iIsParagraph()) // ; //下一个是硬回车, 则软硬回车同时输出 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 aec 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 aec 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 AecDbMTextNew::GetPageWidth(BOOL bAsPaperUnit) const { double nVal=m_nPageWidth; if(!bAsPaperUnit) nVal *= GetPScale(); return nVal; } void AecDbMTextNew::SetPageWidth(double nWidth, BOOL bAsPaperUnit) { assertWriteEnabled(); m_nPageWidth=nWidth; if(!bAsPaperUnit) m_nPageWidth /= GetPScale(); } double AecDbMTextNew::GetLineSpace(BOOL bAsPaperUnit) const { double nVal=m_nLineSpace; if(!bAsPaperUnit) nVal *= GetPScale(); return nVal; } void AecDbMTextNew::SetLineSpace(double nWidth, BOOL bAsPaperUnit) { assertWriteEnabled(); m_nLineSpace=nWidth; if(!bAsPaperUnit) m_nLineSpace /= GetPScale(); } void InitDbText(BOOL bTrue) { if(bTrue) { AecDbText::rxInit(); AecDbMText::rxInit(); AecDbMTextNew::rxInit(); acrxBuildClassHierarchy(); AecDbText::InitMatchProtocol(TRUE); AecDbMText::InitMatchProtocol(TRUE); AecDbMTextNew::InitMatchProtocol(TRUE); } else { AecDbText::InitMatchProtocol(FALSE); AecDbMText::InitMatchProtocol(FALSE); AecDbMTextNew::InitMatchProtocol(FALSE); deleteAcRxClass(AecDbMText::desc()); deleteAcRxClass(AecDbMTextNew::desc()); deleteAcRxClass(AecDbText::desc()); } }