概述:

使用AutoCAD的过程中,我们常常因为缺失字体而烦恼,本插件就是为了解决这个问题。

插件采用WEB服务器 + CAD插件方式。WEB服务器使用Python编写,部署在百度BAE上;CAD插件使用C++开发,在AutoCAD中使用命令“APPLOAD”加载该插件。

在CAD中打开新的DWG文档后,插件会自动比较DWG文档所需字体以及CAD的Font目录下的字体,如果有缺失字体,则自动到WEB服务器下载;如果有服务器上没有的字体,就悄悄上传到服务器。

下载:

源代码:

https://github.com/Xiongpq/FontCenter

编译源代码需要ObjectARX,请自行下载。

客户端:

http://pan.baidu.com/s/1pJPk6mR

下载客户端后,可以在AutoCAD中,输入“APPLOAD”命令加载相应的Warrentech.FontCenter.Client.arx文件即可加载该插件。请注意AutoCAD不同版本应该加载不同的DLL,例如:AutoCAD 2008 32位,应加载2008_X86文件夹下的DLL。

主要代码:

一、在LoadDwg时添加处理字体代码

客户端使用C++编写,调用AutoCAD的ObjectARX C++ API,在AutoCAD的On_kLoadDwgMsg事件中使用多线程做字体的下载及上传,下面是主要的代码:

    virtual AcRx::AppRetCode On_kLoadDwgMsg(void *pkt){
AcRx::AppRetCode retCode = AcRxArxApp::On_kLoadDwgMsg(pkt); try {
acutPrintf(_T("正在检测该文件字体设置,若有缺失将自动下载...\n")); HANDLE hth1;
unsigned threadID;
FontBLL *fontBLL = new FontBLL();
hth1 = (HANDLE)_beginthreadex(NULL, 0, FontBLL::run, fontBLL, CREATE_SUSPENDED, &threadID); if (hth1 != 0) {
ResumeThread(hth1);
}
}
catch (...) {} return (retCode);
}

二、获取当前DWG文档需要的字体名称

使用ObjectARX接口获取AcDbTextStyleTableIterator,循环这个迭代器,将字体文档的字体名称、大字体名称都加入一个vector<wstring>中,以便后面和Font文件夹中的字体名称进行比较。

注意要对字体名称做一些处理,以及重复性检查,详见源代码。

    Acad::ErrorStatus es;
AcApDocument* pDoc;
AcDbDatabase* pDb;
pDoc = acDocManager->curDocument();
pDb = pDoc->database(); AcDbTextStyleTable* pTextTbl;
AcDbTextStyleTableIterator *pTextIterator;
es = pDb->getTextStyleTable(pTextTbl, AcDb::kForRead);
pTextTbl->newIterator(pTextIterator); //获取迭代器 vector<wstring> fontList;
for (pTextIterator->start(); !pTextIterator->done(); pTextIterator->step()) {
AcDbTextStyleTableRecord *pTextRecord;
es = pTextIterator->getRecord(pTextRecord, AcDb::kForRead); TCHAR* pFontName = NULL;
es = pTextRecord->fileName(pFontName); //获取字体名称
if (es == Acad::eOk) {
AddToFontList(pFontName, fontList);
} es = pTextRecord->bigFontFileName(pFontName); //获取大字体名称
if (es == Acad::eOk) {
AddToFontList(pFontName, fontList);
}
}
pTextTbl->close();

三、获取本地字体列表

获取本地AutoCAD安装目录下Font文件夹下已存在的字体列表。

    vector<wstring> result;
_tfinddata64_t c_file;
intptr_t hFile;
wstring root;
root.append(path); //路径
root.append(L"\\*");
root.append(ext); //扩展名 hFile = _tfindfirst64(root.c_str(), &c_file);
if (hFile == -1)
return result; do {
if (_tcslen(c_file.name) == 1 && c_file.name[0] == _T('.')
|| _tcslen(c_file.name) == 2 && c_file.name[0] == _T('.') && c_file.name[1] == _T('.'))
continue; result.push_back(c_file.name); } while (_tfindnext64(hFile, &c_file) == 0);
_findclose(hFile);

四、下载缺失字体

