获取 DWG 所用字体支持的所有字符
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; }