大部分的 Windows CE 顯示器驅動程式會使用圖形基本引擎 (GPE) 提供的預設顯示驅動程式的基本處理。GPE::Line 方法使用
GPELineParms 及
EGPEPhase 資料結構中所提供的參數的目的表面上繪製線條。本文定義
GPELineParms 和
EGPEPhase 資料結構,並說明如何 GPE 繪製一條線。
GPE 所提供的預設繪圖可能會被取代顯示器驅動程式中由軟體模擬加速或原生的硬體加速如述 Windows CE 2.12 裝置驅動程式套件章節顯示驅動程式有關。
GPELineParms結構
GPELineParms 是一種結構。
GPELineParms 定義在這個目錄平台產生器:
Public\Common\Oak\Inc
GPE 和顯示器驅動程式使用
GPELineParms 來控制線繪圖中。某些結構中參數直接來自應用程式或目前的裝置內容。其餘 GPE,來計算。
struct GPELineParms
{
SCODE (GPE::*pLine)(GPELineParms *);
long xStart; //Starting point of line, in X direction
long yStart; //Starting point of line, in Y direction
int cPels; //Length of line in major direction, in pixels
unsigned long dM; //larger of |xStart-Xend| and |yStart-yEnd|, calculated in 1/16ths of a pixel
unsigned long dN; //smaller of |xStart-Xend| and |yStart-yEnd|, calculated in 1/16ths of a pixel
long llGamma; //typically used as the initial starting value for the slope iterator
int iDir; //Octant number for line
unsigned long style; //IN parameter - line attributes (solid or dashed)
int styleState; //state of line style in current path, in pixels
GPESurf *pDst; //IN parameter - destination surface
COLOR solidColor; //IN parameter brush color
RECTL *prclClip; //clipping rectangle
unsigned short mix; //IN parameter ROP2 values for mark and space
}; GPELineParms 樣式是線條樣式。值零 (0) 表示它是實線 (也就是單一 ROP2),而 0xAAAAAAAA 樣式是單一像素點 (兩個 ROP2s 間交替)。當傳遞至
DrvStrokePath 函式,plineattrs-fl > 中的旗標 LA_ALTERNATE 暗示著 0xAAAAAAAA 樣式。此外,您可以使用使複雜的
pstyle 和
cstyle 參數虛線或點狀的樣式。比方說 0xF0F0F0F0 pParms <-> 樣式中的表示較長的虛線。
GPELineParms 混合是 ROP2 值。它所組成的記號 ROP2 及空間 ROP2 的兩個位元組。-> [混合值 pParms 中兩個位元組之間選擇樣式中的每一個位元的值。 GPELineParms iDir 是 octant 數行 (每 Bresenham 演算法的 8 值其中之一)。 octant 座標軸 X Dir Y Dir 0 X 主要 + 1 + 1 1 Y 主要 + 1 + 1 2 Y 主要-1 + 1 3 X 主要-1 + 1 4 X 主要-1-1 5 Y 主要-1-1 6 Y 主要 + 1-1 7 X 主要 + 1-1
EGPEPHASE 列舉型別
EGPEPHASE 是列舉型別。EGPEPHASE 定義在平台產生器的下列目錄:
Public\Common\Oak\Inc
enum EGPEPhase
{
gpeSingle,
gpePrepare, //device-specific initialization
gpeContinue,
gpeComplete //device-specific clean up
};線繪圖中處理
準備階段
當應用程式呼叫聚合線條方法開始直線繪圖。GDI 會處理對聚合線條方法呼叫。GDI 會驗證有兩個以上的頂點和線條樣式不是 null。GDI 然後呼叫該 GPE
DrvStrokePath 函式或寬畫筆
DrvFillPath 函式。當 GDI 呼叫 GPE 成員函式時,它就會傳遞資訊一起從裝置內容]:
- 介面物件
- 路徑物件
- 美工圖案矩形
- 筆刷
- ROP2 值
- 線條屬性 (實線或虛線)。
這些參數是由應用程式任一組或實現的屬性。GPE 會使用某些輸入參數來填入其 GPELineParms 結構。
在 [GPELineParms 傳遞和傳入的 EGPEPHASE] 設定為
gpePrepare GPE 接著會呼叫顯示器驅動程式
行 函式。驅動程式會檢查是要繪製的線條的屬性。驅動程式然後會選擇是否要使用 GPE
EmulatedLine 函數或處理有它自己加速函式一行。在選取的加速函式之前必須檢查硬體可以處理線條樣式及 ROP 驅動程式。在平台產生器] 目錄 Platform\Cepc\Drivers\Display\S3trio64) 中 S3Trio64 顯示器驅動程式,驅動程式預設 EmulatedLine,設定函式指標,但選擇都會在視訊記憶體,並使用 ROP 0x0D0D 的線條的硬體加速。下列範例程式碼可說明這點:
#ifdef ENABLE_ACCELERATION
if( phase == gpeSingle || phase == gpePrepare )
{
pLineParms->pLine = EmulatedLine;
// pLineParms->pLine = (SCODE (GPE::*)(struct GPELineParms *))EmulatedLine;
if( pLineParms->pDst->InVideoMemory() && pLineParms->mix == 0x0d0d )
{
SelectSolidColor( pLineParms->solidColor );
pLineParms->pLine = (SCODE (GPE::*)(struct GPELineParms *))AcceleratedSolidLine;
}
// if( pLineParms->mix == 0x0B07 ) .. dotted line
}
#else
pLineParms->pLine = EmulatedLine;
#endif而且,在 「 準備 」 階段驅動程式 (選擇性) 可以執行額外的處理,例如初始化硬體暫存器,以選取色彩。在 [準備] 階段之後控制項會返回至 GPE
DrvStrokePath 函式。
DrvStrokePath 管理繪圖的每個區段
在判定驅動程式的線條繪圖函式之後,
DrvStrokePath 函式會執行下列迴圈。這些迴圈的順序被為了充分發揮硬體裁剪。通常,路徑落入剛才的其中一個裁剪矩形。
for( each clip rectangle in clip list )
{
for( each line segment in stroke path )
{
calculate line segment clipped to current cliprect
pParms->pLine(pParms);
}
} DrvStrokePath 函式剪輯到裁剪矩形線段。您不需要如此做,在其
線條 函式之驅動程式。在實際上驅動程式就真的無法裁剪因為在準備階段沒有有效的裁剪資訊。可能沒有裁剪方框或可能有個單一準備呼叫的裁剪矩形為整個序列。
EmulatedLine 是預設直線繪圖函式
EmulatedLine 函式是 GPE 線條繪圖函式。EmulatedLine 實作下列演算法:
long accum = (long)(pParms->dN) + pParms->llGamma;
long axstp = (long)(pParms->dN);
long dgstp = (long)(pParms->dN) - (long)(pParms->dM);
for( remainingPels = pParms->cPels; remainingPels; remainingPels-- )
{
if( axstp ) // ( axstp == 0 implies horizontal or vertical line being drawn )
{
if( accum < 0 )
{
accum += axstp;
}
else
{
increment_in_minor_direction;
accum += dgstp;
}
}
increment_in_major_direction;
} 的 EmulatedLine 建議使用狀況
使用 EmulatedLine 函數來處理的對角線。對角線都相當少見,且通常不需要加速。 同樣地,是相當罕見,如要使用的線條樣式。EmulatedLine 函式應該作為預設處理器使用此種狀況的。
驅動程式可以取代預設的函式
對於支援硬體線條繪圖加速的裝置驅動程式可以實作來取代預設 EmulatedLine 函式的加速的內嵌函式。或者,驅動程式可以呼叫現有的函式,或建立新的軟體模擬函式,來處理線繪圖中。即使沒有適當的線條繪圖加速是可用,如果硬體中實作純色填滿區塊傳輸 (BLT) 加速接著這應該用來加速水平線和垂直線。
硬體加速的水平] 和 [垂直線條僅限
大部分的狀況下建議的方法是模擬所有對角線和樣式化行,使用直線繪圖硬體或填滿 blt 硬體加速構成大部分的 Windows CE 繪製的線條的水平及垂直線條。對於水平及垂直線條 DN 參數是零 (0),以及沒有帳戶需要採取的中 dM 參數和錯誤詞彙 llgamma sub-pixel 資訊。
if( pLineParms->dN == 0 )
{
// Line is vertical or horizontal
// Use fill-blt or h/w line to draw a line starting at
// pLineParms->xStart, pLineParms->yStart
// in the direction specified by pLineParms->iDir
// for a total of pLineParms->cPels pixels
}
else
{
return EmulatedLine( pLineParms ); // use S/W for diagonal line
}
硬體加速的對角的線條務必注意,對角線行文字中
dM 參數
DN 參數值,而且 GPELineParms 錯誤詞彙 llgamma 欄位包含 sub-pixel 資訊。正在初始化硬體線條繪圖會註冊時,應該使用這項資訊。否則,不正確地繪製裁剪的對角線。包含對角線的另一個視窗上方移動一個視窗時,可能會很明顯這種效果。
在 「 準備 」 階段驅動程式會執行一般的檢查的列參數來決定是否它可以加速它。呼叫加速函式時驅動程式可能需要執行額外的驗證。這是因為呼叫驅動程式的加速函式時它是對特定路徑區段裁剪特定的裁剪區域。驅動程式必須確保,例如線條區段長度不會造成溢位其硬體暫存器。比方說,S3Trio64 驅動程式中這個額外的層級的篩選進行下列敘述所示的程式碼中。因為原本調整
dM 和
DN 值表示 1/16ths 的像素中,裝置的硬體斜率 iterators 需要能保留這些的繪製任何線條區段的長度。很多的硬體為了要能夠跨整個螢幕繪製對角線的線條,但預期
dM,軸和
DN 值 (或對等用法),以像素表示。因為 GPE 使用 sub-pixel 精確度,這些計數器需要四 (4) 更多位元。短線條的並非問題,但長線的這些值可以溢位導致剛 zinging 關閉螢幕或甚至包裝大約幾次的某些邊緣的線暫存器]。
不常用的對角線時,長對角線是極為罕見所以時間來呈現長對角線使用
EmulatedLine 函式是不重要。
int errTerm = (int)pLineParms->dN + (int)pLineParms->llGamma - ( ( command & PLUS_X ) ? 0 : 1 );
if(
( pLineParms->dN > 4090 ) ||
( pLineParms->dM-pLineParms->dN > 4090 ) || // remember dM >= dN
( errTerm > 4090 ) ||
( errTerm < -4090 ) )
{
RetVal = EmulatedLine( pLineParms ); // The hardware DDA would overflow so use the emulation
}
else
{
WaitForFIFO(7); // seven parameters required
reg_ALT_CURXY = ((pLineParms->xStart + ((S3Trio64Surf *)(pLineParms->pDst))->Left()) << 16 ) |
(pLineParms->yStart + ((S3Trio64Surf *)(pLineParms->pDst))->Top());
reg_MAJ_AXIS_PCNT = (pLineParms->cPels-1);
reg_ALT_STEP = (((pLineParms->dN-pLineParms->dM)/*&0x3FFF*/)<<16) | (pLineParms->dN /*&0x3FFF*/);
reg_ERR_TERM = errTerm /*&0x3FFF*/;
reg_CMD = command;
RetVal = S_OK;
}完成階段
DrvStrokePath 函式完成線條繪圖之後
DrvStrokePath 再次呼叫驅動程式的
線條 函式傳遞至
gpeComplete EGPEphase 組這段時間。驅動程式應該清除此時硬體所需的任何直線繪圖狀態。