浅析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;
}
阅读(2866) | 评论(0) | 转发(0) |