[原]lpr成功打印中文

本文接上篇《cups-pdf編譯安裝》绝葡,內(nèi)容都為本身根據(jù)項目經(jīng)驗總結(jié),可以轉(zhuǎn)載但請注明出處两波。作者簡書id: weogkoii

開發(fā)環(huán)境:

Linux 4.4.0-31-generic #50~14.04.1-Ubuntu SMP Wed Jul 13 01:07:32 UTC 2016 x86_64 x86_64 x86_64 GNU/Linux

CUPS及周邊安裝請參考前篇:《CUPS-PDF編譯安裝》

http://www.reibang.com/p/4e9b15fe9386

1. lp和lpr命令簡介

這兩個命令都是CUPS系統(tǒng)自帶的打印命令,為了兼容老系統(tǒng)而保留下來的,也是使用起來最方便的哲虾。但是,在中文打印時經(jīng)常出現(xiàn)亂碼择示。命令參考:

https://www.cups.org/doc/man-lp.html

https://www.cups.org/doc/man-lpr.html

已安裝好的cups-pdf打印機:

#lpstat -a

cups-pdf 自從 2019年08月02日 星期五 09時13分34秒 開始接受請求

基本用法:

lpr [-P 打印機] [-#? 打印份數(shù)] -U [用戶名] file

lpr -P cups-pdf /tmp/3333.txt

lp [-d 打印機] [-n 打印份數(shù)] file

lp -d cups-pdf /tmp/3333.txt

2. lpr命令打印中文txt文檔

使用vim隨意編輯一個中文txt文檔束凑,內(nèi)容如下:

#cat /tmp/ChinesePrintTest.txt

一須abc是口

調(diào)用lpr或lp使用cups-pdf進行打印,得到pdf文件卻是亂碼:

lpr -P cups-pdf /tmp/ChinesePrintTest.txt

期望的”一須abc是口“沒有出現(xiàn)栅盲,而是用空白方框代替了4個中文字符汪诉,只剩余中間的abc正常打印出來。



3. 解決亂碼調(diào)試分析過程

初步分析谈秫,生成的pdf文檔中只有位置中間的abc正常打印了扒寄,中文字符均為空白,有可能是不支持中文字符打印拟烫。于是上網(wǎng)google百度了很久该编,發(fā)現(xiàn)竟然都說lp/lpr命令不支持中文,要打印pdf的話硕淑,最好是用圖形化Linux的軟件课竣。但是我有點不甘心嘉赎,因為cups的文檔中并未說明不支持中文,而且現(xiàn)在utf8格式都這么多年了于樟,這些命令也應(yīng)該與時俱進了吧公条。反正是編譯安裝的,索性自己看日志看代碼嘗試解決迂曲。

3.1 首先分析cups日志

查看/var/log/cups/error_log靶橱,本次打印是把txt文檔轉(zhuǎn)換成pdf文檔,一共使用4個filters路捧,分別是texttopdf关霸、pdftopdf、pdftops杰扫、cups-pdf谒拴,4個filter的作用分別如日志所描述:

[Job 124] 4 filters for job:

[Job 124] texttopdf (text/plain to application/pdf, cost 32)

[Job 124] pdftopdf (application/pdf to application/vnd.cups-pdf, cost 66)

[Job 124] pdftops (application/vnd.cups-pdf to application/vnd.cups-postscript, cost 100)

[Job 124] - (application/vnd.cups-postscript to printer/cups-pdf, cost 0)

由于texttopdf是cups-filters項目編譯而來的,所以直接查看相應(yīng)代碼涉波。接下來模擬cups調(diào)用texttopdf(如果不熟悉這部分英上,可以去查看相關(guān)cups filters的原理文檔)。從error_log中獲取調(diào)用texttopdf的參數(shù):

[Job 124] argv[0]="cups-pdf"

[Job 124] argv[1]="124"

[Job 124] argv[2]="root"

[Job 124] argv[3]="ChinesePrintTest.txt"

[Job 124] argv[4]="1"

[Job 124] argv[5]="finishings=3 number-up=1 job-uuid=urn:uuid:431814bd-dd50-3e6b-6fbc-ae490d3763a9 job-originating-host-name=localhost date-time-at-creati? ? on= date-time-at-processing= time-at-creation=1564970267 time-at-processing=1564970267 document-name-supplied=ChinesePrintTest.txt"

[Job 124] argv[6]="/var/spool/cups/d00124-001"

環(huán)境變量:

[Job 124] envp[0]="CUPS_CACHEDIR=/var/cache/cups"

[Job 124] envp[1]="CUPS_DATADIR=/usr/share/cups"

[Job 124] envp[2]="CUPS_DOCROOT=/usr/share/doc/cups"

[Job 124] envp[3]="CUPS_FONTPATH=/usr/share/cups/fonts"

[Job 124] envp[4]="CUPS_REQUESTROOT=/var/spool/cups"

[Job 124] envp[5]="CUPS_SERVERBIN=/usr/lib/cups"

[Job 124] envp[6]="CUPS_SERVERROOT=/etc/cups"

[Job 124] envp[7]="CUPS_STATEDIR=/var/run/cups"

[Job 124] envp[8]="HOME=/var/spool/cups/tmp"

[Job 124] envp[9]="PATH=/usr/lib/cups/filter:/usr/bin:/usr/sbin:/bin:/usr/bin"

[Job 124] envp[10]="SERVER_ADMIN=root@ximi"

[Job 124] envp[11]="SOFTWARE=CUPS/2.2.9"

[Job 124] envp[12]="TMPDIR=/var/spool/cups/tmp"

[Job 124] envp[13]="USER=root"

[Job 124] envp[14]="CUPS_MAX_MESSAGE=2047"

[Job 124] envp[15]="CUPS_SERVER=/var/run/cups/cups.sock"

[Job 124] envp[16]="CUPS_ENCRYPTION=IfRequested"

[Job 124] envp[17]="IPP_PORT=631"

[Job 124] envp[18]="CHARSET=utf-8"

[Job 124] envp[19]="LANG=zh_CN.UTF-8"

[Job 124] envp[20]="PPD=/etc/cups/ppd/cups-pdf.ppd"

[Job 124] envp[21]="RIP_MAX_CACHE=128m"

[Job 124] envp[22]="CONTENT_TYPE=text/plain"

[Job 124] envp[23]="DEVICE_URI=cups-pdf:/"

[Job 124] envp[24]="PRINTER_INFO=cups-pdf"

[Job 124] envp[25]="PRINTER_LOCATION="

[Job 124] envp[26]="PRINTER=cups-pdf"

[Job 124] envp[27]="PRINTER_STATE_REASONS=none"

[Job 124] envp[28]="CUPS_FILETYPE=document"

[Job 124] envp[29]="FINAL_CONTENT_TYPE=application/vnd.cups-postscript"

[Job 124] envp[30]="AUTH_I****"

3.2 使用shell腳本模擬cups調(diào)用texttopdf啤覆,將stdout重寫向到文件中苍日,這個文件中就包括轉(zhuǎn)換的pdf格式文件。查看其中內(nèi)容:

? 6 stream

? 7 q

? 8 0 g

? 9 BT

10? 18 745.884 Td

11? 105.522 Tz

12? /FN02 11.333 Tf <00000000> Tj

13 ET

14 0 g

15 BT

16? 46.800 745.884 Td

17? 105.522 Tz

18? /FN00 11.333 Tf <004400450046> Tj

19 ET

20 0 g

21 BT

22? 68.400 745.884 Td

23? 105.522 Tz

24? /FN02 11.333 Tf <00000000> Tj

25 ET

26 Q

27 endstream

可以看到在stream中窗声,原本的中文字符變成了<00000000>相恃,只剩余<004400450046>(abc,ASCII碼16進制)笨觅。從這里可以判斷拦耐,應(yīng)該是這一步轉(zhuǎn)換出了問題,原來txt文件中的中文见剩,在生成的pdf格式文件中已經(jīng)被0000所代替了杀糯。找到了問題點,再繼續(xù)分析出問題的原因苍苞。

3.3 查看txt文件格式和編碼

:set ff

fileformat=unix

:set fileencoding

fileencoding=utf-8

經(jīng)過查看固翰,文件格式和編碼都沒有問題

3.4 查看texttopdf源碼

為什么會把中文弄成空格呢?經(jīng)過查看代碼終于是有所發(fā)現(xiàn)羹呵,texttopdf沒有找到中文字體骂际?!為什么呢冈欢,vim都已經(jīng)可以顯示中文字符了歉铝,那為什么texttopdf卻又找不到字體呢?

查看cups-filters的README發(fā)現(xiàn)一點線索:

TEXTTOPDF

=========

This implements a texttopdf filter, and is derived from cups' texttops.

To configure:

-------------

- texttopdf uses CUPS_DATADIR/charset/pdf.utf-8 for font configuration

? (when utf-8 was requested as charset). The font names given there are

? used as fontconfig selectors; the best matching font, that is both

? monospaced and in a supported format (TTC, TTF or OTF) will then be used.

- As a special exception, all fontnames that start with a '.' or '/' are

? considered filenames, and fontconfig is skipped; the name is used directly

? for loading the font file.

- Implementation note: TrueType Collections (.TTC) are internally handled

? by appending '/' and the index of the font inside the collection to

? the filename (e.g. to use the second font of uming.ttc, the filename

? uming.ttc/1 must be given to the fontembed-library).

? By appending the index-field returned from fontconfig, this is completely

? transparent to the user (but currently not widely tested).

- You may look at the two examples: pdf.utf-8.simple and pdf.utf-8.heavy.

To use:

-------

The filter is called just like any other cups filter. Have a

look at test.sh for example.

Known Issues

------------

- Text extraction does not work (at least for pdftotext from xpdf)

? for the resulting pdfs.

- OTF(CFF) embedding currently does not subset the fonts.

- Text wrapping in pretty-printing mode does not respect double-wide

? characters (CJK), and thus produce wrong results (wrap too late)

? for lines where they occur.? The fix is not trivial, since all the

? pretty-printing processing is done without knowledge of / prior to

? the font configuration (which is where single or double width

? code-ranges are specified).

- The hebrew example in test5.pdf shows one of our limitations:

? Compose glyphs are not composed with the primary glyph but printed

? as separate glyphs.

原來texttopdf使用CUPS_DATADIR/charset/pdf.utf-8文件配置自身的字體和字符集凑耻,看樣子是這個文件配置不對太示。

3.5 研究pdf.utf-8配置格式

這個配置文件是一段注釋送火,但是說得不是特別清楚,還是根據(jù)代碼反推才搞明白先匪。原來texttopdf是讀取fontconfig字體配置。需要texttopdf中使用的字體都需要在這個配置文件中添加弃衍,相應(yīng)字體才能被加載到texttopdf中正常使用呀非。打開文件一看,果然沒有中文字體:

charset utf8

#

# This file defines the font mappings used for Unicode/UTF-8 text printing

# through PDF.

#

# Each line consists of:

#

#? first last direction width normal bold italic bold-italic

#

# First and last are the first and last glyphs in the font mapping

# that correspond to that font; contrary to PostScript printing

# they only select the font. To find the glyph the complete unicode

# character will be looked up in the (3,1) resp. (3,0) cmap of the

# TrueType font. The glyph values are hexadecimal.

#

# Direction is the string "ltor" or "rtol", indicating left-to-right or

# right-to-left text.

#

# Width is the string "single" or "double"; double means that the glyphs

# are twice as wide as ASCII characters in the Courier typeface.

#

# "Normal", "bold", "italic", and "bold-italic" are the typefaces to use

# for each presentation.? If characters are only available in a single

# style then only one typeface should be listed (e.g. "Symbol")

#

# Each font that is listed will be used (and downloaded if needed) when

# printing.

#

0000 04FF ltor single monospace monospace:bold monospace:oblique monospace:bold:oblique

0500 05FF rtol single monospace

“#”號開頭的都是注釋可以直接跳過镜盯。重點在最后面兩排岸裙,表示utf8編碼范圍使用的對應(yīng)字體。

3.5 fontconfig配置字體

用fc-list查看當(dāng)前已經(jīng)配置字體

/usr/share/fonts/truetype/dejavu/DejaVuSerif-Bold.ttf: DejaVu Serif:style=Bold

/usr/share/fonts/truetype/arphic/uming.ttc: AR PL UMing TW MBE:style=Light

/usr/share/fonts/truetype/dejavu/DejaVuSansMono.ttf: DejaVu Sans Mono:style=Book

/usr/share/fonts/truetype/dejavu/DejaVuSans.ttf: DejaVu Sans:style=Book

/usr/share/fonts/truetype/wqy/wqy-microhei.ttc: 文泉驛微米黑,文泉驛微米黑,WenQuanYi Micro Hei:style=Regular

/usr/share/fonts/truetype/dejavu/DejaVuSans-Bold.ttf: DejaVu Sans:style=Bold

/usr/share/fonts/truetype/dejavu/DejaVuSansMono-Bold.ttf: DejaVu Sans Mono:style=Bold

/usr/share/fonts/truetype/arphic/uming.ttc: AR PL UMing TW:style=Light

/usr/share/fonts/truetype/arphic/uming.ttc: AR PL UMing CN:style=Light

/usr/share/fonts/truetype/arphic/uming.ttc: AR PL UMing HK:style=Light

/usr/share/fonts/truetype/wqy/wqy-microhei.ttc: 文泉驛等寬微米黑,文泉驛等寬微米黑,WenQuanYi Micro Hei Mono:style=Regular

/usr/share/fonts/truetype/dejavu/DejaVuSerif.ttf: DejaVu Serif:style=Book

3.6 修改pdf.utf-8配置文件

參考pdf.utf-8.heavy文件速缆,配置中文字體降允,添加下面一行在配置文件中

3000 9FFF ltor double /usr/share/fonts/truetype/arphic/uming.ttc/0

7. 成功打印中文

再次執(zhí)行打印,查看pdf格式文件:

? 6 stream

? 7 q

? 8 0 g

? 9 BT

10? 18 745.884 Td

11? 127.059 Tz

12? /FN02 11.333 Tf <086149ba> Tj

13 ET

14 0 g

15 BT

16? 46.800 745.884 Td

17? 105.522 Tz

18? /FN00 11.333 Tf <004400450046> Tj

19 ET

20 0 g

21 BT

22? 68.400 745.884 Td

23? 127.059 Tz

24? /FN02 11.333 Tf <1dad0e10> Tj

25 ET

26 Q

27 endstream

這一次艺糜,相應(yīng)的中文編碼不再是0000了剧董,變成實際對應(yīng)的utf-8編碼。再查看打印出來的文件:


終于使用lp/lpr命令成功打印中文了破停!

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末翅楼,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子真慢,更是在濱河造成了極大的恐慌毅臊,老刑警劉巖,帶你破解...
    沈念sama閱讀 218,122評論 6 505
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件黑界,死亡現(xiàn)場離奇詭異管嬉,居然都是意外死亡,警方通過查閱死者的電腦和手機朗鸠,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,070評論 3 395
  • 文/潘曉璐 我一進店門蚯撩,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人烛占,你說我怎么就攤上這事求厕。” “怎么了扰楼?”我有些...
    開封第一講書人閱讀 164,491評論 0 354
  • 文/不壞的土叔 我叫張陵呀癣,是天一觀的道長。 經(jīng)常有香客問我弦赖,道長项栏,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,636評論 1 293
  • 正文 為了忘掉前任蹬竖,我火速辦了婚禮沼沈,結(jié)果婚禮上流酬,老公的妹妹穿的比我還像新娘。我一直安慰自己列另,他們只是感情好芽腾,可當(dāng)我...
    茶點故事閱讀 67,676評論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著页衙,像睡著了一般摊滔。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上店乐,一...
    開封第一講書人閱讀 51,541評論 1 305
  • 那天艰躺,我揣著相機與錄音,去河邊找鬼眨八。 笑死腺兴,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的廉侧。 我是一名探鬼主播页响,決...
    沈念sama閱讀 40,292評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼段誊!你這毒婦竟也來了拘泞?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,211評論 0 276
  • 序言:老撾萬榮一對情侶失蹤枕扫,失蹤者是張志新(化名)和其女友劉穎陪腌,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體烟瞧,經(jīng)...
    沈念sama閱讀 45,655評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡诗鸭,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,846評論 3 336
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了参滴。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片强岸。...
    茶點故事閱讀 39,965評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖砾赔,靈堂內(nèi)的尸體忽然破棺而出蝌箍,到底是詐尸還是另有隱情,我是刑警寧澤暴心,帶...
    沈念sama閱讀 35,684評論 5 347
  • 正文 年R本政府宣布妓盲,位于F島的核電站,受9級特大地震影響专普,放射性物質(zhì)發(fā)生泄漏悯衬。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,295評論 3 329
  • 文/蒙蒙 一檀夹、第九天 我趴在偏房一處隱蔽的房頂上張望筋粗。 院中可真熱鬧策橘,春花似錦、人聲如沸娜亿。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,894評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽买决。三九已至沛婴,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間策州,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,012評論 1 269
  • 我被黑心中介騙來泰國打工宫仗, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留够挂,地道東北人。 一個月前我還...
    沈念sama閱讀 48,126評論 3 370
  • 正文 我出身青樓藕夫,卻偏偏與公主長得像孽糖,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子毅贮,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,914評論 2 355

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