Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/php/240.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Php pdfmark:生成的PDF书签标题中的某些重音字符显示不正确_Php_Pdf_Pdf Generation_Ghostscript - Fatal编程技术网

Php pdfmark:生成的PDF书签标题中的某些重音字符显示不正确

Php pdfmark:生成的PDF书签标题中的某些重音字符显示不正确,php,pdf,pdf-generation,ghostscript,Php,Pdf,Pdf Generation,Ghostscript,我正在将书签插入到现有PDF中,但重音“c”有一些问题。有一个示例(示例中使用的字符集是UTF-8): 问题是重音的č在最终PDF的书签中显示为Ċ(不同重音的大写字母)。我尝试了我的语言(捷克语)中使用的其他口音字符,除了这一个,一切都正常 感谢您提供解决此问题的任何线索 编辑(2013-02-01): 使用的鬼脚本版本为9.06(2012-08-08)。 我正在使用AdobeReader11.0.1查看生成的PDF文件 我还在考虑…它是否必须以某种方式在PDF中指定编码?因为源PDF不在我的控

我正在将书签插入到现有PDF中,但重音“c”有一些问题。有一个示例(示例中使用的字符集是UTF-8):

问题是重音的
č
在最终PDF的书签中显示为
Ċ
(不同重音的大写字母)。我尝试了我的语言(捷克语)中使用的其他口音字符,除了这一个,一切都正常

感谢您提供解决此问题的任何线索

编辑(2013-02-01):

使用的鬼脚本版本为9.06(2012-08-08)。 我正在使用AdobeReader11.0.1查看生成的PDF文件

我还在考虑…它是否必须以某种方式在PDF中指定编码?因为源PDF不在我的控制范围内,我对此一无所知。如果是这样的话,有没有办法使用GS或pdfmark这样做? 我想如果书签的编码是Unicode,那么这真的不重要,但也许我错了

编辑(2013-02-05):


GS的pdfwrite或Acrobat中似乎存在漏洞,更多信息请参阅。解决问题后,我将在此处编写解决方案信息。

下面的代码片段说明了您需要执行的操作

在postscript中,可以使用\000符号访问特殊字符,其中000是字符位置。3位位置为八进制,其中\350等于十进制位置232和十六进制位置E8

你要找的角色是Ccaron和Ccaron。为了能够访问这些字符,您需要在字体编码表中定义它们。CEEncoding表是Adobe的中欧字符集。Postscript可能已经在某个地方定义了CEEncoding,但本例定义了自己的CEEncoding。与本例一样,您可以定义您喜欢的任何编码。网页上提供了postscript语言参考手册,提供了有关可用字符的详细信息

此示例使用standard/Helvetica输出测试1234,然后基于standard/Helvetica定义新字体/Helvetica CE,但使用CEEncoding。(Ru\350ní)show使用CEEncoding定义为ccaron的字符\350。为了好玩,我还将字符\001重新定义为Ccaron,将\002定义为欧元符号,将\003定义为商标符号,以说明任何字符都可以定义为任何字符,并将其输出为(测试4567\001\002\003)显示。并非所有字体都定义了所有符号。不带符号的字体将替换空格字符

就这么简单;)


首先,我将把字符串简化为一个有问题的字符。然后查看pdfmark.txt中的字符串,并查看其UTF-16BE编码是否正确

假设这是正确的,然后尝试从命令行运行Ghostscript,看看是否有效。如果没有,您将能够打开一个bug报告,您可以在提供源文件和命令行

你没有说你正在使用什么版本的Ghostscript,你也没有说你正在使用什么来查看生成的PDF文件。这两种方法都很有用……

因为我可以用不同的方式对字符串进行编码(也可以帮助下载新版本):

$name=“Ručnínářadí”;
$name='FEFF'.strtoupper(bin2hex(iconv('UTF-8','UCS-2BE','str\'u replace(数组('(','),'/')),数组('\(','\\)','\/',$name));
$fh=fopen('pdfmark.txt','w');
fputs($fh,“[/Title/Page 1/OUT pdfmark\n”);
fclose($fh);
$command=“gs-sDEVICE=pdfwrite-dNOPAUSE-dQUIET-dBATCH-sOutputFile=out.pdf final.pdf pdfmark.txt;mv out.pdf final.pdf”;
exec($command);

请注意十六进制格式的编码以及标题定义中不同的括号。

恐怕这并不能真正解决问题。PDF标记字符串不会呈现,也不要使用PostScript规则。在这种情况下,字符串需要在PDFDOCENCODE或UTF-16BE中,这就是(我认为)的内容该脚本旨在生成。感谢您的回答,但这并没有多大帮助。我想避免使用postscript,实际上我对它一无所知:)我使用的代码几乎足以完成我需要完成的任务。只是为了解决这个小问题。出于好奇,试着将$name=“Ručnářadí”更改为$name=“\252Ručnínářadí\372";如果字符串遵循postscript的常规规则,\252和\272会在名称周围加上一个开引号和闭引号,但如果不在postscript规则下,名称将显示文字字符\252。对不起,这根本不起作用。现在整个书签标题不可见/生成。对不起,GS版本是9.06,PDF viewer i在Adobe Reader 11.0.1中,我还更新了我的问题以包含这些信息。还有,“单个冒犯字符”是什么?这是否意味着最好将其从UTF-8转换为单字节编码(如CP1250),然后再转换为UTF-16BE?谢谢。通过使用单个有问题的字符,我的意思是使传递给pdfmark的字符串仅包含一个字符,即导致问题的字符。传递给padfmark的字符串必须是正确编码的UTF-16BE字符串(或PDFDocencode,但这很难)。因此,我建议您查看UTF-16BE字符串并确保其正确,即它指定了您认为应该使用的标志符号。查看pdfmark.txt中的数据,该数据应该是您的UTF-16BE字符串,并查看实际存在的内容,如果不正确,您不能期望最终文件正确。根据ccaron,应为010D,使用UTF-16十六进制,即ch是根据规范在pdfmark.txt文件中正确生成的。从命令行运行GS可以在没有任何警告消息的情况下工作。好的,然后您可以在上打开一个bug,我来看看。请附加所需的文件并引用命令行。好的,bug报告。当我得到一些响应时,我会在这里发布结果。
$name = "Ruční nářadí";

