[2014 write a UI library when writing a few articles, published]
A few years ago an embedded UI development that gave itself the opportunity to access some of the underlying knowledge of the UI, although it had developed many of the information applications under Windows, but also did a lot of interface development, but was not aware of some of the workings of the UI.
Boss decided to use Ucgui as the basic library for UI to develop some applications of UI interface. With the Ucgui library to do the development, it has a very good basic components, such as the form of management, basic controls, pictures, word processing, etc., but I heard that Ucgui licensing fees is also very expensive, but I think it is really a value for money things.
In the use of also encountered some problems, but these basic will not have any big impact, the main is the source code, there are some small bugs, can also handle themselves, can not meet the control to develop their own, can also be very convenient on the basis of his control to do some expansion.
Using it avoids the need to read some of its underlying code, which gives you a chance to get a basic understanding of the UI's actions. Recently also do some UI, think of Ucgui code architecture is worth learning, so oneself from the basic principle of the UI to learn once again, oneself also took time to do some basic code implementation, a lot of basic principles are learned from the Ucgui, and then put these basic things down, Convenient for later learners.
How do I write a UI myself? I never thought about it before I touched the underlying UI, and I thought it was a complicated and difficult thing. How hard is it? Now I think if a programming language can write a UI out, this foundation is enough, I think you can give it a try!
Start by drawing a point
The word "pixel" we must already very familiar with, now buy mobile phone when everyone is very important to view a parameter is the camera's imaging pixel is how much, because the quality of the image is a large degree of its decision, a pixel represents a point, also on the monitor is the same, we say the resolution is the length of the number of pixels, There are text on a screen, there are forms, pictures and various shapes and so on! It seems to be a very complicated thing, but it is composed of one point, a point represents a pixel, and this point different pixel value represents a different color, a pixel can be 8-bit, 16-bit, 32-bit to represent, the more the number of digits, indicating that it can represent the more colors displayed more colorful.
One screen looks like this:
We do a coordinate system with the upper left corner as the origin, with the x, y direction respectively. Like my current computer The resolution is 1440x900, so X maximum value is 1440,y maximum value is 900.
If we want to draw a point on a screen, given a point such as: (500,500), as long as the coordinate system to find the corresponding position can write a pixel value in, the screen will show a color point.
The display has a video memory, to draw points on the screen, it is necessary to write the color value in the corresponding memory location, the video memory will be mapped to a contiguous area, so we just write the value to the memory area, the system will be I/O read and write to update the value of the memory, the heart we just care about the area of the writing of
Operating memory
In Linux there is a concept called framebuffer, called "Frame cache", in fact, is the memory of the current value of the cache, the Linux system graphics driver has been implemented, we read and write to Framebuffer is the memory of the read and write.
In the Linux/dev directory, there should be a similar FBX (x represents a number) device file, open it, and then use the MMAP function to map framebuffer memory into our process can be easily recognized on the monitor operation, so we can draw points, draw lines displayed on the display.
As the following code operates, open fb0, and read the appropriate parameters for the setting:
static struct Fb_var_screeninfo stvarinfo;
static struct Fb_fix_screeninfo stfixinfo;
static unsigned char *pframebuffer = NULL;
Char *file_name = "/dev/fb0";
int FbDev, S32ret;
FbDev = open (file_name,o_rdwr,0);
if (FbDev < 0)
{
printf ("Open Framebuff failed!\n");
Return
}
Stvarinfo.bits_per_pixel = 16;
Stvarinfo.activate = Fb_activate_now;
Stvarinfo.xres = stvarinfo.xres_virtual = 1440;
Stvarinfo.yres = Stvarinfo.yres_virtual = 900;
S32ret = IOCTL (FbDev, Fbioput_vscreeninfo, &stvarinfo);
if (S32ret < 0)
{
printf ("Put_vscreeninfo failed!%x\n", S32ret);
return;
}
if (IOCTL (FbDev, Fbioget_fscreeninfo, &stfixinfo) < 0)
{
printf ("Get fix screen Info failed!\n");
return;
}
Pframebuffer = Mmap (Hi_null, Stfixinfo.smem_len, prot_read| Prot_write, map_shared, FbDev, 0);
memset (Pframebuffer,0x00,stfixinfo.smem_len);
In the above code, open a framebuffer, set the reading information of the display two of the more important structure: Fb_var_screeninfo and Fb_fix_screeninfo, the specific can be searched to understand.
In the mmap, Stfixinfo.smem_len is the size of the memory area, memset operation effect is that we set the display to black, because we write every point of the pixel value is 0x0.
Draw a point at a specified point
Memory address space is a linear one-dimensional address space, our screen like the above coordinate system, is a two-dimensional, given a point (x, y), so we need to convert it to the corresponding memory address. When you know the resolution of a screen, such as 1440 * 900, now through Fbioget_fscreeninfo know some basic information, through mmap know the first address. A pixel can be expressed in 8-bit, or 16-bit, or 32-bit, or more bits, as the system on my board is 16 bits, and the Linux system I use is 32-bit. For example on my board, use 16 bits to represent a pixel, that is, 2 bytes to represent a pixel point.
So the point on the screen is so sure, imagine you take a pen from the first line to draw a point, but the first line is full, and then start from the second line, continue to fill the entire screen, draw points on the screen is also the case, if the 16-bit 2 bytes represents a pixel, the resolution is 1400*900, so the address of the given point (
X * 2 + y * (1440 * 2),
If you use the information from the previous step of the code to indicate that:
(x + stvarinfo.xoffset) * (Stvarinfo.bits_per_pixel >> 3) + (y + stvarinfo.yoffset) * STFIXINFO.LINE_LENGTH;
Xoffset,yoffset indicates whether the offset of the relative origin, bit_per_pixel indicates how many bits of a pixel are represented, and line_length indicates how many bytes a row occupies.
The address of a point (x, y) is determined so that a value is written and the corresponding color is displayed in the appropriate location. So the corresponding draw point function is as follows:
void Ui_setpointpixel (int x, int y, int pixelvalue)
{
int location = 0;
Location = (x + stvarinfo.xoffset) * (Stvarinfo.bits_per_pixel >> 3) + (y + stvarinfo.yoffset) * Stfixinfo.line_leng Th
* (short *) (pframebuffer + location) = (short) pixelvalue;
}
Should be 16 bits, so note the above conversion (short *).
Gets the color of a point
Also sometimes the operation needs to get the color of a point, according to the function of the point above, you can write the function of acquiring the point as follows:
unsigned int fb_getpointpixel (int x, int y)
{
int location = 0;
Location = (x + stvarinfo.xoffset) * (Stvarinfo.bits_per_pixel >> 3) + (y + stvarinfo.yoffset) * Stfixinfo.line_leng Th
int pixelindex = * (short*) (Pshowscreen + location);
return pixelindex;
}
Basic UI bottom-up operations
We work with the operation of the UI, there are forms, pictures, videos and so on, a lot of things, look very complex, but such a complex north, but it is the basic pixel composition, but the complex implementation, are in the above point function, based on, in order to facilitate the opening of the law, so that the expansion of the above point function, there are , round and so on, in order to facilitate the subsequent drawing of more complex, we implement the draw line and fill the rectangle function:
void Fb_drawhline (int x0, int y0, int x1)
{
U16 Pixelcolor = Ui_getdrawpixecolor ();
for (; x0 <= x1; x0++)
{
Ui_setpointpixel (x0, y0, pixelcolor);
}
}
void Fb_drawvline (int x0, int y0, int y1)
{
U16 Pixelcolor = Ui_getdrawpixecolor ();
for (; y0 <= y1; y0++)
{
Ui_setpointpixel (x0, y0, pixelcolor);
}
}
void Fb_drawfillrect (int x0, int y0, int x1, int y1)
{
for (; y0<=y1; y0++)
{
Ui_drawhline (x0, y0, X1);
}
}
To achieve the horizontal, vertical line, fill the rectangle, the above Ui_getdrawpixecolor function to get the current draw point line fill color values.
So we have the basic tools to manipulate the UI. We can now draw points, lines, rectangles, or very simply using the functions above.
2014-11-15
Copyright NOTICE: This article for Bo Master original article, without Bo Master permission not reproduced.
Self-Implementing a UI Library