Index: 顏色 Graphics Context Graphics Image 例
--------------------------------------------------------------------------------
1. 顏色 在 X Window 視窗系統(tǒng),程式使用顏色都是透過(guò)配置 color cell。 color cell 存放著顏色的 RGB 色值,即繪圖時(shí)顯示器上所顯示出來(lái) 的色值。在我們使用某種顏色之前,必需先配置一個(gè)正確的 cell, 使用該 cell 做為繪圖時(shí)的參數(shù)。當(dāng) server 將圖形輸出到顯示器時(shí) ,顯示器(顯示卡)會(huì)取出 cell 內(nèi)所設(shè)定之 RGB 值,輸出到畫(huà)面。 RGB 即光學(xué)三元色紅、綠、藍(lán),經(jīng)由三元色的比例不同,可以得到不 同的顏色。
color cells 分成兩種,read-only cell 和 read/write cell。 read-only cell 只能被使用,不能被應(yīng)用程式修改,但是由各個(gè)應(yīng)用 程式之間一起分享,共同使用。read/write cell 被配置(allocate) 之後可以修改其 RGB 值,但一般是不在各應(yīng)用程式之間分享,是私有 的。
colormap 是 color cell 的集合。每個(gè) client 都可以有自己的 colormap,所以同時(shí)可能會(huì)有多個(gè) colormap 存在。而系統(tǒng)在同一 時(shí)間內(nèi),只安裝一個(gè) colormap 到顯示器上(有些硬容許同時(shí)安裝多 個(gè) colormap),所以當(dāng)一個(gè)視窗能顯示正確的顏色時(shí),其它視窗的顏色 可能會(huì)不正確。這是因?yàn)椴煌?nbsp;colormap,其 cell 和 RGB 值的對(duì) 應(yīng)可能不同,所以當(dāng) server 把某個(gè)視窗的 colormap 安裝到硬體上 時(shí),其它視窗內(nèi)的 cell 和 RGB 的對(duì)映,就變成新被安裝的 colormap 的對(duì)映方式,導(dǎo)至不正確的顏色顯示。也就是當(dāng) server 把某個(gè)視窗 的 colormap 安裝到顯示硬上時(shí),該視窗的顏色顯示就會(huì)正確。反 之,則會(huì)顯示目前被安裝的 colormap 的對(duì)映狀況,顯示不正確的顏 色。為了避免這個(gè)問(wèn)題,一般建議使用預(yù)定(default)共用的 colormap ,每個(gè)視窗都使用同一個(gè) colormap。default 的 colormap 可由 函數(shù) XDefaultColormap 取得。
顏色是以 R、G、B 三種元色光的量值來(lái)表示,當(dāng)某元色的量值越大時(shí) ,則顯示出來(lái)的顏色就越偏向該元色。Xlib 使用 XColor 記錄 RGB 值。 --------------------------------------------------------------------------------
typedef struct { unsigned long pixel; /* pixel value */ unsigned short red, green, blue; /* rgb values */ char flags; /* DoRed, DoGreen, DoBlue */ char pad; } XColor;
-------------------------------------------------------------------------------- red、green、blue 的圍從 0 到 65535。Black 用 (0,0,0) 表示, White 用 (65535,65535,65535) 表示。
每個(gè) color cell 在 colormap 上都占有一個(gè)位子,為了分別不同的 color cell,我們?yōu)槊總€(gè) color cell 指定一個(gè)編號(hào),稱之為 pixel。 所以當(dāng)我們需要指定一個(gè) cell 時(shí),我是指定其 pixel 值。pixel 是一個(gè) long 整數(shù),每一個(gè) bit 我們稱之為一個(gè) plane。因此,當(dāng)我 們?cè)?nbsp;colormap 上分配 x 個(gè) plane 時(shí),我們就是分配 2^x^ 個(gè) cell。
cell 有分 read-only 和 read/write:read-only cell的 RGB 值是由 server 設(shè)定的,不能更改。但是可由各 client 并同使用。每當(dāng)有一 個(gè) client 配置(allocate)read-only cell,則 server 會(huì)紀(jì)錄下來(lái), 當(dāng)所有配置該 cell 的 client 都釋放該 cell 後,該 cell 才算真正 被釋放。否則該 cell 就只能維持其原來(lái)的值不能改變,也不能被當(dāng)成 read/write cell 配置。而同一個(gè) client 多次配置同一個(gè) cell 則視 為多次的配置,client 也必需釋放該 cell 相同次數(shù)。read/write cell 則不會(huì)有初值,但卻可以由 client 設(shè)定更改其 RGB 值。當(dāng) client 分 配到 read/write cell 後,雖然其它 client 也可以設(shè)定其內(nèi)容 (RGB 值),但一般我們還是認(rèn)為 read/write cell是屬私人的,不被分 享共用的。
--------------------------------------------------------------------------------
Status XAllocColor(display, colormap, screen_in_out) Display *display; Colormap colormap; XColor *screen_in_out;
colormap 指定使用的 colormap。 screen_in_out 指定和傳回 colormap 內(nèi),實(shí)際的值。
-------------------------------------------------------------------------------- 可配置一個(gè) read-only cell。client 指定一個(gè) RGB 值,XAllocColor 分配一個(gè)對(duì)映到硬體所能提供最接近該 RGB 值的 cell。RGB 值設(shè)定在 screen_in_out 的 red、green、blue,而 cell 的 pixel 值會(huì)將由 pixel 傳回。硬體實(shí)際提供的 RGB 值,則經(jīng)由 red、green、blue 傳 回。
--------------------------------------------------------------------------------
Status XAllocColorCells(display, colormap, contig plane_masks_return, nplanes, pixels_return, npixels) Display *display; Colormap colormap; Bool contig; unsigned long plane_masks_return[]; unsigned int nplanes; unsigned long pixels_return[]; unsigned int npixels;
colormap 指定使用的 colormap contig 一個(gè) Boolean 值,指示配置的 planes 是否必 需是連續(xù)的。 plane_mask_return 傳回 plane masks 的 array。 nplanes 指定在 plane_mask_return 要傳回多少個(gè) plane masks。 pixels_return 傳回 pixel 陣列。 npixels 指定在 pixels_return 傳回多少個(gè) pixel values。
-------------------------------------------------------------------------------- 分配多個(gè) read/write cell。這些 cell 都未指定內(nèi)容,分配之後, client 程式可以更改其 RGB 值。在這你必需在 nplanes 指定你要分 配幾個(gè) plane,分配到的 plane,會(huì)經(jīng)由 plane_mask_return 傳回。 plane_mask_return 這個(gè)陣列內(nèi)的每個(gè)元素,指定了分配到的 plane 的 mask。npixels 則指定了要分配多少個(gè) pixel,pixel 則由 pixels_return 這個(gè)陣列傳回。所有分配到的 cell 的數(shù)目為 npixels * 2^nplanes^,而 cell 的 pixel 值則為 pixels_return 傳回之 pixel 值和 plane mask 做 OR 運(yùn)算所能產(chǎn)生 的所有值。如果 contig 設(shè)為 true,則所有分配到之 plane 會(huì)是相 鄰連續(xù)的,也就是所有傳回之 plane mask 做 OR 運(yùn)算,會(huì)得到一群 設(shè)為 1 的連續(xù) bits。
--------------------------------------------------------------------------------
XStoreColor(display, colormap, color) Display *display; Colormap colormap; XColor *color;
colormap 指定 colormap。 color 指定 pixel 和 RGB 值。
-------------------------------------------------------------------------------- 使用 XStoreColor 設(shè)定指定之 cell 的 RGB 值,但只限於 read/write cell。
--------------------------------------------------------------------------------
XStoreColors(display, colormap, color, ncolors) Display *display; Colormap colormap; XColor color[]; int ncolor;
colormap 指定 colormap。 color 指定要設(shè)定之顏色的結(jié)構(gòu)陣列。 ncolor 指定 color 陣列中有多少個(gè)設(shè)定值。
-------------------------------------------------------------------------------- XStoreColors 可以同時(shí)設(shè)定多個(gè) color cells 的 RGB 值,但只 限於 read/write cell,read-only cell 不能更改。
--------------------------------------------------------------------------------
XFreeColors(display, colormap, pixels, npixels, planes) Display *display; Colormap colormap; unsigned long pixels[]; int npixels; unsigned long planes;
colormap 指定使用之 colormap。 pixels 指定對(duì)映到 cells 的 pixels 值的陣列。 npixels 指定 pixels 陣列中有多少個(gè) pixel 值。 planes 指定你要釋放的 planes。
-------------------------------------------------------------------------------- 當(dāng)你所配置到的 color cell 不再被需要時(shí),你可以使用 XFreeColors 釋放。XFreeColors 同一時(shí)間內(nèi)可以釋放多個(gè) cell ,pixels 是指定要釋放掉的 cell 的陣列,npixels 則指定 cell 的數(shù)目。planes 則是要釋放之 planes 的 plane mask,將要釋放 之所有 plane 的 mask OR 起來(lái)所得到的 mask。所釋放的 pixels 為,任一指定之 pixel 和 plane mask 之部分集合做 OR 運(yùn)算後,所 有可能產(chǎn)生的 pixel 集合。
使用顏色名稱 除了使用 RGB 值之外,你可以使用顏色的名稱,并取得適當(dāng)?shù)?nbsp;pixel 值。 --------------------------------------------------------------------------------
status XAllocNamedColor(display, colormap, color_name, screen_def_return, exact_def_return) Display *display; Colormap colormap; char *color_name; XColor *screen_def_return, *exact_def_return;
colormap 指定 colormap。 color_name 顏色之名稱。 screen_def_return 傳回硬所能提供最接近之 RGB 值。 screen_def_exact 傳回精確的 RGB 值。
-------------------------------------------------------------------------------- screen_def_exact 傳回的是原本正確顏色所該有的 RGB 色值,而 screen_def_return 傳回的則是目前硬所能提供顏色最接近之 RGB 色值。
操作 Colormaps 除了使用預(yù)定公用的 colormap (從 parent 視窗拷貝而來(lái)的) 分配我 們需要的顏色之外,我們也可以為每個(gè)個(gè)別的視窗建立獨(dú)立的 colormap,讓每個(gè)視窗能獨(dú)力擁有 colormap,或者是由一群視窗來(lái) 分享(share)一個(gè) colormap。
--------------------------------------------------------------------------------
Colormap XCreateColormap(display, w, visual, alloc) Display *display; Window w; Visual *visual; int alloc;
w 指定視窗。 visual 指定一個(gè)該 screen 所提供之 visual。 alloc 指定是否要分配在 colormap 的所有 entry。 可以是 AllocNone 或 AllocAll。
-------------------------------------------------------------------------------- XCreateColormap 會(huì)傳回一個(gè)在指定視窗所在的 screen 上建立之新的 colormap。visual 指定該 colormap 所提供之 visual。
我們可以隨時(shí)為視窗設(shè)定新的 colormap,但是 colormap 的 visual 必需和視窗的 visual 相同。指定視窗的 colormap,我們可以透過(guò) XSetWindowColormap: --------------------------------------------------------------------------------
XSetWindowColormap(display, w, colormap) Display *display; Window w; Colormap colormap;
--------------------------------------------------------------------------------
--------------------------------------------------------------------------------
XFreeColormap(display, colormap) Display *display; Colormap colormap;
colormap 要釋放之 colormap。
-------------------------------------------------------------------------------- 釋放一個(gè) colormap,但對(duì)於預(yù)定之 colormap 沒(méi)有作用。如果要 釋放之 colormap 已被使用在某個(gè)視窗上時(shí),則 XFreeColormap 會(huì)將該視窗之 colormap 設(shè)成 None,并對(duì)該視窗產(chǎn)生 ColormapNotify event ( event 在後面的章節(jié)會(huì)談到 )。
2. Graphics Context Graphics Context 簡(jiǎn)稱 GC,是存在 server 上的一種資源。GC 是用來(lái) 存放繪圖時(shí)所需要的各項(xiàng)資訊(例如: 線的寬度和長(zhǎng)度,前景和背景顏色 等等),在大部分的繪圖功能中,都需要使用 GC 做為參數(shù)。其實(shí),我們 可以把 GC 看做是我們?cè)谧霎?huà)時(shí)的畫(huà)筆,不同的畫(huà)筆會(huì)產(chǎn)生不同的效果 。同樣的,我們也可以使用不同的 GC 內(nèi)容的變化,來(lái)組合達(dá)成我們所 需要的畫(huà)面效果。同一個(gè) GC 可以在不同的視窗使用,也可以在不同的 client 間使用,但是一般來(lái)說(shuō) ,并不鼓勵(lì)由不同的 client 使用,因?yàn)?nbsp;Xlib 會(huì)對(duì) GC 暫存,可能會(huì)造 成同步上的問(wèn)題。GC 是和 screen 結(jié)合在一起的,同時(shí)也和 depth 有關(guān) ,只有 screen 和 depth 和 GC 和同的視窗,才可以使用該 GC。也就是 該視窗必需和 GC 是在同一個(gè) screen,并且要有相同的 depth。
Xlib 提供 XGCValues 這個(gè)結(jié)構(gòu), 以存放 GC 的相關(guān)資訊。我們將要 設(shè)定的值,存於這個(gè)結(jié)構(gòu),同時(shí)也經(jīng)由這個(gè)結(jié)構(gòu)傳回 GC 的內(nèi)存值。 --------------------------------------------------------------------------------
/* GC attribute value mask bits */
#define GCFunction (1L<<0) #define GCPlaneMask (1L<<1) #define GCForeground (1L<<2) #define GCBackground (1L<<3) #define GCLineWidth (1L<<4) #define GCLineStyle (1L<<5) #define GCCapStyle (1L<<6) #define GCJoinStyle (1L<<7) #define GCFillStyle (1L<<8) #define GCFillRule (1L<<9) #define GCTile (1L<<10) #define GCStipple (1L<<11) #define GCTileStipXOrigin (1L<<12) #define GCTileStipYOrigin (1L<<13) #define GCFont (1L<<14) #define GCSubwindowMode (1L<<15) #define GraphicsExposures (1L<<16) #define GCClipXOrigin (1L<<17) #define GCClipYOrigin (1L<<18) #define GCClipMask (1L<<19) #define GCDashOffset (1L<<20) #define GCDashList (1L<<21) #define GCArcMode (1L<<22)
/* Values */
typedef struct { int function; unsigned long plane_mask; unsigned long foreground; unsigned long background; int line_width; int line_style; int cap_style; int join_style; int fill_style; int fill_rule; int arc_mode; Pixmap tile; Pixmap stipple; int ts_x_origin; int ts_y_origin; Font font; int subwindow_mode; Bool graphics_exposures; int clip_x_origin; int clip_y_origin; Pixmap clip_mask; int dash_offset; char dashes; } XGCValues;
-------------------------------------------------------------------------------- 下面是 XGCValues 的欄位說(shuō)明。 欄位 預(yù)設(shè)值 說(shuō)明 function GXcopy Xlib 定義了 16 種 function, 用以定義各種 X 所提供的繪圖形式. Xlib 提供了一些繪圖函數(shù), 當(dāng)我們?cè)谝粋€(gè) drawable 上繪圖時(shí), 新繪上的 圖該如何和在原本位置上的圖形配合呢? function 定義了 X 所提供的 16 種可能中的一種. 當(dāng)我們?yōu)?nbsp;GC 設(shè)好新的 function 之後, 下一次我們使用 GC 進(jìn)行繪圖時(shí), 新的 function 就開(kāi)始發(fā)生了作用. 下面是 Xlib 定義的 16 種 function. GXclear 把輸出圖素清除為 0 GXand 把輸出之圖與原圖素做 and 運(yùn)算 GXandReverse 先把原圖素反相, 然後和輸出圖素做 and 運(yùn)算 GXcopy 直接用輸出圖素替代原圖素 GXandInverted 先將輸出圖素和原圖素做 and 運(yùn)算後, 再將結(jié)果反相 GXnoop 維持原圖素 GXxor 輸出圖素和原圖素做 xor 運(yùn)算 GXor 輸出圖素和原圖素做 or 運(yùn)算 GXnor 先分別把輸出圖素和原圖素做反相, 再將反相後的兩圖做 and 運(yùn)算 GXequiv 先反相輸出圖素,然後和原圖素做 xor 運(yùn)算 GXinvert 把原圖素反相 GXorReverse 反相原圖素, 然後和輸出圖素做 xor 運(yùn)算 GXcopyInverted 把輸出圖素反相當(dāng)為最後結(jié)果 GXorInverted 把輸出圖素反相後和原圖素做 or 運(yùn)算 GXnand 把輸出圖素和原圖素做反相, 然後兩圖做 or 運(yùn)算 GXset 把輸出部分全設(shè)為 1 plane_mask AllPlanes 指定會(huì)被影的 planes, 會(huì)被影的 planes 設(shè)為 1。Xlib 中定義 AllPlanes 常數(shù), 指定所有的 planes。繪圖的最後結(jié)果是: ((輸出圖素 function 原圖素) AND plane_mask)
foreground 1 指定圖形輸出時(shí)的前景所使用的圖素值(pixel) background 0 指定圖形輸出時(shí)的背景所使用的圖素值(pixel) line_width 0 如果輸出中有線條時(shí), 線條的寬度. line_style LineSolid 線條的樣式, Xlib 定義三個(gè)常數(shù), 代表三種樣式. LineSolid 實(shí)線 LineOnOffDash 虛線 LineDoubleDash 另一種虛線 cap_style CapButt 指定線條端線點(diǎn)(起點(diǎn)和終點(diǎn))的樣式。 CapNotLast 和 CapButt 相似, 只是 line width 為 0 時(shí), 不畫(huà)出端點(diǎn). CapButt 方形長(zhǎng)角的端點(diǎn) CapRound 圓弧形的端點(diǎn) CapProjecting 和 CapButt 相似, 但端點(diǎn)會(huì)再延伸 line width 的一半長(zhǎng)度 join_style JoinMiter 折線的折點(diǎn)形式。 JoinMiter 角狀的折點(diǎn) JoinRound 圖弧狀的折點(diǎn) JoinBevel 像是兩個(gè) CapButt 的端點(diǎn)重疊在一起 fill_style FillSolid 設(shè)定線段,文字,和填充畫(huà)面的來(lái)源。 FillSolid 前景填滿 foreground 顏色 FillTiled 以 tile 填滿 FillStippled 前景以填上 foreground 但以 stipple 遮罩起來(lái). FillOpaqueStippled 和 FillStippled 相似, 但被遮罩的部分(stipple 內(nèi)為 0 的部分) 填上 background。 fill_rule EvenOddRule 設(shè)定呼叫 XFillPolygon 時(shí),如何定義出內(nèi)部和外部。 EvenOddRule 以通過(guò)指定點(diǎn)的線為基準(zhǔn), 通過(guò) path 奇數(shù)次的為 inside WindingRule 通過(guò)順時(shí)鐘方向的 path 和逆時(shí)鐘方向的 path 的次數(shù)如果不同 即為 inside。 arc_mode ArcPieSlice 控制 XFillArcs 如何填滿圓弧。 ArcChord 以琴弦般的填滿弧 ArcPieSlice 像被切開(kāi)的 pie 一樣的填滿弧 tile 0 和 GC 有相同 root 和深度(depth)的 pixmap stipple 0 深度(depth)為 1 的 pixmap ts_x_origin 0 設(shè)定 tile/stipple 的原點(diǎn)的 x 座標(biāo) ts_y_origin 0 設(shè)定 tile/stipple 的原點(diǎn)的 y 座標(biāo) font Implementation dependent 字形,XLoadFont 的傳回值 subwindow_mode ClipByChildren ClipByChildren IncludeInferiors graphics_exposures True 控制 XCopyArea 和 XCopyPlane 的 GraphicsExpose 事件(event)的產(chǎn)生。 clip_x_origin 0 clip_mask 的原點(diǎn)相對(duì)於 drawable 的位置 clip_y_origin 0 clip_mask 的原點(diǎn)相對(duì)於 drawable 的位置 clip_mask None clip_mask 為深度(depth)為 1 并和 GC 相同 root 的 pixmap, 做為輸出的 mask dash_offset dashes
你可以透過(guò) XCreateGC 建立一新的 GC: --------------------------------------------------------------------------------
GC XCreateGC(display, d, valuemask, values) Display *display; Drawable d; unsigned long valuemask; XGCValues *values;
d 指定 drawable。 valuemask 指定使用了那些 GC 元件。這個(gè)參數(shù)是把各元件之 mask OR 起來(lái)得到的 mask,用以指定設(shè)了那些元 件。 value 指定設(shè)定的 GC 內(nèi)容。
-------------------------------------------------------------------------------- 呼叫 XCreateGC 後,建立一個(gè)新的 GC,并會(huì)傳回 GC。所謂的 drawable 指的是一個(gè)可以使用繪圖功能,在其上進(jìn)行繪圖的視窗或是其它 X 上的 物件。
--------------------------------------------------------------------------------
XFreeGC(display, gc) Display *display; GC gc;
gc 指定要釋放之 GC。
-------------------------------------------------------------------------------- 釋放一個(gè)己建立之 GC。
下面我們介紹一些設(shè)定 GC 的方便函數(shù),以方便我們做 GC 設(shè)定。
--------------------------------------------------------------------------------
XSetForeground(display, gc, foreground) Display *display; GC gc; usigned long foreground;
gc 指定作用對(duì)像之 GC。 foreground 指定前景顏色。
-------------------------------------------------------------------------------- 設(shè)定 GC 內(nèi)容的前景。當(dāng)你使用該 GC 繪圖時(shí),前景顏色即為 GC 內(nèi)所設(shè)的前景顏色。
--------------------------------------------------------------------------------
XSetBackground(display, gc, background) Display *display; GC gc; usigned long background;
gc 指定作用對(duì)像之 GC。 background 指定背景顏色。
-------------------------------------------------------------------------------- 設(shè)定 GC 的背景顏色。當(dāng)你使用該 GC 繪圖時(shí),前景顏色即為 GC 內(nèi)所設(shè)的前景顏色。
--------------------------------------------------------------------------------
XSetLineAttributes(display, gc, line_width, line_style, cap_style, join_style) Display *display; GC gc; unsigned int line_width; int line_style; int cap_style; int join_style;
gc 指定作用對(duì)像之 GC。 line_width 線條之寬度。 line_style 線條型式,有 LineSolid、LineOnOffDash、 LineDoubleDash。 cap_style 指定線條端點(diǎn)之型式,有 CapNotLast、 CapButt、CapRound、CapProjecting。 join_style 指定線條轉(zhuǎn)折點(diǎn)的型式,有 JoinMiter、 JoinRound、JoinBevel。
-------------------------------------------------------------------------------- 設(shè)定線的形式。
--------------------------------------------------------------------------------
XSetFont(display, gc, font) Display *display; GC gc; Font font;
gc 指定作用對(duì)像之 GC。 font 指定字型。
-------------------------------------------------------------------------------- 設(shè)定字形。
--------------------------------------------------------------------------------
XSetArcMode(display, gc, arc_mode) Display *display; GC gc; int arc_mode;
gc 指定作用對(duì)像之 GC。 arc_mode 指定畫(huà)弧時(shí),封口的型式,有 ArcChord、 ArcPieSlice。
-------------------------------------------------------------------------------- 設(shè)定畫(huà)弧時(shí),封口的型式。 3. Graphics Xlib 提供大量的函數(shù),處理圖形的輸出。 --------------------------------------------------------------------------------
XClearWindow(display, w) Display *display; Window w;
-------------------------------------------------------------------------------- 清除視窗。
--------------------------------------------------------------------------------
XDrawPoint(display, d, gc, x, y) Display *display; Drawable d; GC gc; int x, y;
d 指定 drawable。 gc 指定要使用之 GC。 x, y 指定畫(huà)點(diǎn)的座標(biāo)。
-------------------------------------------------------------------------------- 在視窗上畫(huà)一點(diǎn)。
--------------------------------------------------------------------------------
XDrawLine(display, d, gc, x1, y1, x2, y2) Display *display; Drawable d; GC gc; int x1, y1, x2, y2;
d 指定目的 drawable。 gc 指定使用之 GC。 x1, y1, x2, y2 指定線的兩端點(diǎn)座標(biāo)。
-------------------------------------------------------------------------------- 在視窗上畫(huà)一條線。
--------------------------------------------------------------------------------
XDrawRectangle(display, d, gc, x, y, width, height) Display *display; Drawable d; GC gc; int x, y; unsigned int width, height;
x, y 指定矩形的左上角座標(biāo)。 width, height 指定矩形的大小。
-------------------------------------------------------------------------------- 在視窗上畫(huà)一個(gè)矩形。
--------------------------------------------------------------------------------
XDrawArc(display, d, gc, x, y, width, height, angle1, angle2) Display *display; Drawable d; GC gc; int x, y; unsigned int width, height; int angle1, angle2;
x, y 指定弧的中心點(diǎn)(原點(diǎn))。 width, height 指定弧的 x 軸和 y 軸的比例。 angle1, angle2 弧的起始角度和結(jié)止角度。
-------------------------------------------------------------------------------- 在視窗上畫(huà)一個(gè)弧形。
--------------------------------------------------------------------------------
XFillRectangle(display, d, gc, x, y, width, height) Display *display; Drawable d; GC gc; int x, y; unsigned int width, height;
-------------------------------------------------------------------------------- 在視窗上畫(huà)一個(gè)填滿顏色的矩形。
--------------------------------------------------------------------------------
XFillArc(display, d, gc, x, y, width, height, angle1, angle2) Display *display; Drawable d; GC gc; int x, y; unsigned int width, height; int angle1, angle2;
-------------------------------------------------------------------------------- 在視窗上畫(huà)一個(gè)填滿顏色的弧形。
--------------------------------------------------------------------------------
Font XLoadFont(display, name) Display *display; char *name;
name 指定字形名稱。
-------------------------------------------------------------------------------- 載入字形,當(dāng)我要在視窗上顯示某一字形時(shí),我們必需先載入字形, 然後才能使用。使用這個(gè)函數(shù)之後,會(huì)傳回一個(gè) Font 的 ID,這 就是我們?cè)谑褂?nbsp;XSetFont 函數(shù)設(shè)定 GC 所要傳入的參數(shù)之一。 當(dāng)我們使用傳回來(lái)的 Font 設(shè)定 GC 後,就可以使用該 GC 當(dāng)做 參數(shù)在螢?zāi)簧巷@示該字形的字串。
--------------------------------------------------------------------------------
XUnloadFont(display, font) Display *display; Font font;
font 指定要 unload 的字形。
-------------------------------------------------------------------------------- 移除字形。當(dāng)我們不再使用一字形時(shí),我們必需將之移除。
--------------------------------------------------------------------------------
XDrawString(display, d, gc, x, y, string, lengtth) Display *display; Drawable d; GC gc; int x, y; char *string; int length;
gc 畫(huà)字時(shí)所要用的 GC。 x, y 指定字串顯示的座標(biāo)。 string 要顯示的字串。 length 字串的長(zhǎng)度。
-------------------------------------------------------------------------------- 在螢?zāi)簧巷@示一字串。
--------------------------------------------------------------------------------
XDrawString16(display, d, gc, x, y, string, length) Display *display; Drawable d; GC gc; int x, y; XChar2b *string; int length;
gc 指定使用之 GC。 x, y 指定字串顯示的座標(biāo)。 string 指定顯示之字串。 length 指定字串內(nèi)有多少個(gè)字。
-------------------------------------------------------------------------------- 在螢?zāi)簧巷@示一雙位元組(或 16bits)的字串。X Window 有支援雙位元組 字集,用以顯示雙位元組的語(yǔ)言(如中文等)。雙位元組的字元是以 XChar2b 這個(gè) structure 來(lái)表示: typedef struct { unsigned char byte1; unsigned char byte2; } XChar2b;
byte1 存放的是雙位元組字元的高位元組(MSB:most significant byte) ,byte2 存放的則是低位元組(LSB:least significant byte)。一個(gè)雙 位元組的字串就是 XChar2b 的陣列。
4. Image 在 GUI 介面下, 常會(huì)需要將一張圖片直接 show 在視窗上, 像是 show 照片. Xlib 提供一些可以直接在 client 和 server 間傳送影像(image)的函數(shù), 以直接處理一張張的影像, 例如, 圖形檔. 在這提到的 image 相關(guān)函數(shù), 都會(huì)使用 XImage 結(jié)構(gòu)做為函數(shù)的輸入?yún)?shù). Xlib 在 client 端使用 XImage 描述影像資料, 當(dāng)你要使用 Xlib 的函數(shù)處理影像資料時(shí), 必需透過(guò) XImage 進(jìn)行操作. XImage 提供一個(gè)物件化的介面, 透過(guò)物件提供的函數(shù), 我們可以相同的方式, 處理不同的影像資料. --------------------------------------------------------------------------------
/* * Data structure for "image" data, used by image manipulation routines. */ typedef struct _XImage { int width, height; /* size of image */ int xoffset; /* number of pixels offset in X direction */ int format; /* XYBitmap, XYPixmap, ZPixmap */ char *data; /* pointer to image data */ int byte_order; /* data byte order, LSBFirst, MSBFirst */ int bitmap_unit; /* quant. of scanline 8, 16, 32 */ int bitmap_bit_order; /* LSBFirst, MSBFirst */ int bitmap_pad; /* 8, 16, 32 either XY or ZPixmap */ int depth; /* depth of image */ int bytes_per_line; /* accelarator to next line */ int bits_per_pixel; /* bits per pixel (ZPixmap) */ unsigned long red_mask; /* bits in z arrangment */ unsigned long green_mask; unsigned long blue_mask; XPointer obdata; /* hook for the object routines to hang on */ struct funcs { /* image manipulation routines */ struct _XImage *(*create_image)(); #if NeedFunctionPrototypes int (*destroy_image) (struct _XImage *); unsigned long (*get_pixel) (struct _XImage *, int, int); int (*put_pixel) (struct _XImage *, int, int, unsigned long); struct _XImage *(*sub_image)(struct _XImage *, int, int, unsigned int, unsigned int); int (*add_pixel) (struct _XImage *, long); #else int (*destroy_image)(); unsigned long (*get_pixel)(); int (*put_pixel)(); struct _XImage *(*sub_image)(); int (*add_pixel)(); #endif } f; } XImage;
-------------------------------------------------------------------------------- XImage 可以建過(guò) XInitImage 和 XCreateImage 建立. 建立之後的 object, 可以使用 XGetPixel, XPutPixel, XSubImage 和 XAddPixel 讀取和修改內(nèi)容. 使用 XPutImage 輸出到 drawable (視窗或 pixmap), 使用 XGetImage 從 drawable 讀取. object 最後必需使用 XDestroyImage 釋放.
--------------------------------------------------------------------------------
Status XInitImage(image) XImage *image;
-------------------------------------------------------------------------------- XImage 在使用之前, 必需先經(jīng)過(guò) XInitImage 進(jìn)行 initialize. 在呼叫 XInitImage 之前, 除了 manipulate functions 之外, 其它的欄位都必需 先設(shè)定好. 成功的話, 傳回非0值, 否則傳回 0.
--------------------------------------------------------------------------------
XImage *XCreateImage(display, visual, depth, format, off- set, data, width, height, bitmap_pad, bytes_per_line) Display *display; Visual *visual; unsigned int depth; int format; int offset; char *data; unsigned int width; unsigned int height; int bitmap_pad; int bytes_per_line;
-------------------------------------------------------------------------------- XCreateImage 會(huì)為輸入之影像資料產(chǎn)生一個(gè) XImage 結(jié)構(gòu), 并傳回結(jié)構(gòu). 是一個(gè)包裝 XInitImage 的函數(shù). 'format' 指定影像儲(chǔ)存的形式, 有 ZPixmap, XYPixmap 和 XYBitmap. ZPixmap 的儲(chǔ)存方式是一個(gè) pixel 接 著一個(gè) pixel 存放. XYPixmap 則是 plane 接著 plane, 將所有 pixel 特定 plane 的內(nèi)容集成 bitmap, 然後依 plane 的順序儲(chǔ)存各 plane 形式的 bitmap. XYBitmap 和 XYPixmap 一樣, 但是 XYBitmap只有一個(gè) plane. 而, 影像的內(nèi)容則存在 data 所指定的 memory block . 使用者必需指定一塊記憶(data)以儲(chǔ)存影像, XCreateImage 并不會(huì)主動(dòng)為您配置. data 的大小和 image 的大小和深度(depth)有關(guān), format 也會(huì)影響. 下面是 data 大小和 bytes_per_line 的計(jì)算公式. format size of data bytes_per_line ZPixmap width * height * ((depth + 7) / 8) width * ((depth + 7) / 8) XYPixmap ((width + 7) / 8) * height * depth (width + 7) / 8 XYBitmap ((width + 7) / 8) * height * 1 (width + 7) / 8
--------------------------------------------------------------------------------
unsigned long XGetPixel(ximage, x, y) XImage *ximage; int x; int y;
-------------------------------------------------------------------------------- 取得影像內(nèi)的一個(gè)圖點(diǎn).
--------------------------------------------------------------------------------
XPutPixel(ximage, x, y, pixel) XImage *ximage; int x; int y; unsigned long pixel;
-------------------------------------------------------------------------------- 在影像上放上一個(gè)點(diǎn).
--------------------------------------------------------------------------------
XImage *XSubImage(ximage, x, y, subimage_width, subimage_height) XImage *ximage; int x; int y; unsigned int subimage_width; unsigned int subimage_height;
-------------------------------------------------------------------------------- 讀取影像的一部分內(nèi)容, 并傳回 XImage. x, y, subimage_width, 和 subimage_height 指定 image 內(nèi)的一個(gè)方框的位置和大小, 讀 取方框內(nèi)的資料.
--------------------------------------------------------------------------------
XAddPixel(ximage, value) XImage *ximage; long value;
-------------------------------------------------------------------------------- 把 image 內(nèi)每個(gè)點(diǎn)的 pixel 值都加上指定的 valuex.
--------------------------------------------------------------------------------
XDestroyImage(ximage) XImage *ximage;
-------------------------------------------------------------------------------- 由上面和下面各函數(shù)所產(chǎn)生的 XImage 物件, 最後不用時(shí), 都要使用 XDestroyImage 釋放掉。注意, XDestroyImage 會(huì)主動(dòng)將 data 釋放
--------------------------------------------------------------------------------
XPutImage(display, d, gc, image, src_x, src_y, dest_x, dest_y, width, height) Display *display; Drawable d; GC gc; XImage *image; int src_x, src_y; int dest_x, dest_y; unsigned int width, height;
-------------------------------------------------------------------------------- 將 image 輸出 'd' 所指定的 drawable.
--------------------------------------------------------------------------------
XImage *XGetImage(display, d, x, y, width, height, plane_mask, format) Display *display; Drawable d; int x, y; unsigned int width, height; unsigned long plane_mask; int format;
-------------------------------------------------------------------------------- 讀取 'd' 所指定之 drawable 的影像. 'plane_mask' 指定要讀取的 planes. 若指定的 planes, 為 drawable 所有 planes 的 subset, 那麼傳回的 image 的 depth 將和指定的 planes 數(shù)目相同.
--------------------------------------------------------------------------------
XImage *XGetSubImage(display, d, x, y, width, height, plane_mask, format, dest_image, dest_x, dest_y) Display *display; Drawable d; int x, y; unsigned int width, height; unsigned long plane_mask; int format; XImage *dest_image; int dest_x, dest_y;
--------------------------------------------------------------------------------
下面是處理影像的例. --------------------------------------------------------------------------------
/* -- Image-test.c -- */ #include #include #include #include #include #include #include "gnu.xpm" #include "doomface.xpm" #include "Boss2.xpm"
struct ColorElm { char *tag; unsigned long pixel; };
unsigned long get_pixel(Display *display, Colormap colormap, char *str) { char *cp = str; XColor color, excolor;
if(*cp == '#') { int j, k; int t; int rgbl; unsigned short rgb[3];
cp++; if(strlen(cp) == 6) rgbl = 2; else rgbl = 4;
for(k = 0; k < 3; k++) { t = 0; for(j = 0; j < rgbl; j++) { char c = *(cp++);
t <<= 4; if(c >= 'A' && c <= 'F') t += c - 'A' + 10; else if(c >= 'a' && c <= 'f') t += c - 'a' + 10; else t += c - '0'; } rgb[k] = t; }
color.red = rgb[0]; color.green = rgb[1]; color.blue = rgb[2]; color.flags = DoRed | DoGreen | DoBlue; XAllocColor(display, colormap, &color); } else { char *cp;
if(strcasecmp(str, "None") == 0) cp = "black"; else cp = str; XAllocNamedColor(display, colormap, cp, &color, &excolor); }
return color.pixel; }
/* * 從 *.xpm 轉(zhuǎn)換成 Xlib 能處理的 image 資料形式 (ZPixmap) */ char * xpm_to_data(char **xpm, Display *display, Colormap colormap, int depth, int *width, int *height) { int nc, el; /* # of color, and element length */ int i; int bpp; /* byte per pixel */ struct ColorElm *ce, *cep; unsigned short rgb[3]; XColor color; char *data, *dp;
sscanf(*(xpm++), "%d %d %d %d", width, height, &nc, &el); bpp = (depth + 7) / 8;
data = (char *)malloc(sizeof(char) * bpp * *width * *height); ce = (struct ColorElm *)malloc(sizeof(struct ColorElm) * nc);
cep = ce; for(i = 0; i < nc; i++) { char *cp;
cep->tag = (char *)malloc(sizeof(char) * el); memcpy(cep->tag, *xpm, el);
cp = *xpm + el; /* * skip redundant character */ while(isspace(*cp)) cp++; while(*(cp++) != 'c') { while(isspace(*cp)) cp++; while(!isspace(*cp)) cp++; while(isspace(*cp)) cp++; } /* * get pixel of color */ while(isspace(*cp)) cp++; cep->pixel = get_pixel(display, colormap, cp);
cep++; xpm++; }
/* * generate image data */ dp = data; for(i = 0; i < *height; i++) { int j; char *p;
p = *(xpm++); for(j = 0; j < *width; j++) { int idx; unsigned long pixel;
/* * find pixel of point */ for(idx = 0; idx < nc; idx++) if(!memcmp(p, ce[idx].tag, el)) { memcpy(dp, &ce[idx].pixel, bpp); break; } dp += bpp; p += el; } }
free(ce); return data; }
main() { Display *display; Window window; XSetWindowAttributes attr; Colormap colormap; XColor color1, color2; XGCValues gcvalue; GC gc; XSizeHints *sz; XImage *img1, *img2, *img3; int screen; char *data; /* image data */ int w, h; /* width & height */ int bpp; /* byte per pixel */
display = XOpenDisplay("0:0");
colormap = DefaultColormap(display, screen = DefaultScreen(display)); color1.red = color1.blue = 0xffff; color1.green = 0; color2.red = color2.green = color2.blue = 0xff; color1.flags = color2.flags = DoRed | DoGreen | DoBlue; XAllocColor(display, colormap, &color1); XAllocColor(display, colormap, &color2);
attr.background_pixel = color2.pixel; window = XCreateWindow(display, XDefaultRootWindow(display), 100, 100, 500, 300, 2, XDefaultDepth(display, 0), InputOutput, CopyFromParent, CWBackPixel, &attr);
XStoreName(display, window, "hello!! world!!"); sz = XAllocSizeHints(); sz->x = 100; sz->y = 100; sz->width = 300; sz->height = 500; sz->flags = USPosition | USSize; XSetNormalHints(display, window, sz); XMapWindow(display, window);
gc = XCreateGC(display, window, 0, &gcvalue); XSetForeground(display, gc, color1.pixel); XSetBackground(display, gc, color2.pixel); XFlush(display);
printf("Show image!!\n"); bpp = (DefaultDepth(display, screen) + 7) / 8; /* * Create gnu.xpm */ data = xpm_to_data(image_name, display, colormap, DefaultDepth(display, screen), &w, &h); img1 = XCreateImage(display, DefaultVisual(display, screen), DefaultDepth(display, screen), ZPixmap, 0, data, w, h, 8, w * bpp); /* (w, h) 是影像的寬和高 */
/* * Create doomface.xpm */ data = xpm_to_data(xpm, display, colormap, DefaultDepth(display, screen), &w, &h); img2 = XCreateImage(display, DefaultVisual(display, screen), DefaultDepth(display, screen), ZPixmap, 0, data, w, h, 8, w * bpp); /* (w, h) 是影像的寬和高 */
/* * Create Boss2.xpm */ data = xpm_to_data(Boss2_xpm, display, colormap, DefaultDepth(display, screen), &w, &h); img3 = XCreateImage(display, DefaultVisual(display, screen), DefaultDepth(display, screen), ZPixmap, 0, data, w, h, 8, w * bpp); /* (w, h) 是影像的寬和高 */
/* * Show images */ XPutImage(display, window, gc, img1, 0, 0, 10, 10, w, h); XPutImage(display, window, gc, img2, 0, 0, 10, 100, w, h); XPutImage(display, window, gc, img3, 0, 0, 200, 50, w, h); XFlush(display);
/* * Destroy images */ XDestroyImage(img1); XDestroyImage(img2); XDestroyImage(img3); sleep(3);
XDestroyWindow(display, window); XFlush(display);
XCloseDisplay(display); }
-------------------------------------------------------------------------------- 執(zhí)行結(jié)果
顏色和原圖有些不同, 主要原因是使用 default 的 colormap. 上面的程式 在視窗顯示三張 .xpm 的圖形檔, 分別是 gnu.xpm, doomface.xpm 和 Boss2.xpm.
5. 例
--------------------------------------------------------------------------------
/* ---- XGraph.c ---- */
#include #include #include #include
main() { Display *display; Window window; XSetWindowAttributes attr; Colormap colormap; XColor color1, color2; XGCValues gcvalue; GC gc; XSizeHints *sz;
display = XOpenDisplay("0:0");
/* 取得預(yù)設(shè)之 colormap */ colormap = DefaultColormap(display, DefaultScreen(display)); /* 取得 colorcell */ color1.red = color1.blue = 0xffff; color1.green = 0; color2.red = color2.green = color2.blue = 0xff; color1.flags = color2.flags = DoRed | DoGreen | DoBlue; XAllocColor(display, colormap, &color1); XAllocColor(display, colormap, &color2);
/* 設(shè)定視窗的 attribute 和建設(shè) */ attr.background_pixel = color2.pixel; /* 背景顏色 */ window = XCreateWindow(display, XDefaultRootWindow(display), 100, 100, 300, 300, 2, XDefaultDepth(display, 0), InputOutput, CopyFromParent, CWBackPixel, &attr);
/* 設(shè)定和 window manager 進(jìn)行溝通 */ XStoreName(display, window, "hello!! world!!"); sz = XAllocSizeHints(); sz->x = 100; sz->y = 100; sz->width = 300; sz->height = 300; sz->flags = USPosition | USSize; XSetNormalHints(display, window, sz);
/* 顯示視窗 */ printf("Map window\n"); XMapWindow(display, window); XFlush(display); getchar();
/* 建立并設(shè)定 GC */ gc = XCreateGC(display, window, 0, &gcvalue); XSetForeground(display, gc, color1.pixel); XSetBackground(display, gc, color2.pixel);
/* 畫(huà)一個(gè)矩形 */ printf("Draw rectangle\n"); XDrawRectangle(display, window, gc, 10, 10, 100, 100); XFlush(display); getchar();
/* 清除視窗 */ XClearWindow(display, window);
/* 設(shè)定 GC 內(nèi),線的形式 */ XSetLineAttributes(display, gc, 5, LineOnOffDash, CapButt, JoinRound); /* 畫(huà)線 (200, 10) - (200, 290) */ printf("Draw line\n"); XDrawLine(display, window, gc, 200, 10, 200, 290); XFlush(display); getchar();
/* 關(guān)閉視窗 */ printf("Destory Window\n"); XDestroyWindow(display, window); XFlush(display); getchar();
printf("close display\n"); XCloseDisplay(display); getchar(); }
--------------------------------------------------------------------------------
gcc -o XGraph XGraph.c -L/usr/X11R6/lib -lX11
-------------------------------------------------------------------------------- 上面是一個(gè)簡(jiǎn)單的例程式和 compile 的方法。 |
|