熱點推薦:
您现在的位置: 電腦知識網 >> 編程 >> .NET編程 >> 正文

不同映射模式下的直線輸出的效果問題

2013-11-13 09:41:29  來源: .NET編程 
 在做打印預覽時發現有趣的現象

  打印預覽時寬度設置為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*);
  輸出如下
   
   
   
   
   
   
  假設一下如果先四捨五入然後再相減得到寬度是
                   
  比較一下輸出效果果然如此


From:http://tw.wingwit.com/Article/program/net/201311/11339.html
    推薦文章
    Copyright © 2005-2013 電腦知識網 Computer Knowledge   All rights reserved.