Archive

Posts Tagged ‘chinese’

安装ibus输入法

April 6th, 2009 Fwolf 3 comments

编译太麻烦,直接从ppa的源安装,把下面这句加入/etc/apt/sources.list

	deb http://ppa.launchpad.net/ibus-dev/ppa/ubuntu intrepid main

然后安装就是了,不过ppa的源下载真的好慢啊:

	$ sudo aptitude install ibus ibus-pinyin

装好以后,修改/etc/X11/Xsession.d/95xinput,把原来fcitx的部分注释掉,换成ibus的:

	# ibus
	export GTK_IM_MODULE="ibus"
	export XMODIFIERS="@im=ibus"
	export QT_IM_MODULE="ibus"

然后切换系统的默认输入法:

	$ sudo im-switch -c

最后重启系统,一切ok。

一点感受:

  • 速度比fcitx要慢,但似乎用着反而更舒服了。
  • 没有软键盘,无法输入特殊符号(前提:我用自然码双拼,得切换到全拼下用i开头输入特殊符号,如果有全拼/双拼切换快捷键就好了)。
  • haha xixi rq xq lb sj bsn 这些很贴心啊,呵呵。

选用目前并不一定比fcitx好用的ibus,主要是看中它更新比较频繁,相信问题会不断得到修复,功能也会不断完善的。使用python开发也能够让更多的热心人介入。

Update @ 2009-04-21

如果在firefox等程序里无法实现光标跟随,可以试试装上ibus-gtk, ibus-qt4包,然后重启X。

Related posts

Categories: Linux, Tools Tags: , , , ,

在GLPI中输出中文PDF文件

April 2nd, 2009 Fwolf 2 comments

PDF,好东西,就是麻烦,以前鼓捣ThingkingRock的时候打过交道,感觉挺复杂,现在捣鼓GLPI时又遇到了,GLPI用的是ezpdf。

先说点闲话,有些比较偏门的东西是真难找啊,比如今天要说的,算不上是学术问题,也没有企业级的支持(如果你愿意打电话咨询GLPI官方又懂法语我没话说),只能在网上大海捞针的找,一方面这是很辛苦的,查阅各类资料几十篇(前提还是你得能找到),写下来也就寥寥百余字,所以我一般愿意把我翻到的资料列在后面作为参考,或许能为别人省点力气;另一方面就是搜索引擎的功劳了,记得还没有google和百度的时候,只有一个yahoo分类目录,要搜问题就得到几个大型论坛比如CSDN里去翻,信息量就窄多了,另外搜索引擎的质量在这里也起到了很大的作用,信息重复率高不高、能否最快速度找到原创内容、信息关联度、是否有用等因素都关系到用户花费时间的多少,这也是我很少用百度的原因之一,还有就是感觉百度的英文资料差太多了。────谨以此纪念我几乎24小时的连续工作以及疲惫的眼睛和脖子。

EZPDF

EZPDF一般是不支持unicode多字节编码的,不过还是作了一些尝试,毕竟是GLPI内置的,搞定了用着方便。首先EZPDF使用afm字体,要得到afm字体,需要用到ttf2tex,在pdfTeX包里:

	$ aptitude install ttf2tex

转换字体,这次我不用宋体了,用于打印的,还是仿宋看着舒服,用了个方正仿宋简体:

	$ ttf2afm -e T1-WGL4.enc -o fzfangsong.afm fzfangsong.TTF

试了试不能用,然后用afm2font处理:

	$ php5 afm2font.php fzfangsong

得到php_fzfangsong.font等文件,但这些文件无论怎么套上ezpdf都是不行,什么文字都没了,pdf文件中倒是显示了正确的字体名:

fzfangsong
Type1
Not embedded