插件使用curl类库做HTTP请求,到WEB服务器下载需要的文件。服务器上的字体文件全都是ZIP文件,所以下载下来后,需要解压。另外,如果没有下载到需要的字体,则会通过WEB服务器的report_missing_cad_font这个API,报告服务器。

    CURL *curl;
CURLcode res;
FILE *fp;
wstring fullPath = FontBasicPath + L"\\" + fontName + L".zip";
_wfopen_s(&fp, fullPath.c_str(), L"wb"); //创建ZIP文件
if (fp == NULL) {
return false;
}
transform(fontName.begin(), fontName.end(), fontName.begin(), towlower);
bool result = false;
curl = curl_easy_init();
if (curl) {
curl_easy_setopt(curl, CURLOPT_URL, (DownloadCadFontUrl + "/" + WStringToUTF8(fontName.c_str()) + ".zip").c_str());
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write_file_data);
curl_easy_setopt(curl, CURLOPT_WRITEDATA, fp);
res = curl_easy_perform(curl); //请求服务器
if (CURLE_OK == res) {
fclose(fp); char *ct;
res = curl_easy_getinfo(curl, CURLINFO_CONTENT_TYPE, &ct);
if ((CURLE_OK == res) && ct) {
std::string contentType(ct);
curl_easy_cleanup(curl);
if (contentType == "application/zip") { //判断下载文件的类型
result = true; //如果不是"application/zip"类型,就说明服务器上也没有这个字体
}
else {
CURL *reportCurl;
reportCurl = curl_easy_init();
curl_easy_setopt(reportCurl, CURLOPT_URL, ReportMissingCadFontUrl.c_str());
string postData = "keyword=" + WStringToUTF8(fontName.c_str());
curl_easy_setopt(reportCurl, CURLOPT_POSTFIELDS, postData.c_str());
res = curl_easy_perform(reportCurl);
curl_easy_cleanup(reportCurl);
}
}
}
}

五、上传客户端字体到服务器

服务器端虽然预置了2000多种AutoCAD字体,但仍然不是最全面的,所以如果客户端存在服务器端没有的字体,插件就会上传该字体到服务器。

首先,将本地字体名称列表POST到服务器,服务器会比较服务器上的字体列表,并将需要上传的字体列表通过JSON数据返回。

然后,客户端收到字体列表后,将需要上传的字体压缩打包,通过WEB API上传到服务器端。

bool upload_file(const wstring path)
{
CURL *curl;
CURLcode res;
struct curl_httppost *formpost = NULL;
struct curl_httppost *lastptr = NULL; curl_formadd(&formpost,
&lastptr,
CURLFORM_PTRNAME, "file",
CURLFORM_FILE, WStringToString(path).c_str(),
CURLFORM_END);
curl = curl_easy_init();
if (curl) {
curl_easy_setopt(curl, CURLOPT_URL, UploadCadFontUrl.c_str());
curl_easy_setopt(curl, CURLOPT_HTTPPOST, formpost);
res = curl_easy_perform(curl);
curl_easy_cleanup(curl); _wremove(path.c_str());
return true;
} _wremove(path.c_str());
return false;
}

