模組化思想:編碼格式模組,庫模組,顯示模組,描畫,輸入模組。根據傳入引數
物件導向思想:每個模組建立乙個結構機構體鍊錶,如編碼模組,有乙個編碼鏈表,各編碼格式設定為乙個結構體,註冊入鍊錶
以後我們操作,只需要操作到鍊錶,而不需要到操作到底層各編碼格式的具體函式。
操作過程:根據傳入引數,找到支援該編碼格式的結構體,從該結構體中找到支援該編碼格式轉化為位圖的庫,呼叫該庫轉化為位圖,描畫到顯示模組輸出。以下是具體一步步的從原始碼分析:
從main函式開始 ,一開始會根據傳進來的引數進行解析,
./show_file [-s size] [-f freetype_font_file] [-h hzk] //輸入資訊
dwfontsize = strtoul(optarg, null, 0); //size存放的位置,optagr表示引數存在optagr
strncpy(acfreetypefile, optarg, 128); //freetype(字型庫)存放的位置
acfreetypefile[127] = '\0';
strncpy(achzkfile, optarg, 128); //漢子庫存放位置(基本沒用到)
achzkfile[127] = '\0';
strncpy(acdisplay, optarg, 128); //顯示裝置名字存放的
acdisplay[127] = '\0';
3.獲得支援檔案編碼的結構體g_ptencodingoprforfile,如何獲得? selectencodingoprforfile(g_puctextfilemem),該函式會呼叫g_ptencodingoprhead 即 編碼鏈表 取出每個 issupport 函式 判斷哪乙個編碼支援,若支援則返回該編碼的結構體。這裡面issupport是根據傳入的引數,即檔案首位址 g_puctextfilemem 然後strncmp 得到的,因為這幾個編碼格式的頭部不一樣。
該函式裡,根據傳入的庫檔案,字型檔案,字型大小,找到支援的字型庫,並對該庫初始化。怎麼找的呢?進入函式發現,根據「二」中得到的支援編碼結構體g_ptencodingoprforfile 裡的成員 ptfontoprsupportedhead 的name 找到該庫,並呼叫其初始化函式。舉個例子例如,在g_ptencodingoprforfile 如果是 g_tutf8encodingopr,即utf-8編碼格式的檔案,就會找到支援utf-8 的庫,utf-8裡有freetype庫和ascii庫,我們在為utf-8新增支援庫時,把freetype放在 ptfontoprsupportedhead了頭部,所以拿ptfontoprsupportedhead煉表裡的第乙個成員去匹配時,會先找到freetype庫,然後呼叫其初始化函式初始化這個庫。
1.選擇顯示裝置很簡單,selectandinitdisplay(acdisplay);acdisplay裡存放著我們傳入的裝置名(在「一」中以說明),然後根據裝置名從顯示裝置鍊錶中找到匹配的成員,取出該結構體並呼叫其初始化函式初始化裝置。
2.初始化所有輸入裝置也簡單:allinputdevicesinit();該函式會去輸入裝置鍊錶對每乙個成員都初始化,並且建立子執行緒,等待資料傳入後喚醒。一開始是如何休眠的?在初始化裝置時(呼叫每個成員的初始化函式),我們open的方式為阻塞方式。iret = ts_read(g_ttsdev, &tsamp, 1); /* 如果無資料則休眠 *,有資料傳入,就會呼叫 inputeventtreadfunction 去喚醒主線程。
shownextpage(),該函式裡會呼叫showonepage()去顯示一頁,之後就會根據輸入事件去判斷顯示哪一頁了
1.分析shownextpage() 主要做了哪些事情?
1.1得到該頁首位址(資料真正開始的地方),存放在 puctextfilememcurpos
//第一次先執行else,因為 g_ptcurpage一開始等於null
if (g_ptcurpage)
else
1.2.根據當前位置開始顯示一頁內容,顯示完成返回 0 ;
ierror = showonepage(puctextfilememcurpos);
if (ierror == 0)
ptpage = malloc(sizeof(t_pagedesc));
if (ptpage)
}
2.分析主要的顯示函式showonepage
2.1 得到了該編碼用多少位元組表示這個「字」 ,得到dwcode 編碼的內容,這就是getcodefrmbuf 裡的功能(如何得到這些,需要相關編碼知識)
ilen = g_ptencodingoprforfile->getcodefrmbuf(pucbufstart, g_puctextfilememend, &dwcode)
pucbufstart = puctextfilememcurpos,puctextfilememcurpos 資料真正開始的地方,在 (五.1.1)中註明**
g_puctextfilememend 即文字結束的位址,在(二.2)中得到
ptfontopr = g_ptencodingoprforfile->ptfontoprsupportedhead;,準備開始轉換位圖
2.3 轉換位圖 得到位圖存於tfontbitmap,並且重新計算顯示位置,顯示位圖 showonefont(&tfontbitmap),計算下一「字」的原點座標以及資料開始的地方,break跳出又從(五.2.1)開始執行。具體**注釋如下:
while (ptfontopr)
dbg_printf("%s %s %d\n", __file__, __function__, __line__);
if (bhasnotclrsceen)
dbg_printf("%s %s %d\n", __file__, __function__, __line__);
/* 顯示乙個字元 */
if (showonefont(&tfontbitmap))
//獲得下一「字」的原點座標以及資料開始的地方
tfontbitmap.icuroriginx = tfontbitmap.inextoriginx;
tfontbitmap.icuroriginy = tfontbitmap.inextoriginy;
g_puclcdnextposatfile = pucbufstart;
/* 跳出while迴圈,繼續取出下乙個編碼來顯示 */
break;
} ptfontopr = ptfontopr->ptnext;
}
關於轉換位圖 怎麼轉換呢?可以去乙個庫檔案看看便知,如freetype.c 主要是設定 各種引數,xtop,ytop,buf位址等,這些值怎麼來的呢?是初始化的時候,我們就去計算來的。
2.3.1這裡面我們還要關心的兩個函式是relocatefontpos(&tfontbitmap) 重新計算位置 和 showonefont(&tfontbitmap) 顯示乙個字元,重新計算位置這個函式都比較簡單,根據位圖資訊,如果xmax>xres(x方向解析度)就換行,同理ymax>yres換頁,滿頁了,返回,不顯示該字了。
2.3.2說一下showonefont 會裡面是個雙層for迴圈,即y方向和x方向雙層for,顯示點陣圖的每乙個畫素,如果該畫素有值就顯示,沒有值就顯示和背景色一樣的顏色。顯示每乙個畫素就呼叫到了 顯示裝置的 g_ptdispopr->showpixel(x, y, unsigned int dwcolor);
問題1. x,y的引數怎麼來的?
答:去看showonefont(&tfontbitmap),根據傳入的點陣圖,點陣圖的x,y座標等資訊都存在了裡面,我們從位圖原點開始畫每個畫素即可。
問題2. 怎麼顯示乙個畫素的呢?
//得到該畫素的顯示位址,g_dwlinewidth * iy表示在哪一行,g_dwpixelwidth * ix 表示x值
pucfb = g_pucfbmem + g_dwlinewidth * iy + g_dwpixelwidth * ix;
然後根據傳入的顏色值dwcolor 這個顏色值 轉換成 8bpp、16bpp或者32bpp 的 color值,再將其賦值到 顯示位址,即可顯示出來。
我們在(四.2)時allinputdevicesinit(),為輸入事件建立了子執行緒函式並且讓輸入事件 pttmp->getinputevent 休眠了
iret = ts_read(g_ttsdev, &tsamp, 1); /* 如果無資料則休眠 */,它的喚醒函式 inputeventtreadfunction。有資料傳來,處理資料,給
ptinputevent->ival賦值,然後返回0,getinputevent ==0 就會執行相應的if語句了。
其實分析那麼多,最主要的是想把細節說清楚,掌握這些細節的知識,如freetype是怎麼獲得點陣圖的,才算是真正的懂。如果答不出來,說明只是半桶水而已。
所以,細節又涉及很多知識點,具體知識點不在這裡說明,只說方法。我認為重要的細節點是
1.ascii、utf-8、utf-16be、utf-16le編碼如何分辨?即如何分辨出檔案的編碼格式,很簡單,根據資料頭部資訊判斷格式
如何解碼?主要是掌握utf-8, 因為它不固定,即表示乙個字用的位元組數不固定
2.各庫freetype·,gdk,ascii如何 轉換為位圖?其中,以freetype最為重要
3.如何在lcd上顯示?這個問題相當複雜,詳細可以看第五大點,細分為以下幾個問題
數碼相框 電子書之指標和鍊錶(8)
數碼相框 電子書之指標和鍊錶 8 一級指標 int p 表示定義乙個int型 4位元組 的指標p p 表示p自身的位址位置 p 表示p指向的位址位置 也就是p變數的值 p 表示p指向的位址裡面的內容 二級指標 int pp 表示定義乙個int 型的指標pp pp 表示pp自身的位址位置 pp 表示p...
專案1 電子書 第1課 數碼相框之系統框架
主 機 vmware ubuntu 16.04.2 x64 100ask 開發板 jz2440 256m nandflash,2m norflash,64m sdram,lcd 4.3寸 bootlorder u boot 2012.04.01,kernel linux3.4.2 編譯器 arm l...
在PC上顯示電子書測試方法 數碼相框
svgalib 1.4.3.orig.tar.gz svgalib 1.4.3 30.debian.tar.gz svgalib 1.4.3 30.dsc 打補丁tar xzf svgalib 1.4.3.orig.tar.gz tar xzf svgalib 1.4.3 30.debian.tar...