Ghostscript庫中設置FONTPATH不起作用

工作中,需要用ghostscript庫將pdf文件中的非內(nèi)嵌字體全部內(nèi)嵌。先測試一下ghostscript直接處理

gswin64c.exe -o new.pdf -sDEVICE=pdfwrite bad.pdf

GPL Ghostscript 9.56.1 (2022-04-04)
Copyright (C) 2022 Artifex Software, Inc.  All rights reserved.
This software is supplied under the GNU AGPLv3 and comes with NO WARRANTY:
see the file COPYING for details.
Processing pages 1 through 3.
Page 1
Loading font KaiTi (or substitute) from %rom%Resource/Font/NimbusSans-Regular
Loading CIDFont KaiTi (or substitute) from C:/Windows/Fonts/simkai.ttf
Page 2
Page 3

這個源pdf中,有部分KaiTi字體沒有內(nèi)嵌。而Ghostscript因為內(nèi)置字體沒有楷體,用了NimbusSans來替代赘娄,從而導致轉出來的pdf,有部分文字亂碼宏蛉。
為了讓ghostscript可以使用Windows的自帶字體文件遣臼,需要設置FONTPATH指向C:\Windows\Fonts,參考
https://stackoverflow.com/questions/73707930/why-is-ghostscript-replacing-embedded-fonts

gswin64c.exe -o new.pdf -sDEVICE=pdfwrite -sFONTPATH="C:\Windows\Fonts" -dNEWPDF=false bad.pdf

Processing pages 1 through 3.
Page 1
Scanning C:\Windows\Fonts for fonts... 461 files, 269 scanned, 244 new fonts.
Can't find (or can't open) font file %rom%Resource/Font/%rom%.
Can't find (or can't open) font file KaiTi.
Loading KaiTi font from C:\Windows\Fonts/simkai.ttf... 7509676 6105470 22306756 20455617 4 done.
Loading a TT font from C:/Windows/Fonts/simkai.ttf to emulate a CID font KaiTi ... Done.
Page 2
Loading a TT font from C:/Windows/Fonts/simkai.ttf to emulate a CID font KaiTi ... Done.
Can't find (or can't open) font file %rom%Resource/Font/%rom%.
Can't find (or can't open) font file KaiTi.
Loading KaiTi font from C:\Windows\Fonts/simkai.ttf... 9374496 6674894 23208168 21339269 4 done.
Page 3

如果不加 -dNEWPDF=false拾并,雖然顯示可以加載出C:\Windows\Fonts/simkai.ttf揍堰,但是轉換出來的pdf還是有亂碼。Ghostscript的作者解釋到這是9.56.1的bug(實測10.00.0還是有bug辟灰,10.02.0就修復了)
https://stackoverflow.com/questions/72657607/how-to-use-fonts-from-window-fonts-folder-for-a-pdf-in-ghostscript

回到正題个榕。在工作中,是調用ghostscript.dll來完成pdf文件處理的芥喇,按道理把命令行試驗通過的參數(shù)全部傳一遍進 gsapi_init_with_args 就完事了西采。

    gs_argv[0] = "gs";
    gs_argv[1] = "-o";
    gs_argv[2] = "new.pdf";
    gs_argv[3] = "-sDEVICE=pdfwrite";
    gs_argv[4] = "-sFONTPATH=\"C:/Windows/Fonts\"";
    gs_argv[5] = "-dNEWPDF=false";
    gs_argv[6] = inputFile;

    code = f_gsapi_init_with_args(gs_inst, 7, gs_argv);

但是,實際運行卻不行

Processing pages 1 through 3.
Page 1
Scanning "C:/Windows/Fonts" for fonts... 0 files, 0 scanned, 0 new fonts.
Querying operating system for font files...
Substituting font Helvetica for KaiTi.
Loading NimbusSans-Regular font from %rom%Resource/Font/NimbusSans-Regular... 4916440 3557620 7087640 5585527 4 done.
Loading a TT font from C:/Windows/Fonts/simkai.ttf to emulate a CID font KaiTi ... Done.
Page 2
Loading a TT font from C:/Windows/Fonts/simkai.ttf to emulate a CID font KaiTi ... Done.
Substituting font Helvetica for KaiTi.
Page 3

從 C:/Windows/Fonts 目錄中沒有掃描出來字體文件继控!開始以為是調用 ghostscript.dll 流程不對械馆,導致比gswin64c命令行少執(zhí)行了些初始化操作。于是下載了ghostscript的源代碼武通,認真看了 gswin64c 命令行的執(zhí)行過程霹崎,位于 ghostscript-9.56.1\psi\dwmainc.c。我的程序是少調用了 psapi_set_arg_encoding冶忱、gsapi_set_stdio尾菇、gsapi_run_string等動作。但是把這些動作補全囚枪,依然是讀取不到字庫文件派诬。繼續(xù)搜索代碼,發(fā)現(xiàn) Scanning "C:/Windows/Fonts" for fonts 這行打印語句链沼,是 Resource\Init\gs_fonts.ps 這個postscript腳本打印出來的默赂,要想調試ps腳本比調試c代碼難多了。調試了好一會的初始化c代碼括勺,也沒有發(fā)現(xiàn)什么端倪缆八。

