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

基於 Linux 和 MiniGUI 的嵌入式系統軟件開發指南(七)

2022-06-13   來源: Oracle 

  作者魏永明
  
  主題七MiniGUI 引入的新 GDI 功能和函數之二
  
   引言
  我們在本系列主題五中曾經詳細描述了在 MiniGUI 版本開發過程中添加的新 GDI 功能和函數這些接口首次出現在版本 Pre 當中目前 MiniGUI Pre 版本已經發布該版本中的新 GDI 接口趨於穩定相對 Pre 版本而言又新增了若干高級圖形接口這些接口涉及到直線和曲線生成器復雜曲線的繪制封閉曲線填充復雜區域的創建直接的顯示緩沖區訪問YUV 覆蓋和 Gamma 校正等等本文將就這些主題詳細描述各個接口的用法
  
   曲線和填充生成器
  在一般的圖形系統中通常給用戶提供若干用於進行直線或者復雜曲線比如圓弧橢圓和樣條曲線的繪圖函數用戶可以通過這些函數進行繪圖但不能利用這些系統中已有的曲線生成算法完成其他的工作在 MiniGUI 新的 GDI 接口設計當中我們采用了一種特殊的設計方法來實現曲線和封閉曲線的填充這種方法非常靈活而且給用戶提供了直接使用系統內部算法的機會
  
  )系統中定義了若干用來生成直線和曲線的函數我們稱之為曲線生成器
  )用戶在調用生成器之前需要定義一個回調函數並將函數地址傳遞給曲線生成器曲線生成器在生成了一個曲線上的點或者封閉曲線中的一條水平填充線時將調用這個回調函數
  )用戶可以在回調函數當中完成針對新的點或者新的水平填充線的操作對 MiniGUI 繪圖函數來說就是完成繪圖工作
  )因為回調函數在生成器的運行過程中不斷調用為了保持一致的上下文環境系統允許用戶在調用曲線生成器時傳遞一個表示上下文的指針生成器將把該指針傳遞給回調函數
  
  下面將分小節講述目前的 MiniGUI 版本所提供的曲線和填充生成器
  
   直線剪切器和直線生成器
  
  直線剪切器和生成器的原型如下
  
  /* Line clipper */
  BOOL GUIAPI LineClipper (const RECT* cliprc int *_x int *_y int *_x int *_y);
  
  /* Line generators */
  typedef void (* CB_LINE) (void* context int stepx int stepy);
  void GUIAPI LineGenerator (void* context int x int y int x int y CB_LINE cb);
  
  直線剪切器並不是生成器它用於對給定的直線進行剪切操作cliprc 是給定的直線而 _x_y_x 和 _y 傳遞要剪切的直線起始端點並通過這些指針返回剪切之後的直線起始端點MiniGUI 內部使用了 CohenSutherland 算法
  
  LineGenerator 是采用 Breshenham 算法的生成器該生成器從給定直線的起始端點開始每生成一個點調用一次 cb 回調函數並傳遞上下文 context以及新的點相對於上一個點的步進值或者差量比如傳遞 stepx =stepy = 表示新的點比上一個點在 X 軸上前進一步而在 Y 軸上保持不變回調函數可以在步進值基礎上實現某種程度上的優化
  
   圓生成器
  
  MiniGUI 定義的圓生成器原型如下
  
  /* Circle generator */
  typedef void (* CB_CIRCLE) (void* context int x int x int y);
  void GUIAPI CircleGenerator (void* context int sx int sy int r CB_CIRCLE cb);
  
  
  首先要指定圓心坐標以及半徑並傳遞上下文信息以及回調函數每生成一個點生成器將調用一次 cb 回調函數並傳遞三個值xx 和 y這三個值實際表示了圓上的兩個點(x y) 和 (x y)因為圓的對稱性生成器只要計算圓上的四分之一圓弧點即可得出圓上所有的點
  
   橢圓生成器
  
  橢圓生成器和圓生成器類似原型如下
  
  /* Ellipse generator */
  typedef void (* CB_ELLIPSE) (void* context int x int x int y);
  void GUIAPI EllipseGenerator (void* context int sx int sy int rx int ry CB_ELLIPSE cb);
  
  首先要指定橢圓心坐標以及 X 軸和 Y 軸半徑並傳遞上下文信息以及回調函數每生成一個點生成器將調用一次 cb 回調函數並傳遞三個值xx 和 y這三個值實際表示了橢圓上的兩個點(x y) 和 (x y)因為橢圓的對稱性生成器只要計算橢圓上的二分之一圓弧點即可得出橢圓上所有的點
  
   圓弧生成器
  
  MiniGUI 定義的圓弧生成器如下所示
  
  /* Arc generator */
  typedef void (* CB_ARC) (void* context int x int y);
  void GUIAPI ArcGenerator (void* context int sx int sy int r fixed ang fixed ang CB_ARC cb);
  
  首先要指定圓弧的圓心半徑起始弧度和終止弧度需要注意的是起始弧度和終止弧度是采用定點數表示的而不是浮點數並且是弧度而不是角度然後傳遞 cb 回調函數每生成一個圓弧上的點該函數將調用回調函數並傳遞新點的坐標值 (x y)
  
  有關定點數的信息請參閱本系列主題六MiniGUI 提供的非 GUI/GDI 接口一文
  
   垂直單調多邊形生成器
  
  通常而言多邊形有凸多邊形和凹多邊形之分這裡的垂直單調多邊形是為了優化多邊形填充算法而針對計算機圖形特點而提出的一種特殊多邊形這種多邊形的定義如下
  
  垂直單調多邊形是指多邊形的邊和計算機屏幕上的所有水平掃描線只能有一個或者兩個交點不會有更多交點
  
  圖 給出了凸多邊形凹多邊形和垂直單調多邊形的幾個示例
  
  
  
  需要注意的是凸多邊形一定是垂直單調多邊形但垂直單調多邊形可以是凹多邊形顯然普通的多邊形填充算法需要判斷多邊形邊和每條屏幕掃描線之間的交點個數而垂直單調多邊形則可以免去這一判斷所以可以大大提高多邊形填充的速度
  
  MiniGUI 所定義的垂直單調多邊形相關函數原型如下
  
  /* To determine whether the specified Polygon is Monotone Vertical Polygon */
  BOOL GUIAPI PolygonIsMonotoneVertical (const POINT* pts int vertices);
  
  /* Monotone vertical polygon generator */
  typedef void (* CB_POLYGON) (void* context int x int x int y);
  BOOL GUIAPI MonotoneVerticalPolygonGenerator (void* context const POINT* pts int vertices CB_POLYGON cb);
  
  PolygonIsMonotoneVertical 用來判斷給定的多邊形是否是垂直單調多邊形而 MonotoneVerticalPolygonGenerator 函數是垂直多邊形生成器在 MiniGUI 當中多邊形是由組成多邊形的頂點來表示的pts 表示頂點數組而 vertices 表示頂點個數生成器生成的實際是填充多邊形的每一條水平線端點為 (x y) 和 (x y)
  
   一般矩形生成器
  
  MiniGUI 還提供了一般的矩形生成器該生成器可以處理凸多邊形也可以處理凹多邊形原型如下
  
  /* General polygon generator */
  typedef void (* CB_POLYGON) (void* context int x int x int y);
  BOOL GUIAPI PolygonGenerator (void* context const POINT* pts int vertices CB_POLYGON cb);
  
  和垂直單調多邊形生成器一樣該函數生成的是填充多邊形的每一條水平掃描線x 是水平線的起始X坐標x 是水平線的終止 X 坐標y 是水平線的 Y 坐標值
  
   填注生成器
  
  填注(flood filling)生成器比較復雜這個函數在 MiniGUI 內部用於 FloodFill 函數我們知道FloodFill 函數從給定的起始位置開始以給定的顏色向四面八方填充某個區域(像水一樣蔓延因此叫 Flood Filling)一直到遇到與給定起始位置的象素值不同的點為止因此在這一過程中我們需要兩個回調函數一個回調函數用來判斷蔓延過程中遇到的點的象素值是否和起始點相同另外一個回調函數用來生成填充該區域的水平掃描線在進行繪圖時該函數比較的是象素值但實際上該函數也可以比較任何其他值從而完成特有的蔓延動作這就是將填注生成器單獨出來的初衷MiniGUI 如下定義填注生成器
  
  /* General Flood Filling generator */
  typedef BOOL (* CB_EQUAL_PIXEL) (void* context int x int y);
  typedef void (* CB_FLOOD_FILL) (void* context int x int x int y);
  BOOL GUIAPI FloodFillGenerator (void* context const RECT* src_rc int x int y
        CB_EQUAL_PIXEL cb_equal_pixel CB_FLOOD_FILL cb_flood_fill);
  
  cb_equal_pixel 被調用以便判斷目標點的象素值是否和起始點一樣起始點的象素值可以通過 context 來傳遞cb_flood_fill 函數用來填充一條掃描線傳遞的是水平掃描線的端點即(x y) 和 (x y)
  
   曲線和填充生成器的用法
  
  曲線和填充生成器的用法非常簡單為了對曲線和填充生成器有個更好的了解我們首先看 MiniGUI 內部是如何使用曲線和填充生成器的
  
  下面的程序段來自 MiniGUI 的 FloodFill 函數(src/newgdi/floodc)
  
  static void _flood_fill_draw_hline (void* context int x int x int y)
  {
  PDC pdc = (PDC)context;
  RECT rcOutput = {MIN (x x) y MAX (x x) + y + };
  
  ENTER_DRAWING (pdc rcOutput);

From:http://tw.wingwit.com/Article/program/Oracle/201311/16987.html
  • 上一篇文章:

  • 下一篇文章:
  • 推薦文章
    Copyright © 2005-2022 電腦知識網 Computer Knowledge   All rights reserved.