2009年5月27日星期三

让U++的Theide在linux下完美支持中文

blogspot被GFW封了好多天了,有点烦,连自己的博客也访问不了。
昨天在Ubuntu上装了U++,结果发现代码编辑器对中文支持的非常差,无法正常显示中文。仔细看了一下发现是theide不支持中文字体,指望老外是指望不上了,人家不用中文。只能自己动手,阅读了ide的源码,把setup.cpp中的void FontSelectManager::Set函数中的读取字体循环改一下就可以支持中文字体了。
原函数:
void FontSelectManager::Set(DropList& _face, DropList& _height,
Option& _bold, Option& _italic, Option& _naa) {
face = &_face;
face->WhenAction = THISBACK(FaceSelect);
height = &_height;
height->WhenAction = THISBACK(Select);
bold = &_bold;
bold->WhenAction = THISBACK(Select);
italic = &_italic;
italic->WhenAction = THISBACK(Select);
naa = &_naa;
naa->WhenAction = THISBACK(Select);
face->Clear();
for(int i = 0; i < Font::GetFaceCount(); i++)
if(Font::GetFaceInfo(i) & Font::FIXEDPITCH) { //就是要改这一行,原作者为了保持代码编辑器内文本格式的整齐而不读取非固定宽度的字体,这使的支持中文字形的字体无法被IDE支持。
face->Add(i, Font::GetFaceName(i));
LLOG("Face: " << Font::GetFaceName(i));
}
face->SetIndex(0);
height->ClearList();
for(int i = 6; i < 32; i++)
height->Add(i);
FaceSelect();
}

修改后的代码:
void FontSelectManager::Set(DropList& _face, DropList& _height,
Option& _bold, Option& _italic, Option& _naa) {
face = &_face;
face->WhenAction = THISBACK(FaceSelect);
height = &_height;
height->WhenAction = THISBACK(Select);
bold = &_bold;
bold->WhenAction = THISBACK(Select);
italic = &_italic;
italic->WhenAction = THISBACK(Select);
naa = &_naa;
naa->WhenAction = THISBACK(Select);
face->Clear();
for(int i = 0; i < Font::GetFaceCount(); i++)
{ //直接将条件语句删除
face->Add(i, Font::GetFaceName(i));
LLOG("Face: " << Font::GetFaceName(i));
}
face->SetIndex(0);
height->ClearList();
for(int i = 6; i < 32; i++)
height->Add(i);
FaceSelect();
}

这样修改后IDE可以支持中文字体了,但在使用中文字体时显示的格式非常难看,字间距变的大小不等,严重影响源码的编写与阅读。这也让我明白了原作者为什么不读取非固定宽度字体的原因。不过这也难不住咱,继续改。在研究源码后,发现问题在于U++中的LineEdit构件的文字描绘部分。源码位于usr/CtrlLib/LineEdit.cpp中。只要改动一下计算字体宽度的函数中就可以了:
原函数:
Size LineEdit::GetFontSize() const {
FontInfo fi = font.Info();
return Size(fi.GetAveWidth(), fi.GetHeight());
}

更改后的函数:
Size LineEdit::GetFontSize() const {
FontInfo fi = font.Info();
//增加下面这行,用来正确处理非固定宽度字体的宽度。
int width = font.GetFaceInfo() & Font::FIXEDPITCH ? fi.GetAveWidth() : fi.GetAveWidth()/2;
return Size(width , fi.GetHeight());
}

这样修改后对中文字体的支持就一切正常了。

修改前的含中文代码效果:


第一步修改后的效果:


最终修改效果:


最终的文字效果已经与固定宽度字体的显示效果完全相同了,呵呵。问题完满解决。

没有评论: