一 AutoCAD中多行文字的格式设置
AutoCAD在设置多行文字格式时使用了非常特殊的方式,多行文字整体可以有诸多格式属性,比如字高、颜色、旋转角度等等;但是,多行文字的每一个字符其实也可以有自己单独的格式。
比如,下面的多行文字整体是绿色,但是它其中的某一个字却可以是红色。
那么,CAD是怎么实现的呢?我们对这个多行文字执行list命令,执行结果如下:
从中我们可以看出,这个多行文字的内容竟然是:ab{\C1;c}de。这个{}括号括起来的就是字母’c’特有的格式,\C1;说明接下来的这个字符颜色索引为1号。CAD管这个叫做格式代码。我们看看格式代码都有哪些。
CAD就是根据上表的方式,确定了文字格式与格式代码之间的关系。也就是说,AcDbMText实体可以有整体的格式,但是其中每一个字符都可以有自己特定的格式,这个特定的格式由这个字符的格式代码控制。
CAD允许你在外部文字编辑器中输入带格式代码的字符串,这样可以在CAD中生成特定格式的多行文字对象。具体可参见CAD帮助文档“在替换文字编辑器中设置多行文字的格式”。以下是一个示例。
二 ObjectARX如何设置多行文字的格式
我们知道了CAD设置多行文字格式的方式,那么在程序中设置多行文字格式就很简单了。比如说,我们需要让CAD多行文字统一显示为某个颜色,那么我们就应该去掉多行文字内容中所有诸如“\Cxxxx;”之类的格式代码,然后再设置多行文字对象的颜色。
这里额外说一句,千万不要简单的直接设置AcDbMText实体颜色,刚刚我们说过了,对里面单独设置的文字格式,这样设置不起作用。
以下Demo代码可以统一修改一个多行文字实体所有字符的颜色。
//删掉多行文本中表征颜色的格式代码
void RemoveMTextColorField(AcDbMText* pMText)
{
if (!pMText)
return;
TCHAR* psz = pMText->contents();
CString sMText = psz;
delete psz;
if (sMText.GetLength() < 5)
return;
for (int iBegin = 0; iBegin < sMText.GetLength() - 1; iBegin++)
{
//CAD多行文字每个文字都可以拥有格式代码,需要删掉表征颜色的格式代码
if (_T('\\') == sMText[iBegin])
{
if (_T('c') == tolower(sMText[iBegin + 1])) //这是表征颜色的格式代码
{
int iEnd;
for (iEnd = iBegin + 2; iEnd < sMText.GetLength(); iEnd++)
if (_T(';') == sMText[iEnd])
break;
if (iEnd < sMText.GetLength())
{
sMText.Delete(iBegin, iEnd + 1 - iBegin);
iBegin--;
}
else
break;
}
else //排除多行文字字符'\'或者其他以\开头的格式代码
iBegin++;
}
}
pMText->setContents(sMText);
}
void CmdChangeMTextColor(void)
{
Acad::ErrorStatus es;
ads_name ename;
ads_point pt;
if (acedEntSel(_T("\nSelect a MText: "), ename, pt) != RTNORM) return;
AcDbObjectId id = AcDbObjectId::kNull;
acdbGetObjectId(id, ename);
if (id == AcDbObjectId::kNull) return;
AcDbObjectPointer<AcDbMText> pObj(id, AcDb::kForWrite);
if ((es = pObj.openStatus()) != Acad::eOk)
{
if (es == Acad::eNotThatKindOfClass)
{
acutPrintf(_T("\nSelect a MText."));
}
else {
acutPrintf(_T("\nError when opening the entity."));
}
return;
}
int iInput;
if (RTNORM == acedGetInt(_T("\n请输入颜色索引号:"), &iInput))
{
AcDbMText *pMText = AcDbMText::cast(pObj.object());
RemoveMTextColorField(pMText);
pMText->setColorIndex(iInput);
}
}