再在网上翻资料,简直就是钻到TeX用户堆儿里去了,忽然发现windows字体应该是TrueType字体,而ezpdf使用的难道是Type1字体,两者之间还需要转换?终于查到基于texlive2008的中文绿色免安装tex系统中有打包的字体,这里面有给TeX用的Type1字体,就是大了点,“dottexlive2008.tar.bz2 仅包含全部字体包和相关宏包”一共是685M,拉下来,好在网速还算很快。把里面的afm字体单独解压出来:

	$ tar xjvf /big1/dottexlive2008.tar.bz2 .texlive2008/texmf-var/fonts/afm/
	$ cd .texlive2008/texmf-var/fonts/afm/cjk/gbkfs
	$ cat gbkfs??.afm > gbkfs.afm

拿这个gbkfs.afm配置到ezpdf里,能打出字来了,但中文还是问号,估计是因为数据是utf-8编码,而字体是gbk编码的?修改class.ezpdf.php,在function ezProcessText的第一行加上(参考:ezpdf打印德文的处理):

	$text = mb_convert_encoding($text, 'gbk', 'utf-8');

还是问号,难道字体要嵌入pdf才行?

结果又查到一篇Choosing a PHP PDF generation library for Dokeos,说ezpdf根本、确实、100%就不支持utf-8编码,合着白折腾了。

ezpdf官网确认一下,最近的新闻是17 June 2006的,比上面那篇文章还晚,看来ezpdf确实是没法用了。用tcpdf吧,不过在glpi的roadmap里,换上tcpdf是要在0.80实现的,前面还有100+ ticket没完成,也是遥遥无期啊,只好自己动手,丰衣足食了。

TCPDF

从官网下载tcpdf放到php的include路径下,对照字体设置方法来准备字体:

	$ cd tcpdf/fonts
	# Simsun字体好像还不是truetype(嵌入了点阵字体),转换有些问题,先拿方正字体来用,正好方正仿宋简体打印用更好看
	#$ ln -s /big2/fonts/xpfonts/simsun.ttf
	# 注意文件名转为小写
	$ ln -s /big2/fonts/fzfont/fzfangsong.TTF fzfangsong.ttf
	$ utils/ttf2ufm -a -F fzfangsong.ttf 
	# 生成了3个新文件
	$ ls
	fzfangsong.ufm fzfangsong.t1a fzfangsong.afm	
	# 我选的这个方正字体应该是TrueTypeUnicode字体,用TrueType转的不显字
	# 文中有说明,在ttf ufm后面还可以跟参数,这里的false代表不将字体嵌入PDF文档,
	# 那样会使pdf文件大小增大为自身+字体文件大小,很恐怖的
	$ php5 -q utils/makefont.php fzfangsong.ttf fzfangsong.ufm false
	# 生成可用的文件了
	$ls
	fzfangsong.z fzfangsong.php

现在弄个简单的例子,能够用tcpdf输出pdf文件了,里面要有这么一句:

	$pdf->SetFont('fzfangsong', '', 16);

现在文件尺寸还是太大,因为字体依然是全嵌入的(如果是embedded subset更好,不过TCPDF现在还做不到)。按照那篇文章修改fzfangsong.php文件:

	//$type='TrueTypeUnicode';
	$type='cidfont0';
	...
	//$dw=600;
	$dw=1000;
	...
	//$enc='';
	$diff='';
	//$file='fzfangsong.z';
	//$ctg='fzfangsong.ctg.z';
	$originalsize=3548232;
 
	// Chinese Simplified
	$enc='UniGB-UTF16-H';
	$cidinfo=array('Registry'=>'Adobe', 'Ordering'=>'GB1','Supplement'=>2);
	include(dirname(__FILE__).'/uni2cid_ag15.php');

现在生成的pdf文件尺寸倒是很小了,但用eivnce看文字全部是空白,这是在Linux下看,跑到windows下看正常,而且完美,gb和big5编码都能显示。又用其它一些字体试了试,都是windows正常但linux下看不了,应该是刚才作的步骤正确,但与平台配合起来还欠点什么。

