浅析minigui中GDI接口BeginPaint
使用如下3个语句,绘制数据到lcd上.
RotateBitmap(rotate->hdc,
&(rotate->foreground), rotate->forex, rotate->forey,
rotate->angle * 64);
hdc = BeginPaint(hwnd); //
获取的pdc->cur_dst该cur_dst将直接指向framebuffer,进而对cur_dst的赋值数据将
//
直接反应到lcd屏幕上.
BitBlt(rotate->hdc, 0, 0, 0, 0, hdc, 0, 0, 0);
//
将上面经过n多计算之后rotate->hdc矩形区中的数据,剪切之后,按需依次复制到hdc->cur_dst对应的
framebuffer地址中,
//
进而一次性显示到lcd屏幕上,这样BitBlt里面只是进行剪切计算和数据搬移工作,没有任何rotate图像旋转计算了,
//
rotate图像旋转计算的最后结果数据都已经存放到rotate->hdc这个由malloc申请的内存缓冲区中了,
//
所以BitBlt将只是作数据搬移操作,将rotate->hdc中旋转计算好的数据直接搬移到cur_dst指向的framebuffer中,
//
进而不带闪烁的立即显示到lcd屏幕上[luther.gliethttp]
EndPaint(hwnd, hdc);
看看源
码是怎么做到的
BeginPaint
hdc = GetClientDC (hWnd); // 获取一个client
DC,该dc的pixel
#define DCSLOTNUMBER 16
HDC GUIAPI GetClientDC
(HWND hWnd)
{
int i;
LOCK (&dcslot);
for (i = 0; i < DCSLOTNUMBER; i++) { // 最多16个
if
(!DCSlot[i].inuse) {
DCSlot[i].inuse = TRUE;
DCSlot[i].DataType = TYPE_HDC;
DCSlot[i].DCType =
TYPE_GENDC;
DCSlot[i].surface = __gal_screen; //
使用lcd全屏surface : __gal_screen [luther.gliethttp]
//
__gal_screen的创建位于industrialsample/libminigui-1.6.10/src/newgal/newgal.c中
//
__gal_screen = GAL_SetVideoMode (w, h, depth, GAL_HWPALETTE)); 这时
//
__gal_screen->pixels =
mapped_mem+mapped_offset;经过mmap的framebuffer首地址了,
//
对于QVFB来说__gal_screen->pixels = this->hidden->shmrgn +
this->hidden->hdr->dataoffset;
//
同样是以共享内存方式工作qvfb应用程序显示区的首地址[luther.gliethttp]
break;
}
}
UNLOCK (&dcslot);
if (i >=
DCSLOTNUMBER) // 如果超过了,那么返回全屏幕对应的HDC_SCREEN [lutehr.gliethttp]
return HDC_SCREEN;
dc_InitDC (DCSlot + i, hWnd, TRUE); //
初始化该hdc
return (HDC) (DCSlot + i);
}
static void
dc_InitDC (PDC pdc, HWND hWnd, BOOL bIsClient)
{
PCONTROL
pCtrl;
pdc->hwnd = hWnd;
pdc->bkcolor =
GAL_MapRGB (pdc->surface->format, 0xFF, 0xFF, 0xFF);
pdc->bkmode = 0;
pdc->pencolor = GAL_MapRGB
(pdc->surface->format, 0x00, 0x00, 0x00);
pdc->brushcolor = GAL_MapRGB (pdc->surface->format, 0xFF, 0xFF,
0xFF);
pdc->textcolor = GAL_MapRGB
(pdc->surface->format, 0x00, 0x00, 0x00);
if
(!(pdc->pLogFont = GetWindowFont (hWnd)))
pdc->pLogFont
= GetSystemFont (SYSLOGFONT_WCHAR_DEF);
pdc->tabstop = 8;
pdc->cExtra = pdc->alExtra = pdc->blExtra = 0;
pdc->mapmode = MM_TEXT;
pdc->ViewOrig.x =
pdc->ViewOrig.y = 0;
pdc->ViewExtent.x =
pdc->ViewExtent.y = 1;
pdc->WindowOrig.x =
pdc->WindowOrig.y = 0;
pdc->WindowExtent.x =
pdc->WindowExtent.y = 1;
#ifdef _ADV_2DAPI
pdc->pen_type = PT_SOLID;
pdc->pen_cap_style = PT_CAP_BUTT;
pdc->pen_join_style = PT_JOIN_MITER;
pdc->pen_width = 0;
pdc->dash_offset = 0;
pdc->dash_list = NULL;
pdc->dash_list_len = 0;
pdc->brush_type = BT_SOLID;
pdc->brush_orig.x = pdc->brush_orig.y = 0;
pdc->brush_tile = NULL;
pdc->brush_stipple = NULL;
#endif
/* Assume that the local clip region is empty. */
/* Get global
clip region info and generate effective clip region. */
if
(dc_IsGeneralDC (pdc)) {
// 执行如下代码
RECT minimal;
pdc->pGCRInfo = GetGCRgnInfo (hWnd);
LOCK_GCRINFO (pdc);
pdc->oldage = pdc->pGCRInfo->age;
ClipRgnCopy
(&pdc->ecrgn, &pdc->pGCRInfo->crgn);
pdc->bIsClient = bIsClient;
if (bIsClient)
WndClientRect (pdc->hwnd, &pdc->DevRC);
else
WndRect (pdc->hwnd, &pdc->DevRC);
minimal =
pdc->DevRC;
pCtrl = Control (pdc->hwnd);
if (pCtrl && !(pCtrl->dwExStyle & WS_EX_CTRLASMAINWIN))
RestrictControlECRGN (&minimal, pCtrl);
IntersectClipRect (&pdc->ecrgn, &minimal);
UNLOCK_GCRINFO (pdc);
}
/* context info and raster
operations. */
pdc->CurPenPos.x = pdc->CurTextPos.x = 0;
pdc->CurPenPos.y = pdc->CurTextPos.y = 0;
pdc->rop =
ROP_SET;
pdc->step = 1;
pdc->set_pixel =
set_pixel_ops
[pdc->rop][pdc->surface->format->BytesPerPixel - 1];
pdc->draw_hline =
draw_hline_ops
[pdc->rop][pdc->surface->format->BytesPerPixel - 1];
pdc->put_hline =
put_hline_ops
[pdc->rop][pdc->surface->format->BytesPerPixel - 1];
pdc->cur_dst = (BYTE*)pdc->surface->pixels //
pdc->DevRC.top为绝对坐标值,
//
根据绝对坐标值,计算该pdc左上角坐标(left,top)对应的framebuffer
//
区起始地址[luther.gliethttp][这个很关键,因为这就表示以后对该pdc->cur_dst的所有赋值操作,
// 都将直接反应到framebuffer中,进而直接反应到lcd屏幕上][lutehr.gliethttp]
+
pdc->surface->pitch * pdc->DevRC.top
+
pdc->surface->format->BytesPerPixel * pdc->DevRC.left;
pdc->move_to = move_to_ops
[pdc->surface->format->BytesPerPixel - 1];
pdc->step_x = step_x_ops
[pdc->surface->format->BytesPerPixel - 1];
memset
(pdc->gray_pixels, 0, sizeof (pdc->gray_pixels));
memset
(pdc->filter_pixels, 0, sizeof (pdc->filter_pixels));
pdc->alpha_pixel_format = NULL;
}
阅读(1916) | 评论(0) | 转发(1) |