1,打开Frame Buffer
2,把mmap的返回值送到text_out中去
3,把主程序中的数据流接受过来
4,把数据流转换utf8(3个字节/每个字符)->unicode(2个字节/每个字符)
5,在用draw_pixel函数,把位图画上去。
少废话,上代码:
willisway1:
COsd::Osd
{
int fd;
struct fb_fix_screeninfo fix;
struct fb_var_screeninfo var;
stVoDevAttr.u32BgColor = 0x0000FF;
stVoDevAttr.enIntfType = VO_INTF_CVBS;
/* 1. open framebuffer device overlay 0 */
fd = open(pFbDevName, O_RDWR, 0);
if(fd < 0)
{
printf("open %s failed!\n",pFbDevName);
}
/* 2. set the screen original position */
if (ioctl(fd, FBIOPUT_SCREEN_ORIGIN, &stPoint) < 0)
{
printf("set screen original show position failed!\n");
close(fd);
}
/* 3.set alpha */
stAlpha.bAlphaEnable = FALSE;
stAlpha.bAlphaChannel = FALSE;
stAlpha.u8Alpha0 = 0xff;
stAlpha.u8Alpha1 = 0x8f;
stAlpha.u8GlobalAlpha = 0x80;
if (ioctl(fd, FBIOPUT_ALPHA, &stAlpha) < 0)
{
printf("Set alpha failed!\n");
close(fd);
}
/* 4. get the variable screen info */
if (ioctl(fd, FBIOGET_VSCREENINFO, &var) < 0)
{
printf("Get variable screen info failed!\n");
close(fd);
}
/* 5. modify the variable screen info
the screen size: IMAGE_WIDTH*IMAGE_HEIGHT
the virtual screen size: VIR_SCREEN_WIDTH*VIR_SCREEN_HEIGHT
(which equals to VIR_SCREEN_WIDTH*(IMAGE_HEIGHT*2))
the pixel format: ARGB1555
*/
var.xres_virtual = VIR_SCREEN_WIDTH;
var.yres_virtual = VIR_SCREEN_HEIGHT;
var.xres = IMAGE_WIDTH;
var.yres = IMAGE_HEIGHT;
var.transp= g_a16;
var.red = g_r16;
var.green = g_g16;
var.blue = g_b16;
var.bits_per_pixel = 16;
var.activate = FB_ACTIVATE_FORCE;
/* 6. set the variable screeninfo */
if (ioctl(fd, FBIOPUT_VSCREENINFO, &var) < 0)
{
printf("Put variable screen info failed!\n");
close(fd);
}
/* 7. get the fix screen info */
if (ioctl(fd, FBIOGET_FSCREENINFO, &fix) < 0)
{
printf("Get fix screen info failed!\n");
close(fd);
}
u32FixScreenStride = fix.line_length; /*fix screen stride*/
/* 8. map the physical video memory for user use */
m_pShowScreen = (unsigned char *)mmap(NULL, fix.smem_len, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0);
if(MAP_FAILED == m_pShowScreen)
{
printf("mmap framebuffer failed!\n");
close(fd);
}
memset(m_pShowScreen, 0, u32FixScreenStride*IMAGE_HEIGHT);
}
willisway2:
int text_out(textoutattr_t *pString, void *other)
{
int x = pString->x+100, y = 50+pString->y*5;
int i=0, nByteCount = 0, nFontWidth = 0, nFontHeight = 0,j,k;
const unsigned char * pDot=NULL;
unsigned short *pUnicode = NULL;
unsigned char unicodeAry[160];
POINT p = {pString->x, pString->y, 0};
unsigned short r = 0xff;
unsigned short g = 0xff;
unsigned short b = 0xff;
utf8_to_unicode(pString->string, unicodeAry);
pUnicode = (unsigned short *)unicodeAry;
while(pUnicode[i])
{
if(pUnicode[i] <= 0x7f )
{
pDot = pFont[0] + pUnicode[i]*16;
nByteCount = 16;
nFontWidth = 8;
nFontHeight = 16;
}
else if(pUnicode[i] < 0x1000 )
{
pDot = pFont[0] + pUnicode[i]*32 - 128 * 16;
nByteCount = 32;
nFontWidth = 16;
nFontHeight = 16;
}
else
{
pDot = pFont[pUnicode[i] >>12] + (pUnicode[i] & 0xfff)*32;
nByteCount = 32;
nFontWidth = 16;
nFontHeight = 16;
}
for(j=0; j{
for(k=0; k{
p.x = x+j;
p.y = y+k;
if( pDot[j+(k/8)*nFontWidth] & (1 << (k%8)) )
draw_pixel(m_pShowScreen, p, r, g, b);
else if(pString->UseBgColor)
draw_pixel(m_pShowScreen, p, 0xff, 0xff, 0xff);
}
}
x+=nFontWidth;
i++;
}
return 0;
}
willisway3:
int utf8_to_unicode(const char *pString, unsigned char *unicode)
{
int i=0,j=0;
unsigned short nUnicode = 0;
while(pString[i]) //如果只得到一个,屏蔽这一句
{
if( (unsigned char)pString[i] < 0x80 )
{
nUnicode = pString[i];
i++;
}
else if ( 0xc0 == ((unsigned char)pString[i] & 0xe0) )
{
nUnicode = ((pString[i] & 0x1f) << 6) | (pString[i+1] & 0x3f);
i += 2;
}
else if ( 0xe0 == ((unsigned char)pString[i] & 0xf0) )
{
nUnicode = ((pString[i] & 0x0f) << 12) | ((pString[i+1] & 0x3f) << 6) | (pString[i+2] & 0x3f);
i += 3;
}
unicode[j++] = nUnicode & 0xff;
unicode[j++] = ( nUnicode >> 8 ) & 0xff;
}
unicode[j++] = 0;
return i;
}
willisway4:
void draw_pixel (unsigned char *Fbdev, POINT p, unsigned short r, unsigned short g, unsigned short b)
{
unsigned int offset;
unsigned char color[2];
color[0] = b | g<<5 | 0xFF;
color[1] = g >> 3 | r<<3;
offset = p.y*line_th+2*p.x;
memcpy((void*)(Fbdev + offset), color, 2);
}
打完收工,这样,界面上就能把主程序的数据流显示到显示器里面去。