3446 lines
98 KiB
C++
3446 lines
98 KiB
C++
#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; i<nLen; i++)
|
|
if(! ::IsSpacer(m_sText[i]))
|
|
return FALSE;
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
BOOL TTextPart::IsPunctuation() const
|
|
{
|
|
int nLen=_tcslen(m_sText);
|
|
BOOL bFind=FALSE;
|
|
for(int i=0; i<nLen; i++) {
|
|
if(::IsSpacer(m_sText[i])) ;
|
|
else if(::IsPunctuation(m_sText[i]))
|
|
bFind=TRUE;
|
|
else return FALSE;
|
|
}
|
|
return bFind;
|
|
}
|
|
|
|
int TTextPart::GetControlCode() const // ^2==2, ^3=3, ^4=4
|
|
{
|
|
int nRet=0;
|
|
size_t nCount=_tcslen(m_sText);
|
|
if(m_sText[0]==_T('^') && nCount==2) {
|
|
nRet=_ttoi(&m_sText[1]);
|
|
if(nRet<1 || nRet>4)
|
|
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; i<lines.Length(); i++) {
|
|
const TTextPart &part=lines[i];
|
|
if(part.IsParagraph() || part.IsSpacer())
|
|
;
|
|
else {
|
|
bEmpty=FALSE;
|
|
break;
|
|
}
|
|
}
|
|
return bEmpty;
|
|
}
|
|
|
|
|
|
double TTextLine::GetHeight(BOOL bFromBase) const
|
|
{
|
|
XPoint ptExt=GetExtents();
|
|
return (bFromBase? ptExt.y : ptExt.z);
|
|
}
|
|
|
|
double TTextLine::GetWidth() const
|
|
{
|
|
return GetExtents().x;
|
|
}
|
|
|
|
void TTextLine::AdjustWidthFactor(double nFactor)
|
|
{
|
|
int nCount=Length();
|
|
for(int i=0; i<nCount; i++) {
|
|
TTextPart *pText=(*this)[i];
|
|
pText->m_nSizeX *= nFactor;
|
|
pText->m_nWidthFactor *= nFactor;
|
|
pText->m_ptLowLeft.x *= nFactor;
|
|
}
|
|
}
|
|
|
|
void TTextLine::AdjustBasePoint(double x)
|
|
{
|
|
int nCount=Length();
|
|
for(int i=0; i<nCount; i++) {
|
|
TTextPart *pText=(*this)[i];
|
|
pText->m_ptLowLeft.x += x;
|
|
}
|
|
}
|
|
|
|
|
|
// 宽度, 基线上的高度, 总高度
|
|
XPoint TTextLine::GetExtents() const
|
|
{
|
|
double nWidth=0.0;
|
|
int nCount=Length();
|
|
double nYMin=0.0, nYMax=0.0;
|
|
for(int i=0; i<nCount; i++) {
|
|
const TTextPart *pText=&(*this)[i];
|
|
nWidth += pText->GetWidth();
|
|
nYMin=min(pText->GetYMin(), nYMin);
|
|
nYMax=max(pText->GetYMax(), nYMax);
|
|
}
|
|
XPoint vtExt = XPoint(nWidth, nYMax, nYMax-nYMin);
|
|
//ASSERT(vtExt.x>0.0 && vtExt.y>0.0 && vtExt.z>0.0);
|
|
return vtExt;
|
|
}
|
|
|
|
/////////////////////////////////////////////////////////////
|
|
// 文字对象类
|
|
/////////////////////////////////////////////////////////////
|
|
const Adesk::UInt8 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<<XSolid(poly2d);
|
|
dcCommon->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<TTextPart> &lineText) const
|
|
{
|
|
BOOL bExpl=(_tcscmp(dc.Desc(), XExplodeStream::Descriptor())==0);
|
|
dc.SetAlignment(XExplodeDraw::kLeft);
|
|
int nCount=lineText.Length();
|
|
double nRotWcs=Layout2Wcs(m_nRotation);
|
|
for(int i=0; i<nCount; i++)
|
|
{
|
|
const TTextPart *pTextPart=&lineText[i];
|
|
if(bExpl && pTextPart->IsSpacer())
|
|
continue;
|
|
int nCtrlCode=pTextPart->GetControlCode();
|
|
if(!nCtrlCode)
|
|
{
|
|
switch(pTextPart->m_iType)
|
|
{
|
|
case 0://文字
|
|
{
|
|
// mod by 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<ObjInfoUnit> &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<BOOL> 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<BOOL> 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<TTextPart> &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<TTextLine> 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<TTextLine> 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<nLen; i++) {
|
|
int idx=indices[i];
|
|
if(idx==0) {
|
|
m_ptText += vtOffset;
|
|
} else {
|
|
ptRight += vtOffset;
|
|
SetPageWidth(m_ptText.Distance2d(ptRight), FALSE);
|
|
//m_nRotation=ads_angle(m_ptText, ptRight);
|
|
}
|
|
}
|
|
return Acad::eOk;
|
|
}
|
|
|
|
// 取得夹点说明
|
|
Acad::ErrorStatus AecDbMText::GetGripText(int i, CString &cs) const
|
|
{
|
|
Acad::ErrorStatus es=Acad::eOk;
|
|
switch(i) {
|
|
case 0:
|
|
cs=_T("移动文字");
|
|
break;
|
|
case 1:
|
|
cs=_T("改页宽");
|
|
break;
|
|
default:
|
|
es=Acad::eInvalidInput;
|
|
}
|
|
return es;
|
|
}
|
|
|
|
void AecDbMText::GetTips(DList<ObjInfoUnit> &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<TTextLine> 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<TTextLine> &lstLines) const
|
|
{
|
|
DList<TTextPart> lstTextParts;
|
|
if(!GetTextParts(lstTextParts))
|
|
return;
|
|
|
|
double nPageWidth=GetPageWidth(FALSE);
|
|
double nLineSpace=GetLineSpace(FALSE);
|
|
double nLineHeight=GetHeight(FALSE);
|
|
double nAngWcs=Layout2Wcs(m_nRotation);
|
|
|
|
double nWidth=0.0;
|
|
XPoint ptTopLeft=m_ptText;
|
|
int nCount=lstTextParts.Length();
|
|
|
|
TTextLine textLine; //一行
|
|
double nOffsetY=nLineHeight;
|
|
for(int i=0; i<nCount; i++) {
|
|
TTextPart *pText=lstTextParts[i];
|
|
BOOL bExportLine=FALSE;
|
|
if(pText->IsParagraph()) {
|
|
bExportLine=TRUE;
|
|
} else if(nPageWidth<_DIST_SNAP) {
|
|
textLine.Append(new TTextPart(*pText));
|
|
nWidth += pText->GetWidth();
|
|
} else if(nWidth>nPageWidth) {
|
|
ASSERT(0);
|
|
} else if(nWidth+pText->GetWidth()>nPageWidth) { //自动换行
|
|
//判断多一词还是少一词
|
|
if(pText->IsSpacer() || pText->IsPunctuation()) {
|
|
//多一词, 或者是空格, 或者是标点
|
|
textLine.Append(new TTextPart(*pText));
|
|
nWidth += pText->GetWidth();
|
|
} else if(!pText->m_bChinese) { //英文单词或控制符
|
|
if(textLine.Length()==0 || //无法容纳一个单词, 也没有办法
|
|
(m_nAlignment==XExplodeDraw::kTextFit &&
|
|
fabs(nWidth-nPageWidth)>fabs(nWidth+pText->GetWidth()-nPageWidth)
|
|
) //与其少一词还不如多一词
|
|
) {
|
|
textLine.Append(new TTextPart(*pText));
|
|
nWidth += pText->GetWidth();
|
|
} else
|
|
i--;
|
|
} else { //中文字序列, 假设中文字都是等宽
|
|
double nWidthLeft=nPageWidth-nWidth; //还剩下的未满一行的宽度
|
|
double nFactor=nWidthLeft/pText->GetWidth(); //需要往上一行的比例
|
|
int nUnit=_tcslen(_T("我"));
|
|
int nCharNum=pText->m_sText.Length()/nUnit;
|
|
int nCharNumPrev=AS_INT(nFactor*nCharNum);
|
|
if(nCharNumPrev==0 && textLine.Length()==0)
|
|
nCharNumPrev++; //至少要一个汉字
|
|
if(nCharNumPrev==nCharNum) { //全部上
|
|
textLine.Append(new TTextPart(*pText));
|
|
nWidth += pText->GetWidth();
|
|
} else if(nCharNumPrev==0) {//全部下
|
|
i--;
|
|
} else { //部分上, 部分下
|
|
nFactor = double(nCharNumPrev)/double(nCharNum);
|
|
TTextPart *pNewText=new TTextPart(*pText);
|
|
pNewText->m_nSizeX *= nFactor;
|
|
pText->m_sText=&(pNewText->m_sText[nCharNumPrev*nUnit]);
|
|
pNewText->m_sText[nCharNumPrev*nUnit]=EOS;
|
|
textLine.Append(pNewText);
|
|
pText->m_nSizeX -= pNewText->m_nSizeX;
|
|
pText->m_ptLowLeft.x += pNewText->m_nSizeX;
|
|
nWidth += pNewText->GetWidth();
|
|
i--;
|
|
}
|
|
}
|
|
if(m_nAlignment==XExplodeDraw::kTextFit)
|
|
textLine.AdjustWidthFactor(nPageWidth/nWidth);
|
|
if(i<nCount-1 && lstTextParts[i+1]->IsParagraph()) //
|
|
; //下一个是硬回车, 则软硬回车同时输出
|
|
else
|
|
bExportLine=TRUE;
|
|
} else {
|
|
textLine.Append(new TTextPart(*pText));
|
|
nWidth += pText->GetWidth();
|
|
if(i==nCount-1) {
|
|
bExportLine=TRUE;
|
|
}
|
|
}
|
|
|
|
if(bExportLine) {
|
|
if(textLine.Length()) {
|
|
XPoint ptBase;
|
|
ads_polar(ptTopLeft, nAngWcs-PI/2, nOffsetY, ptBase);
|
|
textLine.AdjustBasePoint(-textLine[0]->m_ptLowLeft.x);
|
|
if(m_nAlignment==XExplodeDraw::kCenter) {
|
|
XPoint ptAlign=XExplodeDraw::Base2Align(m_nAlignment, textLine[0]->m_ptLowLeft, textLine.GetExtents());
|
|
ads_polar(XPoint(ptBase), nAngWcs, nPageWidth/2.0-ptAlign.x, ptBase);
|
|
} else if(m_nAlignment==XExplodeDraw::kRight) {
|
|
XPoint ptAlign=XExplodeDraw::Base2Align(m_nAlignment, textLine[0]->m_ptLowLeft, textLine.GetExtents());
|
|
ads_polar(XPoint(ptBase), nAngWcs, nPageWidth-ptAlign.x, ptBase);
|
|
}
|
|
|
|
//OutputTextLine(dc, ptBase, textLine);
|
|
textLine.SetDelFlag(FALSE);
|
|
TTextLine *pTextLine=new TTextLine;
|
|
int nNumText=textLine.Length();
|
|
for(int n=0; n<nNumText; n++)
|
|
pTextLine->Append(textLine[n]);
|
|
lstLines.Append(pTextLine);
|
|
textLine.Reset();
|
|
textLine.SetDelFlag(TRUE);
|
|
} else {
|
|
//空行
|
|
lstLines.Append(new TTextLine);
|
|
}
|
|
|
|
nWidth=0.0;
|
|
nOffsetY += nLineHeight + nLineSpace;
|
|
}
|
|
}
|
|
}
|
|
|
|
Acad::ErrorStatus
|
|
AecDbMText::ExplodeOrDraw2d(XExplodeDraw &dc) const
|
|
{
|
|
assertReadEnabled();
|
|
DList<TTextPart> 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; i<nCount; i++)
|
|
{
|
|
TTextPart *pText=lstTextParts[i];
|
|
BOOL bExportLine=FALSE;
|
|
if(pText->IsParagraph())
|
|
{
|
|
bExportLine=TRUE;
|
|
}
|
|
else if(nPageWidth<_DIST_SNAP)
|
|
{
|
|
textLine.Append(new TTextPart(*pText));
|
|
nWidth += pText->GetWidth();
|
|
}
|
|
else if(nWidth>nPageWidth)
|
|
{
|
|
ASSERT(0);
|
|
//textLine.AdjustWidthFactor(nPageWidth/nWidth);
|
|
//bExportLine=TRUE;
|
|
}
|
|
else if( (nWidth + pText->GetWidth()- nPageWidth) > _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(i<nCount-1 && lstTextParts[i+1]->IsParagraph()) //
|
|
; //下一个是硬回车, 则软硬回车同时输出
|
|
else
|
|
bExportLine=TRUE;
|
|
}
|
|
else
|
|
{
|
|
textLine.Append(new TTextPart(*pText));
|
|
nWidth += pText->GetWidth();
|
|
if(i==nCount-1)
|
|
{
|
|
bExportLine=TRUE;
|
|
}
|
|
}
|
|
|
|
if(bExportLine)
|
|
{
|
|
if(textLine.Length())
|
|
{
|
|
XPoint ptBase;
|
|
ads_polar(ptTopLeft, nAngWcs-PI/2, nOffsetY, ptBase);
|
|
dc.SetSelectionMarker(nMark);
|
|
textLine.AdjustBasePoint(-textLine[0]->m_ptLowLeft.x);
|
|
if(m_nAlignment==XExplodeDraw::kCenter)
|
|
{
|
|
XPoint ptAlign=XExplodeDraw::Base2Align(m_nAlignment, textLine[0]->m_ptLowLeft, textLine.GetExtents());
|
|
ads_polar(XPoint(ptBase), nAngWcs, nPageWidth/2.0-ptAlign.x, ptBase);
|
|
}
|
|
else if(m_nAlignment==XExplodeDraw::kRight)
|
|
{
|
|
XPoint ptAlign=XExplodeDraw::Base2Align(m_nAlignment, textLine[0]->m_ptLowLeft, textLine.GetExtents());
|
|
ads_polar(XPoint(ptBase), nAngWcs, nPageWidth-ptAlign.x, ptBase);
|
|
}
|
|
|
|
if(_tcsicmp(dc.Desc(), XAcGiViewDraw::Descriptor())==0 &&
|
|
((XAcGiViewDraw&)dc).GetCommonDraw()->isDragging()
|
|
&&g_bQuickDragMText)//add by 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<TTextLine> 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<TTextLine> 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<nLen; i++) {
|
|
int idx=indices[i];
|
|
if(idx==0) {
|
|
m_ptText += vtOffset;
|
|
} else {
|
|
ptRight += vtOffset;
|
|
SetPageWidth(m_ptText.Distance2d(ptRight), FALSE);
|
|
//m_nRotation=ads_angle(m_ptText, ptRight);
|
|
}
|
|
}
|
|
return Acad::eOk;
|
|
}
|
|
|
|
// 取得夹点说明
|
|
Acad::ErrorStatus AecDbMTextNew::GetGripText(int i, CString &cs) const
|
|
{
|
|
Acad::ErrorStatus es=Acad::eOk;
|
|
switch(i) {
|
|
case 0:
|
|
cs=_T("移动文字");
|
|
break;
|
|
case 1:
|
|
cs=_T("改页宽");
|
|
break;
|
|
default:
|
|
es=Acad::eInvalidInput;
|
|
}
|
|
return es;
|
|
}
|
|
|
|
void AecDbMTextNew::GetTips(DList<ObjInfoUnit> &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<TTextLine> 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<TTextLine> &lstLines) const
|
|
{
|
|
DList<TTextPart> lstTextParts;
|
|
if(!GetTextParts(lstTextParts))
|
|
return;
|
|
|
|
double nPageWidth=GetPageWidth(FALSE);
|
|
double nLineSpace=GetLineSpace(FALSE);
|
|
double nLineHeight=GetHeight(FALSE);
|
|
double nAngWcs=Layout2Wcs(m_nRotation);
|
|
|
|
double nWidth=0.0;
|
|
XPoint ptTopLeft=m_ptText;
|
|
int nCount=lstTextParts.Length();
|
|
|
|
TTextLine textLine; //一行
|
|
double nOffsetY=nLineHeight;
|
|
for(int i=0; i<nCount; i++) {
|
|
TTextPart *pText=lstTextParts[i];
|
|
BOOL bExportLine=FALSE;
|
|
if(pText->IsParagraph()) {
|
|
bExportLine=TRUE;
|
|
} else if(nPageWidth<_DIST_SNAP) {
|
|
textLine.Append(new TTextPart(*pText));
|
|
nWidth += pText->GetWidth();
|
|
} else if(nWidth>nPageWidth) {
|
|
ASSERT(0);
|
|
} else if(nWidth+pText->GetWidth()>nPageWidth) { //自动换行
|
|
//判断多一词还是少一词
|
|
if(pText->IsSpacer() || pText->IsPunctuation()) {
|
|
//多一词, 或者是空格, 或者是标点
|
|
textLine.Append(new TTextPart(*pText));
|
|
nWidth += pText->GetWidth();
|
|
} else if(!pText->m_bChinese) { //英文单词或控制符
|
|
if(textLine.Length()==0 || //无法容纳一个单词, 也没有办法
|
|
(m_nAlignment==XExplodeDraw::kTextFit &&
|
|
fabs(nWidth-nPageWidth)>fabs(nWidth+pText->GetWidth()-nPageWidth)
|
|
) //与其少一词还不如多一词
|
|
) {
|
|
textLine.Append(new TTextPart(*pText));
|
|
nWidth += pText->GetWidth();
|
|
} else
|
|
i--;
|
|
} else { //中文字序列, 假设中文字都是等宽
|
|
double nWidthLeft=nPageWidth-nWidth; //还剩下的未满一行的宽度
|
|
double nFactor=nWidthLeft/pText->GetWidth(); //需要往上一行的比例
|
|
int nUnit=_tcslen(_T("我"));
|
|
int nCharNum=pText->m_sText.Length()/nUnit;
|
|
int nCharNumPrev=AS_INT(nFactor*nCharNum);
|
|
if(nCharNumPrev==0 && textLine.Length()==0)
|
|
nCharNumPrev++; //至少要一个汉字
|
|
if(nCharNumPrev==nCharNum) { //全部上
|
|
textLine.Append(new TTextPart(*pText));
|
|
nWidth += pText->GetWidth();
|
|
} else if(nCharNumPrev==0) {//全部下
|
|
i--;
|
|
} else { //部分上, 部分下
|
|
nFactor = double(nCharNumPrev)/double(nCharNum);
|
|
TTextPart *pNewText=new TTextPart(*pText);
|
|
pNewText->m_nSizeX *= nFactor;
|
|
pText->m_sText=&(pNewText->m_sText[nCharNumPrev*nUnit]);
|
|
pNewText->m_sText[nCharNumPrev*nUnit]=EOS;
|
|
textLine.Append(pNewText);
|
|
pText->m_nSizeX -= pNewText->m_nSizeX;
|
|
pText->m_ptLowLeft.x += pNewText->m_nSizeX;
|
|
nWidth += pNewText->GetWidth();
|
|
i--;
|
|
}
|
|
}
|
|
if(m_nAlignment==XExplodeDraw::kTextFit)
|
|
textLine.AdjustWidthFactor(nPageWidth/nWidth);
|
|
if(i<nCount-1 && lstTextParts[i+1]->IsParagraph()) //
|
|
; //下一个是硬回车, 则软硬回车同时输出
|
|
else
|
|
bExportLine=TRUE;
|
|
} else {
|
|
textLine.Append(new TTextPart(*pText));
|
|
nWidth += pText->GetWidth();
|
|
if(i==nCount-1) {
|
|
bExportLine=TRUE;
|
|
}
|
|
}
|
|
|
|
if(bExportLine) {
|
|
if(textLine.Length()) {
|
|
XPoint ptBase;
|
|
ads_polar(ptTopLeft, nAngWcs-PI/2, nOffsetY, ptBase);
|
|
textLine.AdjustBasePoint(-textLine[0]->m_ptLowLeft.x);
|
|
if(m_nAlignment==XExplodeDraw::kCenter) {
|
|
XPoint ptAlign=XExplodeDraw::Base2Align(m_nAlignment, textLine[0]->m_ptLowLeft, textLine.GetExtents());
|
|
ads_polar(XPoint(ptBase), nAngWcs, nPageWidth/2.0-ptAlign.x, ptBase);
|
|
} else if(m_nAlignment==XExplodeDraw::kRight) {
|
|
XPoint ptAlign=XExplodeDraw::Base2Align(m_nAlignment, textLine[0]->m_ptLowLeft, textLine.GetExtents());
|
|
ads_polar(XPoint(ptBase), nAngWcs, nPageWidth-ptAlign.x, ptBase);
|
|
}
|
|
|
|
//OutputTextLine(dc, ptBase, textLine);
|
|
textLine.SetDelFlag(FALSE);
|
|
TTextLine *pTextLine=new TTextLine;
|
|
int nNumText=textLine.Length();
|
|
for(int n=0; n<nNumText; n++)
|
|
pTextLine->Append(textLine[n]);
|
|
lstLines.Append(pTextLine);
|
|
textLine.Reset();
|
|
textLine.SetDelFlag(TRUE);
|
|
} else {
|
|
//空行
|
|
lstLines.Append(new TTextLine);
|
|
}
|
|
|
|
nWidth=0.0;
|
|
nOffsetY += nLineHeight + nLineSpace;
|
|
}
|
|
}
|
|
}
|
|
|
|
Acad::ErrorStatus
|
|
AecDbMTextNew::ExplodeOrDraw2d(XExplodeDraw &dc) const
|
|
{
|
|
assertReadEnabled();
|
|
DList<TTextPart> 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; i<nCount; i++)
|
|
{
|
|
TTextPart *pText=lstTextParts[i];
|
|
BOOL bExportLine=FALSE;
|
|
if(pText->IsParagraph())
|
|
{
|
|
bExportLine=TRUE;
|
|
}
|
|
else if(nPageWidth<_DIST_SNAP)
|
|
{
|
|
textLine.Append(new TTextPart(*pText));
|
|
nWidth += pText->GetWidth();
|
|
}
|
|
else if(nWidth>nPageWidth)
|
|
{
|
|
ASSERT(0);
|
|
//textLine.AdjustWidthFactor(nPageWidth/nWidth);
|
|
//bExportLine=TRUE;
|
|
}
|
|
else if( (nWidth + pText->GetWidth()- nPageWidth) > _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(i<nCount-1 && lstTextParts[i+1]->IsParagraph()) //
|
|
; //下一个是硬回车, 则软硬回车同时输出
|
|
else
|
|
bExportLine=TRUE;
|
|
}
|
|
else
|
|
{
|
|
textLine.Append(new TTextPart(*pText));
|
|
nWidth += pText->GetWidth();
|
|
if(i==nCount-1)
|
|
{
|
|
bExportLine=TRUE;
|
|
}
|
|
}
|
|
|
|
if(bExportLine)
|
|
{
|
|
if(textLine.Length())
|
|
{
|
|
XPoint ptBase;
|
|
ads_polar(ptTopLeft, nAngWcs-PI/2, nOffsetY, ptBase);
|
|
dc.SetSelectionMarker(nMark);
|
|
textLine.AdjustBasePoint(-textLine[0]->m_ptLowLeft.x);
|
|
if(m_nAlignment==XExplodeDraw::kCenter)
|
|
{
|
|
XPoint ptAlign=XExplodeDraw::Base2Align(m_nAlignment, textLine[0]->m_ptLowLeft, textLine.GetExtents());
|
|
ads_polar(XPoint(ptBase), nAngWcs, nPageWidth/2.0-ptAlign.x, ptBase);
|
|
}
|
|
else if(m_nAlignment==XExplodeDraw::kRight)
|
|
{
|
|
XPoint ptAlign=XExplodeDraw::Base2Align(m_nAlignment, textLine[0]->m_ptLowLeft, textLine.GetExtents());
|
|
ads_polar(XPoint(ptBase), nAngWcs, nPageWidth-ptAlign.x, ptBase);
|
|
}
|
|
|
|
if(_tcsicmp(dc.Desc(), XAcGiViewDraw::Descriptor())==0 &&
|
|
((XAcGiViewDraw&)dc).GetCommonDraw()->isDragging()
|
|
&&g_bQuickDragMText)//add by 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());
|
|
}
|
|
}
|