仔细对比了上面生成的两种pdf文件,以及另外一个用openoffice.org生成的pdf文件(这个应该比较标准吧),发现还是openoffice.org生成的文件又小、效果又好,用的是“已嵌入子集/embedded subset”方式,

最终查到,我基本上已经作好了,问题出在evince身上,安装poppler-data包(evince用这个来处理中文)后,完美解决,字体为非嵌入not embedded方式。生成的pdf文件非常小,用windows和evince浏览也都正常。混合gb2312和big5编码的内容也没问题:evince下中文出西欧字符不出,windows下Adobe Reader只出gb2312的字,Foxit Reader全部中文和西欧字符完美。而在全内嵌字体的情况下,用evince查看big5字符都是小黑块。

hack GLPI

接下来是大工程,把ezpdf换成tcpdf。修改inc/export.function.phpfunction displaySearchFooter函数,把case PDF_OUTPUT_LANDSCAPEcase PDF_OUTPUT_PORTRAIT两部分的内容都换成TCPDF的处理,源数据还借用原来的$PDF_HEADER,$PDF_ARRAY。除了纸张参数不一样,两部分的处理是相同的,下面是一个简单的例子:

	// --------
	require_once('tcpdf/tcpdf.php');
	global $PDF_HEADER,$PDF_ARRAY;
 
	// create new PDF document
	$pdf = new TCPDF('L', PDF_UNIT, PDF_PAGE_FORMAT, true, 'UTF-8', false); 
 
	// set document information
	$pdf->SetCreator(PDF_CREATOR);
	$pdf->SetAuthor('Fwolf');
	$pdf->SetTitle($title);
	$pdf->SetSubject('GLPI Export');
	$pdf->SetKeywords('TCPDF, PDF, GLPI, export, fwolf, work, asset');
 
	// set header and footer fonts
	$pdf->setHeaderFont(Array(PDF_FONT_NAME_MAIN, '', PDF_FONT_SIZE_MAIN));
	$pdf->setFooterFont(Array(PDF_FONT_NAME_DATA, '', PDF_FONT_SIZE_DATA));
	// remove default header/footer
	$pdf->setPrintHeader(false);
	$pdf->setPrintFooter(true); 
 
	// set default monospaced font
	$pdf->SetDefaultMonospacedFont(PDF_FONT_MONOSPACED);
 
	//set margins
	$pdf->SetMargins(PDF_MARGIN_LEFT, PDF_MARGIN_TOP - 10, PDF_MARGIN_RIGHT);
	$pdf->SetHeaderMargin(PDF_MARGIN_HEADER);
	$pdf->SetFooterMargin(PDF_MARGIN_FOOTER);
 
	//set auto page breaks
	$pdf->SetAutoPageBreak(TRUE, PDF_MARGIN_BOTTOM);
 
	//set some language-dependent strings
	$pdf->setLanguageArray($l); 
 
	// ---------------------------------------------------------
 
	// add a page
	$pdf->AddPage();
 
	// Column width, by conteng max length
	$w_max = $pdf->getPageWidth() - PDF_MARGIN_LEFT - PDF_MARGIN_RIGHT;
	$w = array();
	foreach($PDF_ARRAY as $row) {
		foreach ($row as $i => $cell) {
			// Chinese utf8 2 words length=6, should be 4 here
			$cell = trim($cell);
			$l = mb_strwidth($cell, 'utf-8');
			// FZFangSong is not fixed font, so add some to en chars
			// eg: 哈哈abc
			// strlen = 6 + 3 = 9
			// mbstrlen = 5
			// mbstrwidth = 7
			$l += ($l + mb_strlen($cell, 'utf-8') - strlen($cell))
				* 0.3;
 
			if (!isset($w[$i])) {
				$w[$i] = $l;
			}
			elseif ($w[$i] < $l) {
				$w[$i] = $l;
			}
		}
	}
	// Compare with max width, maybe below 0
	$i = $w_max - array_sum($w);
	// Add back spaces left to each width
	$i = $i / count($w);
	foreach ($w as $k => $v) {
		$w[$k] = $v + $i;
	}
 
 
	// Table title
	$pdf->SetFont('fzfangsong', '', 14);
	$pdf->Write(0, '设备一览表', 0, 0, 'C', 1);
 
	// set font
	$pdf->SetFont('fzfangsong', '', 10);
 
	// Table header
	$pdf->SetFillColor(208, 220, 255);
	$pdf->SetTextColor(0);
	foreach ($PDF_HEADER as $i => $head) {
		$pdf->Cell($w[$i], 7, $head, 1, 0, 'C', 1);
	}
	$pdf->Ln();
 
	// Rows
	$pdf->SetFillColor(224, 235, 255);
	$pdf->SetTextColor(0);
	$fill = 0;
	foreach($PDF_ARRAY as $row) {
		foreach ($row as $i => $cell) {
			$pdf->Cell($w[$i], 6, $cell, 'LR', 0, 'L', $fill);
		}
		$pdf->Ln();
		$fill=!$fill;
	}
	$pdf->Cell(array_sum($w), 0, '', 'T'); 
 
	// ---------------------------------------------------------
 
	//Close and output PDF document
	$pdf->Output('glpi.pdf', 'I'); 
	return;
	break;

总体上这个例子是照着官网Colored Tables例子来的。

最后,把这个文件中所有的utf8_decode处理都去掉,完成。

参考

Update @ 2009-11-06

Print to pdf 的时候,Historical 中的 Comments 如何显示?默认的不好,可以考虑换成 diff 信息,如果又不愿用 pear 里的 xdiff,可以考虑它的前身──用 php 直接实现的 PHP inline diff

Related posts

Categories: PHP Tags: , , , , , , , , ,

Gregarius编辑feed时中文乱码的解决

May 2nd, 2008 Fwolf No comments

Gregarius编辑feeds的时候,中文总是乱码(版本r1787),其实解决方法很简单的:

找到admin/channels.php这个文件,找到第900行,修改为:

//$title = htmlentities($title,ENT_QUOTES);
$title = htmlspecialchars($title, ENT_QUOTES);

这个是feed标题乱码的修正,再向下翻到Description部分,大概在988行左右,修改为:

// Description
//$descr = trim(htmlentities(strip_tags($descr), ENT_QUOTES));
$descr = trim(htmlspecialchars(strip_tags($descr), ENT_QUOTES));

这样就ok了。

原因很简单,htmlentities这个函数在转义到html标记的时候,会吧中文字符中一些字节也进行了转义,形成了乱码,而htmlspecialchars这个函数只转义特定的5个字符,不会存在这种情况。

hack之后,单引号和双引号都能输入了,但是反斜杠\仍然是不能输入的,应该是在输入处理的时候过滤掉了,或者进行了其他的转换,不过一般也用不到,就不改了。西文环境用户的处理习惯就是和我们不大一样啊。

参考

Related posts

Categories: Internet, PHP, Tools Tags: , , , , ,

发现fcitx也很不错嘛

July 8th, 2007 Fwolf 6 comments

scim使用了很长时间了,虽然其中有时候有些麻烦,总体来说也是不错的。不过我只用自然码风格的双拼,scim那丰富的输入法类型对我来说没用,今天心血来潮换fcitx用用,发现居然也是很不错的,比我刚开始在ubuntu 5.10下使用的感觉好多了。

我是直接安装源中的版本,apt安装即可,版本是1:3.4.3-1,输入法选字条上显示的版本是“GirlDog 3.4.3(新年版)”,更换输入法的时候,除了使用im-switch -s fcitx之外,还把/etc/X11/Xsession.d/95input的内容改成了下面这样:

export LC_CTYPE=zh_CN.UTF-8
export XMODIFIERS=@im=fcitx
export XIM=fcitx
export XIM_PROGRAM=fcitx
fcitx

然后重启X就能正常启动fcitx了。

