DWG 用的 SHX 字体是用户可以自己定制的;很多中文 SHX 字体并没有支持全所有中文字符。

那想要知道 SHX 字体里到底都支持哪些字符,可以利用 Teigha 库来提取。

示例代码如下。需要注意的是,字体一定要能找到,否则 getBigFont 返回的会是空指针。

#include <iostream>
#include <set>
#include <string>
#include <codecvt>
#include <OdaCommon.h>
#include <DbDatabase.h>
#include <DbTextStyleTable.h>
#include <DbTextStyleTableRecord.h>
#include <Gi/GiTextStyle.h>
#include <OdCharMapper.h>
#include <ExServices/SimpleServices.h>
using namespace std;

int main()
{
	// 必须把控制台设置成UTF8编码;因为不设置的话,有些特殊字符控制台卡在那里无法输出
	UINT oldcodepage = GetConsoleOutputCP();
	SetConsoleOutputCP(CP_UTF8);

	locale loc(std::locale(""), new std::codecvt_utf8_utf16<wchar_t>());
	wcout.imbue(loc);
	std::locale::global(loc);


	OdStaticRxObject<SimpleServices> svcs;

	try
	{
		odInitialize(&svcs);
		svcs.disableOutput(true);
		svcs.setFontDir(L"e:/cad_fonts_2461");

		OdDbDatabasePtr db = svcs.readFile(OD_T("test.dwg"));
		OdDbTextStyleTablePtr textStyleTable = db->getTextStyleTableId().openObject();
		std::set<OdString> visited;
		for (OdDbSymbolTableIteratorPtr iter = textStyleTable->newIterator(); !iter->done(); iter->step())
		{
			OdDbTextStyleTableRecordPtr record = iter->getRecord();
			OdString filename = record->fileName();
			if (!filename.isEmpty() && visited.count(filename) == 0)
			{
				visited.emplace(filename);

				OdGiTextStyle textStyle;
				giFromDbTextStyle(record, textStyle);
				OdFontPtr font = textStyle.getFont();
				OdCharArray characters;
				font->getAvailableChars(characters);
				wcout << OdUS2W(filename) << endl;
				for (OdChar ch : characters)
				{
					if (ch <= 10)
						continue;
					wcout << (wchar_t)ch;
				}
				wcout << endl;
			}

			filename = record->bigFontFileName();
			if (!filename.isEmpty() && visited.count(filename) == 0)
			{
				visited.emplace(filename);

				OdGiTextStyle textStyle;
				giFromDbTextStyle(record, textStyle);
				OdFontPtr font = textStyle.getBigFont();
				OdCharArray characters;
				font->getAvailableChars(characters);
				wcout << OdUS2W(filename) << endl;
				for (OdChar ch : characters)
				{
					if (ch <= 10)
						continue;

					// 这里取到的 ch 是多字节编码,需要转换成 UNICODE 才能输出。
					OdChar uni;
					OdCharMapper::codepageToUnicode(ch, textStyle.getCodePage(), uni);
					wcout << (wchar_t)uni;
				}
				wcout << endl;
			}
		}
	}
	catch (const OdError& e)
	{
		std::wcout << L"OdError : " << (const wchar_t*)e.description().c_str() << std::endl;
	}

	SetConsoleOutputCP(oldcodepage);

	odUninitialize();

	return 0;
}

发表回复

您的电子邮箱地址不会被公开。