cad.net 读写pc3,pmp打印机文件

动图演示

img

简述

有人问avlisp能不能修改打印机纸张大小?

回答:你若能调用解压包,解压pmp即可,若不能,请使用c#,cpp语言,因为这样有人家做好的库.
毕竟我看过有人可以直接操作内存,能做出来也不出奇.

我,青蛙,e大三个人聊天时候意外发现pc3和pmp是个压缩包,我们用txt直接打开了它,发现了一些字符串头说明,
然后e大找到了这个github的工程: https://github.com/phusband/PiaNO

这说明了,修改打印机纸张大小有戏!

然后我做了大量中文函数翻译的工程和几个函数的增设调改...
因为这个歪果仁更新已经过了很久了,
而且中文也不宜和纯英文工程合并,所以我另建了一个工程,
上传了这个项目到gitee,叫做<Acad打印配置解析库>
地址是: https://gitee.com/inspirefunction/PianNoCN
至于我为什么没有想到做成一个nuget包,
因为我最近才想到,但是不想做了...

C库 https://github.com/paolo-caroni/LibrePIA.git

利用pianoCN现在可以读改 PC3/PMP,STB/CTB(打印样式)四种格式的文件.
也可以去这里看看我是怎么打印的: https://www.bilibili.com/video/BV1oA411J7yd/

下面是一步步实现的概念.

打印发布引擎

此项目并不包含打印发布引擎,
也由于我的打印发布引擎上面有很多漏洞,我就不展示给大家了.

可参考kean博客中的这篇,来写自己的打印引擎:
https://through-the-interface.typepad.com/through_the_interface/2007/09/driving-a-multi.html
也可以去明经通道找,
然后通过本文给你的打印机附魔.

需要备注的是:
A: 虽然打印发布引擎是全版本通用的,
但是我是建立Acad2019的(若可能则用最新的Acad).
因为最新的"dwg to pdf.pc3"打印机,
它打印出来的文件比PdfFactory和Acad2008低版本的要清晰和文件小.

B: 打印机高低版本之间有很多差异,
无论是低版本还是高版本我都统一使用了循环发布"单页打印".
(主要因为低版本会出现上页图元跑下页去)

C: 我制作的时候发现不可以用模态对话框,
否则打印预览的时候会卡死.
(这个是我实现成功的方式,可能不一定非模态...)

D: 打印之后是一张一张的pdf,然后调用网上的合并pdf的功能就行.

任意纸张大小的实现概念

首先说明是pc3/pmp是同一种格式,它有个格式头,
导致它并不像Nuget包一样可以用解压软件解压,
但是它本质上就是一个压缩包.(似乎是某种工业标准?)

然后我会根据cad的pc3文件来创建一个pmp文件,
这个过程就是仿照cad内部运行的一个操作.为什么要根据pc3?
因为它有系统纸张,不能丢掉!否则致命错误或者闪退!

甚至我会将此pmp文件新建在cad放置pmp的同文件目录上,
这样可以令cad打印时候直接调用到.

而解压后的pmp文件有点像json,通过文本描述的形式来实现对各类设备参数的描述.

我便可修改pmp中的用户纸张部分,从而创建了一段与图框长高一样的数据.

这个过程颇为复杂,有序列化(解压),文件修改,反序列化(压缩),发布引擎调用...多个部分组成.

序列化(解压)

引用NuGet包

在项目NuGet管理,引用SharpZipLib,人家已经写好的解压包.
我把项目从github在迁移到gitee的时候顺带升级到.net standard工程,它会自动下载包.
所以这里的旧文给.net framework的用户留个印记.

pmp文件修改的注意事项

[pmp]注意事项:
        不能改:
        系统纸张数量
        系统纸张的名称
        只能改:
        系统纸张边界范围,在 mod:description下
        用户纸张的大小,在 udm:添加size,添加description

[pmp]解析: 
    mod:media:size:        本地中文名称和英文名称对照表
    mod:media:description: 是纸张大小和纸张边界的描述--这里就是修改纸张大小
    del:   估计是删除纸张的..
    udm:   用户定义的纸张
    hidden:隐藏纸张,主要作用是手选打印的时候可以不显示那么多纸张. 

