国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 開發 > 綜合 > 正文

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

2024-07-21 02:38:19
字體:
來源:轉載
供稿:網友

  作者:魏永明
  
  主題七:MiniGUI 1.1.0 引入的新 GDI 功能和函數之二
  
  1 引言
  我們在本系列主題五中曾經具體描述了在 MiniGUI 1.1.0 版本開發過程中添加的新 GDI 功能和函數。這些接口首次出現在版本 1.1.0PRe4 當中。目前 MiniGUI 1.1.0Pre7 版本已經發布,該版本中的新 GDI 接口趨于穩定,相對 1.1.0Pre4 版本而言,又新增了若干高級圖形接口。這些接口涉及到直線和曲線生成器、復雜曲線的繪制、封閉曲線填充、復雜區域的創建、直接的顯示緩沖區訪問、YUV 覆蓋和 Gamma 校正等等。本文將就這些主題具體描述各個接口的用法。
  
  2 曲線和填充生成器
  在一般的圖形系統中,通常給用戶提供若干用于進行直線或者復雜曲線,比如圓弧、橢圓和樣條曲線的繪圖函數。用戶可以通過這些函數進行繪圖,但不能利用這些系統中已有的曲線生成算法完成其他的工作。在 MiniGUI 新的 GDI 接口設計當中,我們采用了一種非凡的設計方法來實現曲線和封閉曲線的填充,這種方法非常靈活,而且給用戶提供了直接使用系統內部算法的機會:
  
  1)系統中定義了若干用來生成直線和曲線的函數,我們稱之為"曲線生成器";
  2)用戶在調用生成器之前,需要定義一個回調函數,并將函數地址傳遞給曲線生成器,曲線生成器在生成了一個曲線上的點或者封閉曲線中的一條水平填充線時,將調用這個回調函數。
  3)用戶可以在回調函數當中完成針對新的點或者新的水平填充線的操作。對 MiniGUI 繪圖函數來說,就是完成繪圖工作。
  4)因為回調函數在生成器的運行過程中不斷調用,為了保持一致的上下文環境,系統答應用戶在調用曲線生成器時傳遞一個表示上下文的指針,生成器將把該指針傳遞給回調函數。
  
  下面將分小節講述目前的 MiniGUI 版本所提供的曲線和填充生成器。
  
  2.1 直線剪切器和直線生成器
  
  直線剪切器和生成器的原型如下:
  
  /* Line clipper */
  BOOL GUIAPI LineClipper (const RECT* cliprc, int *_x0, int *_y0, int *_x1, int *_y1);
  
  /* Line generators */
  typedef void (* CB_LINE) (void* context, int stepx, int stepy);
  void GUIAPI LineGenerator (void* context, int x1, int y1, int x2, int y2, CB_LINE cb);
  
  直線剪切器并不是生成器,它用于對給定的直線進行剪切操作。cliprc 是給定的直線,而 _x0、_y0、_x1 和 _y1 傳遞要剪切的直線起始端點,并通過這些指針返回剪切之后的直線起始端點。MiniGUI 內部使用了 Cohen-Sutherland 算法。
  
  LineGenerator 是采用 Breshenham 算法的生成器。該生成器從給定直線的起始端點開始,每生成一個點調用一次 cb 回調函數,并傳遞上下文 context、以及新的點相對于上一個點的步進值或者差量。比如,傳遞 stepx =1,stepy = 0 表示新的點比上一個點在 X 軸上前進一步,而在 Y 軸上保持不變。回調函數可以在步進值基礎上實現某種程度上的優化。
  
  2.2 圓生成器
  
  MiniGUI 定義的圓生成器原型如下:
  
  /* Circle generator */
  typedef void (* CB_CIRCLE) (void* context, int x1, int x2, int y);
  void GUIAPI CircleGenerator (void* context, int sx, int sy, int r, CB_CIRCLE cb);
  
  
  首先要指定圓心坐標以及半徑,并傳遞上下文信息以及回調函數,每生成一個點,生成器將調用一次 cb 回調函數,并傳遞三個值:x1、x2 和 y。這三個值實際表示了圓上的兩個點:(x1, y) 和 (x2, y)。因為圓的對稱性,生成器只要計算圓上的四分之一圓弧點即可得出圓上所有的點。
  
  2.3 橢圓生成器
  
  橢圓生成器和圓生成器類似,原型如下:
  
  /* Ellipse generator */
  typedef void (* CB_ELLIPSE) (void* context, int x1, int x2, int y);
  void GUIAPI EllipseGenerator (void* context, int sx, int sy, int rx, int ry, CB_ELLIPSE cb);
  
  首先要指定橢圓心坐標以及 X 軸和 Y 軸半徑,并傳遞上下文信息以及回調函數,每生成一個點,生成器將調用一次 cb 回調函數,并傳遞三個值:x1、x2 和 y。這三個值實際表示了橢圓上的兩個點:(x1, y) 和 (x2, y)。因為橢圓的對稱性,生成器只要計算橢圓上的二分之一圓弧點即可得出橢圓上所有的點。
  
  2.4 圓弧生成器
  
  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 ang1, fixed ang2, CB_ARC cb);
  
  首先要指定圓弧的圓心、半徑、起始弧度和終止弧度。需要注重的是,起始弧度和終止弧度是采用定點數表示的,而不是浮點數,并且是弧度而不是角度。然后傳遞 cb 回調函數。
