2012年5月16日 星期三

GDI 映射模式

GDI 映射公式

以 X 方向的視窗口邏輯單位(xWindow)轉換為視埠設備單位(xViewport)為例:
 
xViewport = (xWindow - xWimOrg) * (xViewExt / xWinExt) + xViewOrg

(xViewExt / xWinExt) 是用來做轉換的比值,兩數是可任意值,但依平台不同有其實際的數值來源,兩者可由設備物件的 CDC::GetViewportExt() 和 CDC::GetWindowExt() 取得。

在 WinXP 這個 CDC::GetViewportExt() 若指的是螢幕設備,則會與你所設定的螢幕解析度相同,但依平台不同會不同的數值來源。

而 CDC::GetWindowExt() 則依 GDI 映射模式的不同,而和 xViewExt有適當的對應值,以達到正確轉換比值的要求。

用一個程式碼來瞭解一下這個關係:

void CtestDlg::OnBnClickedButton2()
{
  CDC *pDC = this->GetDC(); // 取得視窗的設備 

  // 設定此模式表示 xWinExt 一個邏輯單位代表   
  // 0.01 英吋 
  pDC->SetMapMode(MM_LOENGLISH); 
  
  // 我的電腦螢幕解析度為 1280 * 800 
  CSize V = pDC->GetViewportExt();      

  //  1181 * 736 (單位 0.01 英吋) 
  CSize W = pDC->GetWindowExt();
  
  // 2999 計算出 X 是多少 0.1 mm
  int m = W.cx * 2.54;  

  // 設定此模式表示 xWinExt 一個邏輯單位代表 0.1 mm 
  pDC->SetMapMode(MM_LOMETRIC); 

  // 3000 * 1870 (單位 0.1 mm),X 方向和 m 相  
  // 同(2999 是電腦浮點計算上的誤差) 
  W = pDC->GetWindowExt();  

  // 設定此模式表示xWinExt 一個邏輯單位代表 0.01 英 
  // 吋,xWinExt : xViewExt = 1 : 1.08 
  pDC->SetMapMode(MM_LOENGLISH);  

  // 在 x,y 為 1 英吋的位置上秀出文字, 
  pDC->TextOutW(100,-100,L"Test",4);  
  
  // 設定此模式表示xWinExt 一個邏輯單位代表 1 個  
  // 像素,即和 xViewExt 對應為 1:1 
  pDC->SetMapMode(MM_TEXT);  

  //  x 位置和上一個相同 
  pDC->TextOutW(108,100,L"Test",4);
  

  // 可用以下取得基準對應關係,以下是我電腦的數值 
  int i = pDC->GetDeviceCaps(HORZSIZE); // 300 公分(邏輯單位) 
  int j = pDC->GetDeviceCaps(HORZRES); // 1280 像素(設備單位) 
}

字型尺寸

字型的尺寸單位換算基準為 72點 / 每英吋,所以若在我的電腦用一個 8 點高的字型,為 1/9 英吋,視埠高為 108 / 9 = 12 個像素









沒有留言:

張貼留言