电脑故障

位置:IT落伍者 >> 电脑故障 >> 浏览文章

不同映射模式下的直线输出的效果问题


发布日期:2019/8/16
 
在做打印预览时发现有趣的现象

打印预览时宽度设置为mm的线与设置为mm的线显示效果一样无区别

打印机输出正常

打印预览时相同宽度的线有些显示有些不显示

打印机输出正常

仔细查看了一下实际上是映射模式下的显示问题鑒于映射模式总是让人焦头

烂额值得总结一下

开始分析

第一步写一个MM_TEXT模式的例子打印条竖线宽度由递增


dcSetMapMode(MM_TEXT);

for(int ii=;ii<=;ii++)

{

CPen pen;

penCreatePen(PS_SOLIDiiRGB());

CPen *pOldPen = dcSelectObject(&pen);

dcMoveTo(xStart+xInterval*ii);

dcLineTo(xStart+xInterval*iixLineLen);

dcSelectObject(&pOldPen);

}

当然会输出不同宽度的条线

很正常映射模式是像素为单位

第二步模拟一下打印预览下的模式(mm的方式)

long lLogInch = ;

dcSetMapMode(MM_ANISOTROPIC);

dcSetWindowExt(lLogInch lLogInch);

dcSetViewportExt(dcGetDeviceCaps(LOGPIXELSX) dcGetDeviceCaps(LOGPIXELSY));

映射个单位是mm

同样用上面的代码输出

线一样粗线一样粗

实际打印机输出粗细是递增的非常正常

Why?

第三步估计是精度问题吧?

看看新的映射模式下每根线的实际输出像素

首先通过long lX = dcGetDeviceCaps(LOGPIXELSX);

取得当前显示器一个英寸是等于个像素

算一下

毫米 ——》/ =

毫米 ——》

毫米 ——》

毫米 ——》

毫米 ——》

毫米 ——》

很好解释了四捨五入后都是像素都是像素

实际打印机呢? lX =

不用计算了吧精度高打印出来当然就OK了

结论

由于显示器的像素点精度问题在使用Pen进行绘制时会进行四捨五入如果

当前映射模式不合适会导致应用端不同的输入在四捨五入后得到一样的显示

解决办法如Excel一般不要提供太小的线宽比如最小线宽必须是折算后的

一个像素/ = mm

第四步以上规则只适用于Pen的Line绘制方法直线还可以通过FillRect或

FillSolidRect方式并且会出现开头讲的现像

再试试FillSolidRect会如何

long xStart = ;

long xLineLen = *;

long xInterval = ;

for(int ii=;ii<=;ii++)

{

CRect rc(xStart+xInterval*iixStart+xInterval*ii+ii+xLineLen);

dcFillSolidRect(rcRGB());

}

结果

只显示出后四条线

为何?为啥不四捨五入了呢?

第五步矩形可能会是先四捨五入再算宽度的?是吗?做个测试先

打印时加多一行测试

TRACE(_T(\n%f%f)rcleft*rcright*);

输出如下

假设一下如果先四捨五入然后再相减得到宽度是

比较一下输出效果果然如此

上一篇:毕业总结:学会举一反三,扩展更多功能

下一篇:JMail组件使用中文文档