$name = chr(254).chr(255).iconv('UTF-8', 'UTF-16BE', str_replace(array('(',')','/'),array('\\(','\\)','\\/'),$name));

$fh = fopen('pdfmark.txt', 'w');
fputs($fh, "[/Title ({$name}) /Page 1 /OUT pdfmark\n");
fclose($fh);

$command = "gs -sDEVICE=pdfwrite -dNOPAUSE -dQUIET -dBATCH -sOutputFile=out.pdf final.pdf pdfmark.txt; mv out.pdf final.pdf";
exec($command);
/Helvetica findfont 46 scalefont setfont
100 75 moveto
(testing 1234) show
/CEEncoding [
/.notdef /Ccaron /Euro /trademark /.notdef
/.notdef /.notdef /.notdef /.notdef /.notdef
/.notdef /.notdef /.notdef /.notdef /.notdef
/.notdef /.notdef /.notdef /.notdef /.notdef
/.notdef /.notdef /.notdef /.notdef /.notdef
/.notdef /.notdef /.notdef /.notdef /.notdef
/.notdef /.notdef /space /exclam /quotedbl
/numbersign /dollar /percent /ampersand /quoteright
/parenleft /parenright /asterisk /plus /comma
/minus /period /slash /zero /one
/two /three /four /five /six
/seven /eight /nine /colon /semicolon
/less /equal /greater /question /at
/A /B /C /D /E
/F /G /H /I /J
/K /L /M /N /O
/P /Q /R /S /T
/U /V /W /X /Y
/Z /bracketleft /backslash /bracketright /asciicircum
/underscore /quoteleft /a /b /c
/d /e /f /g /h
/i /j /k /l /m
/n /o /p /q /r
/s /t /u /v /w
/x /y /z /braceleft /bar
/braceright /tilde /.notdef /.notdef /.notdef
/.notdef /.notdef /.notdef /.notdef /.notdef
/.notdef /.notdef /.notdef /.notdef /.notdef
/Sacute /.notdef /.notdef /Zacute /.notdef
/.notdef /.notdef /.notdef /.notdef /.notdef
/.notdef /.notdef /.notdef /.notdef /.notdef
/.notdef /sacute /.notdef /.notdef /zacute
/space /.notdef /breve /Lslash /currency
/Aogonek /.notdef /dieresis /.notdef /Scaron
/Scedilla /Tcaron /Zacute /hyphen /Zcaron
/Zdotaccent /degree /aogonek /ogonek /lslash
/acute /lcaron /.notdef /caron /cedilla
/aogonek /scedilla /tcaron /zacute /hungarumlaut
/zcaron /zdotaccent /Racute /Aacute /Acircumflex
/Abreve /Adieresis /Lacute /Cacute /Ccedilla
/Ccaron /Eacute /Eogonek /Edieresis /Ecaron
/Iacute /Icircumflex /Dcaron /Eth /Nacute
/Ncaron /Oacute /Ocircumflex /Ohungarumlaut /Odieresis
/multiply /Rcaron /Uring /Uacute /Uhungarumlaut
/Udieresis /Yacute /Tcedilla /germandbls /racute
/aacute /acircumflex /abreve /adieresis /lacute
/cacute /ccedilla /ccaron /eacute /eogonek
/edieresis /ecaron /iacute /icircumflex /dcaron
/eth /nacute /ncaron /oacute /ocircumflex
/ohungarumlaut /odieresis /divide /rcaron /uring
/uacute /uhungarumlaut /udieresis /yacute /tcedilla
/dotaccent
] def

/Helvetica findfont
dup length dict begin
{ 1 index /FID ne
{def}
{pop pop}
ifelse
} forall
/Encoding CEEncoding def
currentdict
end
/Helvetica-CE exch definefont pop
/Helvetica-CE findfont 36 scalefont setfont
100 100 moveto
(\310\350) show
100 150 moveto 
(Ru\350ní) show
100 200 moveto
(testing 4567\001\002\003) show
 showpage
$name = "Ruční nářadí";

$name = 'FEFF'.strtoupper(bin2hex(iconv('UTF-8', 'UCS-2BE', str_replace(array('(',')','/'),array('\\(','\\)','\\/'),$name))));

$fh = fopen('pdfmark.txt', 'w');
fputs($fh, "[/Title <{$name}> /Page 1 /OUT pdfmark\n");
fclose($fh);

$command = "gs -sDEVICE=pdfwrite -dNOPAUSE -dQUIET -dBATCH -sOutputFile=out.pdf final.pdf pdfmark.txt; mv out.pdf final.pdf";
exec($command);