gmt-china / GMT_docs

GMT 中文手册
https://docs.gmt-china.org
110 stars 76 forks source link

一种Linux和MacOS下中文支持的通用方案 #973

Closed CovMat closed 1 year ago

CovMat commented 1 year ago

以下的方法也适用于conda安装的gmt和ghostscript

根据 https://www.ghostscript.com/doc/current/Use.htm#Finding_files gs中使用 -I 选项可以指定搜索文件的路径,我们可以手动创建一个cidfmap文件,然后用 -I 指定该文件的路径。这样就可以方便的实现GMT/gs中文支持。

例如,创建一个cidfmap文件(文件名即为cidfmap),文件内容为:

/STSong-Light <</FileType /TrueType /Path (/home/cxh/winfonts/simsun.ttc) /SubfontId 0 /CSI [(GB1) 4] >> ;
/STFangsong-Light <</FileType /TrueType /Path (/home/cxh/winfonts/simfang.ttf) /SubfontId 0 /CSI [(GB1) 4] >> ;
/STHeiti-Regular <</FileType /TrueType /Path (/home/cxh/winfonts/simhei.ttf) /SubfontId 0 /CSI [(GB1) 4] >> ;
/STKaiti-Regular <</FileType /TrueType /Path (/home/cxh/winfonts/simkai.ttf) /SubfontId 0 /CSI [(GB1) 4] >> ;

从Windows系统中拷贝出4个字体的文件 simsun.ttc simfang.ttf simhei.ttf simkai.ttf 把中文字体都放在 /home/cxh/winfonts里面。把cidfmap文件也放在/home/cxh/winfonts里面。

创建GMT中文配置文件 ~/.gmt/PSL_custom_fonts.txt,内容

STSong-Light--UniGB-UTF8-H  0.700    1
STFangsong-Light--UniGB-UTF8-H  0.700    1
STHeiti-Regular--UniGB-UTF8-H   0.700   1
STKaiti-Regular--UniGB-UTF8-H   0.700   1
STSong-Light--UniGB-UTF8-V  0.700    1
STFangsong-Light--UniGB-UTF8-V  0.700    1
STHeiti-Regular--UniGB-UTF8-V   0.700   1
STKaiti-Regular--UniGB-UTF8-V   0.700   1

然后把中文测试脚本修改为:

#!/usr/bin/env bash
gmt begin GMT_Chinese pdf,png
# 添加这一行
gmt set PS_CONVERT="C-I'/home/cxh/winfonts'"

# GMT处理中文存在一些已知BUG
# 需要设置 PS_CHAR_ENCODING 为 Standard+ 以绕过这一BUG
gmt set PS_CHAR_ENCODING Standard+
gmt set FONT_TITLE 25p,41,black
gmt set FONT_LABEL 15p,39,black

gmt text -R0/8/0/4 -JX12c/4c -Bxaf+l"X轴" -Byaf+l"Y轴" -BWSen+t"中文标题" -F+f << EOF
2 3.5 25p,39,black 中文宋体
2 2.5 25p,40,blue  中文仿宋
2 1.5 25p,41,red   中文黑体
2 0.5 25p,42,green 中文楷体
4 3.5 25p,43,black 中文宋体
5 3.5 25p,44,blue  中文仿宋
6 3.5 25p,45,red   中文黑体
7 3.5 25p,46,green 中文楷体
EOF
gmt end

脚本添加 PS_CONVERT 一行即可。 这样gs就会去 -I 的目录里找cidfmap,然后根据cidfmap指定的字体路径去找字体。

以上方法在ubuntu/conda安装的GMT6.4中测试通过。

如果你们认可的话,我提议删除 https://docs.gmt-china.org/latest/chinese/linux/https://docs.gmt-china.org/latest/chinese/macOS/ 的现有内容,改为这种通用方法

@seisman @wangliang1989 @liuzhumei @core-man

ZMAlt commented 1 year ago

macos 12.3 intel. brew 安装的 gmt 6.4。测试不通过,中文字符不显示 macos 12.4 M1. 结果一样不显示

CovMat commented 1 year ago

macos 12.3 intel. brew 安装的 gmt 6.4。测试不通过,中文字符不显示 macos 12.4 M1. 结果一样不显示

