2010年10月13日星期三

使用wxWidgets时发现的一些bug及解决方案

Ubuntu中

wxDC类

bug 1.  使用SetLogicalOrigin时必须确保坐标轴为默认方向(SetAxisOrientation(true,false)),使用后可更改为需要的方向(SetAxisOrientation(true,true));

解决方案:查看wxGTK源代码文件dc.cpp可看到如下代码:

void wxDC::SetLogicalOrigin( wxCoord x, wxCoord y )
{
m_logicalOriginX = x * m_signX; // is this still correct ?
m_logicalOriginY = y * m_signY;
ComputeScaleAndOrigin();
}

作者也察觉到了这里可能有问题,标注了// is this still correct ?


将上面代码修改如下即可:



void wxDC::SetLogicalOrigin( wxCoord x, wxCoord y )
{
m_logicalOriginX = x ;
m_logicalOriginY = y ;
ComputeScaleAndOrigin();
}

bug 2. 使用SetUserScale函数设置放大倍数时画笔(wxPen)的宽度随之放大,但在xp系统下画笔宽度不变。也就是说如果设置SetUserScale(1,1000),则画笔宽度可能变为1000像素,导致无法成功绘制图像。

解决方案:从源代码文件dc.cpp中我们可以看到SetUserScale函数的定义:

void wxDC::SetUserScale( double x, double y )
{
// allow negative ? -> no
m_userScaleX = x;
m_userScaleY = y;
ComputeScaleAndOrigin();
}

在源代码文件dcclient.cpp中我们可以看到wxWindowDC::ComputeScaleAndOrigin()函数的定义:



void wxWindowDC::ComputeScaleAndOrigin()
{
const wxRealPoint origScale(m_scaleX, m_scaleY);

wxDC::ComputeScaleAndOrigin();

// if scale has changed call SetPen to recalulate the line width
if ( wxRealPoint(m_scaleX, m_scaleY) != origScale && m_pen.Ok() )
{
// this is a bit artificial, but we need to force wxDC to think the pen
// has changed
wxPen pen = m_pen;
m_pen = wxNullPen;
SetPen( pen );
}
}

进一步我们可以找到函数 wxWindowDC::SetPen 的定义



void wxWindowDC::SetPen( const wxPen &pen )

{

wxCHECK_RET( Ok(), wxT(“invalid window dc”) );
if (m_pen == pen) return;
m_pen = pen;
if (!m_pen.Ok()) return;
if (!m_window) return;

gint width = m_pen.GetWidth();
if (width <= 0)
{
// CMB: if width is non-zero scale it with the dc
width = 1;
}
else
{
// X doesn’t allow different width in x and y and so we take
// the average
double w = 0.5 +
( fabs((double) XLOG2DEVREL(width)) +
fabs((double) YLOG2DEVREL(width)) ) / 2.0;
width = (int)w; //注意,这个宽度是最终绘制的宽度
if ( !width )
{
// width can’t be 0 or an internal GTK error occurs inside
// gdk_gc_set_dashes() below
width = 1;
}
}

//…… 中间的代码省略

gdk_gc_set_line_attributes( m_penGC, width, lineStyle, capStyle, joinStyle );

m_pen.GetColour().CalcPixel( m_cmap );

gdk_gc_set_foreground( m_penGC, m_pen.GetColour().GetColor() );

}

综合以上代码分析我们可以看到:当我们调用函数SetUserScale 放大绘制的图形时,wxGTK同时放大了绘制线条的宽度。


解决办法是删除 width = (int)w;  这行代码。



修改源代码后,重新编译wxGTK即可。



XP中

wxDateTime

bug 1. wxDateTime::Format 函数不支持中文字符的格式化。

解决方案:暂时可以使用wxString::Format函数替代。

没有评论:

发表评论