每生成一個圓弧上的點,該函數將調用回調函數,并傳遞新點的坐標值 (x, y)。
  
  有關定點數的信息,請參閱本系列"主題六:MiniGUI 提供的非 GUI/GDI 接口"一文。
  
  2.5 垂直單調多邊形生成器
  
  通常而言,多邊形有凸多邊形和凹多邊形之分。這里的垂直單調多邊形,是為了優化多邊形填充算法而針對計算機圖形特點而提出的一種非凡多邊形,這種多邊形的定義如下:
  
  垂直單調多邊形是指,多邊形的邊和計算機屏幕上的所有水平掃描線,只能有一個或者兩個交點,不會有更多交點。
  
  圖 1 給出了凸多邊形、凹多邊形和垂直單調多邊形的幾個示例。
  
  基于 Linux 和 MiniGUI 的嵌入式系統軟件開發指南(七)
  
  需要注重的是,凸多邊形一定是垂直單調多邊形,但垂直單調多邊形可以是凹多邊形。顯然,普通的多邊形填充算法需要判定多邊形邊和每條屏幕掃描線之間的交點個數,而垂直單調多邊形則可以免去這一判定,所以可以大大提高多邊形填充的速度。
  
  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 x1, int x2, int y);
  BOOL GUIAPI MonotoneVerticalPolygonGenerator (void* context, const POINT* pts, int vertices, CB_POLYGON cb);
  
  PolygonIsMonotoneVertical 用來判定給定的多邊形是否是垂直單調多邊形,而 MonotoneVerticalPolygonGenerator 函數是垂直多邊形生成器。在 MiniGUI 當中,多邊形是由組成多邊形的頂點來表示的。pts 表示頂點數組,而 vertices 表示頂點個數。生成器生成的實際是填充多邊形的每一條水平線,端點為 (x1, y) 和 (x2, y)。
  
  2.6 一般矩形生成器
  
  MiniGUI 還提供了一般的矩形生成器,該生成器可以處理凸多邊形,也可以處理凹多邊形。原型如下:
  
  /* General polygon generator */
  typedef void (* CB_POLYGON) (void* context, int x1, int x2, int y);
  BOOL GUIAPI PolygonGenerator (void* context, const POINT* pts, int vertices, CB_POLYGON cb);
  
  和垂直單調多邊形生成器一樣,該函數生成的是填充多邊形的每一條水平掃描線:x1 是水平線的起始X坐標;x2 是水平線的終止 X 坐標;y 是水平線的 Y 坐標值。
  
  2.7 填注生成器
  
  填注(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 x1, int x2, 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 函數用來填充一條掃描線,傳遞的是水平掃描線的端點,即(x1, y) 和 (x2, y)。
  
  2.8 曲線和填充生成器的用法
  
  曲線和填充生成器的用法非常簡單。為了對曲線和填充生成器有個更好的了解,我們首先看 MiniGUI 內部是如何使用曲線和填充生成器的。
  
  下面的程序段來自 MiniGUI 的 FloodFill 函數(src/newgdi/flood.c):
  
  static void _flood_fill_draw_hline (void* context, int x1, int x2, int y)
  {
  PDC pdc = (PDC)context;
  RECT rcOutput = {MIN (x1, x2), y, MAX (x1, x2) + 1, y + 1};
  
  ENTER_DRAWING (pdc, rcOutput);

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 略阳县| 瑞丽市| 城步| 平和县| 长岛县| 北宁市| 五大连池市| 镇雄县| 新乐市| 山东| 英吉沙县| 讷河市| 砀山县| 新干县| 安泽县| 屏东市| 南涧| 滕州市| 玛多县| 天长市| 甘孜县| 乳山市| 堆龙德庆县| 绥江县| 敦化市| 彭山县| 延边| 鄂托克旗| 长岛县| 包头市| 高雄市| 融水| 阿坝县| 辉县市| 紫云| 闸北区| 四子王旗| 青田县| 大渡口区| 富蕴县| 阜城县|