最后一行改成gmt end -Vd,看看调试信息,我分析一下

ZMAlt commented 1 year ago
gmt [DEBUG]: GMT_Create_Session: Terminal width = 108
gmt [DEBUG]: Obtained the ppid from parent: 51477
gmt [DEBUG]: Enter: gmtinit_new_GMT_ctrl
gmt [DEBUG]: GMT->session.SHAREDIR = /usr/local/Cellar/gmt/6.4.0/share/gmt
gmt [DEBUG]: GMT->session.HOMEDIR = /Users/zm
gmt [DEBUG]: GMT->session.USERDIR = /Users/zm/.gmt [created]
gmt [DEBUG]: GMT->session.CACHEDIR = /Users/zm/.gmt/cache [created]
gmt [DEBUG]: GMT: 0. Will try to find subdir=postscriptlight stem = PSL_custom_fonts suffix=.txt
gmt [DEBUG]: GMT: 1. gmt_getsharepath trying current dir
gmt [DEBUG]: GMT: 2. gmt_getsharepath trying USERDIR /Users/zm/.gmt
gmt [DEBUG]: Map distance calculation will be Cartesian
gmt [DEBUG]: Exit:  gmtinit_new_GMT_ctrl
gmt [DEBUG]: Enter: New_PSL_Ctrl
gmt [DEBUG]: Exit:  New_PSL_Ctrl
gmt [DEBUG]: Enter: gmt_manage_workflow
gmt [DEBUG]: GMT now running in modern mode [Session ID = 51477]
gmt [DEBUG]: Exit : gmt_manage_workflow
gmt [DEBUG]: Enter: PSL_beginsession
gmt [DEBUG]: Exit : PSL_beginsession
gmt [DEBUG]: Enter: PSL_setdefaults
gmt [DEBUG]: Exit : PSL_setdefaults
gmt [DEBUG]: Enter: gmtlib_io_init
gmt [DEBUG]: Exit : gmtlib_io_init
gmt [DEBUG]: Enter: gmt_hash_init
gmt [DEBUG]: Exit:  gmt_hash_init
gmt [DEBUG]: Enter: gmt_hash_init
gmt [DEBUG]: Exit:  gmt_hash_init
gmt [DEBUG]: Enter: gmt_reload_settings
gmt [DEBUG]: The PROJ_GEODESIC set to Vincenty
gmt [DEBUG]: gmtlib_get_graphics_item: Fig: 0 Subplot: 2 Panel: () Inset: 0
gmt [DEBUG]: Reading GMT Default parameters from file: /Users/zm/.gmt/sessions/gmt_session.51477/gmt.conf
gmt [DEBUG]: Exit:  gmt_reload_settings
gmt [DEBUG]: Enter: gmtlib_plot_C_format
gmt [DEBUG]: Exit:  gmtlib_plot_C_format
gmt [DEBUG]: Enter: gmtinit_get_history
gmt [DEBUG]: gmtlib_get_graphics_item: Fig: 0 Subplot: 2 Panel: () Inset: 0
gmt [DEBUG]: Initialize FFTW with 4 threads.
gmt [DEBUG]: GMT_Create_Session initialized GMT structure
gmt [DEBUG]: Loading core GMT shared library: libgmt.dylib
gmt [DEBUG]: Shared Library # 0 (core). Path = libgmt.dylib
gmt [DEBUG]: Loading GMT plugins from: /usr/local/Cellar/gmt/6.4.0/lib/gmt/plugins
gmt [DEBUG]: Shared Library # 1 (supplements). Path = /usr/local/Cellar/gmt/6.4.0/lib/gmt/plugins/supplements.so
gmt [DEBUG]: GMT now running in modern mode [Session ID = 51477]
gmt [DEBUG]: Use PS filename /Users/zm/.gmt/sessions/gmt_session.51477/gmt_0.ps-
gmt [DEBUG]: gmtinit_get_current_panel: No current panel selected so not in subplot mode
gmt [DEBUG]: Revised options: -R0/8/0/4 -JX12c/4c -Bxaf+lX轴 -Byaf+lY轴 -BWSen+t中文标题 -F+f -Vd
text [DEBUG]: History: Process -R0/8/0/4
text [DEBUG]: History: Process -JX12c/4c
text [INFORMATION]: GMT_Parse_Options: Interval-setting -B options were reordered to appear before axis and frame -B options to ensure proper parsing.
text [INFORMATION]: GMT_Parse_Options: New option order: -R0/8/0/4 -JX12c/4c -F+f -Vd -Bxaf+lX轴 -Byaf+lY轴 -BWSen+t中文标题
text [DEBUG]: Look for file 0/8/0/4 in /Users/zm/.gmt
text [DEBUG]: Look for file 0/8/0/4 in /Users/zm/Desktop/china-geospatial-data-UTF8
text [DEBUG]: Look for file 0/8/0/4 in /Users/zm/.gmt/cache
text [DEBUG]: Look for file 0/8/0/4 in /Users/zm/.gmt/server
text [DEBUG]: Got regular w/e/s/n for region (0/8/0/4)
text [INFORMATION]: Processing input text table data
text [DEBUG]: Reset MAP_ANNOT_OBLIQUE to anywhere
text [DEBUG]: Projected values in meters: 0 8 0 4
text [INFORMATION]: Linear projection implies x-axis distance exaggeration relative to the y-axis by a factor of 0.666667
text [DEBUG]: Computed automatic parameters using dimension scaling: 0.859043
text [DEBUG]: Auto-frame interval for axis 0 item 0: d = 2  f = 1
text [INFORMATION]: Auto-frame interval for x-axis (item 0): a2f1
text [DEBUG]: Auto-frame interval for axis 1 item 0: d = 1  f = 0.2
text [INFORMATION]: Auto-frame interval for y-axis (item 0): a1f0.2
text [INFORMATION]: Map scale is 0.000666667 km per cm or 1:66.6667.
text [DEBUG]: Running in PS mode modern
text [DEBUG]: Use PS filename /Users/zm/.gmt/sessions/gmt_session.51477/gmt_0.ps-
text [DEBUG]: Create hidden PS file /Users/zm/.gmt/sessions/gmt_session.51477/gmt_0.ps-
text [DEBUG]: No figure file /Users/zm/.gmt/sessions/gmt_session.51477/gmt.figures - nothing to do
text [DEBUG]: Got session name as GMT_Chinese and default graphics formats as pdf
text [DEBUG]: Basemap order: Frame = above  Grid = below  Tick/Annot = below
text [DEBUG]: Expects a mixed record with 2 leading numerical columns, followed by 1 text parameters and with trailing text
text [DEBUG]: gmtapi_init_import: Passed family = Data Table and geometry = Volume
text [DEBUG]: gmtapi_init_import: Added 0 new sources
text [DEBUG]: Object ID 0 : Registered Data Table Stream 7ff84c5c46c0 as an Input resource with geometry Volume [n_objects = 1]
text [DEBUG]: gmtapi_init_import: Added stdin to registered sources
text [DEBUG]: GMT_Init_IO: Returned first Input object ID = 0
text [DEBUG]: GMT_Begin_IO: Mode value 1 not considered (ignored)
text [DEBUG]: GMT_Begin_IO: Initialize record-by-record access for Input
text [DEBUG]: gmtapi_next_io_source: Selected object 0
text [INFORMATION]: Reading Data Table from Standard Input stream
text [DEBUG]: GMT_Begin_IO: Input resource access is now enabled [record-by-record]
text [DEBUG]: Source col types: (Number,Number,String)
text [DEBUG]: ASCII source scanned: Numerical columns: 2, Trailing text: Y, Record type: Numerical with trailing text
text [DEBUG]: GMT_End_IO: Input resource access is now disabled
text [DEBUG]: Current size of half-baked PS file /Users/zm/.gmt/sessions/gmt_session.51477/gmt_0.ps- = 24894.
text [INFORMATION]: pstext: Plotted 8 text strings
text [DEBUG]: gmtlib_unregister_io: Unregistering object no 0 [n_objects = 0]
gmt [DEBUG]: Entering GMT_Destroy_Session
gmt [DEBUG]: gmtlib_get_graphics_item: Fig: 0 Subplot: 2 Panel: () Inset: 0
gmt [DEBUG]: GMT_Create_Session: Terminal width = 108
gmt [DEBUG]: Obtained the ppid from parent: 51477
gmt [DEBUG]: Enter: gmtinit_new_GMT_ctrl
gmt [DEBUG]: GMT->session.SHAREDIR = /usr/local/Cellar/gmt/6.4.0/share/gmt
gmt [DEBUG]: GMT->session.HOMEDIR = /Users/zm
gmt [DEBUG]: GMT->session.USERDIR = /Users/zm/.gmt [created]
gmt [DEBUG]: GMT->session.CACHEDIR = /Users/zm/.gmt/cache [created]
gmt [DEBUG]: GMT: 0. Will try to find subdir=postscriptlight stem = PSL_custom_fonts suffix=.txt
gmt [DEBUG]: GMT: 1. gmt_getsharepath trying current dir
gmt [DEBUG]: GMT: 2. gmt_getsharepath trying USERDIR /Users/zm/.gmt
gmt [DEBUG]: Map distance calculation will be Cartesian
gmt [DEBUG]: Exit:  gmtinit_new_GMT_ctrl
gmt [DEBUG]: Enter: New_PSL_Ctrl
gmt [DEBUG]: Exit:  New_PSL_Ctrl
gmt [DEBUG]: Enter: gmt_manage_workflow
gmt [DEBUG]: GMT now running in modern mode [Session ID = 51477]
gmt [DEBUG]: Exit : gmt_manage_workflow
gmt [DEBUG]: Enter: PSL_beginsession
gmt [DEBUG]: Exit : PSL_beginsession
gmt [DEBUG]: Enter: PSL_setdefaults
gmt [DEBUG]: Exit : PSL_setdefaults
gmt [DEBUG]: Enter: gmtlib_io_init
gmt [DEBUG]: Exit : gmtlib_io_init
gmt [DEBUG]: Enter: gmt_hash_init
gmt [DEBUG]: Exit:  gmt_hash_init
gmt [DEBUG]: Enter: gmt_hash_init
gmt [DEBUG]: Exit:  gmt_hash_init
gmt [DEBUG]: Enter: gmt_reload_settings
gmt [DEBUG]: The PROJ_GEODESIC set to Vincenty
gmt [DEBUG]: gmtlib_get_graphics_item: Fig: 0 Subplot: 2 Panel: () Inset: 0
gmt [DEBUG]: Reading GMT Default parameters from file: /Users/zm/.gmt/sessions/gmt_session.51477/gmt.conf
gmt [DEBUG]: Exit:  gmt_reload_settings
gmt [DEBUG]: Enter: gmtlib_plot_C_format
gmt [DEBUG]: Exit:  gmtlib_plot_C_format
gmt [DEBUG]: Enter: gmtinit_get_history
gmt [DEBUG]: gmtlib_get_graphics_item: Fig: 0 Subplot: 2 Panel: () Inset: 0
gmt [DEBUG]: Enter: gmt_hash_init
gmt [DEBUG]: Exit:  gmt_hash_init
gmt [DEBUG]: Exit:  gmtinit_get_history
gmt [DEBUG]: Initialize FFTW with 4 threads.
gmt [DEBUG]: GMT_Create_Session initialized GMT structure
gmt [DEBUG]: Loading core GMT shared library: libgmt.dylib
gmt [DEBUG]: Shared Library # 0 (core). Path = libgmt.dylib
gmt [DEBUG]: Loading GMT plugins from: /usr/local/Cellar/gmt/6.4.0/lib/gmt/plugins
gmt [DEBUG]: Shared Library # 1 (supplements). Path = /usr/local/Cellar/gmt/6.4.0/lib/gmt/plugins/supplements.so
gmt [DEBUG]: GMT now running in modern mode [Session ID = 51477]
gmt [DEBUG]: Revised options: show -Vd
end [DEBUG]: End Workflow.  Session ID = 51477. Directory /Users/zm/.gmt/sessions/gmt_session.51477 removed.
end [DEBUG]: No figure file /Users/zm/.gmt/sessions/gmt_session.51477/gmt.figures - nothing to do
end [DEBUG]: No figure file /Users/zm/.gmt/sessions/gmt_session.51477/gmt.figures - nothing to do
end [DEBUG]: Got session name as GMT_Chinese and default graphics formats as pdf
end [INFORMATION]: Process GMT figure queue: 1 figures found
end [INFORMATION]: Processing GMT figure #0 [GMT_Chinese pdf ]
end [DEBUG]: gmtlib_get_graphics_item: Fig: 0 Subplot: 2 Panel: () Inset: 0
end [DEBUG]: psconvert: '/Users/zm/.gmt/sessions/gmt_session.51477/gmt_0.ps-' -Tf -FGMT_Chinese -C-I/Users/zm/Desktop/winfonts -A
end [DEBUG]: GMT now running in modern mode [Session ID = 51477]
end [DEBUG]: Revised options: '/Users/zm/.gmt/sessions/gmt_session.51477/gmt_0.ps-' -Tf -FGMT_Chinese -C-I/Users/zm/Desktop/winfonts -A
psconvert [DEBUG]: gmt_check_executable: Pass to popen: [gs --version 2> /dev/null]
psconvert [DEBUG]: gs --version 2> /dev/null was successful
psconvert [DEBUG]: Ghostscript version: 9.56.1
psconvert [DEBUG]: Complete partial PS file /Users/zm/.gmt/sessions/gmt_session.51477/gmt_0.ps-
psconvert [DEBUG]: Size of half-baked PS file = 24894.
psconvert [DEBUG]: Fattened up PS file /Users/zm/.gmt/sessions/gmt_session.51477/gmt_0.ps-
psconvert [INFORMATION]: Processing /Users/zm/.gmt/sessions/gmt_session.51477/gmt_0.ps-...
psconvert [INFORMATION]: Find HiResBoundingBox ...
psconvert [DEBUG]: Running: gs -q -dNOSAFER -dNOPAUSE -dBATCH -sDEVICE=bbox -DPSL_no_pagefill -I/Users/zm/Desktop/winfonts -dMaxBitmap=2147483647 -dUseFastColor=true '/Users/zm/.gmt/sessions/gmt_session.51477/gmt_0.ps-' 2> '/Users/zm/.gmt/sessions/gmt_session.51477/psconvert_51484c.bb'
psconvert [INFORMATION]: Figure dimensions: Width: 372.117 points [13.1275 cm]  Height: 176.616 points [6.23062 cm]
psconvert [DEBUG]: Delete /Users/zm/.gmt/sessions/gmt_session.51477/psconvert_51484c.bb
psconvert [INFORMATION]: [2851.74 2850.8 3223.86 3027.42]...
psconvert [INFORMATION]: An unknown psconvert setting was found but since image coordinates seem to be geographical, a linear transformation will be used.
psconvert [INFORMATION]: Convert to PDF...
psconvert [DEBUG]: Running: gs -q -dNOPAUSE -dBATCH -dNOSAFER -dPDFSETTINGS=/prepress -dDownsampleColorImages=false -dDownsampleGrayImages=false -dDownsampleMonoImages=false -dUseFlateCompression=true -dEmbedAllFonts=true -dSubsetFonts=true -dMonoImageFilter=/FlateEncode -dAutoFilterGrayImages=false -dGrayImageFilter=/FlateEncode -dAutoFilterColorImages=false -dColorImageFilter=/FlateEncode -dSCANCONVERTERTYPE=2 -dALLOWPSTRANSPARENCY -I/Users/zm/Desktop/winfonts -dMaxBitmap=2147483647 -dUseFastColor=true -sDEVICE=pdfwrite  -g3722x1767 -r720 -sOutputFile='GMT_Chinese.pdf' '/Users/zm/.gmt/sessions/gmt_session.51477/psconvert_51484d.eps'
psconvert [DEBUG]: Delete /Users/zm/.gmt/sessions/gmt_session.51477/psconvert_51484d.eps
psconvert [DEBUG]: Final input buffer length was 256
end [DEBUG]: GMT now running in modern mode [Session ID = 51477]
end [DEBUG]: Revised options: GMT_Chinese.pdf
docs [DEBUG]: Opening local file(s) via open GMT_Chinese.pdf
end [INFORMATION]: Destroying the current workflow directory /Users/zm/.gmt/sessions/gmt_session.51477
end [DEBUG]: Delete gmt.canvas.0
end [DEBUG]: Delete gmt.conf
end [DEBUG]: Delete gmt.frame.0
end [DEBUG]: Delete gmt.history
end [DEBUG]: Delete gmt.layers.0
end [DEBUG]: Delete gmt.session
end [DEBUG]: Delete gmt_0.ps-
gmt [DEBUG]: Entering GMT_Destroy_Session
gmt [DEBUG]: gmtlib_get_graphics_item: Fig: 0 Subplot: 2 Panel: () Inset: 0
CovMat commented 1 year ago