[pmp]用户表解析: 
    udm{                     这里就是用户定义的
            size{              中英兑换表
            0{
            caps_type=2
            name="UserDefinedMetric (2222.00 x 2222.00毫米)
            localized_name="用户 1 (2222.00 x 2222.00 毫米)  这里文字可以随便写的
            media_description_name="UserDefinedMetric 横向 2222.00W x 2222.00H - (5, 4) x (2215, 2218) =4896479 毫米
            media_group=15
            landscape_mode=TRUE
            }
            }
            description{     纸张信息表,注意所有的小数点存在
            0{
            caps_type=2
            name="UserDefinedMetric 横向 2222.00W x 2222.00H - (5, 4) x (2215, 2218) =4896479 毫米
            media_bounds_urx=2222.0
            media_bounds_ury=2222.0
            printable_bounds_llx=5.0999999046   //注意所有的小数点必须存在
            printable_bounds_lly=4.0999999046   //注意所有的小数点必须存在
            printable_bounds_urx=2215.8999023   //注意所有的小数点必须存在
            printable_bounds_ury=2218.8999023   //注意所有的小数点必须存在
            printable_area=4896479.8408  
            dimensional=TRUE
            }
    } 
[我的pmp设置]
    我在2019 dwgToPdf打印机先
    恢复了-默认值,再-过滤图纸尺寸,
    然后剩下A0 A1 A2 A3 A4 去掉边界值,这一步就可以手动打印无边了.
    ISO A0 (841.00 x 1189.00 毫米)       建议用
    ISO_expand_A0_(841.00_x_1189.00_MM) 这种cad2008用这种纸张会有边界靠左的问题,2019就没有问题. 

修改纸张的边界偏移的时候,
左推到右:图形会以右边中点进行等比缩放,
下推到上:图形会以上边中点进行等比缩放,
然后此时要重设图形原点.否则图纸是偏的. 

pc3/pmp翻译

Acad2008的

meta{
 关联到PMP的位置        user_defined_model_pathname="
 用户定义的模型库名称  user_defined_model_basename="
 驱动程序路径名      driver_pathname="C:\Program Files (x86)\AutoCAD 2008\drv\gdiplot9.hdi
 驱动程序版本         driver_version="1.1-9.1.51.0
 驱动标签线            driver_tag_line ="Windows 系统驱动程序 - 由 Autodesk 提供
 工具包版本            toolkit_version=1
 驱动程序类型        driver_type=1
 规范家庭名称        canonical_family_name="System
 先显示自定义        show_custom_first=TRUE
 类型是文本           truetype_as_text=TRUE
 规范模型名称        canonical_model_name="System
 本地家庭名称        localized_family_name="系统
 本地模型名称        localized_model_name="系统
 只有文件              file_only=FALSE
 模型能力              model_abilities="555555555055
 UDM描述                udm_description="
 视窗系统设备名称     win_device_name="pdfFactory Pro
 视窗系统设备名称     win_driver_name= "pdfFactory 6
 短的网络名称           short_net_name="pdfFactory Pro
 友好的网络名称        friendly_net_name="FPP6:
 dm驱动程序版本      dm_driver_version=1555
 默认系统配置(猜测是从系统继承打印机)        default_system_cfg=FALSE
 平台 platform ="2,6,1
 地区 locale="4B00409
}
mod{
 media{
  能力                abilities="100004455400144444000005005005000400000000000005000
  状态                caps_state caps="00000
  拥有人              ui_owner="22212222121111212112221
  纸张最大的规格的x   size_max_x=914.40002441 (    0#.3C$ &E@)
  纸张最大的规格的y   size_max_y=1219.2000732 (    X,P,DT 5'@)
  description{
   0{
    caps_type=1
    name="ISO_A4_Portrait_210.00W_x_297.00H_-_(5,_17)_x_(205,_280)_=52600_MM
    media_bounds_urx=210.0
    media_bounds_ury=297.0
    printable_bounds_llx=0.0
    printable_bounds_lly=0.0
    printable_bounds_urx=210.0
    printable_bounds_ury=297.0
    printable_area=62370.0
    dimensional=TRUE
   }
   //其他的都是每个纸张的信息

   1{
    caps_type=1
    name="ISO_A4_Landscape_297.00W_x_210.00H_-_(5,_17)_x_(292,_193)_=50512_MM
    media_bounds_urx=297.0
    media_bounds_ury=210.0
    printable_bounds_llx=0.0
    printable_bounds_lly=0.0
    printable_bounds_urx=297.0
    printable_bounds_ury=210.0
    printable_area=62370.0
    dimensional=TRUE
   }
   2{
    caps_type=1
    name="ISO_A3_Portrait_297.00W_x_420.00H_-_(5,_17)_x_(292,_403)_=110782_MM
    media_bounds_urx=297.0
    media_bounds_ury=420.0
    printable_bounds_llx=0.0
    printable_bounds_lly=0.0
    printable_bounds_urx=297.0
    printable_bounds_ury=420.0
    printable_area=124740.0
    dimensional=TRUE
   }
   3{
    caps_type=1
    name="ISO_A3_Landscape_420.00W_x_297.00H_-_(5,_17)_x_(415,_280)_=107830_MM
    media_bounds_urx=420.0
    media_bounds_ury=297.0
    printable_bounds_llx=0.0
    printable_bounds_lly=0.0
    printable_bounds_urx=420.0
    printable_bounds_ury=297.0
    printable_area=124740.0
    dimensional=TRUE
   }
   4{
    caps_type=1
    name="ISO_A2_Portrait_420.00W_x_594.00H_-_(5,_17)_x_(415,_577)_=229600_MM
    media_bounds_urx=420.0
    media_bounds_ury=594.0
    printable_bounds_llx=0.0
    printable_bounds_lly=0.0
    printable_bounds_urx=420.0
    printable_bounds_ury=594.0
    printable_area=249480.00000 (     $!T#D$:G )
    dimensional=TRUE
   }
   5{
    caps_type=1
    name="ISO_A2_Landscape_594.00W_x_420.00H_-_(5,_17)_x_(589,_403)_=225424_MM
    media_bounds_urx=594.0
    media_bounds_ury=420.0
    printable_bounds_llx=0.0
    printable_bounds_lly=0.0
    printable_bounds_urx=594.0
    printable_bounds_ury=420.0
    printable_area=249480.00000 (     $!T#D$:G )
    dimensional=TRUE
   }
   6{
    caps_type=1
    name="ISO_A1_Portrait_594.00W_x_841.00H_-_(5,_17)_x_(589,_824)_=471288_MM
    media_bounds_urx=594.0
    media_bounds_ury=841.0
    printable_bounds_llx=0.0
    printable_bounds_lly=0.0
    printable_bounds_urx=594.0
    printable_bounds_ury=841.0
    printable_area=499554.00000 (     (A]'D&X?P)
    dimensional=TRUE
   }
   7{
    caps_type=1
    name="ISO_A1_Landscape_841.00W_x_594.00H_-_(5,_17)_x_(836,_577)_=465360_MM
    media_bounds_urx=841.0
    media_bounds_ury=594.0
    printable_bounds_llx=0.0
    printable_bounds_lly=0.0
    printable_bounds_urx=841.0
    printable_bounds_ury=594.0
    printable_area=499554.00000 (     (A]'D&X?P)
    dimensional=TRUE
   }
   8{
    caps_type=1
    name="ISO_expand_A1_Portrait_594.00W_x_841.00H_-_(5,_10)_x_(589,_831)_=479464_MM
    media_bounds_urx=594.0
    media_bounds_ury=841.0
    printable_bounds_llx=0.0
    printable_bounds_lly=0.0
    printable_bounds_urx=594.0
    printable_bounds_ury=841.0
    printable_area=499554.00000 (     (A]'D&X?P)
    dimensional=TRUE
   }
   9{
    caps_type=1
    name="ISO_expand_A1_Landscape_841.00W_x_594.00H_-_(5,_10)_x_(836,_584)_=476994_MM
    media_bounds_urx=841.0
    media_bounds_ury=594.0
    printable_bounds_llx=0.0
    printable_bounds_lly=0.0
    printable_bounds_urx=841.0
    printable_bounds_ury=594.0
    printable_area=499554.00000 (     (A]'D&X?P)
    dimensional=TRUE
   }
   10{
    caps_type=1
    name="ISO_A0_Portrait_841.00W_x_1189.00H_-_(5,_17)_x_(836,_1172)_=959805_MM
    media_bounds_urx=841.0
    media_bounds_ury=1189.0
    printable_bounds_llx=0.0
    printable_bounds_lly=0.0
    printable_bounds_urx=841.0
    printable_bounds_ury=1189.0
    printable_area=999949.00000 (     !J$+D$QEP)
    dimensional=TRUE
   }
   11{
    caps_type=1
    name="ISO_expand_A0_Portrait_841.00W_x_1189.00H_-_(5,_10)_x_(836,_1179)_=971439_MM
    media_bounds_urx=841.0
    media_bounds_ury=1189.0
    printable_bounds_llx=0.0
    printable_bounds_lly=0.0
    printable_bounds_urx=841.0
    printable_bounds_ury=1189.0
    printable_area=999949.00000 (     !J$+D$QEP)
    dimensional=TRUE
   }
  }
 }
}
del{
 media{
  abilities="100004455400144444000005005005000400000000000005000
  caps_state ="00000
  ui_owner="22212222121111212112221
  size_max_x =914.40002441 (    0#.3C$ &E@)
  size_max_y=1219.2000732 (    X,P,DT 5'@)
 }
}
udm{
 calibration{
  _x=1.0
  _y=1.0
 }
 media{
  abilities="100004455400144444000005005005000400000000000005000
  caps_state="00000
  ui_owner="22212222121111212112221
  size_max_x=914.40002441 (    0#.3C$ &E@)
  size_max_y=1219.2000732 (    X,P,DT 5'@)
 }
}
hidden{
 media{
  abilities="04455400144444000005005005000400000000000005000
  caps_state="00000
  ui_owner="22212222121111212112221
  size_max_x=914.40002441 (    0#.3C$ &E@)
  size_max_y=1219.2000732 (    X,P,DT 5'@)
 }
}

Acad2019的

meta{
 关联到PMP的位置     user_defined_model_pathname="G:\K01.惊惊连盒\04.工作小工具\2019dwgToPdf打印机\DWG To PDF.pmp
 用户定义的模型库名称  user_defined_model_basename="
 驱动程序路径名      driver_pathname="C:\Program Files\Autodesk\AutoCAD 2019\drv\pdfplot15.hdi
 驱动程序版本        driver_version="1.1-15.0.61.0 [v018-1] [v018-1]
 驱动标签线          driver_tag_line="PDF ePlot - by Autodesk
 工具包版本          toolkit_version=1
 驱动类型            driver_type=3
 规范家庭名称        canonical_family_name="Autodesk ePlot
 先显示自定义        show_custom_first=FALSE
 以文本形式输入      truetype_as_text=TRUE
 规范模型名称        canonical_model_name="pdf
 本地家庭名称        localized_family_name="Autodesk ePlot (PDF)
 本地模型名称        localized_model_name="DWG To PDF
 是否打印到文件(false就是后台打印?)      file_only=TRUE
 模型能力            model_abilities="000550055000
 udm描述            udm_description="
 短的网络名称         short_net_name="
 友好的网络名称       friendly_net_name="
 dm驱动程序版本       dm_driver_version=0
 默认系统配置(猜测是从系统继承打印机)   default_system_cfg=FALSE
 平台                platform="2,10,0
 地区                locale="4B0040
 配置说明            config_description="
 配置自动线轴        config_autospool=FALSE
}                
  
media{             
 选择方法            selection_method=2
 类型                type="
 dm方向              dm_orientation=1
 实际打印x边界偏移   actual_printable_bounds_llx=0.0
 实际打印y边界偏移   actual_printable_bounds_lly=0.0
 实际打印x边界范围   actual_printable_bounds_urx=210.0
 实际打印y边界范围   actual_printable_bounds_ury=297.0
 份数副本            number_of_copies=1
 
 size{
  name="ISO_A4_(210.00_x_297.00_MM)
  group=4
  情景模式           landscape_mode=FALSE
  长打印_减少        longplot_reduction=1.0
  媒介描述           media_description{
  实际打印x边界偏移  printable_bounds_llx=5.0
  实际打印y边界偏移  printable_bounds_lly=17.0
  实际打印x边界范围  printable_bounds_urx=205.0
  实际打印y边界范围  printable_bounds_ury=280.0
  实际打印面积       printable_area=52600.0
  尺寸的             dimensional=TRUE
  媒介界限           media_bounds{
  纸张范围           urx=210.0
  纸张范围           ury=297.0
   }
  }
 }
}
io{
 type=2
 pathname="
 allsysvalid=FALSE
 plot_to_file=TRUE
}
res_color_mem{
 name="RGB
 num_colors=16777216
 color_depth=24
 num_undithered_colors=16777216
 color_system=1
 dm_color=1
 lines_overwrite=TRUE
 resolution{
  name="Default
  phys_resolution_x=600.0
  phys_resolution_y=600.0
  addr_resolution_x=1.0
  addr_resolution_y=1.0
  effective_resolution_x=600.0
  effective_resolution_y=600.0
 }
}
custom{
 0{
  name="Create_Bookmarks
  value=TRUE
 }
 1{
  name="Thumbnail_Title
  value=TRUE
 }
 2{
  name="Sheet_Links
  value=TRUE
 }
 3{
  name="Rasterize_Geometry
  value=FALSE
 }
 4{
  name="View_New_File
  value=TRUE
 }
 5{
  name="Custom_Raster_Resolution
  value=FALSE
 }
 6{
  name="Custom_DWF_Resolution
  value=FALSE
 }
 7{
  name="Custom_Monochrome_Resolution
  value=FALSE
 }
 8{
  name="Custom_Gradient_Resolution
  value=FALSE
 }
 9{
  name="Gradient_Limit
  value=600
 }
 10{
  name="Monochrome_Raster_Limit
  value=400
 }
 11{
  name="Raster_Limit
  value=400
 }
 12{
  name="All_As_Geometry
  value=FALSE
 }
 13{
  name="Capture
  value=2
 }
 14{
  name="Font_Capture
  value=TRUE
 }
 15{
  name="Hardcopy_Resolution
  value=600
 }
 16{
  name="Include_Layer
  value=TRUE
 }
 17{
  name="Resolution
  value=14
 }
}

代码部分:

创建pmp文件/附着pmp路径到pc3内

using JoinBoxCurrency;
using PiaNO;
using System.IO;

namespace JoinBox.批量打印 {
    public class CreatePMP
    {
        public string Path_pmp { set; get; }
        public string Path_pc3 { set; get; }
        public string Dwgtopdf = "DWG To PDF";
        public string DwgtopdfPC3 = Dwgtopdf + ".PC3";

        /// <summary>
        /// 创建pmp文件
        /// </summary>    
        public CreatePMP()
        {
            // pc3打印机位置
            string plottersPath = CadSystem.Getvar("PrinterConfigDir") + "\\";
            Path_pc3 = plottersPath + DwgtopdfPC3;
            if (!File.Exists(Path_pc3)) return;

            // 驱动位置
            string drvFilePath = "";
            DirectoryInfo theFolder = new(CadSystem.Getvar("ACADDRV"));
            if (!theFolder.Exists) return;
            foreach (FileInfo nextFile in theFolder.GetFiles())
            {
                if (nextFile.Extension.ToUpper() == ".HDI" && nextFile.Name.Contains("pdfplot"))
                {
                    drvFilePath = nextFile.FullName;
                    break;
                }
            }
            
            var pmpfiles = plottersPath + "PMP Files";
            FileTool.NewFolder(pmpfiles);//新建一个文件夹
            var pdfConfig = new PlotterConfiguration(Path_pc3)
            {
                ModelPath = pmpfiles,      
                DriverPath = drvFilePath,  
                TruetypeAsText = true
            };
            var names = new string[] { "media", "io", "res_color_mem", "custom" };
            foreach (var name in names)
            {
                pdfConfig.Remove(name);
            }
            //解压了打印机信息之后,遍历打印机节点  
            foreach (var nodeA in pdfConfig)
            {
                switch (nodeA.NodeName)
                {
                    case "meta":
                        nodeA.Values.Remove("config_description_str");
                        nodeA.Values.Remove("config_autospool");
                        break;
                }
            }
            string str =
                "{\nabilities=\"500005500500505555000005550000000550000500000500000\n" +
                "caps_state=\"000000000000000000000000000000000000000000000000000\n" +
                "ui_owner=\"11111111111111111111110\n" +
                "size_max_x=320000.00000\n" +
                "size_max_y=320000.00000\n}";
            pdfConfig.Add("mod", "").Add("media", str);
            pdfConfig.Add("del", "", true);
            pdfConfig.Add("udm", "", true).Add("media", str);
            pdfConfig.Add("hidden", "", true);
            Path_pmp = pmpfiles + "\\" + Dwgtopdf + ".PMP";
            pdfConfig.Saves(Path_pmp);
        }

        /// <summary>
        /// 附着pmp路径到pc3内
        /// </summary>     
        public void ChangeUserDefinedModel()
        {
            // 获取这个打印机的完整路径 
            var ns = new string[] { Path_pc3, Path_pmp };
            foreach (var path in ns)
            {
                if (!File.Exists(path)) continue;

                var PdfConfig = new PlotterConfiguration(path);
                //解压了打印机信息之后,遍历打印机节点
                foreach (var nodeA in PdfConfig)
                {
                    if (nodeA.NodeName == "meta")
                    {
                        nodeA.ValueChang("user_defined_model_pathname" + "_str", Path_pmp);
                        break;
                    }
                }
                PdfConfig.Saves();
            }
        }

    }
}

添加纸张

public class Printer
{
    // 节点名称-纸张中英兑换表
    public const string str_size = "size";
    // 节点名称-纸张边界信息
    public const string str_description = "description";

    /// <summary>
    /// 打印纸张全球名
    /// </summary>
    public string Name { private set; get; }

    /// <summary>
    /// 打印纸张本地名(中文名)
    /// </summary>
    public string Localized_name => Name.Replace("_", " ").Replace("MM", "毫米");

    /// <summary>
    /// 打印纸张英文名
    /// </summary>
    public string Media_description_name { private set; get; }

    // 偏移量
    double Offset_Left = 0;
    double Offset_Down = 0;
    // 纸张大小
    double PaperX = 0;
    double PaperY = 0;
    PlotterConfiguration PdfConfig;

    /// <summary>
    /// 添加纸张
    /// </summary>
    /// <param name="ext">纸张范围</param>
    /// <param name="offset_Left">左偏移量</param>
    /// <param name="offset_Down">下偏移量</param>
    public Printer(Extents2d ext, double offset_Left = 0, double offset_Down = 0)
    {
        //纸张大小
        var ve2 = ext.MinPoint.GetVectorTo(ext.MaxPoint);
        PaperX = ve2.X;
        PaperY = ve2.Y;
        Offset_Left = offset_Left;
        Offset_Down = offset_Down;
    }

    /// <summary>
    /// 添加纸张
    /// </summary>
    /// <param name="ve2">纸张范围</param>
    /// <param name="offset_Left">偏移量</param>
    /// <param name="offset_Down">偏移量</param>
    public Printer(Vector2d ve2, double offset_Left = 0, double offset_Down = 0) : this(ve2.X, ve2.Y, offset_Left, offset_Down) { }

    /// <summary>
    /// 添加纸张
    /// </summary>
    /// <param name="paperx">纸张横向长度</param>
    /// <param name="papery">纸张纵向高度</param>
    /// <param name="offset_Left">偏移量</param>
    /// <param name="offset_Down">偏移量</param>
    public Printer(double paperx, double papery, double offset_Left = 0, double offset_Down = 0)
    {
        //纸张大小
        PaperX = paperx;
        PaperY = papery;
        Offset_Left = offset_Left;
        Offset_Down = offset_Down;
    }

    /// <summary>
    /// 生成纸张pmp
    /// </summary>
    /// <param name="dwgtopdfpmp">打印机pmp文件路径</param> 
    /// <returns></returns>
    public PlotterConfiguration AddPrinter(string dwgtopdfpmp)
    {
        Name = $"JBS_PDF_({PaperY:#0.00}_x_{PaperX:#0.00}_MM)";
        // JoinBoxStandard 嘻嘻
        //                                                              (5,_17)这个是默认偏移量
        // media_description_name="ISO_A0_Portrait_841.00W_x_1189.00H_-_(5,_17)_x_(836,_1172)_=959805_MM 
        //实际打印面积(虽然因为偏移值是0,等于长乘宽就可以,但是为了日后我忘记这里怎么算的,还是求一下吧)
        double area = (PaperY - (Offset_Left * 2)) * (PaperX - (Offset_Down * 2));
        //如果没有小数点保留,可能cad闪退!
        StringBuilder description_name = new StringBuilder();
        description_name.Append($"JBS_PDF_Portrait_{PaperY:#0.00}W_x_{PaperX:#0.00}H");
        description_name.Append("_-_");
        description_name.Append($"({Offset_Left:#0.00},_{Offset_Down:#0.00})");//偏移量
        description_name.Append("_x_");
        description_name.Append($"({PaperY - Offset_Left:#0.00},_{PaperX - Offset_Down:#0.00})_");
        description_name.Append($"={area:#0.00}_MM");
        Media_description_name = description_name.ToString();
        PdfConfig = new PlotterConfiguration(dwgtopdfpmp)
        {
            TruetypeAsText = true
        };

        //解压了打印机信息之后,遍历打印机节点
        foreach (var nodeA in _PdfConfig)
        {
            if (nodeA.NodeName != "udm")
                continue;

            if (nodeA.Count() == 0)//这个是根据pc3生成pmp使用
                continue;

            foreach (var nodeB in nodeA)
            {
                if (nodeB.NodeName != "media")
                    continue;

                PiaNode piaNode_size = null;
                PiaNode piaNode_description = null;

                //遍历是否有节点
                foreach (PiaNode nodeC in nodeB)
                {
                    switch (nodeC.NodeName)
                    {
                        case str_size:
                            piaNode_size = nodeC;
                            break;
                        case str_description:
                            piaNode_description = nodeC;
                            break;
                    }
                }

                // 找不到就添加节点          
                piaNode_size ??= nodeB.Add(str_size);
                piaNode_description ??= nodeB.Add(str_description);

                // 在节点中添加/修改信息
                AddPaperEnAndCn(piaNode_size);
                AddPaperDescription(piaNode_description);
                break;
            }
            break;
        }

        PdfConfig.Saves();
        return PdfConfig;
    }

    /// <summary>
    /// 添加pmp纸张-中英兑换表
    /// </summary>
    /// <param name="nodeC"></param>
    void AddPaperEnAndCn(PiaNode node)
    {
        //图纸数量+1就是新建一张图   
        string name = node.Count().ToString();
        string[] paper = new string[] {
            name+ "{",
            $"caps_type=2",             //1是系统的,2是用户的.这里严格,可不可以在打印纸看见就是这里了
            $"name=\"{Name}",
            $"localized_name=\"{Localized_name}",
            $"media_description_name=\"{Media_description_name}",
            $"media_group=15",          //4是系统的,15是用户的...网友说15是毫米,16是像素.
            "landscape_mode=TRUE\n}",   //false是系统的,true是用户的
        };
        string paperAll = string.Join("\n ", paper) + '\n';
        PlusNode(node, name, paperAll);
    }

    /// <summary>
    /// 判断是否已有同名节点,有就不加入
    /// </summary>
    /// <param name="node">节点</param>
    /// <param name="name">名称</param>
    /// <param name="paperAll">加入对象</param>
    void PlusNode(PiaNode node, string name, string paperAll)
    {
        bool has = false;
        foreach (var nodeA in node){
            if(nodeA.Values.TryGetValue("media_description_name_str",out var v)
               && v == Media_description_name){
                    has = true;
                    break;
            }
        }
        if (!has)
            node.Add(name, paperAll);
    }
    /// <summary>
    /// 添加pmp纸张-信息
    /// </summary>
    /// <param name="nodeC"></param>
    private void AddPaperDescription(PiaNode nodeC)
    {
        var spl = '\n';
        int count = nodeC.Count();
        string name = count.ToString();
        string[] paper = new string[] {
            name + "{",
            $"caps_type=2",  //1是系统的,2是用户的.这里严格,可不可以在打印纸看见就是这里了
            $"name=\"{Media_description_name}",
            $"media_bounds_urx={LimitDosDecimalPrecision(PaperX)}",
            $"media_bounds_ury={LimitDosDecimalPrecision(PaperY)}",
            $"printable_bounds_llx={LimitDosDecimalPrecision(Offset_Left)}",
            $"printable_bounds_lly={LimitDosDecimalPrecision(Offset_Down)}",
            $"printable_bounds_urx={LimitDosDecimalPrecision(PaperX)}",
            $"printable_bounds_ury={LimitDosDecimalPrecision(PaperY)}",
            $"printable_area={LimitDosDecimalPrecision((_PaperX - 2*_Offset_Left)*(_PaperY - 2*_Offset_Down))}",
            "dimensional=TRUE\n}",
        };
        string paperAll = string.Join(spl + " ", paper) + spl;
        PlusNode(nodeC, name, paperAll);
    }
    /// <summary>
    /// 保证数字在12位内
    /// </summary>
    /// <param name="dos"></param>
    /// <returns></returns>
    string LimitDosDecimalPrecision(double dos)
    {
        var str = string.Format("{0:0.0#########}", dos);
        if (str.Length >= 12)
            str = str.Substring(0, 12);
        return str;
    }  
}

移除纸张

public static class PrinterTool
{
    /// <summary>
    /// 移除纸张
    /// </summary> 
    /// <param name="plot"></param>
    /// <param name="dwgtopdfpmp">pmp名称</param>
    /// <param name="printerNames">要移除的纸张名称</param>
    /// <param name="db">数据库</param>
    /// <param name="tr">事务</param>
    public static void RemovePrinters(this Plot plot, 
        string dwgtopdfpmp, string[] printerNames, 
        Database db, Transaction tr)
    {
        var pdfConfig = new PlotterConfiguration(dwgtopdfpmp)
        {
            TruetypeAsText = true
        };
        pdfConfig.RemovePrinters(printerNames);
        pdfConfig.Saves();

        // 需要刷新一次打印机设备纸张,不然会有残留显示.
        var bt = (BlockTable)tr.GetObject(db.BlockTableId, OpenMode.ForRead, false);
        foreach (ObjectId btrId in bt)
        {
            var btr = (BlockTableRecord)tr.GetObject(btrId, OpenMode.ForRead, false);
            if (!btr.IsLayout) continue; //是布局才进入    
            var layout = (Layout)tr.GetObject(btr.LayoutId, OpenMode.ForRead);
            plot.RefreshLists(new PlotSettings(layout.ModelType));
        }
    }

    /// <summary>
    /// 移除纸张 
    /// </summary> 
    /// <param name="pdfConfig">pmp的解析</param>
    /// <param name="printerNames">要移除的纸张名称</param>
    static void RemovePrinters(this PlotterConfiguration pdfConfig, string[] printerNames)
    {
        //解压了打印机信息之后,遍历打印机节点
        foreach (var nodeA in pdfConfig)
        {
            if (nodeA.NodeName != "udm")
                continue;
            foreach (var nodeB in nodeA)
            {
                if (nodeB.NodeName != "media")
                    continue;

                foreach (PiaNode nodeC in nodeB)
                {
                    switch (nodeC.NodeName)
                    {
                        case Printer.str_size:
                        case Printer.str_description:
                            nodeC.RemoveChildNodes(printerNames);
                            break;
                    }
                }
                break;
            }
            break;
        }
    }
}

后话

最后发现一个问题没有,并不能改系统的纸张.
所以这个系统纸张是哪里改到呢?我们认为是在.hdi这个驱动上面.
啊?打开它的方式?那我怎么知道嘞?

(完)

posted @ 2019-05-22 23:36  惊惊  阅读(8893)  评论(38编辑  收藏  举报