Hi. I’m working on a project with the LeopardBoard DM368 which includes writing some texts on screen (OSD) and I’m using Davinci SDK 4.02.00.06 version. I’m using TI SimpleWidget library to write texts on screen. I can successfully write on screen but I want to clear that region I want to write on first. Cause now if there was a text on that region from before then the new text wouldn't look very nice and they would get on each other! So I'm looking for a way to clear a pixel before writing something on it.
This is the function I have written that uses a couple of text.c functions included in SimpleWidget library It takes a UI buffer and the desired text, its color, its background color, transparency(if yes then it ignores background color), blending value and of course XY position on the screen where it will put the text on:
Int Text_showPrev(UI_Handle hUI, Char *txt, Int height, Int x, Int y, UInt32 colorVal, UInt32 bgColorVal, UInt8 keyEnable,UInt8 blendVal) { Buffer_Handle hBuf,hBufAttr; Int ret; BufferGfx_Dimensions dim; if(getOSDAttrBuf(hUI, &hBuf, &hBufAttr)) return FAILURE; BufferGfx_getDimensions(hBuf, &dim); if((x<0)||(y<0)||(x>=dim.width)||(y>=dim.height)) { ERR("Invalid Param for show text\n"); return FAILURE; } y=y+height+1; // keyEnable = 1 means transparent ! if(keyEnable) ret=Text_show_key(hUI->hFont, txt, height, x, y, hBuf, colorVal, blendVal); else ret=Text_show_col(hUI->hFont, txt, height, x, y, hBuf, colorVal, bgColorVal, blendVal); // Text_show(hUI->hFont, txt, height, x, y, hBuf); if(ret) { ERR("Failed to show text prev\n"); return FAILURE; } if(Text_show_blend(hUI->hFont, txt, height, x, y, hBufAttr, keyEnable, blendVal)) { ERR("Failed to show text prev\n"); return FAILURE; } return putOSDAttrBuf(hUI, hBuf, hBufAttr); }
As you can see I'm calling for Text_show_key() or Text_show_col() (depending on being transparent or not) and also Text_show_blend() at the end. I couldn't make much sense from the implementation of this functions in text.c which is attached to the post. Could you guys please check if there is a way that I could somehow make a change so they clear the pixels before they change its value.
I don't know how exactly the buffer works or how the blending works. Unfortunately I couldn't find a documentation for this matter. It's kind of urgent.
/* * Text.c * * ============================================================================ * Copyright (c) Texas Instruments Inc 2009 * * Use of this software is controlled by the terms and conditions found in the * license agreement under which this software has been supplied or provided. * ============================================================================ */ #include <stdio.h> #include <ft2build.h> #include FT_FREETYPE_H #include FT_GLYPH_H #include <xdc/std.h> #include <ti/sdo/dmai/BufferGfx.h> #include <ti/sdo/simplewidget/Text.h> #include <ti/sdo/simplewidget/Font.h> #include <ti/sdo/simplewidget/Screen.h> #include <ti/sdo/simplewidget/Convert.h> #define GET_2BPP_BYTE(x) ((x) >> 2) #define GET_2BPP_SHIFT(x) (((x) % 4) * 2) Int Text_show_blend(Font_Handle hFont, Char *txt, Int fontHeight, Int x, Int y, Buffer_Handle hBuf, UInt8 keyEnable, UInt8 blendVal) { BufferGfx_Dimensions dim; FT_Error error; Int index; Int width, height; Int i, j, p, q, x_max, y_max, sp; UInt8 *src; FT_Vector pen; FT_Face face = (FT_Face) hFont->face; UInt8 *ptr, *rowPtr; UInt8 blendCnt,blend0; Int x2; BufferGfx_getDimensions(hBuf, &dim); FT_Set_Char_Size(face, fontHeight << 6, fontHeight << 6, 100, 100); pen.x = x << 6; pen.y = (dim.height - y) << 6; blend0=blendVal&0xf; while (*txt) { FT_Set_Transform(face, NULL, &pen); index = FT_Get_Char_Index(face, *txt); error = FT_Load_Glyph(face, index, 0); if (error) { SW_ERR("Failed to load glyph for character %c\n", *txt); break; } if (face->glyph->format != FT_GLYPH_FORMAT_BITMAP) { error = FT_Render_Glyph(face->glyph, FT_RENDER_MODE_NORMAL); if (error) { SW_ERR("Failed to render glyph for character %c\n", *txt); break; } } width = face->glyph->bitmap.width; height = face->glyph->bitmap.rows; x = face->glyph->bitmap_left; y = dim.height - face->glyph->bitmap_top; x2=x>>1; x_max = x + width; y_max = y + height; src = face->glyph->bitmap.buffer; ptr = (UInt8 *) Buffer_getUserPtr(hBuf) + y * dim.lineLength; printf("changes 5 \n"); for (j = y, q = 0; j < y_max; j++, q++) { blendCnt=(x&0x1)<<2; rowPtr = ptr + x2; for (i = x, p = 0; i < x_max; i++, p++) { if (i >= dim.width || j >= dim.height) continue; sp = q * width + p; if(keyEnable && src[sp]) //if(keyEnable ) { if(blend0) *rowPtr|=(blend0<<blendCnt); else *rowPtr&=(0xf0>>blendCnt); } else if(!keyEnable) { if(blend0) *rowPtr|=(blend0<<blendCnt); else *rowPtr&=(0xf0>>blendCnt); } blendCnt+=4; if(blendCnt==8) { blendCnt=0; rowPtr++; } } ptr += dim.lineLength; } txt++; pen.x += face->glyph->advance.x; pen.y += face->glyph->advance.y; } return SW_EOK; } Int Text_show(Font_Handle hFont, Char *txt, Int fontHeight, Int x, Int y, Buffer_Handle hBuf) { BufferGfx_Dimensions dim; FT_Error error; Int index; Int width, height; Int i, j, p, q, x_max, y_max, sp; UInt32 srcValue, dstValue; UInt8 *src; FT_Vector pen; FT_Face face = (FT_Face) hFont->face; Convert_Mode cMode; Int inc, start; UInt8 *ptr, *rowPtr; Int32 bufSize = Buffer_getSize(hBuf); ColorSpace_Type colorSpace = BufferGfx_getColorSpace(hBuf); BufferGfx_getDimensions(hBuf, &dim); FT_Set_Char_Size(face, fontHeight << 6, fontHeight << 6, 100, 100); Convert_init(); if (colorSpace == ColorSpace_2BIT) { cMode = Convert_Mode_RGB888_2BIT; start = 65; inc = 80; } else if (colorSpace == ColorSpace_YUV422PSEMI) { cMode = Convert_Mode_RGB888_YUV422SEMI; start = 80; inc = 80; } else if (colorSpace == ColorSpace_RGB565) { cMode = Convert_Mode_RGB888_RGB565; start = 0; inc = 0; } else { SW_ERR("Text_show() not supporting image color format\n"); return SW_EFAIL; } pen.x = x << 6; pen.y = (dim.height - y + start) << 6; while (*txt) { FT_Set_Transform(face, NULL, &pen); index = FT_Get_Char_Index(face, *txt); error = FT_Load_Glyph(face, index, 0); if (error) { SW_ERR("Failed to load glyph for character %c\n", *txt); break; } if (face->glyph->format != FT_GLYPH_FORMAT_BITMAP) { error = FT_Render_Glyph(face->glyph, FT_RENDER_MODE_NORMAL); if (error) { SW_ERR("Failed to render glyph for character %c\n", *txt); break; } } width = face->glyph->bitmap.width; height = face->glyph->bitmap.rows; x = face->glyph->bitmap_left; y = dim.height + inc - face->glyph->bitmap_top; x_max = x + width; y_max = y + height; src = face->glyph->bitmap.buffer; ptr = (UInt8 *) Buffer_getUserPtr(hBuf) + y * dim.lineLength; for (j = y, q = 0; j < y_max; j++, q++) { rowPtr = ptr + Screen_getInc(colorSpace, x); for (i = x, p = 0; i < x_max; i++, p++) { if (i >= dim.width || j >= dim.height) continue; sp = q * width + p; srcValue = src[sp] << 16 | src[sp] << 8 | src[sp]; dstValue = Convert_execute(cMode, srcValue, i & 1); Screen_setPixelPtr(rowPtr, bufSize, i, dstValue, FALSE, colorSpace); rowPtr += Screen_getStep(colorSpace, i); } ptr += dim.lineLength; } txt++; pen.x += face->glyph->advance.x; pen.y += face->glyph->advance.y; } return SW_EOK; } Int Text_show_col(Font_Handle hFont, Char *txt, Int fontHeight, Int x, Int y, Buffer_Handle hBuf, UInt32 colorVal, UInt32 bgColorVal, UInt8 blendVal) { BufferGfx_Dimensions dim; FT_Error error; Int index; Int width, height; Int i, j, p, q, x_max, y_max, sp; UInt32 srcValue, dstValue; UInt8 *src; FT_Vector pen; FT_Face face = (FT_Face) hFont->face; Convert_Mode cMode; Int inc, start; UInt8 *ptr, *rowPtr; Int32 bufSize = Buffer_getSize(hBuf); ColorSpace_Type colorSpace = BufferGfx_getColorSpace(hBuf); BufferGfx_getDimensions(hBuf, &dim); FT_Set_Char_Size(face, fontHeight << 6, fontHeight << 6, 100, 100); Convert_init(); if (colorSpace == ColorSpace_2BIT) { cMode = Convert_Mode_RGB888_2BIT; start = 65; inc = 80; } else if (colorSpace == ColorSpace_YUV422PSEMI) { cMode = Convert_Mode_RGB888_YUV422SEMI; start = 80; inc = 80; } else if (colorSpace == ColorSpace_RGB565) { cMode = Convert_Mode_RGB888_RGB565; start = 0; inc = 0; } else { SW_ERR("Text_show() not supporting image color format\n"); return SW_EFAIL; } pen.x = x << 6; pen.y = (dim.height - y + start) << 6; srcValue=0; while (*txt) { FT_Set_Transform(face, NULL, &pen); index = FT_Get_Char_Index(face, *txt); error = FT_Load_Glyph(face, index, 0); if (error) { SW_ERR("Failed to load glyph for character %c\n", *txt); break; } if (face->glyph->format != FT_GLYPH_FORMAT_BITMAP) { error = FT_Render_Glyph(face->glyph, FT_RENDER_MODE_NORMAL); if (error) { SW_ERR("Failed to render glyph for character %c\n", *txt); break; } } width = face->glyph->bitmap.width; height = face->glyph->bitmap.rows; x = face->glyph->bitmap_left; y = dim.height + inc - face->glyph->bitmap_top; x_max = x + width; y_max = y + height; src = face->glyph->bitmap.buffer; ptr = (UInt8 *) Buffer_getUserPtr(hBuf) + y * dim.lineLength; for (j = y, q = 0; j < y_max; j++, q++) { rowPtr = ptr + Screen_getInc(colorSpace, x); for (i = x, p = 0; i < x_max; i++, p++) { if (i >= dim.width || j >= dim.height) continue; sp = q * width + p; if(src[sp]) srcValue=colorVal; else srcValue=bgColorVal; dstValue = Convert_execute(cMode, srcValue, i & 1); if(blendVal==0) dstValue=0; Screen_setPixelPtr(rowPtr, bufSize, i, dstValue, FALSE, colorSpace); rowPtr += Screen_getStep(colorSpace, i); } ptr += dim.lineLength; } txt++; pen.x += face->glyph->advance.x; pen.y += face->glyph->advance.y; } return SW_EOK; } //Only Capture Int Text_show_key(Font_Handle hFont, Char *txt, Int fontHeight, Int x, Int y, Buffer_Handle hBuf,UInt32 colorVal, UInt8 blendVal) { BufferGfx_Dimensions dim; FT_Error error; Int index; Int width, height; Int i, j, p, q, x_max, y_max, sp; UInt32 srcValue, dstValue; UInt8 *src; FT_Vector pen; FT_Face face = (FT_Face) hFont->face; Convert_Mode cMode; Int inc, start; UInt8 *ptr, *rowPtr; Int32 bufSize = Buffer_getSize(hBuf); ColorSpace_Type colorSpace = BufferGfx_getColorSpace(hBuf); BufferGfx_getDimensions(hBuf, &dim); FT_Set_Char_Size(face, fontHeight << 6, fontHeight << 6, 100, 100); Convert_init(); if (colorSpace == ColorSpace_2BIT) { cMode = Convert_Mode_RGB888_2BIT; start = 65; inc = 80; } else if (colorSpace == ColorSpace_YUV422PSEMI) { cMode = Convert_Mode_RGB888_YUV422SEMI; start = 80; inc = 80; } else if (colorSpace == ColorSpace_RGB565) { cMode = Convert_Mode_RGB888_RGB565; start = 0; inc = 0; } else { SW_ERR("Text_show() not supporting image color format\n"); return SW_EFAIL; } pen.x = x << 6; pen.y = (dim.height - y + start) << 6; while (*txt) { FT_Set_Transform(face, NULL, &pen); index = FT_Get_Char_Index(face, *txt); error = FT_Load_Glyph(face, index, 0); if (error) { SW_ERR("Failed to load glyph for character %c\n", *txt); break; } if (face->glyph->format != FT_GLYPH_FORMAT_BITMAP) { error = FT_Render_Glyph(face->glyph, FT_RENDER_MODE_NORMAL); if (error) { SW_ERR("Failed to render glyph for character %c\n", *txt); break; } } width = face->glyph->bitmap.width; height = face->glyph->bitmap.rows; x = face->glyph->bitmap_left; y = dim.height + inc - face->glyph->bitmap_top; x_max = x + width; y_max = y + height; src = face->glyph->bitmap.buffer; ptr = (UInt8 *) Buffer_getUserPtr(hBuf) + y * dim.lineLength; printf("changes 3\n"); for (j = y, q = 0; j < y_max; j++, q++) { rowPtr = ptr + Screen_getInc(colorSpace, x); for (i = x, p = 0; i < x_max; i++, p++) { if (i >= dim.width || j >= dim.height) continue; sp = q * width + p; if(src[sp]) { srcValue = colorVal; dstValue = Convert_execute(cMode, srcValue, i & 1); if(blendVal==0) dstValue = 0;//transparent color = black Screen_setPixelPtr(rowPtr, bufSize, i, dstValue, FALSE, colorSpace);//======>FALSE } else { Screen_setPixelPtr(rowPtr, bufSize, i, 0 , FALSE, colorSpace);//======>FALSE } rowPtr += Screen_getStep(colorSpace, i); } ptr += dim.lineLength; } txt++; pen.x += face->glyph->advance.x; pen.y += face->glyph->advance.y; } return SW_EOK; } Int Text_stringSize(Font_Handle hFont, Char *txt, Int fontHeight, Int *stringWidth, Int *stringHeight) { Int index; Int width = 0; Int height = 0; FT_Vector pen; FT_Face face = (FT_Face) hFont->face; FT_Set_Char_Size(face, fontHeight << 6, fontHeight << 6, 100, 100); pen.x = 0; pen.y = 0; while (*txt) { FT_Set_Transform(face, NULL, &pen); index = FT_Get_Char_Index(face, *txt); if (FT_Load_Glyph(face, index, 0)) { SW_ERR("Failed to load glyph for character %c\n", *txt); break; } if (face->glyph->format != FT_GLYPH_FORMAT_BITMAP) { if (FT_Render_Glyph(face->glyph, FT_RENDER_MODE_NORMAL)) { SW_ERR("Failed to render glyph for character %c\n", *txt); break; } } width += face->glyph->bitmap.width + 1; if (face->glyph->bitmap.rows > height) { height = face->glyph->bitmap.rows; } pen.x += face->glyph->advance.x; pen.y += face->glyph->advance.y; txt++; } *stringWidth = width; *stringHeight = height; return SW_EOK; }