后來又想到曲掰,要能夠讀取"C:/Windows/Fonts"目錄中的字體文件,肯定需要給這個目錄賦予讀權限奈辰。dll層賦予目錄權限的api是 gsapi_add_control_path栏妖,根據(jù)代碼一層層跟蹤,最后實際運行函數(shù)是 gs_add_control_path_len_flags()冯挎。在這里打了一個斷點底哥,觀察傳進來的 path 參數(shù)咙鞍。這個函數(shù)被調用20來次之后房官,終于傳進來 C:/Windows/Fonts 目錄名。對于命令行 gswin64c.exe 续滋,傳過來的目錄名是對的翰守。但是對于我通過 gsapi_init_with_args 的調用,傳過來的目錄名變成了 "C:/Windows/Fonts"疲酌,前后多了雙引號@濉(其實如果認真一點地對比命令行中的輸出,應該也可以發(fā)現(xiàn)這個差異)

繼續(xù)跟蹤朗恳,可以發(fā)現(xiàn)湿颅,命令行中的 -sFONTPATH="C:\Windows\Fonts",傳到wmain函數(shù)時粥诫,argv中得到的已經(jīng)是 -sFONTPATH=C:\Windows\Fonts油航,windows的命令行在解析命令行參數(shù)的時候,已經(jīng)把雙引號去掉了怀浆。但如果我們直接傳 -sFONTPATH="C:\Windows\Fonts" 給gsapi_init_with_args谊囚,這個雙引號原封保留帶了過去,從而導致了postscript中看到的FONTPATH參數(shù)帶了雙引號

?著作權歸作者所有,轉載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末执赡,一起剝皮案震驚了整個濱河市镰踏,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌沙合,老刑警劉巖奠伪,帶你破解...
    沈念sama閱讀 221,695評論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異首懈,居然都是意外死亡绊率,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,569評論 3 399
  • 文/潘曉璐 我一進店門猜拾,熙熙樓的掌柜王于貴愁眉苦臉地迎上來即舌,“玉大人,你說我怎么就攤上這事挎袜⊥缒簦” “怎么了肥惭?”我有些...
    開封第一講書人閱讀 168,130評論 0 360
  • 文/不壞的土叔 我叫張陵,是天一觀的道長紊搪。 經(jīng)常有香客問我蜜葱,道長,這世上最難降的妖魔是什么耀石? 我笑而不...
    開封第一講書人閱讀 59,648評論 1 297
  • 正文 為了忘掉前任牵囤,我火速辦了婚禮,結果婚禮上滞伟,老公的妹妹穿的比我還像新娘揭鳞。我一直安慰自己,他們只是感情好梆奈,可當我...
    茶點故事閱讀 68,655評論 6 397
  • 文/花漫 我一把揭開白布野崇。 她就那樣靜靜地躺著,像睡著了一般亩钟。 火紅的嫁衣襯著肌膚如雪乓梨。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 52,268評論 1 309
  • 那天清酥,我揣著相機與錄音扶镀,去河邊找鬼。 笑死焰轻,一個胖子當著我的面吹牛臭觉,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播鹦马,決...
    沈念sama閱讀 40,835評論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼胧谈,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了荸频?” 一聲冷哼從身側響起菱肖,我...
    開封第一講書人閱讀 39,740評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎旭从,沒想到半個月后稳强,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 46,286評論 1 318
  • 正文 獨居荒郊野嶺守林人離奇死亡和悦,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,375評論 3 340
  • 正文 我和宋清朗相戀三年退疫,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片鸽素。...
    茶點故事閱讀 40,505評論 1 352
  • 序言:一個原本活蹦亂跳的男人離奇死亡褒繁,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出馍忽,到底是詐尸還是另有隱情棒坏,我是刑警寧澤燕差,帶...
    沈念sama閱讀 36,185評論 5 350
  • 正文 年R本政府宣布,位于F島的核電站坝冕,受9級特大地震影響徒探,放射性物質發(fā)生泄漏。R本人自食惡果不足惜喂窟,卻給世界環(huán)境...
    茶點故事閱讀 41,873評論 3 333
  • 文/蒙蒙 一测暗、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧磨澡,春花似錦碗啄、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,357評論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至秩命,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間褒傅,已是汗流浹背弃锐。 一陣腳步聲響...
    開封第一講書人閱讀 33,466評論 1 272
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留殿托,地道東北人霹菊。 一個月前我還...
    沈念sama閱讀 48,921評論 3 376
  • 正文 我出身青樓,卻偏偏與公主長得像支竹,于是被迫代替她去往敵國和親旋廷。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 45,515評論 2 359

推薦閱讀更多精彩內(nèi)容