1671 lines
43 KiB
C++
1671 lines
43 KiB
C++
#include "stdafx.h"
|
|
#include "AcDbObjectPtr.h"
|
|
#include "AecDbText.h"
|
|
#include "globalFunc.h"
|
|
#include "GePoly2D.h"
|
|
#include "FindParser.h"
|
|
#include "AecDbSymbDrawingIndex.h"
|
|
|
|
static BOOL g_bPenups = FALSE;
|
|
|
|
namespace
|
|
{
|
|
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(AcGiDraw::TextAlignment m_nAlignment)
|
|
{
|
|
const TCHAR *str = _T("未知");
|
|
switch (m_nAlignment) {
|
|
case AcGiDraw::kTopLeft:
|
|
str = _T("左上");
|
|
break;
|
|
case AcGiDraw::kTopCenter:
|
|
str = _T("中上");
|
|
break;
|
|
case AcGiDraw::kTopRight:
|
|
str = _T("右上");
|
|
break;
|
|
case AcGiDraw::kMiddleLeft:
|
|
str = _T("左中");
|
|
break;
|
|
case AcGiDraw::kMiddleCenter:
|
|
str = _T("正中");
|
|
break;
|
|
case AcGiDraw::kMiddleRight:
|
|
str = _T("右中");
|
|
break;
|
|
case AcGiDraw::kBottomLeft:
|
|
str = _T("左下");
|
|
break;
|
|
case AcGiDraw::kBottomCenter:
|
|
str = _T("中下");
|
|
break;
|
|
case AcGiDraw::kBottomRight:
|
|
str = _T("右下");
|
|
break;
|
|
case AcGiDraw::kLeft:
|
|
str = _T("左");
|
|
break;
|
|
case AcGiDraw::kCenter:
|
|
str = _T("中心");
|
|
break;
|
|
case AcGiDraw::kRight:
|
|
str = _T("右");
|
|
break;
|
|
case AcGiDraw::kMiddle:
|
|
str = _T("中间");
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
return str;
|
|
}
|
|
|
|
AcGiDraw::TextAlignment GetTextAlignment(AcDb::TextHorzMode nHMode, AcDb::TextVertMode nVMode)
|
|
{
|
|
return GlobalFunc::GetTextAlignment(nHMode, nVMode);
|
|
}
|
|
|
|
void GetTextAlignment(const AcGiDraw::TextAlignment &align
|
|
, AcDb::TextHorzMode &hMode
|
|
, AcDb::TextVertMode &vMode)
|
|
{
|
|
GlobalFunc::GetTextAlignment(align, hMode, vMode);
|
|
}
|
|
}
|
|
|
|
BOOL TextPart::IsSpacer() const
|
|
{
|
|
int nLen = _tcslen(m_sText);
|
|
for (int i = 0; i < nLen; i++)
|
|
if (!::IsSpacer(m_sText[i]))
|
|
return FALSE;
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
BOOL TextPart::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 TextPart::GetControlCode() const // ^2==2, ^3=3, ^4=4
|
|
{
|
|
int nRet = 0;
|
|
size_t nCount = _tcslen(m_sText);
|
|
if (m_sText[0] == _T('^') && nCount == 2)
|
|
{
|
|
TCHAR ch(m_sText[1]);
|
|
nRet = _ttoi(&ch);
|
|
// sg add 120609,增加对9.0新增三角形标高符号的注写功能
|
|
// if(nRet<1 || nRet>4)
|
|
if (nRet < 1 || nRet>6)
|
|
nRet = 0;
|
|
}
|
|
return nRet;
|
|
}
|
|
|
|
TextPart & TextPart::operator= (const TextPart &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;
|
|
}
|
|
|
|
TextParser::TParserStatus TextParser::GetNext(TCString &sNext, BOOL bSplitEAndC)
|
|
{
|
|
TParserStatus nStatus;
|
|
|
|
char szOut[1024] = "";
|
|
const char *p = m_pCurrent;
|
|
char *q = szOut;
|
|
|
|
if (!p || !*p)
|
|
nStatus = TextParser::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);
|
|
GlobalFunc::_StrCpy(szOut, p + 2, pFind);
|
|
|
|
if (pFind)
|
|
m_pCurrent = pFind + 2;
|
|
else
|
|
m_pCurrent = NULL;
|
|
|
|
sNext = (LPCTSTR)CString(szOut);
|
|
nStatus = bLow ? TextParser::kLowerText : TextParser::kUpperText;
|
|
return nStatus;
|
|
}
|
|
else if (*(p + 1) == 'C') // 圆圈文字
|
|
{
|
|
const char *pSubStr = "^C";
|
|
char *pFind = (char*)strstr(p + 1, pSubStr);
|
|
GlobalFunc::_StrCpy(szOut, p + 2, pFind);
|
|
|
|
if (pFind)
|
|
m_pCurrent = pFind + 2;
|
|
else
|
|
m_pCurrent = NULL;
|
|
|
|
sNext = (LPCTSTR)CString(szOut);
|
|
nStatus = TextParser::kCircleText;
|
|
return nStatus;
|
|
}
|
|
else // 钢筋符号、三角形标高符号
|
|
{
|
|
*q = *p;
|
|
p++;
|
|
q++;
|
|
*q = *p;
|
|
q++;
|
|
p++;
|
|
*q = EOS;
|
|
|
|
m_pCurrent = p;
|
|
sNext = (LPCTSTR)CString(szOut);
|
|
return TextParser::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)CString(szOut);
|
|
m_pCurrent = p;
|
|
if (szOut[0] == '\n')
|
|
nStatus = TextParser::kParagragh;
|
|
else
|
|
{
|
|
nStatus = bEng ? TextParser::kNormalEnglish : TextParser::kNormalChinese;
|
|
|
|
// sg modify 120516,导出T3时,允许中英文联排,而不管字高
|
|
nStatus = bMix ? TextParser::kT3NormalText : nStatus;
|
|
}
|
|
}
|
|
return nStatus;
|
|
}
|
|
|
|
BOOL TextLine::IsEmpty() const
|
|
{
|
|
const TextLine &lines = *this;
|
|
BOOL bEmpty = TRUE;
|
|
for (int i = 0; i < lines.Length(); i++) {
|
|
const TextPart &part = lines[i];
|
|
if (part.IsParagraph() || part.IsSpacer())
|
|
;
|
|
else {
|
|
bEmpty = FALSE;
|
|
break;
|
|
}
|
|
}
|
|
return bEmpty;
|
|
}
|
|
|
|
double TextLine::GetHeight(BOOL bFromBase) const
|
|
{
|
|
ADSGePoint3d ptExt = GetExtents();
|
|
return (bFromBase ? ptExt.y : ptExt.z);
|
|
}
|
|
|
|
double TextLine::GetWidth() const
|
|
{
|
|
return GetExtents().x;
|
|
}
|
|
|
|
void TextLine::AdjustWidthFactor(double nFactor)
|
|
{
|
|
int nCount = Length();
|
|
for (int i = 0; i < nCount; i++) {
|
|
TextPart *pText = (*this)[i];
|
|
pText->m_nSizeX *= nFactor;
|
|
pText->m_nWidthFactor *= nFactor;
|
|
pText->m_ptLowLeft.x *= nFactor;
|
|
}
|
|
}
|
|
|
|
void TextLine::AdjustBasePoint(double x)
|
|
{
|
|
int nCount = Length();
|
|
for (int i = 0; i < nCount; i++) {
|
|
TextPart *pText = (*this)[i];
|
|
pText->m_ptLowLeft.x += x;
|
|
}
|
|
}
|
|
|
|
// 宽度, 基线上的高度, 总高度
|
|
ADSGePoint3d TextLine::GetExtents() const
|
|
{
|
|
double nWidth = 0.0;
|
|
int nCount = Length();
|
|
double nYMin = 0.0, nYMax = 0.0;
|
|
for (int i = 0; i < nCount; i++) {
|
|
const TextPart *pText = &(*this)[i];
|
|
nWidth += pText->GetWidth();
|
|
nYMin = min(pText->GetYMin(), nYMin);
|
|
nYMax = max(pText->GetYMax(), nYMax);
|
|
}
|
|
ADSGePoint3d vtExt = ADSGePoint3d(nWidth, nYMax, nYMax - nYMin);
|
|
//ASSERT(vtExt.x>0.0 && vtExt.y>0.0 && vtExt.z>0.0);
|
|
return vtExt;
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////
|
|
|
|
const Adesk::UInt8 AecXDbText::g_nVersion = 2;
|
|
|
|
|
|
ACRX_DXF_DEFINE_MEMBERS(AecXDbText, AecXDbEntityBaseEx, AcDb::kDHL_CURRENT, AcDb::kMReleaseCurrent,
|
|
1, AEC_DANHTEXT, "AEC_DANHTEXT|图形无法解析, 请下载上华软件|网址: www.shanghuasoft.com");
|
|
|
|
AecXDbText::AecXDbText()
|
|
{
|
|
m_nHeight = 3.5;
|
|
m_nRotation = 0.0;
|
|
m_nAlignment = AcGiDraw::kLeft;
|
|
m_nMaskFlag = 0;
|
|
}
|
|
|
|
|
|
AecXDbText::~AecXDbText()
|
|
{
|
|
}
|
|
|
|
//Acad::ErrorStatus
|
|
//AecXDbText::audit(AcDbAuditInfo* pAuditInfo)
|
|
//{
|
|
//
|
|
// // 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 AecXDbText::IsValid() const
|
|
//{
|
|
// BOOL bRet = TDbEntity::IsValid();
|
|
// if (!bRet)
|
|
// return bRet;
|
|
// bRet = (!!m_sText && !!m_idStyle);
|
|
// return bRet;
|
|
//}
|
|
|
|
// 提供对格式刷的支持
|
|
//void AecXDbText::CopyPropertiesFrom(AcDbEntity *pSrcEntity, unsigned gMatchFlag)
|
|
//{
|
|
// assertWriteEnabled();
|
|
// TDbEntity::CopyPropertiesFrom(pSrcEntity, gMatchFlag);
|
|
// AecXDbText *pSrc = AecXDbText::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 AecXDbText::subGetClassID(CLSID* pClsid) const
|
|
//{
|
|
// return Acad::eOk;
|
|
//}
|
|
|
|
//Acad::ErrorStatus AecXDbText::DownGradeSave(int nDrawMode, AcDbVoidPtrArray &entSet, BOOL *bErase)
|
|
//{
|
|
// Acad::ErrorStatus es = Acad::eOk;
|
|
// CString sText = m_sText;
|
|
// if (g_nSaveTArchVer < 7 && sText.Find(_T("^C")) != -1)//7.0开始才有圆圈文字
|
|
// {
|
|
// AcGiDraw 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 AecXDbText::dwgInFields(AcDbDwgFiler* pFiler)
|
|
{
|
|
assertWriteEnabled();
|
|
|
|
Acad::ErrorStatus es = AecDbEntityBase::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);
|
|
GlobalFunc::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 = (AcGiDraw::TextAlignment)nAlign;
|
|
|
|
if (nVer > 1)
|
|
pFiler->readItem(&m_nMaskFlag);
|
|
|
|
return pFiler->filerStatus();
|
|
}
|
|
|
|
Acad::ErrorStatus AecXDbText::dwgOutFields(AcDbDwgFiler* pFiler) const
|
|
{
|
|
assertReadEnabled();
|
|
Acad::ErrorStatus es = AecDbEntityBase::dwgOutFields(pFiler);
|
|
if (es != Acad::eOk) return es;
|
|
|
|
pFiler->writeItem(g_nVersion);
|
|
|
|
pFiler->writeItem(m_idStyle);
|
|
pFiler->writeString((LPCTSTR)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 AecXDbText::dxfInFields(AcDbDxfFiler* pFiler)
|
|
{
|
|
assertWriteEnabled();
|
|
return AecDbEntityBase::dxfInFields(pFiler);
|
|
}
|
|
|
|
Acad::ErrorStatus AecXDbText::dxfOutFields(AcDbDxfFiler* pFiler) const
|
|
{
|
|
assertReadEnabled();
|
|
return AecDbEntityBase::dxfOutFields(pFiler);
|
|
}
|
|
|
|
Acad::ErrorStatus AecXDbText::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 AecXDbText::subIntersectWith(const AcDbEntity* ent,
|
|
AcDb::Intersect intType,
|
|
AcGePoint3dArray& points,
|
|
INT_PTR thisGsMarker,
|
|
INT_PTR otherGsMarker) const
|
|
{
|
|
return Acad::eNotApplicable;
|
|
}
|
|
|
|
Acad::ErrorStatus AecXDbText::subIntersectWith(const AcDbEntity* ent,
|
|
AcDb::Intersect intType,
|
|
const AcGePlane& projPlane,
|
|
AcGePoint3dArray& points,
|
|
INT_PTR thisGsMarker,
|
|
INT_PTR otherGsMarker) const
|
|
{
|
|
return Acad::eNotApplicable;
|
|
}
|
|
|
|
Acad::ErrorStatus AecXDbText::subGetGripPoints(AcGePoint3dArray& gripPoints,
|
|
AcDbIntArray& osnapModes,
|
|
AcDbIntArray& geomIds) const
|
|
{
|
|
assertReadEnabled();
|
|
gripPoints.append(m_ptText); //0
|
|
return Acad::eOk;
|
|
}
|
|
|
|
Acad::ErrorStatus AecXDbText::subGetStretchPoints(AcGePoint3dArray & stretchPoints) const
|
|
{
|
|
assertReadEnabled();
|
|
AcDbIntArray osnapModes;
|
|
AcDbIntArray geomIds;
|
|
return subGetGripPoints(stretchPoints, osnapModes, geomIds);
|
|
}
|
|
|
|
Acad::ErrorStatus AecXDbText::subTransformBy(const AcGeMatrix3d& xform)
|
|
{
|
|
assertWriteEnabled();
|
|
AecDbEntityBase::subTransformBy(xform);
|
|
ads_matrix mat;
|
|
GlobalFunc::AsAdsMatrix(xform, mat);
|
|
|
|
BOOL bMirror = GlobalFunc::IsMirrorMatrix(mat);
|
|
if (bMirror || g_Option::instance().g_bTextAdjust) { //镜像或角度自调
|
|
double nWidth, nHeight, nHeight1;
|
|
if (GetExtents(&nWidth, &nHeight, &nHeight1)) {
|
|
ADSGePoint3d ext(nWidth, nHeight, nHeight1);
|
|
ADSGePoint3d ptBase = Align2Base(m_ptText, ext);
|
|
AcGiDraw::TextAlignment nOldAlign = m_nAlignment;
|
|
m_nAlignment = AcGiDraw::kMiddleCenter;
|
|
ADSGePoint3d ptCen = Base2Align(ptBase, ext);
|
|
|
|
if (!g_Option::instance().g_bLayoutRotate) { //布局旋转时,局部不旋转
|
|
AcGeVector3d vt(cos(m_nRotation + m_nLayoutRotation), sin(m_nRotation + m_nLayoutRotation), 0.0);
|
|
vt.transformBy(xform);
|
|
m_nRotation = ads_angle(ADSGePoint3d(), ADSGePoint3d(vt[0], vt[1]));
|
|
m_nRotation = GlobalFunc::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_Option::instance().g_bLayoutRotate) {
|
|
AcGeVector3d vt(cos(m_nRotation + m_nLayoutRotation), sin(m_nRotation + m_nLayoutRotation), 0.0);
|
|
vt.transformBy(xform);
|
|
m_nRotation = Wcs2Layout(ads_angle(ADSGePoint3d(), ADSGePoint3d(vt[0], vt[1])));
|
|
m_nHeight *= vt.length();
|
|
}
|
|
|
|
m_ptText.TransformBy(mat);
|
|
}
|
|
return Acad::eOk;
|
|
}
|
|
|
|
void AecXDbText::UnionScale(double nScale)
|
|
{
|
|
assertWriteEnabled();
|
|
AcGeMatrix3d mat;
|
|
mat.setToScaling(nScale);
|
|
m_ptText.TransformBy(mat);
|
|
}
|
|
|
|
// 功能: 夹点操作
|
|
Acad::ErrorStatus AecXDbText::subMoveGripPointsAt(
|
|
const AcDbIntArray& indices,
|
|
const AcGeVector3d& offset)
|
|
{
|
|
assertWriteEnabled();
|
|
ADSGePoint3d 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 AecXDbText::subMoveStretchPointsAt(
|
|
const AcDbIntArray& indices,
|
|
const AcGeVector3d& offset)
|
|
{
|
|
return subMoveGripPointsAt(indices, offset);
|
|
}
|
|
|
|
|
|
// 取得夹点说明
|
|
Acad::ErrorStatus AecXDbText::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 AecXDbText::ConvertText(TConvertTextPtr ptr, void *pData)
|
|
{
|
|
TCString sText;
|
|
int nRet = ptr(m_sText, sText, pData);
|
|
if (nRet == RTNORM) {
|
|
assertWriteEnabled();
|
|
m_sText = sText;
|
|
}
|
|
return nRet;
|
|
}
|
|
|
|
void AecXDbText::GetMaskPoly(std::vector<GePoly2D> &polys)
|
|
{
|
|
ADSGePoint3d ext = GetExtents();
|
|
ADSGePoint3d 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;
|
|
TVector3D 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;
|
|
|
|
GePoly2D poly2d(1);
|
|
ADSGePoint3d ptOldOrg = origin;
|
|
ads_polar(ADSGePoint3d(origin), xDir + PI, ext.y * 0.1, origin);
|
|
ads_polar(ADSGePoint3d(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 AecXDbText::Draw2d(AcGiDraw &dc) const
|
|
{
|
|
assertReadEnabled();
|
|
|
|
if (Has2DBuffer())
|
|
{
|
|
dc.SetColor(colorIndex());
|
|
dc.SetLayer(layerId());
|
|
Draw2DBuffers(dc);
|
|
return Acad::eOk;
|
|
}
|
|
|
|
AcDbObjectId idst = GlobalFunc::GetTextStyleId(_T("standard"));
|
|
if (idst.isValid())
|
|
dc.SetTextStyle(idst);
|
|
|
|
TextLine lstTextParts;
|
|
if (!GetTextParts(lstTextParts, TRUE))
|
|
return Acad::eInvalidInput;
|
|
|
|
ADSGePoint3d ptBase = Align2Base(m_ptText, lstTextParts.GetExtents());
|
|
dc.SetTextStyle(m_idStyle);
|
|
OutputTextLine(dc, ptBase, lstTextParts, Layout2Wcs(m_nRotation));
|
|
return Acad::eOk;
|
|
}
|
|
|
|
void AecXDbText::OutputTextLine(AcGiDraw &dc, ADSGePoint3d ptBase, const PtrList<TextPart> &lineText, const double &dRotate) const
|
|
{
|
|
AcGiDraw::TextAlignment align = AcGiDraw::kLeft;
|
|
|
|
int nCount = lineText.Length();
|
|
double nRotWcs = Layout2Wcs(m_nRotation);
|
|
for (int i = 0; i < nCount; i++)
|
|
{
|
|
const TextPart *pTextPart = &lineText[i];
|
|
if (pTextPart->IsSpacer()) continue;
|
|
|
|
int nCtrlCode = pTextPart->GetControlCode();
|
|
if (!nCtrlCode)
|
|
{
|
|
switch (pTextPart->m_iType)
|
|
{
|
|
case 0://文字
|
|
{
|
|
double dHeight = pTextPart->m_nHeight;
|
|
double dWFactor = pTextPart->m_nWidthFactor;
|
|
|
|
ADSGePoint3d ptLoc;
|
|
ads_polar(ptBase, nRotWcs, pTextPart->m_ptLowLeft.x, ptLoc);
|
|
ads_polar(ADSGePoint3d(ptLoc), nRotWcs + PI / 2, pTextPart->m_ptLowLeft.y, ptLoc);
|
|
|
|
dc.SetColor(colorIndex());
|
|
dc.SetLayer(layerId());
|
|
|
|
AcDbText *pTxt = new AcDbText(ptLoc.AsAcGePoint3d()
|
|
, pTextPart->m_sText
|
|
, m_idStyle
|
|
, dHeight
|
|
, dRotate);
|
|
pTxt->setWidthFactor(dWFactor);
|
|
AcDb::TextHorzMode hMode;
|
|
AcDb::TextVertMode vMode;
|
|
GetTextAlignment(align, hMode, vMode);
|
|
pTxt->setHorizontalMode(hMode);
|
|
pTxt->setVerticalMode(vMode);
|
|
dc.DrawEntity(*pTxt);
|
|
Add2DBuffer(pTxt);
|
|
}
|
|
break;
|
|
case 1://圆字
|
|
{
|
|
AecXDbSymbDrawingIndex index;
|
|
index.CopyPropertiesFrom((AcDbEntity*)this, 0);
|
|
index.SetSymbText(FALSE); // sg add 090729,解决了圆圈文字中的文字图层及颜色错误的BUG
|
|
ADSGePoint3d ptLoc;
|
|
ads_polar(ptBase, nRotWcs, pTextPart->m_ptLowLeft.x + GetHeight(FALSE) / 2, ptLoc);
|
|
ads_polar(ADSGePoint3d(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);
|
|
DrawBaseEx(dc, index);
|
|
//index.ExplodeOrDraw2d(dc);
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
AcDbLine *pL(NULL);
|
|
// sg add 120609,增加对9.0新增三角形标高符号的注写功能
|
|
if (nCtrlCode == 5 || nCtrlCode == 6)
|
|
{
|
|
ADSGePoint3d 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);
|
|
|
|
pL = new AcDbLine(ptTriangle3.AsAcGePoint3d(), ptTriangle2.AsAcGePoint3d());
|
|
dc.DrawEntity(*pL);
|
|
Add2DBuffer(pL);
|
|
pL = new AcDbLine(ptTriangle1.AsAcGePoint3d(), ptTriangle3.AsAcGePoint3d());
|
|
dc.DrawEntity(*pL);
|
|
Add2DBuffer(pL);
|
|
pL = new AcDbLine(ptTriangle1.AsAcGePoint3d(), ptTriangle2.AsAcGePoint3d());
|
|
dc.DrawEntity(*pL);
|
|
Add2DBuffer(pL);
|
|
|
|
if (nCtrlCode == 5) // 填充
|
|
{
|
|
GePoly2D polySolid(1);
|
|
polySolid.AppendNode(ptTriangle1);
|
|
polySolid.AppendNode(ptTriangle2);
|
|
polySolid.AppendNode(ptTriangle3);
|
|
AcDbCurve *pCurve = polySolid.AsAcDbCurve();
|
|
if (pCurve)
|
|
{
|
|
dc.DrawEntity(pCurve);
|
|
Add2DBuffer(pCurve);
|
|
}
|
|
}
|
|
continue;
|
|
}
|
|
|
|
// 输出钢筋符号
|
|
ADSGePoint3d ptCen;
|
|
ads_polar(ptBase, nRotWcs, pTextPart->m_ptLowLeft.x + pTextPart->GetWidth() / 2.0, ptCen);
|
|
ads_polar(ADSGePoint3d(ptCen), nRotWcs + PI / 2, pTextPart->m_ptLowLeft.y + pTextPart->GetHeightReal() / 2.0, ptCen);
|
|
double nRadius = min(pTextPart->GetWidth(), pTextPart->GetHeightReal()) * 0.3;
|
|
AcDbCircle *pCir = new AcDbCircle(ptCen.AsAcGePoint3d(), AcGeVector3d::kZAxis, nRadius);
|
|
dc.DrawEntity(*pCir);
|
|
Add2DBuffer(pCir);
|
|
|
|
if (nCtrlCode == 1 || nCtrlCode == 2)
|
|
{
|
|
ADSGePoint3d pt1, pt2;
|
|
ads_polar(ptCen, nRotWcs + PI / 2, pTextPart->GetHeightReal() * 0.45, pt1);
|
|
ads_polar(ptCen, nRotWcs - PI / 2, pTextPart->GetHeightReal() * 0.5, pt2);
|
|
pL = new AcDbLine(pt1.AsAcGePoint3d(), pt2.AsAcGePoint3d());
|
|
dc.DrawEntity(*pL);
|
|
Add2DBuffer(pL);
|
|
|
|
if (nCtrlCode == 2)
|
|
{
|
|
ADSGePoint3d pta, ptb;
|
|
ads_polar(pt2, nRotWcs - PI, nRadius, pta);
|
|
ads_polar(pt2, nRotWcs, nRadius, ptb);
|
|
pL = new AcDbLine(pta.AsAcGePoint3d(), ptb.AsAcGePoint3d());
|
|
dc.DrawEntity(*pL);
|
|
Add2DBuffer(pL);
|
|
}
|
|
}
|
|
else if (nCtrlCode == 3 || nCtrlCode == 4)
|
|
{
|
|
ADSGePoint3d pt1, pt2;
|
|
ads_polar(ptCen, nRotWcs + PI / 2, pTextPart->GetHeightReal() * 0.45, pt1);
|
|
ads_polar(ptCen, nRotWcs - PI / 2, pTextPart->GetHeightReal() * 0.5, pt2);
|
|
|
|
GeLine lnMid(pt1, pt2);
|
|
GeLine ln1 = lnMid.Offset(nRadius * 0.3);
|
|
GeLine ln2 = lnMid.Offset(-nRadius * 0.3);
|
|
|
|
pL = new AcDbLine(ln1.StartPoint().AsAcGePoint3d(), ln1.EndPoint().AsAcGePoint3d());
|
|
dc.DrawEntity(*pL);
|
|
Add2DBuffer(pL);
|
|
|
|
pL = new AcDbLine(ln2.StartPoint().AsAcGePoint3d(), ln2.EndPoint().AsAcGePoint3d());
|
|
dc.DrawEntity(*pL);
|
|
Add2DBuffer(pL);
|
|
|
|
ADSGePoint3d pta, ptb;
|
|
ads_polar(pt2, nRotWcs - PI, nRadius, pta);
|
|
ads_polar(pt2, nRotWcs, nRadius, ptb);
|
|
pL = new AcDbLine(pta.AsAcGePoint3d(), ptb.AsAcGePoint3d());
|
|
dc.DrawEntity(*pL);
|
|
Add2DBuffer(pL);
|
|
|
|
if (nCtrlCode == 4)
|
|
{
|
|
ads_polar(pt1, nRotWcs - PI, nRadius, pta);
|
|
ads_polar(pt1, nRotWcs, nRadius, ptb);
|
|
pL = new AcDbLine(pta.AsAcGePoint3d(), ptb.AsAcGePoint3d());
|
|
dc.DrawEntity(*pL);
|
|
Add2DBuffer(pL);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// 没有考虑转角
|
|
BOOL AecXDbText::GetExtents(double *pWidth, double *pHeight, double *pHeight1) const
|
|
{
|
|
TextLine lstTextParts;
|
|
if (!GetTextParts(lstTextParts))
|
|
return FALSE;
|
|
ADSGePoint3d ext = lstTextParts.GetExtents();
|
|
if (pWidth)
|
|
*pWidth = ext.x;
|
|
if (pHeight)
|
|
*pHeight = ext.y;
|
|
if (pHeight1)
|
|
*pHeight1 = ext.z;
|
|
return TRUE;
|
|
}
|
|
|
|
// 没有考虑转角
|
|
ADSGePoint3d AecXDbText::GetExtents() const
|
|
{
|
|
ADSGePoint3d ext;
|
|
TextLine lstTextParts;
|
|
if (!GetTextParts(lstTextParts))
|
|
return ext;
|
|
ext = lstTextParts.GetExtents();
|
|
return ext;
|
|
}
|
|
|
|
|
|
const TCHAR *AecXDbText::GetDefaultLayer() const
|
|
{
|
|
extern TCHAR* LAY_TEXT;
|
|
return LAY_TEXT;
|
|
}
|
|
|
|
DrawModeType AecXDbText::GetDrawType() const
|
|
{
|
|
return k2DOnly;
|
|
}
|
|
|
|
/* * * * * * * * * * 取 动 态 属 性 显 示 数 据 的 函 数 * * * * * * * * * */
|
|
void AecXDbText::GetTips(PtrList<ObjInfoUnit> &lstInfo) const
|
|
{
|
|
lstInfo.Append(new ObjInfoUnit(_T("对象类型"), _T("文字")));
|
|
lstInfo.Append(new ObjInfoUnit(_T("文字内容"), m_sText));
|
|
TCString sTextStyle = GlobalFunc::GetSymbolName(m_idStyle);
|
|
lstInfo.Append(new ObjInfoUnit(_T("文字样式"), sTextStyle));
|
|
lstInfo.Append(new ObjInfoUnit(_T("对正方式"), GetAlignString(m_nAlignment)));
|
|
TCString sHeight;
|
|
GlobalFunc::ftoa(m_nHeight, 1, sHeight);
|
|
sHeight << _T("P");
|
|
lstInfo.Append(new ObjInfoUnit(_T("文字高度"), sHeight));
|
|
lstInfo.Append(new ObjInfoUnit(_T("旋转角度"), GlobalFunc::Angle2Str(m_nRotation * 180 / PI)));
|
|
}
|
|
|
|
// 下面两个变量未使用
|
|
BOOL g_bUseTextMatchRule = FALSE;//使用通配符
|
|
BOOL g_bIgnoreCaps = FALSE; //忽略大小写
|
|
|
|
FindParser g_FindParser;
|
|
|
|
// 返回发现的位置,同时posStart往前移动(以便继续找下一个使用),
|
|
TextPosition
|
|
AecXDbText::FindSubText(const TCHAR *sSubText, TextPosition &posStart, TextRange *pRange) const
|
|
{
|
|
GlobalFunc::PushMemVar<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) {
|
|
TCString sPrefix(nCharByte + 1);
|
|
GlobalFunc::_StrCpy(sPrefix, csText, &((const TCHAR *)csText)[nFindPos]); //前面的字符串
|
|
|
|
ADSGePoint3d ptExt = GetExtents(); //x, y方向的尺寸
|
|
ADSGePoint3d ptTextBase = Align2Base(GetLocation(), ptExt); //左下角
|
|
double nRot = GetRotation(); //转角
|
|
|
|
ADSGePoint3d ptLowLeft;
|
|
AecXDbText *pClone = (AecXDbText *)this->clone();
|
|
pClone->SetText(sPrefix);
|
|
ADSGePoint3d extTemp = pClone->GetExtents();
|
|
ads_polar(ptTextBase, nRot, extTemp.x, ptLowLeft);
|
|
//pClone->SetText(sSubText);
|
|
pClone->SetText(csSubText);
|
|
extTemp = pClone->GetExtents();
|
|
delete pClone;
|
|
|
|
// 求找到的位置范围
|
|
GePoly2D *pPoly = new GePoly2D(1);
|
|
GePoly2D &polyExt = *pPoly;
|
|
polyExt.AppendNode(ptLowLeft);
|
|
ADSGePoint3d 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 AecXDbText::ReplaceSubText(const TextPosition &posRep, const TCHAR *sRepText, TextRange *pRange)
|
|
{
|
|
assertWriteEnabled();
|
|
GlobalFunc::PushMemVar<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;
|
|
|
|
TCString sPrefix(nCharByte + 1), sSuffix(nCharByte + 1);
|
|
GlobalFunc::_StrCpy(sPrefix, csText, &((const TCHAR *)csText)[nFindPos]); //前面的字符串
|
|
GlobalFunc::_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) {
|
|
ADSGePoint3d ptExt = GetExtents(); //x, y方向的尺寸
|
|
ADSGePoint3d ptTextBase = Align2Base(GetLocation(), ptExt); //左下角
|
|
double nRot = GetRotation(); //转角
|
|
|
|
ADSGePoint3d ptLowLeft;
|
|
AecXDbText *pClone = (AecXDbText *)this->clone();
|
|
pClone->SetText(sPrefix);
|
|
ADSGePoint3d extTemp = pClone->GetExtents();
|
|
ads_polar(ptTextBase, nRot, extTemp.x, ptLowLeft);
|
|
pClone->SetText(sRepText);
|
|
extTemp = pClone->GetExtents();
|
|
delete pClone;
|
|
|
|
// 求找到的位置范围
|
|
GePoly2D *pPoly = new GePoly2D(1);
|
|
GePoly2D &polyExt = *pPoly;
|
|
polyExt.AppendNode(ptLowLeft);
|
|
ADSGePoint3d 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
|
|
ADSGePoint3d AecXDbText::Align2Base(ADSGePoint3d ptAlign, ADSGePoint3d ext) const
|
|
{
|
|
ADSGePoint3d ptBase = AcGiDraw::Align2Base(m_nAlignment, ptAlign, ext);
|
|
ads_matrix mat;
|
|
ptAlign.GetRotationMatrix(m_nLayoutRotation + m_nRotation, mat);
|
|
ptBase.TransformBy(mat);
|
|
return ptBase;
|
|
}
|
|
|
|
ADSGePoint3d AecXDbText::Base2Align(ADSGePoint3d ptBase, ADSGePoint3d ext) const
|
|
{
|
|
ADSGePoint3d ptAlign = AcGiDraw::Base2Align(m_nAlignment, ptBase, ext);
|
|
ads_matrix mat;
|
|
ptBase.GetRotationMatrix(m_nLayoutRotation + m_nRotation, mat);
|
|
ptAlign.TransformBy(mat);
|
|
return ptAlign;
|
|
}
|
|
|
|
AcDbEntity * AecXDbText::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 AecXDbText::InitWipeout() const
|
|
{
|
|
#if (ARX<16)
|
|
if (!GlobalFunc::IsArxAppLoaded(_T("wipeout"))) {
|
|
int nRet = acrxLoadModule(_T("wipeout.arx"), Adesk::kFalse, true);
|
|
if (!nRet) {
|
|
g_Option::instance().adsout << _T("\n请事先安装AutoCAD快捷工具!");
|
|
return FALSE;
|
|
}
|
|
}
|
|
//LH 2013-2-27 修改原因当ARX=19时不执行下面代码
|
|
//#else if (ARX<19)
|
|
#endif
|
|
#if (16<ARX && ARX<19)
|
|
if (!GlobalFunc::IsArxAppLoaded(_T("AcWipeout"))) {
|
|
int nRet = acrxLoadModule(_T("AcWipeout.arx"), Adesk::kFalse, true);
|
|
if (!nRet) {
|
|
g_Option::instance().adsout << _T("\n无法加载AcWipeout.arx!");
|
|
return FALSE;
|
|
}
|
|
}
|
|
#endif
|
|
//LH 2013-2-28 由于AutoCAD2013版本后去除了AcWipeout.arx文件,所以2013版本需要判断是否加载了acismobj19.dbx
|
|
#if (ARX == 19)
|
|
if (!GlobalFunc::IsArxAppLoaded(_T("acismobj19")))
|
|
{
|
|
int nRet = acrxLoadModule(_T("acismobj19.dbx"), Adesk::kFalse, true);
|
|
if (!nRet) {
|
|
g_Option::instance().adsout << _T("\n无法加载acismobj19.dbx!");
|
|
return FALSE;
|
|
}
|
|
}
|
|
#endif
|
|
#if (ARX==20)
|
|
if (!GlobalFunc::IsArxAppLoaded(_T("acismobj20")))
|
|
{
|
|
int nRet = acrxLoadModule(_T("acismobj20.dbx"), Adesk::kFalse, true);
|
|
if (!nRet) {
|
|
g_Option::instance().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 = GlobalFunc::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 AecXDbText::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);
|
|
ADSGePoint3d ext = GetExtents();
|
|
ADSGePoint3d origin = Align2Base(GetLocation(), ext);
|
|
// origin.y -= ext.y*0.2;
|
|
// origin.x -= ext.y*0.1;
|
|
ADSGePoint3d ptOldOrg = origin;
|
|
ads_polar(ADSGePoint3d(origin), xDir + PI, ext.y * 0.1, origin);
|
|
ads_polar(ADSGePoint3d(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();
|
|
}
|
|
|
|
SubText* AecXDbText::HitTestText(ADSGePoint3d pt)const
|
|
{
|
|
return g_Option::instance().g_bDClickInplaceEdit ? GetSubText(0) : NULL;
|
|
}
|
|
|
|
BOOL AecXDbText::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 = GetTextAlignment(nHorMode, nVerMode);
|
|
if (!m_nAlignment)
|
|
//return FALSE;
|
|
//m_nAlignment=AcGiDraw::kLeft;//modified by whl on 040923
|
|
m_nAlignment = AcGiDraw::kBottomLeft;//modified by whl on 070108
|
|
|
|
setPropertiesFrom(pText);
|
|
m_idStyle = idStyle;
|
|
m_ptText = m_nAlignment == AcGiDraw::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);
|
|
ADSGePoint3d 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(GlobalFunc::AsAcGeMatrix3d(mat));
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
BOOL AecXDbText::GetTextParts(PtrList<TextPart> &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 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;
|
|
|
|
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;
|
|
}
|
|
|
|
|
|
ADSGePoint3d ptLowLeft;
|
|
#ifdef TASD
|
|
//mod my xlc on 140326 添加钢筋符号
|
|
//TextParser 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(""));
|
|
TextParser parser1(strText);
|
|
#else
|
|
TextParser parser1(m_sText);
|
|
#endif
|
|
|
|
TCString sWord1;
|
|
TextParser::TParserStatus nStatus1;
|
|
double nSizeScale = 0.5;
|
|
double nHeight1 = nHeightC;
|
|
while ((nStatus1 = parser1.GetNext(sWord1, bSplitEAndC)) != TextParser::kEndBuffer)
|
|
{
|
|
if (nStatus1 == TextParser::kParagragh)
|
|
{
|
|
ptLowLeft = ADSGePoint3d();
|
|
lstTextParts.Append(new TextPart(sWord1, ptLowLeft, FALSE, 0.0, 0.0, 0.0, 0.0, 0.0));
|
|
}
|
|
else if (nStatus1 == TextParser::kNormalEnglish || nStatus1 == TextParser::kNormalChinese
|
|
|| nStatus1 == TextParser::kControlCode)
|
|
{
|
|
nHeight1 = (nStatus1 == TextParser::kNormalEnglish ? nHeightE : nHeightC);
|
|
double nScale1 = (nStatus1 == TextParser::kNormalEnglish ? nWidthFactorE : nWidthFactorC);
|
|
txtStyle.setTextSize((bWinFont || nStatus1 == TextParser::kNormalChinese) ? nHeight1 * nSize2Real : nHeight1);
|
|
txtStyle.setXScale(nScale1);
|
|
|
|
const TCHAR *pszBigFont = txtStyle.bigFontFileName();
|
|
BOOL bPenups = parser1.IsEOS() ? g_bPenups : TRUE;
|
|
AcGePoint2d ext1 =
|
|
nStatus1 == TextParser::kControlCode ? AcGePoint2d(nHeight1 * nScale1, nHeight1) : txtStyle.extents(sWord1, bPenups, -1, Adesk::kFalse);
|
|
ptLowLeft.y = 0.0;
|
|
|
|
lstTextParts.Append(new TextPart(sWord1, ptLowLeft,
|
|
nStatus1 == TextParser::kNormalChinese, nHeight1,
|
|
((bWinFont || nStatus1 == TextParser::kNormalChinese) ? nHeight1 * nSize2Real : nHeight1),
|
|
nScale1, ext1[0], ext1[1]));
|
|
ptLowLeft.x += ext1.x;
|
|
}
|
|
else if (nStatus1 == TextParser::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 TextPart(sWord1, ptLowLeft, TRUE, nHeight1, nHeight1 * nSize2Real, nScale1, ext1[0], ext1[1]));
|
|
ptLowLeft.x += ext1.x;
|
|
}
|
|
else if (nStatus1 == TextParser::kCircleText)
|
|
{
|
|
ptLowLeft.y = 0.0;
|
|
lstTextParts.Append(new TextPart(sWord1, ptLowLeft, GetHeight() * GetPScale()));
|
|
ptLowLeft.x += GetHeight() * GetPScale();
|
|
}
|
|
else
|
|
{
|
|
TextParser parser2(sWord1);
|
|
TextParser::TParserStatus nStatus2;
|
|
TCString sWord2;
|
|
while ((nStatus2 = parser2.GetNext(sWord2, bSplitEAndC)) != TextParser::kEndBuffer)
|
|
{
|
|
double nHeight2 = (nStatus2 == TextParser::kNormalEnglish ? nHeightE : nHeightC);
|
|
double nScale2 = (nStatus2 == TextParser::kNormalEnglish ? nWidthFactorE : nWidthFactorC);
|
|
double nAcadSize =
|
|
nSizeScale * ((bWinFont || nStatus2 == TextParser::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 == TextParser::kLowerText)
|
|
ptLowLeft.y = 0.0; //-nHeight1*nSizeScale;
|
|
else
|
|
ptLowLeft.y = nHeightC * (1.0 - nSizeScale);
|
|
|
|
lstTextParts.Append(new TextPart(sWord2, ptLowLeft,
|
|
nStatus2 == TextParser::kNormalChinese,
|
|
nSizeScale * nHeight2, nAcadSize,
|
|
nScale2, ext2[0], ext2[1]));
|
|
ptLowLeft.x += ext2.x;
|
|
}
|
|
}
|
|
}
|
|
return TRUE;
|
|
}
|
|
|
|
// Properties
|
|
BOOL AecXDbText::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 AecXDbText::GetStyleParam2(double *nHeight, double *nWidthFactor) const
|
|
{
|
|
if (!g_Option::instance().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;
|
|
}
|
|
|
|
ADSGePoint3d AecXDbText::GetLocation() const
|
|
{
|
|
return m_ptText;
|
|
}
|
|
|
|
double AecXDbText::GetRotation() const
|
|
{
|
|
return m_nRotation;
|
|
}
|
|
|
|
double AecXDbText::GetHeight(BOOL bAsPaperUnit) const
|
|
{
|
|
double nVal = m_nHeight;
|
|
if (!bAsPaperUnit)
|
|
nVal *= GetPScale();
|
|
return nVal;
|
|
}
|
|
|
|
Adesk::UInt8
|
|
AecXDbText::GetMaskFlag() const
|
|
{
|
|
return m_nMaskFlag;
|
|
}
|
|
|
|
AcGiDraw::TextAlignment
|
|
AecXDbText::GetAlignment() const
|
|
{
|
|
return m_nAlignment;
|
|
}
|
|
|
|
AcDbObjectId AecXDbText::GetStyleId() const
|
|
{
|
|
return m_idStyle;
|
|
}
|
|
|
|
const TCHAR* AecXDbText::GetText() const
|
|
{
|
|
return (const TCHAR*)m_sText;
|
|
}
|
|
|
|
|
|
void AecXDbText::SetLocation(ADSGePoint3d pt)
|
|
{
|
|
assertWriteEnabled();
|
|
m_ptText = pt;
|
|
}
|
|
|
|
void AecXDbText::SetRotation(double nRot)
|
|
{
|
|
assertWriteEnabled();
|
|
m_nRotation = nRot;
|
|
}
|
|
|
|
void AecXDbText::SetHeight(double nHeight, BOOL bAsPaperUnit)
|
|
{
|
|
assertWriteEnabled();
|
|
m_nHeight = nHeight;
|
|
if (!bAsPaperUnit)
|
|
m_nHeight /= GetPScale();
|
|
}
|
|
|
|
void AecXDbText::SetAlignment(AcGiDraw::TextAlignment nAlign)
|
|
{
|
|
assertWriteEnabled();
|
|
m_nAlignment = nAlign;
|
|
}
|
|
|
|
void AecXDbText::SetStyleId(AcDbObjectId id)
|
|
{
|
|
assertWriteEnabled();
|
|
m_idStyle = id;
|
|
}
|
|
|
|
void AecXDbText::SetText(const TCHAR *pszText)
|
|
{
|
|
assertWriteEnabled();
|
|
m_sText = pszText;
|
|
}
|
|
|
|
void AecXDbText::SetMaskFlag(Adesk::UInt8 nFlag)
|
|
{
|
|
assertWriteEnabled();
|
|
m_nMaskFlag = nFlag;
|
|
}
|
|
|
|
|
|
BOOL AecXDbText::TBaseConvertFrom(const AcDbText *pText)
|
|
{
|
|
return ConvertFrom(pText);
|
|
}
|
|
|
|
AcDbEntity* AecXDbText::TBaseCreateWipeOut()
|
|
{
|
|
return CreateWipeOut();
|
|
}
|
|
|
|
const TCHAR * AecXDbText::TBaseGetText() const
|
|
{
|
|
return (const TCHAR *)GetText();
|
|
}
|
|
|
|
void AecXDbText::TBaseSetText(const TCHAR *pszText)
|
|
{
|
|
SetText(pszText);
|
|
}
|
|
|
|
ADSGePoint3d AecXDbText::TBaseGetLocation() const
|
|
{
|
|
return GetLocation();
|
|
}
|
|
|
|
void AecXDbText::TBaseSetLocation(ADSGePoint3d pt)
|
|
{
|
|
SetLocation(pt);
|
|
}
|
|
|
|
void AecXDbText::TBaseSetRotation(double nRot)
|
|
{
|
|
SetRotation(nRot);
|
|
}
|
|
|
|
double AecXDbText::TBaseGetRotation() const
|
|
{
|
|
return GetRotation();
|
|
}
|
|
|
|
// sg add 101116,支持统一标高
|
|
bool AecXDbText::UnifyElevation(double dElevation)
|
|
{
|
|
assertWriteEnabled();
|
|
m_ptText.z = dElevation;
|
|
return true;
|
|
}
|
|
|
|
SHJson::WValue & AecXDbText::ToJson() const
|
|
{
|
|
return AecXDbEntityBaseEx::ToJson();
|
|
}
|
|
|
|
bool AecXDbText::ByJson(const SHJson::WValue & v)
|
|
{
|
|
return AecXDbEntityBaseEx::ByJson(v);
|
|
}
|