fcitx的主要配置文件是$HOME/.fcitx/config,不过这个文件的编码是gb2312的,所以编辑之前要先更改一下shell环境的字符集(注意文件编码不能改,不然设置无效):

export LANG=zh_CN.utf-8
gedit config

更改设置之后,想立即生效就kill掉fcitx再重启(或者按Ctrl_5也行):

pkill -9 fcitx;fcitx

在我的安装中,或许是ubuntu改装的原因,反查拼音、删除拼音用户词组等快捷键好像无法使用,不过还好,自造词挺省事,直接编辑QuickPhrase.mb就可以了,不过这个文件也必须是gb2312编码才行。

总体fcitx给我的感觉是小巧、快速、够用,不过配置略微麻烦了一点点,需要修改配置文件,而不是像scim那样有图形界面的配置功能;另外就是很多地方,比如配置文件,使用gb2312内码,对于现在大多数utf8编码的linux来说,略微麻烦了一点点。

推荐大家看看fcitx官方网站上的中文PDF文档,挺不错的。

另外还有一个我不知道的问题,比如输入ubuntu,没按回车出英文,而是按空格出了个“手刹虐杀”的中文,以后就记住了,像这种“自造词”如何删除?Ctrl+Del不起作用呀。

Update @ 2007-07-11

刚换过来没几天,作者就由于别人的打击要放弃这个项目,真让人郁闷,Yuking一定要顶住恶势力的攻击啊~~

Related posts

Categories: Linux, Tools Tags: , , , ,

让phpmailer支持中文名称的附件

May 23rd, 2006 Fwolf 5 comments

phpmailer设置使用utf-8编码发送邮件以后,已经能够正常的发送中文邮件了,当然你调用时传进去的中文参数必须也是utf-8编码才行,但是我发现,即使这样,发送中文文件名的附件的时候,附件名称不能正确的显示。

比如我们要发送的附件是“测试.txt”,如果在添加附件的时候强制使用指定文件名的方式:

$mail->AddAttachment($attach, $attach);

那么发送过去的附件文件名将会是乱码,如果不指定:

$mail->AddAttachment($attach, $attach);

那么发送过去的文件名中的中文干脆没了,成了“.txt”。

究其原因,打开class.phpmailer.php,在大概第1007行左右,函数AddAttachment中,有一句

$filename = basename($path);

原因就在这里,现在我们使用的php 5.1.2,包括他以前的很多版本,basename函数和dirname函数都是不支持中文文件名的,所以一解析就把中文给过滤掉了。而如果强行指定文件名为什么还乱码呢,这是因为phpmailer虽然会自动根据你设定的编码方式给主题、正文进行utf-8编码化,但是却不会给附件的文件名编码。现在,只需要修改上面这一句,就能够同时解决这两方面的问题了。修改结果如下:

//$filename = basename($path);
if (false === strpos($path, '/'))
    $filename = $this->EncodeHeader($path);
else
    $filename = $this->EncodeHeader(substr($path, strrpos($path, '/') + 1));

不使用basename函数了,改用自己的方法来得到文件名,并且借用了主题Subject的编码函数EncodeHeader来生成utf-8编码形式的附件名称,搞定。

Update @ 2008-04-14

在phpMailer 2.1.0 Beta 2中,这个问题依然没有得到处理,需要作的修改还是一样,不过代码的位置在1018行附近。

另外在发送中文邮件的时候,中文会出现乱码,看了网上有处理的方式,没有讲原因,也粗暴了点,直接把函数截断了,还要改两个地方。

我看了一下源码,乱码的产生大概是在将邮件标题转成几个小的=?utf-8?B?...?=时,可能是无意中把中文给截断了产生的,所以我的修改更简单而又略微温柔一点,修改第1185行:

$maxlen = 75 - 7 - strlen($this->CharSet);
改成:
$maxlen = 75000 - 7 - strlen($this->CharSet);

就行了,把字符串的值设大点,让它不分段就行了。

Related posts

Categories: PHP Tags: , , , , ,