DXF笔记:MText字符串格式的解析

前期研究

  • abc{\W2;abc\W4;abc}
    在这里插入图片描述

  • {\W4;abc\W2;abc}abc
    在这里插入图片描述

  • abc{\W4;abc}abc\Pabc\Pa{\W4;bc\W2;ab\P\W4;abc\P}abcdeg{ab}a{\W4;bc\Pd}

在这里插入图片描述

  • abc\P{\W4;abc\P}abc
    在这里插入图片描述

算法思路

/*
示例:
1.abc{\W2;abc\W4;abc}
2.{\W4;abc\W2;abc}abc
3.abc{\W4;abc}abc\Pabc\Pa{\W4;bc\W2;ab\P\W4;abc\P}abcdeg\{ab\}a{\W4;bc\Pd}
4.abc\P{\W4;abc\P}abc

算法:
	结果数据结构如下:

	行字符串1
		宽高比1-字符串2
		宽高比2-字符串2
		...
	行字符串2
		宽高比1-字符串2
		宽高比2-字符串2
		...
	...


算法思路描述:
	当前宽高比ws = 1.0

	遍历字符串
	IF 出现转义字符:'\',则进入转义逻辑
		'W': 新的宽高比,设置给ws
		'P': 换行
		其他(如'{', '}'等):加入当前字符串
	
	ELSE IF出现’{‘
		宽高比ws将要变化
	ELSE IF出现’}’
		宽高比ws恢复1.0
	ELSE
		字符加入到当前字符串
*/

示例代码

#include <iostream>
#include <memory>
#include <string>
#include <list>
#include <vector>



/*
示例:
1.abc{\W2;abc\W4;abc}
2.{\W4;abc\W2;abc}abc
3.abc{\W4;abc}abc\Pabc\Pa{\W4;bc\W2;ab\P\W4;abc\P}abcdeg\{ab\}a{\W4;bc\Pd}
4.abc\P{\W4;abc\P}abc

算法:
	结果数据结构如下:

	行字符串1
		宽高比1-字符串2
		宽高比2-字符串2
		...
	行字符串2
		宽高比1-字符串2
		宽高比2-字符串2
		...
	...


算法思路描述:
	当前宽高比ws = 1.0

	遍历字符串
	IF 出现转义字符:'\',则进入转义逻辑
		'W': 新的宽高比,设置给ws
		'P': 换行
		其他(如'{', '}'等):加入当前字符串
	
	ELSE IF出现’{‘
		宽高比ws将要变化
	ELSE IF出现’}’
		宽高比ws恢复1.0
	ELSE
		字符加入到当前字符串
*/
typedef std::list<std::pair<double, std::shared_ptr<std::string>>> OneLineText; //一行文本
typedef std::list<std::shared_ptr<OneLineText>> MutiLineText; //多行文本

//倾印多行文本
void DumpMutiLineText(const MutiLineText& mMutiLineText)
{
	for (auto it = mMutiLineText.begin(); it != mMutiLineText.end(); ++it)
	{
		auto pOneLineText = *it;
		if (!pOneLineText) continue;

		std::cout << "一行文本:" << std::endl;
		for (auto itSub = pOneLineText->begin(); itSub != pOneLineText->end(); ++itSub)
		{
			auto pString = itSub->second;
			if (!pString) continue;
			std::cout << "\t" << itSub->first << "  " << pString->c_str() << std::endl;
		}

		std::cout << std::endl;
	}
}

//新行文本
std::shared_ptr<std::string> NewLineText(MutiLineText& mMutiLineText, double dCurWidthScale )
{
	auto pNewString = std::make_shared<std::string>();//当前字符串
	auto pNewLineText = std::make_shared<OneLineText>();
	pNewLineText->push_back(std::pair<double, std::shared_ptr<std::string>>(dCurWidthScale, pNewString));
	mMutiLineText.push_back(pNewLineText);
	return pNewString;
}

//当前行中宽高比变化
std::shared_ptr<std::string> NewWidthScaleAtCurLine(MutiLineText& mMutiLineText, double dCurWidthScale)
{
	if (mMutiLineText.size() == 0)
	{
		return nullptr; //逻辑错误
	}

	//当前行中宽度
	std::shared_ptr<OneLineText> pCurLineText = mMutiLineText.back();
	if (!pCurLineText)
	{
		return nullptr; //逻辑错误
	}

	auto pNewString = std::make_shared<std::string>();//当前字符串
	pCurLineText->push_back(std::pair<double, std::shared_ptr<std::string>>(dCurWidthScale, pNewString));
	return pNewString;
}

//解析MText
void ParseMutiText(const std::string& strMText, MutiLineText& mRtMutiLineText)
{
	int nSize = int(strMText.size());
	int i = 0;
	double dCurWidthScale = 1.0; //当前宽高比

	
	std::shared_ptr<std::string> pCurString = NewLineText(mRtMutiLineText, 1.0);
	while (i < nSize && pCurString )
	{
		char c = strMText.at(i++);
		switch (c)
		{
		case '\\'://出现转义字符,进入转义逻辑
		{
			if (i < nSize)
			{
				char c1 = strMText.at(i++);
				switch (c1)
				{
				case 'W': //新的宽高比
				{
					std::string strWidth;
					while (i < nSize)
					{
						char c2 = strMText.at(i++);
						if (c2 == ';') break;
						strWidth.push_back(c2);
					}
						
					dCurWidthScale = std::stod(strWidth);
					pCurString = NewWidthScaleAtCurLine(mRtMutiLineText, dCurWidthScale);

					break;
				}
				case 'P': //换行
				{
					pCurString = NewLineText(mRtMutiLineText, dCurWidthScale);
					break;
				}
				default://其他(如'{', '}'等):加入当前字符串
				{
					if (pCurString) pCurString->push_back(c1);
					break;
				}
				}
			}
			break;
		}
		case '{'://宽高比ws将要变化
		{
			break;
		}
		case '}'://宽高比ws恢复1.0
		{
			dCurWidthScale = 1.0;
			pCurString = NewWidthScaleAtCurLine(mRtMutiLineText, dCurWidthScale);
			break;
		}
		default://字符加入到当前字符串
		{
			if (pCurString) pCurString->push_back(c);
		}
		}
	}
}



int main()
{
	/*
	1.abc{\W2;abc\W4;abc}
	2.{\W4;abc\W2;abc}abc
	3.abc{\W4;abc}abc\Pabc\Pa{\W4;bc\W2;ab\P\W4;abc\P}abcdeg\{ab\}a{\W4;bc\Pd}
	4.abc\P{\W4;abc\P}abc
	*/

	std::vector<std::string> mMTextArray;
	mMTextArray.push_back("abc{\\W2;abc\\W4;abc}");
	mMTextArray.push_back("{\\W4;abc\\W2;abc}abc");
	mMTextArray.push_back("abc{\\W4;abc}abc\\Pabc\\Pa{\\W4;bc\\W2;ab\\P\\W4;abc\\P}abcdeg\\{ab\\}a{\\W4;bc\\Pd}");
	mMTextArray.push_back("abc\\P{\\W4;abc\\P}abc");

	for (auto it = mMTextArray.begin(); it != mMTextArray.end(); ++it)
	{
		MutiLineText mMutiLineText;
		ParseMutiText(*it, mMutiLineText);
		DumpMutiLineText(mMutiLineText);
		std::cout << "--------------------------------------------" << std::endl;
	}

	return 0;
}



运行结果

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值