@ZMAlt 再看看三个信息 winfonts目录的内容截图 cidfmap的内容截图 which gs的结果

ZMAlt commented 1 year ago
image image
CovMat commented 1 year ago

目前来看原因是gs读取了其他地方的cidfmap,我先研究一下怎么让gs打印调试信息

CovMat commented 1 year ago

@ZMAlt 我仔细读了gs的文档,确实是 -I 选项指定cidfmap的位置。我猜测可能是Ubuntu和macOS对路径处理的问题。我把路径加上了单引号,改成了gmt set PS_CONVERT="C-I'/home/cxh/winfonts'" , 麻烦你再试一下加上单引号行不行。如果不行的话,再试试gmt set PS_CONVERT="C-I'/home/cxh/winfonts/'" ,最后补一个斜杆。

ZMAlt commented 1 year ago

@ZMAlt 我仔细读了gs的文档,确实是 -I 选项指定cidfmap的位置。我猜测可能是Ubuntu和macOS对路径处理的问题。我把路径加上了单引号,改成了gmt set PS_CONVERT="C-I'/home/cxh/winfonts'" , 麻烦你再试一下加上单引号行不行。如果不行的话,再试试gmt set PS_CONVERT="C-I'/home/cxh/winfonts/'" ,最后补一个斜杆。

