Files
envi-code/SourceCode/Code2026/tg_shs/shs_kernal/dbtext.cpp
T
gjm 164968b62e chore
把非utf8-bom编码的cpp/h文件改为 utf8 bom 编码, msvc识别utf8编码时,如果不是bom格式的,会使用当前cp_oem来解码.
2026-10-04 00:04:20 +08:00

3050 lines
80 KiB
C++

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