AutoCAD 自动管理字体插件[使用ObjectARX C++]的更多相关文章

  1. AutoCAD神器! AutoCAD自动切换中英文输入法插件(ZDSRF)

    AutoCAD神器! AutoCAD自动切换中英文输入法插件 (一)功能特点: CAD命令中只能输入英文字符,不能输入中文,在文字编辑.文字输入.尺寸编辑中经常需要输入中文,此时就需要频繁的切换输入法 ...

  2. CentOS 7下的Vim自动补齐插件YouCompleteMe安装及配置

    备注:现在对于 YouCompleteMe 的安装应采用更为简单的方法,即利用 Vundle 来安装这个插件.具体方法可见: Vundle 主页 YouCompleteMe 主页 而 .vimrc 的 ...

  3. vim自动补全插件YouCompleteMe

    前言 Valloric/YouCompleteMe可以说是vim安装最复杂的插件之一,但是一旦装好,却又是非常好用的.YouCompleteMe简称ycm 在安装折腾的过程中,我再一次的体会到,除了官 ...

  4. VIM自动补全插件 - YouCompleteMe--"大神级vim补全插件"

    VIM自动补全插件 - YouCompleteMe 序言 vim 之所以被称为编辑器之神多半归功于其丰富的可DIY的灵活插件功能,( 例如vim下的这款神级般的代码补全插件YouCompleteMe) ...

  5. 使用pathogen管理Vim插件并托管到Github

    参照文章[1][2]的办法,将vim打造成一个Python开发环境.文章中使用的是 pathogen + git 来管理 Vim 插件的.对这种方式还不太明白的同学可以参考[3]中的介绍.pathog ...

  6. Grunt :任务自动管理工具

    来自<JavaScript 标准参考教程(alpha)>,by 阮一峰 在Javascript的开发过程中,经常会遇到一些重复性的任务,比如合并文件.压缩代码.检查语法错误.将Sass代码 ...

  7. 转:Grunt:任务自动管理工具

    Grunt:任务自动管理工具 来自<JavaScript 标准参考教程(alpha)>,by 阮一峰 目录 安装 命令脚本文件Gruntfile.js Gruntfile.js实例:gru ...

  8. 会跳高的字体插件jquery.beattext.js

    插件描述:字体特效,会弹跳的字体插件jquery.beattext.js,兼容性如下: 使用方法 导入如下3个js文件: <script type="text/javascript&q ...

  9. 使用Vundle管理Vim插件

    附:仓库地址 附:我自用的vim配置文件,里面注释很多,仅供参考. Vundle是一款Vim的插件管理软件(Linux),用起来很方便的原因有几点: 支持插件超多,可以来源于github.Vundle ...

随机推荐

  1. BUAA OO 2019 第二单元作业总结

    目录 总 架构 controller model view 优化算法 Look 算法 多种算法取优 预测未来 多线程 第五次作业 第六次作业 第七次作业 代码静态分析 UML 类图 类复杂度 类总代码 ...

  2. Eclipse操作Servlet入门案例,创建类无法实现Servlet接口和继承HttpServlet类

    问题描述: 从昨天下午到今天中午,这个问题被缠绕了良久.百度了很多,却都没有一言命中要害. 首先,还是基于对Web的理解. 第一:建立的是Dynamic  Web   Project: 第二:然后需要 ...

  3. Angular7教程-02-Angular项目目录及基本文件说明

    本教程基于Angular7,更新时间2018-11-05. 1. 项目根目录如下: e2e文件夹:end to end,测试目录,主要用于集成测试. node_modules:项目的模块依赖目录. s ...

  4. Extjs6 编写自己的富文本组件(以ueditor为基础)

    一.下载ueditor 地址:http://ueditor.baidu.com/website/ 二.将ueitor资源引入自己的项目 在index.html中引入ueditor.config.js. ...

  5. 执行 sql 报错未缓冲查询,错误码 2014

    sql语句为 SELECT COUNT(id) AS tp_count FROM `tableName` WHERE `status` = 0 AND `source` = 1 AND ( `end_ ...

  6. macOS,安装+配置+激活:MySQL8.0 + Navicat Premium12

    作者的电脑是10.13.3,些许配置偏差请自行略过 本文是学习探讨途径,请勿滥用,后果自负 MySQL8.0 篇章 官网http://www.mysql.com/downloads/ 下载即可,无需激 ...

  7. (转载)SendKeys.Send()的使用

    SendKeys.Send() 使用SendKeys将键击和组合键击发送到活动应用程序.此类无法实例化.若要发送一个键击给某个类并立即继续程序流,请使用Send.若要等待键击启动的任何进程,请使用Se ...

  8. HAProxy负载均衡策略

    HAProxy是一个使用C语言编写的自由及开放源代码软件,其提供高可用性.负载均衡,以及基于TCP和HTTP的应用程序代理.HAProxy是支持虚拟主机的,HAProxy的优点能够补充Nginx的一些 ...

  9. 搭建php服务器网站

    一.Apache安装 yum install httpd启动systemctl start httpd.service #启动systemctl stop httpd.service #停止syste ...

  10. PhpStorm 克隆下来的项目改动,版本控制不起效果

    打开的目录 —>多个 git项目—>版本控制无法监控. 打开的目录 —>一个 git项目—>版本控制可以监控.