都试了,不行,还是不显示。

C-I那一串能否改成C-sGenericResourceDir=path (来自 QQ)

这里试了,能显示,但是乱码(不过这里的 path 必须补斜杠)

ZMAlt commented 1 year ago

macos 12.3 intel. brew 安装的 gmt 6.4。测试不通过,中文字符不显示 macos 12.4 M1. 结果一样不显示

我的错,pdf 在 mac预览 是不显示中文字符的。同时生成 png 和 pdf 如下,png 没有问题,pdf 会有些错位

GMT_Chinese

image

我建议

  1. 直接在脚本里指定只生成 png 格式。
  2. 自定义字体 似乎也可以删掉,或者合并到这里
CovMat commented 1 year ago

我的看法是PDF错位是阅读器的问题,用adobe 的阅读器估计就没问题

seisman commented 1 year ago

macos 12.3 intel. brew 安装的 gmt 6.4。测试不通过,中文字符不显示 macos 12.4 M1. 结果一样不显示

我的错,pdf 在 mac预览 是不显示中文字符的。同时生成 png 和 pdf 如下,png 没有问题,pdf 会有些错位

GMT_Chinese

image

我在 Intel macOS 12.5.1 下做了测试,分别使用了 Homebrew 和 conda 提供的 gs,跟你的结果都是一致的。明天我再试试 Linux。

我建议

  1. 直接在脚本里指定只生成 png 格式。

我建议还是生成PNG和PDF,但是解释一下PDF中竖排字体可能存在问题。

seisman commented 1 year ago

macos 12.3 intel. brew 安装的 gmt 6.4。测试不通过,中文字符不显示 macos 12.4 M1. 结果一样不显示

我的错,pdf 在 mac预览 是不显示中文字符的。同时生成 png 和 pdf 如下,png 没有问题,pdf 会有些错位

GMT_Chinese

image

我建议

  1. 直接在脚本里指定只生成 png 格式。
  2. 自定义字体 似乎也可以删掉,或者合并到这里

我试了一下,Linux 下用自带的 PDF 阅读器是正常的,所以文件本身应该没有问题,还是 PDF 阅读器自身的问题。